PageSourceSearch

https://bronia.ai/vendor.js

js bronia.ai collected 2026-10-05 11:52:26 UTC 3,544,586 bytes, 109,618 lines download raw bytes

1"use strict";
2(self["webpackChunkblk_design_system_angular"] = self["webpackChunkblk_design_system_angular"] || []).push([["vendor"],{
3
4/***/ 4505:
5/*!****************************************************************!*\
6  !*** ./node_modules/rxjs/_esm2015/internal/BehaviorSubject.js ***!
7  \****************************************************************/
8/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9
10__webpack_require__.r(__webpack_exports__);
11/* harmony export */ __webpack_require__.d(__webpack_exports__, {
12/* harmony export */   "BehaviorSubject": () => (/* binding */ BehaviorSubject)
13/* harmony export */ });
14/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subject */ 2218);
15/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/ObjectUnsubscribedError */ 9086);
16
17
18class BehaviorSubject extends _Subject__WEBPACK_IMPORTED_MODULE_0__.Subject {
19  constructor(_value) {
20    super();
21    this._value = _value;
22  }
23
24  get value() {
25    return this.getValue();
26  }
27
28  _subscribe(subscriber) {
29    const subscription = super._subscribe(subscriber);
30
31    if (subscription && !subscription.closed) {
32      subscriber.next(this._value);
33    }
34
35    return subscription;
36  }
37
38  getValue() {
39    if (this.hasError) {
40      throw this.thrownError;
41    } else if (this.closed) {
42      throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_1__.ObjectUnsubscribedError();
43    } else {
44      return this._value;
45    }
46  }
47
48  next(value) {
49    super.next(this._value = value);
50  }
51
52}
53
54/***/ }),
55
56/***/ 472:
57/*!****************************************************************!*\
58  !*** ./node_modules/rxjs/_esm2015/internal/InnerSubscriber.js ***!
59  \****************************************************************/
60/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
61
62__webpack_require__.r(__webpack_exports__);
63/* harmony export */ __webpack_require__.d(__webpack_exports__, {
64/* harmony export */   "InnerSubscriber": () => (/* binding */ InnerSubscriber)
65/* harmony export */ });
66/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subscriber */ 14);
67
68class InnerSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
69  constructor(parent, outerValue, outerIndex) {
70    super();
71    this.parent = parent;
72    this.outerValue = outerValue;
73    this.outerIndex = outerIndex;
74    this.index = 0;
75  }
76
77  _next(value) {
78    this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this);
79  }
80
81  _error(error) {
82    this.parent.notifyError(error, this);
83    this.unsubscribe();
84  }
85
86  _complete() {
87    this.parent.notifyComplete(this);
88    this.unsubscribe();
89  }
90
91}
92
93/***/ }),
94
95/***/ 2378:
96/*!***********************************************************!*\
97  !*** ./node_modules/rxjs/_esm2015/internal/Observable.js ***!
98  \***********************************************************/
99/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
100
101__webpack_require__.r(__webpack_exports__);
102/* harmony export */ __webpack_require__.d(__webpack_exports__, {
103/* harmony export */   "Observable": () => (/* binding */ Observable)
104/* harmony export */ });
105/* harmony import */ var _util_canReportError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/canReportError */ 5739);
106/* harmony import */ var _util_toSubscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util/toSubscriber */ 8333);
107/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./symbol/observable */ 6831);
108/* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./util/pipe */ 6800);
109/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./config */ 146);
110
111
112
113
114
115class Observable {
116  constructor(subscribe) {
117    this._isScalar = false;
118
119    if (subscribe) {
120      this._subscribe = subscribe;
121    }
122  }
123
124  lift(operator) {
125    const observable = new Observable();
126    observable.source = this;
127    observable.operator = operator;
128    return observable;
129  }
130
131  subscribe(observerOrNext, error, complete) {
132    const {
133      operator
134    } = this;
135    const sink = (0,_util_toSubscriber__WEBPACK_IMPORTED_MODULE_0__.toSubscriber)(observerOrNext, error, complete);
136
137    if (operator) {
138      sink.add(operator.call(sink, this.source));
139    } else {
140      sink.add(this.source || _config__WEBPACK_IMPORTED_MODULE_1__.config.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable ? this._subscribe(sink) : this._trySubscribe(sink));
141    }
142
143    if (_config__WEBPACK_IMPORTED_MODULE_1__.config.useDeprecatedSynchronousErrorHandling) {
144      if (sink.syncErrorThrowable) {
145        sink.syncErrorThrowable = false;
146
147        if (sink.syncErrorThrown) {
148          throw sink.syncErrorValue;
149        }
150      }
151    }
152
153    return sink;
154  }
155
156  _trySubscribe(sink) {
157    try {
158      return this._subscribe(sink);
159    } catch (err) {
160      if (_config__WEBPACK_IMPORTED_MODULE_1__.config.useDeprecatedSynchronousErrorHandling) {
161        sink.syncErrorThrown = true;
162        sink.syncErrorValue = err;
163      }
164
165      if ((0,_util_canReportError__WEBPACK_IMPORTED_MODULE_2__.canReportError)(sink)) {
166        sink.error(err);
167      } else {
168        console.warn(err);
169      }
170    }
171  }
172
173  forEach(next, promiseCtor) {
174    promiseCtor = getPromiseCtor(promiseCtor);
175    return new promiseCtor((resolve, reject) => {
176      let subscription;
177      subscription = this.subscribe(value => {
178        try {
179          next(value);
180        } catch (err) {
181          reject(err);
182
183          if (subscription) {
184            subscription.unsubscribe();
185          }
186        }
187      }, reject, resolve);
188    });
189  }
190
191  _subscribe(subscriber) {
192    const {
193      source
194    } = this;
195    return source && source.subscribe(subscriber);
196  }
197
198  [_symbol_observable__WEBPACK_IMPORTED_MODULE_3__.observable]() {
199    return this;
200  }
201
202  pipe(...operations) {
203    if (operations.length === 0) {
204      return this;
205    }
206
207    return (0,_util_pipe__WEBPACK_IMPORTED_MODULE_4__.pipeFromArray)(operations)(this);
208  }
209
210  toPromise(promiseCtor) {
211    promiseCtor = getPromiseCtor(promiseCtor);
212    return new promiseCtor((resolve, reject) => {
213      let value;
214      this.subscribe(x => value = x, err => reject(err), () => resolve(value));
215    });
216  }
217
218}
219
220Observable.create = subscribe => {
221  return new Observable(subscribe);
222};
223
224function getPromiseCtor(promiseCtor) {
225  if (!promiseCtor) {
226    promiseCtor = _config__WEBPACK_IMPORTED_MODULE_1__.config.Promise || Promise;
227  }
228
229  if (!promiseCtor) {
230    throw new Error('no Promise impl found');
231  }
232
233  return promiseCtor;
234}
235
236/***/ }),
237
238/***/ 9957:
239/*!*********************************************************!*\
240  !*** ./node_modules/rxjs/_esm2015/internal/Observer.js ***!
241  \*********************************************************/
242/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
243
244__webpack_require__.r(__webpack_exports__);
245/* harmony export */ __webpack_require__.d(__webpack_exports__, {
246/* harmony export */   "empty": () => (/* binding */ empty)
247/* harmony export */ });
248/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./config */ 146);
249/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/hostReportError */ 8897);
250
251
252const empty = {
253  closed: true,
254
255  next(value) {},
256
257  error(err) {
258    if (_config__WEBPACK_IMPORTED_MODULE_0__.config.useDeprecatedSynchronousErrorHandling) {
259      throw err;
260    } else {
261      (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_1__.hostReportError)(err);
262    }
263  },
264
265  complete() {}
266
267};
268
269/***/ }),
270
271/***/ 5266:
272/*!****************************************************************!*\
273  !*** ./node_modules/rxjs/_esm2015/internal/OuterSubscriber.js ***!
274  \****************************************************************/
275/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
276
277__webpack_require__.r(__webpack_exports__);
278/* harmony export */ __webpack_require__.d(__webpack_exports__, {
279/* harmony export */   "OuterSubscriber": () => (/* binding */ OuterSubscriber)
280/* harmony export */ });
281/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subscriber */ 14);
282
283class OuterSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
284  notifyNext(outerValue, innerValue, outerIndex, innerIndex, innerSub) {
285    this.destination.next(innerValue);
286  }
287
288  notifyError(error, innerSub) {
289    this.destination.error(error);
290  }
291
292  notifyComplete(innerSub) {
293    this.destination.complete();
294  }
295
296}
297
298/***/ }),
299
300/***/ 2218:
301/*!********************************************************!*\
302  !*** ./node_modules/rxjs/_esm2015/internal/Subject.js ***!
303  \********************************************************/
304/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
305
306__webpack_require__.r(__webpack_exports__);
307/* harmony export */ __webpack_require__.d(__webpack_exports__, {
308/* harmony export */   "AnonymousSubject": () => (/* binding */ AnonymousSubject),
309/* harmony export */   "Subject": () => (/* binding */ Subject),
310/* harmony export */   "SubjectSubscriber": () => (/* binding */ SubjectSubscriber)
311/* harmony export */ });
312/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Observable */ 2378);
313/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subscriber */ 14);
314/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Subscription */ 2425);
315/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./util/ObjectUnsubscribedError */ 9086);
316/* harmony import */ var _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./SubjectSubscription */ 1722);
317/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal/symbol/rxSubscriber */ 1482);
318
319
320
321
322
323
324class SubjectSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
325  constructor(destination) {
326    super(destination);
327    this.destination = destination;
328  }
329
330}
331class Subject extends _Observable__WEBPACK_IMPORTED_MODULE_1__.Observable {
332  constructor() {
333    super();
334    this.observers = [];
335    this.closed = false;
336    this.isStopped = false;
337    this.hasError = false;
338    this.thrownError = null;
339  }
340
341  [_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__.rxSubscriber]() {
342    return new SubjectSubscriber(this);
343  }
344
345  lift(operator) {
346    const subject = new AnonymousSubject(this, this);
347    subject.operator = operator;
348    return subject;
349  }
350
351  next(value) {
352    if (this.closed) {
353      throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__.ObjectUnsubscribedError();
354    }
355
356    if (!this.isStopped) {
357      const {
358        observers
359      } = this;
360      const len = observers.length;
361      const copy = observers.slice();
362
363      for (let i = 0; i < len; i++) {
364        copy[i].next(value);
365      }
366    }
367  }
368
369  error(err) {
370    if (this.closed) {
371      throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__.ObjectUnsubscribedError();
372    }
373
374    this.hasError = true;
375    this.thrownError = err;
376    this.isStopped = true;
377    const {
378      observers
379    } = this;
380    const len = observers.length;
381    const copy = observers.slice();
382
383    for (let i = 0; i < len; i++) {
384      copy[i].error(err);
385    }
386
387    this.observers.length = 0;
388  }
389
390  complete() {
391    if (this.closed) {
392      throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__.ObjectUnsubscribedError();
393    }
394
395    this.isStopped = true;
396    const {
397      observers
398    } = this;
399    const len = observers.length;
400    const copy = observers.slice();
401
402    for (let i = 0; i < len; i++) {
403      copy[i].complete();
404    }
405
406    this.observers.length = 0;
407  }
408
409  unsubscribe() {
410    this.isStopped = true;
411    this.closed = true;
412    this.observers = null;
413  }
414
415  _trySubscribe(subscriber) {
416    if (this.closed) {
417      throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__.ObjectUnsubscribedError();
418    } else {
419      return super._trySubscribe(subscriber);
420    }
421  }
422
423  _subscribe(subscriber) {
424    if (this.closed) {
425      throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__.ObjectUnsubscribedError();
426    } else if (this.hasError) {
427      subscriber.error(this.thrownError);
428      return _Subscription__WEBPACK_IMPORTED_MODULE_4__.Subscription.EMPTY;
429    } else if (this.isStopped) {
430      subscriber.complete();
431      return _Subscription__WEBPACK_IMPORTED_MODULE_4__.Subscription.EMPTY;
432    } else {
433      this.observers.push(subscriber);
434      return new _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__.SubjectSubscription(this, subscriber);
435    }
436  }
437
438  asObservable() {
439    const observable = new _Observable__WEBPACK_IMPORTED_MODULE_1__.Observable();
440    observable.source = this;
441    return observable;
442  }
443
444}
445
446Subject.create = (destination, source) => {
447  return new AnonymousSubject(destination, source);
448};
449
450class AnonymousSubject extends Subject {
451  constructor(destination, source) {
452    super();
453    this.destination = destination;
454    this.source = source;
455  }
456
457  next(value) {
458    const {
459      destination
460    } = this;
461
462    if (destination && destination.next) {
463      destination.next(value);
464    }
465  }
466
467  error(err) {
468    const {
469      destination
470    } = this;
471
472    if (destination && destination.error) {
473      this.destination.error(err);
474    }
475  }
476
477  complete() {
478    const {
479      destination
480    } = this;
481
482    if (destination && destination.complete) {
483      this.destination.complete();
484    }
485  }
486
487  _subscribe(subscriber) {
488    const {
489      source
490    } = this;
491
492    if (source) {
493      return this.source.subscribe(subscriber);
494    } else {
495      return _Subscription__WEBPACK_IMPORTED_MODULE_4__.Subscription.EMPTY;
496    }
497  }
498
499}
500
501/***/ }),
502
503/***/ 1722:
504/*!********************************************************************!*\
505  !*** ./node_modules/rxjs/_esm2015/internal/SubjectSubscription.js ***!
506  \********************************************************************/
507/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
508
509__webpack_require__.r(__webpack_exports__);
510/* harmony export */ __webpack_require__.d(__webpack_exports__, {
511/* harmony export */   "SubjectSubscription": () => (/* binding */ SubjectSubscription)
512/* harmony export */ });
513/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subscription */ 2425);
514
515class SubjectSubscription extends _Subscription__WEBPACK_IMPORTED_MODULE_0__.Subscription {
516  constructor(subject, subscriber) {
517    super();
518    this.subject = subject;
519    this.subscriber = subscriber;
520    this.closed = false;
vendor: 4,328 bytes, lines 521-682
521  }
522
523  unsubscribe() {
524    if (this.closed) {
525      return;
526    }
527
528    this.closed = true;
529    const subject = this.subject;
530    const observers = subject.observers;
531    this.subject = null;
532
533    if (!observers || observers.length === 0 || subject.isStopped || subject.closed) {
534      return;
535    }
536
537    const subscriberIndex = observers.indexOf(this.subscriber);
538
539    if (subscriberIndex !== -1) {
540      observers.splice(subscriberIndex, 1);
541    }
542  }
543
544}
545
546/***/ }),
547
548/***/ 14:
549/*!***********************************************************!*\
550  !*** ./node_modules/rxjs/_esm2015/internal/Subscriber.js ***!
551  \***********************************************************/
552/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
553
554__webpack_require__.r(__webpack_exports__);
555/* harmony export */ __webpack_require__.d(__webpack_exports__, {
556/* harmony export */   "SafeSubscriber": () => (/* binding */ SafeSubscriber),
557/* harmony export */   "Subscriber": () => (/* binding */ Subscriber)
558/* harmony export */ });
559/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./util/isFunction */ 1900);
560/* harmony import */ var _Observer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Observer */ 9957);
561/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subscription */ 2425);
562/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal/symbol/rxSubscriber */ 1482);
563/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./config */ 146);
564/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./util/hostReportError */ 8897);
565
566
567
568
569
570
571class Subscriber extends _Subscription__WEBPACK_IMPORTED_MODULE_0__.Subscription {
572  constructor(destinationOrNext, error, complete) {
573    super();
574    this.syncErrorValue = null;
575    this.syncErrorThrown = false;
576    this.syncErrorThrowable = false;
577    this.isStopped = false;
578
579    switch (arguments.length) {
580      case 0:
581        this.destination = _Observer__WEBPACK_IMPORTED_MODULE_1__.empty;
582        break;
583
584      case 1:
585        if (!destinationOrNext) {
586          this.destination = _Observer__WEBPACK_IMPORTED_MODULE_1__.empty;
587          break;
588        }
589
590        if (typeof destinationOrNext === 'object') {
591          if (destinationOrNext instanceof Subscriber) {
592            this.syncErrorThrowable = destinationOrNext.syncErrorThrowable;
593            this.destination = destinationOrNext;
594            destinationOrNext.add(this);
595          } else {
596            this.syncErrorThrowable = true;
597            this.destination = new SafeSubscriber(this, destinationOrNext);
598          }
599
600          break;
601        }
602
603      default:
604        this.syncErrorThrowable = true;
605        this.destination = new SafeSubscriber(this, destinationOrNext, error, complete);
606        break;
607    }
608  }
609
610  [_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__.rxSubscriber]() {
611    return this;
612  }
613
614  static create(next, error, complete) {
615    const subscriber = new Subscriber(next, error, complete);
616    subscriber.syncErrorThrowable = false;
617    return subscriber;
618  }
619
620  next(value) {
621    if (!this.isStopped) {
622      this._next(value);
623    }
624  }
625
626  error(err) {
627    if (!this.isStopped) {
628      this.isStopped = true;
629
630      this._error(err);
631    }
632  }
633
634  complete() {
635    if (!this.isStopped) {
636      this.isStopped = true;
637
638      this._complete();
639    }
640  }
641
642  unsubscribe() {
643    if (this.closed) {
644      return;
645    }
646
647    this.isStopped = true;
648    super.unsubscribe();
649  }
650
651  _next(value) {
652    this.destination.next(value);
653  }
654
655  _error(err) {
656    this.destination.error(err);
657    this.unsubscribe();
658  }
659
660  _complete() {
661    this.destination.complete();
662    this.unsubscribe();
663  }
664
665  _unsubscribeAndRecycle() {
666    const {
667      _parentOrParents
668    } = this;
669    this._parentOrParents = null;
670    this.unsubscribe();
671    this.closed = false;
672    this.isStopped = false;
673    this._parentOrParents = _parentOrParents;
674    return this;
675  }
676
677}
678class SafeSubscriber extends Subscriber {
679  constructor(_parentSubscriber, observerOrNext, error, complete) {
680    super();
681    this._parentSubscriber = _parentSubscriber;
682    let next;
683    let context = this;
684
685    if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_3__.isFunction)(observerOrNext)) {
686      next = observerOrNext;
687    } else if (observerOrNext) {
688      next = observerOrNext.next;
689      error = observerOrNext.error;
690      complete = observerOrNext.complete;
691
692      if (observerOrNext !== _Observer__WEBPACK_IMPORTED_MODULE_1__.empty) {
693        context = Object.create(observerOrNext);
694
695        if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_3__.isFunction)(context.unsubscribe)) {
696          this.add(context.unsubscribe.bind(context));
697        }
698
699        context.unsubscribe = this.unsubscribe.bind(this);
700      }
701    }
702
703    this._context = context;
704    this._next = next;
705    this._error = error;
706    this._complete = complete;
707  }
708
709  next(value) {
710    if (!this.isStopped && this._next) {
711      const {
712        _parentSubscriber
713      } = this;
714
715      if (!_config__WEBPACK_IMPORTED_MODULE_4__.config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) {
716        this.__tryOrUnsub(this._next, value);
717      } else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) {
718        this.unsubscribe();
719      }
720    }
721  }
722
723  error(err) {
724    if (!this.isStopped) {
725      const {
726        _parentSubscriber
727      } = this;
728      const {
729        useDeprecatedSynchronousErrorHandling
730      } = _config__WEBPACK_IMPORTED_MODULE_4__.config;
731
732      if (this._error) {
733        if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) {
734          this.__tryOrUnsub(this._error, err);
735
736          this.unsubscribe();
737        } else {
738          this.__tryOrSetError(_parentSubscriber, this._error, err);
739
740          this.unsubscribe();
741        }
742      } else if (!_parentSubscriber.syncErrorThrowable) {
743        this.unsubscribe();
744
745        if (useDeprecatedSynchronousErrorHandling) {
746          throw err;
747        }
748
749        (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_5__.hostReportError)(err);
750      } else {
751        if (useDeprecatedSynchronousErrorHandling) {
752          _parentSubscriber.syncErrorValue = err;
753          _parentSubscriber.syncErrorThrown = true;
754        } else {
755          (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_5__.hostReportError)(err);
756        }
757
758        this.unsubscribe();
759      }
760    }
761  }
762
763  complete() {
764    if (!this.isStopped) {
765      const {
766        _parentSubscriber
767      } = this;
768
769      if (this._complete) {
770        const wrappedComplete = () => this._complete.call(this._context);
771
772        if (!_config__WEBPACK_IMPORTED_MODULE_4__.config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) {
773          this.__tryOrUnsub(wrappedComplete);
774
775          this.unsubscribe();
776        } else {
777          this.__tryOrSetError(_parentSubscriber, wrappedComplete);
778
779          this.unsubscribe();
780        }
781      } else {
782        this.unsubscribe();
783      }
784    }
785  }
786
787  __tryOrUnsub(fn, value) {
788    try {
789      fn.call(this._context, value);
790    } catch (err) {
791      this.unsubscribe();
792
793      if (_config__WEBPACK_IMPORTED_MODULE_4__.config.useDeprecatedSynchronousErrorHandling) {
794        throw err;
795      } else {
796        (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_5__.hostReportError)(err);
797      }
798    }
799  }
800
801  __tryOrSetError(parent, fn, value) {
802    if (!_config__WEBPACK_IMPORTED_MODULE_4__.config.useDeprecatedSynchronousErrorHandling) {
803      throw new Error('bad call');
804    }
805
806    try {
807      fn.call(this._context, value);
808    } catch (err) {
809      if (_config__WEBPACK_IMPORTED_MODULE_4__.config.useDeprecatedSynchronousErrorHandling) {
810        parent.syncErrorValue = err;
811        parent.syncErrorThrown = true;
812        return true;
813      } else {
814        (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_5__.hostReportError)(err);
815        return true;
816      }
817    }
818
819    return false;
820  }
821
822  _unsubscribe() {
823    const {
824      _parentSubscriber
825    } = this;
826    this._context = null;
827    this._parentSubscriber = null;
828
829    _parentSubscriber.unsubscribe();
830  }
831
832}
833
834/***/ }),
835
836/***/ 2425:
837/*!*************************************************************!*\
838  !*** ./node_modules/rxjs/_esm2015/internal/Subscription.js ***!
839  \*************************************************************/
840/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
841
842__webpack_require__.r(__webpack_exports__);
843/* harmony export */ __webpack_require__.d(__webpack_exports__, {
844/* harmony export */   "Subscription": () => (/* binding */ Subscription)
845/* harmony export */ });
846/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/isArray */ 4327);
847/* harmony import */ var _util_isObject__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./util/isObject */ 6549);
848/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util/isFunction */ 1900);
849/* harmony import */ var _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/UnsubscriptionError */ 7875);
850
851
852
853
854class Subscription {
855  constructor(unsubscribe) {
856    this.closed = false;
vendor: 4,639 bytes, lines 857-1027
857    this._parentOrParents = null;
858    this._subscriptions = null;
859
860    if (unsubscribe) {
861      this._ctorUnsubscribe = true;
862      this._unsubscribe = unsubscribe;
863    }
864  }
865
866  unsubscribe() {
867    let errors;
868
869    if (this.closed) {
870      return;
871    }
872
873    let {
874      _parentOrParents,
875      _ctorUnsubscribe,
876      _unsubscribe,
877      _subscriptions
878    } = this;
879    this.closed = true;
880    this._parentOrParents = null;
881    this._subscriptions = null;
882
883    if (_parentOrParents instanceof Subscription) {
884      _parentOrParents.remove(this);
885    } else if (_parentOrParents !== null) {
886      for (let index = 0; index < _parentOrParents.length; ++index) {
887        const parent = _parentOrParents[index];
888        parent.remove(this);
889      }
890    }
891
892    if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(_unsubscribe)) {
893      if (_ctorUnsubscribe) {
894        this._unsubscribe = undefined;
895      }
896
897      try {
898        _unsubscribe.call(this);
899      } catch (e) {
900        errors = e instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_1__.UnsubscriptionError ? flattenUnsubscriptionErrors(e.errors) : [e];
901      }
902    }
903
904    if ((0,_util_isArray__WEBPACK_IMPORTED_MODULE_2__.isArray)(_subscriptions)) {
905      let index = -1;
906      let len = _subscriptions.length;
907
908      while (++index < len) {
909        const sub = _subscriptions[index];
910
911        if ((0,_util_isObject__WEBPACK_IMPORTED_MODULE_3__.isObject)(sub)) {
912          try {
913            sub.unsubscribe();
914          } catch (e) {
915            errors = errors || [];
916
917            if (e instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_1__.UnsubscriptionError) {
918              errors = errors.concat(flattenUnsubscriptionErrors(e.errors));
919            } else {
920              errors.push(e);
921            }
922          }
923        }
924      }
925    }
926
927    if (errors) {
928      throw new _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_1__.UnsubscriptionError(errors);
929    }
930  }
931
932  add(teardown) {
933    let subscription = teardown;
934
935    if (!teardown) {
936      return Subscription.EMPTY;
937    }
938
939    switch (typeof teardown) {
940      case 'function':
941        subscription = new Subscription(teardown);
942
943      case 'object':
944        if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') {
945          return subscription;
946        } else if (this.closed) {
947          subscription.unsubscribe();
948          return subscription;
949        } else if (!(subscription instanceof Subscription)) {
950          const tmp = subscription;
951          subscription = new Subscription();
952          subscription._subscriptions = [tmp];
953        }
954
955        break;
956
957      default:
958        {
959          throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.');
960        }
961    }
962
963    let {
964      _parentOrParents
965    } = subscription;
966
967    if (_parentOrParents === null) {
968      subscription._parentOrParents = this;
969    } else if (_parentOrParents instanceof Subscription) {
970      if (_parentOrParents === this) {
971        return subscription;
972      }
973
974      subscription._parentOrParents = [_parentOrParents, this];
975    } else if (_parentOrParents.indexOf(this) === -1) {
976      _parentOrParents.push(this);
977    } else {
978      return subscription;
979    }
980
981    const subscriptions = this._subscriptions;
982
983    if (subscriptions === null) {
984      this._subscriptions = [subscription];
985    } else {
986      subscriptions.push(subscription);
987    }
988
989    return subscription;
990  }
991
992  remove(subscription) {
993    const subscriptions = this._subscriptions;
994
995    if (subscriptions) {
996      const subscriptionIndex = subscriptions.indexOf(subscription);
997
998      if (subscriptionIndex !== -1) {
999        subscriptions.splice(subscriptionIndex, 1);
1000      }
1001    }
1002  }
1003
1004}
1005
1006Subscription.EMPTY = function (empty) {
1007  empty.closed = true;
1008  return empty;
1009}(new Subscription());
1010
1011function flattenUnsubscriptionErrors(errors) {
1012  return errors.reduce((errs, err) => errs.concat(err instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_1__.UnsubscriptionError ? err.errors : err), []);
1013}
1014
1015/***/ }),
1016
1017/***/ 146:
1018/*!*******************************************************!*\
1019  !*** ./node_modules/rxjs/_esm2015/internal/config.js ***!
1020  \*******************************************************/
1021/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1022
1023__webpack_require__.r(__webpack_exports__);
1024/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1025/* harmony export */   "config": () => (/* binding */ config)
1026/* harmony export */ });
1027let _enable_super_gross_mode_that_will_cause_bad_things = false;
1028const config = {
1029  Promise: undefined,
1030
1031  set useDeprecatedSynchronousErrorHandling(value) {
1032    if (value) {
1033      const error = new Error();
1034      console.warn('DEPRECATED! RxJS was set to use deprecated synchronous error handling behavior by code at: \n' + error.stack);
1035    } else if (_enable_super_gross_mode_that_will_cause_bad_things) {
1036      console.log('RxJS: Back to a better error behavior. Thank you. <3');
1037    }
1038
1039    _enable_super_gross_mode_that_will_cause_bad_things = value;
1040  },
1041
1042  get useDeprecatedSynchronousErrorHandling() {
1043    return _enable_super_gross_mode_that_will_cause_bad_things;
1044  }
1045
1046};
1047
1048/***/ }),
1049
1050/***/ 2831:
1051/*!***************************************************************!*\
1052  !*** ./node_modules/rxjs/_esm2015/internal/innerSubscribe.js ***!
1053  \***************************************************************/
1054/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1055
1056__webpack_require__.r(__webpack_exports__);
1057/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1058/* harmony export */   "ComplexInnerSubscriber": () => (/* binding */ ComplexInnerSubscriber),
1059/* harmony export */   "ComplexOuterSubscriber": () => (/* binding */ ComplexOuterSubscriber),
1060/* harmony export */   "SimpleInnerSubscriber": () => (/* binding */ SimpleInnerSubscriber),
1061/* harmony export */   "SimpleOuterSubscriber": () => (/* binding */ SimpleOuterSubscriber),
1062/* harmony export */   "innerSubscribe": () => (/* binding */ innerSubscribe)
1063/* harmony export */ });
1064/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subscriber */ 14);
1065/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Observable */ 2378);
1066/* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/subscribeTo */ 6983);
1067
1068
1069
1070class SimpleInnerSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
1071  constructor(parent) {
1072    super();
1073    this.parent = parent;
1074  }
1075
1076  _next(value) {
1077    this.parent.notifyNext(value);
1078  }
1079
1080  _error(error) {
1081    this.parent.notifyError(error);
1082    this.unsubscribe();
1083  }
1084
1085  _complete() {
1086    this.parent.notifyComplete();
1087    this.unsubscribe();
1088  }
1089
1090}
1091class ComplexInnerSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
1092  constructor(parent, outerValue, outerIndex) {
1093    super();
1094    this.parent = parent;
1095    this.outerValue = outerValue;
1096    this.outerIndex = outerIndex;
1097  }
1098
1099  _next(value) {
1100    this.parent.notifyNext(this.outerValue, value, this.outerIndex, this);
1101  }
1102
1103  _error(error) {
1104    this.parent.notifyError(error);
1105    this.unsubscribe();
1106  }
1107
1108  _complete() {
1109    this.parent.notifyComplete(this);
1110    this.unsubscribe();
1111  }
1112
1113}
1114class SimpleOuterSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
1115  notifyNext(innerValue) {
1116    this.destination.next(innerValue);
1117  }
1118
1119  notifyError(err) {
1120    this.destination.error(err);
1121  }
1122
1123  notifyComplete() {
1124    this.destination.complete();
1125  }
1126
1127}
1128class ComplexOuterSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
1129  notifyNext(_outerValue, innerValue, _outerIndex, _innerSub) {
1130    this.destination.next(innerValue);
1131  }
1132
1133  notifyError(error) {
1134    this.destination.error(error);
1135  }
1136
1137  notifyComplete(_innerSub) {
1138    this.destination.complete();
1139  }
1140
1141}
1142function innerSubscribe(result, innerSubscriber) {
1143  if (innerSubscriber.closed) {
1144    return undefined;
1145  }
1146
1147  if (result instanceof _Observable__WEBPACK_IMPORTED_MODULE_1__.Observable) {
1148    return result.subscribe(innerSubscriber);
1149  }
1150
1151  return (0,_util_subscribeTo__WEBPACK_IMPORTED_MODULE_2__.subscribeTo)(result)(innerSubscriber);
1152}
1153
1154/***/ }),
1155
1156/***/ 4483:
1157/*!*********************************************************************************!*\
1158  !*** ./node_modules/rxjs/_esm2015/internal/observable/ConnectableObservable.js ***!
1159  \*********************************************************************************/
1160/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1161
1162__webpack_require__.r(__webpack_exports__);
1163/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1164/* harmony export */   "ConnectableObservable": () => (/* binding */ ConnectableObservable),
1165/* harmony export */   "connectableObservableDescriptor": () => (/* binding */ connectableObservableDescriptor)
1166/* harmony export */ });
1167/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Subject */ 2218);
1168/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
1169/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Subscriber */ 14);
1170/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Subscription */ 2425);
1171/* harmony import */ var _operators_refCount__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../operators/refCount */ 8331);
1172
1173
1174
1175
1176
1177class ConnectableObservable extends _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable {
1178  constructor(source, subjectFactory) {
1179    super();
1180    this.source = source;
1181    this.subjectFactory = subjectFactory;
1182    this._refCount = 0;
1183    this._isComplete = false;
vendor: 4,258 bytes, lines 1184-1374
1184  }
1185
1186  _subscribe(subscriber) {
1187    return this.getSubject().subscribe(subscriber);
1188  }
1189
1190  getSubject() {
1191    const subject = this._subject;
1192
1193    if (!subject || subject.isStopped) {
1194      this._subject = this.subjectFactory();
1195    }
1196
1197    return this._subject;
1198  }
1199
1200  connect() {
1201    let connection = this._connection;
1202
1203    if (!connection) {
1204      this._isComplete = false;
1205      connection = this._connection = new _Subscription__WEBPACK_IMPORTED_MODULE_1__.Subscription();
1206      connection.add(this.source.subscribe(new ConnectableSubscriber(this.getSubject(), this)));
1207
1208      if (connection.closed) {
1209        this._connection = null;
1210        connection = _Subscription__WEBPACK_IMPORTED_MODULE_1__.Subscription.EMPTY;
1211      }
1212    }
1213
1214    return connection;
1215  }
1216
1217  refCount() {
1218    return (0,_operators_refCount__WEBPACK_IMPORTED_MODULE_2__.refCount)()(this);
1219  }
1220
1221}
1222const connectableObservableDescriptor = (() => {
1223  const connectableProto = ConnectableObservable.prototype;
1224  return {
1225    operator: {
1226      value: null
1227    },
1228    _refCount: {
1229      value: 0,
1230      writable: true
1231    },
1232    _subject: {
1233      value: null,
1234      writable: true
1235    },
1236    _connection: {
1237      value: null,
1238      writable: true
1239    },
1240    _subscribe: {
1241      value: connectableProto._subscribe
1242    },
1243    _isComplete: {
1244      value: connectableProto._isComplete,
1245      writable: true
1246    },
1247    getSubject: {
1248      value: connectableProto.getSubject
1249    },
1250    connect: {
1251      value: connectableProto.connect
1252    },
1253    refCount: {
1254      value: connectableProto.refCount
1255    }
1256  };
1257})();
1258
1259class ConnectableSubscriber extends _Subject__WEBPACK_IMPORTED_MODULE_3__.SubjectSubscriber {
1260  constructor(destination, connectable) {
1261    super(destination);
1262    this.connectable = connectable;
1263  }
1264
1265  _error(err) {
1266    this._unsubscribe();
1267
1268    super._error(err);
1269  }
1270
1271  _complete() {
1272    this.connectable._isComplete = true;
1273
1274    this._unsubscribe();
1275
1276    super._complete();
1277  }
1278
1279  _unsubscribe() {
1280    const connectable = this.connectable;
1281
1282    if (connectable) {
1283      this.connectable = null;
1284      const connection = connectable._connection;
1285      connectable._refCount = 0;
1286      connectable._subject = null;
1287      connectable._connection = null;
1288
1289      if (connection) {
1290        connection.unsubscribe();
1291      }
1292    }
1293  }
1294
1295}
1296
1297class RefCountOperator {
1298  constructor(connectable) {
1299    this.connectable = connectable;
1300  }
1301
1302  call(subscriber, source) {
1303    const {
1304      connectable
1305    } = this;
1306    connectable._refCount++;
1307    const refCounter = new RefCountSubscriber(subscriber, connectable);
1308    const subscription = source.subscribe(refCounter);
1309
1310    if (!refCounter.closed) {
1311      refCounter.connection = connectable.connect();
1312    }
1313
1314    return subscription;
1315  }
1316
1317}
1318
1319class RefCountSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_4__.Subscriber {
1320  constructor(destination, connectable) {
1321    super(destination);
1322    this.connectable = connectable;
1323  }
1324
1325  _unsubscribe() {
1326    const {
1327      connectable
1328    } = this;
1329
1330    if (!connectable) {
1331      this.connection = null;
1332      return;
1333    }
1334
1335    this.connectable = null;
1336    const refCount = connectable._refCount;
1337
1338    if (refCount <= 0) {
1339      this.connection = null;
1340      return;
1341    }
1342
1343    connectable._refCount = refCount - 1;
1344
1345    if (refCount > 1) {
1346      this.connection = null;
1347      return;
1348    }
1349
1350    const {
1351      connection
1352    } = this;
1353    const sharedConnection = connectable._connection;
1354    this.connection = null;
1355
1356    if (sharedConnection && (!connection || sharedConnection === connection)) {
1357      sharedConnection.unsubscribe();
1358    }
1359  }
1360
1361}
1362
1363/***/ }),
1364
1365/***/ 9193:
1366/*!*************************************************************************!*\
1367  !*** ./node_modules/rxjs/_esm2015/internal/observable/combineLatest.js ***!
1368  \*************************************************************************/
1369/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1370
1371__webpack_require__.r(__webpack_exports__);
1372/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1373/* harmony export */   "CombineLatestOperator": () => (/* binding */ CombineLatestOperator),
1374/* harmony export */   "CombineLatestSubscriber": () => (/* binding */ CombineLatestSubscriber),
1375/* harmony export */   "combineLatest": () => (/* binding */ combineLatest)
1376/* harmony export */ });
1377/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isScheduler */ 7507);
1378/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/isArray */ 4327);
1379/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../OuterSubscriber */ 5266);
1380/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../util/subscribeToResult */ 640);
1381/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fromArray */ 8005);
1382
1383
1384
1385
1386
1387const NONE = {};
1388function combineLatest(...observables) {
1389  let resultSelector = undefined;
1390  let scheduler = undefined;
1391
1392  if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__.isScheduler)(observables[observables.length - 1])) {
1393    scheduler = observables.pop();
1394  }
1395
1396  if (typeof observables[observables.length - 1] === 'function') {
1397    resultSelector = observables.pop();
1398  }
1399
1400  if (observables.length === 1 && (0,_util_isArray__WEBPACK_IMPORTED_MODULE_1__.isArray)(observables[0])) {
1401    observables = observables[0];
1402  }
1403
1404  return (0,_fromArray__WEBPACK_IMPORTED_MODULE_2__.fromArray)(observables, scheduler).lift(new CombineLatestOperator(resultSelector));
1405}
1406class CombineLatestOperator {
1407  constructor(resultSelector) {
1408    this.resultSelector = resultSelector;
1409  }
1410
1411  call(subscriber, source) {
1412    return source.subscribe(new CombineLatestSubscriber(subscriber, this.resultSelector));
1413  }
1414
1415}
1416class CombineLatestSubscriber extends _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__.OuterSubscriber {
1417  constructor(destination, resultSelector) {
1418    super(destination);
1419    this.resultSelector = resultSelector;
1420    this.active = 0;
1421    this.values = [];
1422    this.observables = [];
1423  }
1424
1425  _next(observable) {
1426    this.values.push(NONE);
1427    this.observables.push(observable);
1428  }
1429
1430  _complete() {
1431    const observables = this.observables;
1432    const len = observables.length;
1433
1434    if (len === 0) {
1435      this.destination.complete();
1436    } else {
1437      this.active = len;
1438      this.toRespond = len;
1439
1440      for (let i = 0; i < len; i++) {
1441        const observable = observables[i];
1442        this.add((0,_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__.subscribeToResult)(this, observable, undefined, i));
1443      }
1444    }
1445  }
1446
1447  notifyComplete(unused) {
1448    if ((this.active -= 1) === 0) {
1449      this.destination.complete();
1450    }
1451  }
1452
1453  notifyNext(_outerValue, innerValue, outerIndex) {
1454    const values = this.values;
1455    const oldVal = values[outerIndex];
1456    const toRespond = !this.toRespond ? 0 : oldVal === NONE ? --this.toRespond : this.toRespond;
1457    values[outerIndex] = innerValue;
1458
1459    if (toRespond === 0) {
1460      if (this.resultSelector) {
1461        this._tryResultSelector(values);
1462      } else {
1463        this.destination.next(values.slice());
1464      }
1465    }
1466  }
1467
1468  _tryResultSelector(values) {
1469    let result;
1470
1471    try {
1472      result = this.resultSelector.apply(this, values);
1473    } catch (err) {
1474      this.destination.error(err);
1475      return;
1476    }
1477
1478    this.destination.next(result);
1479  }
1480
1481}
1482
1483/***/ }),
1484
1485/***/ 5828:
1486/*!******************************************************************!*\
1487  !*** ./node_modules/rxjs/_esm2015/internal/observable/concat.js ***!
1488  \******************************************************************/
1489/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1490
1491__webpack_require__.r(__webpack_exports__);
1492/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1493/* harmony export */   "concat": () => (/* binding */ concat)
1494/* harmony export */ });
1495/* harmony import */ var _of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./of */ 4139);
1496/* harmony import */ var _operators_concatAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../operators/concatAll */ 2692);
1497
1498
1499function concat(...observables) {
1500  return (0,_operators_concatAll__WEBPACK_IMPORTED_MODULE_0__.concatAll)()((0,_of__WEBPACK_IMPORTED_MODULE_1__.of)(...observables));
1501}
1502
1503/***/ }),
1504
1505/***/ 2160:
1506/*!*****************************************************************!*\
1507  !*** ./node_modules/rxjs/_esm2015/internal/observable/defer.js ***!
1508  \*****************************************************************/
1509/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1510
1511__webpack_require__.r(__webpack_exports__);
1512/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1513/* harmony export */   "defer": () => (/* binding */ defer)
1514/* harmony export */ });
1515/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
1516/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./from */ 4383);
1517/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./empty */ 6439);
1518
1519
1520
1521function defer(observableFactory) {
1522  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
1523    let input;
1524
1525    try {
1526      input = observableFactory();
1527    } catch (err) {
1528      subscriber.error(err);
1529      return undefined;
1530    }
1531
1532    const source = input ? (0,_from__WEBPACK_IMPORTED_MODULE_1__.from)(input) : (0,_empty__WEBPACK_IMPORTED_MODULE_2__.empty)();
1533    return source.subscribe(subscriber);
1534  });
1535}
1536
1537/***/ }),
1538
1539/***/ 6439:
1540/*!*****************************************************************!*\
1541  !*** ./node_modules/rxjs/_esm2015/internal/observable/empty.js ***!
1542  \*****************************************************************/
1543/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1544
1545__webpack_require__.r(__webpack_exports__);
1546/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1547/* harmony export */   "EMPTY": () => (/* binding */ EMPTY),
1548/* harmony export */   "empty": () => (/* binding */ empty)
1549/* harmony export */ });
1550/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
1551
1552const EMPTY = new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => subscriber.complete());
1553function empty(scheduler) {
1554  return scheduler ? emptyScheduled(scheduler) : EMPTY;
1555}
1556
1557function emptyScheduled(scheduler) {
1558  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => scheduler.schedule(() => subscriber.complete()));
1559}
1560
1561/***/ }),
1562
1563/***/ 4350:
1564/*!********************************************************************!*\
1565  !*** ./node_modules/rxjs/_esm2015/internal/observable/forkJoin.js ***!
1566  \********************************************************************/
1567/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1568
1569__webpack_require__.r(__webpack_exports__);
1570/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1571/* harmony export */   "forkJoin": () => (/* binding */ forkJoin)
1572/* harmony export */ });
1573/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Observable */ 2378);
1574/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isArray */ 4327);
1575/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../operators/map */ 6942);
1576/* harmony import */ var _util_isObject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/isObject */ 6549);
1577/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./from */ 4383);
1578
1579
1580
1581
1582
1583function forkJoin(...sources) {
1584  if (sources.length === 1) {
1585    const first = sources[0];
1586
1587    if ((0,_util_isArray__WEBPACK_IMPORTED_MODULE_0__.isArray)(first)) {
1588      return forkJoinInternal(first, null);
1589    }
1590
1591    if ((0,_util_isObject__WEBPACK_IMPORTED_MODULE_1__.isObject)(first) && Object.getPrototypeOf(first) === Object.prototype) {
1592      const keys = Object.keys(first);
1593      return forkJoinInternal(keys.map(key => first[key]), keys);
1594    }
1595  }
1596
1597  if (typeof sources[sources.length - 1] === 'function') {
1598    const resultSelector = sources.pop();
1599    sources = sources.length === 1 && (0,_util_isArray__WEBPACK_IMPORTED_MODULE_0__.isArray)(sources[0]) ? sources[0] : sources;
1600    return forkJoinInternal(sources, null).pipe((0,_operators_map__WEBPACK_IMPORTED_MODULE_2__.map)(args => resultSelector(...args)));
1601  }
1602
1603  return forkJoinInternal(sources, null);
1604}
1605
1606function forkJoinInternal(sources, keys) {
1607  return new _Observable__WEBPACK_IMPORTED_MODULE_3__.Observable(subscriber => {
1608    const len = sources.length;
1609
1610    if (len === 0) {
1611      subscriber.complete();
1612      return;
1613    }
1614
1615    const values = new Array(len);
1616    let completed = 0;
1617    let emitted = 0;
1618
1619    for (let i = 0; i < len; i++) {
1620      const source = (0,_from__WEBPACK_IMPORTED_MODULE_4__.from)(sources[i]);
1621      let hasValue = false;
1622      subscriber.add(source.subscribe({
1623        next: value => {
1624          if (!hasValue) {
1625            hasValue = true;
1626            emitted++;
1627          }
1628
1629          values[i] = value;
1630        },
1631        error: err => subscriber.error(err),
1632        complete: () => {
1633          completed++;
1634
1635          if (completed === len || !hasValue) {
1636            if (emitted === len) {
1637              subscriber.next(keys ? keys.reduce((result, key, i) => (result[key] = values[i], result), {}) : values);
1638            }
1639
1640            subscriber.complete();
1641          }
1642        }
1643      }));
1644    }
1645  });
1646}
1647
1648/***/ }),
1649
1650/***/ 4383:
1651/*!****************************************************************!*\
1652  !*** ./node_modules/rxjs/_esm2015/internal/observable/from.js ***!
1653  \****************************************************************/
1654/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1655
1656__webpack_require__.r(__webpack_exports__);
1657/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1658/* harmony export */   "from": () => (/* binding */ from)
1659/* harmony export */ });
1660/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
1661/* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/subscribeTo */ 6983);
1662/* harmony import */ var _scheduled_scheduled__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../scheduled/scheduled */ 2476);
1663
1664
1665
1666function from(input, scheduler) {
1667  if (!scheduler) {
1668    if (input instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable) {
1669      return input;
1670    }
1671
1672    return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable((0,_util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__.subscribeTo)(input));
1673  } else {
1674    return (0,_scheduled_scheduled__WEBPACK_IMPORTED_MODULE_2__.scheduled)(input, scheduler);
1675  }
1676}
1677
1678/***/ }),
1679
1680/***/ 8005:
1681/*!*********************************************************************!*\
1682  !*** ./node_modules/rxjs/_esm2015/internal/observable/fromArray.js ***!
1683  \*********************************************************************/
1684/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1685
1686__webpack_require__.r(__webpack_exports__);
1687/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1688/* harmony export */   "fromArray": () => (/* binding */ fromArray)
1689/* harmony export */ });
1690/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
1691/* harmony import */ var _util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/subscribeToArray */ 5414);
1692/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../scheduled/scheduleArray */ 8403);
1693
1694
1695
1696function fromArray(input, scheduler) {
1697  if (!scheduler) {
1698    return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable((0,_util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__.subscribeToArray)(input));
1699  } else {
1700    return (0,_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__.scheduleArray)(input, scheduler);
1701  }
1702}
1703
1704/***/ }),
1705
1706/***/ 6312:
1707/*!*********************************************************************!*\
1708  !*** ./node_modules/rxjs/_esm2015/internal/observable/fromEvent.js ***!
1709  \*********************************************************************/
1710/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1711
1712__webpack_require__.r(__webpack_exports__);
1713/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1714/* harmony export */   "fromEvent": () => (/* binding */ fromEvent)
1715/* harmony export */ });
1716/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Observable */ 2378);
1717/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/isArray */ 4327);
1718/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isFunction */ 1900);
1719/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../operators/map */ 6942);
1720
1721
1722
1723
1724
1725const toString = (() => Object.prototype.toString)();
1726
1727function fromEvent(target, eventName, options, resultSelector) {
1728  if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(options)) {
1729    resultSelector = options;
1730    options = undefined;
1731  }
1732
1733  if (resultSelector) {
1734    return fromEvent(target, eventName, options).pipe((0,_operators_map__WEBPACK_IMPORTED_MODULE_1__.map)(args => (0,_util_isArray__WEBPACK_IMPORTED_MODULE_2__.isArray)(args) ? resultSelector(...args) : resultSelector(args)));
1735  }
1736
1737  return new _Observable__WEBPACK_IMPORTED_MODULE_3__.Observable(subscriber => {
1738    function handler(e) {
1739      if (arguments.length > 1) {
1740        subscriber.next(Array.prototype.slice.call(arguments));
1741      } else {
1742        subscriber.next(e);
1743      }
1744    }
1745
1746    setupSubscription(target, eventName, handler, subscriber, options);
1747  });
1748}
1749
1750function setupSubscription(sourceObj, eventName, handler, subscriber, options) {
1751  let unsubscribe;
1752
1753  if (isEventTarget(sourceObj)) {
1754    const source = sourceObj;
1755    sourceObj.addEventListener(eventName, handler, options);
1756
1757    unsubscribe = () => source.removeEventListener(eventName, handler, options);
1758  } else if (isJQueryStyleEventEmitter(sourceObj)) {
1759    const source = sourceObj;
1760    sourceObj.on(eventName, handler);
1761
1762    unsubscribe = () => source.off(eventName, handler);
1763  } else if (isNodeStyleEventEmitter(sourceObj)) {
1764    const source = sourceObj;
1765    sourceObj.addListener(eventName, handler);
1766
1767    unsubscribe = () => source.removeListener(eventName, handler);
1768  } else if (sourceObj && sourceObj.length) {
1769    for (let i = 0, len = sourceObj.length; i < len; i++) {
1770      setupSubscription(sourceObj[i], eventName, handler, subscriber, options);
1771    }
1772  } else {
1773    throw new TypeError('Invalid event target');
1774  }
1775
1776  subscriber.add(unsubscribe);
1777}
1778
1779function isNodeStyleEventEmitter(sourceObj) {
1780  return sourceObj && typeof sourceObj.addListener === 'function' && typeof sourceObj.removeListener === 'function';
1781}
1782
1783function isJQueryStyleEventEmitter(sourceObj) {
1784  return sourceObj && typeof sourceObj.on === 'function' && typeof sourceObj.off === 'function';
1785}
1786
1787function isEventTarget(sourceObj) {
1788  return sourceObj && typeof sourceObj.addEventListener === 'function' && typeof sourceObj.removeEventListener === 'function';
1789}
1790
1791/***/ }),
1792
1793/***/ 8623:
1794/*!*****************************************************************!*\
1795  !*** ./node_modules/rxjs/_esm2015/internal/observable/merge.js ***!
1796  \*****************************************************************/
1797/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1798
1799__webpack_require__.r(__webpack_exports__);
1800/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1801/* harmony export */   "merge": () => (/* binding */ merge)
1802/* harmony export */ });
1803/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Observable */ 2378);
1804/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isScheduler */ 7507);
1805/* harmony import */ var _operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../operators/mergeAll */ 6675);
1806/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./fromArray */ 8005);
1807
1808
1809
1810
1811function merge(...observables) {
1812  let concurrent = Number.POSITIVE_INFINITY;
1813  let scheduler = null;
1814  let last = observables[observables.length - 1];
1815
1816  if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__.isScheduler)(last)) {
1817    scheduler = observables.pop();
1818
1819    if (observables.length > 1 && typeof observables[observables.length - 1] === 'number') {
1820      concurrent = observables.pop();
1821    }
1822  } else if (typeof last === 'number') {
1823    concurrent = observables.pop();
1824  }
1825
1826  if (scheduler === null && observables.length === 1 && observables[0] instanceof _Observable__WEBPACK_IMPORTED_MODULE_1__.Observable) {
1827    return observables[0];
1828  }
1829
1830  return (0,_operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__.mergeAll)(concurrent)((0,_fromArray__WEBPACK_IMPORTED_MODULE_3__.fromArray)(observables, scheduler));
1831}
1832
1833/***/ }),
1834
1835/***/ 4139:
1836/*!**************************************************************!*\
1837  !*** ./node_modules/rxjs/_esm2015/internal/observable/of.js ***!
1838  \**************************************************************/
1839/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1840
1841__webpack_require__.r(__webpack_exports__);
1842/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1843/* harmony export */   "of": () => (/* binding */ of)
1844/* harmony export */ });
1845/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isScheduler */ 7507);
1846/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fromArray */ 8005);
1847/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../scheduled/scheduleArray */ 8403);
1848
1849
1850
1851function of(...args) {
1852  let scheduler = args[args.length - 1];
1853
1854  if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__.isScheduler)(scheduler)) {
1855    args.pop();
1856    return (0,_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_1__.scheduleArray)(args, scheduler);
1857  } else {
1858    return (0,_fromArray__WEBPACK_IMPORTED_MODULE_2__.fromArray)(args);
1859  }
1860}
1861
1862/***/ }),
1863
1864/***/ 6587:
1865/*!**********************************************************************!*\
1866  !*** ./node_modules/rxjs/_esm2015/internal/observable/throwError.js ***!
1867  \**********************************************************************/
1868/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1869
1870__webpack_require__.r(__webpack_exports__);
1871/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1872/* harmony export */   "throwError": () => (/* binding */ throwError)
1873/* harmony export */ });
1874/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
1875
1876function throwError(error, scheduler) {
1877  if (!scheduler) {
1878    return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => subscriber.error(error));
1879  } else {
1880    return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber =>
1880 scheduler.schedule(dispatch, 0, {
1881      error,
1882      subscriber
1883    }));
1884  }
1885}
1886
1887function dispatch({
1888  error,
1889  subscriber
1890}) {
1891  subscriber.error(error);
1892}
1893
1894/***/ }),
1895
1896/***/ 7418:
1897/*!*********************************************************************!*\
1898  !*** ./node_modules/rxjs/_esm2015/internal/operators/catchError.js ***!
1899  \*********************************************************************/
1900/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1901
1902__webpack_require__.r(__webpack_exports__);
1903/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1904/* harmony export */   "catchError": () => (/* binding */ catchError)
1905/* harmony export */ });
1906/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../innerSubscribe */ 2831);
1907
1908function catchError(selector) {
1909  return function catchErrorOperatorFunction(source) {
1910    const operator = new CatchOperator(selector);
1911    const caught = source.lift(operator);
1912    return operator.caught = caught;
1913  };
1914}
1915
1916class CatchOperator {
1917  constructor(selector) {
1918    this.selector = selector;
1919  }
1920
1921  call(subscriber, source) {
1922    return source.subscribe(new CatchSubscriber(subscriber, this.selector, this.caught));
1923  }
1924
1925}
1926
1927class CatchSubscriber extends _innerSubscribe__WEBPACK_IMPORTED_MODULE_0__.SimpleOuterSubscriber {
1928  constructor(destination, selector, caught) {
1929    super(destination);
1930    this.selector = selector;
1931    this.caught = caught;
1932  }
1933
1934  error(err) {
1935    if (!this.isStopped) {
1936      let result;
1937
1938      try {
1939        result = this.selector(err, this.caught);
1940      } catch (err2) {
1941        super.error(err2);
1942        return;
1943      }
1944
1945      this._unsubscribeAndRecycle();
1946
1947      const innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_0__.SimpleInnerSubscriber(this);
1948      this.add(innerSubscriber);
1949      const innerSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_0__.innerSubscribe)(result, innerSubscriber);
1950
1951      if (innerSubscription !== innerSubscriber) {
1952        this.add(innerSubscription);
1953      }
1954    }
1955  }
1956
1957}
1958
1959/***/ }),
1960
1961/***/ 2692:
1962/*!********************************************************************!*\
1963  !*** ./node_modules/rxjs/_esm2015/internal/operators/concatAll.js ***!
1964  \********************************************************************/
1965/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1966
1967__webpack_require__.r(__webpack_exports__);
1968/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1969/* harmony export */   "concatAll": () => (/* binding */ concatAll)
1970/* harmony export */ });
1971/* harmony import */ var _mergeAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mergeAll */ 6675);
1972
1973function concatAll() {
1974  return (0,_mergeAll__WEBPACK_IMPORTED_MODULE_0__.mergeAll)(1);
1975}
1976
1977/***/ }),
1978
1979/***/ 1133:
1980/*!********************************************************************!*\
1981  !*** ./node_modules/rxjs/_esm2015/internal/operators/concatMap.js ***!
1982  \********************************************************************/
1983/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1984
1985__webpack_require__.r(__webpack_exports__);
1986/* harmony export */ __webpack_require__.d(__webpack_exports__, {
1987/* harmony export */   "concatMap": () => (/* binding */ concatMap)
1988/* harmony export */ });
1989/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mergeMap */ 522);
1990
1991function concatMap(project, resultSelector) {
1992  return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__.mergeMap)(project, resultSelector, 1);
1993}
1994
1995/***/ }),
1996
1997/***/ 9701:
1998/*!*************************************************************************!*\
1999  !*** ./node_modules/rxjs/_esm2015/internal/operators/defaultIfEmpty.js ***!
2000  \*************************************************************************/
2001/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2002
2003__webpack_require__.r(__webpack_exports__);
2004/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2005/* harmony export */   "defaultIfEmpty": () => (/* binding */ defaultIfEmpty)
2006/* harmony export */ });
2007/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
2008
2009function defaultIfEmpty(defaultValue = null) {
2010  return source =>
2010 source.lift(new DefaultIfEmptyOperator(defaultValue));
2011}
2012
2013class DefaultIfEmptyOperator {
2014  constructor(defaultValue) {
2015    this.defaultValue = defaultValue;
2016  }
2017
2018  call(subscriber, source) {
2019    return source.subscribe(new DefaultIfEmptySubscriber(subscriber, this.defaultValue));
2020  }
2021
2022}
2023
2024class DefaultIfEmptySubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
2025  constructor(destination, defaultValue) {
2026    super(destination);
2027    this.defaultValue = defaultValue;
2028    this.isEmpty = true;
2029  }
2030
2031  _next(value) {
2032    this.isEmpty = false;
2033    this.destination.next(value);
2034  }
2035
2036  _complete() {
2037    if (this.isEmpty) {
2038      this.destination.next(this.defaultValue);
2039    }
2040
2041    this.destination.complete();
2042  }
2043
2044}
2045
2046/***/ }),
2047
2048/***/ 9151:
2049/*!*****************************************************************!*\
2050  !*** ./node_modules/rxjs/_esm2015/internal/operators/filter.js ***!
2051  \*****************************************************************/
2052/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2053
2054__webpack_require__.r(__webpack_exports__);
2055/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2056/* harmony export */   "filter": () => (/* binding */ filter)
2057/* harmony export */ });
2058/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
2059
2060function filter(predicate, thisArg) {
2061  return function filterOperatorFunction(source) {
2062    return source.lift(new FilterOperator(predicate, thisArg));
2063  };
2064}
2065
2066class FilterOperator {
2067  constructor(predicate, thisArg) {
2068    this.predicate = predicate;
2069    this.thisArg = thisArg;
2070  }
2071
2072  call(subscriber, source) {
2073    return source.subscribe(new FilterSubscriber(subscriber, this.predicate, this.thisArg));
2074  }
2075
2076}
2077
2078class FilterSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
2079  constructor(destination, predicate, thisArg) {
2080    super(destination);
2081    this.predicate = predicate;
2082    this.thisArg = thisArg;
2083    this.count = 0;
2084  }
2085
2086  _next(value) {
2087    let result;
2088
2089    try {
2090      result = this.predicate.call(this.thisArg, value, this.count++);
2091    } catch (err) {
2092      this.destination.error(err);
2093      return;
2094    }
2095
2096    if (result) {
2097      this.destination.next(value);
2098    }
2099  }
2100
2101}
2102
2103/***/ }),
2104
2105/***/ 4661:
2106/*!*******************************************************************!*\
2107  !*** ./node_modules/rxjs/_esm2015/internal/operators/finalize.js ***!
2108  \*******************************************************************/
2109/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2110
2111__webpack_require__.r(__webpack_exports__);
2112/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2113/* harmony export */   "finalize": () => (/* binding */ finalize)
2114/* harmony export */ });
2115/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
2116/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Subscription */ 2425);
2117
2118
2119function finalize(callback) {
2120  return source => source.lift(new FinallyOperator(callback));
2121}
2122
2123class FinallyOperator {
2124  constructor(callback) {
2125    this.callback = callback;
2126  }
2127
2128  call(subscriber, source) {
2129    return source.subscribe(new FinallySubscriber(subscriber, this.callback));
2130  }
2131
2132}
2133
2134class FinallySubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
2135  constructor(destination, callback) {
2136    super(destination);
2137    this.add(new _Subscription__WEBPACK_IMPORTED_MODULE_1__.Subscription(callback));
2138  }
2139
2140}
2141
2142/***/ }),
2143
2144/***/ 5670:
2145/*!****************************************************************!*\
2146  !*** ./node_modules/rxjs/_esm2015/internal/operators/first.js ***!
2147  \****************************************************************/
2148/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2149
2150__webpack_require__.r(__webpack_exports__);
2151/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2152/* harmony export */   "first": () => (/* binding */ first)
2153/* harmony export */ });
2154/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../util/EmptyError */ 213);
2155/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./filter */ 9151);
2156/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./take */ 3910);
2157/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./defaultIfEmpty */ 9701);
2158/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./throwIfEmpty */ 2013);
2159/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/identity */ 1356);
2160
2161
2162
2163
2164
2165
2166function first(predicate, defaultValue) {
2167  const hasDefaultValue = arguments.length >= 2;
2168  return source => source.pipe(predicate ? (0,_filter__WEBPACK_IMPORTED_MODULE_0__.filter)((v, i) => predicate(v, i, source)) : _util_identity__WEBPACK_IMPORTED_MODULE_1__.identity, (0,_take__WEBPACK_IMPORTED_MODULE_2__.take)(1), hasDefaultValue ? (0,_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__.defaultIfEmpty)(defaultValue) : (0,_throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__.throwIfEmpty)(() => new _util_EmptyError__WEBPACK_IMPORTED_MODULE_5__.EmptyError()));
2169}
2170
2171/***/ }),
2172
2173/***/ 5690:
2174/*!***************************************************************!*\
2175  !*** ./node_modules/rxjs/_esm2015/internal/operators/last.js ***!
2176  \***************************************************************/
2177/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2178
2179__webpack_require__.r(__webpack_exports__);
2180/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2181/* harmony export */   "last": () => (/* binding */ last)
2182/* harmony export */ });
2183/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../util/EmptyError */ 213);
2184/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./filter */ 9151);
2185/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./takeLast */ 7760);
2186/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./throwIfEmpty */ 2013);
2187/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./defaultIfEmpty */ 9701);
2188/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/identity */ 1356);
2189
2190
2191
2192
2193
2194
2195function last(predicate, defaultValue) {
2196  const hasDefaultValue = arguments.length >= 2;
2197  return source => source.pipe(predicate ? (0,_filter__WEBPACK_IMPORTED_MODULE_0__.filter)((v, i) => predicate(v, i, source)) : _util_identity__WEBPACK_IMPORTED_MODULE_1__.identity, (0,_takeLast__WEBPACK_IMPORTED_MODULE_2__.takeLast)(1), hasDefaultValue ? (0,_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__.defaultIfEmpty)(defaultValue) : (0,_throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__.throwIfEmpty)(() => new _util_EmptyError__WEBPACK_IMPORTED_MODULE_5__.EmptyError()));
2198}
2199
2200/***/ }),
2201
2202/***/ 6942:
2203/*!**************************************************************!*\
2204  !*** ./node_modules/rxjs/_esm2015/internal/operators/map.js ***!
2205  \**************************************************************/
2206/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2207
2208__webpack_require__.r(__webpack_exports__);
2209/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2210/* harmony export */   "MapOperator": () => (/* binding */ MapOperator),
2211/* harmony export */   "map": () => (/* binding */ map)
2212/* harmony export */ });
2213/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
2214
2215function map(project, thisArg) {
2216  return function mapOperation(source) {
2217    if (typeof project !== 'function') {
2218      throw new TypeError('argument is not a function. Are you looking for `mapTo()`?');
2219    }
2220
2221    return source.lift(new MapOperator(project, thisArg));
2222  };
2223}
2224class MapOperator {
2225  constructor(project, thisArg) {
2226    this.project = project;
2227    this.thisArg = thisArg;
2228  }
2229
2230  call(subscriber, source) {
2231    return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg));
2232  }
2233
2234}
2235
2236class MapSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
2237  constructor(destination, project, thisArg) {
2238    super(destination);
2239    this.project = project;
2240    this.count = 0;
2241    this.thisArg = thisArg || this;
2242  }
2243
2244  _next(value) {
2245    let result;
2246
2247    try {
2248      result = this.project.call(this.thisArg, value, this.count++);
2249    } catch (err) {
2250      this.destination.error(err);
2251      return;
2252    }
2253
2254    this.destination.next(result);
2255  }
2256
2257}
2258
2259/***/ }),
2260
2261/***/ 9361:
2262/*!****************************************************************!*\
2263  !*** ./node_modules/rxjs/_esm2015/internal/operators/mapTo.js ***!
2264  \****************************************************************/
2265/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2266
2267__webpack_require__.r(__webpack_exports__);
2268/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2269/* harmony export */   "mapTo": () => (/* binding */ mapTo)
2270/* harmony export */ });
2271/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
2272
2273function mapTo(value) {
2274  return source => source.lift(new MapToOperator(value));
2275}
2276
2277class MapToOperator {
2278  constructor(value) {
2279    this.value = value;
2280  }
2281
2282  call(subscriber, source) {
2283    return source.subscribe(new MapToSubscriber(subscriber, this.value));
2284  }
2285
2286}
2287
2288class MapToSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
2289  constructor(destination, value) {
2290    super(destination);
2291    this.value = value;
2292  }
2293
2294  _next(x) {
2295    this.destination.next(this.value);
2296  }
2297
2298}
2299
2300/***/ }),
2301
2302/***/ 6675:
2303/*!*******************************************************************!*\
2304  !*** ./node_modules/rxjs/_esm2015/internal/operators/mergeAll.js ***!
2305  \*******************************************************************/
2306/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2307
2308__webpack_require__.r(__webpack_exports__);
2309/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2310/* harmony export */   "mergeAll": () => (/* binding */ mergeAll)
2311/* harmony export */ });
2312/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mergeMap */ 522);
2313/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/identity */ 1356);
2314
2315
2316function mergeAll(concurrent = Number.POSITIVE_INFINITY) {
2317  return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__.mergeMap)(_util_identity__WEBPACK_IMPORTED_MODULE_1__.identity, concurrent);
2318}
2319
2320/***/ }),
2321
2322/***/ 522:
2323/*!*******************************************************************!*\
2324  !*** ./node_modules/rxjs/_esm2015/internal/operators/mergeMap.js ***!
2325  \*******************************************************************/
2326/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2327
2328__webpack_require__.r(__webpack_exports__);
2329/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2330/* harmony export */   "MergeMapOperator": () => (/* binding */ MergeMapOperator),
2331/* harmony export */   "MergeMapSubscriber": () => (/* binding */ MergeMapSubscriber),
2332/* harmony export */   "flatMap": () => (/* binding */ flatMap),
2333/* harmony export */   "mergeMap": () => (/* binding */ mergeMap)
2334/* harmony export */ });
2335/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./map */ 6942);
2336/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/from */ 4383);
2337/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../innerSubscribe */ 2831);
2338
2339
2340
2341function mergeMap(project, resultSelector, concurrent = Number.POSITIVE_INFINITY) {
2342  if (typeof resultSelector === 'function') {
2343    return source => source.pipe(mergeMap((a, i) => (0,_observable_from__WEBPACK_IMPORTED_MODULE_0__.from)(project(a, i)).pipe((0,_map__WEBPACK_IMPORTED_MODULE_1__.map)((b, ii) => resultSelector(a, b, i, ii))), concurrent));
2344  } else if (typeof resultSelector === 'number') {
2345    concurrent = resultSelector;
2346  }
2347
2348  return source => source.lift(new MergeMapOperator(project, concurrent));
2349}
2350class MergeMapOperator {
2351  constructor(project, concurrent = Number.POSITIVE_INFINITY) {
2352    this.project = project;
2353    this.concurrent = concurrent;
2354  }
2355
2356  call(observer, source) {
2357    return source.subscribe(new MergeMapSubscriber(observer, this.project, this.concurrent));
2358  }
2359
2360}
2361class MergeMapSubscriber extends _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__.SimpleOuterSubscriber {
2362  constructor(destination, project, concurrent = Number.POSITIVE_INFINITY) {
2363    super(destination);
2364    this.project = project;
2365    this.concurrent = concurrent;
2366    this.hasCompleted = false;
2367    this.buffer = [];
2368    this.active = 0;
2369    this.index = 0;
2370  }
2371
2372  _next(value) {
2373    if (this.active < this.concurrent) {
2374      this._tryNext(value);
2375    } else {
2376      this.buffer.push(value);
2377    }
2378  }
2379
2380  _tryNext(value) {
2381    let result;
2382    const index = this.index++;
2383
2384    try {
2385      result = this.project(value, index);
2386    } catch (err) {
2387      this.destination.error(err);
2388      return;
2389    }
2390
2391    this.active++;
2392
2393    this._innerSub(result);
2394  }
2395
2396  _innerSub(ish) {
2397    const innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__.SimpleInnerSubscriber(this);
2398    const destination = this.destination;
2399    destination.add(innerSubscriber);
2400    const innerSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__.innerSubscribe)(ish, innerSubscriber);
2401
2402    if (innerSubscription !== innerSubscriber) {
2403      destination.add(innerSubscription);
2404    }
2405  }
2406
2407  _complete() {
2408    this.hasCompleted = true;
2409
2410    if (this.active === 0 && this.buffer.length === 0) {
2411      this.destination.complete();
2412    }
2413
2414    this.unsubscribe();
2415  }
2416
2417  notifyNext(innerValue) {
2418    this.destination.next(innerValue);
2419  }
2420
2421  notifyComplete() {
2422    const buffer = this.buffer;
2423    this.active--;
2424
2425    if (buffer.length > 0) {
2426      this._next(buffer.shift());
2427    } else if (this.active === 0 && this.hasCompleted) {
2428      this.destination.complete();
2429    }
2430  }
2431
2432}
2433const flatMap = mergeMap;
2434
2435/***/ }),
2436
2437/***/ 2787:
2438/*!********************************************************************!*\
2439  !*** ./node_modules/rxjs/_esm2015/internal/operators/multicast.js ***!
2440  \********************************************************************/
2441/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2442
2443__webpack_require__.r(__webpack_exports__);
2444/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2445/* harmony export */   "MulticastOperator": () => (/* binding */ MulticastOperator),
2446/* harmony export */   "multicast": () => (/* binding */ multicast)
2447/* harmony export */ });
2448/* harmony import */ var _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/ConnectableObservable */ 4483);
2449
2450function multicast(subjectOrSubjectFactory, selector) {
2451  return function multicastOperatorFunction(source) {
2452    let subjectFactory;
2453
2454    if (typeof subjectOrSubjectFactory === 'function') {
2455      subjectFactory = subjectOrSubjectFactory;
2456    } else {
2457      subjectFactory = function subjectFactory() {
2458        return subjectOrSubjectFactory;
2459      };
2460    }
2461
2462    if (typeof selector === 'function') {
2463      return source.lift(new MulticastOperator(subjectFactory, selector));
2464    }
2465
2466    const connectable = Object.create(source, _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__.connectableObservableDescriptor);
2467    connectable.source = source;
2468    connectable.subjectFactory = subjectFactory;
2469    return connectable;
2470  };
2471}
2472class MulticastOperator {
2473  constructor(subjectFactory, selector) {
2474    this.subjectFactory = subjectFactory;
2475    this.selector = selector;
2476  }
2477
2478  call(subscriber, source) {
2479    const {
2480      selector
2481    } = this;
2482    const subject = this.subjectFactory();
2483    const subscription = selector(subject).subscribe(subscriber);
2484    subscription.add(source.subscribe(subject));
2485    return subscription;
2486  }
2487
2488}
2489
2490/***/ }),
2491
2492/***/ 8331:
2493/*!*******************************************************************!*\
2494  !*** ./node_modules/rxjs/_esm2015/internal/operators/refCount.js ***!
2495  \*******************************************************************/
2496/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2497
2498__webpack_require__.r(__webpack_exports__);
2499/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2500/* harmony export */   "refCount": () => (/* binding */ refCount)
2501/* harmony export */ });
2502/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
2503
2504function refCount() {
2505  return function refCountOperatorFunction(source) {
2506    return source.lift(new RefCountOperator(source));
2507  };
2508}
2509
2510class RefCountOperator {
2511  constructor(connectable) {
2512    this.connectable = connectable;
2513  }
2514
2515  call(subscriber, source) {
2516    const {
2517      connectable
2518    } = this;
2519    connectable._refCount++;
2520    const refCounter = new RefCountSubscriber(subscriber, connectable);
2521    const subscription = source.subscribe(refCounter);
2522
2523    if (!refCounter.closed) {
2524      refCounter.connection = connectable.connect();
2525    }
2526
2527    return subscription;
2528  }
2529
2530}
2531
2532class RefCountSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
2533  constructor(destination, connectable) {
2534    super(destination);
2535    this.connectable = connectable;
2536  }
2537
2538  _unsubscribe() {
2539    const {
2540      connectable
2541    } = this;
2542
2543    if (!connectable) {
2544      this.connection = null;
2545      return;
2546    }
2547
2548    this.connectable = null;
2549    const refCount = connectable._refCount;
2550
2551    if (refCount <= 0) {
2552      this.connection = null;
2553      return;
2554    }
2555
2556    connectable._refCount = refCount - 1;
2557
2558    if (refCount > 1) {
2559      this.connection = null;
2560      return;
2561    }
2562
2563    const {
2564      connection
2565    } = this;
2566    const sharedConnection = connectable._connection;
2567    this.connection = null;
2568
2569    if (sharedConnection && (!connection || sharedConnection === connection)) {
2570      sharedConnection.unsubscribe();
2571    }
2572  }
2573
2574}
2575
2576/***/ }),
2577
2578/***/ 2647:
2579/*!***************************************************************!*\
2580  !*** ./node_modules/rxjs/_esm2015/internal/operators/scan.js ***!
2581  \***************************************************************/
2582/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2583
2584__webpack_require__.r(__webpack_exports__);
2585/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2586/* harmony export */   "scan": () => (/* binding */ scan)
2587/* harmony export */ });
2588/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
2589
2590function scan(accumulator, seed) {
2591  let hasSeed = false;
2592
2593  if (arguments.length >= 2) {
2594    hasSeed = true;
2595  }
2596
2597  return function scanOperatorFunction(source) {
2598    return source.lift(new ScanOperator(accumulator, seed, hasSeed));
2599  };
2600}
2601
2602class ScanOperator {
2603  constructor(accumulator, seed, hasSeed = false) {
2604    this.accumulator = accumulator;
2605    this.seed = seed;
2606    this.hasSeed = hasSeed;
2607  }
2608
2609  call(subscriber, source) {
2610    return source.subscribe(new ScanSubscriber(subscriber, this.accumulator, this.seed, this.hasSeed));
2611  }
2612
2613}
2614
2615class ScanSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
2616  constructor(destination, accumulator, _seed, hasSeed) {
2617    super(destination);
2618    this.accumulator = accumulator;
2619    this._seed = _seed;
2620    this.hasSeed = hasSeed;
2621    this.index = 0;
2622  }
2623
2624  get seed() {
2625    return this._seed;
2626  }
2627
2628  set seed(value) {
2629    this.hasSeed = true;
2630    this._seed = value;
2631  }
2632
2633  _next(value) {
2634    if (!this.hasSeed) {
2635      this.seed = value;
2636      this.destination.next(value);
2637    } else {
2638      return this._tryNext(value);
2639    }
2640  }
2641
2642  _tryNext(value) {
2643    const index = this.index++;
2644    let result;
2645
2646    try {
2647      result = this.accumulator(this.seed, value, index);
2648    } catch (err) {
2649      this.destination.error(err);
2650    }
2651
2652    this.seed = result;
2653    this.destination.next(result);
2654  }
2655
2656}
2657
2658/***/ }),
2659
2660/***/ 4514:
2661/*!****************************************************************!*\
2662  !*** ./node_modules/rxjs/_esm2015/internal/operators/share.js ***!
2663  \****************************************************************/
2664/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2665
2666__webpack_require__.r(__webpack_exports__);
2667/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2668/* harmony export */   "share": () => (/* binding */ share)
2669/* harmony export */ });
2670/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./multicast */ 2787);
2671/* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./refCount */ 8331);
2672/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subject */ 2218);
2673
2674
2675
2676
2677function shareSubjectFactory() {
2678  return new _Subject__WEBPACK_IMPORTED_MODULE_0__.Subject();
2679}
2680
2681function share() {
2682  return source => (0,_refCount__WEBPACK_IMPORTED_MODULE_1__.refCount)()((0,_multicast__WEBPACK_IMPORTED_MODULE_2__.multicast)(shareSubjectFactory)(source));
2683}
2684
2685/***/ }),
2686
2687/***/ 6276:
2688/*!***************************************************************!*\
2689  !*** ./node_modules/rxjs/_esm2015/internal/operators/skip.js ***!
2690  \***************************************************************/
2691/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2692
2693__webpack_require__.r(__webpack_exports__);
2694/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2695/* harmony export */   "skip": () => (/* binding */ skip)
2696/* harmony export */ });
2697/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
2698
2699function skip(count) {
2700  return source => source.lift(new SkipOperator(count));
2701}
2702
2703class SkipOperator {
2704  constructor(total) {
2705    this.total = total;
2706  }
2707
2708  call(subscriber, source) {
2709    return source.subscribe(new SkipSubscriber(subscriber, this.total));
2710  }
2711
2712}
2713
2714class SkipSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
2715  constructor(destination, total) {
2716    super(destination);
2717    this.total = total;
2718    this.count = 0;
2719  }
2720
2721  _next(x) {
2722    if (++this.count > this.total) {
2723      this.destination.next(x);
2724    }
2725  }
2726
2727}
2728
2729/***/ }),
2730
2731/***/ 5722:
2732/*!********************************************************************!*\
2733  !*** ./node_modules/rxjs/_esm2015/internal/operators/startWith.js ***!
2734  \********************************************************************/
2735/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2736
2737__webpack_require__.r(__webpack_exports__);
2738/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2739/* harmony export */   "startWith": () => (/* binding */ startWith)
2740/* harmony export */ });
2741/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../observable/concat */ 5828);
2742/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isScheduler */ 7507);
2743
2744
2745function startWith(...array) {
2746  const scheduler = array[array.length - 1];
2747
2748  if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__.isScheduler)(scheduler)) {
2749    array.pop();
2750    return source => (0,_observable_concat__WEBPACK_IMPORTED_MODULE_1__.concat)(array, source, scheduler);
2751  } else {
2752    return source => (0,_observable_concat__WEBPACK_IMPORTED_MODULE_1__.concat)(array, source);
2753  }
2754}
2755
2756/***/ }),
2757
2758/***/ 9095:
2759/*!********************************************************************!*\
2760  !*** ./node_modules/rxjs/_esm2015/internal/operators/switchMap.js ***!
2761  \********************************************************************/
2762/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2763
2764__webpack_require__.r(__webpack_exports__);
2765/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2766/* harmony export */   "switchMap": () => (/* binding */ switchMap)
2767/* harmony export */ });
2768/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./map */ 6942);
2769/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/from */ 4383);
2770/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../innerSubscribe */ 2831);
2771
2772
2773
2774function switchMap(project, resultSelector) {
2775  if (typeof resultSelector === 'function') {
2776    return source => source.pipe(switchMap((a, i) => (0,_observable_from__WEBPACK_IMPORTED_MODULE_0__.from)(project(a, i)).pipe((0,_map__WEBPACK_IMPORTED_MODULE_1__.map)((b, ii) => resultSelector(a, b, i, ii)))));
2777  }
2778
2779  return source => source.lift(new SwitchMapOperator(project));
2780}
2781
2782class SwitchMapOperator {
2783  constructor(project) {
2784    this.project = project;
2785  }
2786
2787  call(subscriber, source) {
2788    return source.subscribe(new SwitchMapSubscriber(subscriber, this.project));
2789  }
2790
2791}
2792
2793class SwitchMapSubscriber extends _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__.SimpleOuterSubscriber {
2794  constructor(destination, project) {
2795    super(destination);
2796    this.project = project;
2797    this.index = 0;
2798  }
2799
2800  _next(value) {
2801    let result;
2802    const index = this.index++;
2803
2804    try {
2805      result = this.project(value, index);
2806    } catch (error) {
2807      this.destination.error(error);
2808      return;
2809    }
2810
2811    this._innerSub(result);
2812  }
2813
2814  _innerSub(result) {
2815    const innerSubscription = this.innerSubscription;
2816
2817    if (innerSubscription) {
2818      innerSubscription.unsubscribe();
2819    }
2820
2821    const innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__.SimpleInnerSubscriber(this);
2822    const destination = this.destination;
2823    destination.add(innerSubscriber);
2824    this.innerSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__.innerSubscribe)(result, innerSubscriber);
2825
2826    if (this.innerSubscription !== innerSubscriber) {
2827      destination.add(this.innerSubscription);
2828    }
2829  }
2830
2831  _complete() {
2832    const {
2833      innerSubscription
2834    } = this;
2835
2836    if (!innerSubscription || innerSubscription.closed) {
2837      super._complete();
2838    }
2839
2840    this.unsubscribe();
2841  }
2842
2843  _unsubscribe() {
2844    this.innerSubscription = undefined;
2845  }
2846
2847  notifyComplete() {
2848    this.innerSubscription = undefined;
2849
2850    if (this.isStopped) {
2851      super._complete();
2852    }
2853  }
2854
2855  notifyNext(innerValue) {
2856    this.destination.next(innerValue);
2857  }
2858
2859}
2860
2861/***/ }),
2862
2863/***/ 3910:
2864/*!***************************************************************!*\
2865  !*** ./node_modules/rxjs/_esm2015/internal/operators/take.js ***!
2866  \***************************************************************/
2867/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2868
2869__webpack_require__.r(__webpack_exports__);
2870/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2871/* harmony export */   "take": () => (/* binding */ take)
2872/* harmony export */ });
2873/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Subscriber */ 14);
2874/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/ArgumentOutOfRangeError */ 2846);
2875/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/empty */ 6439);
2876
2877
2878
2879function take(count) {
2880  return source => {
2881    if (count === 0) {
2882      return (0,_observable_empty__WEBPACK_IMPORTED_MODULE_0__.empty)();
2883    } else {
2884      return source.lift(new TakeOperator(count));
2885    }
2886  };
2887}
2888
2889class TakeOperator {
2890  constructor(total) {
2891    this.total = total;
2892
2893    if (this.total < 0) {
2894      throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_1__.ArgumentOutOfRangeError();
2895    }
2896  }
2897
2898  call(subscriber, source) {
2899    return source.subscribe(new TakeSubscriber(subscriber, this.total));
2900  }
2901
2902}
2903
2904class TakeSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_2__.Subscriber {
2905  constructor(destination, total) {
2906    super(destination);
2907    this.total = total;
2908    this.count = 0;
2909  }
2910
2911  _next(value) {
2912    const total = this.total;
2913    const count = ++this.count;
2914
2915    if (count <= total) {
2916      this.destination.next(value);
2917
2918      if (count === total) {
2919        this.destination.complete();
2920        this.unsubscribe();
2921      }
2922    }
2923  }
2924
2925}
2926
2927/***/ }),
2928
2929/***/ 7760:
2930/*!*******************************************************************!*\
2931  !*** ./node_modules/rxjs/_esm2015/internal/operators/takeLast.js ***!
2932  \*******************************************************************/
2933/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2934
2935__webpack_require__.r(__webpack_exports__);
2936/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2937/* harmony export */   "takeLast": () => (/* binding */ takeLast)
2938/* harmony export */ });
2939/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Subscriber */ 14);
2940/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/ArgumentOutOfRangeError */ 2846);
2941/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/empty */ 6439);
2942
2943
2944
2945function takeLast(count) {
2946  return function takeLastOperatorFunction(source) {
2947    if (count === 0) {
2948      return (0,_observable_empty__WEBPACK_IMPORTED_MODULE_0__.empty)();
2949    } else {
2950      return source.lift(new TakeLastOperator(count));
2951    }
2952  };
2953}
2954
2955class TakeLastOperator {
2956  constructor(total) {
2957    this.total = total;
2958
2959    if (this.total < 0) {
2960      throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_1__.ArgumentOutOfRangeError();
2961    }
2962  }
2963
2964  call(subscriber, source) {
2965    return source.subscribe(new TakeLastSubscriber(subscriber, this.total));
2966  }
2967
2968}
2969
2970class TakeLastSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_2__.Subscriber {
2971  constructor(destination, total) {
2972    super(destination);
2973    this.total = total;
2974    this.ring = new Array();
2975    this.count = 0;
2976  }
2977
2978  _next(value) {
2979    const ring = this.ring;
2980    const total = this.total;
2981    const count = this.count++;
2982
2983    if (ring.length < total) {
2984      ring.push(value);
2985    } else {
2986      const index = count % total;
2987      ring[index] = value;
2988    }
2989  }
2990
2991  _complete() {
2992    const destination = this.destination;
2993    let count = this.count;
2994
2995    if (count > 0) {
2996      const total = this.count >= this.total ? this.total : this.count;
2997      const ring = this.ring;
2998
2999      for (let i = 0; i < total; i++) {
3000        const idx = count++ % total;
3001        destination.next(ring[idx]);
3002      }
3003    }
3004
3005    destination.complete();
3006  }
3007
3008}
3009
3010/***/ }),
3011
3012/***/ 5050:
3013/*!********************************************************************!*\
3014  !*** ./node_modules/rxjs/_esm2015/internal/operators/takeWhile.js ***!
3015  \********************************************************************/
3016/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3017
3018__webpack_require__.r(__webpack_exports__);
3019/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3020/* harmony export */   "takeWhile": () => (/* binding */ takeWhile)
3021/* harmony export */ });
3022/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
3023
3024function takeWhile(predicate, inclusive = false) {
3025  return source => source.lift(new TakeWhileOperator(predicate, inclusive));
3026}
3027
3028class TakeWhileOperator {
3029  constructor(predicate, inclusive) {
3030    this.predicate = predicate;
3031    this.inclusive = inclusive;
3032  }
3033
3034  call(subscriber, source) {
3035    return source.subscribe(new TakeWhileSubscriber(subscriber, this.predicate, this.inclusive));
3036  }
3037
3038}
3039
3040class TakeWhileSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
3041  constructor(destination, predicate, inclusive) {
3042    super(destination);
3043    this.predicate = predicate;
3044    this.inclusive = inclusive;
3045    this.index = 0;
3046  }
3047
3048  _next(value) {
3049    const destination = this.destination;
3050    let result;
3051
3052    try {
3053      result = this.predicate(value, this.index++);
3054    } catch (err) {
3055      destination.error(err);
3056      return;
3057    }
3058
3059    this.nextOrComplete(value, result);
3060  }
3061
3062  nextOrComplete(value, predicateResult) {
3063    const destination = this.destination;
3064
3065    if (Boolean(predicateResult)) {
3066      destination.next(value);
3067    } else {
3068      if (this.inclusive) {
3069        destination.next(value);
3070      }
3071
3072      destination.complete();
3073    }
3074  }
3075
3076}
3077
3078/***/ }),
3079
3080/***/ 8759:
3081/*!**************************************************************!*\
3082  !*** ./node_modules/rxjs/_esm2015/internal/operators/tap.js ***!
3083  \**************************************************************/
3084/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3085
3086__webpack_require__.r(__webpack_exports__);
3087/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3088/* harmony export */   "tap": () => (/* binding */ tap)
3089/* harmony export */ });
3090/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
3091/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/noop */ 6882);
3092/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/isFunction */ 1900);
3093
3094
3095
3096function tap(nextOrObserver, error, complete) {
3097  return function tapOperatorFunction(source) {
3098    return source.lift(new DoOperator(nextOrObserver, error, complete));
3099  };
3100}
3101
3102class DoOperator {
3103  constructor(nextOrObserver, error, complete) {
3104    this.nextOrObserver = nextOrObserver;
3105    this.error = error;
3106    this.complete = complete;
3107  }
3108
3109  call(subscriber, source) {
3110    return source.subscribe(new TapSubscriber(subscriber, this.nextOrObserver, this.error, this.complete));
3111  }
3112
3113}
3114
3115class TapSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
3116  constructor(destination, observerOrNext, error, complete) {
3117    super(destination);
3118    this._tapNext = _util_noop__WEBPACK_IMPORTED_MODULE_1__.noop;
3119    this._tapError = _util_noop__WEBPACK_IMPORTED_MODULE_1__.noop;
3120    this._tapComplete = _util_noop__WEBPACK_IMPORTED_MODULE_1__.noop;
3121    this._tapError = error || _util_noop__WEBPACK_IMPORTED_MODULE_1__.noop;
3122    this._tapComplete = complete || _util_noop__WEBPACK_IMPORTED_MODULE_1__.noop;
3123
3124    if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observerOrNext)) {
3125      this._context = this;
3126      this._tapNext = observerOrNext;
3127    } else if (observerOrNext) {
3128      this._context = observerOrNext;
3129      this._tapNext = observerOrNext.next || _util_noop__WEBPACK_IMPORTED_MODULE_1__.noop;
3130      this._tapError = observerOrNext.error || _util_noop__WEBPACK_IMPORTED_MODULE_1__.noop;
3131      this._tapComplete = observerOrNext.complete || _util_noop__WEBPACK_IMPORTED_MODULE_1__.noop;
3132    }
3133  }
3134
3135  _next(value) {
3136    try {
3137      this._tapNext.call(this._context, value);
3138    } catch (err) {
3139      this.destination.error(err);
3140      return;
3141    }
3142
3143    this.destination.next(value);
3144  }
3145
3146  _error(err) {
3147    try {
3148      this._tapError.call(this._context, err);
3149    } catch (err) {
3150      this.destination.error(err);
3151      return;
3152    }
3153
3154    this.destination.error(err);
3155  }
3156
3157  _complete() {
3158    try {
3159      this._tapComplete.call(this._context);
3160    } catch (err) {
3161      this.destination.error(err);
3162      return;
3163    }
3164
3165    return this.destination.complete();
3166  }
3167
3168}
3169
3170/***/ }),
3171
3172/***/ 2013:
3173/*!***********************************************************************!*\
3174  !*** ./node_modules/rxjs/_esm2015/internal/operators/throwIfEmpty.js ***!
3175  \***********************************************************************/
3176/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3177
3178__webpack_require__.r(__webpack_exports__);
3179/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3180/* harmony export */   "throwIfEmpty": () => (/* binding */ throwIfEmpty)
3181/* harmony export */ });
3182/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/EmptyError */ 213);
3183/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
3184
3185
3186function throwIfEmpty(errorFactory = defaultErrorFactory) {
3187  return source => {
3188    return source.lift(new ThrowIfEmptyOperator(errorFactory));
3189  };
3190}
3191
3192class ThrowIfEmptyOperator {
3193  constructor(errorFactory) {
3194    this.errorFactory = errorFactory;
3195  }
3196
3197  call(subscriber, source) {
3198    return source.subscribe(new ThrowIfEmptySubscriber(subscriber, this.errorFactory));
3199  }
3200
3201}
3202
3203class ThrowIfEmptySubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
3204  constructor(destination, errorFactory) {
3205    super(destination);
3206    this.errorFactory = errorFactory;
3207    this.hasValue = false;
3208  }
3209
3210  _next(value) {
3211    this.hasValue = true;
3212    this.destination.next(value);
3213  }
3214
3215  _complete() {
3216    if (!this.hasValue) {
3217      let err;
3218
3219      try {
3220        err = this.errorFactory();
3221      } catch (e) {
3222        err = e;
3223      }
3224
3225      this.destination.error(err);
3226    } else {
3227      return this.destination.complete();
3228    }
3229  }
3230
3231}
3232
3233function defaultErrorFactory() {
3234  return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__.EmptyError();
3235}
3236
3237/***/ }),
3238
3239/***/ 8403:
3240/*!************************************************************************!*\
3241  !*** ./node_modules/rxjs/_esm2015/internal/scheduled/scheduleArray.js ***!
3242  \************************************************************************/
3243/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3244
3245__webpack_require__.r(__webpack_exports__);
3246/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3247/* harmony export */   "scheduleArray": () => (/* binding */ scheduleArray)
3248/* harmony export */ });
3249/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
3250/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Subscription */ 2425);
3251
3252
3253function scheduleArray(input, scheduler) {
3254  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
3255    const sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__.Subscription();
3256    let i = 0;
3257    sub.add(scheduler.schedule(function () {
3258      if (i === input.length) {
3259        subscriber.complete();
3260        return;
3261      }
3262
3263      subscriber.next(input[i++]);
3264
3265      if (!subscriber.closed) {
3266        sub.add(this.schedule());
3267      }
3268    }));
3269    return sub;
3270  });
3271}
3272
3273/***/ }),
3274
3275/***/ 1232:
3276/*!***************************************************************************!*\
3277  !*** ./node_modules/rxjs/_esm2015/internal/scheduled/scheduleIterable.js ***!
3278  \***************************************************************************/
3279/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3280
3281__webpack_require__.r(__webpack_exports__);
3282/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3283/* harmony export */   "scheduleIterable": () => (/* binding */ scheduleIterable)
3284/* harmony export */ });
3285/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
3286/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Subscription */ 2425);
3287/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../symbol/iterator */ 2803);
3288
3289
3290
3291function scheduleIterable(input, scheduler) {
3292  if (!input) {
3293    throw new Error('Iterable cannot be null');
3294  }
3295
3296  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
3297    const sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__.Subscription();
3298    let iterator;
3299    sub.add(() => {
3300      if (iterator && typeof iterator.return === 'function') {
3301        iterator.return();
3302      }
3303    });
3304    sub.add(scheduler.schedule(() => {
3305      iterator = input[_symbol_iterator__WEBPACK_IMPORTED_MODULE_2__.iterator]();
3306      sub.add(scheduler.schedule(function () {
3307        if (subscriber.closed) {
3308          return;
3309        }
3310
3311        let value;
3312        let done;
3313
3314        try {
3315          const result = iterator.next();
3316          value = result.value;
3317          done = result.done;
3318        } catch (err) {
3319          subscriber.error(err);
3320          return;
3321        }
3322
3323        if (done) {
3324          subscriber.complete();
3325        } else {
3326          subscriber.next(value);
3327          this.schedule();
3328        }
3329      }));
3330    }));
3331    return sub;
3332  });
3333}
3334
3335/***/ }),
3336
3337/***/ 1145:
3338/*!*****************************************************************************!*\
3339  !*** ./node_modules/rxjs/_esm2015/internal/scheduled/scheduleObservable.js ***!
3340  \*****************************************************************************/
3341/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3342
3343__webpack_require__.r(__webpack_exports__);
3344/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3345/* harmony export */   "scheduleObservable": () => (/* binding */ scheduleObservable)
3346/* harmony export */ });
3347/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
3348/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Subscription */ 2425);
3349/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../symbol/observable */ 6831);
3350
3351
3352
3353function scheduleObservable(input, scheduler) {
3354  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
3355    const sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__.Subscription();
3356    sub.add(scheduler.schedule(() => {
3357      const observable = input[_symbol_observable__WEBPACK_IMPORTED_MODULE_2__.observable]();
3358      sub.add(observable.subscribe({
3359        next(value) {
3360          sub.add(scheduler.schedule(() => subscriber.next(value)));
3361        },
3362
3363        error(err) {
3364          sub.add(scheduler.schedule(() => subscriber.error(err)));
3365        },
3366
3367        complete() {
3368          sub.add(scheduler.schedule(() => subscriber.complete()));
3369        }
3370
3371      }));
3372    }));
3373    return sub;
3374  });
3375}
3376
3377/***/ }),
3378
3379/***/ 467:
3380/*!**************************************************************************!*\
3381  !*** ./node_modules/rxjs/_esm2015/internal/scheduled/schedulePromise.js ***!
3382  \**************************************************************************/
3383/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3384
3385__webpack_require__.r(__webpack_exports__);
3386/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3387/* harmony export */   "schedulePromise": () => (/* binding */ schedulePromise)
3388/* harmony export */ });
3389/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 2378);
3390/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Subscription */ 2425);
3391
3392
3393function schedulePromise(input, scheduler) {
3394  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
3395    const sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__.Subscription();
3396    sub.add(scheduler.schedule(() => input.then(value => {
3397      sub.add(scheduler.schedule(() => {
3398        subscriber.next(value);
3399        sub.add(scheduler.schedule(() => subscriber.complete()));
3400      }));
3401    }, err => {
3402      sub.add(scheduler.schedule(() => subscriber.error(err)));
3403    }
3403)));
3404    return sub;
3405  });
3406}
3407
3408/***/ }),
3409
3410/***/ 2476:
3411/*!********************************************************************!*\
3412  !*** ./node_modules/rxjs/_esm2015/internal/scheduled/scheduled.js ***!
3413  \********************************************************************/
3414/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3415
3416__webpack_require__.r(__webpack_exports__);
3417/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3418/* harmony export */   "scheduled": () => (/* binding */ scheduled)
3419/* harmony export */ });
3420/* harmony import */ var _scheduleObservable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./scheduleObservable */ 1145);
3421/* harmony import */ var _schedulePromise__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./schedulePromise */ 467);
3422/* harmony import */ var _scheduleArray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./scheduleArray */ 8403);
3423/* harmony import */ var _scheduleIterable__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./scheduleIterable */ 1232);
3424/* harmony import */ var _util_isInteropObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isInteropObservable */ 5781);
3425/* harmony import */ var _util_isPromise__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/isPromise */ 5192);
3426/* harmony import */ var _util_isArrayLike__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../util/isArrayLike */ 5122);
3427/* harmony import */ var _util_isIterable__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../util/isIterable */ 9674);
3428
3429
3430
3431
3432
3433
3434
3435
3436function scheduled(input, scheduler) {
3437  if (input != null) {
3438    if ((0,_util_isInteropObservable__WEBPACK_IMPORTED_MODULE_0__.isInteropObservable)(input)) {
3439      return (0,_scheduleObservable__WEBPACK_IMPORTED_MODULE_1__.scheduleObservable)(input, scheduler);
3440    } else if ((0,_util_isPromise__WEBPACK_IMPORTED_MODULE_2__.isPromise)(input)) {
3441      return (0,_schedulePromise__WEBPACK_IMPORTED_MODULE_3__.schedulePromise)(input, scheduler);
3442    } else if ((0,_util_isArrayLike__WEBPACK_IMPORTED_MODULE_4__.isArrayLike)(input)) {
3443      return (0,_scheduleArray__WEBPACK_IMPORTED_MODULE_5__.scheduleArray)(input, scheduler);
3444    } else if ((0,_util_isIterable__WEBPACK_IMPORTED_MODULE_6__.isIterable)(input) || typeof input === 'string') {
3445      return (0,_scheduleIterable__WEBPACK_IMPORTED_MODULE_7__.scheduleIterable)(input, scheduler);
3446    }
3447  }
3448
3449  throw new TypeError((input !== null && typeof input || input) + ' is not observable');
3450}
3451
3452/***/ }),
3453
3454/***/ 2803:
3455/*!****************************************************************!*\
3456  !*** ./node_modules/rxjs/_esm2015/internal/symbol/iterator.js ***!
3457  \****************************************************************/
3458/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3459
3460__webpack_require__.r(__webpack_exports__);
3461/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3462/* harmony export */   "$$iterator": () => (/* binding */ $$iterator),
3463/* harmony export */   "getSymbolIterator": () => (/* binding */ getSymbolIterator),
3464/* harmony export */   "iterator": () => (/* binding */ iterator)
3465/* harmony export */ });
3466function getSymbolIterator() {
3467  if (typeof Symbol !== 'function' || !Symbol.iterator) {
3468    return '@@iterator';
3469  }
3470
3471  return Symbol.iterator;
3472}
3473const iterator = getSymbolIterator();
3474const $$iterator = iterator;
3475
3476/***/ }),
3477
3478/***/ 6831:
3479/*!******************************************************************!*\
3480  !*** ./node_modules/rxjs/_esm2015/internal/symbol/observable.js ***!
3481  \******************************************************************/
3482/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3483
3484__webpack_require__.r(__webpack_exports__);
3485/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3486/* harmony export */   "observable": () => (/* binding */ observable)
3487/* harmony export */ });
3488const observable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
3489
3490/***/ }),
3491
3492/***/ 1482:
3493/*!********************************************************************!*\
3494  !*** ./node_modules/rxjs/_esm2015/internal/symbol/rxSubscriber.js ***!
3495  \********************************************************************/
3496/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3497
3498__webpack_require__.r(__webpack_exports__);
3499/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3500/* harmony export */   "$$rxSubscriber": () => (/* binding */ $$rxSubscriber),
3501/* harmony export */   "rxSubscriber": () => (/* binding */ rxSubscriber)
3502/* harmony export */ });
3503const rxSubscriber = (() => typeof Symbol === 'function' ? Symbol('rxSubscriber') : '@@rxSubscriber_' + Math.random())();
3504const $$rxSubscriber = rxSubscriber;
3505
3506/***/ }),
3507
3508/***/ 2846:
3509/*!*****************************************************************************!*\
3510  !*** ./node_modules/rxjs/_esm2015/internal/util/ArgumentOutOfRangeError.js ***!
3511  \*****************************************************************************/
3512/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3513
3514__webpack_require__.r(__webpack_exports__);
3515/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3516/* harmony export */   "ArgumentOutOfRangeError": () => (/* binding */ ArgumentOutOfRangeError)
3517/* harmony export */ });
3518const ArgumentOutOfRangeErrorImpl = (() => {
3519  function ArgumentOutOfRangeErrorImpl() {
3520    Error.call(this);
3521    this.message = 'argument out of range';
3522    this.name = 'ArgumentOutOfRangeError';
3523    return this;
3524  }
3525
3526  ArgumentOutOfRangeErrorImpl.prototype = Object.create(Error.prototype);
3527  return ArgumentOutOfRangeErrorImpl;
3528})();
3529
3530const ArgumentOutOfRangeError = ArgumentOutOfRangeErrorImpl;
3531
3532/***/ }),
3533
3534/***/ 213:
3535/*!****************************************************************!*\
3536  !*** ./node_modules/rxjs/_esm2015/internal/util/EmptyError.js ***!
3537  \****************************************************************/
3538/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3539
3540__webpack_require__.r(__webpack_exports__);
3541/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3542/* harmony export */   "EmptyError": () => (/* binding */ EmptyError)
3543/* harmony export */ });
3544const EmptyErrorImpl = (() => {
3545  function EmptyErrorImpl() {
3546    Error.call(this);
3547    this.message = 'no elements in sequence';
3548    this.name = 'EmptyError';
3549    return this;
3550  }
3551
3552  EmptyErrorImpl.prototype = Object.create(Error.prototype);
3553  return EmptyErrorImpl;
3554})();
3555
3556const EmptyError = EmptyErrorImpl;
3557
3558/***/ }),
3559
3560/***/ 9086:
3561/*!*****************************************************************************!*\
3562  !*** ./node_modules/rxjs/_esm2015/internal/util/ObjectUnsubscribedError.js ***!
3563  \*****************************************************************************/
3564/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3565
3566__webpack_require__.r(__webpack_exports__);
3567/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3568/* harmony export */   "ObjectUnsubscribedError": () => (/* binding */ ObjectUnsubscribedError)
3569/* harmony export */ });
3570const ObjectUnsubscribedErrorImpl = (() => {
3571  function ObjectUnsubscribedErrorImpl() {
3572    Error.call(this);
3573    this.message = 'object unsubscribed';
3574    this.name = 'ObjectUnsubscribedError';
3575    return this;
3576  }
3577
3578  ObjectUnsubscribedErrorImpl.prototype = Object.create(Error.prototype);
3579  return ObjectUnsubscribedErrorImpl;
3580})();
3581
3582const ObjectUnsubscribedError = ObjectUnsubscribedErrorImpl;
3583
3584/***/ }),
3585
3586/***/ 7875:
3587/*!*************************************************************************!*\
3588  !*** ./node_modules/rxjs/_esm2015/internal/util/UnsubscriptionError.js ***!
3589  \*************************************************************************/
3590/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3591
3592__webpack_require__.r(__webpack_exports__);
3593/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3594/* harmony export */   "UnsubscriptionError": () => (/* binding */ UnsubscriptionError)
3595/* harmony export */ });
3596const UnsubscriptionErrorImpl = (() => {
3597  function UnsubscriptionErrorImpl(errors) {
3598    Error.call(this);
3599    this.message = errors ? `${errors.length} errors occurred during unsubscription:
3600${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\n  ')}` : '';
3601    this.name = 'UnsubscriptionError';
3602    this.errors = errors;
3603    return this;
3604  }
3605
3606  UnsubscriptionErrorImpl.prototype = Object.create(Error.prototype);
3607  return UnsubscriptionErrorImpl;
3608})();
3609
3610const UnsubscriptionError = UnsubscriptionErrorImpl;
3611
3612/***/ }),
3613
3614/***/ 5739:
3615/*!********************************************************************!*\
3616  !*** ./node_modules/rxjs/_esm2015/internal/util/canReportError.js ***!
3617  \********************************************************************/
3618/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3619
3620__webpack_require__.r(__webpack_exports__);
3621/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3622/* harmony export */   "canReportError": () => (/* binding */ canReportError)
3623/* harmony export */ });
3624/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
3625
3626function canReportError(observer) {
3627  while (observer) {
3628    const {
3629      closed,
3630      destination,
3631      isStopped
3632    } = observer;
3633
3634    if (closed || isStopped) {
3635      return false;
3636    } else if (destination && destination instanceof _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber) {
3637      observer = destination;
3638    } else {
3639      observer = null;
3640    }
3641  }
3642
3643  return true;
3644}
3645
3646/***/ }),
3647
3648/***/ 8897:
3649/*!*********************************************************************!*\
3650  !*** ./node_modules/rxjs/_esm2015/internal/util/hostReportError.js ***!
3651  \*********************************************************************/
3652/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3653
3654__webpack_require__.r(__webpack_exports__);
3655/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3656/* harmony export */   "hostReportError": () => (/* binding */ hostReportError)
3657/* harmony export */ });
3658function hostReportError(err) {
3659  setTimeout(() => {
3660    throw err;
3661  }, 0);
3662}
3663
3664/***/ }),
3665
3666/***/ 1356:
3667/*!**************************************************************!*\
3668  !*** ./node_modules/rxjs/_esm2015/internal/util/identity.js ***!
3669  \**************************************************************/
3670/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3671
3672__webpack_require__.r(__webpack_exports__);
3673/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3674/* harmony export */   "identity": () => (/* binding */ identity)
3675/* harmony export */ });
3676function identity(x) {
3677  return x;
3678}
3679
3680/***/ }),
3681
3682/***/ 4327:
3683/*!*************************************************************!*\
3684  !*** ./node_modules/rxjs/_esm2015/internal/util/isArray.js ***!
3685  \*************************************************************/
3686/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3687
3688__webpack_require__.r(__webpack_exports__);
3689/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3690/* harmony export */   "isArray": () => (/* binding */ isArray)
3691/* harmony export */ });
3692const isArray = (() => Array.isArray || (x => x && typeof x.length === 'number'))();
3693
3694/***/ }),
3695
3696/***/ 5122:
3697/*!*****************************************************************!*\
3698  !*** ./node_modules/rxjs/_esm2015/internal/util/isArrayLike.js ***!
3699  \*****************************************************************/
3700/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3701
3702__webpack_require__.r(__webpack_exports__);
3703/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3704/* harmony export */   "isArrayLike": () => (/* binding */ isArrayLike)
3705/* harmony export */ });
3706const isArrayLike = x => x && typeof x.length === 'number' && typeof x !== 'function';
3707
3708/***/ }),
3709
3710/***/ 1900:
3711/*!****************************************************************!*\
3712  !*** ./node_modules/rxjs/_esm2015/internal/util/isFunction.js ***!
3713  \****************************************************************/
3714/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3715
3716__webpack_require__.r(__webpack_exports__);
3717/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3718/* harmony export */   "isFunction": () => (/* binding */ isFunction)
3719/* harmony export */ });
3720function isFunction(x) {
3721  return typeof x === 'function';
3722}
3723
3724/***/ }),
3725
3726/***/ 5781:
3727/*!*************************************************************************!*\
3728  !*** ./node_modules/rxjs/_esm2015/internal/util/isInteropObservable.js ***!
3729  \*************************************************************************/
3730/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3731
3732__webpack_require__.r(__webpack_exports__);
3733/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3734/* harmony export */   "isInteropObservable": () => (/* binding */ isInteropObservable)
3735/* harmony export */ });
3736/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../symbol/observable */ 6831);
3737
3738function isInteropObservable(input) {
3739  return input && typeof input[_symbol_observable__WEBPACK_IMPORTED_MODULE_0__.observable] === 'function';
3740}
3741
3742/***/ }),
3743
3744/***/ 9674:
3745/*!****************************************************************!*\
3746  !*** ./node_modules/rxjs/_esm2015/internal/util/isIterable.js ***!
3747  \****************************************************************/
3748/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3749
3750__webpack_require__.r(__webpack_exports__);
3751/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3752/* harmony export */   "isIterable": () => (/* binding */ isIterable)
3753/* harmony export */ });
3754/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../symbol/iterator */ 2803);
3755
3756function isIterable(input) {
3757  return input && typeof input[_symbol_iterator__WEBPACK_IMPORTED_MODULE_0__.iterator] === 'function';
3758}
3759
3760/***/ }),
3761
3762/***/ 6549:
3763/*!**************************************************************!*\
3764  !*** ./node_modules/rxjs/_esm2015/internal/util/isObject.js ***!
3765  \**************************************************************/
3766/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3767
3768__webpack_require__.r(__webpack_exports__);
3769/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3770/* harmony export */   "isObject": () => (/* binding */ isObject)
3771/* harmony export */ });
3772function isObject(x) {
3773  return x !== null && typeof x === 'object';
3774}
3775
3776/***/ }),
3777
3778/***/ 5192:
3779/*!***************************************************************!*\
3780  !*** ./node_modules/rxjs/_esm2015/internal/util/isPromise.js ***!
3781  \***************************************************************/
3782/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3783
3784__webpack_require__.r(__webpack_exports__);
3785/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3786/* harmony export */   "isPromise": () => (/* binding */ isPromise)
3787/* harmony export */ });
3788function isPromise(value) {
3789  return !!value && typeof value.subscribe !== 'function' && typeof value.then === 'function';
3790}
3791
3792/***/ }),
3793
3794/***/ 7507:
3795/*!*****************************************************************!*\
3796  !*** ./node_modules/rxjs/_esm2015/internal/util/isScheduler.js ***!
3797  \*****************************************************************/
3798/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3799
3800__webpack_require__.r(__webpack_exports__);
3801/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3802/* harmony export */   "isScheduler": () => (/* binding */ isScheduler)
3803/* harmony export */ });
3804function isScheduler(value) {
3805  return value && typeof value.schedule === 'function';
3806}
3807
3808/***/ }),
3809
3810/***/ 6882:
3811/*!**********************************************************!*\
3812  !*** ./node_modules/rxjs/_esm2015/internal/util/noop.js ***!
3813  \**********************************************************/
3814/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3815
3816__webpack_require__.r(__webpack_exports__);
3817/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3818/* harmony export */   "noop": () => (/* binding */ noop)
3819/* harmony export */ });
3820function noop() {}
3821
3822/***/ }),
3823
3824/***/ 6800:
3825/*!**********************************************************!*\
3826  !*** ./node_modules/rxjs/_esm2015/internal/util/pipe.js ***!
3827  \**********************************************************/
3828/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3829
3830__webpack_require__.r(__webpack_exports__);
3831/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3832/* harmony export */   "pipe": () => (/* binding */ pipe),
3833/* harmony export */   "pipeFromArray": () => (/* binding */ pipeFromArray)
3834/* harmony export */ });
3835/* harmony import */ var _identity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./identity */ 1356);
3836
3837function pipe(...fns) {
3838  return pipeFromArray(fns);
3839}
3840function pipeFromArray(fns) {
3841  if (fns.length === 0) {
3842    return _identity__WEBPACK_IMPORTED_MODULE_0__.identity;
3843  }
3844
3845  if (fns.length === 1) {
3846    return fns[0];
3847  }
3848
3849  return function piped(input) {
3850    return fns.reduce((prev, fn) => fn(prev), input);
3851  };
3852}
3853
3854/***/ }),
3855
3856/***/ 6983:
3857/*!*****************************************************************!*\
3858  !*** ./node_modules/rxjs/_esm2015/internal/util/subscribeTo.js ***!
3859  \*****************************************************************/
3860/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3861
3862__webpack_require__.r(__webpack_exports__);
3863/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3864/* harmony export */   "subscribeTo": () => (/* binding */ subscribeTo)
3865/* harmony export */ });
3866/* harmony import */ var _subscribeToArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./subscribeToArray */ 5414);
3867/* harmony import */ var _subscribeToPromise__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./subscribeToPromise */ 4276);
3868/* harmony import */ var _subscribeToIterable__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./subscribeToIterable */ 6473);
3869/* harmony import */ var _subscribeToObservable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./subscribeToObservable */ 1492);
3870/* harmony import */ var _isArrayLike__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./isArrayLike */ 5122);
3871/* harmony import */ var _isPromise__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./isPromise */ 5192);
3872/* harmony import */ var _isObject__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./isObject */ 6549);
3873/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../symbol/iterator */ 2803);
3874/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../symbol/observable */ 6831);
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884const subscribeTo = result => {
3885  if (!!result && typeof result[_symbol_observable__WEBPACK_IMPORTED_MODULE_0__.observable] === 'function') {
3886    return (0,_subscribeToObservable__WEBPACK_IMPORTED_MODULE_1__.subscribeToObservable)(result);
3887  } else if ((0,_isArrayLike__WEBPACK_IMPORTED_MODULE_2__.isArrayLike)(result)) {
3888    return (0,_subscribeToArray__WEBPACK_IMPORTED_MODULE_3__.subscribeToArray)(result);
3889  } else if ((0,_isPromise__WEBPACK_IMPORTED_MODULE_4__.isPromise)(result)) {
3890    return (0,_subscribeToPromise__WEBPACK_IMPORTED_MODULE_5__.subscribeToPromise)(result);
3891  } else if (!!result && typeof result[_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__.iterator] === 'function') {
3892    return (0,_subscribeToIterable__WEBPACK_IMPORTED_MODULE_7__.subscribeToIterable)(result);
3893  } else {
3894    const value = (0,_isObject__WEBPACK_IMPORTED_MODULE_8__.isObject)(result) ? 'an invali
3894d object' : `'${result}'`;
3895    const msg = `You provided ${value} where a stream was expected.` + ' You can provide an Observable, Promise, Array, or Iterable.';
3896    throw new TypeError(msg);
3897  }
3898};
3899
3900/***/ }),
3901
3902/***/ 5414:
3903/*!**********************************************************************!*\
3904  !*** ./node_modules/rxjs/_esm2015/internal/util/subscribeToArray.js ***!
3905  \**********************************************************************/
3906/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3907
3908__webpack_require__.r(__webpack_exports__);
3909/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3910/* harmony export */   "subscribeToArray": () => (/* binding */ subscribeToArray)
3911/* harmony export */ });
3912const subscribeToArray = array => subscriber => {
3913  for (let i = 0, len = array.length; i < len && !subscriber.closed; i++) {
3914    subscriber.next(array[i]);
3915  }
3916
3917  subscriber.complete();
3918};
3919
3920/***/ }),
3921
3922/***/ 6473:
3923/*!*************************************************************************!*\
3924  !*** ./node_modules/rxjs/_esm2015/internal/util/subscribeToIterable.js ***!
3925  \*************************************************************************/
3926/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3927
3928__webpack_require__.r(__webpack_exports__);
3929/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3930/* harmony export */   "subscribeToIterable": () => (/* binding */ subscribeToIterable)
3931/* harmony export */ });
3932/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../symbol/iterator */ 2803);
3933
3934const subscribeToIterable = iterable => subscriber => {
3935  const iterator = iterable[_symbol_iterator__WEBPACK_IMPORTED_MODULE_0__.iterator]();
3936
3937  do {
3938    let item;
3939
3940    try {
3941      item = iterator.next();
3942    } catch (err) {
3943      subscriber.error(err);
3944      return subscriber;
3945    }
3946
3947    if (item.done) {
3948      subscriber.complete();
3949      break;
3950    }
3951
3952    subscriber.next(item.value);
3953
3954    if (subscriber.closed) {
3955      break;
3956    }
3957  } while (true);
3958
3959  if (typeof iterator.return === 'function') {
3960    subscriber.add(() => {
3961      if (iterator.return) {
3962        iterator.return();
3963      }
3964    });
3965  }
3966
3967  return subscriber;
3968};
3969
3970/***/ }),
3971
3972/***/ 1492:
3973/*!***************************************************************************!*\
3974  !*** ./node_modules/rxjs/_esm2015/internal/util/subscribeToObservable.js ***!
3975  \***************************************************************************/
3976/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3977
3978__webpack_require__.r(__webpack_exports__);
3979/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3980/* harmony export */   "subscribeToObservable": () => (/* binding */ subscribeToObservable)
3981/* harmony export */ });
3982/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../symbol/observable */ 6831);
3983
3984const subscribeToObservable = obj => subscriber => {
3985  const obs = obj[_symbol_observable__WEBPACK_IMPORTED_MODULE_0__.observable]();
3986
3987  if (typeof obs.subscribe !== 'function') {
3988    throw new TypeError('Provided object does not correctly implement Symbol.observable');
3989  } else {
3990    return obs.subscribe(subscriber);
3991  }
3992};
3993
3994/***/ }),
3995
3996/***/ 4276:
3997/*!************************************************************************!*\
3998  !*** ./node_modules/rxjs/_esm2015/internal/util/subscribeToPromise.js ***!
3999  \************************************************************************/
4000/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4001
4002__webpack_require__.r(__webpack_exports__);
4003/* harmony export */ __webpack_require__.d(__webpack_exports__, {
4004/* harmony export */   "subscribeToPromise": () => (/* binding */ subscribeToPromise)
4005/* harmony export */ });
4006/* harmony import */ var _hostReportError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./hostReportError */ 8897);
4007
4008const subscribeToPromise = promise => subscriber => {
4009  promise.then(value => {
4010    if (!subscriber.closed) {
4011      subscriber.next(value);
4012      subscriber.complete();
4013    }
4014  }, err => subscriber.error(err)).then(null, _hostReportError__WEBPACK_IMPORTED_MODULE_0__.hostReportError);
4015  return subscriber;
4016};
4017
4018/***/ }),
4019
4020/***/ 640:
4021/*!***********************************************************************!*\
4022  !*** ./node_modules/rxjs/_esm2015/internal/util/subscribeToResult.js ***!
4023  \***********************************************************************/
4024/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4025
4026__webpack_require__.r(__webpack_exports__);
4027/* harmony export */ __webpack_require__.d(__webpack_exports__, {
4028/* harmony export */   "subscribeToResult": () => (/* binding */ subscribeToResult)
4029/* harmony export */ });
4030/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../InnerSubscriber */ 472);
4031/* harmony import */ var _subscribeTo__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./subscribeTo */ 6983);
4032/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Observable */ 2378);
4033
4034
4035
4036function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_0__.InnerSubscriber(outerSubscriber, outerValue, outerIndex)) {
4037  if (innerSubscriber.closed) {
4038    return undefined;
4039  }
4040
4041  if (result instanceof _Observable__WEBPACK_IMPORTED_MODULE_1__.Observable) {
4042    return result.subscribe(innerSubscriber);
4043  }
4044
4045  return (0,_subscribeTo__WEBPACK_IMPORTED_MODULE_2__.subscribeTo)(result)(innerSubscriber);
4046}
4047
4048/***/ }),
4049
4050/***/ 8333:
4051/*!******************************************************************!*\
4052  !*** ./node_modules/rxjs/_esm2015/internal/util/toSubscriber.js ***!
4053  \******************************************************************/
4054/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4055
4056__webpack_require__.r(__webpack_exports__);
4057/* harmony export */ __webpack_require__.d(__webpack_exports__, {
4058/* harmony export */   "toSubscriber": () => (/* binding */ toSubscriber)
4059/* harmony export */ });
4060/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 14);
4061/* harmony import */ var _symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../symbol/rxSubscriber */ 1482);
4062/* harmony import */ var _Observer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Observer */ 9957);
4063
4064
4065
4066function toSubscriber(nextOrObserver, error, complete) {
4067  if (nextOrObserver) {
4068    if (nextOrObserver instanceof _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber) {
4069      return nextOrObserver;
4070    }
4071
4072    if (nextOrObserver[_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_1__.rxSubscriber]) {
4073      return nextOrObserver[_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_1__.rxSubscriber]();
4074    }
4075  }
4076
4077  if (!nextOrObserver && !error && !complete) {
4078    return new _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber(_Observer__WEBPACK_IMPORTED_MODULE_2__.empty);
4079  }
4080
4081  return new _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber(nextOrObserver, error, complete);
4082}
4083
4084/***/ }),
4085
4086/***/ 4929:
4087/*!*****************************************!*\
4088  !*** ./node_modules/tslib/tslib.es6.js ***!
4089  \*****************************************/
4090/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4091
4092__webpack_require__.r(__webpack_exports__);
4093/* harmony export */ __webpack_require__.d(__webpack_exports__, {
4094/* harmony export */   "__assign": () => (/* binding */ __assign),
4095/* harmony export */   "__asyncDelegator": () => (/* binding */ __asyncDelegator),
4096/* harmony export */   "__asyncGenerator": () => (/* binding */ __asyncGenerator),
4097/* harmony export */   "__asyncValues": () => (/* binding */ __asyncValues),
4098/* harmony export */   "__await": () => (/* binding */ __await),
4099/* harmony export */   "__awaiter": () => (/* binding */ __awaiter),
4100/* harmony export */   "__classPrivateFieldGet": () => (/* binding */ __classPrivateFieldGet),
4101/* harmony export */   "__classPrivateFieldSet": () => (/* binding */ __classPrivateFieldSet),
4102/* harmony export */   "__createBinding": () => (/* binding */ __createBinding),
vendor: 4,739 bytes, lines 4103-4192
4103/* harmony export */   "__decorate": () => (/* binding */ __decorate),
4104/* harmony export */   "__exportStar": () => (/* binding */ __exportStar),
4105/* harmony export */   "__extends": () => (/* binding */ __extends),
4106/* harmony export */   "__generator": () => (/* binding */ __generator),
4107/* harmony export */   "__importDefault": () => (/* binding */ __importDefault),
4108/* harmony export */   "__importStar": () => (/* binding */ __importStar),
4109/* harmony export */   "__makeTemplateObject": () => (/* binding */ __makeTemplateObject),
4110/* harmony export */   "__metadata": () => (/* binding */ __metadata),
4111/* harmony export */   "__param": () => (/* binding */ __param),
4112/* harmony export */   "__read": () => (/* binding */ __read),
4113/* harmony export */   "__rest": () => (/* binding */ __rest),
4114/* harmony export */   "__spread": () => (/* binding */ __spread),
4115/* harmony export */   "__spreadArrays": () => (/* binding */ __spreadArrays),
4116/* harmony export */   "__values": () => (/* binding */ __values)
4117/* harmony export */ });
4118/*! *****************************************************************************
4119Copyright (c) Microsoft Corporation.
4120
4121Permission to use, copy, modify, and/or distribute this software for any
4122purpose with or without fee is hereby granted.
4123
4124THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
4125REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
4126AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
4127INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
4128LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
4129OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
4130PERFORMANCE OF THIS SOFTWARE.
4131***************************************************************************** */
4132/* global Reflect, Promise */
4133
4134var extendStatics = function(d, b) {
4135    extendStatics = Object.setPrototypeOf ||
4136        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4137        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
4138    return extendStatics(d, b);
4139};
4140
4141function __extends(d, b) {
4142    extendStatics(d, b);
4143    function __() { this.constructor = d; }
4144    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
4145}
4146
4147var __assign = function() {
4148    __assign = Object.assign || function __assign(t) {
4149        for (var s, i = 1, n = arguments.length; i < n; i++) {
4150            s = arguments[i];
4151            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
4152        }
4153        return t;
4154    }
4155    return __assign.apply(this, arguments);
4156}
4157
4158function __rest(s, e) {
4159    var t = {};
4160    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4161        t[p] = s[p];
4162    if (s != null && typeof Object.getOwnPropertySymbols === "function")
4163        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
4164            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
4165                t[p[i]] = s[p[i]];
4166        }
4167    return t;
4168}
4169
4170function __decorate(decorators, target, key, desc) {
4171    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4172    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4173    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4174    return c > 3 && r && Object.defineProperty(target, key, r), r;
4175}
4176
4177function __param(paramIndex, decorator) {
4178    return function (target, key) { decorator(target, key, paramIndex); }
4179}
4180
4181function __metadata(metadataKey, metadataValue) {
4182    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
4183}
4184
4185function __awaiter(thisArg, _arguments, P, generator) {
4186    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4187    return new (P || (P = Promise))(function (resolve, reject) {
4188        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
4189        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
4190        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
4191        step((generator = generator.apply(thisArg, _arguments || [])).next());
4192    });
vendor: 5,103 bytes, lines 4193-4302
4193}
4194
4195function __generator(thisArg, body) {
4196    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
4197    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
4198    function verb(n) { return function (v) { return step([n, v]); }; }
4199    function step(op) {
4200        if (f) throw new TypeError("Generator is already executing.");
4201        while (_) try {
4202            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
4203            if (y = 0, t) op = [op[0] & 2, t.value];
4204            switch (op[0]) {
4205                case 0: case 1: t = op; break;
4206                case 4: _.label++; return { value: op[1], done: false };
4207                case 5: _.label++; y = op[1]; op = [0]; continue;
4208                case 7: op = _.ops.pop(); _.trys.pop(); continue;
4209                default:
4210                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
4211                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
4212                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
4213                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
4214                    if (t[2]) _.ops.pop();
4215                    _.trys.pop(); continue;
4216            }
4217            op = body.call(thisArg, _);
4218        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
4219        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
4220    }
4221}
4222
4223var __createBinding = Object.create ? (function(o, m, k, k2) {
4224    if (k2 === undefined) k2 = k;
4225    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4226}) : (function(o, m, k, k2) {
4227    if (k2 === undefined) k2 = k;
4228    o[k2] = m[k];
4229});
4230
4231function __exportStar(m, o) {
4232    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
4233}
4234
4235function __values(o) {
4236    var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
4237    if (m) return m.call(o);
4238    if (o && typeof o.length === "number") return {
4239        next: function () {
4240            if (o && i >= o.length) o = void 0;
4241            return { value: o && o[i++], done: !o };
4242        }
4243    };
4244    throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
4245}
4246
4247function __read(o, n) {
4248    var m = typeof Symbol === "function" && o[Symbol.iterator];
4249    if (!m) return o;
4250    var i = m.call(o), r, ar = [], e;
4251    try {
4252        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
4253    }
4254    catch (error) { e = { error: error }; }
4255    finally {
4256        try {
4257            if (r && !r.done && (m = i["return"])) m.call(i);
4258        }
4259        finally { if (e) throw e.error; }
4260    }
4261    return ar;
4262}
4263
4264function __spread() {
4265    for (var ar = [], i = 0; i < arguments.length; i++)
4266        ar = ar.concat(__read(arguments[i]));
4267    return ar;
4268}
4269
4270function __spreadArrays() {
4271    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
4272    for (var r = Array(s), k = 0, i = 0; i < il; i++)
4273        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
4274            r[k] = a[j];
4275    return r;
4276};
4277
4278function __await(v) {
4279    return this instanceof __await ? (this.v = v, this) : new __await(v);
4280}
4281
4282function __asyncGenerator(thisArg, _arguments, generator) {
4283    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
4284    var g = generator.apply(thisArg, _arguments || []), i, q = [];
4285    return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
4286    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
4287    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
4288    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
4289    function fulfill(value) { resume("next", value); }
4290    function reject(value) { resume("throw", value); }
4291    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
4292}
4293
4294function __asyncDelegator(o) {
4295    var i, p;
4296    return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
4297    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
4298}
4299
4300function __asyncValues(o) {
4301    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
4302    var m = o[Symbol.asyncIterator], i;
vendor: 5,690 bytes, lines 4303-4456
4303    return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
4304    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
4305    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
4306}
4307
4308function __makeTemplateObject(cooked, raw) {
4309    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4310    return cooked;
4311};
4312
4313var __setModuleDefault = Object.create ? (function(o, v) {
4314    Object.defineProperty(o, "default", { enumerable: true, value: v });
4315}) : function(o, v) {
4316    o["default"] = v;
4317};
4318
4319function __importStar(mod) {
4320    if (mod && mod.__esModule) return mod;
4321    var result = {};
4322    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
4323    __setModuleDefault(result, mod);
4324    return result;
4325}
4326
4327function __importDefault(mod) {
4328    return (mod && mod.__esModule) ? mod : { default: mod };
4329}
4330
4331function __classPrivateFieldGet(receiver, privateMap) {
4332    if (!privateMap.has(receiver)) {
4333        throw new TypeError("attempted to get private field on non-instance");
4334    }
4335    return privateMap.get(receiver);
4336}
4337
4338function __classPrivateFieldSet(receiver, privateMap, value) {
4339    if (!privateMap.has(receiver)) {
4340        throw new TypeError("attempted to set private field on non-instance");
4341    }
4342    privateMap.set(receiver, value);
4343    return value;
4344}
4345
4346
4347/***/ }),
4348
4349/***/ 4851:
4350/*!******************************************************************!*\
4351  !*** ./node_modules/@angular/animations/fesm2020/animations.mjs ***!
4352  \******************************************************************/
4353/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
4354
4355__webpack_require__.r(__webpack_exports__);
4356/* harmony export */ __webpack_require__.d(__webpack_exports__, {
4357/* harmony export */   "AUTO_STYLE": () => (/* binding */ AUTO_STYLE),
4358/* harmony export */   "AnimationBuilder": () => (/* binding */ AnimationBuilder),
4359/* harmony export */   "AnimationFactory": () => (/* binding */ AnimationFactory),
4360/* harmony export */   "NoopAnimationPlayer": () => (/* binding */ NoopAnimationPlayer),
4361/* harmony export */   "animate": () => (/* binding */ animate),
4362/* harmony export */   "animateChild": () => (/* binding */ animateChild),
4363/* harmony export */   "animation": () => (/* binding */ animation),
4364/* harmony export */   "group": () => (/* binding */ group),
4365/* harmony export */   "keyframes": () => (/* binding */ keyframes),
4366/* harmony export */   "query": () => (/* binding */ query),
4367/* harmony export */   "sequence": () => (/* binding */ sequence),
4368/* harmony export */   "stagger": () => (/* binding */ stagger),
4369/* harmony export */   "state": () => (/* binding */ state),
4370/* harmony export */   "style": () => (/* binding */ style),
4371/* harmony export */   "transition": () => (/* binding */ transition),
4372/* harmony export */   "trigger": () => (/* binding */ trigger),
4373/* harmony export */   "useAnimation": () => (/* binding */ useAnimation),
4374/* harmony export */   "ɵAnimationGroupPlayer": () => (/* binding */ AnimationGroupPlayer),
4375/* harmony export */   "ɵPRE_STYLE": () => (/* binding */ ɵPRE_STYLE)
4376/* harmony export */ });
4377/**
4378 * @license Angular v14.2.10
4379 * (c) 2010-2022 Google LLC. https://angular.io/
4380 * License: MIT
4381 */
4382
4383/**
4384 * An injectable service that produces an animation sequence programmatically within an
4385 * Angular component or directive.
4386 * Provided by the `BrowserAnimationsModule` or `NoopAnimationsModule`.
4387 *
4388 * @usageNotes
4389 *
4390 * To use this service, add it to your component or directive as a dependency.
4391 * The service is instantiated along with your component.
4392 *
4393 * Apps do not typically need to create their own animation players, but if you
4394 * do need to, follow these steps:
4395 *
4396 * 1. Use the <code>[AnimationBuilder.build](api/animations/AnimationBuilder#build)()</code> method
4397 * to create a programmatic animation. The method returns an `AnimationFactory` instance.
4398 *
4399 * 2. Use the factory object to create an `AnimationPlayer` and attach it to a DOM element.
4400 *
4401 * 3. Use the player object to control the animation programmatically.
4402 *
4403 * For example:
4404 *
4405 * ```ts
4406 * // import the service from BrowserAnimationsModule
4407 * import {AnimationBuilder} from '@angular/animations';
4408 * // require the service as a dependency
4409 * class MyCmp {
4410 *   constructor(private _builder: AnimationBuilder) {}
4411 *
4412 *   makeAnimation(element: any) {
4413 *     // first define a reusable animation
4414 *     const myAnimation = this._builder.build([
4415 *       style({ width: 0 }),
4416 *       animate(1000, style({ width: '100px' }))
4417 *     ]);
4418 *
4419 *     // use the returned factory object to create a player
4420 *     const player = myAnimation.create(element);
4421 *
4422 *     player.play();
4423 *   }
4424 * }
4425 * ```
4426 *
4427 * @publicApi
4428 */
4429class AnimationBuilder {}
4430/**
4431 * A factory object returned from the
4432 * <code>[AnimationBuilder.build](api/animations/AnimationBuilder#build)()</code>
4433 * method.
4434 *
4435 * @publicApi
4436 */
4437
4438
4439class AnimationFactory {}
4440/**
4441 * @license
4442 * Copyright Google LLC All Rights Reserved.
4443 *
4444 * Use of this source code is governed by an MIT-style license that can be
4445 * found in the LICENSE file at https://angular.io/license
4446 */
4447
4448/**
4449 * Specifies automatic styling.
4450 *
4451 * @publicApi
4452 */
4453
4454
4455const AUTO_STYLE = '*';
4456/**
4457 * Creates a named animation trigger, containing a  list of [`state()`](api/animations/state)
4458 * and `transition()` entries to be evaluated when the expression
4459 * bound to the trigger changes.
4460 *
4461 * @param name An identifying string.
4462 * @param definitions  An animation definition object, containing an array of
4463 * [`state()`](api/animations/state) and `transition()` declarations.
4464 *
4465 * @return An object that encapsulates the trigger data.
4466 *
4467 * @usageNotes
4468 * Define an animation trigger in the `animations` section of `@Component` metadata.
4469 * In the template, reference the trigger by name and bind it to a trigger expression that
4470 * evaluates to a defined animation state, using the following format:
4471 *
4472 * `[@triggerName]="expression"`
4473 *
4474 * Animation trigger bindings convert all values to strings, and then match the
4475 * previous and current values against any linked transitions.
4476 * Booleans can be specified as `1` or `true` and `0` or `false`.
4477 *
4478 * ### Usage Example
4479 *
4480 * The following example creates an animation trigger reference based on the provided
4481 * name value.
4482 * The provided animation value is expected to be an array consisting of state and
4483 * transition declarations.
4484 *
4485 * ```typescript
4486 * @Component({
4487 *   selector: "my-component",
4488 *   templateUrl: "my-component-tpl.html",
4489 *   animations: [
4490 *     trigger("myAnimationTrigger", [
4491 *       state(...),
4492 *       state(...),
4493 *       transition(...),
4494 *       transition(...)
4495 *     ])
4496 *   ]
4497 * })
4498 * class MyComponent {
4499 *   myStatusExp = "something";
4500 * }
4501 * ```
4502 *
4503 * The template associated with this component makes use of the defined trigger
4504 * by binding to an element within its template code.
4505 *
4506 * ```html
4507 * <!-- somewhere inside of my-component-tpl.html -->
4508 * <div [@myAnimationTrigger]="myStatusExp">...</div>
4509 * ```
4510 *
4511 * ### Using an inline function
4512 * The `transition` animation method also supports reading an inline function which can decide
4513 * if its associated animation should be run.
4514 *
4515 * ```typescript
4516 * // this method is run each time the `myAnimationTrigger` trigger value changes.
4517 * function myInlineMatcherFn(fromState: string, toState: string, element: any, params: {[key:
4518 string]: any}): boolean {
4519 *   // notice that `element` and `params` are also available here
4520 *   return toState == 'yes-please-animate';
4521 * }
4522 *
4523 * @Component({
4524 *   selector: 'my-component',
4525 *   templateUrl: 'my-component-tpl.html',
4526 *   animations: [
4527 *     trigger('myAnimationTrigger', [
4528 *       transition(myInlineMatcherFn, [
4529 *         // the animation sequence code
4530 *       ]),
4531 *     ])
4532 *   ]
4533 * })
4534 * class MyComponent {
4535 *   myStatusExp = "yes-please-animate";
4536 * }
4537 * ```
4538 *
4539 * ### Disabling Animations
4540 * When true, the special animation control binding `@.disabled` binding prevents
4541 * all animations from rendering.
4542 * Place the  `@.disabled` binding on an element to disable
4543 * animations on the element itself, as well as any inner animation triggers
4544 * within the element.
4545 *
4546 * The following example shows how to use this feature:
4547 *
4548 * ```typescript
4549 * @Component({
4550 *   selector: 'my-component',
4551 *   template: `
4552 *     <div [@.disabled]="isDisabled">
4553 *       <div [@childAnimation]="exp"></div>
4554 *     </div>
4555 *   `,
4556 *   animations: [
4557 *     trigger("childAnimation", [
4558 *       // ...
4559 *     ])
4560 *   ]
4561 * })
4562 * class MyComponent {
4563 *   isDisabled = true;
4564 *   exp = '...';
4565 * }
4566 * ```
4567 *
4568 * When `@.disabled` is true, it prevents the `@childAnimation` trigger from animating,
4569 * along with any inner animations.
4570 *
4571 * ### Disable animations application-wide
4572 * When an area of the template is set to have animations disabled,
4573 * **all** inner components have their animations disabled as well.
4574 * This means that you can disable all animations for an app
4575 * by placing a host binding set on `@.disabled` on the topmost Angular component.
4576 *
4577 * ```typescript
4578 * import {Component, HostBinding} from '@angular/core';
4579 *
4580 * @Component({
4581 *   selector: 'app-component',
4582 *   templateUrl: 'app.component.html',
4583 * })
4584 * class AppComponent {
4585 *   @HostBinding('@.disabled')
4586 *   public animationsDisabled = true;
4587 * }
4588 * ```
4589 *
4590 * ### Overriding disablement of inner animations
4591 * Despite inner animations being disabled, a parent animation can `query()`
4592 * for inner elements located in disabled areas of the template and still animate
4593 * them if needed. This is also the case for when a sub animation is
4594 * queried by a parent and then later animated using `animateChild()`.
4595 *
4596 * ### Detecting when an animation is disabled
4597 * If a region of the DOM (or the entire application) has its animations disabled, the animation
4598 * trigger callbacks still fire, but for zero seconds. When the callback fires, it provides
4599 * an instance of an `AnimationEvent`. If animations are disabled,
4600 * the `.disabled` flag on the event is true.
4601 *
4602 * @publicApi
4603 */
4604
4605function trigger(name, definitions) {
4606  return {
4607    type: 7
4608    /* AnimationMetadataType.Trigger */
4609    ,
4610    name,
4611    definitions,
4612    options: {}
4613  };
4614}
4615/**
4616 * Defines an animation step that combines styling information with timing information.
4617 *
4618 * @param timings Sets `AnimateTimings` for the parent animation.
4619 * A string in the format "duration [delay] [easing]".
4620 *  - Duration and delay are expressed as a number and optional time unit,
4621 * such as "1s" or "10ms" for one second and 10 milliseconds, respectively.
4622 * The default unit is milliseconds.
4623 *  - The easing value controls how the animation accelerates and decelerates
4624 * during its runtime. Value is one of  `ease`, `ease-in`, `ease-out`,
4625 * `ease-in-out`, or a `cubic-bezier()` function call.
4626 * If not supplied, no easing is applied.
4627 *
4628 * For example, the string "1s 100ms ease-out" specifies a duration of
4629 * 1000 milliseconds, and delay of 100 ms, and the "ease-out" easing style,
4630 * which decelerates near the end of the duration.
4631 * @param styles Sets AnimationStyles for the parent animation.
4632 * A function call to either `style()` or `keyframes()`
4633 * that returns a collection of CSS style entries to be applied to the parent animation.
4634 * When null, uses the styles from the destination state.
4635 * This is useful when describing an animation step that will complete an animation;
4636 * see "Animating to the final state" in `transitions()`.
4637 * @returns An object that encapsulates the animation step.
4638 *
4639 * @usageNotes
4640 * Call within an animation `sequence()`, `{@link animations/group group()}`, or
4641 * `transition()` call to specify an animation step
4642 * that applies given style data to the parent animation for a given amount of time.
4643 *
4644 * ### Syntax Examples
4645 * **Timing examples**
4646 *
4647 * The following examples show various `timings` specifications.
4648 * - `animate(500)` : Duration is 500 milliseconds.
4649 * - `animate("1s")` : Duration is 1000 milliseconds.
4650 * - `animate("100ms 0.5s")` : Duration is 100 milliseconds, delay is 500 milliseconds.
4651 * - `animate("5s ease-in")` : Duration is 5000 milliseconds, easing in.
4652 * - `animate("5s 10ms cubic-bezier(.17,.67,.88,.1)")` : Duration is 5000 milliseconds, delay is 10
4653 * milliseconds, easing according to a bezier curve.
4654 *
4655 * **Style examples**
4656 *
4657 * The following example calls `style()` to set a single CSS style.
4658 * ```typescript
4659 * animate(500, style({ background: "red" }))
4660 * ```
4661 * The following example calls `keyframes()` to set a CSS style
4662 * to different values for successive keyframes.
4663 * ```typescript
4664 * animate(500, keyframes(
4665 *  [
4666 *   style({ background: "blue" }),
4667 *   style({ background: "red" })
4668 *  ])
4669 * ```
4670 *
4671 * @publicApi
4672 */
4673
4674
4675function animate(timings, styles = null) {
4676  return {
4677    type: 4
4678    /* AnimationMetadataType.Animate */
4679    ,
4680    styles,
4681    timings
4682  };
4683}
4684/**
4685 * @description Defines a list of animation steps to be run in parallel.
4686 *
4687 * @param steps An array of animation step objects.
4688 * - When steps are defined by `style()` or `animate()`
4689 * function calls, each call within the group is executed instantly.
4690 * - To specify offset styles to be applied at a later time, define steps with
4691 * `keyframes()`, or use `animate()` calls with a delay value.
4692 * For example:
4693 *
4694 * ```typescript
4695 * group([
4696 *   animate("1s", style({ background: "black" })),
4697 *   animate("2s", style({ color: "white" }))
4698 * ])
4699 * ```
4700 *
4701 * @param options An options object containing a delay and
4702 * developer-defined parameters that provide styling defaults and
4703 * can be overridden on invocation.
4704 *
4705 * @return An object that encapsulates the group data.
4706 *
4707 * @usageNotes
4708 * Grouped animations are useful when a series of styles must be
4709 * animated at different starting times and closed off at different ending times.
4710 *
4711 * When called within a `sequence()` or a
4712 * `transition()` call, does not continue to the next
4713 * instruction until all of the inner animation steps have completed.
4714 *
4715 * @publicApi
4716 */
4717
4718
4719function group(steps, options = null) {
4720  return {
4721    type: 3
4722    /* AnimationMetadataType.Group */
4723    ,
4724    steps,
4725    options
4726  };
4727}
4728/**
4729 * Defines a list of animation steps to be run sequentially, one by one.
4730 *
4731 * @param steps An array of animation step objects.
4732 * - Steps defined by `style()` calls apply the styling data immediately.
4733 * - Steps defined by `animate()` calls apply the styling data over time
4734 *   as specified by the timing data.
4735 *
4736 * ```typescript
4737 * sequence([
4738 *   style({ opacity: 0 }),
4739 *   animate("1s", style({ opacity: 1 }))
4740 * ])
4741 * ```
4742 *
4743 * @param options An options object containing a delay and
4744 * developer-defined parameters that provide styling defaults and
4745 * can be overridden on invocation.
4746 *
4747 * @return An object that encapsulates the sequence data.
4748 *
4749 * @usageNotes
4750 * When you pass an array of steps to a
4751 * `transition()` call, the steps run sequentially by default.
4752 * Compare this to the `{@link animations/group group()}` call, which runs animation steps in
4753 *parallel.
4754 *
4755 * When a sequence is used within a `{@link animations/group group()}` or a `transition()` call,
4756 * execution continues to the next instruction only after each of the inner animation
4757 * steps have completed.
4758 *
4759 * @publicApi
4760 **/
4761
4762
4763function sequence(steps, options = null) {
4764  return {
4765    type: 2
4766    /* AnimationMetadataType.Sequence */
4767    ,
4768    steps,
4769    options
4770  };
4771}
4772/**
4773 * Declares a key/value object containing CSS properties/styles that
4774 * can then be used for an animation [`state`](api/animations/state), within an animation
4775 *`sequence`, or as styling data for calls to `animate()` and `keyframes()`.
4776 *
4777 * @param tokens A set of CSS styles or HTML styles associated with an animation state.
4778 * The value can be any of the following:
4779 * - A key-value style pair associating a CSS property with a value.
4780 * - An array of key-value style pairs.
4781 * - An asterisk (*), to use auto-styling, where styles are derived from the element
4782 * being animated and applied to the animation when it starts.
4783 *
4784 * Auto-styling can be used to define a state that depends on layout or other
4785 * environmental factors.
4786 *
4787 * @return An object that encapsulates the style data.
4788 *
4789 * @usageNotes
4790 * The following examples create animation styles that collect a set of
4791 * CSS property values:
4792 *
4793 * ```typescript
4794 * // string values for CSS properties
4795 * style({ background: "red", color: "blue" })
4796 *
4797 * // numerical pixel values
4798 * style({ width: 100, height: 0 })
4799 * ```
4800 *
4801 * The following example uses auto-styling to allow an element to animate from
4802 * a height of 0 up to its full height:
4803 *
4804 * ```
4805 * style({ height: 0 }),
4806 * animate("1s", style({ height: "*" }))
4807 * ```
4808 *
4809 * @publicApi
4810 **/
4811
4812
4813function style(tokens) {
4814  return {
4815    type: 6
4816    /* AnimationMetadataType.Style */
4817    ,
4818    styles: tokens,
4819    offset: null
4820  };
4821}
4822/**
4823 * Declares an animation state within a trigger attached to an element.
4824 *
4825 * @param name One or more names for the defined state in a comma-separated string.
4826 * The following reserved state names can be supplied to define a style for specific use
4827 * cases:
4828 *
4829 * - `void` You can associate styles with this name to be used when
4830 * the element is detached from the application. For example, when an `ngIf` evaluates
4831 * to false, the state of the associated element is void.
4832 *  - `*` (asterisk) Indicates the default state. You can associate styles with this name
4833 * to be used as the fallback when the state that is being animated is not declared
4834 * within the trigger.
4835 *
4836 * @param styles A set of CSS styles associated with this state, created using the
4837 * `style()` function.
4838 * This set of styles persists on the element once the state has been reached.
4839 * @param options Parameters that can be passed to the state when it is invoked.
4840 * 0 or more key-value pairs.
4841 * @return An object that encapsulates the new state data.
4842 *
4843 * @usageNotes
4844 * Use the `trigger()` function to register states to an animation trigger.
4845 * Use the `transition()` function to animate between states.
4846 * When a state is active within a component, its associated styles persist on the element,
4847 * even when the animation ends.
4848 *
4849 * @publicApi
4850 **/
4851
4852
4853function state(name, styles, options) {
4854  return {
4855    type: 0
4856    /* AnimationMetadataType.State */
4857    ,
4858    name,
4859    styles,
4860    options
4861  };
4862}
4863/**
4864 * Defines a set of animation styles, associating each style with an optional `offset` value.
4865 *
4866 * @param steps A set of animation styles with optional offset data.
4867 * The optional `offset` value for a style specifies a percentage of the total animation
4868 * time at which that style is applied.
4869 * @returns An object that encapsulates the keyframes data.
4870 *
4871 * @usageNotes
4872 * Use with the `animate()` call. Instead of applying animations
4873 * from the current state
4874 * to the destination state, keyframes describe how each style entry is a
4874pplied and at what point
4875 * within the animation arc.
4876 * Compare [CSS Keyframe Animations](https://www.w3schools.com/css/css3_animations.asp).
4877 *
4878 * ### Usage
4879 *
4880 * In the following example, the offset values describe
4881 * when each `backgroundColor` value is applied. The color is red at the start, and changes to
4882 * blue when 20% of the total time has elapsed.
4883 *
4884 * ```typescript
4885 * // the provided offset values
4886 * animate("5s", keyframes([
4887 *   style({ backgroundColor: "red", offset: 0 }),
4888 *   style({ backgroundColor: "blue", offset: 0.2 }),
4889 *   style({ backgroundColor: "orange", offset: 0.3 }),
4890 *   style({ backgroundColor: "black", offset: 1 })
4891 * ]))
4892 * ```
4893 *
4894 * If there are no `offset` values specified in the style entries, the offsets
4895 * are calculated automatically.
4896 *
4897 * ```typescript
4898 * animate("5s", keyframes([
4899 *   style({ backgroundColor: "red" }) // offset = 0
4900 *   style({ backgroundColor: "blue" }) // offset = 0.33
4901 *   style({ backgroundColor: "orange" }) // offset = 0.66
4902 *   style({ backgroundColor: "black" }) // offset = 1
4903 * ]))
4904 *```
4905
4906 * @publicApi
4907 */
4908
4909
4910function keyframes(steps) {
4911  return {
4912    type: 5
4913    /* AnimationMetadataType.Keyframes */
4914    ,
4915    steps
4916  };
4917}
4918/**
4919 * Declares an animation transition which is played when a certain specified condition is met.
4920 *
4921 * @param stateChangeExpr A string with a specific format or a function that specifies when the
4922 * animation transition should occur (see [State Change Expression](#state-change-expression)).
4923 *
4924 * @param steps One or more animation objects that represent the animation's instructions.
4925 *
4926 * @param options An options object that can be used to specify a delay for the animation or provide
4927 * custom parameters for it.
4928 *
4929 * @returns An object that encapsulates the transition data.
4930 *
4931 * @usageNotes
4932 *
4933 * ### State Change Expression
4934 *
4935 * The State Change Expression instructs Angular when to run the transition's animations, it can
4936 *either be
4937 *  - a string with a specific syntax
4938 *  - or a function that compares the previous and current state (value of the expression bound to
4939 *    the element's trigger) and returns `true` if the transition should occur or `false` otherwise
4940 *
4941 * The string format can be:
4942 *  - `fromState => toState`, which indicates that the transition's animations should occur then the
4943 *    expression bound to the trigger's element goes from `fromState` to `toState`
4944 *
4945 *    _Example:_
4946 *      ```typescript
4947 *        transition('open => closed', animate('.5s ease-out', style({ height: 0 }) ))
4948 *      ```
4949 *
4950 *  - `fromState <=> toState`, which indicates that the transition's animations should occur then
4951 *    the expression bound to the trigger's element goes from `fromState` to `toState` or vice versa
4952 *
4953 *    _Example:_
4954 *      ```typescript
4955 *        transition('enabled <=> disabled', animate('1s cubic-bezier(0.8,0.3,0,1)'))
4956 *      ```
4957 *
4958 *  - `:enter`/`:leave`, which indicates that the transition's animations should occur when the
4959 *    element enters or exists the DOM
4960 *
4961 *    _Example:_
4962 *      ```typescript
4963 *        transition(':enter', [
4964 *          style({ opacity: 0 }),
4965 *          animate('500ms', style({ opacity: 1 }))
4966 *        ])
4967 *      ```
4968 *
4969 *  - `:increment`/`:decrement`, which indicates that the transition's animations should occur when
4970 *    the numerical expression bound to the trigger's element has increased in value or decreased
4971 *
4972 *    _Example:_
4973 *      ```typescript
4974 *        transition(':increment', query('@counter', animateChild()))
4975 *      ```
4976 *
4977 *  - a sequence of any of the above divided by commas, which indicates that transition's animations
4978 *    should occur whenever one of the state change expressions matches
4979 *
4980 *    _Example:_
4981 *      ```typescript
4982 *        transition(':increment, * => enabled, :enter', animate('1s ease', keyframes([
4983 *          style({ transform: 'scale(1)', offset: 0}),
4984 *          style({ transform: 'scale(1.1)', offset: 0.7}),
4985 *          style({ transform: 'scale(1)', offset: 1})
4986 *        ]))),
4987 *      ```
4988 *
4989 * Also note that in such context:
4990 *  - `void` can be used to indicate the absence of the element
4991 *  - asterisks can be used as wildcards that match any state
4992 *  - (as a consequence of the above, `void => *` is equivalent to `:enter` and `* => void` is
4993 *    equivalent to `:leave`)
4994 *  - `true` and `false` also match expression values of `1` and `0` respectively (but do not match
4995 *    _truthy_ and _falsy_ values)
4996 *
4997 * <div class="alert is-helpful">
4998 *
4999 *  Be careful about entering end leaving elements as their transitions present a common
5000 *  pitfall for developers.
5001 *
5002 *  Note that when an element with a trigger enters the DOM its `:enter` transition always
5003 *  gets executed, but its `:leave` transition will not be executed if the element is removed
5004 *  alongside its parent (as it will be removed "without warning" before its transition has
5005 *  a chance to be executed, the only way that such transition can occur is if the element
5006 *  is exiting the DOM on its own).
5007 *
5008 *
5009 * </div>
5010 *
5011 * ### Animating to a Final State
5012 *
5013 * If the final step in a transition is a call to `animate()` that uses a timing value
5014 * with no `style` data, that step is automatically considered the final animation arc,
5015 * for the element to reach the final state, in such case Angular automatically adds or removes
5016 * CSS styles to ensure that the element is in the correct final state.
5017 *
5018 *
5019 * ### Usage Examples
5020 *
5021 *  - Transition animations applied based on
5022 *    the trigger's expression value
5023 *
5024 *   ```HTML
5025 *   <div [@myAnimationTrigger]="myStatusExp">
5026 *    ...
5027 *   </div>
5028 *   ```
5029 *
5030 *   ```typescript
5031 *   trigger("myAnimationTrigger", [
5032 *     ..., // states
5033 *     transition("on => off, open => closed", animate(500)),
5034 *     transition("* <=> error", query('.indicator', animateChild()))
5035 *   ])
5036 *   ```
5037 *
5038 *  - Transition animations applied based on custom logic dependent
5039 *    on the trigger's expression value and provided parameters
5040 *
5041 *    ```HTML
5042 *    <div [@myAnimationTrigger]="{
5043 *     value: stepName,
5044 *     params: { target: currentTarget }
5045 *    }">
5046 *     ...
5047 *    </div>
5048 *    ```
5049 *
5050 *    ```typescript
5051 *    trigger("myAnimationTrigger", [
5052 *      ..., // states
5053 *      transition(
5054 *        (fromState, toState, _element, params) =>
5055 *          ['firststep', 'laststep'].includes(fromState.toLowerCase())
5056 *          && toState === params?.['target'],
5057 *        animate('1s')
5058 *      )
5059 *    ])
5060 *    ```
5061 *
5062 * @publicApi
5063 **/
5064
5065
5066function transition(stateChangeExpr, steps, options = null) {
5067  return {
5068    type: 1
5069    /* AnimationMetadataType.Transition */
5070    ,
5071    expr: stateChangeExpr,
5072    animation: steps,
5073    options
5074  };
5075}
5076/**
5077 * Produces a reusable animation that can be invoked in another animation or sequence,
5078 * by calling the `useAnimation()` function.
5079 *
5080 * @param steps One or more animation objects, as returned by the `animate()`
5081 * or `sequence()` function, that form a transformation from one state to another.
5082 * A sequence is used by default when you pass an array.
5083 * @param options An options object that can contain a delay value for the start of the
5084 * animation, and additional developer-defined parameters.
5085 * Provided values for additional parameters are used as defaults,
5086 * and override values can be passed to the caller on invocation.
5087 * @returns An object that encapsulates the animation data.
5088 *
5089 * @usageNotes
5090 * The following example defines a reusable animation, providing some default parameter
5091 * values.
5092 *
5093 * ```typescript
5094 * var fadeAnimation = animation([
5095 *   style({ opacity: '{{ start }}' }),
5096 *   animate('{{ time }}',
5097 *   style({ opacity: '{{ end }}'}))
5098 *   ],
5099 *   { params: { time: '1000ms', start: 0, end: 1 }});
5100 * ```
5101 *
5102 * The following invokes the defined animation with a call to `useAnimation()`,
5103 * passing in override parameter values.
5104 *
5105 * ```js
5106 * useAnimation(fadeAnimation, {
5107 *   params: {
5108 *     time: '2s',
5109 *     start: 1,
5110 *     end: 0
5111 *   }
5112 * })
5113 * ```
5114 *
5115 * If any of the passed-in parameter values are missing from this call,
5116 * the default values are used. If one or more parameter values are missing before a step is
5117 * animated, `useAnimation()` throws an error.
5118 *
5119 * @publicApi
5120 */
5121
5122
5123function animation(steps, options = null) {
5124  return {
5125    type: 8
5126    /* AnimationMetadataType.Reference */
5127    ,
5128    animation: steps,
5129    options
5130  };
5131}
5132/**
5133 * Executes a queried inner animation element within an animation sequence.
5134 *
5135 * @param options An options object that can contain a delay value for the start of the
5136 * animation, and additional override values for developer-defined parameters.
5137 * @return An object that encapsulates the child animation data.
5138 *
5139 * @usageNotes
5140 * Each time an animation is triggered in Angular, the parent animation
5141 * has priority and any child animations are blocked. In order
5142 * for a child animation to run, the parent animation must query each of the elements
5143 * containing child animations, and run them using this function.
5144 *
5145 * Note that this feature is designed to be used with `query()` and it will only work
5146 * with animations that are assigned using the Angular animation library. CSS keyframes
5147 * and transitions are not handled by this API.
5148 *
5149 * @publicApi
5150 */
5151
5152
5153function animateChild(options = null) {
5154  return {
5155    type: 9
5156    /* AnimationMetadataType.AnimateChild */
5157    ,
5158    options
5159  };
5160}
5161/**
5162 * Starts a reusable animation that is created using the `animation()` function.
5163 *
5164 * @param animation The reusable animation to start.
5165 * @param options An options object that can contain a delay value for the start of
5166 * the animation, and additional override values for developer-defined parameters.
5167 * @return An object that contains the animation parameters.
5168 *
5169 * @publicApi
5170 */
5171
5172
5173function useAnimation(animation, options = null) {
5174  return {
5175    type: 10
5176    /* AnimationMetadataType.AnimateRef */
5177    ,
5178    animation,
5179    options
5180  };
5181}
5182/**
5183 * Finds one or more inner elements within the current element that is
5184 * being animated within a sequence. Use with `animate()`.
5185 *
5186 * @param selector The element to query, or a set of elements that contain Angular-specific
5187 * characteristics, specified with one or more of the following tokens.
5188 *  - `query(":enter")` or `query(":leave")` : Query for newly inserted/removed elements (not
5189 *     all elements can be queried via these tokens, see
5190 *     [Entering and Leaving Elements](#entering-and-leaving-elements))
5191 *  - `query(":animating")` : Query all currently animating elements.
5192 *  - `query("@triggerName")` : Query elements that contain an animation trigger.
5193 *  - `query("@*")` : Query all elements that contain an animation triggers.
5194 *  - `query(":self")` : Include the current element into the animation sequence.
5195 *
5196 * @param animation One or more animation steps to apply to the queried element or elements.
5197 * An array is treated as an animation sequence.
5198 * @param options An options object. Use the 'limit' field to limit the total number of
5199 * items to collect.
5200 * @return An object that encapsulates the query data.
5201 *
5202 * @usageNotes
5203 *
5204 * ### Multiple Tokens
5205 *
5206 * Tokens can be merged into a combined query selector string. For example:
5207 *
5208 * ```typescript
5209 *  query(':self, .record:enter, .record:leave, @subTrigger', [...])
5210 * ```
5211 *
5212 * The `query()` function collects multiple elements and works internally by using
5213 * `element.querySelectorAll`. Use the `limit` field of an options object to limit
5214 * the total number of items to be collected. For example:
5215 *
5216 * ```js
5217 * query('div', [
5218 *   animate(...),
5219 *   animate(...)
5220 * ], { limit: 1 })
5221 * ```
5222 *
5223 * By default, throws an error when zero items are found. Set the
5224 * `optional` flag to ignore this error. For example:
5225 *
5226 * ```js
5227 * query('.some-element-that-may-not-be-there', [
5228 *   animate(...),
5229 *   animate(...)
5230 * ], { optional: true })
5231 * ```
5232 *
5233 * ### Entering and Leaving Elements
5234 *
5235 * Not all elements can be queried via the `:enter` and `:leave` tokens, the only ones
5236 * that can are those that Angular assumes can enter/leave based on their own logic
5237 * (if their insertion/removal is simply a consequence of that of their parent they
5238 * should be queried via a different token in their parent's `:enter`/`:leave` transitions).
5239 *
5240 * The only elements Angular assumes can enter/leave based on their own logic (thus the only
5241 * ones that can be queried via the `:enter` and `:leave` tokens) are:
5242 *  - Those inserted dynamically (via `ViewContainerRef`)
5243 *  - Those that have a structural directive (which, under the hood, are a subset of the above ones)
5244 *
5245 * <div class="alert is-helpful">
5246 *
5247 *  Note that elements will be successfully queried via `:enter`/`:leave` even if their
5248 *  insertion/removal is not done manually via `ViewContainerRef`or caused by their structural
5249 *  directive (e.g. they enter/exit alongside their parent).
5250 *
5251 * </div>
5252 *
5253 * <div class="alert is-important">
5254 *
5255 *  There is an exception to what previously mentioned, besides elements entering/leaving based on
5256 *  their own logic, elements with an animation trigger can always be queried via `:leave` when
5257 * their parent is also leaving.
5258 *
5259 * </div>
5260 *
5261 * ### Usage Example
5262 *
5263 * The following example queries for inner elements and animates them
5264 * individually using `animate()`.
5265 *
5266 * ```typescript
5267 * @Component({
5268 *   selector: 'inner',
5269 *   template: `
5270 *     <div [@queryAnimation]="exp">
5271 *       <h1>Title</h1>
5272 *       <div class="content">
5273 *         Blah blah blah
5274 *       </div>
5275 *     </div>
5276 *   `,
5277 *   animations: [
5278 *    trigger('queryAnimation', [
5279 *      transition('* => goAnimate', [
5280 *        // hide the inner elements
5281 *        query('h1', style({ opacity: 0 })),
5282 *        query('.content', style({ opacity: 0 })),
5283 *
5284 *        // animate the inner elements in, one by one
5285 *        query('h1', animate(1000, style({ opacity: 1 }))),
5286 *        query('.content', animate(1000, style({ opacity: 1 }))),
5287 *      ])
5288 *    ])
5289 *  ]
5290 * })
5291 * class Cmp {
5292 *   exp = '';
5293 *
5294 *   goAnimate() {
5295 *     this.exp = 'goAnimate';
5296 *   }
5297 * }
5298 * ```
5299 *
5300 * @publicApi
5301 */
5302
5303
5304function query(selector, animation, options = null) {
5305  return {
5306    type: 11
5307    /* AnimationMetadataType.Query */
5308    ,
5309    selector,
5310    animation,
5311    options
5312  };
5313}
5314/**
5315 * Use within an animation `query()` call to issue a timing gap after
5316 * each queried item is animated.
5317 *
5318 * @param timings A delay value.
5319 * @param animation One ore more animation steps.
5320 * @returns An object that encapsulates the stagger data.
5321 *
5322 * @usageNotes
5323 * In the following example, a container element wraps a list of items stamped out
5324 * by an `ngFor`. The container element contains an animation trigger that will later be set
5325 * to query for each of the inner items.
5326 *
5327 * Each time items are added, the opacity fade-in animation runs,
5328 * and each removed item is faded out.
5329 * When either of these animations occur, the stagger effect is
5330 * applied after each item's animation is started.
5331 *
5332 * ```html
5333 * <!-- list.component.html -->
5334 * <button (click)="toggle()">Show / Hide Items</button>
5335 * <hr />
5336 * <div [@listAnimation]="items.length">
5337 *   <div *ngFor="let item of items">
5338 *     {{ item }}
5339 *   </div>
5340 * </div>
5341 * ```
5342 *
5343 * Here is the component code:
5344 *
5345 * ```typescript
5346 * import {trigger, transition, style, animate, query, stagger} from '@angular/animations';
5347 * @Component({
5348 *   templateUrl: 'list.component.html',
5349 *   animations: [
5350 *     trigger('listAnimation', [
5351 *     ...
5352 *     ])
5353 *   ]
5354 * })
5355 * class ListComponent {
5356 *   items = [];
5357 *
5358 *   showItems() {
5359 *     this.items = [0,1,2,3,4];
5360 *   }
5361 *
5362 *   hideItems() {
5363 *     this.items = [];
5364 *   }
5365 *
5366 *   toggle() {
5367 *     this.items.length ? this.hideItems() : this.showItems();
5368 *    }
5369 *  }
5370 * ```
5371 *
5372 * Here is the animation trigger code:
5373 *
5374 * ```typescript
5375 * trigger('listAnimation', [
5376 *   transition('* => *', [ // each time the binding value changes
5377 *     query(':leave', [
5378 *       stagger(100, [
5379 *         animate('0.5s', style({ opacity: 0 }))
5380 *       ])
5381 *     ]),
5382 *     query(':enter', [
5383 *       style({ opacity: 0 }),
5384 *       stagger(100, [
5385 *         animate('0.5s', style({ opacity: 1 }))
5386 *       ])
5387 *     ])
5388 *   ])
5389 * ])
5390 * ```
5391 *
5392 * @publicApi
5393 */
5394
5395
5396function stagger(timings, animation) {
5397  return {
5398    type: 12
5399    /* AnimationMetadataType.Stagger */
5400    ,
5401    timings,
5402    animation
5403  };
5404}
5405/**
5406 * @license
5407 * Copyright Google LLC All Rights Reserved.
5408 *
5409 * Use of this source code is governed by an MIT-style license that can be
5410 * found in the LICENSE file at https://angular.io/license
5411 */
5412
5413
5414function scheduleMicroTask(cb) {
5415  Promise.resolve().then(cb);
5416}
5417/**
5418 * @license
5419 * Copyright Google LLC All Rights Reserved.
5420 *
5421 * Use of this source code is governed by an MIT-style license that can be
5422 * found in the LICENSE file at https://angular.io/license
5423 */
5424
5425/**
5426 * An empty programmatic controller for reusable animations.
5427 * Used internally when animations are disabled, to avoid
5428 * checking for the null case when an animation player is expected.
5429 *
5430 * @see `animate()`
5431 * @see `AnimationPlayer`
5432 * @see `GroupPlayer`
5433 *
5434 * @publicApi
5435 */
5436
5437
5438class NoopAnimationPlayer {
5439  constructor(duration = 0, delay = 0) {
5440    this._onDoneFns = [];
5441    this._onStartFns = [];
5442    this._onDestroyFns = [];
5443    this._originalOnDoneFns = [];
5444    this._originalOnStartFns = [];
5445    this._started = false;
5446    this._destroyed = false;
5447    this._finished = false;
5448    this._position = 0;
5449    this.parentPlayer = null;
5450    this.totalTime = duration + delay;
5451  }
5452
5453  _onFinish() {
5454    if (!this._finished) {
5455      this._finished = true;
5456
5457      this._onDoneFns.forEach(fn => fn());
5458
5459      this._onDoneFns = [];
5460    }
5461  }
5462
5463  onStart(fn) {
5464    this._originalOnStartFns.push(fn);
5465
5466    this._onStartFns.push(fn);
5467  }
5468
5469  onDone(fn) {
5470    this._originalOnDoneFns.push(fn);
5471
5472    this._onDoneFns.push(fn);
5473  }
5474
5475  onDestroy(fn) {
5476    this._onDestroyFns.push(fn);
5477  }
5478
5479  hasStarted() {
5480    return this._started;
5481  }
5482
5483  init() {}
5484
5485  play() {
5486    if (!this.hasStarted()) {
5487      this._onStart();
5488
5489      this.triggerMicrotask();
5490    }
5491
5492    this._started = true;
5493  }
5494  /** @internal */
5495
5496
5497  triggerMicrotask() {
5498    scheduleMicroTask(() => this._onFinish());
5499  }
5500
5501  _onStart() {
5502    this._onStartFns.forEach(fn => fn());
5503
5504    this._onStartFns = [];
5505  }
5506
5507  pause() {}
5508
5509  restart() {}
5510
5511  finish() {
5512    this._onFinish();
5513  }
5514
5515  destroy() {
5516    if (!this._destroyed) {
5517      this._destroyed = true;
5518
5519      if (!this.hasStarted()) {
5520        this._onStart();
5521      }
5522
5523      this.finish();
5524
5525      this._onDestroyFns.forEach(fn => fn());
5526
5527      this._onDestroyFns = [];
5528    }
5529  }
5530
5531  reset() {
5532    this._started = false;
5533    this._finished = false;
5534    this._onStartFns = this._originalOnStartFns;
5535    this._onDoneFns = this._originalOnDoneFns;
5536  }
5537
5538  setPosition(position) {
5539    this._position = this.totalTime ? position * this.totalTime : 1;
5540  }
5541
5542  getPosition() {
5543    return this.totalTime ? this._position / this.totalTime : 1;
5544  }
5545  /** @internal */
5546
5547
5548  triggerCallback(phaseName) {
5549    const methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
5550    methods.forEach(fn => fn());
5551    methods.length = 0;
5552  }
5553
5554}
5555/**
5556 * @license
5557 * Copyright Google LLC All Rights Reserved.
5558 *
5559 * Use of this source code is governed by an MIT-style license that can be
5560 * found in the LICENSE file at https://angular.io/license
5561 */
5562
5563/**
5564 * A programmatic controller for a group of reusable animations.
5565 * Used internally to control animations.
5566 *
5567 * @see `AnimationPlayer`
5568 * @see `{@link animations/group group()}`
5569 *
5570 */
5571
5572
5573class AnimationGroupPlayer {
5574  constructor(_players) {
5575    this._onDoneFns = [];
5576    this._onStartFns = [];
5577    this._finished = false;
5578    this._started = false;
5579    this._destroyed = false;
5580    this._onDestroyFns = [];
5581    this.parentPlayer = null;
5582    this.totalTime = 0;
5583    this.players = _players;
5584    let doneCount = 0;
5585    let destroyCount = 0;
5586    let startCount = 0;
5587    const total = this.players.length;
5588
5589    if (total == 0) {
5590      scheduleMicroTask(() => this._onFinish());
5591    } else {
5592      this.players.forEach(player => {
5593        player.onDone(() => {
5594          if (++doneCount == total) {
5595            this._onFinish();
5596          }
5597        });
5598        player.onDestroy(() => {
5599          if (++destroyCount == total) {
5600            this._onDestroy();
5601          }
5602        });
5603        player.onStart(() => {
5604          if (++startCount == total) {
5605            this._onStart();
5606          }
5607        });
5608      });
5609    }
5610
5611    this.totalTime = this.players.reduce((time, player) => Math.max(time, player.totalTime), 0);
5612  }
5613
5614  _onFinish() {
5615    if (!this._finished) {
5616      this._finished = true;
5617
5618      this._onDoneFns.forEach(fn => fn());
5619
5620      this._onDoneFns = [];
5621    }
5622  }
5623
5624  init() {
5625    this.players.forEach(player => player.init());
5626  }
5627
5628  onStart(fn) {
5629    this._onStartFns.push(fn);
5630  }
5631
5632  _onStart() {
5633    if (!this.hasStarted()) {
5634      this._started = true;
5635
5636      this._onStartFns.forEach(fn => fn());
5637
5638      this._onStartFns = [];
5639    }
5640  }
5641
5642  onDone(fn) {
5643    this._onDoneFns.push(fn);
5644  }
5645
5646  onDestroy(fn) {
5647    this._onDestroyFns.push(fn);
5648  }
5649
5650  hasStarted() {
5651    return this._started;
5652  }
5653
5654  play() {
5655    if (!this.parentPlayer) {
5656      this.init();
5657    }
5658
5659    this._onStart();
5660
5661    this.players.forEach(player => player.play());
5662  }
5663
5664  pause() {
5665    this.players.forEach(player => player.pause());
5666  }
5667
5668  restart() {
5669    this.players.forEach(player => player.restart());
5670  }
5671
5672  finish() {
5673    this._onFinish();
5674
5675    this.players.forEach(player => player.finish());
5676  }
5677
5678  destroy() {
5679    this._onDestroy();
5680  }
5681
5682  _onDestroy() {
5683    if (!this._destroyed) {
5684      this._destroyed = true;
5685
5686      this._onFinish();
5687
5688      this.players.forEach(player => player.destroy());
5689
5690      this._onDestroyFns.forEach(fn => fn());
5691
5692      this._onDestroyFns = [];
5693    }
5694  }
5695
5696  reset() {
5697    this.players.forEach(player => player.reset());
5698    this._destroyed = false;
5699    this._finished = false;
5700    this._started = false;
5701  }
5702
5703  setPosition(p) {
5704    const timeAtPosition = p * this.totalTime;
5705    this.players.forEach(player => {
5706      const position = player.totalTime ? Math.min(1, timeAtPosition / player.totalTime) : 1;
5707      player.setPosition(position);
5708    });
5709  }
5710
5711  getPosition() {
5712    const longestPlayer = this.players.reduce((longestSoFar, player) => {
5713      const newPlayerIsLongest = longestSoFar === null || player.totalTime > longestSoFar.totalTime;
5714      return newPlayerIsLongest ? player : longestSoFar;
5715    }, null);
5716    return longestPlayer != null ? longestPlayer.getPosition() : 0;
5717  }
5718
5719  beforeDestroy() {
5720    this.players.forEach(player => {
5721      if (player.beforeDestroy) {
5722        player.beforeDestroy();
5723      }
5724    });
5725  }
5726  /** @internal */
5727
5728
5729  triggerCallback(phaseName) {
5730    const methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
5731    methods.forEach(fn => fn());
5732    methods.length = 0;
5733  }
5734
5735}
5736/**
5737 * @license
5738 * Copyright Google LLC All Rights Reserved.
5739 *
5740 * Use of this source code is governed by an MIT-style license that can be
5741 * found in the LICENSE file at https://angular.io/license
5742 */
5743
5744
5745const ɵPRE_STYLE = '!';
5746/**
5747 * @license
5748 * Copyright Google LLC All Rights Reserved.
5749 *
5750 * Use of this source code is governed by an MIT-style license that can be
5751 * found in the LICENSE file at https://angular.io/license
5752 */
5753
5754/**
5755 * @license
5756 * Copyright Google LLC All Rights Reserved.
5757 *
5758 * Use of this source code is governed by an MIT-style license that can be
5759 * found in the LICENSE file at https://angular.io/license
5760 */
5761
5762/**
5763 * @license
5764 * Copyright Google LLC All Rights Reserved.
5765 *
5766 * Use of this source code is governed by an MIT-style license that can be
5767 * found in the LICENSE file at https://angular.io/license
5768 */
5769
5770/**
5771 * Generated bundle index. Do not edit.
5772 */
5773
5774
5775
5776/***/ }),
5777
5778/***/ 5787:
5779/*!***************************************************************!*\
5780  !*** ./node_modules/@angular/animations/fesm2020/browser.mjs ***!
5781  \***************************************************************/
5782/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
5783
5784__webpack_require__.r(__webpack_exports__);
5785/* harmony export */ __webpack_require__.d(__webpack_exports__, {
5786/* harmony export */   "AnimationDriver": () => (/* binding */ AnimationDriver),
5787/* harmony export */   "ɵAnimation": () => (/* binding */ Animation),
5788/* harmony export */   "ɵAnimationEngine": () => (/* binding */ AnimationEngine),
5789/* harmony export */   "ɵAnimationStyleNormalizer": () => (/* binding */ AnimationStyleNormalizer),
5790/* harmony export */   "ɵNoopAnimationDriver": () => (/* binding */ NoopAnimationDriver),
5791/* harmony export */   "ɵNoopAnimationStyleNormalizer": () => (/* binding */ NoopAnimationStyleNormalizer),
5792/* harmony export */   "ɵWebAnimationsDriver": () => (/* binding */ WebAnimationsDriver),
5793/* harmony export */   "ɵWebAnimationsPlayer": () => (/* binding */ WebAnimationsPlayer),
5794/* harmony export */   "ɵWebAnimationsStyleNormalizer": () => (/* binding */ WebAnimationsStyleNormalizer),
5795/* harmony export */   "ɵallowPreviousPlayerStylesMerge": () => (/* binding */ allowPreviousPlayerStylesMerge),
5796/* harmony export */   "ɵcontainsElement": () => (/* binding */ containsElement),
5797/* harmony export */   "ɵgetParentElement": () => (/* binding */ getParentElement),
5798/* harmony export */   "ɵinvokeQuery": () => (/* binding */ invokeQuery),
5799/* harmony export */   "ɵnormalizeKeyframes": () => (/* binding */ normalizeKeyframes),
5800/* harmony export */   "ɵvalidateStyleProperty": () => (/* binding */ validateStyleProperty)
5801/* harmony export */ });
5802/* harmony import */ var _angular_animations__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/animations */ 4851);
5803/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 2560);
5804/**
5805 * @license Angular v14.2.10
5806 * (c) 2010-2022 Google LLC. https://angular.io/
5807 * License: MIT
5808 */
5809
5810
5811
5812/**
5813 * @license
5814 * Copyright Google LLC All Rights Reserved.
5815 *
5816 * Use of this source code is governed by an MIT-style license that can be
5817 * found in the LICENSE file at https://angular.io/license
5818 */
5819
5820const LINE_START = '\n - ';
5821
5822function invalidTimingValue(exp) {
5823  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3000
5824  /* RuntimeErrorCode.INVALID_TIMING_VALUE */
5825  , ngDevMode && `The provided timing value "${exp}" is invalid.`);
5826}
5827
5828function negativeStepValue() {
5829  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3100
5830  /* RuntimeErrorCode.NEGATIVE_STEP_VALUE */
5831  , ngDevMode && 'Duration values below 0 are not allowed for this animation step.');
5832}
5833
5834function negativeDelayValue() {
5835  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3101
5836  /* RuntimeErrorCode.NEGATIVE_DELAY_VALUE */
5837  , ngDevMode && 'Delay values below 0 are not allowed for this animation step.');
5838}
5839
5840function invalidStyleParams(varName) {
5841  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3001
5842  /* RuntimeErrorCode.INVALID_STYLE_PARAMS */
5843  , ngDevMode && `Unable to resolve the local animation param ${varName} in the given list of values`);
5844}
5845
5846function invalidParamValue(varName) {
5847  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3003
5848  /* RuntimeErrorCode.INVALID_PARAM_VALUE */
5849  , ngDevMode && `Please provide a value for the animation param ${varName}`);
5850}
5851
5852function invalidNodeType(nodeType) {
5853  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3004
5854  /* RuntimeErrorCode.INVALID_NODE_TYPE */
5855  , ngDevMode && `Unable to resolve animation metadata node #${nodeType}`);
5856}
5857
5858function invalidCssUnitValue(userProvidedProperty, value) {
5859  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3005
5860  /* RuntimeErrorCode.INVALID_CSS_UNIT_VALUE */
5861  , ngDevMode && `Please provide a CSS unit value for ${userProvidedProperty}:${value}`);
5862}
5863
5864function invalidTrigger() {
5865  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3006
5866  /* RuntimeErrorCode.INVALID_TRIGGER */
5867  , ngDevMode && 'animation triggers cannot be prefixed with an `@` sign (e.g. trigger(\'@foo\', [...]))');
5868}
5869
5870function invalidDefinition() {
5871  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3007
5872  /* RuntimeErrorCode.INVALID_DEFINITION */
5873  , ngDevMode && 'only state() and transition() definitions can sit inside of a trigger()');
5874}
5875
5876function invalidState(metadataName, missingSubs) {
5877  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3008
5878  /* RuntimeErrorCode.INVALID_STATE */
5879  , ngDevMode && `state("${metadataName}", ...) must define default values for all the following style substitutions: ${missingSubs.join(', ')}`);
5880}
5881
5882function invalidStyleValue(value) {
5883  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3002
5884  /* RuntimeErrorCode.INVALID_STYLE_VALUE */
5885  , ngDevMode && `The provided style string value ${value} is not allowed.`);
5886}
5887
5888function invalidProperty(prop) {
5889  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3009
5890  /* RuntimeErrorCode.INVALID_PROPERTY */
5891  , ngDevMode && `The provided animation property "${prop}" is not a supported CSS property for animations`);
5892}
5893
5894function invalidParallelAnimation(prop, firstStart, firstEnd, secondStart, secondEnd) {
5895  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3010
5896  /* RuntimeErrorCode.INVALID_PARALLEL_ANIMATION */
5897  , 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"`);
5898}
5899
5900function invalidKeyframes() {
5901  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3011
5902  /* RuntimeErrorCode.INVALID_KEYFRAMES */
5903  , ngDevMode && `keyframes() must be placed inside of a call to animate()`);
5904}
5905
5906function invalidOffset() {
5907  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3012
5908  /* RuntimeErrorCode.INVALID_OFFSET */
5909  , ngDevMode && `Please ensure that all keyframe offsets are between 0 and 1`);
5910}
5911
5912function keyframeOffsetsOutOfOrder() {
5913  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3200
5914  /* RuntimeErrorCode.KEYFRAME_OFFSETS_OUT_OF_ORDER */
5915  , ngDevMode && `Please ensure that all keyframe offsets are in order`);
5916}
5917
5918function keyframesMissingOffsets() {
5919  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3202
5920  /* RuntimeErrorCode.KEYFRAMES_MISSING_OFFSETS */
5921  , ngDevMode && `Not all style() steps within the declared keyframes() contain offsets`);
5922}
5923
5924function invalidStagger() {
5925  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3013
5926  /* RuntimeErrorCode.INVALID_STAGGER */
5927  , ngDevMode && `stagger() can only be used inside of query()`);
5928}
5929
5930function invalidQuery(selector) {
5931  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3014
5932  /* RuntimeErrorCode.INVALID_QUERY */
5933  , ngDevMode && `\`query("${selector}")\` returned zero elements. (Use \`query("${selector}", { optional: true })\` if you wish to allow this.)`);
5934}
5935
5936function invalidExpression(expr) {
5937  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3015
5938  /* RuntimeErrorCode.INVALID_EXPRESSION */
5939  , ngDevMode && `The provided transition expression "${expr}" is not supported`);
5940}
5941
5942function invalidTransitionAlias(alias) {
5943  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3016
5944  /* RuntimeErrorCode.INVALID_TRANSITION_ALIAS */
5945  , ngDevMode && `The transition alias value "${alias}" is not supported`);
5946}
5947
5948function validationFailed(errors) {
5949  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3500
5950  /* RuntimeErrorCode.VALIDATION_FAILED */
5951  , ngDevMode && `animation validation failed:\n${errors.map(err => err.message).join('\n')}`);
5952}
5953
5954function buildingFailed(errors) {
5955  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3501
5956  /* RuntimeErrorCode.BUILDING_FAILED */
5957  , ngDevMode && `animation building failed:\n${errors.map(err => err.message).join('\n')}`);
5958}
5959
5960function triggerBuildFailed(name, errors) {
5961  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3404
5962  /* RuntimeErrorCode.TRIGGER_BUILD_FAILED */
5963  , ngDevMode && `The animation trigger "${name}" has failed to build due to the following errors:\n - ${errors.map(err => err.message).join('\n - ')}`);
5964}
5965
5966function animationFailed(errors) {
5967  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3502
5968  /* RuntimeErrorCode.ANIMATION_FAILED */
5969  , ngDevMode && `Unable to animate due to the following errors:${LINE_START}${errors.map(err => err.message).join(LINE_START)}`);
5970}
5971
5972function registerFailed(errors) {
5973  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3503
5974  /* RuntimeErrorCode.REGISTRATION_FAILED */
5975  , ngDevMode && `Unable to build the animation due to the following errors: ${errors.map(err => err.message).join('\n')}`);
5976}
5977
5978function missingOrDestroyedAnimation() {
5979  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3300
5980  /* RuntimeErrorCode.MISSING_OR_DESTROYED_ANIMATION */
5981  , ngDevMode && 'The requested animation doesn\'t exist or has already been destroyed');
5982}
5983
5984function createAnimationFailed(errors) {
5985  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3504
5986  /* RuntimeErrorCode.CREATE_ANIMATION_FAILED */
5987  , ngDevMode && `Unable to create the animation due to the following errors:${errors.map(err => err.message).join('\n')}`);
5988}
5989
5990function missingPlayer(id) {
5991  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3301
5992  /* RuntimeErrorCode.MISSING_PLAYER */
5993  , ngDevMode && `Unable to find the timeline player referenced by ${id}`);
5994}
5995
5996function missingTrigger(phase, name) {
5997  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3302
5998  /* RuntimeErrorCode.MISSING_TRIGGER */
5999  , ngDevMode && `Unable to listen on the animation trigger event "${phase}" because the animation trigger "${name}" doesn\'t exist!`);
6000}
6001
6002function missingEvent(name) {
6003  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3303
6004  /* RuntimeErrorCode.MISSING_EVENT */
6005  , ngDevMode && `Unable to listen on the animation trigger "${name}" because the provided event is undefined!`);
6006}
6007
6008function unsupportedTriggerEvent(phase, name) {
6009  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3400
6010  /* RuntimeErrorCode.UNSUPPORTED_TRIGGER_EVENT */
6011  , ngDevMode && `The provided animation trigger event "${phase}" for the animation trigger "${name}" is not supported!`);
6012}
6013
6014function unregisteredTrigger(name) {
6015  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3401
6016  /* RuntimeErrorCode.UNREGISTERED_TRIGGER */
6017  , ngDevMode && `The provided animation trigger "${name}" has not been registered!`);
6018}
6019
6020function triggerTransitionsFailed(errors) {
6021  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3402
6022  /* RuntimeErrorCode.TRIGGER_TRANSITIONS_FAILED */
6023  , ngDevMode && `Unable to process animations due to the following failed trigger transitions\n ${errors.map(err => err.message).join('\n')}`);
6024}
6025
6026function triggerParsingFailed(name, errors) {
6027  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3403
6028  /* RuntimeErrorCode.TRIGGER_PARSING_FAILED */
6029  , ngDevMode && `Animation parsing for the ${name} trigger have failed:${LINE_START}${errors.map(err => err.message).join(LINE_START)}`);
6030}
6031
6032function transitionFailed(name, errors) {
6033  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3505
6034  /* RuntimeErrorCode.TRANSITION_FAILED */
6035  , ngDevMode && `@${name} has failed due to:\n ${errors.map(err => err.message).join('\n- ')}`);
6036}
6037/**
6038 * @license
6039 * Copyright Google LLC All Rights Reserved.
6040 *
6041 * Use of this source code is governed by an MIT-style license that can be
6042 * found in the LICENSE file at https://angular.io/license
6043 */
6044
6045/**
6046 * Set of all animatable CSS properties
6047 *
6048 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
6049 */
6050
6051
6052const ANIMATABLE_PROP_SET = 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']);
6053/**
6054 * @license
6055 * Copyright Google LLC All Rights Reserved.
6056 *
6057 * Use of this source code is governed by an MIT-style license that can be
6058 * found in the LICENSE file at https://angular.io/license
6059 */
6060
6061function isBrowser() {
6062  return typeof window !== 'undefined' && typeof window.document !== 'undefined';
6063}
6064
6065function isNode() {
6066  // Checking only for `process` isn't enough to identify whether or not we're in a Node
6067  // environment, because Webpack by default will polyfill the `process`. While we can discern
6068  // that Webpack polyfilled it by looking at `process.browser`, it's very Webpack-specific and
6069  // might not be future-proof. Instead we look at the stringified version of `process` which
6070  // is `[object process]` in Node and `[object Object]` when polyfilled.
6071  return typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
6072}
6073
6074function optimizeGroupPlayer(players) {
6075  switch (players.length) {
6076    case 0:
6077      return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer();
6078
6079    case 1:
6080      return players[0];
6081
6082    default:
6083      return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationGroupPlayer"](players);
6084  }
6085}
6086
6087function normalizeKeyframes$1(driver, normalizer, element, keyframes, preStyles = new Map(), postStyles = new Map()) {
6088  const errors = [];
6089  const normalizedKeyframes = [];
6090  let previousOffset = -1;
6091  let previousKeyframe = null;
6092  keyframes.forEach(kf => {
6093    const offset = kf.get('offset');
6094    const isSameOffset = offset == previousOffset;
6095    const normalizedKeyframe = isSameOffset && previousKeyframe || new Map();
6096    kf.forEach((val, prop) => {
6097      let normalizedProp = prop;
6098      let normalizedValue = val;
6099
6100      if (prop !== 'offset') {
6101        normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors);
6102
6103        switch (normalizedValue) {
6104          case _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵPRE_STYLE"]:
6105            normalizedValue = preStyles.get(prop);
6106            break;
6107
6108          case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE:
6109            normalizedValue = postStyles.get(prop);
6110            break;
6111
6112          default:
6113            normalizedValue = normalizer.normalizeStyleValue(prop, normalizedProp, normalizedValue, errors);
6114            break;
6115        }
6116      }
6117
6118      normalizedKeyframe.set(normalizedProp, normalizedValue);
6119    });
6120
6121    if (!isSameOffset) {
6122      normalizedKeyframes.push(normalizedKeyframe);
6123    }
6124
6125    previousKeyframe = normalizedKeyframe;
6126    previousOffset = offset;
6127  });
6128
6129  if (errors.length) {
6130    throw animationFailed(errors);
6131  }
6132
6133  return normalizedKeyframes;
6134}
6135
6136function listenOnPlayer(player, eventName, event, callback) {
6137  switch (eventName) {
6138    case 'start':
6139      player.onStart(() => callback(event && copyAnimationEvent(event, 'start', player)));
6140      break;
6141
6142    case 'done':
6143      player.onDone(() => callback(event && copyAnimationEvent(event, 'done', player)));
6144      break;
6145
6146    case 'destroy':
6147      player.onDestroy(() => callback(event && copyAnimationEvent(event, 'destroy', player)));
6148      break;
6149  }
6150}
6151
6152function copyAnimationEvent(e, phaseName, player) {
6153  const totalTime = player.totalTime;
6154  const disabled = player.disabled ? true : false;
6155  const event = makeAnimationEvent(e.element, e.triggerName, e.fromState, e.toState, phaseName || e.phaseName, totalTime == undefined ? e.totalTime : totalTime, disabled);
6156  const data = e['_data'];
6157
6158  if (data != null) {
6159    event['_data'] = data;
6160  }
6161
6162  return event;
6163}
6164
6165function makeAnimationEvent(element, triggerName, fromState, toState, phaseName = '', totalTime = 0, disabled) {
6166  return {
6167    element,
6168    triggerName,
6169    fromState,
6170    toState,
6171    phaseName,
6172    totalTime,
6173    disabled: !!disabled
6174  };
6175}
6176
6177function getOrSetDefaultValue(map, key, defaultValue) {
6178  let value = map.get(key);
6179
6180  if (!value) {
6181    map.set(key, value = defaultValue);
6182  }
6183
6184  return value;
6185}
6186
6187function parseTimelineCommand(command) {
6188  const separatorPos = command.indexOf(':');
6189  const id = command.substring(1, separatorPos);
6190  const action = command.slice(separatorPos + 1);
6191  return [id, action];
6192}
6193
6194let _contains = (elm1, elm2) => false;
6195
6196let _query = (element, selector, multi) => {
6197  return [];
6198};
6199
6200let _documentElement = null;
6201
6202function getParentElement(element) {
6203  const parent = element.parentNode || element.host; // consider host to support shadow DOM
6204
6205  if (parent === _documentElement) {
6206    return null;
6207  }
6208
6209  return parent;
6210} // Define utility methods for browsers and platform-server(domino) where Element
6211// and utility methods exist.
6212
6213
6214const _isNode = isNode();
6215
6216if (_isNode || typeof Element !== 'undefined') {
6217  if (!isBrowser()) {
6218    _contains = (elm1, elm2) => elm1.contains(elm2);
6219  } else {
6220    // Read the document element in an IIFE that's been marked pure to avoid a top-level property
6221    // read that may prevent tree-shaking.
6222    _documentElement = /* @__PURE__ */(() => document.documentElement)();
6223
6224    _contains = (elm1, elm2) => {
6225      while (elm2) {
6226        if (elm2 === elm1) {
6227          return true;
6228        }
6229
6230        elm2 = getParentElement(elm2);
6231      }
6232
6233      return false;
6234    };
6235  }
6236
6237  _query = (element, selector, multi) => {
6238    if (multi) {
6239      return Array.from(element.querySelectorAll(selector));
6240    }
6241
6242    const elem = element.querySelector(selector);
6243    return elem ? [elem] : [];
6244  };
6245}
6246
6247function containsVendorPrefix(prop) {
6248  // Webkit is the only real popular vendor prefix nowadays
6249  // cc: http://shouldiprefix.com/
6250  return prop.substring(1, 6) == 'ebkit'; // webkit or Webkit
6251}
6252
6253let _CACHED_BODY = null;
6254let _IS_WEBKIT = false;
6255
6256function validateStyleProperty(prop) {
6257  if (!_CACHED_BODY) {
6258    _CACHED_BODY = getBodyNode() || {};
6259    _IS_WEBKIT = _CACHED_BODY.style ? 'WebkitAppearance' in _CACHED_BODY.style : false;
6260  }
6261
6262  let result = true;
6263
6264  if (_CACHED_BODY.style && !containsVendorPrefix(prop)) {
6265    result = prop in _CACHED_BODY.style;
6266
6267    if (!result && _IS_WEBKIT) {
6268      const camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.slice(1);
6269      result = camelProp in _CACHED_BODY.style;
6270    }
6271  }
6272
6273  return result;
6274}
6275
6276function validateWebAnimatableStyleProperty(prop) {
6277  return ANIMATABLE_PROP_SET.has(prop);
6278}
6279
6280function getBodyNode() {
6281  if (typeof document != 'undefined') {
6282    return document.body;
6283  }
6284
6285  return null;
6286}
6287
6288const containsElement = _contains;
6289const invokeQuery = _query;
6290
6291function hypenatePropsKeys(original) {
6292  const newMap = new Map();
6293  original.forEach((val, prop) => {
6294    const newProp = prop.replace(/([a-z])([A-Z])/g, '$1-$2');
6295    newMap.set(newProp, val);
6296  });
6297  return newMap;
6298}
6299/**
6300 * @license
6301 * Copyright Google LLC All Rights Reserved.
6302 *
6303 * Use of this source code is governed by an MIT-style license that can be
6304 * found in the LICENSE file at https://angular.io/license
6305 */
6306
6307/**
6308 * @publicApi
6309 */
6310
6311
6312class NoopAnimationDriver {
6313  validateStyleProperty(prop) {
6314    return validateStyleProperty(prop);
6315  }
6316
6317  matchesElement(_element, _selector) {
6318    // This method is deprecated and no longer in use so we return false.
6319    return false;
6320  }
6321
6322  containsElement(elm1, elm2) {
6323    return containsElement(elm1, elm2);
6324  }
6325
6326  getParentElement(element) {
6327    return getParentElement(element);
6328  }
6329
6330  query(element, selector, multi) {
6331    return invokeQuery(element, selector, multi);
6332  }
6333
6334  computeStyle(element, prop, defaultValue) {
6335    return defaultValue || '';
6336  }
6337
6338  animate(element, keyframes, duration, delay, easing, previousPlayers = [], scrubberAccessRequested) {
6339    return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer(duration, delay);
6340  }
6341
6342}
6343
6344NoopAnimationDriver.ɵfac = function NoopAnimationDriver_Factory(t) {
6345  return new (t || NoopAnimationDriver)();
6346};
6347
6348NoopAnimationDriver.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
6349  token: NoopAnimationDriver,
6350  factory: NoopAnimationDriver.ɵfac
6351});
6352
6353(function () {
6354  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NoopAnimationDriver, [{
6355    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
6356  }], null, null);
6357})();
6358/**
6359 * @publicApi
6360 */
6361
6362
6363class AnimationDriver {}
6364
6365AnimationDriver.NOOP = /* @__PURE__ */new NoopAnimationDriver();
6366/**
6367 * @license
6368 * Copyright Google LLC All Rights Reserved.
6369 *
6370 * Use of this source code is governed by an MIT-style license that can be
6371 * found in the LICENSE file at https://angular.io/license
6372 */
6373
6374const ONE_SECOND = 1000;
6375const SUBSTITUTION_EXPR_START = '{{';
6376const SUBSTITUTION_EXPR_END = '}}';
6377const ENTER_CLASSNAME = 'ng-enter';
6378const LEAVE_CLASSNAME = 'ng-leave';
6379const NG_TRIGGER_CLASSNAME = 'ng-trigger';
6380const NG_TRIGGER_SELECTOR = '.ng-trigger';
6381const NG_ANIMATING_CLASSNAME = 'ng-animating';
6382const NG_ANIMATING_SELECTOR = '.ng-animating';
6383
6384function resolveTimingValue(value) {
6385  if (typeof value == 'number') return value;
6386  const matches = value.match(/^(-?[\.\d]+)(m?s)/);
6387  if (!matches || matches.length < 2) return 0;
6388  return _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
6389}
6390
6391function _convertTimeValueToMS(value, unit) {
6392  switch (unit) {
6393    case 's':
6394      return value * ONE_SECOND;
6395
6396    default:
6397      // ms or something else
6398      return value;
6399  }
6400}
6401
6402function resolveTiming(timings, errors, allowNegativeValues) {
6403  return timings.hasOwnProperty('duration') ? timings : parseTimeExpression(timings, errors, allowNegativeValues);
6404}
6405
6406function parseTimeExpression(exp, errors, allowNegativeValues) {
6407  const regex = /^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i;
6408  let duration;
6409  let delay = 0;
6410  let easing = '';
6411
6412  if (typeof exp === 'string') {
6413    const matches = exp.match(regex);
6414
6415    if (matches === null) {
6416      errors.push(invalidTimingValue(exp));
6417      return {
6418        duration: 0,
6419        delay: 0,
6420        easing: ''
6421      };
6422    }
6423
6424    duration = _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
6425    const delayMatch = matches[3];
6426
6427    if (delayMatch != null) {
6428      delay = _convertTimeValueToMS(parseFloat(delayMatch), matches[4]);
6429    }
6430
6431    const easingVal = matches[5];
6432
6433    if (easingVal) {
6434      easing = easingVal;
6435    }
6436  } else {
6437    duration = exp;
6438  }
6439
6440  if (!allowNegativeValues) {
6441    let containsErrors = false;
6442    let startIndex = errors.length;
6443
6444    if (duration < 0) {
6445      errors.push(negativeStepValue());
6446      containsErrors = true;
6447    }
6448
6449    if (delay < 0) {
6450      errors.push(negativeDelayValue());
6451      containsErrors = true;
6452    }
6453
6454    if (containsErrors) {
6455      errors.splice(startIndex, 0, invalidTimingValue(exp));
6456    }
6457  }
6458
6459  return {
6460    duration,
6461    delay,
6462    easing
6463  };
6464}
6465
6466function copyObj(obj, destination = {}) {
6467  Object.keys(obj).forEach(prop => {
6468    destination[prop] = obj[prop];
6469  });
6470  return destination;
6471}
6472
6473function convertToMap(obj) {
6474  const styleMap = new Map();
6475  Object.keys(obj).forEach(prop => {
6476    const val = obj[prop];
6477    styleMap.set(prop, val);
6478  });
6479  return styleMap;
6480}
6481
6482function normalizeKeyframes(keyframes) {
6483  if (!keyframes.length) {
6484    return [];
6485  }
6486
6487  if (keyframes[0] instanceof Map) {
6488    return keyframes;
6489  }
6490
6491  return keyframes.map(kf => convertToMap(kf));
6492}
6493
6494function normalizeStyles(styles) {
6495  const normalizedStyles = new Map();
6496
6497  if (Array.isArray(styles)) {
6498    styles.forEach(data => copyStyles(data, normalizedStyles));
6499  } else {
6500    copyStyles(styles, normalizedStyles);
6501  }
6502
6503  return normalizedStyles;
6504}
6505
6506function copyStyles(styles, destination = new Map(), backfill) {
6507  if (backfill) {
6508    for (let [prop, val] of backfill) {
6509      destination.set(prop, val);
6510    }
6511  }
6512
6513  for (let [prop, val] of styles) {
6514    destination.set(prop, val);
6515  }
6516
6517  return destination;
6518}
6519
6520function getStyleAttributeString(element, key, value) {
6521  // Return the key-value pair string to be added to the style attribute for the
6522  // given CSS style key.
6523  if (value) {
6524    return key + ':' + value + ';';
6525  } else {
6526    return '';
6527  }
6528}
6529
6530function writeStyleAttribute(element) {
6531  // Read the style property of the element and manually reflect it to the
6532  // style attribute. This is needed because Domino on platform-server doesn't
6533  // understand the full set of allowed CSS properties and doesn't reflect some
6534  // of them automatically.
6535  let styleAttrValue = '';
6536
6537  for (let i = 0; i < element.style.length; i++) {
6538    const key = element.style.item(i);
6539    styleAttrValue += getStyleAttributeString(element, key, element.style.getPropertyValue(key));
6540  }
6541
6542  for (const key in element.style) {
6543    // Skip internal Domino properties that don't need to be reflected.
6544    if (!element.style.hasOwnProperty(key) || key.startsWith('_')) {
6545      continue;
6546    }
6547
6548    const dashKey = camelCaseToDashCase(key);
6549    styleAttrValue += getStyleAttributeString(element, dashKey, element.style[key]);
6550  }
6551
6552  element.setAttribute('style', styleAttrValue);
6553}
6554
6555function setStyles(element, styles, formerStyles) {
6556  if (element['style']) {
6557    styles.forEach((val, prop) => {
6558      const camelProp = dashCaseToCamelCase(prop);
6559
6560      if (formerStyles && !formerStyles.has(prop)) {
6561        formerStyles.set(prop, element.style[camelProp]);
6562      }
6563
6564      element.style[camelProp] = val;
6565    }); // On the server set the 'style' attribute since it's not automatically reflected.
6566
6567    if (isNode()) {
6568      writeStyleAttribute(element);
6569    }
6570  }
6571}
6572
6573function eraseStyles(element, styles) {
6574  if (element['style']) {
6575    styles.forEach((_, prop) => {
6576      const camelProp = dashCaseToCamelCase(prop);
6577      element.style[camelProp] = '';
6578    }); // On the server set the 'style' attribute since it's not automatically reflected.
6579
6580    if (isNode()) {
6581      writeStyleAttribute(element);
6582    }
6583  }
6584}
6585
6586function normalizeAnimationEntry(steps) {
6587  if (Array.isArray(steps)) {
6588    if (steps.length == 1) return steps[0];
6589    return (0,_angular_animations__WEBPACK_IMPORTED_MODULE_1__.sequence)(steps);
6590  }
6591
6592  return steps;
6593}
6594
6595function validateStyleParams(value, options, errors) {
6596  const params = options.params || {};
6597  const matches = extractStyleParams(value);
6598
6599  if (matches.length) {
6600    matches.forEach(varName => {
6601      if (!params.hasOwnProperty(varName)) {
6602        errors.push(invalidStyleParams(varName));
6603      }
6604    });
6605  }
6606}
6607
6608const PARAM_REGEX = new RegExp(`${SUBSTITUTION_EXPR_START}\\s*(.+?)\\s*${SUBSTITUTION_EXPR_END}`, 'g');
6609
6610function extractStyleParams(value) {
6611  let params = [];
6612
6613  if (typeof value === 'string') {
6614    let match;
6615
6616    while (match = PARAM_REGEX.exec(value)) {
6617      params.push(match[1]);
6618    }
6619
6620    PARAM_REGEX.lastIndex = 0;
6621  }
6622
6623  return params;
6624}
6625
6626function interpolateParams(value, params, errors) {
6627  const original = value.toString();
6628  const str = original.replace(PARAM_REGEX, (_, varName) => {
6629    let localVal = params[varName]; // this means that the value was never overridden by the data passed in by the user
6630
6631    if (localVal == null) {
6632      errors.push(invalidParamValue(varName));
6633      localVal = '';
6634    }
6635
6636    return localVal.toString();
6637  }); // we do this to assert that numeric values stay as they are
6638
6639  return str == original ? value : str;
6640}
6641
6642function iteratorToArray(iterator) {
6643  const arr = [];
6644  let item = iterator.next();
6645
6646  while (!item.done) {
6647    arr.push(item.value);
6648    item = iterator.next();
6649  }
6650
6651  return arr;
6652}
6653
6654const DASH_CASE_REGEXP = /-+([a-z0-9])/g;
6655
6656function dashCaseToCamelCase(input) {
6657  return input.replace(DASH_CASE_REGEXP, (...m) => m[1].toUpperCase());
6658}
6659
6660function camelCaseToDashCase(input) {
6661  return input.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
6662}
6663
6664function allowPreviousPlayerStylesMerge(duration, delay) {
6665  return duration === 0 || delay === 0;
6666}
6667
6668function balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles) {
6669  if (previousStyles.size && keyframes.length) {
6670    let startingKeyframe = keyframes[0];
6671    let missingStyleProps = [];
6672    previousStyles.forEach((val, prop) => {
6673      if (!startingKeyframe.has(prop)) {
6674        missingStyleProps.push(prop);
6675      }
6676
6677      startingKeyframe.set(prop, val);
6678    });
6679
6680    if (missingStyleProps.length) {
6681      for (let i = 1; i < keyframes.length; i++) {
6682        let kf = keyframes[i];
6683        missingStyleProps.forEach(prop => kf.set(prop, computeStyle(element, prop)));
6684      }
6685    }
6686  }
6687
6688  return keyframes;
6689}
6690
6691function visitDslNode(visitor, node, context) {
6692  switch (node.type) {
6693    case 7
6694    /* AnimationMetadataType.Trigger */
6695    :
6696      return visitor.visitTrigger(node, context);
6697
6698    case 0
6699    /* AnimationMetadataType.State */
6700    :
6701      return visitor.visitState(node, context);
6702
6703    case 1
6704    /* AnimationMetadataType.Transition */
6705    :
6706      return visitor.visitTransition(node, context);
6707
6708    case 2
6709    /* AnimationMetadataType.Sequence */
6710    :
6711      return visitor.visitSequence(node, context);
6712
6713    case 3
6714    /* AnimationMetadataType.Group */
6715    :
6716      return visitor.visitGroup(node, context);
6717
6718    case 4
6719    /* AnimationMetadataType.Animate */
6720    :
6721      return visitor.visitAnimate(node, context);
6722
6723    case 5
6724    /* AnimationMetadataType.Keyframes */
6725    :
6726      return visitor.visitKeyframes(node, context);
6727
6728    case 6
6729    /* AnimationMetadataType.Style */
6730    :
6731      return visitor.visitStyle(node, context);
6732
6733    case 8
6734    /* AnimationMetadataType.Reference */
6735    :
6736      return visitor.visitReference(node, context);
6737
6738    case 9
6739    /* AnimationMetadataType.AnimateChild */
6740    :
6741      return visitor.visitAnimateChild(node, context);
6742
6743    case 10
6744    /* AnimationMetadataType.AnimateRef */
6745    :
6746      return visitor.visitAnimateRef(node, context);
6747
6748    case 11
6749    /* AnimationMetadataType.Query */
6750    :
6751      return visitor.visitQuery(node, context);
6752
6753    case 12
6754    /* AnimationMetadataType.Stagger */
6755    :
6756      return visitor.visitStagger(node, context);
6757
6758    default:
6759      throw invalidNodeType(node.type);
6760  }
6761}
6762
6763function computeStyle(element, prop) {
6764  return window.getComputedStyle(element)[prop];
6765}
6766/**
6767 * @license
6768 * Copyright Google LLC All Rights Reserved.
6769 *
6770 * Use of this source code is governed by an MIT-style license that can be
6771 * found in the LICENSE file at https://angular.io/license
6772 */
6773
6774
6775const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
6776
6777function createListOfWarnings(warnings) {
6778  const LINE_START = '\n - ';
6779  return `${LINE_START}
6779${warnings.filter(Boolean).map(warning => warning).join(LINE_START)}`;
6780}
6781
6782function warnValidation(warnings) {
6783  NG_DEV_MODE && console.warn(`animation validation warnings:${createListOfWarnings(warnings)}`);
6784}
6785
6786function warnTriggerBuild(name, warnings) {
6787  NG_DEV_MODE && console.warn(`The animation trigger "${name}" has built with the following warnings:${createListOfWarnings(warnings)}`);
6788}
6789
6790function warnRegister(warnings) {
6791  NG_DEV_MODE && console.warn(`Animation built with the following warnings:${createListOfWarnings(warnings)}`);
6792}
6793
6794function triggerParsingWarnings(name, warnings) {
6795  NG_DEV_MODE && console.warn(`Animation parsing for the ${name} trigger presents the following warnings:${createListOfWarnings(warnings)}`);
6796}
6797
6798function pushUnrecognizedPropertiesWarning(warnings, props) {
6799  if (props.length) {
6800    warnings.push(`The following provided properties are not recognized: ${props.join(', ')}`);
6801  }
6802}
6803/**
6804 * @license
6805 * Copyright Google LLC All Rights Reserved.
6806 *
6807 * Use of this source code is governed by an MIT-style license that can be
6808 * found in the LICENSE file at https://angular.io/license
6809 */
6810
6811
6812const ANY_STATE = '*';
6813
6814function parseTransitionExpr(transitionValue, errors) {
6815  const expressions = [];
6816
6817  if (typeof transitionValue == 'string') {
6818    transitionValue.split(/\s*,\s*/).forEach(str => parseInnerTransitionStr(str, expressions, errors));
6819  } else {
6820    expressions.push(transitionValue);
6821  }
6822
6823  return expressions;
6824}
6825
6826function parseInnerTransitionStr(eventStr, expressions, errors) {
6827  if (eventStr[0] == ':') {
6828    const result = parseAnimationAlias(eventStr, errors);
6829
6830    if (typeof result == 'function') {
6831      expressions.push(result);
6832      return;
6833    }
6834
6835    eventStr = result;
6836  }
6837
6838  const match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
6839
6840  if (match == null || match.length < 4) {
6841    errors.push(invalidExpression(eventStr));
6842    return expressions;
6843  }
6844
6845  const fromState = match[1];
6846  const separator = match[2];
6847  const toState = match[3];
6848  expressions.push(makeLambdaFromStates(fromState, toState));
6849  const isFullAnyStateExpr = fromState == ANY_STATE && toState == ANY_STATE;
6850
6851  if (separator[0] == '<' && !isFullAnyStateExpr) {
6852    expressions.push(makeLambdaFromStates(toState, fromState));
6853  }
6854}
6855
6856function parseAnimationAlias(alias, errors) {
6857  switch (alias) {
6858    case ':enter':
6859      return 'void => *';
6860
6861    case ':leave':
6862      return '* => void';
6863
6864    case ':increment':
6865      return (fromState, toState) => parseFloat(toState) > parseFloat(fromState);
6866
6867    case ':decrement':
6868      return (fromState, toState) => parseFloat(toState) < parseFloat(fromState);
6869
6870    default:
6871      errors.push(invalidTransitionAlias(alias));
6872      return '* => *';
6873  }
6874} // DO NOT REFACTOR ... keep the follow set instantiations
6875// with the values intact (closure compiler for some reason
6876// removes follow-up lines that add the values outside of
6877// the constructor...
6878
6879
6880const TRUE_BOOLEAN_VALUES = new Set(['true', '1']);
6881const FALSE_BOOLEAN_VALUES = new Set(['false', '0']);
6882
6883function makeLambdaFromStates(lhs, rhs) {
6884  const LHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(lhs) || FALSE_BOOLEAN_VALUES.has(lhs);
6885  const RHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(rhs) || FALSE_BOOLEAN_VALUES.has(rhs);
6886  return (fromState, toState) => {
6887    let lhsMatch = lhs == ANY_STATE || lhs == fromState;
6888    let rhsMatch = rhs == ANY_STATE || rhs == toState;
6889
6890    if (!lhsMatch && LHS_MATCH_BOOLEAN && typeof fromState === 'boolean') {
6891      lhsMatch = fromState ? TRUE_BOOLEAN_VALUES.has(lhs) : FALSE_BOOLEAN_VALUES.has(lhs);
6892    }
6893
6894    if (!rhsMatch && RHS_MATCH_BOOLEAN && typeof toState === 'boolean') {
6895      rhsMatch = toState ? TRUE_BOOLEAN_VALUES.has(rhs) : FALSE_BOOLEAN_VALUES.has(rhs);
6896    }
6897
6898    return lhsMatch && rhsMatch;
6899  };
6900}
6901/**
6902 * @license
6903 * Copyright Google LLC All Rights Reserved.
6904 *
6905 * Use of this source code is governed by an MIT-style license that can be
6906 * found in the LICENSE file at https://angular.io/license
6907 */
6908
6909
6910const SELF_TOKEN = ':self';
6911const SELF_TOKEN_REGEX = new RegExp(`\s*${SELF_TOKEN}\s*,?`, 'g');
6912/*
6913 * [Validation]
6914 * The visitor code below will traverse the animation AST generated by the animation verb functions
6915 * (the output is a tree of objects) and attempt to perform a series of validations on the data. The
6916 * following corner-cases will be validated:
6917 *
6918 * 1. Overlap of animations
6919 * Given that a CSS property cannot be animated in more than one place at the same time, it's
6920 * important that this behavior is detected and validated. The way in which this occurs is that
6921 * each time a style property is examined, a string-map containing the property will be updated with
6922 * the start and end times for when the property is used within an animation step.
6923 *
6924 * If there are two or more parallel animations that are currently running (these are invoked by the
6925 * group()) on the same element then the validator will throw an error. Since the start/end timing
6926 * values are collected for each property then if the current animation step is animating the same
6927 * property and its timing values fall anywhere into the window of time that the property is
6928 * currently being animated within then this is what causes an error.
6929 *
6930 * 2. Timing values
6931 * The validator will validate to see if a timing value of `duration delay easing` or
6932 * `durationNumber` is valid or not.
6933 *
6934 * (note that upon validation the code below will replace the timing data with an object c
6934ontaining
6935 * {duration,delay,easing}.
6936 *
6937 * 3. Offset Validation
6938 * Each of the style() calls are allowed to have an offset value when placed inside of keyframes().
6939 * Offsets within keyframes() are considered valid when:
6940 *
6941 *   - No offsets are used at all
6942 *   - Each style() entry contains an offset value
6943 *   - Each offset is between 0 and 1
6944 *   - Each offset is greater to or equal than the previous one
6945 *
6946 * Otherwise an error will be thrown.
6947 */
6948
6949function buildAnimationAst(driver, metadata, errors, warnings) {
6950  return new AnimationAstBuilderVisitor(driver).build(metadata, errors, warnings);
6951}
6952
6953const ROOT_SELECTOR = '';
6954
6955class AnimationAstBuilderVisitor {
6956  constructor(_driver) {
6957    this._driver = _driver;
6958  }
6959
6960  build(metadata, errors, warnings) {
6961    const context = new AnimationAstBuilderContext(errors);
6962
6963    this._resetContextStyleTimingState(context);
6964
6965    const ast = visitDslNode(this, normalizeAnimationEntry(metadata), context);
6966
6967    if (typeof ngDevMode === 'undefined' || ngDevMode) {
6968      if (context.unsupportedCSSPropertiesFound.size) {
6969        pushUnrecognizedPropertiesWarning(warnings, [...context.unsupportedCSSPropertiesFound.keys()]);
6970      }
6971    }
6972
6973    return ast;
6974  }
6975
6976  _resetContextStyleTimingState(context) {
6977    context.currentQuerySelector = ROOT_SELECTOR;
6978    context.collectedStyles = new Map();
6979    context.collectedStyles.set(ROOT_SELECTOR, new Map());
6980    context.currentTime = 0;
6981  }
6982
6983  visitTrigger(metadata, context) {
6984    let queryCount = context.queryCount = 0;
6985    let depCount = context.depCount = 0;
6986    const states = [];
6987    const transitions = [];
6988
6989    if (metadata.name.charAt(0) == '@') {
6990      context.errors.push(invalidTrigger());
6991    }
6992
6993    metadata.definitions.forEach(def => {
6994      this._resetContextStyleTimingState(context);
6995
6996      if (def.type == 0
6997      /* AnimationMetadataType.State */
6998      ) {
6999        const stateDef = def;
7000        const name = stateDef.name;
7001        name.toString().split(/\s*,\s*/).forEach(n => {
7002          stateDef.name = n;
7003          states.push(this.visitState(stateDef, context));
7004        });
7005        stateDef.name = name;
7006      } else if (def.type == 1
7007      /* AnimationMetadataType.Transition */
7008      ) {
7009        const transition = this.visitTransition(def, context);
7010        queryCount += transition.queryCount;
7011        depCount += transition.depCount;
7012        transitions.push(transition);
7013      } else {
7014        context.errors.push(invalidDefinition());
7015      }
7016    });
7017    return {
7018      type: 7
7019      /* AnimationMetadataType.Trigger */
7020      ,
7021      name: metadata.name,
7022      states,
7023      transitions,
7024      queryCount,
7025      depCount,
7026      options: null
7027    };
7028  }
7029
7030  visitState(metadata, context) {
7031    const styleAst = this.visitStyle(metadata.styles, context);
7032    const astParams = metadata.options && metadata.options.params || null;
7033
7034    if (styleAst.containsDynamicStyles) {
7035      const missingSubs = new Set();
7036      const params = astParams || {};
7037      styleAst.styles.forEach(style => {
7038        if (style instanceof Map) {
7039          style.forEach(value => {
7040            extractStyleParams(value).forEach(sub => {
7041              if (!params.hasOwnProperty(sub)) {
7042                missingSubs.add(sub);
7043              }
7044            });
7045          });
7046        }
7047      });
7048
7049      if (missingSubs.size) {
7050        const missingSubsArr = iteratorToArray(missingSubs.values());
7051        context.errors.push(invalidState(metadata.name, missingSubsArr));
7052      }
7053    }
7054
7055    return {
7056      type: 0
7057      /* AnimationMetadataType.State */
7058      ,
7059      name: metadata.name,
7060      style: styleAst,
7061      options: astParams ? {
7062        params: astParams
7063      } : null
7064    };
7065  }
7066
7067  visitTransition(metadata, context) {
7068    context.queryCount = 0;
7069    context.depCount = 0;
7070    const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
7071    const matchers = parseTransitionExpr(metadata.expr, context.errors);
7072    return {
7073      type: 1
7074      /* AnimationMetadataType.Transition */
7075      ,
7076      matchers,
7077      animation,
7078      queryCount: context.queryCount,
7079      depCount: context.depCount,
7080      options: normalizeAnimationOptions(metadata.options)
7081    };
7082  }
7083
7084  visitSequence(metadata, context) {
7085    return {
7086      type: 2
7087      /* AnimationMetadataType.Sequence */
7088      ,
7089      steps: metadata.steps.map(s => visitDslNode(this, s, context)),
7090      options: normalizeAnimationOptions(metadata.options)
7091    };
7092  }
7093
7094  visitGroup(metadata, context) {
7095    const currentTime = context.currentTime;
7096    let furthestTime = 0;
7097    const steps = metadata.steps.map(step => {
7098      context.currentTime = currentTime;
7099      const innerAst = visitDslNode(this, step, context);
7100      furthestTime = Math.max(furthestTime, context.currentTime);
7101      return innerAst;
7102    });
7103    context.currentTime = furthestTime;
7104    return {
7105      type: 3
vendor: 9,292 bytes, lines 7106-7415
7106      /* AnimationMetadataType.Group */
7107      ,
7108      steps,
7109      options: normalizeAnimationOptions(metadata.options)
7110    };
7111  }
7112
7113  visitAnimate(metadata, context) {
7114    const timingAst = constructTimingAst(metadata.timings, context.errors);
7115    context.currentAnimateTimings = timingAst;
7116    let styleAst;
7117    let styleMetadata = metadata.styles ? metadata.styles : (0,_angular_animations__WEBPACK_IMPORTED_MODULE_1__.style)({});
7118
7119    if (styleMetadata.type == 5
7120    /* AnimationMetadataType.Keyframes */
7121    ) {
7122      styleAst = this.visitKeyframes(styleMetadata, context);
7123    } else {
7124      let styleMetadata = metadata.styles;
7125      let isEmpty = false;
7126
7127      if (!styleMetadata) {
7128        isEmpty = true;
7129        const newStyleData = {};
7130
7131        if (timingAst.easing) {
7132          newStyleData['easing'] = timingAst.easing;
7133        }
7134
7135        styleMetadata = (0,_angular_animations__WEBPACK_IMPORTED_MODULE_1__.style)(newStyleData);
7136      }
7137
7138      context.currentTime += timingAst.duration + timingAst.delay;
7139
7140      const _styleAst = this.visitStyle(styleMetadata, context);
7141
7142      _styleAst.isEmptyStep = isEmpty;
7143      styleAst = _styleAst;
7144    }
7145
7146    context.currentAnimateTimings = null;
7147    return {
7148      type: 4
7149      /* AnimationMetadataType.Animate */
7150      ,
7151      timings: timingAst,
7152      style: styleAst,
7153      options: null
7154    };
7155  }
7156
7157  visitStyle(metadata, context) {
7158    const ast = this._makeStyleAst(metadata, context);
7159
7160    this._validateStyleAst(ast, context);
7161
7162    return ast;
7163  }
7164
7165  _makeStyleAst(metadata, context) {
7166    const styles = [];
7167    const metadataStyles = Array.isArray(metadata.styles) ? metadata.styles : [metadata.styles];
7168
7169    for (let styleTuple of metadataStyles) {
7170      if (typeof styleTuple === 'string') {
7171        if (styleTuple === _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE) {
7172          styles.push(styleTuple);
7173        } else {
7174          context.errors.push(invalidStyleValue(styleTuple));
7175        }
7176      } else {
7177        styles.push(convertToMap(styleTuple));
7178      }
7179    }
7180
7181    let containsDynamicStyles = false;
7182    let collectedEasing = null;
7183    styles.forEach(styleData => {
7184      if (styleData instanceof Map) {
7185        if (styleData.has('easing')) {
7186          collectedEasing = styleData.get('easing');
7187          styleData.delete('easing');
7188        }
7189
7190        if (!containsDynamicStyles) {
7191          for (let value of styleData.values()) {
7192            if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {
7193              containsDynamicStyles = true;
7194              break;
7195            }
7196          }
7197        }
7198      }
7199    });
7200    return {
7201      type: 6
7202      /* AnimationMetadataType.Style */
7203      ,
7204      styles,
7205      easing: collectedEasing,
7206      offset: metadata.offset,
7207      containsDynamicStyles,
7208      options: null
7209    };
7210  }
7211
7212  _validateStyleAst(ast, context) {
7213    const timings = context.currentAnimateTimings;
7214    let endTime = context.currentTime;
7215    let startTime = context.currentTime;
7216
7217    if (timings && startTime > 0) {
7218      startTime -= timings.duration + timings.delay;
7219    }
7220
7221    ast.styles.forEach(tuple => {
7222      if (typeof tuple === 'string') return;
7223      tuple.forEach((value, prop) => {
7224        if (typeof ngDevMode === 'undefined' || ngDevMode) {
7225          if (!this._driver.validateStyleProperty(prop)) {
7226            tuple.delete(prop);
7227            context.unsupportedCSSPropertiesFound.add(prop);
7228            return;
7229          }
7230        } // This is guaranteed to have a defined Map at this querySelector location making it
7231        // safe to add the assertion here. It is set as a default empty map in prior methods.
7232
7233
7234        const collectedStyles = context.collectedStyles.get(context.currentQuerySelector);
7235        const collectedEntry = collectedStyles.get(prop);
7236        let updateCollectedStyle = true;
7237
7238        if (collectedEntry) {
7239          if (startTime != endTime && startTime >= collectedEntry.startTime && endTime <= collectedEntry.endTime) {
7240            context.errors.push(invalidParallelAnimation(prop, collectedEntry.startTime, collectedEntry.endTime, startTime, endTime));
7241            updateCollectedStyle = false;
7242          } // we always choose the smaller start time value since we
7243          // want to have a record of the entire animation window where
7244          // the style property is being animated in between
7245
7246
7247          startTime = collectedEntry.startTime;
7248        }
7249
7250        if (updateCollectedStyle) {
7251          collectedStyles.set(prop, {
7252            startTime,
7253            endTime
7254          });
7255        }
7256
7257        if (context.options) {
7258          validateStyleParams(value, context.options, context.errors);
7259        }
7260      });
7261    });
7262  }
7263
7264  visitKeyframes(metadata, context) {
7265    const ast = {
7266      type: 5
7267      /* AnimationMetadataType.Keyframes */
7268      ,
7269      styles: [],
7270      options: null
7271    };
7272
7273    if (!context.currentAnimateTimings) {
7274      context.errors.push(invalidKeyframes());
7275      return ast;
7276    }
7277
7278    const MAX_KEYFRAME_OFFSET = 1;
7279    let totalKeyframesWithOffsets = 0;
7280    const offsets = [];
7281    let offsetsOutOfOrder = false;
7282    let keyframesOutOfRange = false;
7283    let previousOffset = 0;
7284    const keyframes = metadata.steps.map(styles => {
7285      const style = this._makeStyleAst(styles, context);
7286
7287      let offsetVal = style.offset != null ? style.offset : consumeOffset(style.styles);
7288      let offset = 0;
7289
7290      if (offsetVal != null) {
7291        totalKeyframesWithOffsets++;
7292        offset = style.offset = offsetVal;
7293      }
7294
7295      keyframesOutOfRange = keyframesOutOfRange || offset < 0 || offset > 1;
7296      offsetsOutOfOrder = offsetsOutOfOrder || offset < previousOffset;
7297      previousOffset = offset;
7298      offsets.push(offset);
7299      return style;
7300    });
7301
7302    if (keyframesOutOfRange) {
7303      context.errors.push(invalidOffset());
7304    }
7305
7306    if (offsetsOutOfOrder) {
7307      context.errors.push(keyframeOffsetsOutOfOrder());
7308    }
7309
7310    const length = metadata.steps.length;
7311    let generatedOffset = 0;
7312
7313    if (totalKeyframesWithOffsets > 0 && totalKeyframesWithOffsets < length) {
7314      context.errors.push(keyframesMissingOffsets());
7315    } else if (totalKeyframesWithOffsets == 0) {
7316      generatedOffset = MAX_KEYFRAME_OFFSET / (length - 1);
7317    }
7318
7319    const limit = length - 1;
7320    const currentTime = context.currentTime;
7321    const currentAnimateTimings = context.currentAnimateTimings;
7322    const animateDuration = currentAnimateTimings.duration;
7323    keyframes.forEach((kf, i) => {
7324      const offset = generatedOffset > 0 ? i == limit ? 1 : generatedOffset * i : offsets[i];
7325      const durationUpToThisFrame = offset * animateDuration;
7326      context.currentTime = currentTime + currentAnimateTimings.delay + durationUpToThisFrame;
7327      currentAnimateTimings.duration = durationUpToThisFrame;
7328
7329      this._validateStyleAst(kf, context);
7330
7331      kf.offset = offset;
7332      ast.styles.push(kf);
7333    });
7334    return ast;
7335  }
7336
7337  visitReference(metadata, context) {
7338    return {
7339      type: 8
7340      /* AnimationMetadataType.Reference */
7341      ,
7342      animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
7343      options: normalizeAnimationOptions(metadata.options)
7344    };
7345  }
7346
7347  visitAnimateChild(metadata, context) {
7348    context.depCount++;
7349    return {
7350      type: 9
7351      /* AnimationMetadataType.AnimateChild */
7352      ,
7353      options: normalizeAnimationOptions(metadata.options)
7354    };
7355  }
7356
7357  visitAnimateRef(metadata, context) {
7358    return {
7359      type: 10
7360      /* AnimationMetadataType.AnimateRef */
7361      ,
7362      animation: this.visitReference(metadata.animation, context),
7363      options: normalizeAnimationOptions(metadata.options)
7364    };
7365  }
7366
7367  visitQuery(metadata, context) {
7368    const parentSelector = context.currentQuerySelector;
7369    const options = metadata.options || {};
7370    context.queryCount++;
7371    context.currentQuery = metadata;
7372    const [selector, includeSelf] = normalizeSelector(metadata.selector);
7373    context.currentQuerySelector = parentSelector.length ? parentSelector + ' ' + selector : selector;
7374    getOrSetDefaultValue(context.collectedStyles, context.currentQuerySelector, new Map());
7375    const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
7376    context.currentQuery = null;
7377    context.currentQuerySelector = parentSelector;
7378    return {
7379      type: 11
7380      /* AnimationMetadataType.Query */
7381      ,
7382      selector,
7383      limit: options.limit || 0,
7384      optional: !!options.optional,
7385      includeSelf,
7386      animation,
7387      originalSelector: metadata.selector,
7388      options: normalizeAnimationOptions(metadata.options)
7389    };
7390  }
7391
7392  visitStagger(metadata, context) {
7393    if (!context.currentQuery) {
7394      context.errors.push(invalidStagger());
7395    }
7396
7397    const timings = metadata.timings === 'full' ? {
7398      duration: 0,
7399      delay: 0,
7400      easing: 'full'
7401    } : resolveTiming(metadata.timings, context.errors, true);
7402    return {
7403      type: 12
7404      /* AnimationMetadataType.Stagger */
7405      ,
7406      animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
7407      timings,
7408      options: null
7409    };
7410  }
7411
7412}
7413
7414function normalizeSelector(selector) {
7415  const hasAmpersand = selector.split(/\s*,\s*/).find(token => token == SELF_TOKEN) ? true : false;
7416
7417  if (hasAmpersand) {
7418    selector = selector.replace(SELF_TOKEN_REGEX, '');
7419  } // Note: the :enter and :leave aren't normalized here since those
7420  // selectors are filled in at runtime during timeline building
7421
7422
7423  selector = selector.replace(/@\*/g, NG_TRIGGER_SELECTOR).replace(/@\w+/g, match => NG_TRIGGER_SELECTOR + '-' + match.slice(1)).replace(/:animating/g, NG_ANIMATING_SELECTOR);
7424  return [selector, hasAmpersand];
7425}
7426
7427function normalizeParams(obj) {
7428  return obj ? copyObj(obj) : null;
7429}
7430
7431class AnimationAstBuilderContext {
7432  constructor(errors) {
7433    this.errors = errors;
7434    this.queryCount = 0;
7435    this.depCount = 0;
7436    this.currentTransition = null;
7437    this.currentQuery = null;
7438    this.currentQuerySelector = null;
7439    this.currentAnimateTimings = null;
7440    this.currentTime = 0;
7441    this.collectedStyles = new Map();
7442    this.options = null;
7443    this.unsupportedCSSPropertiesFound = new Set();
7444  }
7445
7446}
7447
7448function consumeOffset(styles) {
7449  if (typeof styles == 'string') return null;
7450  let offset = null;
7451
7452  if (Array.isArray(styles)) {
7453    styles.forEach(styleTuple => {
7454      if (styleTuple instanceof Map && styleTuple.has('offset')) {
7455        const obj = styleTuple;
7456        offset = parseFloat(obj.get('offset'));
7457        obj.delete('offset');
7458      }
7459    });
7460  } else if (styles instanceof Map && styles.has('offset')) {
7461    const obj = styles;
7462    offset = parseFloat(obj.get('offset'));
7463    obj.delete('offset');
7464  }
7465
7466  return offset;
7467}
7468
7469function constructTimingAst(value, errors) {
7470  if (value.hasOwnProperty('duration')) {
7471    return value;
7472  }
7473
7474  if (typeof value == 'number') {
7475    const duration = resolveTiming(value, errors).duration;
7476    return makeTimingAst(duration, 0, '');
7477  }
7478
7479  const strValue = value;
7480  const isDynamic = strValue.split(/\s+/).some(v => v.charAt(0) == '{' && v.charAt(1) == '{');
7481
7482  if (isDynamic) {
7483    const ast = makeTimingAst(0, 0, '');
7484    ast.dynamic = true;
7485    ast.strValue = strValue;
7486    return ast;
7487  }
7488
7489  const timings = resolveTiming(strValue, errors);
7490  return makeTimingAst(timings.duration, timings.delay, timings.easing);
7491}
7492
7493function normalizeAnimationOptions(options) {
7494  if (options) {
7495    options = copyObj(options);
7496
7497    if (options['params']) {
7498      options['params'] = normalizeParams(options['params']);
7499    }
7500  } else {
7501    options = {};
7502  }
7503
7504  return options;
7505}
7506
7507function makeTimingAst(duration, delay, easing) {
7508  return {
7509    duration,
7510    delay,
7511    easing
7512  };
7513}
7514
7515function createTimelineInstruction(element, keyframes, preStyleProps, postStyleProps, duration, delay, easing = null, subTimeline = false) {
7516  return {
7517    type: 1
7518    /* AnimationTransitionInstructionType.TimelineAnimation */
7519    ,
7520    element,
7521    keyframes,
7522    preStyleProps,
7523    postStyleProps,
7524    duration,
7525    delay,
7526    totalTime: duration + delay,
7527    easing,
7528    subTimeline
7529  };
7530}
7531
7532class ElementInstructionMap {
7533  constructor() {
7534    this._map = new Map();
7535  }
7536
7537  get(element) {
7538    return this._map.get(element) || [];
7539  }
7540
7541  append(element, instructions) {
7542    let existingInstructions = this._map.get(element);
7543
7544    if (!existingInstructions) {
7545      this._map.set(element, existingInstructions = []);
7546    }
7547
7548    existingInstructions.push(...instructions);
7549  }
7550
7551  has(element) {
7552    return this._map.has(element);
7553  }
7554
7555  clear() {
7556    this._map.clear();
7557  }
7558
7559}
7560/**
7561 * @license
7562 * Copyright Google LLC All Rights Reserved.
7563 *
7564 * Use of this source code is governed by an MIT-style license that can be
7565 * found in the LICENSE file at https://angular.io/license
7566 */
7567
7568
7569const ONE_FRAME_IN_MILLISECONDS = 1;
7570const ENTER_TOKEN = ':enter';
7571const ENTER_TOKEN_REGEX = new RegExp(ENTER_TOKEN, 'g');
7572const LEAVE_TOKEN = ':leave';
7573const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
7574/*
7575 * The code within this file aims to generate web-animations-compatible keyframes from Angular's
7576 * animation DSL code.
7577 *
7578 * The code below will be converted from:
7579 *
7580 * ```
7581 * sequence([
7582 *   style({ opacity: 0 }),
7583 *   animate(1000, style({ opacity: 0 }))
7584 * ])
7585 * ```
7586 *
7587 * To:
7588 * ```
7589 * keyframes = [{ opacity: 0, offset: 0 }, { opacity: 1, offset: 1 }]
7590 * duration = 1000
7591 * delay = 0
7592 * easing = ''
7593 * ```
7594 *
7595 * For this operation to cover the combination of animation verbs (style, animate, group, etc...) a
7596 * combination of AST traversal and merge-sort-like algorithms are used.
7597 *
7598 * [AST Traversal]
7599 * Each of the animation verbs, when executed, will return an string-map object representing what
7600 * type of action it is (style, animate, group, etc...) and the data associated with it. This means
7601 * that when functional composition mix of these functions is evaluated (like in the example above)
7602 * then it will end up producing a tree of objects representing the animation itself.
7603 *
7604 * When this animation object tree is processed by the visitor code below it will visit each of the
7605 * verb statements within the visitor. And during each visit it will build the context of the
7606 * animation keyframes by interacting with the `TimelineBuilder`.
7607 *
7608 * [TimelineBuilder]
7609 * This class is responsible for tracking the styles and building a series of keyframe objects for a
7610 * timeline between a start and end time. The builder starts off with an initial timeline and each
7611 * time the AST comes across a `group()`, `keyframes()` or a combination of the two within a
7612 * `sequence()` then it will generate a sub timeline for each step as well as a new one after
7613 * they are complete.
7614 *
7615 * As the AST is traversed, the timing state on each of the timelines will be incremented. If a sub
7616 * timeline was created (based on one of the cases above) then the parent timeline will attempt to
7617 * merge the styles used within the sub timelines into itself (only with group() this will happen).
7618 * This happens with a merge operation (much like how the merge works in mergeSort) and it will only
7619 * copy the most recently used styles from the sub timelines into the parent timeline. This ensures
7620 * that if the styles are used later on in another phase of the animation then they will be the most
7621 * up-to-date values.
7622 *
7623 * [How Missing Styles Are Updated]
7624 * Each timeline has a `backFill` property which is responsible for filling in new styles into
7625 * already processed keyframes if a new style shows up later within the animation sequence.
7626 *
7627 * ```
7628 * sequence([
7629 *   style({ width: 0 }),
7630 *   animate(1000, style({ width: 100 })),
7631 *   animate(1000, style({ width: 200 })),
7632 *   animate(1000, style({ width: 300 }))
7633 *   animate(1000, style({ width: 400, height: 400 })) // notice how `height` doesn't exist anywhere
7634 * else
7635 * ])
7636 * ```
7637 *
7638 * What is happening here is that the `height` value is added later in the sequence, but is missing
7639 * from all previous animation steps. Therefore when a keyframe is created it would also be missing
7640 * from all previous keyframes up until where it is first used. For the timeline keyframe generation
7641 * to properly fill in the style it will place the previous value (the value from the parent
7642 * timeline) or a default value of `*` into the backFill map. The `copyStyles` method in util.ts
7643 * handles propagating that backfill map to the styles object.
7644 *
7645 * When a sub-timeline is created it will have its own backFill property. This is done so that
7646 * styles present within the sub-timeline do not accidentally seep into the previous/future timeline
7647 * keyframes
7648 *
7649 * [Validation]
7650 * The code in this file is not responsible for validation. That functionality happens with within
7651 * the `AnimationValidatorVisitor` code.
7652 */
7653
7654function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles = new Map(), finalStyles = new Map(), options, subInstru
vendor: 22,926 bytes, lines 7654-8340
7654ctions, errors = []) {
7655  return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors);
7656}
7657
7658class AnimationTimelineBuilderVisitor {
7659  buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors = []) {
7660    subInstructions = subInstructions || new ElementInstructionMap();
7661    const context = new AnimationTimelineContext(driver, rootElement, subInstructions, enterClassName, leaveClassName, errors, []);
7662    context.options = options;
7663    const delay = options.delay ? resolveTimingValue(options.delay) : 0;
7664    context.currentTimeline.delayNextStep(delay);
7665    context.currentTimeline.setStyles([startingStyles], null, context.errors, options);
7666    visitDslNode(this, ast, context); // this checks to see if an actual animation happened
7667
7668    const timelines = context.timelines.filter(timeline => timeline.containsAnimation()); // note: we just want to apply the final styles for the rootElement, so we do not
7669    //       just apply the styles to the last timeline but the last timeline which
7670    //       element is the root one (basically `*`-styles are replaced with the actual
7671    //       state style values only for the root element)
7672
7673    if (timelines.length && finalStyles.size) {
7674      let lastRootTimeline;
7675
7676      for (let i = timelines.length - 1; i >= 0; i--) {
7677        const timeline = timelines[i];
7678
7679        if (timeline.element === rootElement) {
7680          lastRootTimeline = timeline;
7681          break;
7682        }
7683      }
7684
7685      if (lastRootTimeline && !lastRootTimeline.allowOnlyTimelineStyles()) {
7686        lastRootTimeline.setStyles([finalStyles], null, context.errors, options);
7687      }
7688    }
7689
7690    return timelines.length ? timelines.map(timeline => timeline.buildKeyframes()) : [createTimelineInstruction(rootElement, [], [], [], 0, delay, '', false)];
7691  }
7692
7693  visitTrigger(ast, context) {// these values are not visited in this AST
7694  }
7695
7696  visitState(ast, context) {// these values are not visited in this AST
7697  }
7698
7699  visitTransition(ast, context) {// these values are not visited in this AST
7700  }
7701
7702  visitAnimateChild(ast, context) {
7703    const elementInstructions = context.subInstructions.get(context.element);
7704
7705    if (elementInstructions) {
7706      const innerContext = context.createSubContext(ast.options);
7707      const startTime = context.currentTimeline.currentTime;
7708
7709      const endTime = this._visitSubInstructions(elementInstructions, innerContext, innerContext.options);
7710
7711      if (startTime != endTime) {
7712        // we do this on the upper context because we created a sub context for
7713        // the sub child animations
7714        context.transformIntoNewTimeline(endTime);
7715      }
7716    }
7717
7718    context.previousNode = ast;
7719  }
7720
7721  visitAnimateRef(ast, context) {
7722    const innerContext = context.createSubContext(ast.options);
7723    innerContext.transformIntoNewTimeline();
7724
7725    this._applyAnimationRefDelays([ast.options, ast.animation.options], context, innerContext);
7726
7727    this.visitReference(ast.animation, innerContext);
7728    context.transformIntoNewTimeline(innerContext.currentTimeline.currentTime);
7729    context.previousNode = ast;
7730  }
7731
7732  _applyAnimationRefDelays(animationsRefsOptions, context, innerContext) {
7733    for (const animationRefOptions of animationsRefsOptions) {
7734      const animationDelay = animationRefOptions?.delay;
7735
7736      if (animationDelay) {
7737        const animationDelayValue = typeof animationDelay === 'number' ? animationDelay : resolveTimingValue(interpolateParams(animationDelay, animationRefOptions?.params ?? {}, context.errors));
7738        innerContext.delayNextStep(animationDelayValue);
7739      }
7740    }
7741  }
7742
7743  _visitSubInstructions(instructions, context, options) {
7744    const startTime = context.currentTimeline.currentTime;
7745    let furthestTime = startTime; // this is a special-case for when a user wants to skip a sub
7746    // animation from being fired entirely.
7747
7748    const duration = options.duration != null ? resolveTimingValue(options.duration) : null;
7749    const delay = options.delay != null ? resolveTimingValue(options.delay) : null;
7750
7751    if (duration !== 0) {
7752      instructions.forEach(instruction => {
7753        const instructionTimings = context.appendInstructionToTimeline(instruction, duration, delay);
7754        furthestTime = Math.max(furthestTime, instructionTimings.duration + instructionTimings.delay);
7755      });
7756    }
7757
7758    return furthestTime;
7759  }
7760
7761  visitReference(ast, context) {
7762    context.updateOptions(ast.options, true);
7763    visitDslNode(this, ast.animation, context);
7764    context.previousNode = ast;
7765  }
7766
7767  visitSequence(ast, context) {
7768    const subContextCount = context.subContextCount;
7769    let ctx = context;
7770    const options = ast.options;
7771
7772    if (options && (options.params || options.delay)) {
7773      ctx = context.createSubContext(options);
7774      ctx.transformIntoNewTimeline();
7775
7776      if (options.delay != null) {
7777        if (ctx.previousNode.type == 6
7778        /* AnimationMetadataType.Style */
7779        ) {
7780          ctx.currentTimeline.snapshotCurrentStyles();
7781          ctx.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
7782        }
7783
7784        const delay = resolveTimingValue(options.delay);
7785        ctx.delayNextStep(delay);
7786      }
7787    }
7788
7789    if (ast.steps.length) {
7790      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
7791
7792      ctx.currentTimeline.applyStylesToKeyframe(); // this means that some animation function within the sequence
7793      // ended up creating a sub timeline (which means the current
7794      // timeline cannot overlap with the contents of the sequence)
7795
7796      if (ctx.subContextCount > subContextCount) {
7797        ctx.transformIntoNewTimeline();
7798      }
7799    }
7800
7801    context.previousNode = ast;
7802  }
7803
7804  visitGroup(ast, context) {
7805    const innerTimelines = [];
7806    let furthestTime = context.currentTimeline.currentTime;
7807    const delay = ast.options && ast.options.delay ? resolveTimingValue(ast.options.delay) : 0;
7808    ast.steps.forEach(s => {
7809      const innerContext = context.createSubContext(ast.options);
7810
7811      if (delay) {
7812        innerContext.delayNextStep(delay);
7813      }
7814
7815      visitDslNode(this, s, innerContext);
7816      furthestTime = Math.max(furthestTime, innerContext.currentTimeline.currentTime);
7817      innerTimelines.push(innerContext.currentTimeline);
7818    }); // this operation is run after the AST loop because otherwise
7819    // if the parent timeline's collected styles were updated then
7820    // it would pass in invalid data into the new-to-be forked items
7821
7822    innerTimelines.forEach(timeline => context.currentTimeline.mergeTimelineCollectedStyles(timeline));
7823    context.transformIntoNewTimeline(furthestTime);
7824    context.previousNode = ast;
7825  }
7826
7827  _visitTiming(ast, context) {
7828    if (ast.dynamic) {
7829      const strValue = ast.strValue;
7830      const timingValue = context.params ? interpolateParams(strValue, context.params, context.errors) : strValue;
7831      return resolveTiming(timingValue, context.errors);
7832    } else {
7833      return {
7834        duration: ast.duration,
7835        delay: ast.delay,
7836        easing: ast.easing
7837      };
7838    }
7839  }
7840
7841  visitAnimate(ast, context) {
7842    const timings = context.currentAnimateTimings = this._visitTiming(ast.timings, context);
7843
7844    const timeline = context.currentTimeline;
7845
7846    if (timings.delay) {
7847      context.incrementTime(timings.delay);
7848      timeline.snapshotCurrentStyles();
7849    }
7850
7851    const style = ast.style;
7852
7853    if (style.type == 5
7854    /* AnimationMetadataType.Keyframes */
7855    ) {
7856      this.visitKeyframes(style, context);
7857    } else {
7858      context.incrementTime(timings.duration);
7859      this.visitStyle(style, context);
7860      timeline.applyStylesToKeyframe();
7861    }
7862
7863    context.currentAnimateTimings = null;
7864    context.previousNode = ast;
7865  }
7866
7867  visitStyle(ast, context) {
7868    const timeline = context.currentTimeline;
7869    const timings = context.currentAnimateTimings; // this is a special case for when a style() call
7870    // directly follows  an animate() call (but not inside of an animate() call)
7871
7872    if (!timings && timeline.hasCurrentStyleProperties()) {
7873      timeline.forwardFrame();
7874    }
7875
7876    const easing = timings && timings.easing || ast.easing;
7877
7878    if (ast.isEmptyStep) {
7879      timeline.applyEmptyStep(easing);
7880    } else {
7881      timeline.setStyles(ast.styles, easing, context.errors, context.options);
7882    }
7883
7884    context.previousNode = ast;
7885  }
7886
7887  visitKeyframes(ast, context) {
7888    const currentAnimateTimings = context.currentAnimateTimings;
7889    const startTime = context.currentTimeline.duration;
7890    const duration = currentAnimateTimings.duration;
7891    const innerContext = context.createSubContext();
7892    const innerTimeline = innerContext.currentTimeline;
7893    innerTimeline.easing = currentAnimateTimings.easing;
7894    ast.styles.forEach(step => {
7895      const offset = step.offset || 0;
7896      innerTimeline.forwardTime(offset * duration);
7897      innerTimeline.setStyles(step.styles, step.easing, context.errors, context.options);
7898      innerTimeline.applyStylesToKeyframe();
7899    }); // this will ensure that the parent timeline gets all the styles from
7900    // the child even if the new timeline below is not used
7901
7902    context.currentTimeline.mergeTimelineCollectedStyles(innerTimeline); // we do this because the window between this timeline and the sub timeline
7903    // should ensure that the styles within are exactly the same as they were before
7904
7905    context.transformIntoNewTimeline(startTime + duration);
7906    context.previousNode = ast;
7907  }
7908
7909  visitQuery(ast, context) {
7910    // in the event that the first step before this is a style step we need
7911    // to ensure the styles are applied before the children are animated
7912    const startTime = context.currentTimeline.currentTime;
7913    const options = ast.options || {};
7914    const delay = options.delay ? resolveTimingValue(options.delay) : 0;
7915
7916    if (delay && (context.previousNode.type === 6
7917    /* AnimationMetadataType.Style */
7918    || startTime == 0 && context.currentTimeline.hasCurrentStyleProperties())) {
7919      context.currentTimeline.snapshotCurrentStyles();
7920      context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
7921    }
7922
7923    let furthestTime = startTime;
7924    const elms = context.invokeQuery(ast.selector, ast.originalSelector, ast.limit, ast.includeSelf, options.optional ? true : false, context.errors);
7925    context.currentQueryTotal = elms.length;
7926    let sameElementTimeline = null;
7927    elms.forEach((element, i) => {
7928      context.currentQueryIndex = i;
7929      const innerContext = context.createSubContext(ast.options, element);
7930
7931      if (delay) {
7932        innerContext.delayNextStep(delay);
7933      }
7934
7935      if (element === context.element) {
7936        sameElementTimeline = innerContext.currentTimeline;
7937      }
7938
7939      visitDslNode(this, ast.animation, innerContext); // this is here just incase the inner steps only contain or end
7940      // with a style() call (which is here to signal that this is a preparatory
7941      // call to style an element before it is animated again)
7942
7943      innerContext.currentTimeline.applyStylesToKeyframe();
7944      const endTime = innerContext.currentTimeline.currentTime;
7945      furthestTime = Math.max(furthestTime, endTime);
7946    });
7947    context.currentQueryIndex = 0;
7948    context.currentQueryTotal = 0;
7949    context.transformIntoNewTimeline(furthestTime);
7950
7951    if (sameElementTimeline) {
7952      context.currentTimeline.mergeTimelineCollectedStyles(sameElementTimeline);
7953      context.currentTimeline.snapshotCurrentStyles();
7954    }
7955
7956    context.previousNode = ast;
7957  }
7958
7959  visitStagger(ast, context) {
7960    const parentContext = context.parentContext;
7961    const tl = context.currentTimeline;
7962    const timings = ast.timings;
7963    const duration = Math.abs(timings.duration);
7964    const maxTime = duration * (context.currentQueryTotal - 1);
7965    let delay = duration * context.currentQueryIndex;
7966    let staggerTransformer = timings.duration < 0 ? 'reverse' : timings.easing;
7967
7968    switch (staggerTransformer) {
7969      case 'reverse':
7970        delay = maxTime - delay;
7971        break;
7972
7973      case 'full':
7974        delay = parentContext.currentStaggerTime;
7975        break;
7976    }
7977
7978    const timeline = context.currentTimeline;
7979
7980    if (delay) {
7981      timeline.delayNextStep(delay);
7982    }
7983
7984    const startingTime = timeline.currentTime;
7985    visitDslNode(this, ast.animation, context);
7986    context.previousNode = ast; // time = duration + delay
7987    // the reason why this computation is so complex is because
7988    // the inner timeline may either have a delay value or a stretched
7989    // keyframe depending on if a subtimeline is not used or is used.
7990
7991    parentContext.currentStaggerTime = tl.currentTime - startingTime + (tl.startTime - parentContext.currentTimeline.startTime);
7992  }
7993
7994}
7995
7996const DEFAULT_NOOP_PREVIOUS_NODE = {};
7997
7998class AnimationTimelineContext {
7999  constructor(_driver, element, subInstructions, _enterClassName, _leaveClassName, errors, timelines, initialTimeline) {
8000    this._driver = _driver;
8001    this.element = element;
8002    this.subInstructions = subInstructions;
8003    this._enterClassName = _enterClassName;
8004    this._leaveClassName = _leaveClassName;
8005    this.errors = errors;
8006    this.timelines = timelines;
8007    this.parentContext = null;
8008    this.currentAnimateTimings = null;
8009    this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
8010    this.subContextCount = 0;
8011    this.options = {};
8012    this.currentQueryIndex = 0;
8013    this.currentQueryTotal = 0;
8014    this.currentStaggerTime = 0;
8015    this.currentTimeline = initialTimeline || new TimelineBuilder(this._driver, element, 0);
8016    timelines.push(this.currentTimeline);
8017  }
8018
8019  get params() {
8020    return this.options.params;
8021  }
8022
8023  updateOptions(options, skipIfExists) {
8024    if (!options) return;
8025    const newOptions = options;
8026    let optionsToUpdate = this.options; // NOTE: this will get patched up when other animation methods support duration overrides
8027
8028    if (newOptions.duration != null) {
8029      optionsToUpdate.duration = resolveTimingValue(newOptions.duration);
8030    }
8031
8032    if (newOptions.delay != null) {
8033      optionsToUpdate.delay = resolveTimingValue(newOptions.delay);
8034    }
8035
8036    const newParams = newOptions.params;
8037
8038    if (newParams) {
8039      let paramsToUpdate = optionsToUpdate.params;
8040
8041      if (!paramsToUpdate) {
8042        paramsToUpdate = this.options.params = {};
8043      }
8044
8045      Object.keys(newParams).forEach(name => {
8046        if (!skipIfExists || !paramsToUpdate.hasOwnProperty(name)) {
8047          paramsToUpdate[name] = interpolateParams(newParams[name], paramsToUpdate, this.errors);
8048        }
8049      });
8050    }
8051  }
8052
8053  _copyOptions() {
8054    const options = {};
8055
8056    if (this.options) {
8057      const oldParams = this.options.params;
8058
8059      if (oldParams) {
8060        const params = options['params'] = {};
8061        Object.keys(oldParams).forEach(name => {
8062          params[name] = oldParams[name];
8063        });
8064      }
8065    }
8066
8067    return options;
8068  }
8069
8070  createSubContext(options = null, element, newTime) {
8071    const target = element || this.element;
8072    const context = new AnimationTimelineContext(this._driver, target, this.subInstructions, this._enterClassName, this._leaveClassName, this.errors, this.timelines, this.currentTimeline.fork(target, newTime || 0));
8073    context.previousNode = this.previousNode;
8074    context.currentAnimateTimings = this.currentAnimateTimings;
8075    context.options = this._copyOptions();
8076    context.updateOptions(options);
8077    context.currentQueryIndex = this.currentQueryIndex;
8078    context.currentQueryTotal = this.currentQueryTotal;
8079    context.parentContext = this;
8080    this.subContextCount++;
8081    return context;
8082  }
8083
8084  transformIntoNewTimeline(newTime) {
8085    this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
8086    this.currentTimeline = this.currentTimeline.fork(this.element, newTime);
8087    this.timelines.push(this.currentTimeline);
8088    return this.currentTimeline;
8089  }
8090
8091  appendInstructionToTimeline(instruction, duration, delay) {
8092    const updatedTimings = {
8093      duration: duration != null ? duration : instruction.duration,
8094      delay: this.currentTimeline.currentTime + (delay != null ? delay : 0) + instruction.delay,
8095      easing: ''
8096    };
8097    const builder = new SubTimelineBuilder(this._driver, instruction.element, instruction.keyframes, instruction.preStyleProps, instruction.postStyleProps, updatedTimings, instruction.stretchStartingKeyframe);
8098    this.timelines.push(builder);
8099    return updatedTimings;
8100  }
8101
8102  incrementTime(time) {
8103    this.currentTimeline.forwardTime(this.currentTimeline.duration + time);
8104  }
8105
8106  delayNextStep(delay) {
8107    // negative delays are not yet supported
8108    if (delay > 0) {
8109      this.currentTimeline.delayNextStep(delay);
8110    }
8111  }
8112
8113  invokeQuery(selector, originalSelector, limit, includeSelf, optional, errors) {
8114    let results = [];
8115
8116    if (includeSelf) {
8117      results.push(this.element);
8118    }
8119
8120    if (selector.length > 0) {
8121      // only if :self is used then the selector can be empty
8122      selector = selector.replace(ENTER_TOKEN_REGEX, '.' + this._enterClassName);
8123      selector = selector.replace(LEAVE_TOKEN_REGEX, '.' + this._leaveClassName);
8124      const multi = limit != 1;
8125
8126      let elements = this._driver.query(this.element, selector, multi);
8127
8128      if (limit !== 0) {
8129        elements = limit < 0 ? elements.slice(elements.length + limit, elements.length) : elements.slice(0, limit);
8130      }
8131
8132      results.push(...elements);
8133    }
8134
8135    if (!optional && results.length == 0) {
8136      errors.push(invalidQuery(originalSelector));
8137    }
8138
8139    return results;
8140  }
8141
8142}
8143
8144class TimelineBuilder {
8145  constructor(_driver, element, startTime, _elementTimelineStylesLookup) {
8146    this._driver = _driver;
8147    this.element = element;
8148    this.startTime = startTime;
8149    this._elementTimelineStylesLookup = _elementTimelineStylesLookup;
8150    this.duration = 0;
8151    this._previousKeyframe = new Map();
8152    this._currentKeyframe = new Map();
8153    this._keyframes = new Map();
8154    this._styleSummary = new Map();
8155    this._localTimelineStyles = new Map();
8156    this._pendingStyles = new Map();
8157    this._backFill = new Map();
8158    this._currentEmptyStepKeyframe = null;
8159
8160    if (!this._elementTimelineStylesLookup) {
8161      this._elementTimelineStylesLookup = new Map();
8162    }
8163
8164    this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element);
8165
8166    if (!this._globalTimelineStyles) {
8167      this._globalTimelineStyles = this._localTimelineStyles;
8168
8169      this._elementTimelineStylesLookup.set(element, this._localTimelineStyles);
8170    }
8171
8172    this._loadKeyframe();
8173  }
8174
8175  containsAnimation() {
8176    switch (this._keyframes.size) {
8177      case 0:
8178        return false;
8179
8180      case 1:
8181        return this.hasCurrentStyleProperties();
8182
8183      default:
8184        return true;
8185    }
8186  }
8187
8188  hasCurrentStyleProperties() {
8189    return this._currentKeyframe.size > 0;
8190  }
8191
8192  get currentTime() {
8193    return this.startTime + this.duration;
8194  }
8195
8196  delayNextStep(delay) {
8197    // in the event that a style() step is placed right before a stagger()
8198    // and that style() step is the very first style() value in the animation
8199    // then we need to make a copy of the keyframe [0, copy, 1] so that the delay
8200    // properly applies the style() values to work with the stagger...
8201    const hasPreStyleStep = this._keyframes.size === 1 && this._pendingStyles.size;
8202
8203    if (this.duration || hasPreStyleStep) {
8204      this.forwardTime(this.currentTime + delay);
8205
8206      if (hasPreStyleStep) {
8207        this.snapshotCurrentStyles();
8208      }
8209    } else {
8210      this.startTime += delay;
8211    }
8212  }
8213
8214  fork(element, currentTime) {
8215    this.applyStylesToKeyframe();
8216    return new TimelineBuilder(this._driver, element, currentTime || this.currentTime, this._elementTimelineStylesLookup);
8217  }
8218
8219  _loadKeyframe() {
8220    if (this._currentKeyframe) {
8221      this._previousKeyframe = this._currentKeyframe;
8222    }
8223
8224    this._currentKeyframe = this._keyframes.get(this.duration);
8225
8226    if (!this._currentKeyframe) {
8227      this._currentKeyframe = new Map();
8228
8229      this._keyframes.set(this.duration, this._currentKeyframe);
8230    }
8231  }
8232
8233  forwardFrame() {
8234    this.duration += ONE_FRAME_IN_MILLISECONDS;
8235
8236    this._loadKeyframe();
8237  }
8238
8239  forwardTime(time) {
8240    this.applyStylesToKeyframe();
8241    this.duration = time;
8242
8243    this._loadKeyframe();
8244  }
8245
8246  _updateStyle(prop, value) {
8247    this._localTimelineStyles.set(prop, value);
8248
8249    this._globalTimelineStyles.set(prop, value);
8250
8251    this._styleSummary.set(prop, {
8252      time: this.currentTime,
8253      value
8254    });
8255  }
8256
8257  allowOnlyTimelineStyles() {
8258    return this._currentEmptyStepKeyframe !== this._currentKeyframe;
8259  }
8260
8261  applyEmptyStep(easing) {
8262    if (easing) {
8263      this._previousKeyframe.set('easing', easing);
8264    } // special case for animate(duration):
8265    // all missing styles are filled with a `*` value then
8266    // if any destination styles are filled in later on the same
8267    // keyframe then they will override the overridden styles
8268    // We use `_globalTimelineStyles` here because there may be
8269    // styles in previous keyframes that are not present in this timeline
8270
8271
8272    for (let [prop, value] of this._globalTimelineStyles) {
8273      this._backFill.set(prop, value || _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
8274
8275      this._currentKeyframe.set(prop, _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
8276    }
8277
8278    this._currentEmptyStepKeyframe = this._currentKeyframe;
8279  }
8280
8281  setStyles(input, easing, errors, options) {
8282    if (easing) {
8283      this._previousKeyframe.set('easing', easing);
8284    }
8285
8286    const params = options && options.params || {};
8287    const styles = flattenStyles(input, this._globalTimelineStyles);
8288
8289    for (let [prop, value] of styles) {
8290      const val = interpolateParams(value, params, errors);
8291
8292      this._pendingStyles.set(prop, val);
8293
8294      if (!this._localTimelineStyles.has(prop)) {
8295        this._backFill.set(prop, this._globalTimelineStyles.get(prop) ?? _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
8296      }
8297
8298      this._updateStyle(prop, val);
8299    }
8300  }
8301
8302  applyStylesToKeyframe() {
8303    if (this._pendingStyles.size == 0) return;
8304
8305    this._pendingStyles.forEach((val, prop) => {
8306      this._currentKeyframe.set(prop, val);
8307    });
8308
8309    this._pendingStyles.clear();
8310
8311    this._localTimelineStyles.forEach((val, prop) => {
8312      if (!this._currentKeyframe.has(prop)) {
8313        this._currentKeyframe.set(prop, val);
8314      }
8315    });
8316  }
8317
8318  snapshotCurrentStyles() {
8319    for (let [prop, val] of this._localTimelineStyles) {
8320      this._pendingStyles.set(prop, val);
8321
8322      this._updateStyle(prop, val);
8323    }
8324  }
8325
8326  getFinalKeyframe() {
8327    return this._keyframes.get(this.duration);
8328  }
8329
8330  get properties() {
8331    const properties = [];
8332
8333    for (let prop in this._currentKeyframe) {
8334      properties.push(prop);
8335    }
8336
8337    return properties;
8338  }
8339
8340  mergeTimelineCollectedStyles(timeline) {
8341    timeline._styleSummary.forEach((details1, prop) => {
8342      const details0 = this._styleSummary.get(prop);
8343
8344      if (!details0 || details1.time > details0.time) {
8345        this._updateStyle(prop, details1.value);
8346      }
8347    });
8348  }
8349
8350  buildKeyframes() {
8351    this.applyStylesToKeyframe();
8352    const preStyleProps = new Set();
8353    const postStyleProps = new Set();
8354    const isEmpty = this._keyframes.size === 1 && this.duration === 0;
8355    let finalKeyframes = [];
8356
8357    this._keyframes.forEach((keyframe, time) => {
8358      const finalKeyframe = copyStyles(keyframe, new Map(), this._backFill);
8359      finalKeyframe.forEach((value, prop) => {
8360        if (value === _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵPRE_STYLE"]) {
8361          preStyleProps.add(prop);
8362        } else if (value === _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE) {
8363          postStyleProps.add(prop);
8364        }
8365      });
8366
8367      if (!isEmpty) {
8368        finalKeyframe.set('offset', time / this.duration);
8369      }
8370
8371      finalKeyframes.push(finalKeyframe);
8372    });
8373
8374    const preProps = preStyleProps.size ? iteratorToArray(preStyleProps.values()) : [];
8375    const postProps = postStyleProps.size ? iteratorToArray(postStyleProps.values()) : []; // special case for a 0-second animation (which is designed just to place styles onscreen)
8376
8377    if (isEmpty) {
8378      const kf0 = finalKeyframes[0];
8379      const kf1 = new Map(kf0);
8380      kf0.set('offset', 0);
8381      kf1.set('offset', 1);
8382      finalKeyframes = [kf0, kf1];
8383    }
8384
vendor: 2,684 bytes, lines 8385-8456
8385    return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false);
8386  }
8387
8388}
8389
8390class SubTimelineBuilder extends TimelineBuilder {
8391  constructor(driver, element, keyframes, preStyleProps, postStyleProps, timings, _stretchStartingKeyframe = false) {
8392    super(driver, element, timings.delay);
8393    this.keyframes = keyframes;
8394    this.preStyleProps = preStyleProps;
8395    this.postStyleProps = postStyleProps;
8396    this._stretchStartingKeyframe = _stretchStartingKeyframe;
8397    this.timings = {
8398      duration: timings.duration,
8399      delay: timings.delay,
8400      easing: timings.easing
8401    };
8402  }
8403
8404  containsAnimation() {
8405    return this.keyframes.length > 1;
8406  }
8407
8408  buildKeyframes() {
8409    let keyframes = this.keyframes;
8410    let {
8411      delay,
8412      duration,
8413      easing
8414    } = this.timings;
8415
8416    if (this._stretchStartingKeyframe && delay) {
8417      const newKeyframes = [];
8418      const totalTime = duration + delay;
8419      const startingGap = delay / totalTime; // the original starting keyframe now starts once the delay is done
8420
8421      const newFirstKeyframe = copyStyles(keyframes[0]);
8422      newFirstKeyframe.set('offset', 0);
8423      newKeyframes.push(newFirstKeyframe);
8424      const oldFirstKeyframe = copyStyles(keyframes[0]);
8425      oldFirstKeyframe.set('offset', roundOffset(startingGap));
8426      newKeyframes.push(oldFirstKeyframe);
8427      /*
8428        When the keyframe is stretched then it means that the delay before the animation
8429        starts is gone. Instead the first keyframe is placed at the start of the animation
8430        and it is then copied to where it starts when the original delay is over. This basically
8431        means nothing animates during that delay, but the styles are still rendered. For this
8432        to work the original offset values that exist in the original keyframes must be "warped"
8433        so that they can take the new keyframe + delay into account.
8434               delay=1000, duration=1000, keyframes = 0 .5 1
8435               turns into
8436               delay=0, duration=2000, keyframes = 0 .33 .66 1
8437       */
8438      // offsets between 1 ... n -1 are all warped by the keyframe stretch
8439
8440      const limit = keyframes.length - 1;
8441
8442      for (let i = 1; i <= limit; i++) {
8443        let kf = copyStyles(keyframes[i]);
8444        const oldOffset = kf.get('offset');
8445        const timeAtKeyframe = delay + oldOffset * duration;
8446        kf.set('offset', roundOffset(timeAtKeyframe / totalTime));
8447        newKeyframes.push(kf);
8448      } // the new starting keyframe should be added at the start
8449
8450
8451      duration = totalTime;
8452      delay = 0;
8453      easing = '';
8454      keyframes = newKeyframes;
8455    }
8456
8457    return createTimelineInstruction(this.element, keyframes, this.preStyleProps, this.postStyleProps, duration, delay, easing, true);
8458  }
8459
8460}
8461
8462function roundOffset(offset, decimalPoints = 3) {
8463  const mult = Math.pow(10, decimalPoints - 1);
8464  return Math.round(offset * mult) / mult;
8465}
8466
8467function flattenStyles(input, allStyles) {
8468  const styles = new Map();
8469  let allProperties;
8470  input.forEach(token => {
8471    if (token === '*') {
8472      allProperties = allProperties || allStyles.keys();
8473
8474      for (let prop of allProperties) {
8475        styles.set(prop, _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
8476      }
8477    } else {
8478      copyStyles(token, styles);
8479    }
8480  });
8481  return styles;
8482}
8483
8484class Animation {
8485  constructor(_driver, input) {
8486    this._driver = _driver;
8487    const errors = [];
8488    const warnings = [];
8489    const ast = buildAnimationAst(_driver, input, errors, warnings);
8490
8491    if (errors.length) {
8492      throw validationFailed(errors);
8493    }
8494
8495    if (warnings.length) {
8496      warnValidation(warnings);
8497    }
8498
8499    this._animationAst = ast;
8500  }
8501
8502  buildTimelines(element, startingStyles, destinationStyles, options, subInstructions) {
8503    const start = Array.isArray(startingStyles) ? normalizeStyles(startingStyles) : startingStyles;
8504    const dest = Array.isArray(destinationStyles) ? normalizeStyles(destinationStyles) : destinationStyles;
8505    const errors = [];
8506    subInstructions = subInstructions || new ElementInstructionMap();
8507    const result = buildAnimationTimelines(this._driver, element, this._animationAst, ENTER_CLASSNAME, LEAVE_CLASSNAME, start, dest, options, subInstructions, errors);
8508
8509    if (errors.length) {
8510      throw buildingFailed(errors);
8511    }
8512
8513    return result;
8514  }
8515
8516}
8517/**
8518 * @license
8519 * Copyright Google LLC All Rights Reserved.
8520 *
8521 * Use of this source code is governed by an MIT-style license that can be
8522 * found in the LICENSE file at https://angular.io/license
8523 */
8524
8525/**
8526 * @publicApi
8527 */
8528
8529
8530class AnimationStyleNormalizer {}
8531/**
8532 * @publicApi
8533 */
8534
8535
8536class NoopAnimationStyleNormalizer {
8537  normalizePropertyName(propertyName, errors) {
8538    return propertyName;
8539  }
8540
8541  normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
8542    return value;
8543  }
8544
8545}
8546/**
8547 * @license
8548 * Copyright Google LLC All Rights Reserved.
8549 *
8550 * Use of this source code is governed by an MIT-style license that can be
8551 * found in the LICENSE file at https://angular.io/license
8552 */
8553
8554
8555const DIMENSIONAL_PROP_SET = 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']);
8556
8557class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
8558  normalizePropertyName(propertyName, errors) {
8559    return dashCaseToCamelCase(propertyName);
8560  }
8561
8562  normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
8563    let unit = '';
8564    const strVal = value.toString().trim();
8565
8566    if (DIMENSIONAL_PROP_SET.has(normalizedProperty) && value !== 0 && value !== '0') {
8567      if (typeof value === 'number') {
8568        unit = 'px';
8569      } else {
8570        const valAndSuffixMatch = value.match(/^[+-]?[\d\.]+([a-z]*)$/);
8571
8572        if (valAndSuffixMatch && valAndSuffixMatch[1].length == 0) {
8573          errors.push(invalidCssUnitValue(userProvidedProperty, value));
8574        }
8575      }
8576    }
8577
8578    return strVal + unit;
8579  }
8580
8581}
8582/**
8583 * @license
8584 * Copyright Google LLC All Rights Reserved.
8585 *
8586 * Use of this source code is governed by an MIT-style license that can be
8587 * found in the LICENSE file at https://angular.io/license
8588 */
8589
8590
8591function createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, totalTime, errors) {
8592  return {
8593    type: 0
8594    /* AnimationTransitionInstructionType.TransitionAnimation */
8595    ,
8596    element,
8597    triggerName,
8598    isRemovalTransition,
8599    fromState,
8600    fromStyles,
8601    toState,
8602    toStyles,
8603    timelines,
8604    queriedElements,
8605    preStyleProps,
8606    postStyleProps,
8607    totalTime,
8608    errors
8609  };
8610}
8611
8612const EMPTY_OBJECT = {};
8613
8614class AnimationTransitionFactory {
8615  constructor(_triggerName, ast, _stateStyles) {
8616    this._triggerName = _triggerName;
8617    this.ast = ast;
8618    this._stateStyles = _stateStyles;
8619  }
8620
8621  match(currentState, nextState, element, params) {
8622    return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState, element, params);
8623  }
8624
8625  buildStyles(stateName, params, errors) {
8626    let styler = this._stateStyles.get('*');
8627
8628    if (stateName !== undefined) {
8629      styler = this._stateStyles.get(stateName?.toString()) || styler;
8630    }
8631
8632    return styler ? styler.buildStyles(params, errors) : new Map();
8633  }
8634
8635  build(driver, element, currentState, nextState, enterClassName, leaveClassName, currentOptions, nextOptions, subInstru
8635ctions, skipAstBuild) {
8636    const errors = [];
8637    const transitionAnimationParams = this.ast.options && this.ast.options.params || EMPTY_OBJECT;
8638    const currentAnimationParams = currentOptions && currentOptions.params || EMPTY_OBJECT;
8639    const currentStateStyles = this.buildStyles(currentState, currentAnimationParams, errors);
8640    const nextAnimationParams = nextOptions && nextOptions.params || EMPTY_OBJECT;
8641    const nextStateStyles = this.buildStyles(nextState, nextAnimationParams, errors);
8642    const queriedElements = new Set();
8643    const preStyleMap = new Map();
8644    const postStyleMap = new Map();
8645    const isRemoval = nextState === 'void';
8646    const animationOptions = {
8647      params: applyParamDefaults(nextAnimationParams, transitionAnimationParams),
8648      delay: this.ast.options?.delay
8649    };
8650    const timelines = skipAstBuild ? [] : buildAnimationTimelines(driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors);
8651    let totalTime = 0;
8652    timelines.forEach(tl => {
8653      totalTime = Math.max(tl.duration + tl.delay, totalTime);
8654    });
8655
8656    if (errors.length) {
8657      return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, [], [], preStyleMap, postStyleMap, totalTime, errors);
8658    }
8659
8660    timelines.forEach(tl => {
8661      const elm = tl.element;
8662      const preProps = getOrSetDefaultValue(preStyleMap, elm, new Set());
8663      tl.preStyleProps.forEach(prop => preProps.add(prop));
8664      const postProps = getOrSetDefaultValue(postStyleMap, elm, new Set());
8665      tl.postStyleProps.forEach(prop => postProps.add(prop));
8666
8667      if (elm !== element) {
8668        queriedElements.add(elm);
8669      }
8670    });
8671
8672    if (typeof ngDevMode === 'undefined' || ngDevMode) {
8673      checkNonAnimatableInTimelines(timelines, this._triggerName, driver);
8674    }
8675
8676    const queriedElementsList = iteratorToArray(queriedElements.values());
8677    return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, timelines, queriedElementsList, preStyleMap, postStyleMap, totalTime);
8678  }
8679
8680}
8681/**
8682 * Checks inside a set of timelines if they try to animate a css property which is not considered
8683 * animatable, in that case it prints a warning on the console.
8684 * Besides that the function doesn't have any other effect.
8685 *
8686 * Note: this check is done here after the timelines are built instead of doing on a lower level so
8687 * that we can make sure that the warning appears only once per instruction (we can aggregate here
8688 * all the issues instead of finding them separately).
8689 *
8690 * @param timelines The built timelines for the current instruction.
8691 * @param triggerName The name of the trigger for the current instruction.
8692 * @param driver Animation driver used to perform the check.
8693 *
8694 */
8695
8696
8697function checkNonAnimatableInTimelines(timelines, triggerName, driver) {
8698  if (!driver.validateAnimatableStyleProperty) {
8699    return;
8700  }
8701
8702  const invalidNonAnimatableProps = new Set();
8703  timelines.forEach(({
8704    keyframes
8705  }) => {
8706    const nonAnimatablePropsInitialValues = new Map();
8707    keyframes.forEach(keyframe => {
8708      for (const [prop, value] of keyframe.entries()) {
8709        if (!driver.validateAnimatableStyleProperty(prop)) {
8710          if (nonAnimatablePropsInitialValues.has(prop) && !invalidNonAnimatableProps.has(prop)) {
8711            const propInitialValue = nonAnimatablePropsInitialValues.get(prop);
8712
8713            if (propInitialValue !== value) {
8714              invalidNonAnimatableProps.add(prop);
8715            }
8716          } else {
8717            nonAnimatablePropsInitialValues.set(prop, value);
8718          }
8719        }
8720      }
8721    });
8722  });
8723
8724  if (invalidNonAnimatableProps.size > 0) {
8725    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)');
8726  }
8727}
8728
8729function oneOrMoreTransitionsMatch(matchFns, currentState, nextState, element, params) {
8730  return matchFns.some(fn => fn(currentState, nextState, element, params));
8731}
8732
8733function applyParamDefaults(userParams, defaults) {
8734  const result = copyObj(defaults);
8735
8736  for (const key in userParams) {
8737    if (userParams.hasOwnProperty(key) && userParams[key] != null) {
8738      result[key] = userParams[key];
8739    }
8740  }
8741
8742  return result;
8743}
8744
8745class AnimationStateStyles {
8746  constructor(styles, defaultParams, normalizer) {
8747    this.styles = styles;
8748    this.defaultParams = defaultParams;
8749    this.normalizer = normalizer;
8750  }
8751
8752  buildStyles(params, errors) {
8753    const finalStyles = new Map();
8754    const combinedParams = copyObj(this.defaultParams);
8755    Object.keys(params).forEach(key => {
8756      const value = params[key];
8757
8758      if (value !== null) {
8759        combinedParams[key] = value;
8760      }
8761    });
8762    this.styles.styles.forEach(value => {
8763      if (typeof value !== 'string') {
8764        value.forEach((val, prop) => {
8765          if (val) {
8766            val = interpolateParams(val, combinedParams, errors);
8767          }
8768
8769          const normalizedProp = this.normalizer.normalizePropertyName(prop, errors);
8770          val = this.normalizer.normalizeStyleValue(prop, normalizedProp, val, errors);
8771          finalStyles.set(normalizedProp, val);
8772        });
8773      }
8774    });
8775    return finalStyles;
8776  }
8777
8778}
8779
8780function buildTrigger(name, ast, normalizer) {
8781  return new AnimationTrigger(name, ast, normalizer);
8782}
8783
8784class AnimationTrigger {
8785  constructor(name, ast, _normalizer) {
8786    this.name = name;
8787    this.ast = ast;
8788    this._normalizer = _normalizer;
8789    this.transitionFactories = [];
8790    this.states = new Map();
8791    ast.states.forEach(ast => {
8792      const defaultParams = ast.options && ast.options.params || {};
8793      this.states.set(ast.name, new AnimationStateStyles(ast.style, defaultParams, _normalizer));
8794    });
8795    balanceProperties(this.states, 'true', '1');
8796    balanceProperties(this.states, 'false', '0');
8797    ast.transitions.forEach(ast => {
8798      this.transitionFactories.push(new AnimationTransitionFactory(name, ast, this.states));
8799    });
8800    this.fallbackTransition = createFallbackTransition(name, this.states, this._normalizer);
8801  }
8802
8803  get containsQueries() {
8804    return this.ast.queryCount > 0;
8805  }
8806
8807  matchTransition(currentState, nextState, element, params) {
8808    const entry = this.transitionFactories.find(f => f.match(currentState, nextState, element, params));
8809    return entry || null;
8810  }
8811
8812  matchStyles(currentState, params, errors) {
8813    return this.fallbackTransition.buildStyles(currentState, params, errors);
8814  }
8815
8816}
8817
8818function createFallbackTransition(triggerName, states, normalizer) {
8819  const matchers = [(fromState, toState) => true];
8820  const animation = {
8821    type: 2
8822    /* AnimationMetadataType.Sequence */
8823    ,
8824    steps: [],
8825    options: null
8826  };
8827  const transition = {
8828    type: 1
8829    /* AnimationMetadataType.Transition */
8830    ,
8831    animation,
8832    matchers,
8833    options: null,
8834    queryCount: 0,
8835    depCount: 0
8836  };
8837  return new AnimationTransitionFactory(triggerName, transition, states);
8838}
8839
8840function balanceProperties(stateMap, key1, key2) {
8841  if (stateMap.has(key1)) {
8842    if (!stateMap.has(key2)) {
8843      stateMap.set(key2, stateMap.get(key1));
8844    }
8845  } else if (stateMap.has(key2)) {
8846    stateMap.set(key1, stateMap.get(key2));
8847  }
8848}
8849/**
8850 * @license
8851 * Copyright Google LLC All Rights Reserved.
8852 *
8853 * Use of this source code is governed by an MIT-style license that can be
8854 * found in the LICENSE file at https://angular.io/license
8855 */
8856
8857
8858const EMPTY_INSTRUCTION_MAP = new ElementInstructionMap();
8859
8860class TimelineAnimationEngine {
8861  constructor(bodyNode, _driver, _normalizer) {
8862    this.bodyNode = bodyNode;
8863    this._driver = _driver;
8864    this._normalizer = _normalizer;
8865    this._animations = new Map();
8866    this._playersById = new Map();
8867    this.players = [];
8868  }
8869
8870  register(id, metadata) {
8871    const errors = [];
8872    const warnings = [];
8873    const ast = buildAnimationAst(this._driver, metadata, errors, warnings);
8874
8875    if (errors.length) {
8876      throw registerFailed(errors);
8877    } else {
8878      if (warnings.length) {
8879        warnRegister(warnings);
8880      }
8881
8882      this._animations.set(id, ast);
8883    }
8884  }
8885
8886  _buildPlayer(i, preStyles, postStyles) {
8887    const element = i.element;
8888    const keyframes = normalizeKeyframes$1(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
8889    return this._driver.animate(element, keyframes, i.duration, i.delay, i.easing, [], true);
8890  }
8891
8892  create(id, element, options = {}) {
8893    const errors = [];
8894
8895    const ast = this._animations.get(id);
8896
8897    let instructions;
8898    const autoStylesMap = new Map();
8899
8900    if (ast) {
8901      instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, new Map(), new Map(), options, EMPTY_INSTRUCTION_MAP, errors);
8902      instructions.forEach(inst => {
8903        const styles = getOrSetDefaultValue(autoStylesMap, inst.element, new Map());
8904        inst.postStyleProps.forEach(prop => styles.set(prop, null));
8905      });
8906    } else {
8907      errors.push(missingOrDestroyedAnimation());
8908      instructions = [];
8909    }
8910
8911    if (errors.length) {
8912      throw createAnimationFailed(errors);
8913    }
8914
vendor: 17,520 bytes, lines 8915-9511
8915    autoStylesMap.forEach((styles, element) => {
8916      styles.forEach((_, prop) => {
8917        styles.set(prop, this._driver.computeStyle(element, prop, _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE));
8918      });
8919    });
8920    const players = instructions.map(i => {
8921      const styles = autoStylesMap.get(i.element);
8922      return this._buildPlayer(i, new Map(), styles);
8923    });
8924    const player = optimizeGroupPlayer(players);
8925
8926    this._playersById.set(id, player);
8927
8928    player.onDestroy(() => this.destroy(id));
8929    this.players.push(player);
8930    return player;
8931  }
8932
8933  destroy(id) {
8934    const player = this._getPlayer(id);
8935
8936    player.destroy();
8937
8938    this._playersById.delete(id);
8939
8940    const index = this.players.indexOf(player);
8941
8942    if (index >= 0) {
8943      this.players.splice(index, 1);
8944    }
8945  }
8946
8947  _getPlayer(id) {
8948    const player = this._playersById.get(id);
8949
8950    if (!player) {
8951      throw missingPlayer(id);
8952    }
8953
8954    return player;
8955  }
8956
8957  listen(id, element, eventName, callback) {
8958    // triggerName, fromState, toState are all ignored for timeline animations
8959    const baseEvent = makeAnimationEvent(element, '', '', '');
8960    listenOnPlayer(this._getPlayer(id), eventName, baseEvent, callback);
8961    return () => {};
8962  }
8963
8964  command(id, element, command, args) {
8965    if (command == 'register') {
8966      this.register(id, args[0]);
8967      return;
8968    }
8969
8970    if (command == 'create') {
8971      const options = args[0] || {};
8972      this.create(id, element, options);
8973      return;
8974    }
8975
8976    const player = this._getPlayer(id);
8977
8978    switch (command) {
8979      case 'play':
8980        player.play();
8981        break;
8982
8983      case 'pause':
8984        player.pause();
8985        break;
8986
8987      case 'reset':
8988        player.reset();
8989        break;
8990
8991      case 'restart':
8992        player.restart();
8993        break;
8994
8995      case 'finish':
8996        player.finish();
8997        break;
8998
8999      case 'init':
9000        player.init();
9001        break;
9002
9003      case 'setPosition':
9004        player.setPosition(parseFloat(args[0]));
9005        break;
9006
9007      case 'destroy':
9008        this.destroy(id);
9009        break;
9010    }
9011  }
9012
9013}
9014/**
9015 * @license
9016 * Copyright Google LLC All Rights Reserved.
9017 *
9018 * Use of this source code is governed by an MIT-style license that can be
9019 * found in the LICENSE file at https://angular.io/license
9020 */
9021
9022
9023const QUEUED_CLASSNAME = 'ng-animate-queued';
9024const QUEUED_SELECTOR = '.ng-animate-queued';
9025const DISABLED_CLASSNAME = 'ng-animate-disabled';
9026const DISABLED_SELECTOR = '.ng-animate-disabled';
9027const STAR_CLASSNAME = 'ng-star-inserted';
9028const STAR_SELECTOR = '.ng-star-inserted';
9029const EMPTY_PLAYER_ARRAY = [];
9030const NULL_REMOVAL_STATE = {
9031  namespaceId: '',
9032  setForRemoval: false,
9033  setForMove: false,
9034  hasAnimation: false,
9035  removedBeforeQueried: false
9036};
9037const NULL_REMOVED_QUERIED_STATE = {
9038  namespaceId: '',
9039  setForMove: false,
9040  setForRemoval: false,
9041  hasAnimation: false,
9042  removedBeforeQueried: true
9043};
9044const REMOVAL_FLAG = '__ng_removed';
9045
9046class StateValue {
9047  constructor(input, namespaceId = '') {
9048    this.namespaceId = namespaceId;
9049    const isObj = input && input.hasOwnProperty('value');
9050    const value = isObj ? input['value'] : input;
9051    this.value = normalizeTriggerValue(value);
9052
9053    if (isObj) {
9054      const options = copyObj(input);
9055      delete options['value'];
9056      this.options = options;
9057    } else {
9058      this.options = {};
9059    }
9060
9061    if (!this.options.params) {
9062      this.options.params = {};
9063    }
9064  }
9065
9066  get params() {
9067    return this.options.params;
9068  }
9069
9070  absorbOptions(options) {
9071    const newParams = options.params;
9072
9073    if (newParams) {
9074      const oldParams = this.options.params;
9075      Object.keys(newParams).forEach(prop => {
9076        if (oldParams[prop] == null) {
9077          oldParams[prop] = newParams[prop];
9078        }
9079      });
9080    }
9081  }
9082
9083}
9084
9085const VOID_VALUE = 'void';
9086const DEFAULT_STATE_VALUE = new StateValue(VOID_VALUE);
9087
9088class AnimationTransitionNamespace {
9089  constructor(id, hostElement, _engine) {
9090    this.id = id;
9091    this.hostElement = hostElement;
9092    this._engine = _engine;
9093    this.players = [];
9094    this._triggers = new Map();
9095    this._queue = [];
9096    this._elementListeners = new Map();
9097    this._hostClassName = 'ng-tns-' + id;
9098    addClass(hostElement, this._hostClassName);
9099  }
9100
9101  listen(element, name, phase, callback) {
9102    if (!this._triggers.has(name)) {
9103      throw missingTrigger(phase, name);
9104    }
9105
9106    if (phase == null || phase.length == 0) {
9107      throw missingEvent(name);
9108    }
9109
9110    if (!isTriggerEventValid(phase)) {
9111      throw unsupportedTriggerEvent(phase, name);
9112    }
9113
9114    const listeners = getOrSetDefaultValue(this._elementListeners, element, []);
9115    const data = {
9116      name,
9117      phase,
9118      callback
9119    };
9120    listeners.push(data);
9121    const triggersWithStates = getOrSetDefaultValue(this._engine.statesByElement, element, new Map());
9122
9123    if (!triggersWithStates.has(name)) {
9124      addClass(element, NG_TRIGGER_CLASSNAME);
9125      addClass(element, NG_TRIGGER_CLASSNAME + '-' + name);
9126      triggersWithStates.set(name, DEFAULT_STATE_VALUE);
9127    }
9128
9129    return () => {
9130      // the event listener is removed AFTER the flush has occurred such
9131      // that leave animations callbacks can fire (otherwise if the node
9132      // is removed in between then the listeners would be deregistered)
9133      this._engine.afterFlush(() => {
9134        const index = listeners.indexOf(data);
9135
9136        if (index >= 0) {
9137          listeners.splice(index, 1);
9138        }
9139
9140        if (!this._triggers.has(name)) {
9141          triggersWithStates.delete(name);
9142        }
9143      });
9144    };
9145  }
9146
9147  register(name, ast) {
9148    if (this._triggers.has(name)) {
9149      // throw
9150      return false;
9151    } else {
9152      this._triggers.set(name, ast);
9153
9154      return true;
9155    }
9156  }
9157
9158  _getTrigger(name) {
9159    const trigger = this._triggers.get(name);
9160
9161    if (!trigger) {
9162      throw unregisteredTrigger(name);
9163    }
9164
9165    return trigger;
9166  }
9167
9168  trigger(element, triggerName, value, defaultToFallback = true) {
9169    const trigger = this._getTrigger(triggerName);
9170
9171    const player = new TransitionAnimationPlayer(this.id, triggerName, element);
9172
9173    let triggersWithStates = this._engine.statesByElement.get(element);
9174
9175    if (!triggersWithStates) {
9176      addClass(element, NG_TRIGGER_CLASSNAME);
9177      addClass(element, NG_TRIGGER_CLASSNAME + '-' + triggerName);
9178
9179      this._engine.statesByElement.set(element, triggersWithStates = new Map());
9180    }
9181
9182    let fromState = triggersWithStates.get(triggerName);
9183    const toState = new StateValue(value, this.id);
9184    const isObj = value && value.hasOwnProperty('value');
9185
9186    if (!isObj && fromState) {
9187      toState.absorbOptions(fromState.options);
9188    }
9189
9190    triggersWithStates.set(triggerName, toState);
9191
9192    if (!fromState) {
9193      fromState = DEFAULT_STATE_VALUE;
9194    }
9195
9196    const isRemoval = toState.value === VOID_VALUE; // normally this isn't reached by here, however, if an object expression
9197    // is passed in then it may be a new object each time. Comparing the value
9198    // is important since that will stay the same despite there being a new object.
9199    // The removal arc here is special cased because the same element is triggered
9200    // twice in the event that it contains animations on the outer/inner portions
9201    // of the host container
9202
9203    if (!isRemoval && fromState.value === toState.value) {
9204      // this means that despite the value not changing, some inner params
9205      // have changed which means that the animation final styles need to be applied
9206      if (!objEquals(fromState.params, toState.params)) {
9207        const errors = [];
9208        const fromStyles = trigger.matchStyles(fromState.value, fromState.params, errors);
9209        const toStyles = trigger.matchStyles(toState.value, toState.params, errors);
9210
9211        if (errors.length) {
9212          this._engine.reportError(errors);
9213        } else {
9214          this._engine.afterFlush(() => {
9215            eraseStyles(element, fromStyles);
9216            setStyles(element, toStyles);
9217          });
9218        }
9219      }
9220
9221      return;
9222    }
9223
9224    const playersOnElement = getOrSetDefaultValue(this._engine.playersByElement, element, []);
9225    playersOnElement.forEach(player => {
9226      // only remove the player if it is queued on the EXACT same trigger/namespace
9227      // we only also deal with queued players here because if the animation has
9228      // started then we want to keep the player alive until the flush happens
9229      // (which is where the previousPlayers are passed into the new player)
9230      if (player.namespaceId == this.id && player.triggerName == triggerName && player.queued) {
9231        player.destroy();
9232      }
9233    });
9234    let transition = trigger.matchTransition(fromState.value, toState.value, element, toState.params);
9235    let isFallbackTransition = false;
9236
9237    if (!transition) {
9238      if (!defaultToFallback) return;
9239      transition = trigger.fallbackTransition;
9240      isFallbackTransition = true;
9241    }
9242
9243    this._engine.totalQueuedPlayers++;
9244
9245    this._queue.push({
9246      element,
9247      triggerName,
9248      transition,
9249      fromState,
9250      toState,
9251      player,
9252      isFallbackTransition
9253    });
9254
9255    if (!isFallbackTransition) {
9256      addClass(element, QUEUED_CLASSNAME);
9257      player.onStart(() => {
9258        removeClass(element, QUEUED_CLASSNAME);
9259      });
9260    }
9261
9262    player.onDone(() => {
9263      let index = this.players.indexOf(player);
9264
9265      if (index >= 0) {
9266        this.players.splice(index, 1);
9267      }
9268
9269      const players = this._engine.playersByElement.get(element);
9270
9271      if (players) {
9272        let index = players.indexOf(player);
9273
9274        if (index >= 0) {
9275          players.splice(index, 1);
9276        }
9277      }
9278    });
9279    this.players.push(player);
9280    playersOnElement.push(player);
9281    return player;
9282  }
9283
9284  deregister(name) {
9285    this._triggers.delete(name);
9286
9287    this._engine.statesByElement.forEach(stateMap => stateMap.delete(name));
9288
9289    this._elementListeners.forEach((listeners, element) => {
9290      this._elementListeners.set(element, listeners.filter(entry => {
9291        return entry.name != name;
9292      }));
9293    });
9294  }
9295
9296  clearElementCache(element) {
9297    this._engine.statesByElement.delete(element);
9298
9299    this._elementListeners.delete(element);
9300
9301    const elementPlayers = this._engine.playersByElement.get(element);
9302
9303    if (elementPlayers) {
9304      elementPlayers.forEach(player => player.destroy());
9305
9306      this._engine.playersByElement.delete(element);
9307    }
9308  }
9309
9310  _signalRemovalForInnerTriggers(rootElement, context) {
9311    const elements = this._engine.driver.query(rootElement, NG_TRIGGER_SELECTOR, true); // emulate a leave animation for all inner nodes within this node.
9312    // If there are no animations found for any of the nodes then clear the cache
9313    // for the element.
9314
9315
9316    elements.forEach(elm => {
9317      // this means that an inner remove() operation has already kicked off
9318      // the animation on this element...
9319      if (elm[REMOVAL_FLAG]) return;
9320
9321      const namespaces = this._engine.fetchNamespacesByElement(elm);
9322
9323      if (namespaces.size) {
9324        namespaces.forEach(ns => ns.triggerLeaveAnimation(elm, context, false, true));
9325      } else {
9326        this.clearElementCache(elm);
9327      }
9328    }); // If the child elements were removed along with the parent, their animations might not
9329    // have completed. Clear all the elements from the cache so we don't end up with a memory leak.
9330
9331    this._engine.afterFlushAnimationsDone(() => elements.forEach(elm => this.clearElementCache(elm)));
9332  }
9333
9334  triggerLeaveAnimation(element, context, destroyAfterComplete, defaultToFallback) {
9335    const triggerStates = this._engine.statesByElement.get(element);
9336
9337    const previousTriggersValues = new Map();
9338
9339    if (triggerStates) {
9340      const players = [];
9341      triggerStates.forEach((state, triggerName) => {
9342        previousTriggersValues.set(triggerName, state.value); // this check is here in the event that an element is removed
9343        // twice (both on the host level and the component level)
9344
9345        if (this._triggers.has(triggerName)) {
9346          const player = this.trigger(element, triggerName, VOID_VALUE, defaultToFallback);
9347
9348          if (player) {
9349            players.push(player);
9350          }
9351        }
9352      });
9353
9354      if (players.length) {
9355        this._engine.markElementAsRemoved(this.id, element, true, context, previousTriggersValues);
9356
9357        if (destroyAfterComplete) {
9358          optimizeGroupPlayer(players).onDone(() => this._engine.processLeaveNode(element));
9359        }
9360
9361        return true;
9362      }
9363    }
9364
9365    return false;
9366  }
9367
9368  prepareLeaveAnimationListeners(element) {
9369    const listeners = this._elementListeners.get(element);
9370
9371    const elementStates = this._engine.statesByElement.get(element); // if this statement fails then it means that the element was picked up
9372    // by an earlier flush (or there are no listeners at all to track the leave).
9373
9374
9375    if (listeners && elementStates) {
9376      const visitedTriggers = new Set();
9377      listeners.forEach(listener => {
9378        const triggerName = listener.name;
9379        if (visitedTriggers.has(triggerName)) return;
9380        visitedTriggers.add(triggerName);
9381
9382        const trigger = this._triggers.get(triggerName);
9383
9384        const transition = trigger.fallbackTransition;
9385        const fromState = elementStates.get(triggerName) || DEFAULT_STATE_VALUE;
9386        const toState = new StateValue(VOID_VALUE);
9387        const player = new TransitionAnimationPlayer(this.id, triggerName, element);
9388        this._engine.totalQueuedPlayers++;
9389
9390        this._queue.push({
9391          element,
9392          triggerName,
9393          transition,
9394          fromState,
9395          toState,
9396          player,
9397          isFallbackTransition: true
9398        });
9399      });
9400    }
9401  }
9402
9403  removeNode(element, context) {
9404    const engine = this._engine;
9405
9406    if (element.childElementCount) {
9407      this._signalRemovalForInnerTriggers(element, context);
9408    } // this means that a * => VOID animation was detected and kicked off
9409
9410
9411    if (this.triggerLeaveAnimation(element, context, true)) return; // find the player that is animating and make sure that the
9412    // removal is delayed until that player has completed
9413
9414    let containsPotentialParentTransition = false;
9415
9416    if (engine.totalAnimations) {
9417      const currentPlayers = engine.players.length ? engine.playersByQueriedElement.get(element) : []; // when this `if statement` does not continue forward it means that
9418      // a previous animation query has selected the current element and
9419      // is animating it. In this situation want to continue forwards and
9420      // allow the element to be queued up for animation later.
9421
9422      if (currentPlayers && currentPlayers.length) {
9423        containsPotentialParentTransition = true;
9424      } else {
9425        let parent = element;
9426
9427        while (parent = parent.parentNode) {
9428          const triggers = engine.statesByElement.get(parent);
9429
9430          if (triggers) {
9431            containsPotentialParentTransition = true;
9432            break;
9433          }
9434        }
9435      }
9436    } // at this stage we know that the element will either get removed
9437    // during flush or will be picked up by a parent query. Either way
9438    // we need to fire the listeners for this element when it DOES get
9439    // removed (once the query parent animation is done or after flush)
9440
9441
9442    this.prepareLeaveAnimationListeners(element); // whether or not a parent has an animation we need to delay the deferral of the leave
9443    // operation until we have more information (which we do after flush() has been called)
9444
9445    if (containsPotentialParentTransition) {
9446      engine.markElementAsRemoved(this.id, element, false, context);
9447    } else {
9448      const removalFlag = element[REMOVAL_FLAG];
9449
9450      if (!removalFlag || removalFlag === NULL_REMOVAL_STATE) {
9451        // we do this after the flush has occurred such
9452        // that the callbacks can be fired
9453        engine.afterFlush(() => this.clearElementCache(element));
9454        engine.destroyInnerAnimations(element);
9455
9456        engine._onRemovalComplete(element, context);
9457      }
9458    }
9459  }
9460
9461  insertNode(element, parent) {
9462    addClass(element, this._hostClassName);
9463  }
9464
9465  drainQueuedTransitions(microtaskId) {
9466    const instructions = [];
9467
9468    this._queue.forEach(entry => {
9469      const player = entry.player;
9470      if (player.destroyed) return;
9471      const element = entry.element;
9472
9473      const listeners = this._elementListeners.get(element);
9474
9475      if (listeners) {
9476        listeners.forEach(listener => {
9477          if (listener.name == entry.triggerName) {
9478            const baseEvent = makeAnimationEvent(element, entry.triggerName, entry.fromState.value, entry.toState.value);
9479            baseEvent['_data'] = microtaskId;
9480            listenOnPlayer(entry.player, listener.phase, baseEvent, listener.callback);
9481          }
9482        });
9483      }
9484
9485      if (player.markedForDestroy) {
9486        this._engine.afterFlush(() => {
9487          // now we can destroy the element properly since the event listeners have
9488          // been bound to the player
9489          player.destroy();
9490        });
9491      } else {
9492        instructions.push(entry);
9493      }
9494    });
9495
9496    this._queue = [];
9497    return instructions.sort((a, b) => {
9498      // if depCount == 0 them move to front
9499      // otherwise if a contains b then move back
9500      const d0 = a.transition.ast.depCount;
9501      const d1 = b.transition.ast.depCount;
9502
9503      if (d0 == 0 || d1 == 0) {
9504        return d0 - d1;
9505      }
9506
9507      return this._engine.driver.containsElement(a.element, b.element) ? 1 : -1;
9508    });
9509  }
9510
9511  destroy(context) {
9512    this.players.forEach(p => p.destroy());
9513
9514    this._signalRemovalForInnerTriggers(this.hostElement, context);
9515  }
9516
9517  elementContainsData(element) {
9518    let containsData = false;
9519    if (this._elementListeners.has(element)) containsData = true;
9520    containsData = (this._queue.find(entry => entry.element === element) ? true : false) || containsData;
9521    return containsData;
9522  }
9523
9524}
9525
9526class TransitionAnimationEngine {
9527  constructor(bodyNode, driver, _normalizer) {
9528    this.bodyNode = bodyNode;
9529    this.driver = driver;
9530    this._normalizer = _normalizer;
9531    this.players = [];
9532    this.newHostElements = new Map();
9533    this.playersByElement = new Map();
9534    this.playersByQueriedElement = new Map();
9535    this.statesByElement = new Map();
9536    this.disabledNodes = new Set();
9537    this.totalAnimations = 0;
9538    this.totalQueuedPlayers = 0;
9539    this._namespaceLookup = {};
9540    this._namespaceList = [];
9541    this._flushFns = [];
9542    this._whenQuietFns = [];
9543    this.namespacesByHostElement = new Map();
9544    this.collectedEnterElements = [];
9545    this.collectedLeaveElements = []; // this method is designed to be overridden by the code that uses this engine
9546
9547    this.onRemovalComplete = (element, context) => {};
9548  }
9549  /** @internal */
9550
9551
9552  _onRemovalComplete(element, context) {
9553    this.onRemovalComplete(element, context);
9554  }
9555
9556  get queuedPlayers() {
9557    const players = [];
9558
9559    this._namespaceList.forEach(ns => {
9560      ns.players.forEach(player => {
9561        if (player.queued) {
9562          players.push(player);
9563        }
9564      });
9565    });
9566
9567    return players;
9568  }
9569
9570  createNamespace(namespaceId, hostElement) {
9571    const ns = new AnimationTransitionNamespace(namespaceId, hostElement, this);
9572
9573    if (this.bodyNode && this.driver.containsElement(this.bodyNode, hostElement)) {
9574      this._balanceNamespaceList(ns, hostElement);
9575    } else {
9576      // defer this later until flush during when the host element has
9577      // been inserted so that we know exactly where to place it in
9578      // the namespace list
9579      this.newHostElements.set(hostElement, ns); // given that this host element is a part of the animation code, it
9580      // may or may not be inserted by a parent node that is of an
9581      // animation renderer type. If this happens then we can still have
9582      // access to this item when we query for :enter nodes. If the parent
9583      // is a renderer then the set data-structure will normalize the entry
9584
9585      this.collectEnterElement(hostElement);
9586    }
9587
9588    return this._namespaceLookup[namespaceId] = ns;
9589  }
9590
9591  _balanceNamespaceList(ns, hostElement) {
9592    const namespaceList = this._namespaceList;
9593    const namespacesByHostElement = this.namespacesByHostElement;
9594    const limit = namespaceList.length - 1;
9595
9596    if (limit >= 0) {
9597      let found = false; // Find the closest ancestor with an existing namespace so we can then insert `ns` after it,
9598      // establishing a top-down ordering of namespaces in `this._namespaceList`.
9599
9600      let ancestor = this.driver.getParentElement(hostElement);
9601
9602      while (ancestor) {
9603        const ancestorNs = namespacesByHostElement.get(ancestor);
9604
9605        if (ancestorNs) {
9606          // An animation namespace has been registered for this ancestor, so we insert `ns`
9607          // right after it to establish top-down ordering of animation namespaces.
9608          const index = namespaceList.indexOf(ancestorNs);
9609          namespaceList.splice(index + 1, 0, ns);
9610          found = true;
9611          break;
9612        }
9613
9614        ancestor = this.driver.getParentElement(ancestor);
9615      }
9616
9617      if (!found) {
9618        // No namespace exists that is an ancestor of `ns`, so `ns` is inserted at the front to
9619        // ensure that any existing descendants are ordered after `ns`, retaining the desired
9620        // top-down ordering.
9621        namespaceList.unshift(ns);
9622      }
9623    } else {
9624      namespaceList.push(ns);
9625    }
9626
9627    namespacesByHostElement.set(hostElement, ns);
9628    return ns;
9629  }
9630
9631  register(namespaceId, hostElement) {
9632    let ns = this._namespaceLookup[namespaceId];
9633
9634    if (!ns) {
9635      ns = this.createNamespace(namespaceId, hostElement);
9636    }
9637
9638    return ns;
9639  }
9640
9641  registerTrigger(namespaceId, name, trigger) {
9642    let ns = this._namespaceLookup[namespaceId];
9643
9644    if (ns && ns.register(name, trigger)) {
9645      this.totalAnimations++;
9646    }
9647  }
9648
9649  destroy(namespaceId, context) {
9650    if (!namespaceId) return;
9651
9652    const ns = this._fetchNamespace(namespaceId);
9653
9654    this.afterFlush(() => {
9655      this.namespacesByHostElement.delete(ns.hostElement);
9656      delete this._namespaceLookup[namespaceId];
9657
9658      const index = this._namespaceList.indexOf(ns);
9659
9660      if (index >= 0) {
9661        this._namespaceList.splice(index, 1);
9662      }
9663    });
9664    this.afterFlushAnimationsDone(() => ns.destroy(context));
9665  }
9666
9667  _fetchNamespace(id) {
9668    return this._namespaceLookup[id];
9669  }
9670
9671  fetchNamespacesByElement(element) {
9672    // normally there should only be one namespace per element, however
9673    // if @triggers are placed on both the component element and then
9674    // its host element (within the component code) then there will be
9675    // two namespaces returned. We use a set here to simply deduplicate
9676    // the namespaces in case (for the reason described above) there are multiple triggers
9677    const namespaces = new Set();
9678    const elementStates = this.statesByElement.get(element);
9679
9680    if (elementStates) {
9681      for (let stateValue of elementStates.values()) {
9682        if (stateValue.namespaceId) {
9683          const ns = this._fetchNamespace(stateValue.namespaceId);
9684
9685          if (ns) {
9686            namespaces.add(ns);
9687          }
9688        }
9689      }
9690    }
9691
9692    return namespaces;
9693  }
9694
9695  trigger(namespaceId, element, name, value) {
9696    if (isElementNode(element)) {
9697      const ns = this._fetchNamespace(namespaceId);
9698
9699      if (ns) {
9700        ns.trigger(element, name, value);
9701        return true;
9702      }
9703    }
9704
9705    return false;
vendor: 8,359 bytes, lines 9706-9965
9706  }
9707
9708  insertNode(namespaceId, element, parent, insertBefore) {
9709    if (!isElementNode(element)) return; // special case for when an element is removed and reinserted (move operation)
9710    // when this occurs we do not want to use the element for deletion later
9711
9712    const details = element[REMOVAL_FLAG];
9713
9714    if (details && details.setForRemoval) {
9715      details.setForRemoval = false;
9716      details.setForMove = true;
9717      const index = this.collectedLeaveElements.indexOf(element);
9718
9719      if (index >= 0) {
9720        this.collectedLeaveElements.splice(index, 1);
9721      }
9722    } // in the event that the namespaceId is blank then the caller
9723    // code does not contain any animation code in it, but it is
9724    // just being called so that the node is marked as being inserted
9725
9726
9727    if (namespaceId) {
9728      const ns = this._fetchNamespace(namespaceId); // This if-statement is a workaround for router issue #21947.
9729      // The router sometimes hits a race condition where while a route
9730      // is being instantiated a new navigation arrives, triggering leave
9731      // animation of DOM that has not been fully initialized, until this
9732      // is resolved, we need to handle the scenario when DOM is not in a
9733      // consistent state during the animation.
9734
9735
9736      if (ns) {
9737        ns.insertNode(element, parent);
9738      }
9739    } // only *directives and host elements are inserted before
9740
9741
9742    if (insertBefore) {
9743      this.collectEnterElement(element);
9744    }
9745  }
9746
9747  collectEnterElement(element) {
9748    this.collectedEnterElements.push(element);
9749  }
9750
9751  markElementAsDisabled(element, value) {
9752    if (value) {
9753      if (!this.disabledNodes.has(element)) {
9754        this.disabledNodes.add(element);
9755        addClass(element, DISABLED_CLASSNAME);
9756      }
9757    } else if (this.disabledNodes.has(element)) {
9758      this.disabledNodes.delete(element);
9759      removeClass(element, DISABLED_CLASSNAME);
9760    }
9761  }
9762
9763  removeNode(namespaceId, element, isHostElement, context) {
9764    if (isElementNode(element)) {
9765      const ns = namespaceId ? this._fetchNamespace(namespaceId) : null;
9766
9767      if (ns) {
9768        ns.removeNode(element, context);
9769      } else {
9770        this.markElementAsRemoved(namespaceId, element, false, context);
9771      }
9772
9773      if (isHostElement) {
9774        const hostNS = this.namespacesByHostElement.get(element);
9775
9776        if (hostNS && hostNS.id !== namespaceId) {
9777          hostNS.removeNode(element, context);
9778        }
9779      }
9780    } else {
9781      this._onRemovalComplete(element, context);
9782    }
9783  }
9784
9785  markElementAsRemoved(namespaceId, element, hasAnimation, context, previousTriggersValues) {
9786    this.collectedLeaveElements.push(element);
9787    element[REMOVAL_FLAG] = {
9788      namespaceId,
9789      setForRemoval: context,
9790      hasAnimation,
9791      removedBeforeQueried: false,
9792      previousTriggersValues
9793    };
9794  }
9795
9796  listen(namespaceId, element, name, phase, callback) {
9797    if (isElementNode(element)) {
9798      return this._fetchNamespace(namespaceId).listen(element, name, phase, callback);
9799    }
9800
9801    return () => {};
9802  }
9803
9804  _buildInstruction(entry, subTimelines, enterClassName, leaveClassName, skipBuildAst) {
9805    return entry.transition.build(this.driver, entry.element, entry.fromState.value, entry.toState.value, enterClassName, leaveClassName, entry.fromState.options, entry.toState.options, subTimelines, skipBuildAst);
9806  }
9807
9808  destroyInnerAnimations(containerElement) {
9809    let elements = this.driver.query(containerElement, NG_TRIGGER_SELECTOR, true);
9810    elements.forEach(element => this.destroyActiveAnimationsForElement(element));
9811    if (this.playersByQueriedElement.size == 0) return;
9812    elements = this.driver.query(containerElement, NG_ANIMATING_SELECTOR, true);
9813    elements.forEach(element => this.finishActiveQueriedAnimationOnElement(element));
9814  }
9815
9816  destroyActiveAnimationsForElement(element) {
9817    const players = this.playersByElement.get(element);
9818
9819    if (players) {
9820      players.forEach(player => {
9821        // special case for when an element is set for destruction, but hasn't started.
9822        // in this situation we want to delay the destruction until the flush occurs
9823        // so that any event listeners attached to the player are triggered.
9824        if (player.queued) {
9825          player.markedForDestroy = true;
9826        } else {
9827          player.destroy();
9828        }
9829      });
9830    }
9831  }
9832
9833  finishActiveQueriedAnimationOnElement(element) {
9834    const players = this.playersByQueriedElement.get(element);
9835
9836    if (players) {
9837      players.forEach(player => player.finish());
9838    }
9839  }
9840
9841  whenRenderingDone() {
9842    return new Promise(resolve => {
9843      if (this.players.length) {
9844        return optimizeGroupPlayer(this.players).onDone(() => resolve());
9845      } else {
9846        resolve();
9847      }
9848    });
9849  }
9850
9851  processLeaveNode(element) {
9852    const details = element[REMOVAL_FLAG];
9853
9854    if (details && details.setForRemoval) {
9855      // this will prevent it from removing it twice
9856      element[REMOVAL_FLAG] = NULL_REMOVAL_STATE;
9857
9858      if (details.namespaceId) {
9859        this.destroyInnerAnimations(element);
9860
9861        const ns = this._fetchNamespace(details.namespaceId);
9862
9863        if (ns) {
9864          ns.clearElementCache(element);
9865        }
9866      }
9867
9868      this._onRemovalComplete(element, details.setForRemoval);
9869    }
9870
9871    if (element.classList?.contains(DISABLED_CLASSNAME)) {
9872      this.markElementAsDisabled(element, false);
9873    }
9874
9875    this.driver.query(element, DISABLED_SELECTOR, true).forEach(node => {
9876      this.markElementAsDisabled(node, false);
9877    });
9878  }
9879
9880  flush(microtaskId = -1) {
9881    let players = [];
9882
9883    if (this.newHostElements.size) {
9884      this.newHostElements.forEach((ns, element) => this._balanceNamespaceList(ns, element));
9885      this.newHostElements.clear();
9886    }
9887
9888    if (this.totalAnimations && this.collectedEnterElements.length) {
9889      for (let i = 0; i < this.collectedEnterElements.length; i++) {
9890        const elm = this.collectedEnterElements[i];
9891        addClass(elm, STAR_CLASSNAME);
9892      }
9893    }
9894
9895    if (this._namespaceList.length && (this.totalQueuedPlayers || this.collectedLeaveElements.length)) {
9896      const cleanupFns = [];
9897
9898      try {
9899        players = this._flushAnimations(cleanupFns, microtaskId);
9900      } finally {
9901        for (let i = 0; i < cleanupFns.length; i++) {
9902          cleanupFns[i]();
9903        }
9904      }
9905    } else {
9906      for (let i = 0; i < this.collectedLeaveElements.length; i++) {
9907        const element = this.collectedLeaveElements[i];
9908        this.processLeaveNode(element);
9909      }
9910    }
9911
9912    this.totalQueuedPlayers = 0;
9913    this.collectedEnterElements.length = 0;
9914    this.collectedLeaveElements.length = 0;
9915
9916    this._flushFns.forEach(fn => fn());
9917
9918    this._flushFns = [];
9919
9920    if (this._whenQuietFns.length) {
9921      // we move these over to a variable so that
9922      // if any new callbacks are registered in another
9923      // flush they do not populate the existing set
9924      const quietFns = this._whenQuietFns;
9925      this._whenQuietFns = [];
9926
9927      if (players.length) {
9928        optimizeGroupPlayer(players).onDone(() => {
9929          quietFns.forEach(fn => fn());
9930        });
9931      } else {
9932        quietFns.forEach(fn => fn());
9933      }
9934    }
9935  }
9936
9937  reportError(errors) {
9938    throw triggerTransitionsFailed(errors);
9939  }
9940
9941  _flushAnimations(cleanupFns, microtaskId) {
9942    const subTimelines = new ElementInstructionMap();
9943    const skippedPlayers = [];
9944    const skippedPlayersMap = new Map();
9945    const queuedInstructions = [];
9946    const queriedElements = new Map();
9947    const allPreStyleElements = new Map();
9948    const allPostStyleElements = new Map();
9949    const disabledElementsSet = new Set();
9950    this.disabledNodes.forEach(node => {
9951      disabledElementsSet.add(node);
9952      const nodesThatAreDisabled = this.driver.query(node, QUEUED_SELECTOR, true);
9953
9954      for (let i = 0; i < nodesThatAreDisabled.length; i++) {
9955        disabledElementsSet.add(nodesThatAreDisabled[i]);
9956      }
9957    });
9958    const bodyNode = this.bodyNode;
9959    const allTriggerElements = Array.from(this.statesByElement.keys());
9960    const enterNodeMap = buildRootMap(allTriggerElements, this.collectedEnterElements); // this must occur before the instructions are built below such that
9961    // the :enter queries match the elements (since the timeline queries
9962    // are fired during instruction building).
9963
9964    const enterNodeMapIds = new Map();
9965    let i = 0;
9966    enterNodeMap.forEach((nodes, root) => {
9967      const className = ENTER_CLASSNAME + i++;
9968      enterNodeMapIds.set(root, className);
9969      nodes.forEach(node => addClass(node, className));
9970    });
9971    const allLeaveNodes = [];
9972    const mergedLeaveNodes = new Set();
9973    const leaveNodesWithoutAnimations = new Set();
9974
9975    for (let i = 0; i < this.collectedLeaveElements.length; i++) {
9976      const element = this.collectedLeaveElements[i];
9977      const details = element[REMOVAL_FLAG];
9978
9979      if (details && details.setForRemoval) {
9980        allLeaveNodes.push(element);
9981        mergedLeaveNodes.add(element);
9982
9983        if (details.hasAnimation) {
9984          this.driver.query(element, STAR_SELECTOR, true).forEach(elm => mergedLeaveNodes.add(elm));
9985        } else {
9986          leaveNodesWithoutAnimations.add(element);
9987        }
9988      }
9989    }
9990
9991    const leaveNodeMapIds = new Map();
9992    const leaveNodeMap = buildRootMap(allTriggerElements, Array.from(mergedLeaveNodes));
9993    leaveNodeMap.forEach((nodes, root) => {
9994      const className = LEAVE_CLASSNAME + i++;
9995      leaveNodeMapIds.set(root, className);
9996      nodes.forEach(node => addClass(node, className));
9997    });
9998    cleanupFns.push(() => {
vendor: 4,150 bytes, lines 9999-10096
9999      enterNodeMap.forEach((nodes, root) => {
10000        const className = enterNodeMapIds.get(root);
10001        nodes.forEach(node => removeClass(node, className));
10002      });
10003      leaveNodeMap.forEach((nodes, root) => {
10004        const className = leaveNodeMapIds.get(root);
10005        nodes.forEach(node => removeClass(node, className));
10006      });
10007      allLeaveNodes.forEach(element => {
10008        this.processLeaveNode(element);
10009      });
10010    });
10011    const allPlayers = [];
10012    const erroneousTransitions = [];
10013
10014    for (let i = this._namespaceList.length - 1; i >= 0; i--) {
10015      const ns = this._namespaceList[i];
10016      ns.drainQueuedTransitions(microtaskId).forEach(entry => {
10017        const player = entry.player;
10018        const element = entry.element;
10019        allPlayers.push(player);
10020
10021        if (this.collectedEnterElements.length) {
10022          const details = element[REMOVAL_FLAG]; // animations for move operations (elements being removed and reinserted,
10023          // e.g. when the order of an *ngFor list changes) are currently not supported
10024
10025          if (details && details.setForMove) {
10026            if (details.previousTriggersValues && details.previousTriggersValues.has(entry.triggerName)) {
10027              const previousValue = details.previousTriggersValues.get(entry.triggerName); // we need to restore the previous trigger value since the element has
10028              // only been moved and hasn't actually left the DOM
10029
10030              const triggersWithStates = this.statesByElement.get(entry.element);
10031
10032              if (triggersWithStates && triggersWithStates.has(entry.triggerName)) {
10033                const state = triggersWithStates.get(entry.triggerName);
10034                state.value = previousValue;
10035                triggersWithStates.set(entry.triggerName, state);
10036              }
10037            }
10038
10039            player.destroy();
10040            return;
10041          }
10042        }
10043
10044        const nodeIsOrphaned = !bodyNode || !this.driver.containsElement(bodyNode, element);
10045        const leaveClassName = leaveNodeMapIds.get(element);
10046        const enterClassName = enterNodeMapIds.get(element);
10047
10048        const instruction = this._buildInstruction(entry, subTimelines, enterClassName, leaveClassName, nodeIsOrphaned);
10049
10050        if (instruction.errors && instruction.errors.length) {
10051          erroneousTransitions.push(instruction);
10052          return;
10053        } // even though the element may not be in the DOM, it may still
10054        // be added at a later point (due to the mechanics of content
10055        // projection and/or dynamic component insertion) therefore it's
10056        // important to still style the element.
10057
10058
10059        if (nodeIsOrphaned) {
10060          player.onStart(() => eraseStyles(element, instruction.fromStyles));
10061          player.onDestroy(() => setStyles(element, instruction.toStyles));
10062          skippedPlayers.push(player);
10063          return;
10064        } // if an unmatched transition is queued and ready to go
10065        // then it SHOULD NOT render an animation and cancel the
10066        // previously running animations.
10067
10068
10069        if (entry.isFallbackTransition) {
10070          player.onStart(() => eraseStyles(element, instruction.fromStyles));
10071          player.onDestroy(() => setStyles(element, instruction.toStyles));
10072          skippedPlayers.push(player);
10073          return;
10074        } // this means that if a parent animation uses this animation as a sub-trigger
10075        // then it will instruct the timeline builder not to add a player delay, but
10076        // instead stretch the first keyframe gap until the animation starts. This is
10077        // important in order to prevent extra initialization styles from being
10078        // required by the user for the animation.
10079
10080
10081        const timelines = [];
10082        instruction.timelines.forEach(tl => {
10083          tl.stretchStartingKeyframe = true;
10084
10085          if (!this.disabledNodes.has(tl.element)) {
10086            timelines.push(tl);
10087          }
10088        });
10089        instruction.timelines = timelines;
10090        subTimelines.append(element, instruction.timelines);
10091        const tuple = {
10092          instruction,
10093          player,
10094          element
10095        };
10096        queuedInstructions.push(tuple);
10097        instruction.queriedElements.forEach(element => getOrSetDefaultValue(queriedElements, element, []).push(player));
10098        instruction.preStyleProps.forEach((stringMap, element) => {
10099          if (stringMap.size) {
10100            let setVal = allPreStyleElements.get(element);
10101
10102            if (!setVal) {
10103              allPreStyleElements.set(element, setVal = new Set());
10104            }
10105
10106            stringMap.forEach((_, prop) => setVal.add(prop));
10107          }
10108        });
10109        instruction.postStyleProps.forEach((stringMap, element) => {
10110          let setVal = allPostStyleElements.get(element);
10111
10112          if (!setVal) {
10113            allPostStyleElements.set(element, setVal = new Set());
10114          }
10115
10116          stringMap.forEach((_, prop) => setVal.add(prop));
10117        });
10118      });
10119    }
10120
10121    if (erroneousTransitions.length) {
10122      const errors = [];
10123      erroneousTransitions.forEach(instruction => {
10124        errors.push(transitionFailed(instruction.triggerName, instruction.errors));
10125      });
10126      allPlayers.forEach(player => player.destroy());
10127      this.reportError(errors);
10128    }
10129
10130    const allPreviousPlayersMap = new Map(); // this map tells us which element in the DOM tree is contained by
10131    // which animation. Further down this map will get populated once
10132    // the players are built and in doing so we can use it to efficiently
10133    // figure out if a sub player is skipped due to a parent player having priority.
10134
10135    const animationElementMap = new Map();
10136    queuedInstructions.forEach(entry => {
10137      const element = entry.element;
10138
10139      if (subTimelines.has(element)) {
10140        animationElementMap.set(element, element);
10141
10142        this._beforeAnimationBuild(entry.player.namespaceId, entry.instruction, allPreviousPlayersMap);
10143      }
10144    });
10145    skippedPlayers.forEach(player => {
10146      const element = player.element;
10147
10148      const previousPlayers = this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);
10149
10150      previousPlayers.forEach(prevPlayer => {
10151        getOrSetDefaultValue(allPreviousPlayersMap, element, []).push(prevPlayer);
10152        prevPlayer.destroy();
10153      });
10154    }); // this is a special case for nodes that will be removed either by
10155    // having their own leave animations or by being queried in a container
10156    // that will be removed once a parent animation is complete. The idea
10157    // here is that * styles must be identical to ! styles because of
10158    // backwards compatibility (* is also filled in by default in many places).
10159    // Otherwise * styles will return an empty value or "auto" since the element
10160    // passed to getComputedStyle will not be visible (since * === destination)
10161
10162    const replaceNodes = allLeaveNodes.filter(node => {
10163      return replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements);
10164    }); // POST STAGE: fill the * styles
10165
10166    const postStylesMap = new Map();
10167    const allLeaveQueriedNodes = cloakAndComputeStyles(postStylesMap, this.driver, leaveNodesWithoutAnimations, allPostStyleElements, _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
10168    allLeaveQueriedNodes.forEach(node => {
10169      if (replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements)) {
10170        replaceNodes.push(node);
10171      }
10172    }); // PRE STAGE: fill the ! styles
10173
10174    const preStylesMap = new Map();
vendor: 5,685 bytes, lines 10175-10314
10175    enterNodeMap.forEach((nodes, root) => {
10176      cloakAndComputeStyles(preStylesMap, this.driver, new Set(nodes), allPreStyleElements, _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵPRE_STYLE"]);
10177    });
10178    replaceNodes.forEach(node => {
10179      const post = postStylesMap.get(node);
10180      const pre = preStylesMap.get(node);
10181      postStylesMap.set(node, new Map([...Array.from(post?.entries() ?? []), ...Array.from(pre?.entries() ?? [])]));
10182    });
10183    const rootPlayers = [];
10184    const subPlayers = [];
10185    const NO_PARENT_ANIMATION_ELEMENT_DETECTED = {};
10186    queuedInstructions.forEach(entry => {
10187      const {
10188        element,
10189        player,
10190        instruction
10191      } = entry; // this means that it was never consumed by a parent animation which
10192      // means that it is independent and therefore should be set for animation
10193
10194      if (subTimelines.has(element)) {
10195        if (disabledElementsSet.has(element)) {
10196          player.onDestroy(() => setStyles(element, instruction.toStyles));
10197          player.disabled = true;
10198          player.overrideTotalTime(instruction.totalTime);
10199          skippedPlayers.push(player);
10200          return;
10201        } // this will flow up the DOM and query the map to figure out
10202        // if a parent animation has priority over it. In the situation
10203        // that a parent is detected then it will cancel the loop. If
10204        // nothing is detected, or it takes a few hops to find a parent,
10205        // then it will fill in the missing nodes and signal them as having
10206        // a detected parent (or a NO_PARENT value via a special constant).
10207
10208
10209        let parentWithAnimation = NO_PARENT_ANIMATION_ELEMENT_DETECTED;
10210
10211        if (animationElementMap.size > 1) {
10212          let elm = element;
10213          const parentsToAdd = [];
10214
10215          while (elm = elm.parentNode) {
10216            const detectedParent = animationElementMap.get(elm);
10217
10218            if (detectedParent) {
10219              parentWithAnimation = detectedParent;
10220              break;
10221            }
10222
10223            parentsToAdd.push(elm);
10224          }
10225
10226          parentsToAdd.forEach(parent => animationElementMap.set(parent, parentWithAnimation));
10227        }
10228
10229        const innerPlayer = this._buildAnimation(player.namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap);
10230
10231        player.setRealPlayer(innerPlayer);
10232
10233        if (parentWithAnimation === NO_PARENT_ANIMATION_ELEMENT_DETECTED) {
10234          rootPlayers.push(player);
10235        } else {
10236          const parentPlayers = this.playersByElement.get(parentWithAnimation);
10237
10238          if (parentPlayers && parentPlayers.length) {
10239            player.parentPlayer = optimizeGroupPlayer(parentPlayers);
10240          }
10241
10242          skippedPlayers.push(player);
10243        }
10244      } else {
10245        eraseStyles(element, instruction.fromStyles);
10246        player.onDestroy(() => setStyles(element, instruction.toStyles)); // there still might be a ancestor player animating this
10247        // element therefore we will still add it as a sub player
10248        // even if its animation may be disabled
10249
10250        subPlayers.push(player);
10251
10252        if (disabledElementsSet.has(element)) {
10253          skippedPlayers.push(player);
10254        }
10255      }
10256    }); // find all of the sub players' corresponding inner animation players
10257
10258    subPlayers.forEach(player => {
10259      // even if no players are found for a sub animation it
10260      // will still complete itself after the next tick since it's Noop
10261      const playersForElement = skippedPlayersMap.get(player.element);
10262
10263      if (playersForElement && playersForElement.length) {
10264        const innerPlayer = optimizeGroupPlayer(playersForElement);
10265        player.setRealPlayer(innerPlayer);
10266      }
10267    }); // the reason why we don't actually play the animation is
10268    // because all that a skipped player is designed to do is to
10269    // fire the start/done transition callback events
10270
10271    skippedPlayers.forEach(player => {
10272      if (player.parentPlayer) {
10273        player.syncPlayerEvents(player.parentPlayer);
10274      } else {
10275        player.destroy();
10276      }
10277    }); // run through all of the queued removals and see if they
10278    // were picked up by a query. If not then perform the removal
10279    // operation right away unless a parent animation is ongoing.
10280
10281    for (let i = 0; i < allLeaveNodes.length; i++) {
10282      const element = allLeaveNodes[i];
10283      const details = element[REMOVAL_FLAG];
10284      removeClass(element, LEAVE_CLASSNAME); // this means the element has a removal animation that is being
10285      // taken care of and therefore the inner elements will hang around
10286      // until that animation is over (or the parent queried animation)
10287
10288      if (details && details.hasAnimation) continue;
10289      let players = []; // if this element is queried or if it contains queried children
10290      // then we want for the element not to be removed from the page
10291      // until the queried animations have finished
10292
10293      if (queriedElements.size) {
10294        let queriedPlayerResults = queriedElements.get(element);
10295
10296        if (queriedPlayerResults && queriedPlayerResults.length) {
10297          players.push(...queriedPlayerResults);
10298        }
10299
10300        let queriedInnerElements = this.driver.query(element, NG_ANIMATING_SELECTOR, true);
10301
10302        for (let j = 0; j < queriedInnerElements.length; j++) {
10303          let queriedPlayers = queriedElements.get(queriedInnerElements[j]);
10304
10305          if (queriedPlayers && queriedPlayers.length) {
10306            players.push(...queriedPlayers);
10307          }
10308        }
10309      }
10310
10311      const activePlayers = players.filter(p => !p.destroyed);
10312
10313      if (activePlayers.length) {
10314        removeNodesAfterAnimationDone(this, element, activePlayers
10314);
10315      } else {
10316        this.processLeaveNode(element);
10317      }
10318    } // this is required so the cleanup method doesn't remove them
10319
10320
10321    allLeaveNodes.length = 0;
10322    rootPlayers.forEach(player => {
10323      this.players.push(player);
10324      player.onDone(() => {
10325        player.destroy();
10326        const index = this.players.indexOf(player);
10327        this.players.splice(index, 1);
10328      });
10329      player.play();
10330    });
10331    return rootPlayers;
10332  }
10333
10334  elementContainsData(namespaceId, element) {
10335    let containsData = false;
10336    const details = element[REMOVAL_FLAG];
10337    if (details && details.setForRemoval) containsData = true;
10338    if (this.playersByElement.has(element)) containsData = true;
10339    if (this.playersByQueriedElement.has(element)) containsData = true;
10340    if (this.statesByElement.has(element)) containsData = true;
10341    return this._fetchNamespace(namespaceId).elementContainsData(element) || containsData;
10342  }
10343
10344  afterFlush(callback) {
10345    this._flushFns.push(callback);
10346  }
10347
10348  afterFlushAnimationsDone(callback) {
10349    this._whenQuietFns.push(callback);
10350  }
10351
10352  _getPreviousPlayers(element, isQueriedElement, namespaceId, triggerName, toStateValue) {
10353    let players = [];
10354
10355    if (isQueriedElement) {
10356      const queriedElementPlayers = this.playersByQueriedElement.get(element);
10357
10358      if (queriedElementPlayers) {
10359        players = queriedElementPlayers;
10360      }
10361    } else {
10362      const elementPlayers = this.playersByElement.get(element);
10363
10364      if (elementPlayers) {
10365        const isRemovalAnimation = !toStateValue || toStateValue == VOID_VALUE;
10366        elementPlayers.forEach(player => {
10367          if (player.queued) return;
10368          if (!isRemovalAnimation && player.triggerName != triggerName) return;
10369          players.push(player);
10370        });
10371      }
10372    }
10373
10374    if (namespaceId || triggerName) {
10375      players = players.filter(player => {
10376        if (namespaceId && namespaceId != player.namespaceId) return false;
10377        if (triggerName && triggerName != player.triggerName) return false;
10378        return true;
10379      });
10380    }
10381
10382    return players;
10383  }
10384
10385  _beforeAnimationBuild(namespaceId, instruction, allPreviousPlayersMap) {
10386    const triggerName = instruction.triggerName;
10387    const rootElement = instruction.element; // when a removal animation occurs, ALL previous players are collected
10388    // and destroyed (even if they are outside of the current namespace)
10389
10390    const targetNameSpaceId = instruction.isRemovalTransition ? undefined : namespaceId;
10391    const targetTriggerName = instruction.isRemovalTransition ? undefined : triggerName;
10392
10393    for (const timelineInstruction of instruction.timelines) {
10394      const element = timelineInstruction.element;
10395      const isQueriedElement = element !== rootElement;
10396      const players = getOrSetDefaultValue(allPreviousPlayersMap, element, []);
10397
10398      const previousPlayers = this._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);
10399
10400      previousPlayers.forEach(player => {
10401        const realPlayer = player.getRealPlayer();
10402
10403        if (realPlayer.beforeDestroy) {
10404          realPlayer.beforeDestroy();
10405        }
10406
10407        player.destroy();
10408        players.push(player);
10409      });
10410    } // this needs to be done so that the PRE/POST styles can be
10411    // computed properly without interfering with the previous animation
10412
10413
10414    eraseStyles(rootElement, instruction.fromStyles);
10415  }
10416
10417  _buildAnimation(namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap) {
10418    const triggerName = instruction.triggerName;
10419    const rootElement = instruction.element; // we first run this so that the previous animation player
10420    // data can be passed into the successive animation players
10421
10422    const allQueriedPlayers = [];
10423    const allConsumedElements = new Set();
10424    const allSubElements = new Set();
10425    const allNewPlayers = instruction.timelines.map(timelineInstru
10425ction => {
10426      const element = timelineInstruction.element;
10427      allConsumedElements.add(element); // FIXME (matsko): make sure to-be-removed animations are removed properly
10428
10429      const details = element[REMOVAL_FLAG];
10430      if (details && details.removedBeforeQueried) return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer(timelineInstruction.duration, timelineInstruction.delay);
10431      const isQueriedElement = element !== rootElement;
10432      const previousPlayers = flattenGroupPlayers((allPreviousPlayersMap.get(element) || EMPTY_PLAYER_ARRAY).map(p => p.getRealPlayer())).filter(p => {
10433        // the `element` is not apart of the AnimationPlayer definition, but
10434        // Mock/WebAnimations
10435        // use the element within their implementation. This will be added in Angular5 to
10436        // AnimationPlayer
10437        const pp = p;
10438        return pp.element ? pp.element === element : false;
10439      });
10440      const preStyles = preStylesMap.get(element);
10441      const postStyles = postStylesMap.get(element);
10442      const keyframes = normalizeKeyframes$1(this.driver, this._normalizer, element, timelineInstru
vendor: 15,572 bytes, lines 10442-11008
10442ction.keyframes, preStyles, postStyles);
10443
10444      const player = this._buildPlayer(timelineInstruction, keyframes, previousPlayers); // this means that this particular player belongs to a sub trigger. It is
10445      // important that we match this player up with the corresponding (@trigger.listener)
10446
10447
10448      if (timelineInstruction.subTimeline && skippedPlayersMap) {
10449        allSubElements.add(element);
10450      }
10451
10452      if (isQueriedElement) {
10453        const wrappedPlayer = new TransitionAnimationPlayer(namespaceId, triggerName, element);
10454        wrappedPlayer.setRealPlayer(player);
10455        allQueriedPlayers.push(wrappedPlayer);
10456      }
10457
10458      return player;
10459    });
10460    allQueriedPlayers.forEach(player => {
10461      getOrSetDefaultValue(this.playersByQueriedElement, player.element, []).push(player);
10462      player.onDone(() => deleteOrUnsetInMap(this.playersByQueriedElement, player.element, player));
10463    });
10464    allConsumedElements.forEach(element => addClass(element, NG_ANIMATING_CLASSNAME));
10465    const player = optimizeGroupPlayer(allNewPlayers);
10466    player.onDestroy(() => {
10467      allConsumedElements.forEach(element => removeClass(element, NG_ANIMATING_CLASSNAME));
10468      setStyles(rootElement, instruction.toStyles);
10469    }); // this basically makes all of the callbacks for sub element animations
10470    // be dependent on the upper players for when they finish
10471
10472    allSubElements.forEach(element => {
10473      getOrSetDefaultValue(skippedPlayersMap, element, []).push(player);
10474    });
10475    return player;
10476  }
10477
10478  _buildPlayer(instruction, keyframes, previousPlayers) {
10479    if (keyframes.length > 0) {
10480      return this.driver.animate(instruction.element, keyframes, instruction.duration, instruction.delay, instruction.easing, previousPlayers);
10481    } // special case for when an empty transition|definition is provided
10482    // ... there is no point in rendering an empty animation
10483
10484
10485    return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer(instruction.duration, instruction.delay);
10486  }
10487
10488}
10489
10490class TransitionAnimationPlayer {
10491  constructor(namespaceId, triggerName, element) {
10492    this.namespaceId = namespaceId;
10493    this.triggerName = triggerName;
10494    this.element = element;
10495    this._player = new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer();
10496    this._containsRealPlayer = false;
10497    this._queuedCallbacks = new Map();
10498    this.destroyed = false;
10499    this.markedForDestroy = false;
10500    this.disabled = false;
10501    this.queued = true;
10502    this.totalTime = 0;
10503  }
10504
10505  setRealPlayer(player) {
10506    if (this._containsRealPlayer) return;
10507    this._player = player;
10508
10509    this._queuedCallbacks.forEach((callbacks, phase) => {
10510      callbacks.forEach(callback => listenOnPlayer(player, phase, undefined, callback));
10511    });
10512
10513    this._queuedCallbacks.clear();
10514
10515    this._containsRealPlayer = true;
10516    this.overrideTotalTime(player.totalTime);
10517    this.queued = false;
10518  }
10519
10520  getRealPlayer() {
10521    return this._player;
10522  }
10523
10524  overrideTotalTime(totalTime) {
10525    this.totalTime = totalTime;
10526  }
10527
10528  syncPlayerEvents(player) {
10529    const p = this._player;
10530
10531    if (p.triggerCallback) {
10532      player.onStart(() => p.triggerCallback('start'));
10533    }
10534
10535    player.onDone(() => this.finish());
10536    player.onDestroy(() => this.destroy());
10537  }
10538
10539  _queueEvent(name, callback) {
10540    getOrSetDefaultValue(this._queuedCallbacks, name, []).push(callback);
10541  }
10542
10543  onDone(fn) {
10544    if (this.queued) {
10545      this._queueEvent('done', fn);
10546    }
10547
10548    this._player.onDone(fn);
10549  }
10550
10551  onStart(fn) {
10552    if (this.queued) {
10553      this._queueEvent('start', fn);
10554    }
10555
10556    this._player.onStart(fn);
10557  }
10558
10559  onDestroy(fn) {
10560    if (this.queued) {
10561      this._queueEvent('destroy', fn);
10562    }
10563
10564    this._player.onDestroy(fn);
10565  }
10566
10567  init() {
10568    this._player.init();
10569  }
10570
10571  hasStarted() {
10572    return this.queued ? false : this._player.hasStarted();
10573  }
10574
10575  play() {
10576    !this.queued && this._player.play();
10577  }
10578
10579  pause() {
10580    !this.queued && this._player.pause();
10581  }
10582
10583  restart() {
10584    !this.queued && this._player.restart();
10585  }
10586
10587  finish() {
10588    this._player.finish();
10589  }
10590
10591  destroy() {
10592    this.destroyed = true;
10593
10594    this._player.destroy();
10595  }
10596
10597  reset() {
10598    !this.queued && this._player.reset();
10599  }
10600
10601  setPosition(p) {
10602    if (!this.queued) {
10603      this._player.setPosition(p);
10604    }
10605  }
10606
10607  getPosition() {
10608    return this.queued ? 0 : this._player.getPosition();
10609  }
10610  /** @internal */
10611
10612
10613  triggerCallback(phaseName) {
10614    const p = this._player;
10615
10616    if (p.triggerCallback) {
10617      p.triggerCallback(phaseName);
10618    }
10619  }
10620
10621}
10622
10623function deleteOrUnsetInMap(map, key, value) {
10624  let currentValues = map.get(key);
10625
10626  if (currentValues) {
10627    if (currentValues.length) {
10628      const index = currentValues.indexOf(value);
10629      currentValues.splice(index, 1);
10630    }
10631
10632    if (currentValues.length == 0) {
10633      map.delete(key);
10634    }
10635  }
10636
10637  return currentValues;
10638}
10639
10640function normalizeTriggerValue(value) {
10641  // we use `!= null` here because it's the most simple
10642  // way to test against a "falsy" value without mixing
10643  // in empty strings or a zero value. DO NOT OPTIMIZE.
10644  return value != null ? value : null;
10645}
10646
10647function isElementNode(node) {
10648  return node && node['nodeType'] === 1;
10649}
10650
10651function isTriggerEventValid(eventName) {
10652  return eventName == 'start' || eventName == 'done';
10653}
10654
10655function cloakElement(element, value) {
10656  const oldValue = element.style.display;
10657  element.style.display = value != null ? value : 'none';
10658  return oldValue;
10659}
10660
10661function cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, defaultStyle) {
10662  const cloakVals = [];
10663  elements.forEach(element => cloakVals.push(cloakElement(element)));
10664  const failedElements = [];
10665  elementPropsMap.forEach((props, element) => {
10666    const styles = new Map();
10667    props.forEach(prop => {
10668      const value = driver.computeStyle(element, prop, defaultStyle);
10669      styles.set(prop, value); // there is no easy way to detect this because a sub element could be removed
10670      // by a parent animation element being detached.
10671
10672      if (!value || value.length == 0) {
10673        element[REMOVAL_FLAG] = NULL_REMOVED_QUERIED_STATE;
10674        failedElements.push(element);
10675      }
10676    });
10677    valuesMap.set(element, styles);
10678  }); // we use a index variable here since Set.forEach(a, i) does not return
10679  // an index value for the closure (but instead just the value)
10680
10681  let i = 0;
10682  elements.forEach(element => cloakElement(element, cloakVals[i++]));
10683  return failedElements;
10684}
10685/*
10686Since the Angular renderer code will return a collection of inserted
10687nodes in all areas of a DOM tree, it's up to this algorithm to figure
10688out which nodes are roots for each animation @trigger.
10689
10690By placing each inserted node into a Set and traversing upwards, it
10691is possible to find the @trigger elements and well any direct *star
10692insertion nodes, if a @trigger root is found then the enter element
10693is placed into the Map[@trigger] spot.
10694 */
10695
10696
10697function buildRootMap(roots, nodes) {
10698  const rootMap = new Map();
10699  roots.forEach(root => rootMap.set(root, []));
10700  if (nodes.length == 0) return rootMap;
10701  const NULL_NODE = 1;
10702  const nodeSet = new Set(nodes);
10703  const localRootMap = new Map();
10704
10705  function getRoot(node) {
10706    if (!node) return NULL_NODE;
10707    let root = localRootMap.get(node);
10708    if (root) return root;
10709    const parent = node.parentNode;
10710
10711    if (rootMap.has(parent)) {
10712      // ngIf inside @trigger
10713      root = parent;
10714    } else if (nodeSet.has(parent)) {
10715      // ngIf inside ngIf
10716      root = NULL_NODE;
10717    } else {
10718      // recurse upwards
10719      root = getRoot(parent);
10720    }
10721
10722    localRootMap.set(node, root);
10723    return root;
10724  }
10725
10726  nodes.forEach(node => {
10727    const root = getRoot(node);
10728
10729    if (root !== NULL_NODE) {
10730      rootMap.get(root).push(node);
10731    }
10732  });
10733  return rootMap;
10734}
10735
10736function addClass(element, className) {
10737  element.classList?.add(className);
10738}
10739
10740function removeClass(element, className) {
10741  element.classList?.remove(className);
10742}
10743
10744function removeNodesAfterAnimationDone(engine, element, players) {
10745  optimizeGroupPlayer(players).onDone(() => engine.processLeaveNode(element));
10746}
10747
10748function flattenGroupPlayers(players) {
10749  const finalPlayers = [];
10750
10751  _flattenGroupPlayersRecur(players, finalPlayers);
10752
10753  return finalPlayers;
10754}
10755
10756function _flattenGroupPlayersRecur(players, finalPlayers) {
10757  for (let i = 0; i < players.length; i++) {
10758    const player = players[i];
10759
10760    if (player instanceof _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationGroupPlayer"]) {
10761      _flattenGroupPlayersRecur(player.players, finalPlayers);
10762    } else {
10763      finalPlayers.push(player);
10764    }
10765  }
10766}
10767
10768function objEquals(a, b) {
10769  const k1 = Object.keys(a);
10770  const k2 = Object.keys(b);
10771  if (k1.length != k2.length) return false;
10772
10773  for (let i = 0; i < k1.length; i++) {
10774    const prop = k1[i];
10775    if (!b.hasOwnProperty(prop) || a[prop] !== b[prop]) return false;
10776  }
10777
10778  return true;
10779}
10780
10781function replacePostStylesAsPre(element, allPreStyleElements, allPostStyleElements) {
10782  const postEntry = allPostStyleElements.get(element);
10783  if (!postEntry) return false;
10784  let preEntry = allPreStyleElements.get(element);
10785
10786  if (preEntry) {
10787    postEntry.forEach(data => preEntry.add(data));
10788  } else {
10789    allPreStyleElements.set(element, postEntry);
10790  }
10791
10792  allPostStyleElements.delete(element);
10793  return true;
10794}
10795
10796class AnimationEngine {
10797  constructor(bodyNode, _driver, _normalizer) {
10798    this.bodyNode = bodyNode;
10799    this._driver = _driver;
10800    this._normalizer = _normalizer;
10801    this._triggerCache = {}; // this method is designed to be overridden by the code that uses this engine
10802
10803    this.onRemovalComplete = (element, context) => {};
10804
10805    this._transitionEngine = new TransitionAnimationEngine(bodyNode, _driver, _normalizer);
10806    this._timelineEngine = new TimelineAnimationEngine(bodyNode, _driver, _normalizer);
10807
10808    this._transitionEngine.onRemovalComplete = (element, context) => this.onRemovalComplete(element, context);
10809  }
10810
10811  registerTrigger(componentId, namespaceId, hostElement, name, metadata) {
10812    const cacheKey = componentId + '-' + name;
10813    let trigger = this._triggerCache[cacheKey];
10814
10815    if (!trigger) {
10816      const errors = [];
10817      const warnings = [];
10818      const ast = buildAnimationAst(this._driver, metadata, errors, warnings);
10819
10820      if (errors.length) {
10821        throw triggerBuildFailed(name, errors);
10822      }
10823
10824      if (warnings.length) {
10825        warnTriggerBuild(name, warnings);
10826      }
10827
10828      trigger = buildTrigger(name, ast, this._normalizer);
10829      this._triggerCache[cacheKey] = trigger;
10830    }
10831
10832    this._transitionEngine.registerTrigger(namespaceId, name, trigger);
10833  }
10834
10835  register(namespaceId, hostElement) {
10836    this._transitionEngine.register(namespaceId, hostElement);
10837  }
10838
10839  destroy(namespaceId, context) {
10840    this._transitionEngine.destroy(namespaceId, context);
10841  }
10842
10843  onInsert(namespaceId, element, parent, insertBefore) {
10844    this._transitionEngine.insertNode(namespaceId, element, parent, insertBefore);
10845  }
10846
10847  onRemove(namespaceId, element, context, isHostElement) {
10848    this._transitionEngine.removeNode(namespaceId, element, isHostElement || false, context);
10849  }
10850
10851  disableAnimations(element, disable) {
10852    this._transitionEngine.markElementAsDisabled(element, disable);
10853  }
10854
10855  process(namespaceId, element, property, value) {
10856    if (property.charAt(0) == '@') {
10857      const [id, action] = parseTimelineCommand(property);
10858      const args = value;
10859
10860      this._timelineEngine.command(id, element, action, args);
10861    } else {
10862      this._transitionEngine.trigger(namespaceId, element, property, value);
10863    }
10864  }
10865
10866  listen(namespaceId, element, eventName, eventPhase, callback) {
10867    // @@listen
10868    if (eventName.charAt(0) == '@') {
10869      const [id, action] = parseTimelineCommand(eventName);
10870      return this._timelineEngine.listen(id, element, action, callback);
10871    }
10872
10873    return this._transitionEngine.listen(namespaceId, element, eventName, eventPhase, callback);
10874  }
10875
10876  flush(microtaskId = -1) {
10877    this._transitionEngine.flush(microtaskId);
10878  }
10879
10880  get players() {
10881    return this._transitionEngine.players.concat(this._timelineEngine.players);
10882  }
10883
10884  whenRenderingDone() {
10885    return this._transitionEngine.whenRenderingDone();
10886  }
10887
10888}
10889/**
10890 * Returns an instance of `SpecialCasedStyles` if and when any special (non animateable) styles are
10891 * detected.
10892 *
10893 * In CSS there exist properties that cannot be animated within a keyframe animation
10894 * (whether it be via CSS keyframes or web-animations) and the animation implementation
10895 * will ignore them. This function is designed to detect those special cased styles and
10896 * return a container that will be executed at the start and end of the animation.
10897 *
10898 * @returns an instance of `SpecialCasedStyles` if any special styles are detected otherwise `null`
10899 */
10900
10901
10902function packageNonAnimatableStyles(element, styles) {
10903  let startStyles = null;
10904  let endStyles = null;
10905
10906  if (Array.isArray(styles) && styles.length) {
10907    startStyles = filterNonAnimatableStyles(styles[0]);
10908
10909    if (styles.length > 1) {
10910      endStyles = filterNonAnimatableStyles(styles[styles.length - 1]);
10911    }
10912  } else if (styles instanceof Map) {
10913    startStyles = filterNonAnimatableStyles(styles);
10914  }
10915
10916  return startStyles || endStyles ? new SpecialCasedStyles(element, startStyles, endStyles) : null;
10917}
10918/**
10919 * Designed to be executed during a keyframe-based animation to apply any special-cased styles.
10920 *
10921 * When started (when the `start()` method is run) then the provided `startStyles`
10922 * will be applied. When finished (when the `finish()` method is called) the
10923 * `endStyles` will be applied as well any any starting styles. Finally when
10924 * `destroy()` is called then all styles will be removed.
10925 */
10926
10927
10928class SpecialCasedStyles {
10929  constructor(_element, _startStyles, _endStyles) {
10930    this._element = _element;
10931    this._startStyles = _startStyles;
10932    this._endStyles = _endStyles;
10933    this._state = 0
10934    /* SpecialCasedStylesState.Pending */
10935    ;
10936    let initialStyles = SpecialCasedStyles.initialStylesByElement.get(_element);
10937
10938    if (!initialStyles) {
10939      SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = new Map());
10940    }
10941
10942    this._initialStyles = initialStyles;
10943  }
10944
10945  start() {
10946    if (this._state < 1
10947    /* SpecialCasedStylesState.Started */
10948    ) {
10949      if (this._startStyles) {
10950        setStyles(this._element, this._startStyles, this._initialStyles);
10951      }
10952
10953      this._state = 1
10954      /* SpecialCasedStylesState.Started */
10955      ;
10956    }
10957  }
10958
10959  finish() {
10960    this.start();
10961
10962    if (this._state < 2
10963    /* SpecialCasedStylesState.Finished */
10964    ) {
10965      setStyles(this._element, this._initialStyles);
10966
10967      if (this._endStyles) {
10968        setStyles(this._element, this._endStyles);
10969        this._endStyles = null;
10970      }
10971
10972      this._state = 1
10973      /* SpecialCasedStylesState.Started */
10974      ;
10975    }
10976  }
10977
10978  destroy() {
10979    this.finish();
10980
10981    if (this._state < 3
10982    /* SpecialCasedStylesState.Destroyed */
10983    ) {
10984      SpecialCasedStyles.initialStylesByElement.delete(this._element);
10985
10986      if (this._startStyles) {
10987        eraseStyles(this._element, this._startStyles);
10988        this._endStyles = null;
10989      }
10990
10991      if (this._endStyles) {
10992        eraseStyles(this._element, this._endStyles);
10993        this._endStyles = null;
10994      }
10995
10996      setStyles(this._element, this._initialStyles);
10997      this._state = 3
10998      /* SpecialCasedStylesState.Destroyed */
10999      ;
11000    }
11001  }
11002
11003}
11004
11005SpecialCasedStyles.initialStylesByElement = /* @__PURE__ */new WeakMap();
11006
11007function filterNonAnimatableStyles(styles) {
11008  let result = null;
11009  styles.forEach((val, prop) => {
11010    if (isNonAnimatableStyle(prop)) {
11011      result = result || new Map();
11012      result.set(prop, val);
11013    }
11014  });
11015  return result;
11016}
11017
11018function isNonAnimatableStyle(prop) {
11019  return prop === 'display' || prop === 'position';
11020}
11021
11022class WebAnimationsPlayer {
11023  constructor(element, keyframes, options, _specialStyles) {
11024    this.element = element;
11025    this.keyframes = keyframes;
11026    this.options = options;
11027    this._specialStyles = _specialStyles;
11028    this._onDoneFns = [];
11029    this._onStartFns = [];
11030    this._onDestroyFns = [];
11031    this._initialized = false;
11032    this._finished = false;
11033    this._started = false;
11034    this._destroyed = false; // the following original fns are persistent copies of the _onStartFns and _onDoneFns
11035    // and are used to reset the fns to their original values upon reset()
11036    // (since the _onStartFns and _onDoneFns get deleted after they are called)
11037
11038    this._originalOnDoneFns = [];
11039    this._originalOnStartFns = [];
11040    this.time = 0;
11041    this.parentPlayer = null;
11042    this.currentSnapshot = new Map();
11043    this._duration = options['duration'];
11044    this._delay = options['delay'] || 0;
11045    this.time = this._duration + this._delay;
11046  }
11047
11048  _onFinish() {
11049    if (!this._finished) {
11050      this._finished = true;
11051
11052      this._onDoneFns.forEach(fn => fn());
11053
11054      this._onDoneFns = [];
11055    }
11056  }
11057
11058  init() {
11059    this._buildPlayer();
11060
11061    this._preparePlayerBeforeStart();
11062  }
11063
11064  _buildPlayer() {
11065    if (this._initialized) return;
11066    this._initialized = true;
11067    const keyframes = this.keyframes;
11068    this.domPlayer = this._triggerWebAnimation(this.element, keyframes, this.options);
11069    this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : new Map();
11070    this.domPlayer.addEventListener('finish', () => this._onFinish());
11071  }
11072
11073  _preparePlayerBeforeStart() {
11074    // this is required so that the player doesn't start to animate right away
11075    if (this._delay) {
11076      this._resetDomPlayerState();
11077    } else {
11078      this.domPlayer.pause();
11079    }
11080  }
11081
11082  _convertKeyframesToObject(keyframes) {
11083    const kfs = [];
11084    keyframes.forEach(frame => {
11085      kfs.push(Object.fromEntries(frame));
11086    });
11087    return kfs;
11088  }
11089  /** @internal */
11090
11091
11092  _triggerWebAnimation(element, keyframes, options) {
11093    // jscompiler doesn't seem to know animate is a native property because it's not fully
11094    // supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]
11095    return element['animate'](this._convertKeyframesToObject(keyframes), options);
11096  }
11097
11098  onStart(fn) {
11099    this._originalOnStartFns.push(fn);
11100
11101    this._onStartFns.push(fn);
11102  }
11103
11104  onDone(fn) {
11105    this._originalOnDoneFns.push(fn);
11106
11107    this._onDoneFns.push(fn);
11108  }
11109
11110  onDestroy(fn) {
11111    this._onDestroyFns.push(fn);
11112  }
11113
11114  play() {
11115    this._buildPlayer();
11116
11117    if (!this.hasStarted()) {
11118      this._onStartFns.forEach(fn => fn());
11119
11120      this._onStartFns = [];
11121      this._started = true;
11122
11123      if (this._specialStyles) {
11124        this._specialStyles.start();
11125      }
11126    }
11127
11128    this.domPlayer.play();
11129  }
11130
11131  pause() {
11132    this.init();
11133    this.domPlayer.pause();
11134  }
11135
11136  finish() {
11137    this.init();
11138
11139    if (this._specialStyles) {
11140      this._specialStyles.finish();
11141    }
11142
11143    this._onFinish();
11144
11145    this.domPlayer.finish();
11146  }
11147
11148  reset() {
11149    this._resetDomPlayerState();
11150
11151    this._destroyed = false;
11152    this._finished = false;
11153    this._started = false;
11154    this._onStartFns = this._originalOnStartFns;
11155    this._onDoneFns = this._originalOnDoneFns;
11156  }
11157
11158  _resetDomPlayerState() {
11159    if (this.domPlayer) {
11160      this.domPlayer.cancel();
11161    }
11162  }
11163
11164  restart() {
11165    this.reset();
11166    this.play();
11167  }
11168
11169  hasStarted() {
11170    return this._started;
11171  }
11172
11173  destroy() {
11174    if (!this._destroyed) {
11175      this._destroyed = true;
11176
11177      this._resetDomPlayerState();
11178
11179      this._onFinish();
11180
11181      if (this._specialStyles) {
11182        this._specialStyles.destroy();
11183      }
11184
11185      this._onDestroyFns.forEach(fn => fn());
11186
11187      this._onDestroyFns = [];
11188    }
11189  }
11190
11191  setPosition(p) {
11192    if (this.domPlayer === undefined) {
11193      this.init();
11194    }
11195
11196    this.domPlayer.currentTime = p * this.time;
11197  }
11198
11199  getPosition() {
11200    return this.domPlayer.currentTime / this.time;
11201  }
11202
11203  get totalTime() {
11204    return this._delay + this._duration;
11205  }
11206
11207  beforeDestroy() {
11208    const styles = new Map();
11209
11210    if (this.hasStarted()) {
11211      // note: this code is invoked only when the `play` function was called prior to this
11212      // (thus `hasStarted` returns true), this implies that the code that initializes
11213      // `_finalKeyframe` has also been executed and the non-null assertion can be safely used here
11214      const finalKeyframe = this._finalKeyframe;
11215      finalKeyframe.forEach((val, prop) => {
11216        if (prop !== 'offset') {
11217          styles.set(prop, this._finished ? val : computeStyle(this.element, prop));
11218        }
11219      });
11220    }
11221
11222    this.currentSnapshot = styles;
11223  }
11224  /** @internal */
11225
11226
11227  triggerCallback(phaseName) {
11228    const methods = phaseName === 'start' ? this._onStartFns : this._onDoneFns;
11229    methods.forEach(fn => fn());
11230    methods.length = 0;
11231  }
11232
11233}
11234
11235class WebAnimationsDriver {
11236  validateStyleProperty(prop) {
11237    // Perform actual validation in dev mode only, in prod mode this check is a noop.
11238    if (typeof ngDevMode === 'undefined' || ngDevMode) {
11239      return validateStyleProperty(prop);
11240    }
11241
11242    return true;
11243  }
11244
11245  validateAnimatableStyleProperty(prop) {
11246    // Perform actual validation in dev mode only, in prod mode this check is a noop.
11247    if (typeof ngDevMode === 'undefined' || ngDevMode) {
11248      const cssProp = camelCaseToDashCase(prop);
11249      return validateWebAnimatableStyleProperty(cssProp);
11250    }
11251
11252    return true;
11253  }
11254
11255  matchesElement(_element, _selector) {
11256    // This method is deprecated and no longer in use so we return false.
11257    return false;
11258  }
11259
11260  containsElement(elm1, elm2) {
11261    return containsElement(elm1, elm2);
11262  }
11263
11264  getParentElement(element) {
11265    return getParentElement(element);
11266  }
11267
11268  query(element, selector, multi) {
11269    return invokeQuery(element, selector, multi);
11270  }
11271
11272  computeStyle(element, prop, defaultValue) {
11273    return window.getComputedStyle(element)[prop];
11274  }
11275
11276  animate(element, keyframes, duration, delay, easing, previousPlayers = []) {
11277    const fill = delay == 0 ? 'both' : 'forwards';
11278    const playerOptions = {
11279      duration,
11280      delay,
11281      fill
11282    }; // we check for this to avoid having a null|undefined value be present
11283    // for the easing (which results in an error for certain browsers #9752)
11284
11285    if (easing) {
11286      playerOptions['easing'] = easing;
11287    }
11288
11289    const previousStyles = new Map();
11290    const previousWebAnimationPlayers = previousPlayers.filter(player => player instanceof WebAnimationsPlayer);
11291
11292    if (allowPreviousPlayerStylesMerge(duration, delay)) {
11293      previousWebAnimationPlayers.forEach(player => {
11294        player.currentSnapshot.forEach((val, prop) => previousStyles.set(prop, val));
11295      });
11296    }
11297
11298    let _keyframes = normalizeKeyframes(keyframes).map(styles => copyStyles(styles));
11299
11300    _keyframes = balancePreviousStylesIntoKeyframes(element, _keyframes, previousStyles);
11301    const specialStyles = packageNonAnimatableStyles(element, _keyframes);
11302    return new WebAnimationsPlayer(element, _keyframes, playerOptions, specialStyles);
11303  }
11304
11305}
11306/**
11307 * @license
11308 * Copyright Google LLC All Rights Reserved.
11309 *
11310 * Use of this source code is governed by an MIT-style license that can be
11311 * found in the LICENSE file at https://angular.io/license
11312 */
11313
11314/**
11315 * @license
11316 * Copyright Google LLC All Rights Reserved.
11317 *
11318 * Use of this source code is governed by an MIT-style license that can be
11319 * found in the LICENSE file at https://angular.io/license
11320 */
11321
11322/**
11323 * @license
11324 * Copyright Google LLC All Rights Reserved.
11325 *
11326 * Use of this source code is governed by an MIT-style license that can be
11327 * found in the LICENSE file at https://angular.io/license
11328 */
11329
11330/**
11331 * @license
11332 * Copyright Google LLC All Rights Reserved.
11333 *
11334 * Use of this source code is governed by an MIT-style license that can be
11335 * found in the LICENSE file at https://angular.io/license
11336 */
11337
11338/**
11339 * Generated bundle index. Do not edit.
11340 */
11341
11342
11343
11344
11345/***/ }),
11346
11347/***/ 4666:
11348/*!**********************************************************!*\
11349  !*** ./node_modules/@angular/common/fesm2020/common.mjs ***!
11350  \**********************************************************/
11351/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
11352
11353__webpack_require__.r(__webpack_exports__);
11354/* harmony export */ __webpack_require__.d(__webpack_exports__, {
11355/* harmony export */   "APP_BASE_HREF": () => (/* binding */ APP_BASE_HREF),
11356/* harmony export */   "AsyncPipe": () => (/* binding */ AsyncPipe),
11357/* harmony export */   "CommonModule": () => (/* binding */ CommonModule),
11358/* harmony export */   "CurrencyPipe": () => (/* binding */ CurrencyPipe),
11359/* harmony export */   "DATE_PIPE_DEFAULT_TIMEZONE": () => (/* binding */ DATE_PIPE_DEFAULT_TIMEZONE),
11360/* harmony export */   "DOCUMENT": () => (/* binding */ DOCUMENT),
11361/* harmony export */   "DatePipe": () => (/* binding */ DatePipe),
11362/* harmony export */   "DecimalPipe": () => (/* binding */ DecimalPipe),
11363/* harmony export */   "FormStyle": () => (/* binding */ FormStyle),
11364/* harmony export */   "FormatWidth": () => (/* binding */ FormatWidth),
11365/* harmony export */   "HashLocationStrategy": () => (/* binding */ HashLocationStrategy),
11366/* harmony export */   "I18nPluralPipe": () => (/* binding */ I18nPluralPipe),
11367/* harmony export */   "I18nSelectPipe": () => (/* binding */ I18nSelectPipe),
11368/* harmony export */   "IMAGE_LOADER": () => (/* binding */ IMAGE_LOADER),
11369/* harmony export */   "JsonPipe": () => (/* binding */ JsonPipe),
11370/* harmony export */   "KeyValuePipe": () => (/* binding */ KeyValuePipe),
11371/* harmony export */   "LOCATION_INITIALIZED": () => (/* binding */ LOCATION_INITIALIZED),
11372/* harmony export */   "Location": () => (/* binding */ Location),
11373/* harmony export */   "LocationStrategy": () => (/* binding */ LocationStrategy),
11374/* harmony export */   "LowerCasePipe": () => (/* binding */ LowerCasePipe),
11375/* harmony export */   "NgClass": () => (/* binding */ NgClass),
11376/* harmony export */   "NgComponentOutlet": () => (/* binding */ NgComponentOutlet),
11377/* harmony export */   "NgFor": () => (/* binding */ NgForOf),
11378/* harmony export */   "NgForOf": () => (/* binding */ NgForOf),
11379/* harmony export */   "NgForOfContext": () => (/* binding */ NgForOfContext),
11380/* harmony export */   "NgIf": () => (/* binding */ NgIf),
11381/* harmony export */   "NgIfContext": () => (/* binding */ NgIfContext),
11382/* harmony export */   "NgLocaleLocalization": () => (/* binding */ NgLocaleLocalization),
11383/* harmony export */   "NgLocalization": () => (/* binding */ NgLocalization),
11384/* harmony export */   "NgOptimizedImage": () => (/* binding */ NgOptimizedImage),
11385/* harmony export */   "NgPlural": () => (/* binding */ NgPlural),
11386/* harmony export */   "NgPluralCase": () => (/* binding */ NgPluralCase),
11387/* harmony export */   "NgStyle": () => (/* binding */ NgStyle),
11388/* harmony export */   "NgSwitch": () => (/* binding */ NgSwitch),
11389/* harmony export */   "NgSwitchCase": () => (/* binding */ NgSwitchCase),
11390/* harmony export */   "NgSwitchDefault": () => (/* binding */ NgSwitchDefault),
11391/* harmony export */   "NgTemplateOutlet": () => (/* binding */ NgTemplateOutlet),
11392/* harmony export */   "NumberFormatStyle": () => (/* binding */ NumberFormatStyle),
11393/* harmony export */   "NumberSymbol": () => (/* binding */ NumberSymbol),
11394/* harmony export */   "PRECONNECT_CHECK_BLOCKLIST": () => (/* binding */ PRECONNECT_CHECK_BLOCKLIST),
11395/* harmony export */   "PathLocationStrategy": () => (/* binding */ PathLocationStrategy),
11396/* harmony export */   "PercentPipe": () => (/* binding */ PercentPipe),
11397/* harmony export */   "PlatformLocation": () => (/* binding */ PlatformLocation),
11398/* harmony export */   "Plural": () => (/* binding */ Plural),
11399/* harmony export */   "SlicePipe": () => (/* binding */ SlicePipe),
11400/* harmony export */   "TitleCasePipe": () => (/* binding */ TitleCasePipe),
11401/* harmony export */   "TranslationWidth": () => (/* binding */ TranslationWidth),
11402/* harmony export */   "UpperCasePipe": () => (/* binding */ UpperCasePipe),
11403/* harmony export */   "VERSION": () => (/* binding */ VERSION),
11404/* harmony export */   "ViewportScroller": () => (/* binding */ ViewportScroller),
11405/* harmony export */   "WeekDay": () => (/* binding */ WeekDay),
11406/* harmony export */   "XhrFactory": () => (/* binding */ XhrFactory),
11407/* harmony export */   "formatCurrency": () => (/* binding */ formatCurrency),
11408/* harmony export */   "formatDate": () => (/* binding */ formatDate),
11409/* harmony export */   "formatNumber": () => (/* binding */ formatNumber),
11410/* harmony export */   "formatPercent": () => (/* binding */ formatPercent),
11411/* harmony export */   "getCurrencySymbol": () => (/* binding */ getCurrencySymbol),
11412/* harmony export */   "getLocaleCurrencyCode": () => (/* binding */ getLocaleCurrencyCode),
11413/* harmony export */   "getLocaleCurrencyName": () => (/* binding */ getLocaleCurrencyName),
11414/* harmony export */   "getLocaleCurrencySymbol": () => (/* binding */ getLocaleCurrencySymbol),
11415/* harmony export */   "getLocaleDateFormat": () => (/* binding */ getLocaleDateFormat),
11416/* harmony export */   "getLocaleDateTimeFormat": () => (/* binding */ getLocaleDateTimeFormat),
11417/* harmony export */   "getLocaleDayNames": () => (/* binding */ getLocaleDayNames),
11418/* harmony export */   "getLocaleDayPeriods": () => (/* binding */ getLocaleDayPeriods),
11419/* harmony export */   "getLocaleDirection": () => (/* binding */ getLocaleDirection),
11420/* harmony export */   "getLocaleEraNames": () => (/* binding */ getLocaleEraNames),
11421/* harmony export */   "getLocaleExtraDayPeriodRules": () => (/* binding */ getLocaleExtraDayPeriodRules),
11422/* harmony export */   "getLocaleExtraDayPeriods": () => (/* binding */ getLocaleExtraDayPeriods),
11423/* harmony export */   "getLocaleFirstDayOfWeek": () => (/* binding */ getLocaleFirstDayOfWeek),
11424/* harmony export */   "getLocaleId": () => (/* binding */ getLocaleId),
11425/* harmony export */   "getLocaleMonthNames": () => (/* binding */ getLocaleMonthNames),
11426/* harmony export */   "getLocaleNumberFormat": () => (/* binding */ getLocaleNumberFormat),
11427/* harmony export */   "getLocaleNumberSymbol": () => (/* binding */ getLocaleNumberSymbol),
11428/* harmony export */   "getLocalePluralCase": () => (/* binding */ getLocalePluralCase),
11429/* harmony export */   "getLocaleTimeFormat": () => (/* binding */ getLocaleTimeFormat),
11430/* harmony export */   "getLocaleWeekEndRange": () => (/* binding */ getLocaleWeekEndRange),
11431/* harmony export */   "getNumberOfCurrencyDigits": () => (/* binding */ getNumberOfCurrencyDigits),
11432/* harmony export */   "isPlatformBrowser": () => (/* binding */ isPlatformBrowser),
11433/* harmony export */   "isPlatformServer": () => (/* binding */ isPlatformServer),
11434/* harmony export */   "isPlatformWorkerApp": () => (/* binding */ isPlatformWorkerApp),
11435/* harmony export */   "isPlatformWorkerUi": () => (/* binding */ isPlatformWorkerUi),
11436/* harmony export */   "provideCloudflareLoader": () => (/* binding */ provideCloudflareLoader),
11437/* harmony export */   "provideCloudinaryLoader": () => (/* binding */ provideCloudinaryLoader),
11438/* harmony export */   "provideImageKitLoader": () => (/* binding */ provideImageKitLoader),
11439/* harmony export */   "provideImgixLoader": () => (/* binding */ provideImgixLoader),
11440/* harmony export */   "registerLocaleData": () => (/* binding */ registerLocaleData),
11441/* harmony export */   "ɵBrowserPlatformLocation": () => (/* binding */ BrowserPlatformLocation),
11442/* harmony export */   "ɵDomAdapter": () => (/* binding */ DomAdapter),
11443/* harmony export */   "ɵNullViewportScroller": () => (/* binding */ NullViewportScroller),
11444/* harmony export */   "ɵPLATFORM_BROWSER_ID": () => (/* binding */ PLATFORM_BROWSER_ID),
11445/* harmony export */   "ɵPLATFORM_SERVER_ID": () => (/* binding */ PLATFORM_SERVER_ID),
11446/* harmony export */   "ɵPLATFORM_WORKER_APP_ID": () => (/* binding */ PLATFORM_WORKER_APP_ID),
11447/* harmony export */   "ɵPLATFORM_WORKER_UI_ID": () => (/* binding */ PLATFORM_WORKER_UI_ID),
11448/* harmony export */   "ɵgetDOM": () => (/* binding */ getDOM),
11449/* harmony export */   "ɵparseCookieValue": () => (/* binding */ parseCookieValue),
11450/* harmony export */   "ɵsetRootDomAdapter": () => (/* binding */ setRootDomAdapter)
11451/* harmony export */ });
11452/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 2560);
11453/**
11454 * @license Angular v14.2.10
11455 * (c) 2010-2022 Google LLC. https://angular.io/
11456 * License: MIT
11457 */
11458
11459
11460/**
11461 * @license
11462 * Copyright Google LLC All Rights Reserved.
11463 *
11464 * Use of this source code is governed by an MIT-style license that can be
11465 * found in the LICENSE file at https://angular.io/license
11466 */
11467
11468let _DOM = null;
11469
11470function getDOM() {
11471  return _DOM;
11472}
11473
11474function setDOM(adapter) {
11475  _DOM = adapter;
11476}
11477
11478function setRootDomAdapter(adapter) {
11479  if (!_DOM) {
11480    _DOM = adapter;
11481  }
11482}
11483/* tslint:disable:requireParameterType */
11484
11485/**
11486 * Provides DOM operations in an environment-agnostic way.
11487 *
11488 * @security Tread carefully! Interacting with the DOM directly is dangerous and
11489 * can introduce XSS risks.
11490 */
11491
11492
11493class DomAdapter {}
11494/**
11495 * @license
11496 * Copyright Google LLC All Rights Reserved.
11497 *
11498 * Use of this source code is governed by an MIT-style license that can be
11499 * found in the LICENSE file at https://angular.io/license
11500 */
11501
11502/**
11503 * A DI Token representing the main rendering context. In a browser this is the DOM Document.
11504 *
11505 * Note: Document might not be available in the Application Context when Application and Rendering
11506 * Contexts are not the same (e.g. when running the application in a Web Worker).
11507 *
11508 * @publicApi
11509 */
11510
11511
11512const DOCUMENT = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('DocumentToken');
11513/**
11514 * @license
11515 * Copyright Google LLC All Rights Reserved.
11516 *
11517 * Use of this source code is governed by an MIT-style license that can be
11518 * found in the LICENSE file at https://angular.io/license
11519 */
11520
11521/**
11522 * This class should not be used directly by an application developer. Instead, use
11523 * {@link Location}.
11524 *
11525 * `PlatformLocation` encapsulates all calls to DOM APIs, which allows the Router to be
11526 * platform-agnostic.
11527 * This means that we can have different implementation of `PlatformLocation` for the different
11528 * platforms that Angular supports. For example, `@angular/platform-browser` provides an
11529 * implementation specific to the browser environment, while `@angular/platform-server` provides
11530 * one suitable for use with server-side rendering.
11531 *
11532 * The `PlatformLocation` class is used directly by all implementations of {@link LocationStrategy}
11533 * when they need to interact with the DOM APIs like pushState, popState, etc.
11534 *
11535 * {@link LocationStrategy} in turn is used by the {@link Location} service which is used directly
11536 * by the {@link Router} in order to navigate between routes. Since all interactions between {@link
11537 * Router} /
11538 * {@link Location} / {@link LocationStrategy} and DOM APIs flow through the `PlatformLocation`
11539 * class, they are all platform-agnostic.
11540 *
11541 * @publicApi
11542 */
11543
11544class PlatformLocation {
11545  historyGo(relativePosition) {
11546    throw new Error('Not implemented');
11547  }
11548
11549}
11550
11551PlatformLocation.ɵfac = function PlatformLocation_Factory(t) {
11552  return new (t || PlatformLocation)();
11553};
11554
11555PlatformLocation.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
11556  token: PlatformLocation,
11557  factory: function () {
11558    return useBrowserPlatformLocation();
11559  },
11560  providedIn: 'platform'
11561});
11562
11563(function () {
11564  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PlatformLocation, [{
11565    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
11566    args: [{
11567      providedIn: 'platform',
11568      // See #23917
11569      useFactory: useBrowserPlatformLocation
11570    }]
11571  }], null, null);
11572})();
11573
11574function useBrowserPlatformLocation() {
11575  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"])(BrowserPlatformLocation);
11576}
11577/**
11578 * @description
11579 * Indicates when a location is initialized.
11580 *
11581 * @publicApi
11582 */
11583
11584
11585const LOCATION_INITIALIZED = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('Location Initialized');
11586/**
11587 * `PlatformLocation` encapsulates all of the direct calls to platform APIs.
11588 * This class should not be used directly by an application developer. Instead, use
11589 * {@link Location}.
11590 */
11591
11592class BrowserPlatformLocation extends PlatformLocation {
11593  constructor(_doc) {
11594    super();
11595    this._doc = _doc;
11596
11597    this._init();
11598  } // This is moved to its own method so that `MockPlatformLocationStrategy` can overwrite it
11599
11600  /** @internal */
11601
11602
11603  _init() {
11604    this.location = window.location;
11605    this._history = window.history;
11606  }
11607
11608  getBaseHrefFromDOM() {
11609    return getDOM().getBaseHref(this._doc);
11610  }
11611
11612  onPopState(fn) {
11613    const window = getDOM().getGlobalEventTarget(this._doc, 'window');
11614    window.addEventListener('popstate', fn, false);
11615    return () => window.removeEventListener('popstate', fn);
11616  }
11617
11618  onHashChange(fn) {
11619    const window = getDOM().getGlobalEventTarget(this._doc, 'window');
11620    window.addEventListener('hashchange', fn, false);
11621    return () => window.removeEventListener('hashchange', fn);
11622  }
11623
11624  get href() {
11625    return this.location.href;
11626  }
11627
11628  get protocol() {
11629    return this.location.protocol;
11630  }
11631
11632  get hostname() {
11633    return this.location.hostname;
11634  }
11635
11636  get port() {
11637    return this.location.port;
11638  }
11639
11640  get pathname() {
11641    return this.location.pathname;
11642  }
11643
11644  get search() {
11645    return this.location.search;
11646  }
11647
11648  get hash() {
11649    return this.location.hash;
11650  }
11651
11652  set pathname(newPath) {
11653    this.location.pathname = newPath;
11654  }
11655
11656  pushState(state, title, url) {
11657    if (supportsState()) {
11658      this._history.pushState(state, title, url);
11659    } else {
11660      this.location.hash = url;
11661    }
11662  }
11663
11664  replaceState(state, title, url) {
11665    if (supportsState()) {
11666      this._history.replaceState(state, title, url);
11667    } else {
11668      this.location.hash = url;
11669    }
11670  }
11671
11672  forward() {
11673    this._history.forward();
11674  }
11675
11676  back() {
11677    this._history.back();
11678  }
11679
11680  historyGo(relativePosition = 0) {
11681    this._history.go(relativePosition);
11682  }
11683
11684  getState() {
11685    return this._history.state;
11686  }
11687
11688}
11689
11690BrowserPlatformLocation.ɵfac = function BrowserPlatformLocation_Factory(t) {
11691  return new (t || BrowserPlatformLocation)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](DOCUMENT));
11692};
11693
11694BrowserPlatformLocation.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
11695  token: BrowserPlatformLocation,
11696  factory: function () {
11697    return createBrowserPlatformLocation();
11698  },
11699  providedIn: 'platform'
11700});
11701
11702(function () {
11703  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BrowserPlatformLocation, [{
11704    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
11705    args: [{
11706      providedIn: 'platform',
11707      // See #23917
11708      useFactory: createBrowserPlatformLocation
11709    }]
11710  }], function () {
11711    return [{
11712      type: undefined,
11713      decorators: [{
11714        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
11715        args: [DOCUMENT]
11716      }]
11717    }];
11718  }, null);
11719})();
11720
11721function supportsState() {
11722  return !!window.history.pushState;
11723}
11724
11725function createBrowserPlatformLocation() {
11726  return new BrowserPlatformLocation((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"])(DOCUMENT));
11727}
11728/**
11729 * @license
11730 * Copyright Google LLC All Rights Reserved.
11731 *
11732 * Use of this source code is governed by an MIT-style license that can be
11733 * found in the LICENSE file at https://angular.io/license
11734 */
11735
11736/**
11737 * @license
11738 * Copyright Google LLC All Rights Reserved.
11739 *
11740 * Use of this source code is governed by an MIT-style license that can be
11741 * found in the LICENSE file at https://angular.io/license
11742 */
11743
11744/**
11745 * Joins two parts of a URL with a slash if needed.
11746 *
11747 * @param start  URL string
11748 * @param end    URL string
11749 *
11750 *
11751 * @returns The joined URL string.
11752 */
11753
11754
11755function joinWithSlash(start, end) {
11756  if (start.length == 0) {
11757    return end;
11758  }
11759
11760  if (end.length == 0) {
11761    return start;
11762  }
11763
11764  let slashes = 0;
11765
11766  if (start.endsWith('/')) {
11767    slashes++;
11768  }
11769
11770  if (end.startsWith('/')) {
11771    slashes++;
11772  }
11773
11774  if (slashes == 2) {
11775    return start + end.substring(1);
11776  }
11777
11778  if (slashes == 1) {
11779    return start + end;
11780  }
11781
11782  return start + '/' + end;
11783}
11784/**
11785 * Removes a trailing slash from a URL string if needed.
11786 * Looks for the first occurrence of either `#`, `?`, or the end of the
11787 * line as `/` characters and removes the trailing slash if one exists.
11788 *
11789 * @param url URL string.
11790 *
11791 * @returns The URL string, modified if needed.
11792 */
11793
11794
11795function stripTrailingSlash(url) {
11796  const match = url.match(/#|\?|$/);
11797  const pathEndIdx = match && match.index || url.length;
11798  const droppedSlashIdx = pathEndIdx - (url[pathEndIdx - 1] === '/' ? 1 : 0);
11799  return url.slice(0, droppedSlashIdx) + url.slice(pathEndIdx);
11800}
11801/**
11802 * Normalizes URL parameters by prepending with `?` if needed.
11803 *
11804 * @param  params String of URL parameters.
11805 *
11806 * @returns The normalized URL parameters string.
11807 */
11808
11809
11810function normalizeQueryParams(params) {
11811  return params && params[0] !== '?' ? '?' + params : params;
11812}
11813/**
11814 * @license
11815 * Copyright Google LLC All Rights Reserved.
11816 *
11817 * Use of this source code is governed by an MIT-style license that can be
11818 * found in the LICENSE file at https://angular.io/license
11819 */
11820
11821/**
11822 * Enables the `Location` service to read route state from the browser's URL.
11823 * Angular provides two strategies:
11824 * `HashLocationStrategy` and `PathLocationStrategy`.
11825 *
11826 * Applications should use the `Router` or `Location` services to
11827 * interact with application route state.
11828 *
11829 * For instance, `HashLocationStrategy` produces URLs like
11830 * <code class="no-auto-link">http://example.com#/foo</code>,
11831 * and `PathLocationStrategy` produces
11832 * <code class="no-auto-link">http://example.com/foo</code> as an equivalent URL.
11833 *
11834 * See these two classes for more.
11835 *
11836 * @publicApi
11837 */
11838
11839
11840class LocationStrategy {
11841  historyGo(relativePosition) {
11842    throw new Error('Not implemented');
11843  }
11844
11845}
11846
11847LocationStrategy.ɵfac = function LocationStrategy_Factory(t) {
11848  return new (t || LocationStrategy)();
11849};
11850
11851LocationStrategy.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
11852  token: LocationStrategy,
11853  factory: function () {
11854    return (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(PathLocationStrategy))();
11855  },
11856  providedIn: 'root'
11857});
11858
11859(function () {
11860  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LocationStrategy, [{
11861    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
11862    args: [{
11863      providedIn: 'root',
11864      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(PathLocationStrategy)
11865    }]
11866  }], null, null);
11867})();
11868/**
11869 * A predefined [DI token](guide/glossary#di-token) for the base href
11870 * to be used with the `PathLocationStrategy`.
11871 * The base href is the URL prefix that should be preserved when generating
11872 * and recognizing URLs.
11873 *
11874 * @usageNotes
11875 *
11876 * The following example shows how to use this token to configure the root app injector
11877 * with a base href value, so that the DI framework can supply the dependency anywhere in the app.
11878 *
11879 * ```typescript
11880 * import {Component, NgModule} from '@angular/core';
11881 * import {APP_BASE_HREF} from '@angular/common';
11882 *
11883 * @NgModule({
11884 *   providers: [{provide: APP_BASE_HREF, useValue: '/my/app'}]
11885 * })
11886 * class AppModule {}
11887 * ```
11888 *
11889 * @publicApi
11890 */
11891
11892
11893const APP_BASE_HREF = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('appBaseHref');
11894/**
11895 * @description
11896 * A {@link LocationStrategy} used to configure the {@link Location} service to
11897 * represent its state in the
11898 * [path](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax) of the
11899 * browser's URL.
11900 *
11901 * If you're using `PathLocationStrategy`, you may provide a {@link APP_BASE_HREF}
11902 * or add a `<base href>` element to the document to override the default.
11903 *
11904 * For instance, if you provide an `APP_BASE_HREF` of `'/my/app/'` and call
11905 * `location.go('/foo')`, the browser's URL will become
11906 * `example.com/my/app/foo`. To ensure all relative URIs resolve correctly,
11907 * the `<base href>` and/or `APP_BASE_HREF` should end with a `/`.
11908 *
11909 * Similarly, if you add `<base href='/my/app/'/>` to the document and call
11910 * `location.go('/foo')`, the browser's URL will become
11911 * `example.com/my/app/foo`.
11912 *
11913 * Note that when using `PathLocationStrategy`, neither the query nor
11914 * the fragment in the `<base href>` will be preserved, as outlined
11915 * by the [RFC](https://tools.ietf.org/html/rfc3986#section-5.2.2).
11916 *
11917 * @usageNotes
11918 *
11919 * ### Example
11920 *
11921 * {@example common/location/ts/path_location_component.ts region='LocationComponent'}
11922 *
11923 * @publicApi
11924 */
11925
11926class PathLocationStrategy extends LocationStrategy {
11927  constructor(_platformLocation, href) {
11928    super();
11929    this._platformLocation = _platformLocation;
11930    this._removeListenerFns = [];
11931    this._baseHref = href ?? this._platformLocation.getBaseHrefFromDOM() ?? (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DOCUMENT).location?.origin ?? '';
11932  }
11933  /** @nodoc */
11934
11935
11936  ngOnDestroy() {
11937    while (this._removeListenerFns.length) {
11938      this._removeListenerFns.pop()();
11939    }
11940  }
11941
11942  onPopState(fn) {
11943    this._removeListenerFns.push(this._platformLocation.onPopState(fn), this._platformLocation.onHashChange(fn));
11944  }
11945
11946  getBaseHref() {
11947    return this._baseHref;
11948  }
11949
11950  prepareExternalUrl(internal) {
11951    return joinWithSlash(this._baseHref, internal);
11952  }
11953
11954  path(includeHash = false) {
11955    const pathname = this._platformLocation.pathname + normalizeQueryParams(this._platformLocation.search);
11956    const hash = this._platformLocation.hash;
11957    return hash && includeHash ? `${pathname}${hash}` : pathname;
11958  }
11959
11960  pushState(state, title, url, queryParams) {
11961    const externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams));
11962
11963    this._platformLocation.pushState(state, title, externalUrl);
11964  }
11965
11966  replaceState(state, title, url, queryParams) {
11967    const externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams));
11968
11969    this._platformLocation.replaceState(state, title, externalUrl);
11970  }
11971
11972  forward() {
11973    this._platformLocation.forward();
11974  }
11975
11976  back() {
11977    this._platformLocation.back();
11978  }
11979
11980  getState() {
11981    return this._platformLocation.getState();
11982  }
11983
11984  historyGo(relativePosition = 0) {
11985    this._platformLocation.historyGo?.(relativePosition);
11986  }
11987
11988}
11989
11990PathLocationStrategy.ɵfac = function PathLocationStrategy_Factory(t) {
11991  return new (t || PathLocationStrategy)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](PlatformLocation), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](APP_BASE_HREF, 8));
11992};
11993
11994PathLocationStrategy.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
11995  token: PathLocationStrategy,
11996  factory: PathLocationStrategy.ɵfac,
11997  providedIn: 'root'
11998});
11999
12000(function () {
12001  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PathLocationStrategy, [{
12002    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
12003    args: [{
12004      providedIn: 'root'
12005    }]
12006  }], function () {
12007    return [{
12008      type: PlatformLocation
12009    }, {
12010      type: undefined,
12011      decorators: [{
12012        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
12013      }, {
12014        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
12015        args: [APP_BASE_HREF]
12016      }]
12017    }];
12018  }, null);
12019})();
12020/**
12021 * @license
12022 * Copyright Google LLC All Rights Reserved.
12023 *
12024 * Use of this source code is governed by an MIT-style license that can be
12025 * found in the LICENSE file at https://angular.io/license
12026 */
12027
12028/**
12029 * @description
12030 * A {@link LocationStrategy} used to configure the {@link Location} service to
12031 * represent its state in the
12032 * [hash fragment](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax)
12033 * of the browser's URL.
12034 *
12035 * For instance, if you call `location.go('/foo')`, the browser's URL will become
12036 * `example.com#/foo`.
12037 *
12038 * @usageNotes
12039 *
12040 * ### Example
12041 *
12042 * {@example common/location/ts/hash_location_component.ts region='LocationComponent'}
12043 *
12044 * @publicApi
12045 */
12046
12047
12048class HashLocationStrategy extends LocationStrategy {
12049  constructor(_platformLocation, _baseHref) {
12050    super();
12051    this._platformLocation = _platformLocation;
12052    this._baseHref = '';
12053    this._removeListenerFns = [];
12054
12055    if (_baseHref != null) {
12056      this._baseHref = _baseHref;
12057    }
12058  }
12059  /** @nodoc */
12060
12061
12062  ngOnDestroy() {
12063    while (this._removeListenerFns.length) {
12064      this._removeListenerFns.pop()();
12065    }
12066  }
12067
12068  onPopState(fn) {
12069    this._removeListenerFns.push(this._platformLocation.onPopState(fn), this._platformLocation.on
12069HashChange(fn));
12070  }
12071
12072  getBaseHref() {
12073    return this._baseHref;
12074  }
12075
12076  path(includeHash = false) {
12077    // the hash value is always prefixed with a `#`
12078    // and if it is empty then it will stay empty
12079    let path = this._platformLocation.hash;
12080    if (path == null) path = '#';
12081    return path.length > 0 ? path.substring(1) : path;
12082  }
12083
12084  prepareExternalUrl(internal) {
12085    const url = joinWithSlash(this._baseHref, internal);
12086    return url.length > 0 ? '#' + url : url;
12087  }
12088
12089  pushState(state, title, path, queryParams) {
12090    let url = this.prepareExternalUrl(path + normalizeQueryParams(queryParams));
12091
12092    if (url.length == 0) {
12093      url = this._platformLocation.pathname;
12094    }
12095
12096    this._platformLocation.pushState(state, title, url);
12097  }
12098
12099  replaceState(state, title, path, queryParams) {
12100    let url = this.prepareExternalUrl(path + normalizeQueryParams(queryParams));
12101
12102    if (url.length == 0) {
12103      url = this._platformLocation.pathname;
12104    }
12105
12106    this._platformLocation.replaceState(state, title, url);
12107  }
12108
12109  forward() {
12110    this._platformLocation.forward();
12111  }
12112
12113  back() {
12114    this._platformLocation.back();
12115  }
12116
12117  getState() {
12118    return this._platformLocation.getState();
12119  }
12120
12121  historyGo(relativePosition = 0) {
12122    this._platformLocation.historyGo?.(relativePosition);
12123  }
12124
12125}
12126
12127HashLocationStrategy.ɵfac = function HashLocationStrategy_Factory(t) {
12128  return new (t || HashLocationStrategy)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](PlatformLocation), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](APP_BASE_HREF, 8));
12129};
12130
12131HashLocationStrategy.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
12132  token: HashLocationStrategy,
12133  factory: HashLocationStrategy.ɵfac
12134});
12135
12136(function () {
12137  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](HashLocationStrategy, [{
12138    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
12139  }], function () {
12140    return [{
12141      type: PlatformLocation
12142    }, {
12143      type: undefined,
12144      decorators: [{
12145        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
12146      }, {
12147        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
12148        args: [APP_BASE_HREF]
12149      }]
12150    }];
12151  }, null);
12152})();
12153/**
12154 * @license
12155 * Copyright Google LLC All Rights Reserved.
12156 *
12157 * Use of this source code is governed by an MIT-style license that can be
12158 * found in the LICENSE file at https://angular.io/license
12159 */
12160
12161/**
12162 * @description
12163 *
12164 * A service that applications can use to interact with a browser's URL.
12165 *
12166 * Depending on the `LocationStrategy` used, `Location` persists
12167 * to the URL's path or the URL's hash segment.
12168 *
12169 * @usageNotes
12170 *
12171 * It's better to use the `Router.navigate()` service to trigger route changes. Use
12172 * `Location` only if you need to interact with or create normalized URLs outside of
12173 * routing.
12174 *
12175 * `Location` is responsible for normalizing the URL against the application's base href.
12176 * A normalized URL is absolute from the URL host, includes the application's base href, and has no
12177 * trailing slash:
12178 * - `/my/app/user/123` is normalized
12179 * - `my/app/user/123` **is not** normalized
12180 * - `/my/app/user/123/` **is not** normalized
12181 *
12182 * ### Example
12183 *
12184 * <code-example path='common/location/ts/path_location_component.ts'
12185 * region='LocationComponent'></code-example>
12186 *
12187 * @publicApi
12188 */
12189
12190
12191class Location {
12192  constructor(locationStrategy) {
12193    /** @internal */
12194    this._subject = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
12195    /** @internal */
12196
12197    this._urlChangeListeners = [];
12198    /** @internal */
12199
12200    this._urlChangeSubscription = null;
12201    this._locationStrategy = locationStrategy;
12202
12203    const browserBaseHref = this._locationStrategy.getBaseHref();
12204
12205    this._baseHref = stripTrailingSlash(_stripIndexHtml(browserBaseHref));
12206
12207    this._locationStrategy.onPopState(ev => {
12208      this._subject.emit({
12209        'url': this.path(true),
12210        'pop': true,
12211        'state': ev.state,
12212        'type': ev.type
12213      });
12214    });
12215  }
12216  /** @nodoc */
12217
12218
12219  ngOnDestroy() {
12220    this._urlChangeSubscription?.unsubscribe();
12221    this._urlChangeListeners = [];
12222  }
12223  /**
12224   * Normalizes the URL path for this location.
12225   *
12226   * @param includeHash True to include an anchor fragment in the path.
vendor: 4,681 bytes, lines 12227-12388
12227   *
12228   * @returns The normalized URL path.
12229   */
12230  // TODO: vsavkin. Remove the boolean flag and always include hash once the deprecated router is
12231  // removed.
12232
12233
12234  path(includeHash = false) {
12235    return this.normalize(this._locationStrategy.path(includeHash));
12236  }
12237  /**
12238   * Reports the current state of the location history.
12239   * @returns The current value of the `history.state` object.
12240   */
12241
12242
12243  getState() {
12244    return this._locationStrategy.getState();
12245  }
12246  /**
12247   * Normalizes the given path and compares to the current normalized path.
12248   *
12249   * @param path The given URL path.
12250   * @param query Query parameters.
12251   *
12252   * @returns True if the given URL path is equal to the current normalized path, false
12253   * otherwise.
12254   */
12255
12256
12257  isCurrentPathEqualTo(path, query = '') {
12258    return this.path() == this.normalize(path + normalizeQueryParams(query));
12259  }
12260  /**
12261   * Normalizes a URL path by stripping any trailing slashes.
12262   *
12263   * @param url String representing a URL.
12264   *
12265   * @returns The normalized URL string.
12266   */
12267
12268
12269  normalize(url) {
12270    return Location.stripTrailingSlash(_stripBaseHref(this._baseHref, _stripIndexHtml(url)));
12271  }
12272  /**
12273   * Normalizes an external URL path.
12274   * If the given URL doesn't begin with a leading slash (`'/'`), adds one
12275   * before normalizing. Adds a hash if `HashLocationStrategy` is
12276   * in use, or the `APP_BASE_HREF` if the `PathLocationStrategy` is in use.
12277   *
12278   * @param url String representing a URL.
12279   *
12280   * @returns  A normalized platform-specific URL.
12281   */
12282
12283
12284  prepareExternalUrl(url) {
12285    if (url && url[0] !== '/') {
12286      url = '/' + url;
12287    }
12288
12289    return this._locationStrategy.prepareExternalUrl(url);
12290  } // TODO: rename this method to pushState
12291
12292  /**
12293   * Changes the browser's URL to a normalized version of a given URL, and pushes a
12294   * new item onto the platform's history.
12295   *
12296   * @param path  URL path to normalize.
12297   * @param query Query parameters.
12298   * @param state Location history state.
12299   *
12300   */
12301
12302
12303  go(path, query = '', state = null) {
12304    this._locationStrategy.pushState(state, '', path, query);
12305
12306    this._notifyUrlChangeListeners(this.prepareExternalUrl(path + normalizeQueryParams(query)), state);
12307  }
12308  /**
12309   * Changes the browser's URL to a normalized version of the given URL, and replaces
12310   * the top item on the platform's history stack.
12311   *
12312   * @param path  URL path to normalize.
12313   * @param query Query parameters.
12314   * @param state Location history state.
12315   */
12316
12317
12318  replaceState(path, query = '', state = null) {
12319    this._locationStrategy.replaceState(state, '', path, query);
12320
12321    this._notifyUrlChangeListeners(this.prepareExternalUrl(path + normalizeQueryParams(query)), state);
12322  }
12323  /**
12324   * Navigates forward in the platform's history.
12325   */
12326
12327
12328  forward() {
12329    this._locationStrategy.forward();
12330  }
12331  /**
12332   * Navigates back in the platform's history.
12333   */
12334
12335
12336  back() {
12337    this._locationStrategy.back();
12338  }
12339  /**
12340   * Navigate to a specific page from session history, identified by its relative position to the
12341   * current page.
12342   *
12343   * @param relativePosition  Position of the target page in the history relative to the current
12344   *     page.
12345   * A negative value moves backwards, a positive value moves forwards, e.g. `location.historyGo(2)`
12346   * moves forward two pages and `location.historyGo(-2)` moves back two pages. When we try to go
12347   * beyond what's stored in the history session, we stay in the current page. Same behaviour occurs
12348   * when `relativePosition` equals 0.
12349   * @see https://developer.mozilla.org/en-US/docs/Web/API/History_API#Moving_to_a_specific_point_in_history
12350   */
12351
12352
12353  historyGo(relativePosition = 0) {
12354    this._locationStrategy.historyGo?.(relativePosition);
12355  }
12356  /**
12357   * Registers a URL change listener. Use to catch updates performed by the Angular
12358   * framework that are not detectible through "popstate" or "hashchange" events.
12359   *
12360   * @param fn The change handler function, which take a URL and a location history state.
12361   * @returns A function that, when executed, unregisters a URL change listener.
12362   */
12363
12364
12365  onUrlChange(fn) {
12366    this._urlChangeListeners.push(fn);
12367
12368    if (!this._urlChangeSubscription) {
12369      this._urlChangeSubscription = this.subscribe(v => {
12370        this._notifyUrlChangeListeners(v.url, v.state);
12371      });
12372    }
12373
12374    return () => {
12375      const fnIndex = this._urlChangeListeners.indexOf(fn);
12376
12377      this._urlChangeListeners.splice(fnIndex, 1);
12378
12379      if (this._urlChangeListeners.length === 0) {
12380        this._urlChangeSubscription?.unsubscribe();
12381        this._urlChangeSubscription = null;
12382      }
12383    };
12384  }
12385  /** @internal */
12386
12387
12388  _notifyUrlChangeListeners(url = '', state) {
12389    this._urlChangeListeners.forEach(fn => fn(url, state));
12390  }
12391  /**
12392   * Subscribes to the platform's `popState` events.
12393   *
12394   * Note: `Location.go()` does not trigger the `popState` event in the browser. Use
12395   * `Location.onUrlChange()` to subscribe to URL changes instead.
12396   *
12397   * @param value Event that is triggered when the state history changes.
12398   * @param exception The exception to throw.
12399   *
12400   * @see [onpopstate](https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate)
12401   *
12402   * @returns Subscribed events.
12403   */
12404
12405
12406  subscribe(onNext, onThrow, onReturn) {
12407    return this._subject.subscribe({
12408      next: onNext,
12409      error: onThrow,
12410      complete: onReturn
12411    });
12412  }
12413
12414}
12415/**
12416 * Normalizes URL parameters by prepending with `?` if needed.
12417 *
12418 * @param  params String of URL parameters.
12419 *
12420 * @returns The normalized URL parameters string.
12421 */
12422
12423
12424Location.normalizeQueryParams = normalizeQueryParams;
12425/**
12426 * Joins two parts of a URL with a slash if needed.
12427 *
12428 * @param start  URL string
12429 * @param end    URL string
12430 *
12431 *
12432 * @returns The joined URL string.
12433 */
12434
12435Location.joinWithSlash = joinWithSlash;
12436/**
12437 * Removes a trailing slash from a URL string if needed.
12438 * Looks for the first occurrence of either `#`, `?`, or the end of the
12439 * line as `/` characters and removes the trailing slash if one exists.
12440 *
12441 * @param url URL string.
12442 *
12443 * @returns The URL string, modified if needed.
12444 */
12445
12446Location.stripTrailingSlash = stripTrailingSlash;
12447
12448Location.ɵfac = function Location_Factory(t) {
12449  return new (t || Location)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](LocationStrategy));
12450};
12451
12452Location.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
12453  token: Location,
12454  factory: function () {
12455    return createLocation();
12456  },
12457  providedIn: 'root'
12458});
12459
12460(function () {
12461  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](Location, [{
12462    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
12463    args: [{
12464      providedIn: 'root',
12465      // See #23917
12466      useFactory: createLocation
12467    }]
12468  }], function () {
12469    return [{
12470      type: LocationStrategy
12471    }];
12472  }, null);
12473})();
12474
12475function createLocation() {
12476  return new Location((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"])(LocationStrategy));
12477}
12478
12479function _stripBaseHref(baseHref, url) {
12480  return baseHref && url.startsWith(baseHref) ? url.substring(baseHref.length) : url;
12481}
12482
12483function _stripIndexHtml(url) {
12484  return url.replace(/\/index.html$/, '');
12485}
12486/**
12487 * @license
12488 * Copyright Google LLC All Rights Reserved.
12489 *
12490 * Use of this source code is governed by an MIT-style license that can be
12491 * found in the LICENSE file at https://angular.io/license
12492 */
12493
12494/**
12495 * @license
12496 * Copyright Google LLC All Rights Reserved.
12497 *
12498 * Use of this source code is governed by an MIT-style license that can be
12499 * found in the LICENSE file at https://angular.io/license
12500 */
12501
12502/** @internal */
12503
12504
12505const CURRENCIES_EN = {
12506  "ADP": [undefined, undefined, 0],
12507  "AFN": [undefined, "؋", 0],
12508  "ALL": [undefined, undefined, 0],
12509  "AMD": [undefined, "֏", 2],
12510  "AOA": [undefined, "Kz"],
12511  "ARS": [undefined, "$"],
12512  "AUD": ["A$", "$"],
12513  "AZN": [undefined, "₼"],
12514  "BAM": [undefined, "KM"],
12515  "BBD": [undefined, "$"],
12516  "BDT": [undefined, "à§³"],
12517  "BHD": [undefined, undefined, 3],
12518  "BIF": [undefined, undefined, 0],
12519  "BMD": [undefined, "$"],
12520  "BND": [undefined, "$"],
12521  "BOB": [undefined, "Bs"],
12522  "BRL": ["R$"],
12523  "BSD": [undefined, "$"],
12524  "BWP": [undefined, "P"],
12525  "BYN": [undefined, undefined, 2],
12526  "BYR": [undefined, undefined, 0],
12527  "BZD": [undefined, "$"],
12528  "CAD": ["CA$", "$", 2],
12529  "CHF": [undefined, undefined, 2],
12530  "CLF": [undefined, undefined, 4],
12531  "CLP": [undefined, "$", 0],
12532  "CNY": ["CNÂ¥", "Â¥"],
12533  "COP": [undefined, "$", 2],
12534  "CRC": [undefined, "₡", 2],
12535  "CUC": [undefined, "$"],
12536  "CUP": [undefined, "$"],
12537  "CZK": [undefined, "Kč", 2],
12538  "DJF": [undefined, undefined, 0],
12539  "DKK": [undefined, "kr", 2],
12540  "DOP": [undefined, "$"],
12541  "EGP": [undefined, "E£"],
12542  "ESP": [undefined, "₧", 0],
12543  "EUR": ["€"],
12544  "FJD": [undefined, "$"],
12545  "FKP": [undefined, "£"],
12546  "GBP": ["£"],
12547  "GEL": [undefined, "₾"],
12548  "GHS": [undefined, "GH₵"],
12549  "GIP": [undefined, "£"],
12550  "GNF": [undefined, "FG", 0],
12551  "GTQ": [undefined, "Q"],
12552  "GYD": [undefined, "$", 2],
12553  "HKD": ["HK$", "$"],
12554  "HNL": [undefined, "L"],
12555  "HRK": [undefined, "kn"],
12556  "HUF": [undefined, "Ft", 2],
12557  "IDR": [undefined, "Rp", 2],
12558  "ILS": ["₪"],
12559  "INR": ["₹"],
12560  "IQD": [undefined, undefined, 0],
12561  "IRR": [undefined, undefined, 0],
12562  "ISK": [undefined, "kr", 0],
12563  "ITL": [undefined, undefined, 0],
12564  "JMD": [undefined, "$"],
12565  "JOD": [undefined, undefined, 3],
12566  "JPY": ["Â¥", undefined, 0],
12567  "KHR": [undefined, "៛"],
12568  "KMF": [undefined, "CF", 0],
12569  "KPW": [undefined, "₩", 0],
12570  "KRW": ["₩", undefined, 0],
12571  "KWD": [undefined, undefined, 3],
12572  "KYD": [undefined, "$"],
12573  "KZT": [undefined, "₸"],
12574  "LAK": [undefined, "₭", 0],
12575  "LBP": [undefined, "L£", 0],
12576  "LKR": [undefined, "Rs"],
12577  "LRD": [undefined, "$"],
12578  "LTL": [undefined, "Lt"],
12579  "LUF": [undefined, undefined, 0],
12580  "LVL": [undefined, "Ls"],
12581  "LYD": [undefined, undefined, 3],
12582  "MGA": [undefined, "Ar", 0],
12583  "MGF": [undefined, undefined, 0],
12584  "MMK": [undefined, "K", 0],
12585  "MNT": [undefined, "₮", 2],
12586  "MRO": [undefined, undefined, 0],
12587  "MUR": [undefined, "Rs", 2],
12588  "MXN": ["MX$", "$"],
12589  "MYR": [undefined, "RM"],
12590  "NAD": [undefined, "$"],
12591  "NGN": [undefined, "₦"],
12592  "NIO": [undefined, "C$"],
12593  "NOK": [undefined, "kr", 2],
12594  "NPR": [undefined, "Rs"],
12595  "NZD": ["NZ$", "$"],
12596  "OMR": [undefined, undefined, 3],
12597  "PHP": ["₱"],
12598  "PKR": [undefined, "Rs", 2],
12599  "PLN": [undefined, "zł"],
12600  "PYG": [undefined, "₲", 0],
12601  "RON": [undefined, "lei"],
12602  "RSD": [undefined, undefined, 0],
12603  "RUB": [undefined, "₽"],
12604  "RWF": [undefined, "RF", 0],
12605  "SBD": [undefined, "$"],
12606  "SEK": [undefined, "kr", 2],
12607  "SGD": [undefined, "$"],
12608  "SHP": [undefined, "£"],
12609  "SLE": [undefined, undefined, 2],
12610  "SLL": [undefined, undefined, 0],
12611  "SOS": [undefined, undefined, 0],
12612  "SRD": [undefined, "$"],
12613  "SSP": [undefined, "£"],
12614  "STD": [undefined, undefined, 0],
12615  "STN": [undefined, "Db"],
12616  "SYP": [undefined, "£", 0],
12617  "THB": [undefined, "฿"],
12618  "TMM": [undefined, undefined, 0],
12619  "TND": [undefined, undefined, 3],
12620  "TOP": [undefined, "T$"],
12621  "TRL": [undefined, undefined, 0],
12622  "TRY": [undefined, "₺"],
12623  "TTD": [undefined, "$"],
12624  "TWD": ["NT$", "$", 2],
12625  "TZS": [undefined, undefined, 2],
12626  "UAH": [undefined, "₴"],
12627  "UGX": [undefined, undefined, 0],
12628  "USD": ["$"],
12629  "UYI": [undefined, undefined, 0],
12630  "UYU": [undefined, "$"],
12631  "UYW": [undefined, undefined, 4],
12632  "UZS": [undefined, undefined, 2],
12633  "VEF": [undefined, "Bs", 2],
12634  "VND": ["₫", undefined, 0],
12635  "VUV": [undefined, undefined, 0],
12636  "XAF": ["FCFA", undefined, 0],
12637  "XCD": ["EC$", "$"],
12638  "XOF": ["F CFA", undefined, 0],
12639  "XPF": ["CFPF", undefined, 0],
12640  "XXX": ["¤"],
12641  "YER": [undefined, undefined, 0],
12642  "ZAR": [undefined, "R"],
12643  "ZMK": [undefined, undefined, 0],
12644  "ZMW": [undefined, "ZK"],
12645  "ZWD": [undefined, undefined, 0]
12646};
12647/**
12648 * @license
12649 * Copyright Google LLC All Rights Reserved.
12650 *
12651 * Use of this source code is governed by an MIT-style license that can be
12652 * found in the LICENSE file at https://angular.io/license
12653 */
12654
12655/**
12656 * Format styles that can be used to represent numbers.
12657 * @see `getLocaleNumberFormat()`.
12658 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12659 *
12660 * @publicApi
12661 */
12662
12663var NumberFormatStyle;
12664
12665(function (NumberFormatStyle) {
12666  NumberFormatStyle[NumberFormatStyle["Decimal"] = 0] = "Decimal";
12667  NumberFormatStyle[NumberFormatStyle["Percent"] = 1] = "Percent";
12668  NumberFormatStyle[NumberFormatStyle["Currency"] = 2] = "Currency";
12669  NumberFormatStyle[NumberFormatStyle["Scientific"] = 3] = "Scientific";
12670})(NumberFormatStyle || (NumberFormatStyle = {}));
12671/**
12672 * Plurality cases used for translating plurals to different languages.
12673 *
12674 * @see `NgPlural`
12675 * @see `NgPluralCase`
12676 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12677 *
12678 * @publicApi
12679 */
12680
12681
12682var Plural;
12683
12684(function (Plural) {
12685  Plural[Plural["Zero"] = 0] = "Zero";
12686  Plural[Plural["One"] = 1] = "One";
12687  Plural[Plural["Two"] = 2] = "Two";
12688  Plural[Plural["Few"] = 3] = "Few";
12689  Plural[Plural["Many"] = 4] = "Many";
12690  Plural[Plural["Other"] = 5] = "Other";
12691})(Plural || (Plural = {}));
12692/**
12693 * Context-dependant translation forms for strings.
12694 * Typically the standalone version is for the nominative form of the word,
12695 * and the format version is used for the genitive case.
12696 * @see [CLDR website](http://cldr.unicode.org/translation/date-time-1/date-time#TOC-Standalone-vs.-Format-Styles)
12697 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12698 *
12699 * @publicApi
12700 */
12701
12702
12703var FormStyle;
12704
12705(function (FormStyle) {
12706  FormStyle[FormStyle["Format"] = 0] = "Format";
12707  FormStyle[FormStyle["Standalone"] = 1] = "Standalone";
12708})(FormStyle || (FormStyle = {}));
12709/**
12710 * String widths available for translations.
12711 * The specific character widths are locale-specific.
12712 * Examples are given for the word "Sunday" in English.
12713 *
12714 * @publicApi
12715 */
12716
12717
12718var TranslationWidth;
12719
12720(function (TranslationWidth) {
12721  /** 1 character for `en-US`. For example: 'S' */
12722  TranslationWidth[TranslationWidth["Narrow"] = 0] = "Narrow";
12723  /** 3 characters for `en-US`. For example: 'Sun' */
12724
12725  TranslationWidth[TranslationWidth["Abbreviated"] = 1] = "Abbreviated";
12726  /** Full length for `en-US`. For example: "Sunday" */
12727
12728  TranslationWidth[TranslationWidth["Wide"] = 2] = "Wide";
12729  /** 2 characters for `en-US`, For example: "Su" */
12730
12731  TranslationWidth[TranslationWidth["Short"] = 3] = "Short";
12732})(TranslationWidth || (TranslationWidth = {}));
12733/**
12734 * String widths available for date-time formats.
12735 * The specific character widths are locale-specific.
12736 * Examples are given for `en-US`.
12737 *
12738 * @see `getLocaleDateFormat()`
12739 * @see `getLocaleTimeFormat()`
12740 * @see `getLocaleDateTimeFormat()`
12741 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12742 * @publicApi
12743 */
12744
12745
12746var FormatWidth;
12747
12748(function (FormatWidth) {
12749  /**
12750   * For `en-US`, 'M/d/yy, h:mm a'`
12751   * (Example: `6/15/15, 9:03 AM`)
12752   */
12753  FormatWidth[FormatWidth["Short"] = 0] = "Short";
12754  /**
12755   * For `en-US`, `'MMM d, y, h:mm:ss a'`
12756   * (Example: `Jun 15, 2015, 9:03:01 AM`)
12757   */
12758
12759  FormatWidth[FormatWidth["Medium"] = 1] = "Medium";
12760  /**
12761   * For `en-US`, `'MMMM d, y, h:mm:ss a z'`
12762   * (Example: `June 15, 2015 at 9:03:01 AM GMT+1`)
12763   */
12764
12765  FormatWidth[FormatWidth["Long"] = 2] = "Long";
12766  /**
12767   * For `en-US`, `'EEEE, MMMM d, y, h:mm:ss a zzzz'`
12768   * (Example: `Monday, June 15, 2015 at 9:03:01 AM GMT+01:00`)
12769   */
12770
12771  FormatWidth[FormatWidth["Full"] = 3] = "Full";
12772})(FormatWidth || (FormatWidth = {}));
12773/**
12774 * Symbols that can be used to replace placeholders in number patterns.
12775 * Examples are based on `en-US` values.
12776 *
12777 * @see `getLocaleNumberSymbol()`
12778 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12779 *
12780 * @publicApi
12781 */
12782
12783
12784var NumberSymbol;
12785
12786(function (NumberSymbol) {
12787  /**
12788   * Decimal separator.
12789   * For `en-US`, the dot character.
12790   * Example: 2,345`.`67
12791   */
12792  NumberSymbol[NumberSymbol["Decimal"] = 0] = "Decimal";
12793  /**
12794   * Grouping separator, typically for thousands.
12795   * For `en-US`, the comma character.
12796   * Example: 2`,`345.67
12797   */
12798
12799  NumberSymbol[NumberSymbol["Group"] = 1] = "Group";
12800  /**
12801   * List-item separator.
12802   * Example: "one, two, and three"
12803   */
12804
12805  NumberSymbol[NumberSymbol["List"] = 2] = "List";
12806  /**
12807   * Sign for percentage (out of 100).
12808   * Example: 23.4%
12809   */
12810
12811  NumberSymbol[NumberSymbol["PercentSign"] = 3] = "PercentSign";
12812  /**
12813   * Sign for positive numbers.
12814   * Example: +23
12815   */
12816
12817  NumberSymbol[NumberSymbol["PlusSign"] = 4] = "PlusSign";
12818  /**
12819   * Sign for negative numbers.
12820   * Example: -23
12821   */
12822
12823  NumberSymbol[NumberSymbol["MinusSign"] = 5] = "MinusSign";
12824  /**
12825   * Computer notation for exponential value (n times a power of 10).
12826   * Example: 1.2E3
12827   */
12828
12829  NumberSymbol[NumberSymbol["Exponential"] = 6] = "Exponential";
12830  /**
12831   * Human-readable format of exponential.
12832   * Example: 1.2x103
12833   */
12834
12835  NumberSymbol[NumberSymbol["SuperscriptingExponent"] = 7] = "SuperscriptingExponent";
12836  /**
12837   * Sign for permille (out of 1000).
12838   * Example: 23.4‰
12839   */
12840
12841  NumberSymbol[NumberSymbol["PerMille"] = 8] = "PerMille";
12842  /**
12843   * Infinity, can be used with plus and minus.
12844   * Example: ∞, +∞, -∞
12845   */
12846
12847  NumberSymbol[NumberSymbol["Infinity"] = 9] = "Infinity";
12848  /**
12849   * Not a number.
12850   * Example: NaN
12851   */
12852
12853  NumberSymbol[NumberSymbol["NaN"] = 10] = "NaN";
12854  /**
12855   * Symbol used between time units.
12856   * Example: 10:52
12857   */
12858
12859  NumberSymbol[NumberSymbol["TimeSeparator"] = 11] = "TimeSeparator";
12860  /**
12861   * Decimal separator for currency values (fallback to `Decimal`).
12862   * Example: $2,345.67
12863   */
12864
12865  NumberSymbol[NumberSymbol["CurrencyDecimal"] = 12] = "CurrencyDecimal";
12866  /**
12867   * Group separator for currency values (fallback to `Group`).
12868   * Example: $2,345.67
12869   */
12870
12871  NumberSymbol[NumberSymbol["CurrencyGroup"] = 13] = "CurrencyGroup";
12872})(NumberSymbol || (NumberSymbol = {}));
12873/**
12874 * The value for each day of the week, based on the `en-US` locale
12875 *
12876 * @publicApi
12877 */
12878
12879
12880var WeekDay;
12881
12882(function (WeekDay) {
12883  WeekDay[WeekDay["Sunday"] = 0] = "Sunday";
12884  WeekDay[WeekDay["Monday"] = 1] = "Monday";
12885  WeekDay[WeekDay["Tuesday"] = 2] = "Tuesday";
12886  WeekDay[WeekDay["Wednesday"] = 3] = "Wednesday";
12887  WeekDay[WeekDay["Thursday"] = 4] = "Thursday";
12888  WeekDay[WeekDay["Friday"] = 5] = "Friday";
12889  WeekDay[WeekDay["Saturday"] = 6] = "Saturday";
12890})(WeekDay || (WeekDay = {}));
12891/**
12892 * Retrieves the locale ID from the currently loaded locale.
12893 * The loaded locale could be, for example, a global one rather than a regional one.
12894 * @param locale A locale code, such as `fr-FR`.
12895 * @returns The locale code. For example, `fr`.
12896 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12897 *
12898 * @publicApi
12899 */
12900
12901
12902function getLocaleId(locale) {
12903  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale)[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].LocaleId];
12904}
12905/**
12906 * Retrieves day period strings for the given locale.
12907 *
12908 * @param locale A locale code for the locale format rules to use.
12909 * @param formStyle The required grammatical form.
12910 * @param width The required character width.
12911 * @returns An array of localized period strings. For example, `[AM, PM]` for `en-US`.
12912 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12913 *
12914 * @publicApi
12915 */
12916
12917
12918function getLocaleDayPeriods(locale, formStyle, width) {
12919  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
12920  const amPmData = [data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DayPeriodsFormat], data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DayPeriodsStandalone]];
12921  const amPm = getLastDefinedValue(amPmData, formStyle);
12922  return getLastDefinedValue(amPm, width);
12923}
12924/**
12925 * Retrieves days of the week for the given locale, using the Gregorian calendar.
12926 *
12927 * @param locale A locale code for the locale format rules to use.
12928 * @param formStyle The required grammatical form.
12929 * @param width The required character width.
12930 * @returns An array of localized name strings.
12931 * For example,`[Sunday, Monday, ... Saturday]` for `en-US`.
12932 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12933 *
12934 * @publicApi
12935 */
12936
12937
12938function getLocaleDayNames(locale, formStyle, width) {
12939  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
12940  const daysData = [data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DaysFormat], data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DaysStandalone]];
12941  const days = getLastDefinedValue(daysData, formStyle);
12942  return getLastDefinedValue(days, width);
12943}
12944/**
12945 * Retrieves months of the year for the given locale, using the Gregorian calendar.
12946 *
12947 * @param locale A locale code for the locale format rules to use.
12948 * @param formStyle The required grammatical form.
12949 * @param width The required character width.
12950 * @returns An array of localized name strings.
12951 * For example,  `[January, February, ...]` for `en-US`.
12952 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12953 *
12954 * @publicApi
12955 */
12956
12957
12958function getLocaleMonthNames(locale, formStyle, width) {
12959  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
12960  const monthsData = [data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].MonthsFormat], data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].MonthsStandalone]];
12961  const months = getLastDefinedValue(monthsData, formStyle);
12962  return getLastDefinedValue(months, width);
12963}
12964/**
12965 * Retrieves Gregorian-calendar eras for the given locale.
12966 * @param locale A locale code for the locale format rules to use.
12967 * @param width The required character width.
12968
12969 * @returns An array of localized era strings.
12970 * For example, `[AD, BC]` for `en-US`.
12971 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12972 *
12973 * @publicApi
12974 */
12975
12976
12977function getLocaleEraNames(locale, width) {
12978  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
12979  const erasData = data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].Eras];
12980  return getLastDefinedValue(erasData, width);
12981}
12982/**
12983 * Retrieves the first day of the week for the given locale.
12984 *
12985 * @param locale A locale code for the locale format rules to use.
12986 * @returns A day index number, using the 0-based week-day index for `en-US`
12987 * (Sunday = 0, Monday = 1, ...).
12988 * For example, for `fr-FR`, returns 1 to indicate that the first day is Monday.
12989 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
12990 *
12991 * @publicApi
12992 */
12993
12994
12995function getLocaleFirstDayOfWeek(locale) {
12996  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
12997  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].FirstDayOfWeek];
12998}
12999/**
13000 * Range of week days that are considered the week-end for the given locale.
13001 *
13002 * @param locale A locale code for the locale format rules to use.
13003 * @returns The range of day values, `[startDay, endDay]`.
13004 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13005 *
13006 * @publicApi
13007 */
13008
13009
13010function getLocaleWeekEndRange(locale) {
13011  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13012  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].WeekendRange];
13013}
13014/**
13015 * Retrieves a localized date-value formatting string.
13016 *
13017 * @param locale A locale code for the locale format rules to use.
13018 * @param width The format type.
13019 * @returns The localized formatting string.
13020 * @see `FormatWidth`
13021 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13022 *
13023 * @publicApi
13024 */
13025
13026
13027function getLocaleDateFormat(locale, width) {
13028  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13029  return getLastDefinedValue(data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DateFormat], width);
13030}
13031/**
13032 * Retrieves a localized time-value formatting string.
13033 *
13034 * @param locale A locale code for the locale format rules to use.
13035 * @param width The format type.
13036 * @returns The localized formatting string.
13037 * @see `FormatWidth`
13038 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13039
13040 * @publicApi
13041 */
13042
13043
13044function getLocaleTimeFormat(locale, width) {
13045  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13046  return getLastDefinedValue(data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].TimeFormat], width);
13047}
13048/**
13049 * Retrieves a localized date-time formatting string.
13050 *
13051 * @param locale A locale code for the locale format rules to use.
13052 * @param width The format type.
13053 * @returns The localized formatting string.
13054 * @see `FormatWidth`
13055 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13056 *
13057 * @publicApi
13058 */
13059
13060
13061function getLocaleDateTimeFormat(locale, width) {
13062  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13063  const dateTimeFormatData = data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DateTimeFormat];
13064  return getLastDefinedValue(dateTimeFormatData, width);
13065}
13066/**
13067 * Retrieves a localized number symbol that can be used to replace placeholders in number formats.
13068 * @param locale The locale code.
13069 * @param symbol The symbol to localize.
13070 * @returns The character for the localized symbol.
13071 * @see `NumberSymbol`
13072 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13073 *
13074 * @publicApi
13075 */
13076
13077
13078function getLocaleNumberSymbol(locale, symbol) {
13079  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13080  const res = data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].NumberSymbols][symbol];
13081
13082  if (typeof res === 'undefined') {
13083    if (symbol === NumberSymbol.CurrencyDecimal) {
13084      return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].NumberSymbols][NumberSymbol.Decimal];
13085    } else if (symbol === NumberSymbol.CurrencyGroup) {
13086      return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].NumberSymbols][NumberSymbol.Group];
13087    }
13088  }
13089
13090  return res;
13091}
13092/**
13093 * Retrieves a number format for a given locale.
13094 *
13095 * Numbers are formatted using patterns, like `#,###.00`. For example, the pattern `#,###.00`
13096 * when used to format the number 12345.678 could result in "12'345,678". That would happen if the
13097 * grouping separator for your language is an apostrophe, and the decimal separator is a comma.
13098 *
13099 * <b>Important:</b> The characters `.` `,` `0` `#` (and others below) are special placeholders
13100 * that stand for the decimal separator, and so on, and are NOT real characters.
13101 * You must NOT "translate" the placeholders. For example, don't change `.` to `,` even though in
13102 * your language the decimal point is written with a comma. The symbols should be replaced by the
13103 * local equivalents, using the appropriate `NumberSymbol` for your language.
13104 *
13105 * Here are the special characters used in number patterns:
13106 *
13107 * | Symbol | Meaning |
13108 * |--------|---------|
13109 * | . | Replaced automatically by the character used for the decimal point. |
13110 * | , | Replaced by the "grouping" (thousands) separator. |
13111 * | 0 | Replaced by a digit (or zero if there aren't enough digits). |
13112 * | # | Replaced by a digit (or nothing if there aren't enough). |
13113 * | ¤ | Replaced by a currency symbol, such as $ or USD. |
13114 * | % | Marks a percent format. The % symbol may change position, but must be retained. |
13115 * | E | Marks a scientific format. The E symbol may change position, but must be retained. |
13116 * | ' | Special characters used as literal characters are quoted with ASCII single quotes. |
13117 *
13118 * @param locale A locale code for the locale format rules to use.
13119 * @param type The type of numeric value to be formatted (such as `Decimal` or `Currency`.)
13120 * @returns The localized format string.
13121 * @see `NumberFormatStyle`
13122 * @see [CLDR website](http://cldr.unicode.org/translation/number-patterns)
13123 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13124 *
13125 * @publicApi
13126 */
13127
13128
13129function getLocaleNumberFormat(locale, type) {
13130  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13131  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].NumberFormats][type];
13132}
13133/**
13134 * Retrieves the symbol used to represent the currency for the main country
13135 * corresponding to a given locale. For example, '$' for `en-US`.
13136 *
13137 * @param locale A locale code for the locale format rules to use.
13138 * @returns The localized symbol character,
13139 * or `null` if the main country cannot be determined.
13140 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13141 *
13142 * @publicApi
13143 */
13144
13145
13146function getLocaleCurrencySymbol(locale) {
13147  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13148  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].CurrencySymbol] || null;
13149}
13150/**
13151 * Retrieves the name of the currency for the main country corresponding
13152 * to a given locale. For example, 'US Dollar' for `en-US`.
13153 * @param locale A locale code for the locale format rules to use.
13154 * @returns The currency name,
13155 * or `null` if the main country cannot be determined.
13156 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13157 *
13158 * @publicApi
13159 */
13160
13161
13162function getLocaleCurrencyName(locale) {
13163  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13164  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].CurrencyName] || null;
13165}
13166/**
13167 * Retrieves the default currency code for the given locale.
13168 *
13169 * The default is defined as the first currency which is still in use.
13170 *
13171 * @param locale The code of the locale whose currency code we want.
13172 * @returns The code of the default currency for the given locale.
13173 *
13174 * @publicApi
13175 */
13176
13177
13178function getLocaleCurrencyCode(locale) {
13179  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵgetLocaleCurrencyCode"])(locale);
13180}
13181/**
13182 * Retrieves the currency values for a given locale.
13183 * @param locale A locale code for the locale format rules to use.
13184 * @returns The currency values.
13185 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13186 */
13187
13188
13189function getLocaleCurrencies(locale) {
13190  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13191  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].Currencies];
13192}
13193/**
13194 * @alias core/ɵgetLocalePluralCase
13195 * @publicApi
13196 */
13197
13198
13199const getLocalePluralCase = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵgetLocalePluralCase"];
13200
13201function checkFullData(data) {
13202  if (!data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].ExtraData]) {
13203    throw new Error(`Missing extra locale data for the locale "${data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].LocaleId]}". Use "registerLocaleData" to load new data. See the "I18n guide" on angular.io to know more.`);
13204  }
13205}
13206/**
13207 * Retrieves locale-specific rules used to determine which day period to use
13208 * when more than one period is defined for a locale.
13209 *
13210 * There is a rule for each defined day period. The
13211 * first rule is applied to the first day period and so on.
13212 * Fall back to AM/PM when no rules are available.
13213 *
13214 * A rule can specify a period as time range, or as a single time value.
13215 *
13216 * This functionality is only available when you have loaded the full locale data.
13217 * See the ["I18n guide"](guide/i18n-common-format-data-locale).
13218 *
13219 * @param locale A locale code for the locale format rules to use.
13220 * @returns The rules for the locale, a single time value or array of *from-time, to-time*,
13221 * or null if no periods are available.
13222 *
13223 * @see `getLocaleExtraDayPeriods()`
13224 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13225 *
13226 * @publicApi
13227 */
13228
13229
13230function getLocaleExtraDayPeriodRules(locale) {
13231  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13232  checkFullData(data);
13233  const rules = data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].ExtraData][2
13234  /* ɵExtraLocaleDataIndex.ExtraDayPeriodsRules */
13235  ] || [];
13236  return rules.map(rule => {
13237    if (typeof rule === 'string') {
13238      return extractTime(rule);
13239    }
13240
13241    return [extractTime(rule[0]), extractTime(rule[1])];
13242  });
13243}
13244/**
13245 * Retrieves locale-specific day periods, which indicate roughly how a day is broken up
13246 * in different languages.
13247 * For example, for `en-US`, periods are morning, noon, afternoon, evening, and midnight.
13248 *
13249 * This functionality is only available when you have loaded the full locale data.
13250 * See the ["I18n guide"](guide/i18n-common-format-data-locale).
13251 *
13252 * @param locale A locale code for the locale format rules to use.
13253 * @param formStyle The required grammatical form.
13254 * @param width The required character width.
13255 * @returns The translated day-period strings.
13256 * @see `getLocaleExtraDayPeriodRules()`
13257 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13258 *
13259 * @publicApi
13260 */
13261
13262
13263function getLocaleExtraDayPeriods(locale, formStyle, width) {
13264  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13265  checkFullData(data);
13266  const dayPeriodsData = [data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].ExtraData][0
13267  /* ɵExtraLocaleDataIndex.ExtraDayPeriodFormats */
13268  ], data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].ExtraData][1
13269  /* ɵExtraLocaleDataIndex.ExtraDayPeriodStandalone */
13270  ]];
13271  const dayPeriods = getLastDefinedValue(dayPeriodsData, formStyle) || [];
13272  return getLastDefinedValue(dayPeriods, width) || [];
13273}
13274/**
13275 * Retrieves the writing direction of a specified locale
13276 * @param locale A locale code for the locale format rules to use.
13277 * @publicApi
13278 * @returns 'rtl' or 'ltr'
13279 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13280 */
13281
13282
13283function getLocaleDirection(locale) {
13284  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
13285  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].Directionality];
13286}
13287/**
13288 * Retrieves the first value that is defined in an array, going backwards from an index position.
13289 *
13290 * To avoid repeating the same data (as when the "format" and "standalone" forms are the same)
13291 * add the first value to the locale data arrays, and add other values only if they are different.
13292 *
13293 * @param data The data array to retrieve from.
13294 * @param index A 0-based index into the array to start from.
13295 * @returns The value immediately before the given index position.
13296 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13297 *
13298 * @publicApi
13299 */
13300
13301
13302function getLastDefinedValue(data, index) {
13303  for (let i = index; i > -1; i--) {
13304    if (typeof data[i] !== 'undefined') {
13305      return data[i];
13306    }
13307  }
13308
13309  throw new Error('Locale data API: locale data undefined');
13310}
13311/**
13312 * Extracts the hours and minutes from a string like "15:45"
13313 */
13314
13315
13316function extractTime(time) {
13317  const [h, m] = time.split(':');
13318  return {
13319    hours: +h,
13320    minutes: +m
13321  };
13322}
13323/**
13324 * Retrieves the currency symbol for a given currency code.
13325 *
13326 * For example, for the default `en-US` locale, the code `USD` can
13327 * be represented by the narrow symbol `$` or the wide symbol `US$`.
13328 *
13329 * @param code The currency code.
13330 * @param format The format, `wide` or `narrow`.
13331 * @param locale A locale code for the locale format rules to use.
13332 *
13333 * @returns The symbol, or the currency code if no symbol is available.
13334 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13335 *
13336 * @publicApi
13337 */
13338
13339
13340function getCurrencySymbol(code, format, locale = 'en') {
13341  const currency = getLocaleCurrencies(locale)[code] || CURRENCIES_EN[code] || [];
13342  const symbolNarrow = currency[1
13343  /* ɵCurrencyIndex.SymbolNarrow */
13344  ];
13345
13346  if (format === 'narrow' && typeof symbolNarrow === 'string') {
13347    return symbolNarrow;
13348  }
13349
13350  return currency[0
13351  /* ɵCurrencyIndex.Symbol */
13352  ] || code;
13353} // Most currencies have cents, that's why the default is 2
13354
13355
13356const DEFAULT_NB_OF_CURRENCY_DIGITS = 2;
13357/**
13358 * Reports the number of decimal digits for a given currency.
13359 * The value depends upon the presence of cents in that particular currency.
13360 *
13361 * @param code The currency code.
13362 * @returns The number of decimal digits, typically 0 or 2.
13363 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13364 *
13365 * @publicApi
13366 */
13367
13368function getNumberOfCurrencyDigits(code) {
13369  let digits;
13370  const currency = CURRENCIES_EN[code];
13371
13372  if (currency) {
13373    digits = currency[2
13374    /* ɵCurrencyIndex.NbOfDigits */
13375    ];
13376  }
13377
13378  return typeof digits === 'number' ? digits : DEFAULT_NB_OF_CURRENCY_DIGITS;
13379}
13380/**
13381 * @license
13382 * Copyright Google LLC All Rights Reserved.
13383 *
13384 * Use of this source code is governed by an MIT-style license that can be
13385 * found in the LICENSE file at https://angular.io/license
13386 */
13387
13388
13389const ISO8601_DATE_REGEX = /^(\d{4,})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; //    1        2       3         4          5          6          7          8  9     10      11
13390
13391const NAMED_FORMATS = {};
13392const DATE_FORMATS_SPLIT = /((?:[^BEGHLMOSWYZabcdhmswyz']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|c{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/;
13393var ZoneWidth;
13394
13395(function (ZoneWidth) {
13396  ZoneWidth[ZoneWidth["Short"] = 0] = "Short";
13397  ZoneWidth[ZoneWidth["ShortGMT"] = 1] = "ShortGMT";
13398  ZoneWidth[ZoneWidth["Long"] = 2] = "Long";
13399  ZoneWidth[ZoneWidth["Extended"] = 3] = "Extended";
13400})(ZoneWidth || (ZoneWidth = {}));
13401
13402var DateType;
13403
13404(function (DateType) {
13405  DateType[DateType["FullYear"] = 0] = "FullYear";
13406  DateType[DateType["Month"] = 1] = "Month";
13407  DateType[DateType["Date"] = 2] = "Date";
13408  DateType[DateType["Hours"] = 3] = "Hours";
13409  DateType[DateType["Minutes"] = 4] = "Minutes";
13410  DateType[DateType["Seconds"] = 5] = "Seconds";
13411  DateType[DateType["FractionalSeconds"] = 6] = "FractionalSeconds";
13412  DateType[DateType["Day"] = 7] = "Day";
13413})(DateType || (DateType = {}));
13414
13415var TranslationType;
13416
13417(function (TranslationType) {
13418  TranslationType[TranslationType["DayPeriods"] = 0] = "DayPeriods";
13419  TranslationType[TranslationType["Days"] = 1] = "Days";
13420  TranslationType[TranslationType["Months"] = 2] = "Months";
13421  TranslationType[TranslationType["Eras"] = 3] = "Eras";
13422})(TranslationType || (TranslationType = {}));
13423/**
13424 * @ngModule CommonModule
13425 * @description
13426 *
13427 * Formats a date according to locale rules.
13428 *
13429 * @param value The date to format, as a Date, or a number (milliseconds since UTC epoch)
13430 * or an [ISO date-time string](https://www.w3.org/TR/NOTE-datetime).
13431 * @param format The date-time components to include. See `DatePipe` for details.
13432 * @param locale A locale code for the locale format rules to use.
13433 * @param timezone The time zone. A time zone offset from GMT (such as `'+0430'`),
13434 * or a standard UTC/GMT or continental US time zone abbreviation.
13435 * If not specified, uses host system settings.
13436 *
13437 * @returns The formatted date string.
13438 *
13439 * @see `DatePipe`
13440 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
13441 *
13442 * @publicApi
13443 */
13444
13445
13446function formatDate(value, format, locale, timezone) {
13447  let date = toDate(value);
13448  const namedFormat = getNamedFormat(locale, format);
13449  format = namedFormat || format;
13450  let parts = [];
13451  let match;
13452
13453  while (format) {
13454    match = DATE_FORMATS_SPLIT.exec(format);
13455
13456    if (match) {
13457      parts = parts.concat(match.slice(1));
13458      const part = parts.pop();
13459
13460      if (!part) {
13461        break;
13462      }
13463
13464      format = part;
13465    } else {
13466      parts.push(format);
13467      break;
13468    }
13469  }
13470
13471  let dateTimezoneOffset = date.getTimezoneOffset();
13472
13473  if (timezone) {
13474    dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
13475    date = convertTimezoneToLocal(date, timezone, true);
13476  }
13477
13478  let text = '';
vendor: 38,783 bytes, lines 13479-14736
13479  parts.forEach(value => {
13480    const dateFormatter = getDateFormatter(value);
13481    text += dateFormatter ? dateFormatter(date, locale, dateTimezoneOffset) : value === '\'\'' ? '\'' : value.replace(/(^'|'$)/g, '').replace(/''/g, '\'');
13482  });
13483  return text;
13484}
13485/**
13486 * Create a new Date object with the given date value, and the time set to midnight.
13487 *
13488 * We cannot use `new Date(year, month, date)` because it maps years between 0 and 99 to 1900-1999.
13489 * See: https://github.com/angular/angular/issues/40377
13490 *
13491 * Note that this function returns a Date object whose time is midnight in the current locale's
13492 * timezone. In the future we might want to change this to be midnight in UTC, but this would be a
13493 * considerable breaking change.
13494 */
13495
13496
13497function createDate(year, month, date) {
13498  // The `newDate` is set to midnight (UTC) on January 1st 1970.
13499  // - In PST this will be December 31st 1969 at 4pm.
13500  // - In GMT this will be January 1st 1970 at 1am.
13501  // Note that they even have different years, dates and months!
13502  const newDate = new Date(0); // `setFullYear()` allows years like 0001 to be set correctly. This function does not
13503  // change the internal time of the date.
13504  // Consider calling `setFullYear(2019, 8, 20)` (September 20, 2019).
13505  // - In PST this will now be September 20, 2019 at 4pm
13506  // - In GMT this will now be September 20, 2019 at 1am
13507
13508  newDate.setFullYear(year, month, date); // We want the final date to be at local midnight, so we reset the time.
13509  // - In PST this will now be September 20, 2019 at 12am
13510  // - In GMT this will now be September 20, 2019 at 12am
13511
13512  newDate.setHours(0, 0, 0);
13513  return newDate;
13514}
13515
13516function getNamedFormat(locale, format) {
13517  const localeId = getLocaleId(locale);
13518  NAMED_FORMATS[localeId] = NAMED_FORMATS[localeId] || {};
13519
13520  if (NAMED_FORMATS[localeId][format]) {
13521    return NAMED_FORMATS[localeId][format];
13522  }
13523
13524  let formatValue = '';
13525
13526  switch (format) {
13527    case 'shortDate':
13528      formatValue = getLocaleDateFormat(locale, FormatWidth.Short);
13529      break;
13530
13531    case 'mediumDate':
13532      formatValue = getLocaleDateFormat(locale, FormatWidth.Medium);
13533      break;
13534
13535    case 'longDate':
13536      formatValue = getLocaleDateFormat(locale, FormatWidth.Long);
13537      break;
13538
13539    case 'fullDate':
13540      formatValue = getLocaleDateFormat(locale, FormatWidth.Full);
13541      break;
13542
13543    case 'shortTime':
13544      formatValue = getLocaleTimeFormat(locale, FormatWidth.Short);
13545      break;
13546
13547    case 'mediumTime':
13548      formatValue = getLocaleTimeFormat(locale, FormatWidth.Medium);
13549      break;
13550
13551    case 'longTime':
13552      formatValue = getLocaleTimeFormat(locale, FormatWidth.Long);
13553      break;
13554
13555    case 'fullTime':
13556      formatValue = getLocaleTimeFormat(locale, FormatWidth.Full);
13557      break;
13558
13559    case 'short':
13560      const shortTime = getNamedFormat(locale, 'shortTime');
13561      const shortDate = getNamedFormat(locale, 'shortDate');
13562      formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Short), [shortTime, shortDate]);
13563      break;
13564
13565    case 'medium':
13566      const mediumTime = getNamedFormat(locale, 'mediumTime');
13567      const mediumDate = getNamedFormat(locale, 'mediumDate');
13568      formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Medium), [mediumTime, mediumDate]);
13569      break;
13570
13571    case 'long':
13572      const longTime = getNamedFormat(locale, 'longTime');
13573      const longDate = getNamedFormat(locale, 'longDate');
13574      formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Long), [longTime, longDate]);
13575      break;
13576
13577    case 'full':
13578      const fullTime = getNamedFormat(locale, 'fullTime');
13579      const fullDate = getNamedFormat(locale, 'fullDate');
13580      formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Full), [fullTime, fullDate]);
13581      break;
13582  }
13583
13584  if (formatValue) {
13585    NAMED_FORMATS[localeId][format] = formatValue;
13586  }
13587
13588  return formatValue;
13589}
13590
13591function formatDateTime(str, opt_values) {
13592  if (opt_values) {
13593    str = str.replace(/\{([^}]+)}/g, function (match, key) {
13594      return opt_values != null && key in opt_values ? opt_values[key] : match;
13595    });
13596  }
13597
13598  return str;
13599}
13600
13601function padNumber(num, digits, minusSign = '-', trim, negWrap) {
13602  let neg = '';
13603
13604  if (num < 0 || negWrap && num <= 0) {
13605    if (negWrap) {
13606      num = -num + 1;
13607    } else {
13608      num = -num;
13609      neg = minusSign;
13610    }
13611  }
13612
13613  let strNum = String(num);
13614
13615  while (strNum.length < digits) {
13616    strNum = '0' + strNum;
13617  }
13618
13619  if (trim) {
13620    strNum = strNum.slice(strNum.length - digits);
13621  }
13622
13623  return neg + strNum;
13624}
13625
13626function formatFractionalSeconds(milliseconds, digits) {
13627  const strMs = padNumber(milliseconds, 3);
13628  return strMs.substring(0, digits);
13629}
13630/**
13631 * Returns a date formatter that transforms a date into its locale digit representation
13632 */
13633
13634
13635function dateGetter(name, size, offset = 0, trim = false, negWrap = false) {
13636  return function (date, locale) {
13637    let part = getDatePart(name, date);
13638
13639    if (offset > 0 || part > -offset) {
13640      part += offset;
13641    }
13642
13643    if (name === DateType.Hours) {
13644      if (part === 0 && offset === -12) {
13645        part = 12;
13646      }
13647    } else if (name === DateType.FractionalSeconds) {
13648      return formatFractionalSeconds(part, size);
13649    }
13650
13651    const localeMinus = getLocaleNumberSymbol(locale, NumberSymbol.MinusSign);
13652    return padNumber(part, size, localeMinus, trim, negWrap);
13653  };
13654}
13655
13656function getDatePart(part, date) {
13657  switch (part) {
13658    case DateType.FullYear:
13659      return date.getFullYear();
13660
13661    case DateType.Month:
13662      return date.getMonth();
13663
13664    case DateType.Date:
13665      return date.getDate();
13666
13667    case DateType.Hours:
13668      return date.getHours();
13669
13670    case DateType.Minutes:
13671      return date.getMinutes();
13672
13673    case DateType.Seconds:
13674      return date.getSeconds();
13675
13676    case DateType.FractionalSeconds:
13677      return date.getMilliseconds();
13678
13679    case DateType.Day:
13680      return date.getDay();
13681
13682    default:
13683      throw new Error(`Unknown DateType value "${part}".`);
13684  }
13685}
13686/**
13687 * Returns a date formatter that transforms a date into its locale string representation
13688 */
13689
13690
13691function dateStrGetter(name, width, form = FormStyle.Format, extended = false) {
13692  return function (date, locale) {
13693    return getDateTranslation(date, locale, name, width, form, extended);
13694  };
13695}
13696/**
13697 * Returns the locale translation of a date for a given form, type and width
13698 */
13699
13700
13701function getDateTranslation(date, locale, name, width, form, extended) {
13702  switch (name) {
13703    case TranslationType.Months:
13704      return getLocaleMonthNames(locale, form, width)[date.getMonth()];
13705
13706    case TranslationType.Days:
13707      return getLocaleDayNames(locale, form, width)[date.getDay()];
13708
13709    case TranslationType.DayPeriods:
13710      const currentHours = date.getHours();
13711      const currentMinutes = date.getMinutes();
13712
13713      if (extended) {
13714        const rules = getLocaleExtraDayPeriodRules(locale);
13715        const dayPeriods = getLocaleExtraDayPeriods(locale, form, width);
13716        const index = rules.findIndex(rule => {
13717          if (Array.isArray(rule)) {
13718            // morning, afternoon, evening, night
13719            const [from, to] = rule;
13720            const afterFrom = currentHours >= from.hours && currentMinutes >= from.minutes;
13721            const beforeTo = currentHours < to.hours || currentHours === to.hours && currentMinutes < to.minutes; // We must account for normal rules that span a period during the day (e.g. 6am-9am)
13722            // where `from` is less (earlier) than `to`. But also rules that span midnight (e.g.
13723            // 10pm - 5am) where `from` is greater (later!) than `to`.
13724            //
13725            // In the first case the current time must be BOTH after `from` AND before `to`
13726            // (e.g. 8am is after 6am AND before 10am).
13727            //
13728            // In the second case the current time must be EITHER after `from` OR before `to`
13729            // (e.g. 4am is before 5am but not after 10pm; and 11pm is not before 5am but it is
13730            // after 10pm).
13731
13732            if (from.hours < to.hours) {
13733              if (afterFrom && beforeTo) {
13734                return true;
13735              }
13736            } else if (afterFrom || beforeTo) {
13737              return true;
13738            }
13739          } else {
13740            // noon or midnight
13741            if (rule.hours === currentHours && rule.minutes === currentMinutes) {
13742              return true;
13743            }
13744          }
13745
13746          return false;
13747        });
13748
13749        if (index !== -1) {
13750          return dayPeriods[index];
13751        }
13752      } // if no rules for the day periods, we use am/pm by default
13753
13754
13755      return getLocaleDayPeriods(locale, form, width)[currentHours < 12 ? 0 : 1];
13756
13757    case TranslationType.Eras:
13758      return getLocaleEraNames(locale, width)[date.getFullYear() <= 0 ? 0 : 1];
13759
13760    default:
13761      // This default case is not needed by TypeScript compiler, as the switch is exhaustive.
13762      // However Closure Compiler does not understand that and reports an error in typed mode.
13763      // The `throw new Error` below works around the problem, and the unexpected: never variable
13764      // makes sure tsc still checks this code is unreachable.
13765      const unexpected = name;
13766      throw new Error(`unexpected translation type ${unexpected}`);
13767  }
13768}
13769/**
13770 * Returns a date formatter that transforms a date and an offset into a timezone with ISO8601 or
13771 * GMT format depending on the width (eg: short = +0430, short:GMT = GMT+4, long = GMT+04:30,
13772 * extended = +04:30)
13773 */
13774
13775
13776function timeZoneGetter(width) {
13777  return function (date, locale, offset) {
13778    const zone = -1 * offset;
13779    const minusSign = getLocaleNumberSymbol(locale, NumberSymbol.MinusSign);
13780    const hours = zone > 0 ? Math.floor(zone / 60) : Math.ceil(zone / 60);
13781
13782    switch (width) {
13783      case ZoneWidth.Short:
13784        return (zone >= 0 ? '+' : '') + padNumber(hours, 2, minusSign) + padNumber(Math.abs(zone % 60), 2, minusSign);
13785
13786      case ZoneWidth.ShortGMT:
13787        return 'GMT' + (zone >= 0 ? '+' : '') + padNumber(hours, 1, minusSign);
13788
13789      case ZoneWidth.Long:
13790        return 'GMT' + (zone >= 0 ? '+' : '') + padNumber(hours, 2, minusSign) + ':' + padNumber(Math.abs(zone % 60), 2, minusSign);
13791
13792      case ZoneWidth.Extended:
13793        if (offset === 0) {
13794          return 'Z';
13795        } else {
13796          return (zone >= 0 ? '+' : '') + padNumber(hours, 2, minusSign) + ':' + padNumber(Math.abs(zone % 60), 2, minusSign);
13797        }
13798
13799      default:
13800        throw new Error(`Unknown zone width "${width}"`);
13801    }
13802  };
13803}
13804
13805const JANUARY = 0;
13806const THURSDAY = 4;
13807
13808function getFirstThursdayOfYear(year) {
13809  const firstDayOfYear = createDate(year, JANUARY, 1).getDay();
13810  return createDate(year, 0, 1 + (firstDayOfYear <= THURSDAY ? THURSDAY : THURSDAY + 7) - firstDayOfYear);
13811}
13812
13813function getThursdayThisWeek(datetime) {
13814  return createDate(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() + (THURSDAY - datetime.getDay()));
13815}
13816
13817function weekGetter(size, monthBased = false) {
13818  return function (date, locale) {
13819    let result;
13820
13821    if (monthBased) {
13822      const nbDaysBefore1stDayOfMonth = new Date(date.getFullYear(), date.getMonth(), 1).getDay() - 1;
13823      const today = date.getDate();
13824      result = 1 + Math.floor((today + nbDaysBefore1stDayOfMonth) / 7);
13825    } else {
13826      const thisThurs = getThursdayThisWeek(date); // Some days of a year are part of next year according to ISO 8601.
13827      // Compute the firstThurs from the year of this week's Thursday
13828
13829      const firstThurs = getFirstThursdayOfYear(thisThurs.getFullYear());
13830      const diff = thisThurs.getTime() - firstThurs.getTime();
13831      result = 1 + Math.round(diff / 6.048e8); // 6.048e8 ms per week
13832    }
13833
13834    return padNumber(result, size, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign));
13835  };
13836}
13837/**
13838 * Returns a date formatter that provides the week-numbering year for the input date.
13839 */
13840
13841
13842function weekNumberingYearGetter(size, trim = false) {
13843  return function (date, locale) {
13844    const thisThurs = getThursdayThisWeek(date);
13845    const weekNumberingYear = thisThurs.getFullYear();
13846    return padNumber(weekNumberingYear, size, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign), trim);
13847  };
13848}
13849
13850const DATE_FORMATS = {}; // Based on CLDR formats:
13851// See complete list: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
13852// See also explanations: http://cldr.unicode.org/translation/date-time
13853// TODO(ocombe): support all missing cldr formats: U, Q, D, F, e, j, J, C, A, v, V, X, x
13854
13855function getDateFormatter(format) {
13856  if (DATE_FORMATS[format]) {
13857    return DATE_FORMATS[format];
13858  }
13859
13860  let formatter;
13861
13862  switch (format) {
13863    // Era name (AD/BC)
13864    case 'G':
13865    case 'GG':
13866    case 'GGG':
13867      formatter = dateStrGetter(TranslationType.Eras, TranslationWidth.Abbreviated);
13868      break;
13869
13870    case 'GGGG':
13871      formatter = dateStrGetter(TranslationType.Eras, TranslationWidth.Wide);
13872      break;
13873
13874    case 'GGGGG':
13875      formatter = dateStrGetter(TranslationType.Eras, TranslationWidth.Narrow);
13876      break;
13877    // 1 digit representation of the year, e.g. (AD 1 => 1, AD 199 => 199)
13878
13879    case 'y':
13880      formatter = dateGetter(DateType.FullYear, 1, 0, false, true);
13881      break;
13882    // 2 digit representation of the year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10)
13883
13884    case 'yy':
13885      formatter = dateGetter(DateType.FullYear, 2, 0, true, true);
13886      break;
13887    // 3 digit representation of the year, padded (000-999). (e.g. AD 2001 => 01, AD 2010 => 10)
13888
13889    case 'yyy':
13890      formatter = dateGetter(DateType.FullYear, 3, 0, false, true);
13891      break;
13892    // 4 digit representation of the year (e.g. AD 1 => 0001, AD 2010 => 2010)
13893
13894    case 'yyyy':
13895      formatter = dateGetter(DateType.FullYear, 4, 0, false, true);
13896      break;
13897    // 1 digit representation of the week-numbering year, e.g. (AD 1 => 1, AD 199 => 199)
13898
13899    case 'Y':
13900      formatter = weekNumberingYearGetter(1);
13901      break;
13902    // 2 digit representation of the week-numbering year, padded (00-99). (e.g. AD 2001 => 01, AD
13903    // 2010 => 10)
13904
13905    case 'YY':
13906      formatter = weekNumberingYearGetter(2, true);
13907      break;
13908    // 3 digit representation of the week-numbering year, padded (000-999). (e.g. AD 1 => 001, AD
13909    // 2010 => 2010)
13910
13911    case 'YYY':
13912      formatter = weekNumberingYearGetter(3);
13913      break;
13914    // 4 digit representation of the week-numbering year (e.g. AD 1 => 0001, AD 2010 => 2010)
13915
13916    case 'YYYY':
13917      formatter = weekNumberingYearGetter(4);
13918      break;
13919    // Month of the year (1-12), numeric
13920
13921    case 'M':
13922    case 'L':
13923      formatter = dateGetter(DateType.Month, 1, 1);
13924      break;
13925
13926    case 'MM':
13927    case 'LL':
13928      formatter = dateGetter(DateType.Month, 2, 1);
13929      break;
13930    // Month of the year (January, ...), string, format
13931
13932    case 'MMM':
13933      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Abbreviated);
13934      break;
13935
13936    case 'MMMM':
13937      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Wide);
13938      break;
13939
13940    case 'MMMMM':
13941      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Narrow);
13942      break;
13943    // Month of the year (January, ...), string, standalone
13944
13945    case 'LLL':
13946      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Abbreviated, FormStyle.Standalone);
13947      break;
13948
13949    case 'LLLL':
13950      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Wide, FormStyle.Standalone);
13951      break;
13952
13953    case 'LLLLL':
13954      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Narrow, FormStyle.Standalone);
13955      break;
13956    // Week of the year (1, ... 52)
13957
13958    case 'w':
13959      formatter = weekGetter(1);
13960      break;
13961
13962    case 'ww':
13963      formatter = weekGetter(2);
13964      break;
13965    // Week of the month (1, ...)
13966
13967    case 'W':
13968      formatter = weekGetter(1, true);
13969      break;
13970    // Day of the month (1-31)
13971
13972    case 'd':
13973      formatter = dateGetter(DateType.Date, 1);
13974      break;
13975
13976    case 'dd':
13977      formatter = dateGetter(DateType.Date, 2);
13978      break;
13979    // Day of the Week StandAlone (1, 1, Mon, Monday, M, Mo)
13980
13981    case 'c':
13982    case 'cc':
13983      formatter = dateGetter(DateType.Day, 1);
13984      break;
13985
13986    case 'ccc':
13987      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Abbreviated, FormStyle.Standalone);
13988      break;
13989
13990    case 'cccc':
13991      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Wide, FormStyle.Standalone);
13992      break;
13993
13994    case 'ccccc':
13995      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Narrow, FormStyle.Standalone);
13996      break;
13997
13998    case 'cccccc':
13999      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Short, FormStyle.Standalone);
14000      break;
14001    // Day of the Week
14002
14003    case 'E':
14004    case 'EE':
14005    case 'EEE':
14006      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Abbreviated);
14007      break;
14008
14009    case 'EEEE':
14010      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Wide);
14011      break;
14012
14013    case 'EEEEE':
14014      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Narrow);
14015      break;
14016
14017    case 'EEEEEE':
14018      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Short);
14019      break;
14020    // Generic period of the day (am-pm)
14021
14022    case 'a':
14023    case 'aa':
14024    case 'aaa':
14025      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Abbreviated);
14026      break;
14027
14028    case 'aaaa':
14029      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Wide);
14030      break;
14031
14032    case 'aaaaa':
14033      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Narrow);
14034      break;
14035    // Extended period of the day (midnight, at night, ...), standalone
14036
14037    case 'b':
14038    case 'bb':
14039    case 'bbb':
14040      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Abbreviated, FormStyle.Standalone, true);
14041      break;
14042
14043    case 'bbbb':
14044      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Wide, FormStyle.Standalone, true);
14045      break;
14046
14047    case 'bbbbb':
14048      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Narrow, FormStyle.Standalone, true);
14049      break;
14050    // Extended period of the day (midnight, night, ...), standalone
14051
14052    case 'B':
14053    case 'BB':
14054    case 'BBB':
14055      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Abbreviated, FormStyle.Format, true);
14056      break;
14057
14058    case 'BBBB':
14059      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Wide, FormStyle.Format, true);
14060      break;
14061
14062    case 'BBBBB':
14063      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Narrow, FormStyle.Format, true);
14064      break;
14065    // Hour in AM/PM, (1-12)
14066
14067    case 'h':
14068      formatter = dateGetter(DateType.Hours, 1, -12);
14069      break;
14070
14071    case 'hh':
14072      formatter = dateGetter(DateType.Hours, 2, -12);
14073      break;
14074    // Hour of the day (0-23)
14075
14076    case 'H':
14077      formatter = dateGetter(DateType.Hours, 1);
14078      break;
14079    // Hour in day, padded (00-23)
14080
14081    case 'HH':
14082      formatter = dateGetter(DateType.Hours, 2);
14083      break;
14084    // Minute of the hour (0-59)
14085
14086    case 'm':
14087      formatter = dateGetter(DateType.Minutes, 1);
14088      break;
14089
14090    case 'mm':
14091      formatter = dateGetter(DateType.Minutes, 2);
14092      break;
14093    // Second of the minute (0-59)
14094
14095    case 's':
14096      formatter = dateGetter(DateType.Seconds, 1);
14097      break;
14098
14099    case 'ss':
14100      formatter = dateGetter(DateType.Seconds, 2);
14101      break;
14102    // Fractional second
14103
14104    case 'S':
14105      formatter = dateGetter(DateType.FractionalSeconds, 1);
14106      break;
14107
14108    case 'SS':
14109      formatter = dateGetter(DateType.FractionalSeconds, 2);
14110      break;
14111
14112    case 'SSS':
14113      formatter = dateGetter(DateType.FractionalSeconds, 3);
14114      break;
14115    // Timezone ISO8601 short format (-0430)
14116
14117    case 'Z':
14118    case 'ZZ':
14119    case 'ZZZ':
14120      formatter = timeZoneGetter(ZoneWidth.Short);
14121      break;
14122    // Timezone ISO8601 extended format (-04:30)
14123
14124    case 'ZZZZZ':
14125      formatter = timeZoneGetter(ZoneWidth.Extended);
14126      break;
14127    // Timezone GMT short format (GMT+4)
14128
14129    case 'O':
14130    case 'OO':
14131    case 'OOO': // Should be location, but fallback to format O instead because we don't have the data yet
14132
14133    case 'z':
14134    case 'zz':
14135    case 'zzz':
14136      formatter = timeZoneGetter(ZoneWidth.ShortGMT);
14137      break;
14138    // Timezone GMT long format (GMT+0430)
14139
14140    case 'OOOO':
14141    case 'ZZZZ': // Should be location, but fallback to format O instead because we don't have the data yet
14142
14143    case 'zzzz':
14144      formatter = timeZoneGetter(ZoneWidth.Long);
14145      break;
14146
14147    default:
14148      return null;
14149  }
14150
14151  DATE_FORMATS[format] = formatter;
14152  return formatter;
14153}
14154
14155function timezoneToOffset(timezone, fallback) {
14156  // Support: IE 11 only, Edge 13-15+
14157  // IE/Edge do not "understand" colon (`:`) in timezone
14158  timezone = timezone.replace(/:/g, '');
14159  const requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
14160  return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
14161}
14162
14163function addDateMinutes(date, minutes) {
14164  date = new Date(date.getTime());
14165  date.setMinutes(date.getMinutes() + minutes);
14166  return date;
14167}
14168
14169function convertTimezoneToLocal(date, timezone, reverse) {
14170  const reverseValue = reverse ? -1 : 1;
14171  const dateTimezoneOffset = date.getTimezoneOffset();
14172  const timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
14173  return addDateMinutes(date, reverseValue * (timezoneOffset - dateTimezoneOffset));
14174}
14175/**
14176 * Converts a value to date.
14177 *
14178 * Supported input formats:
14179 * - `Date`
14180 * - number: timestamp
14181 * - string: numeric (e.g. "1234"), ISO and date strings in a format supported by
14182 *   [Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).
14183 *   Note: ISO strings without time return a date without timeoffset.
14184 *
14185 * Throws if unable to convert to a date.
14186 */
14187
14188
14189function toDate(value) {
14190  if (isDate(value)) {
14191    return value;
14192  }
14193
14194  if (typeof value === 'number' && !isNaN(value)) {
14195    return new Date(value);
14196  }
14197
14198  if (typeof value === 'string') {
14199    value = value.trim();
14200
14201    if (/^(\d{4}(-\d{1,2}(-\d{1,2})?)?)$/.test(value)) {
14202      /* For ISO Strings without time the day, month and year must be extracted from the ISO String
14203      before Date creation to avoid time offset and errors in the new Date.
14204      If we only replace '-' with ',' in the ISO String ("2015,01,01"), and try to create a new
14205      date, some browsers (e.g. IE 9) will throw an invalid Date error.
14206      If we leave the '-' ("2015-01-01") and try to create a new Date("2015-01-01") the timeoffset
14207      is applied.
14208      Note: ISO months are 0 for January, 1 for February, ... */
14209      const [y, m = 1, d = 1] = value.split('-').map(val => +val);
14210      return createDate(y, m - 1, d);
14211    }
14212
14213    const parsedNb = parseFloat(value); // any string that only contains numbers, like "1234" but not like "1234hello"
14214
14215    if (!isNaN(value - parsedNb)) {
14216      return new Date(parsedNb);
14217    }
14218
14219    let match;
14220
14221    if (match = value.match(ISO8601_DATE_REGEX)) {
14222      return isoStringToDate(match);
14223    }
14224  }
14225
14226  const date = new Date(value);
14227
14228  if (!isDate(date)) {
14229    throw new Error(`Unable to convert "${value}" into a date`);
14230  }
14231
14232  return date;
14233}
14234/**
14235 * Converts a date in ISO8601 to a Date.
14236 * Used instead of `Date.parse` because of browser discrepancies.
14237 */
14238
14239
14240function isoStringToDate(match) {
14241  const date = new Date(0);
14242  let tzHour = 0;
14243  let tzMin = 0; // match[8] means that the string contains "Z" (UTC) or a timezone like "+01:00" or "+0100"
14244
14245  const dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear;
14246  const timeSetter = match[8] ? date.setUTCHours : date.setHours; // if there is a timezone defined like "+01:00" or "+0100"
14247
14248  if (match[9]) {
14249    tzHour = Number(match[9] + match[10]);
14250    tzMin = Number(match[9] + match[11]);
14251  }
14252
14253  dateSetter.call(date, Number(match[1]), Number(match[2]) - 1, Number(match[3]));
14254  const h = Number(match[4] || 0) - tzHour;
14255  const m = Number(match[5] || 0) - tzMin;
14256  const s = Number(match[6] || 0); // The ECMAScript specification (https://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.11)
14257  // defines that `DateTime` milliseconds should always be rounded down, so that `999.9ms`
14258  // becomes `999ms`.
14259
14260  const ms = Math.floor(parseFloat('0.' + (match[7] || 0)) * 1000);
14261  timeSetter.call(date, h, m, s, ms);
14262  return date;
14263}
14264
14265function isDate(value) {
14266  return value instanceof Date && !isNaN(value.valueOf());
14267}
14268/**
14269 * @license
14270 * Copyright Google LLC All Rights Reserved.
14271 *
14272 * Use of this source code is governed by an MIT-style license that can be
14273 * found in the LICENSE file at https://angular.io/license
14274 */
14275
14276
14277const NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;
14278const MAX_DIGITS = 22;
14279const DECIMAL_SEP = '.';
14280const ZERO_CHAR = '0';
14281const PATTERN_SEP = ';';
14282const GROUP_SEP = ',';
14283const DIGIT_CHAR = '#';
14284const CURRENCY_CHAR = '¤';
14285const PERCENT_CHAR = '%';
14286/**
14287 * Transforms a number to a locale string based on a style and a format.
14288 */
14289
14290function formatNumberToLocaleString(value, pattern, locale, groupSymbol, decimalSymbol, digitsInfo, isPercent = false) {
14291  let formattedText = '';
14292  let isZero = false;
14293
14294  if (!isFinite(value)) {
14295    formattedText = getLocaleNumberSymbol(locale, NumberSymbol.Infinity);
14296  } else {
14297    let parsedNumber = parseNumber(value);
14298
14299    if (isPercent) {
14300      parsedNumber = toPercent(parsedNumber);
14301    }
14302
14303    let minInt = pattern.minInt;
14304    let minFraction = pattern.minFrac;
14305    let maxFraction = pattern.maxFrac;
14306
14307    if (digitsInfo) {
14308      const parts = digitsInfo.match(NUMBER_FORMAT_REGEXP);
14309
14310      if (parts === null) {
14311        throw new Error(`${digitsInfo} is not a valid digit info`);
14312      }
14313
14314      const minIntPart = parts[1];
14315      const minFractionPart = parts[3];
14316      const maxFractionPart = parts[5];
14317
14318      if (minIntPart != null) {
14319        minInt = parseIntAutoRadix(minIntPart);
14320      }
14321
14322      if (minFractionPart != null) {
14323        minFraction = parseIntAutoRadix(minFractionPart);
14324      }
14325
14326      if (maxFractionPart != null) {
14327        maxFraction = parseIntAutoRadix(maxFractionPart);
14328      } else if (minFractionPart != null && minFraction > maxFraction) {
14329        maxFraction = minFraction;
14330      }
14331    }
14332
14333    roundNumber(parsedNumber, minFraction, maxFraction);
14334    let digits = parsedNumber.digits;
14335    let integerLen = parsedNumber.integerLen;
14336    const exponent = parsedNumber.exponent;
14337    let decimals = [];
14338    isZero = digits.every(d => !d); // pad zeros for small numbers
14339
14340    for (; integerLen < minInt; integerLen++) {
14341      digits.unshift(0);
14342    } // pad zeros for small numbers
14343
14344
14345    for (; integerLen < 0; integerLen++) {
14346      digits.unshift(0);
14347    } // extract decimals digits
14348
14349
14350    if (integerLen > 0) {
14351      decimals = digits.splice(integerLen, digits.length);
14352    } else {
14353      decimals = digits;
14354      digits = [0];
14355    } // format the integer digits with grouping separators
14356
14357
14358    const groups = [];
14359
14360    if (digits.length >= pattern.lgSize) {
14361      groups.unshift(digits.splice(-pattern.lgSize, digits.length).join(''));
14362    }
14363
14364    while (digits.length > pattern.gSize) {
14365      groups.unshift(digits.splice(-pattern.gSize, digits.length).join(''));
14366    }
14367
14368    if (digits.length) {
14369      groups.unshift(digits.join(''));
14370    }
14371
14372    formattedText = groups.join(getLocaleNumberSymbol(locale, groupSymbol)); // append the decimal digits
14373
14374    if (decimals.length) {
14375      formattedText += getLocaleNumberSymbol(locale, decimalSymbol) + decimals.join('');
14376    }
14377
14378    if (exponent) {
14379      formattedText += getLocaleNumberSymbol(locale, NumberSymbol.Exponential) + '+' + exponent;
14380    }
14381  }
14382
14383  if (value < 0 && !isZero) {
14384    formattedText = pattern.negPre + formattedText + pattern.negSuf;
14385  } else {
14386    formattedText = pattern.posPre + formattedText + pattern.posSuf;
14387  }
14388
14389  return formattedText;
14390}
14391/**
14392 * @ngModule CommonModule
14393 * @description
14394 *
14395 * Formats a number as currency using locale rules.
14396 *
14397 * @param value The number to format.
14398 * @param locale A locale code for the locale format rules to use.
14399 * @param currency A string containing the currency symbol or its name,
14400 * such as "$" or "Canadian Dollar". Used in output string, but does not affect the operation
14401 * of the function.
14402 * @param currencyCode The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)
14403 * currency code, such as `USD` for the US dollar and `EUR` for the euro.
14404 * Used to determine the number of digits in the decimal part.
14405 * @param digitsInfo Decimal representation options, specified by a string in the following format:
14406 * `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`. See `DecimalPipe` for more details.
14407 *
14408 * @returns The formatted currency value.
14409 *
14410 * @see `formatNumber()`
14411 * @see `DecimalPipe`
14412 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
14413 *
14414 * @publicApi
14415 */
14416
14417
14418function formatCurrency(value, locale, currency, currencyCode, digitsInfo) {
14419  const format = getLocaleNumberFormat(locale, NumberFormatStyle.Currency);
14420  const pattern = parseNumberFormat(format, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign));
14421  pattern.minFrac = getNumberOfCurrencyDigits(currencyCode);
14422  pattern.maxFrac = pattern.minFrac;
14423  const res = formatNumberToLocaleString(value, pattern, locale, NumberSymbol.CurrencyGroup, NumberSymbol.CurrencyDecimal, digitsInfo);
14424  return res.replace(CURRENCY_CHAR, currency) // if we have 2 time the currency character, the second one is ignored
14425  .replace(CURRENCY_CHAR, '') // If there is a spacing between currency character and the value and
14426  // the currency character is suppressed by passing an empty string, the
14427  // spacing character would remain as part of the string. Then we
14428  // should remove it.
14429  .trim();
14430}
14431/**
14432 * @ngModule CommonModule
14433 * @description
14434 *
14435 * Formats a number as a percentage according to locale rules.
14436 *
14437 * @param value The number to format.
14438 * @param locale A locale code for the locale format rules to use.
14439 * @param digitsInfo Decimal representation options, specified by a string in the following format:
14440 * `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`. See `DecimalPipe` for more details.
14441 *
14442 * @returns The formatted percentage value.
14443 *
14444 * @see `formatNumber()`
14445 * @see `DecimalPipe`
14446 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
14447 * @publicApi
14448 *
14449 */
14450
14451
14452function formatPercent(value, locale, digitsInfo) {
14453  const format = getLocaleNumberFormat(locale, NumberFormatStyle.Percent);
14454  const pattern = parseNumberFormat(format, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign));
14455  const res = formatNumberToLocaleString(value, pattern, locale, NumberSymbol.Group, NumberSymbol.Decimal, digitsInfo, true);
14456  return res.replace(new RegExp(PERCENT_CHAR, 'g'), getLocaleNumberSymbol(locale, NumberSymbol.PercentSign));
14457}
14458/**
14459 * @ngModule CommonModule
14460 * @description
14461 *
14462 * Formats a number as text, with group sizing, separator, and other
14463 * parameters based on the locale.
14464 *
14465 * @param value The number to format.
14466 * @param locale A locale code for the locale format rules to use.
14467 * @param digitsInfo Decimal representation options, specified by a string in the following format:
14468 * `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`. See `DecimalPipe` for more details.
14469 *
14470 * @returns The formatted text string.
14471 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
14472 *
14473 * @publicApi
14474 */
14475
14476
14477function formatNumber(value, locale, digitsInfo) {
14478  const format = getLocaleNumberFormat(locale, NumberFormatStyle.Decimal);
14479  const pattern = parseNumberFormat(format, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign));
14480  return formatNumberToLocaleString(value, pattern, locale, NumberSymbol.Group, NumberSymbol.Decimal, digitsInfo);
14481}
14482
14483function parseNumberFormat(format, minusSign = '-') {
14484  const p = {
14485    minInt: 1,
14486    minFrac: 0,
14487    maxFrac: 0,
14488    posPre: '',
14489    posSuf: '',
14490    negPre: '',
14491    negSuf: '',
14492    gSize: 0,
14493    lgSize: 0
14494  };
14495  const patternParts = format.split(PATTERN_SEP);
14496  const positive = patternParts[0];
14497  const negative = patternParts[1];
14498  const positiveParts = positive.indexOf(DECIMAL_SEP) !== -1 ? positive.split(DECIMAL_SEP) : [positive.substring(0, positive.lastIndexOf(ZERO_CHAR) + 1), positive.substring(positive.lastIndexOf(ZERO_CHAR) + 1)],
14499        integer = positiveParts[0],
14500        fraction = positiveParts[1] || '';
14501  p.posPre = integer.substring(0, integer.indexOf(DIGIT_CHAR));
14502
14503  for (let i = 0; i < fraction.length; i++) {
14504    const ch = fraction.charAt(i);
14505
14506    if (ch === ZERO_CHAR) {
14507      p.minFrac = p.maxFrac = i + 1;
14508    } else if (ch === DIGIT_CHAR) {
14509      p.maxFrac = i + 1;
14510    } else {
14511      p.posSuf += ch;
14512    }
14513  }
14514
14515  const groups = integer.split(GROUP_SEP);
14516  p.gSize = groups[1] ? groups[1].length : 0;
14517  p.lgSize = groups[2] || groups[1] ? (groups[2] || groups[1]).length : 0;
14518
14519  if (negative) {
14520    const trunkLen = positive.length - p.posPre.length - p.posSuf.length,
14521          pos = negative.indexOf(DIGIT_CHAR);
14522    p.negPre = negative.substring(0, pos).replace(/'/g, '');
14523    p.negSuf = negative.slice(pos + trunkLen).replace(/'/g, '');
14524  } else {
14525    p.negPre = minusSign + p.posPre;
14526    p.negSuf = p.posSuf;
14527  }
14528
14529  return p;
14530} // Transforms a parsed number into a percentage by multiplying it by 100
14531
14532
14533function toPercent(parsedNumber) {
14534  // if the number is 0, don't do anything
14535  if (parsedNumber.digits[0] === 0) {
14536    return parsedNumber;
14537  } // Getting the current number of decimals
14538
14539
14540  const fractionLen = parsedNumber.digits.length - parsedNumber.integerLen;
14541
14542  if (parsedNumber.exponent) {
14543    parsedNumber.exponent += 2;
14544  } else {
14545    if (fractionLen === 0) {
14546      parsedNumber.digits.push(0, 0);
14547    } else if (fractionLen === 1) {
14548      parsedNumber.digits.push(0);
14549    }
14550
14551    parsedNumber.integerLen += 2;
14552  }
14553
14554  return parsedNumber;
14555}
14556/**
14557 * Parses a number.
14558 * Significant bits of this parse algorithm came from https://github.com/MikeMcl/big.js/
14559 */
14560
14561
14562function parseNumber(num) {
14563  let numStr = Math.abs(num) + '';
14564  let exponent = 0,
14565      digits,
14566      integerLen;
14567  let i, j, zeros; // Decimal point?
14568
14569  if ((integerLen = numStr.indexOf(DECIMAL_SEP)) > -1) {
14570    numStr = numStr.replace(DECIMAL_SEP, '');
14571  } // Exponential form?
14572
14573
14574  if ((i = numStr.search(/e/i)) > 0) {
14575    // Work out the exponent.
14576    if (integerLen < 0) integerLen = i;
14577    integerLen += +numStr.slice(i + 1);
14578    numStr = numStr.substring(0, i);
14579  } else if (integerLen < 0) {
14580    // There was no decimal point or exponent so it is an integer.
14581    integerLen = numStr.length;
14582  } // Count the number of leading zeros.
14583
14584
14585  for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) {
14586    /* empty */
14587  }
14588
14589  if (i === (zeros = numStr.length)) {
14590    // The digits are all zero.
14591    digits = [0];
14592    integerLen = 1;
14593  } else {
14594    // Count the number of trailing zeros
14595    zeros--;
14596
14597    while (numStr.charAt(zeros) === ZERO_CHAR) zeros--; // Trailing zeros are insignificant so ignore them
14598
14599
14600    integerLen -= i;
14601    digits = []; // Convert string to array of digits without leading/trailing zeros.
14602
14603    for (j = 0; i <= zeros; i++, j++) {
14604      digits[j] = Number(numStr.charAt(i));
14605    }
14606  } // If the number overflows the maximum allowed digits then use an exponent.
14607
14608
14609  if (integerLen > MAX_DIGITS) {
14610    digits = digits.splice(0, MAX_DIGITS - 1);
14611    exponent = integerLen - 1;
14612    integerLen = 1;
14613  }
14614
14615  return {
14616    digits,
14617    exponent,
14618    integerLen
14619  };
14620}
14621/**
14622 * Round the parsed number to the specified number of decimal places
14623 * This function changes the parsedNumber in-place
14624 */
14625
14626
14627function roundNumber(parsedNumber, minFrac, maxFrac) {
14628  if (minFrac > maxFrac) {
14629    throw new Error(`The minimum number of digits after fraction (${minFrac}) is higher than the maximum (${maxFrac}).`);
14630  }
14631
14632  let digits = parsedNumber.digits;
14633  let fractionLen = digits.length - parsedNumber.integerLen;
14634  const fractionSize = Math.min(Math.max(minFrac, fractionLen), maxFrac); // The index of the digit to where rounding is to occur
14635
14636  let roundAt = fractionSize + parsedNumber.integerLen;
14637  let digit = digits[roundAt];
14638
14639  if (roundAt > 0) {
14640    // Drop fractional digits beyond `roundAt`
14641    digits.splice(Math.max(parsedNumber.integerLen, roundAt)); // Set non-fractional digits beyond `roundAt` to 0
14642
14643    for (let j = roundAt; j < digits.length; j++) {
14644      digits[j] = 0;
14645    }
14646  } else {
14647    // We rounded to zero so reset the parsedNumber
14648    fractionLen = Math.max(0, fractionLen);
14649    parsedNumber.integerLen = 1;
14650    digits.length = Math.max(1, roundAt = fractionSize + 1);
14651    digits[0] = 0;
14652
14653    for (let i = 1; i < roundAt; i++) digits[i] = 0;
14654  }
14655
14656  if (digit >= 5) {
14657    if (roundAt - 1 < 0) {
14658      for (let k = 0; k > roundAt; k--) {
14659        digits.unshift(0);
14660        parsedNumber.integerLen++;
14661      }
14662
14663      digits.unshift(1);
14664      parsedNumber.integerLen++;
14665    } else {
14666      digits[roundAt - 1]++;
14667    }
14668  } // Pad out with zeros to get the required fraction length
14669
14670
14671  for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
14672
14673  let dropTrailingZeros = fractionSize !== 0; // Minimal length = nb of decimals required + current nb of integers
14674  // Any number besides that is optional and can be removed if it's a trailing 0
14675
14676  const minLen = minFrac + parsedNumber.integerLen; // Do any carrying, e.g. a digit was rounded up to 10
14677
14678  const carry = digits.reduceRight(function (carry, d, i, digits) {
14679    d = d + carry;
14680    digits[i] = d < 10 ? d : d - 10; // d % 10
14681
14682    if (dropTrailingZeros) {
14683      // Do not keep meaningless fractional trailing zeros (e.g. 15.52000 --> 15.52)
14684      if (digits[i] === 0 && i >= minLen) {
14685        digits.pop();
14686      } else {
14687        dropTrailingZeros = false;
14688      }
14689    }
14690
14691    return d >= 10 ? 1 : 0; // Math.floor(d / 10);
14692  }, 0);
14693
14694  if (carry) {
14695    digits.unshift(carry);
14696    parsedNumber.integerLen++;
14697  }
14698}
14699
14700function parseIntAutoRadix(text) {
14701  const result = parseInt(text);
14702
14703  if (isNaN(result)) {
14704    throw new Error('Invalid integer literal when parsing ' + text);
14705  }
14706
14707  return result;
14708}
14709/**
14710 * @license
14711 * Copyright Google LLC All Rights Reserved.
14712 *
14713 * Use of this source code is governed by an MIT-style license that can be
14714 * found in the LICENSE file at https://angular.io/license
14715 */
14716
14717/**
14718 * @publicApi
14719 */
14720
14721
14722class NgLocalization {}
14723
14724NgLocalization.ɵfac = function NgLocalization_Factory(t) {
14725  return new (t || NgLocalization)();
14726};
14727
14728NgLocalization.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
14729  token: NgLocalization,
14730  factory: function NgLocalization_Factory(t) {
14731    let r = null;
14732
14733    if (t) {
14734      r = new t();
14735    } else {
14736      r = (locale =>
14736 new NgLocaleLocalization(locale))(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID));
14737    }
14738
14739    return r;
14740  },
14741  providedIn: 'root'
14742});
14743
14744(function () {
14745  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgLocalization, [{
14746    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
14747    args: [{
14748      providedIn: 'root',
14749      useFactory: locale => new NgLocaleLocalization(locale),
14750      deps: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
14751    }]
14752  }], null, null);
14753})();
14754/**
14755 * Returns the plural category for a given value.
14756 * - "=value" when the case exists,
14757 * - the plural category otherwise
14758 */
14759
14760
14761function getPluralCategory(value, cases, ngLocalization, locale) {
14762  let key = `=${value}`;
14763
14764  if (cases.indexOf(key) > -1) {
14765    return key;
14766  }
14767
14768  key = ngLocalization.getPluralCategory(value, locale);
14769
14770  if (cases.indexOf(key) > -1) {
14771    return key;
14772  }
14773
14774  if (cases.indexOf('other') > -1) {
14775    return 'other';
14776  }
14777
14778  throw new Error(`No plural message found for value "${value}"`);
14779}
14780/**
14781 * Returns the plural case based on the locale
14782 *
14783 * @publicApi
14784 */
14785
14786
14787class NgLocaleLocalization extends NgLocalization {
14788  constructor(locale) {
14789    super();
14790    this.locale = locale;
14791  }
14792
14793  getPluralCategory(value, locale) {
14794    const plural = getLocalePluralCase(locale || this.locale)(value);
14795
14796    switch (plural) {
14797      case Plural.Zero:
14798        return 'zero';
14799
14800      case Plural.One:
14801        return 'one';
14802
14803      case Plural.Two:
14804        return 'two';
14805
14806      case Plural.Few:
14807        return 'few';
14808
14809      case Plural.Many:
14810        return 'many';
14811
14812      default:
14813        return 'other';
14814    }
14815  }
14816
14817}
14818
14819NgLocaleLocalization.ɵfac = function NgLocaleLocalization_Factory(t) {
14820  return new (t || NgLocaleLocalization)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID));
14821};
14822
14823NgLocaleLocalization.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
14824  token: NgLocaleLocalization,
14825  factory: NgLocaleLocalization.ɵfac
14826});
14827
14828(function () {
14829  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgLocaleLocalization, [{
14830    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
14831  }], function () {
14832    return [{
14833      type: undefined,
14834      decorators: [{
14835        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
14836        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
14837      }]
14838    }];
14839  }, null);
14840})();
14841/**
14842 * @license
14843 * Copyright Google LLC All Rights Reserved.
14844 *
14845 * Use of this source code is governed by an MIT-style license that can be
14846 * found in the LICENSE file at https://angular.io/license
14847 */
14848
14849/**
14850 * Register global data to be used internally by Angular. See the
14851 * ["I18n guide"](guide/i18n-common-format-data-locale) to know how to import additional locale
14852 * data.
14853 *
14854 * The signature registerLocaleData(data: any, extraData?: any) is deprecated since v5.1
14855 *
14856 * @publicApi
14857 */
14858
14859
14860function registerLocaleData(data, localeId, extraData) {
14861  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵregisterLocaleData"])(data, localeId, extraData);
14862}
14863/**
14864 * @license
14865 * Copyright Google LLC All Rights Reserved.
14866 *
14867 * Use of this source code is governed by an MIT-style license that can be
14868 * found in the LICENSE file at https://angular.io/license
14869 */
14870
14871
14872function parseCookieValue(cookieStr, name) {
14873  name = encodeURIComponent(name);
14874
14875  for (const cookie of cookieStr.split(';')) {
14876    const eqIndex = cookie.indexOf('=');
14877    const [cookieName, cookieValue] = eqIndex == -1 ? [cookie, ''] : [cookie.slice(0, eqIndex), cookie.slice(eqIndex + 1)];
14878
14879    if (cookieName.trim() === name) {
14880      return decodeURIComponent(cookieValue);
14881    }
14882  }
14883
14884  return null;
14885}
14886/**
14887 * @license
14888 * Copyright Google LLC All Rights Reserved.
14889 *
14890 * Use of this source code is governed by an MIT-style license that can be
14891 * found in the LICENSE file at https://angular.io/license
14892 */
14893
14894/**
14895 * @ngModule CommonModule
14896 *
14897 * @usageNotes
14898 * ```
14899 *     <some-element [ngClass]="'first second'">...</some-element>
14900 *
14901 *     <some-element [ngClass]="['first', 'second']">...</some-element>
14902 *
14903 *     <some-element [ngClass]="{'first': true, 'second': true, 'third': false}">...</some-element>
14904 *
14905 *     <some-element [ngClass]="stringExp|arrayExp|objExp">...</some-element>
14906 *
14907 *     <some-element [ngClass]="{'class1 class2 class3' : true}">...</some-element>
14908 * ```
14909 *
14910 * @description
14911 *
14912 * Adds and removes CSS classes on an HTML element.
14913 *
14914 * The CSS classes are updated as follows, depending on the type of the expression evaluation:
14915 * - `string` - the CSS classes listed in the string (space delimited) are added,
14916 * - `Array` - the CSS classes declared as Array elements are added,
14917 * - `Object` - keys are CSS classes that get added when the expression given in the value
14918 *              evaluates to a truthy value, otherwise they are removed.
14919 *
14920 * @publicApi
14921 */
14922
14923
14924class NgClass {
14925  constructor(_iterableDiffers, _keyValueDiffers, _ngEl, _renderer) {
14926    this._iterableDiffers = _iterableDiffers;
14927    this._keyValueDiffers = _keyValueDiffers;
14928    this._ngEl = _ngEl;
14929    this._renderer = _renderer;
14930    this._iterableDiffer = null;
14931    this._keyValueDiffer = null;
14932    this._initialClasses = [];
14933    this._rawClass = null;
14934  }
14935
14936  set klass(value) {
14937    this._removeClasses(this._initialClasses);
14938
14939    this._initialClasses = typeof value === 'string' ? value.split(/\s+/) : [];
14940
14941    this._applyClasses(this._initialClasses);
14942
14943    this._applyClasses(this._rawClass);
14944  }
14945
14946  set ngClass(value) {
14947    this._removeClasses(this._rawClass);
14948
14949    this._applyClasses(this._initialClasses);
14950
14951    this._iterableDiffer = null;
14952    this._keyValueDiffer = null;
14953    this._rawClass = typeof value === 'string' ? value.split(/\s+/) : value;
14954
14955    if (this._rawClass) {
14956      if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisListLikeIterable"])(this._rawClass)) {
14957        this._iterableDiffer = this._iterableDiffers.find(this._rawClass).create();
14958      } else {
14959        this._keyValueDiffer = this._keyValueDiffers.find(this._rawClass).create();
14960      }
14961    }
14962  }
14963
14964  ngDoCheck() {
14965    if (this._iterableDiffer) {
14966      const iterableChanges = this._iterableDiffer.diff(this._rawClass);
14967
14968      if (iterableChanges) {
14969        this._applyIterableChanges(iterableChanges);
14970      }
14971    } else if (this._keyValueDiffer) {
14972      const keyValueChanges = this._keyValueDiffer.diff(this._rawClass);
14973
14974      if (keyValueChanges) {
14975        this._applyKeyValueChanges(keyValueChanges);
14976      }
14977    }
14978  }
14979
14980  _applyKeyValueChanges(changes) {
14981    changes.forEachAddedItem(record => this._toggleClass(record.key, record.currentValue));
14982    changes.forEachChangedItem(record => this._toggleClass(record.key, record.currentValue));
14983    changes.forEachRemovedItem(record => {
14984      if (record.previousValue) {
14985        this._toggleClass(record.key, false);
14986      }
14987    });
14988  }
14989
14990  _applyIterableChanges(changes) {
14991    changes.forEachAddedItem(record => {
14992      if (typeof record.item === 'string') {
14993        this._toggleClass(record.item, true);
14994      } else {
14995        throw new Error(`NgClass can only toggle CSS classes expressed as strings, got ${(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵstringify"])(record.item)}`);
14996      }
14997    });
14998    changes.forEachRemovedItem(record => this._toggleClass(record.item, false));
14999  }
15000  /**
15001   * Applies a collection of CSS classes to the DOM element.
15002   *
15003   * For argument of type Set and Array CSS class names contained in those collections are always
15004   * added.
15005   * For argument of type Map CSS class name in the map's key is toggled based on the value (added
15006   * for truthy and removed for falsy).
15007   */
15008
15009
15010  _applyClasses(rawClassVal) {
15011    if (rawClassVal) {
15012      if (Array.isArray(rawClassVal) || rawClassVal instanceof Set) {
15013        rawClassVal.forEach(klass => this._toggleClass(klass, true));
15014      } else {
15015        Object.keys(rawClassVal).forEach(klass => this._toggleClass(klass, !!rawClassVal[klass]));
15016      }
15017    }
15018  }
15019  /**
15020   * Removes a collection of CSS classes from the DOM element. This is mostly useful for cleanup
15021   * purposes.
15022   */
15023
15024
15025  _removeClasses(rawClassVal) {
15026    if (rawClassVal) {
15027      if (Array.isArray(rawClassVal) || rawClassVal instanceof Set) {
15028        rawClassVal.forEach(klass => this._toggleClass(klass, false));
15029      } else {
15030        Object.keys(rawClassVal).forEach(klass => this._toggleClass(klass, false));
15031      }
15032    }
15033  }
15034
15035  _toggleClass(klass, enabled) {
15036    klass = klass.trim();
15037
15038    if (klass) {
15039      klass.split(/\s+/g).forEach(klass => {
15040        if (enabled) {
15041          this._renderer.addClass(this._ngEl.nativeElement, klass);
15042        } else {
15043          this._renderer.removeClass(this._ngEl.nativeElement, klass);
15044        }
15045      });
15046    }
15047  }
15048
15049}
15050
15051NgClass.ɵfac = function NgClass_Factory(t) {
15052  return new (t || NgClass)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.IterableDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2));
15053};
15054
15055NgClass.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
15056  type: NgClass,
15057  selectors: [["", "ngClass", ""]],
15058  inputs: {
15059    klass: ["class", "klass"],
15060    ngClass: "ngClass"
15061  },
15062  standalone: true
15063});
15064
15065(function () {
15066  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgClass, [{
15067    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
15068    args: [{
15069      selector: '[ngClass]',
15070      standalone: true
15071    }]
15072  }], function () {
15073    return [{
15074      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.IterableDiffers
15075    }, {
15076      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers
15077    }, {
15078      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
15079    }, {
15080      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
15081    }];
15082  }, {
15083    klass: [{
15084      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
15085      args: ['class']
15086    }],
15087    ngClass: [{
15088      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
15089      args: ['ngClass']
15090    }]
15091  });
15092})();
15093/**
15094 * @license
15095 * Copyright Google LLC All Rights Reserved.
15096 *
15097 * Use of this source code is governed by an MIT-style license that can be
15098 * found in the LICENSE file at https://angular.io/license
15099 */
15100
15101/**
15102 * Instantiates a {@link Component} type and inserts its Host View into the current View.
15103 * `NgComponentOutlet` provides a declarative approach for dynamic component creation.
15104 *
15105 * `NgComponentOutlet` requires a component type, if a falsy value is set the view will clear and
15106 * any existing component will be destroyed.
15107 *
15108 * @usageNotes
15109 *
15110 * ### Fine tune control
15111 *
15112 * You can control the component creation process by using the following optional attributes:
15113 *
15114 * * `ngComponentOutletInjector`: Optional custom {@link Injector} that will be used as parent for
15115 * the Component. Defaults to the injector of the current view container.
15116 *
15117 * * `ngComponentOutletContent`: Optional list of projectable nodes to insert into the content
15118 * section of the component, if it exists.
15119 *
15120 * * `ngComponentOutletNgModule`: Optional NgModule class reference to allow loading another
15121 * module dynamically, then loading a component from that module.
15122 *
15123 * * `ngComponentOutletNgModuleFactory`: Deprecated config option that allows providing optional
15124 * NgModule factory to allow loading another module dynamically, then loading a component from that
15125 * module. Use `ngComponentOutletNgModule` instead.
15126 *
15127 * ### Syntax
15128 *
15129 * Simple
15130 * ```
15131 * <ng-container *ngComponentOutlet="componentTypeExpression"></ng-container>
15132 * ```
15133 *
15134 * Customized injector/content
15135 * ```
15136 * <ng-container *ngComponentOutlet="componentTypeExpression;
15137 *                                   injector: injectorExpression;
15138 *                                   content: contentNodesExpression;">
15139 * </ng-container>
15140 * ```
15141 *
15142 * Customized NgModule reference
15143 * ```
15144 * <ng-container *ngComponentOutlet="componentTypeExpression;
15145 *                                   ngModule: ngModuleClass;">
15146 * </ng-container>
15147 * ```
15148 *
15149 * ### A simple example
15150 *
15151 * {@example common/ngComponentOutlet/ts/module.ts region='SimpleExample'}
15152 *
15153 * A more complete example with additional options:
15154 *
15155 * {@example common/ngComponentOutlet/ts/module.ts region='CompleteExample'}
15156 *
15157 * @publicApi
15158 * @ngModule CommonModule
15159 */
15160
15161
15162class NgComponentOutlet {
15163  constructor(_viewContainerRef) {
15164    this._viewContainerRef = _viewContainerRef;
15165    this.ngComponentOutlet = null;
15166  }
15167  /** @nodoc */
15168
15169
15170  ngOnChanges(changes) {
15171    const {
15172      _viewContainerRef: viewContainerRef,
15173      ngComponentOutletNgModule: ngModule,
15174      ngComponentOutletNgModuleFactory: ngModuleFactory
15175    } = this;
15176    viewContainerRef.clear();
15177    this._componentRef = undefined;
15178
15179    if (this.ngComponentOutlet) {
15180      const injector = this.ngComponentOutletInjector || viewContainerRef.parentInjector;
15181
15182      if (changes['ngComponentOutletNgModule'] || changes['ngComponentOutletNgModuleFactory']) {
15183        if (this._moduleRef) this._moduleRef.destroy();
15184
15185        if (ngModule) {
15186          this._moduleRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createNgModule)(ngModule, getParentInjector(injector));
15187        } else if (ngModuleFactory) {
15188          this._moduleRef = ngModuleFactory.create(getParentInjector(injector));
15189        } else {
15190          this._moduleRef = undefined;
15191        }
15192      }
15193
15194      this._componentRef = viewContainerRef.createComponent(this.ngComponentOutlet, {
15195        index: viewContainerRef.length,
15196        injector,
15197        ngModuleRef: this._moduleRef,
15198        projectableNodes: this.ngComponentOutletContent
15199      });
15200    }
15201  }
15202  /** @nodoc */
15203
15204
15205  ngOnDestroy() {
15206    if (this._moduleRef) this._moduleRef.destroy();
15207  }
15208
15209}
15210
15211NgComponentOutlet.ɵfac = function NgComponentOutlet_Factory(t) {
15212  return new (t || NgComponentOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef));
15213};
15214
15215NgComponentOutlet.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
15216  type: NgComponentOutlet,
15217  selectors: [["", "ngComponentOutlet", ""]],
15218  inputs: {
15219    ngComponentOutlet: "ngComponentOutlet",
15220    ngComponentOutletInjector: "ngComponentOutletInjector",
15221    ngComponentOutletContent: "ngComponentOutletContent",
15222    ngComponentOutletNgModule: "ngComponentOutletNgModule",
15223    ngComponentOutletNgModuleFactory: "ngComponentOutletNgModuleFactory"
15224  },
15225  standalone: true,
15226  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
15227});
15228
15229(function () {
15230  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgComponentOutlet, [{
15231    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
15232    args: [{
15233      selector: '[ngComponentOutlet]',
15234      standalone: true
15235    }]
15236  }], function () {
15237    return [{
15238      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
15239    }];
15240  }, {
15241    ngComponentOutlet: [{
15242      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15243    }],
15244    ngComponentOutletInjector: [{
15245      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15246    }],
15247    ngComponentOutletContent: [{
15248      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15249    }],
15250    ngComponentOutletNgModule: [{
15251      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15252    }],
15253    ngComponentOutletNgModuleFactory: [{
15254      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15255    }]
15256  });
15257})(); // Helper function that returns an Injector instance of a parent NgModule.
15258
15259
15260function getParentInjector(injector) {
15261  const parentNgModule = injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModuleRef);
15262  return parentNgModule.injector;
15263}
15264/**
15265 * @license
15266 * Copyright Google LLC All Rights Reserved.
15267 *
15268 * Use of this source code is governed by an MIT-style license that can be
15269 * found in the LICENSE file at https://angular.io/license
15270 */
15271
15272
15273const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
15274/**
15275 * @publicApi
15276 */
15277
15278class NgForOfContext {
15279  constructor($implicit, ngForOf, index, count) {
15280    this.$implicit = $implicit;
15281    this.ngForOf = ngForOf;
15282    this.index = index;
15283    this.count = count;
15284  }
15285
15286  get first() {
15287    return this.index === 0;
15288  }
15289
15290  get last() {
15291    return this.index === this.count - 1;
15292  }
15293
15294  get even() {
15295    return this.index % 2 === 0;
15296  }
15297
15298  get odd() {
15299    return !this.even;
15300  }
15301
15302}
15303/**
15304 * A [structural directive](guide/structural-directives) that renders
15305 * a template for each item in a collection.
15306 * The directive is placed on an element, which becomes the parent
15307 * of the cloned templates.
15308 *
15309 * The `ngForOf` directive is generally used in the
15310 * [shorthand form](guide/structural-directives#asterisk) `*ngFor`.
15311 * In this form, the template to be rendered for each iteration is the content
15312 * of an anchor element containing the directive.
15313 *
15314 * The following example shows the shorthand syntax with some options,
15315 * contained in an `<li>` element.
15316 *
15317 * ```
15318 * <li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>
15319 * ```
15320 *
15321 * The shorthand form expands into a long form that uses the `ngForOf` selector
15322 * on an `<ng-template>` element.
15323 * The content of the `<ng-template>` element is the `<li>` element that held the
15324 * short-form directive.
15325 *
15326 * Here is the expanded version of the short-form example.
15327 *
15328 * ```
15329 * <ng-template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
15330 *   <li>...</li>
15331 * </ng-template>
15332 * ```
15333 *
15334 * Angular automatically expands the shorthand syntax as it compiles the template.
15335 * The context for each embedded view is logically merged to the current component
15336 * context according to its lexical position.
15337 *
15338 * When using the shorthand syntax, Angular allows only [one structural directive
15339 * on an element](guide/structural-directives#one-per-element).
15340 * If you want to iterate conditionally, for example,
15341 * put the `*ngIf` on a container element that wraps the `*ngFor` element.
15342 * For further discussion, see
15343 * [Structural Directives](guide/structural-directives#one-per-element).
15344 *
15345 * @usageNotes
15346 *
15347 * ### Local variables
15348 *
15349 * `NgForOf` provides exported values that can be aliased to local variables.
15350 * For example:
15351 *
15352 *  ```
15353 * <li *ngFor="let user of users; index as i; first as isFirst">
15354 *    {{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
15355 * </li>
15356 * ```
15357 *
15358 * The following exported values can be aliased to local variables:
15359 *
15360 * - `$implicit: T`: The value of the individual items in the iterable (`ngForOf`).
15361 * - `ngForOf: NgIterable<T>`: The value of the iterable expression. Useful when the expression is
15362 * more complex then a property access, for example when using the async pipe (`userStreams |
15363 * async`).
15364 * - `index: number`: The index of the current item in the iterable.
15365 * - `count: number`: The length of the iterable.
15366 * - `first: boolean`: True when the item is the first item in the iterable.
15367 * - `last: boolean`: True when the item is the last item in the iterable.
15368 * - `even: boolean`: True when the item has an even index in the iterable.
15369 * - `odd: boolean`: True when the item has an odd index in the iterable.
15370 *
15371 * ### Change propagation
15372 *
15373 * When the contents of the iterator changes, `NgForOf` makes the corresponding changes to the DOM:
15374 *
15375 * * When an item is added, a new instance of the template is added to the DOM.
15376 * * When an item is removed, its template instance is removed from the DOM.
15377 * * When items are reordered, their respective templates are reordered in the DOM.
15378 *
15379 * Angular uses object identity to track insertions and deletions within the iterator and reproduce
15380 * those changes in the DOM. This has important implications for animations and any stateful
15381 * controls that are present, such as `<input>` elements that accept user input. Inserted rows can
15382 * be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state
15383 * such as user input.
15384 * For more on animations, see [Transitions and Triggers](guide/transition-and-triggers).
15385 *
15386 * The identities of elements in the iterator can change while the data does not.
15387 * This can happen, for example, if the iterator is produced from an RPC to the server, and that
15388 * RPC is re-run. Even if the data hasn't changed, the second response produces objects with
15389 * different identities, and Angular must tear down the entire DOM and rebuild it (as if all old
15390 * elements were deleted and all new elements inserted).
15391 *
15392 * To avoid this expensive operation, you can customize the default tracking algorithm.
15393 * by supplying the `trackBy` option to `NgForOf`.
15394 * `trackBy` takes a function that has two arguments: `index` and `item`.
15395 * If `trackBy` is given, Angular tracks changes by the return value of the function.
15396 *
15397 * @see [Structural Directives](guide/structural-directives)
15398 * @ngModule CommonModule
15399 * @publicApi
15400 */
15401
15402
15403class NgForOf {
15404  constructor(_viewContainer, _template, _differs) {
15405    this._viewContainer = _viewContainer;
15406    this._template = _template;
15407    this._differs = _differs;
15408    this._ngForOf = null;
15409    this._ngForOfDirty = true;
15410    this._differ = null;
15411  }
15412  /**
15413   * The value of the iterable expression, which can be used as a
15414   * [template input variable](guide/structural-directives#shorthand).
15415   */
15416
15417
15418  set ngForOf(ngForOf) {
15419    this._ngForOf = ngForOf;
15420    this._ngForOfDirty = true;
15421  }
15422  /**
15423   * Specifies a custom `TrackByFunction` to compute the identity of items in an iterable.
15424   *
15425   * If a custom `TrackByFunction` is not provided, `NgForOf` will use the item's [object
15426   * identity](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)
15427   * as the key.
15428   *
15429   * `NgForOf` uses the computed key to associate items in an iterable with DOM elements
15430   * it produces for these items.
15431   *
15432   * A custom `TrackByFunction` is useful to provide good user experience in cases when items in an
15433   * iterable rendered using `NgForOf` have a natural identifier (for example, custom ID or a
15434   * primary key), and this iterable could be updated with new object instances that still
15435   * represent the same underlying entity (for example, when data is re-fetched from the server,
15436   * and the iterable is recreated and re-rendered, but most of the data is still the same).
15437   *
15438   * @see `TrackByFunction`
15439   */
15440
15441
15442  set ngForTrackBy(fn) {
15443    if (NG_DEV_MODE && fn != null && typeof fn !== 'function') {
15444      // TODO(vicb): use a log service once there is a public one available
15445      if (console && console.warn) {
15446        console.warn(`trackBy must be a function, but received ${JSON.stringify(fn)}. ` + `See https://angular.io/api/common/NgForOf#change-propagation for more information.`);
15447      }
15448    }
15449
15450    this._trackByFn = fn;
15451  }
15452
15453  get ngForTrackBy() {
15454    return this._trackByFn;
15455  }
15456  /**
15457   * A reference to the template that is stamped out for each item in the iterable.
15458   * @see [template reference variable](guide/template-reference-variables)
15459   */
15460
15461
15462  set ngForTemplate(value) {
15463    // TODO(TS2.1): make TemplateRef<Partial<NgForRowOf<T>>> once we move to TS v2.1
15464    // The current type is too restrictive; a template that just uses index, for example,
15465    // should be acceptable.
15466    if (value) {
15467      this._template = value;
15468    }
15469  }
15470  /**
15471   * Applies the changes when needed.
15472   * @nodoc
15473   */
15474
15475
15476  ngDoCheck() {
15477    if (this._ngForOfDirty) {
15478      this._ngForOfDirty = false; // React on ngForOf changes only once all inputs have been initialized
15479
15480      const value = this._ngForOf;
15481
15482      if (!this._differ && value) {
15483        if (NG_DEV_MODE) {
15484          try {
15485            // CAUTION: this logic is duplicated for production mode below, as the try-catch
15486            // is only present in development builds.
15487            this._differ = this._differs.find(value).create(this.ngForTrackBy);
15488          } catch {
15489            let errorMessage = `Cannot find a differ supporting object '${value}' of type '` + `${getTypeName(value)}'. NgFor only supports binding to Iterables, such as Arrays.`;
15490
15491            if (typeof value === 'object') {
15492              errorMessage += ' Did you mean to use the keyvalue pipe?';
15493            }
15494
15495            throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](-2200
15496            /* RuntimeErrorCode.NG_FOR_MISSING_DIFFER */
15497            , errorMessage);
15498          }
15499        } else {
15500          // CAUTION: this logic is duplicated for development mode above, as the try-catch
15501          // is only present in development builds.
15502          this._differ = this._differs.find(value).create(this.ngForTrackBy);
15503        }
15504      }
15505    }
15506
15507    if (this._differ) {
15508      const changes = this._differ.diff(this._ngForOf);
15509
15510      if (changes) this._applyChanges(changes);
15511    }
15512  }
15513
15514  _applyChanges(changes) {
15515    const viewContainer = this._viewContainer;
15516    changes.forEachOperation((item, adjustedPreviousIndex, currentIndex) => {
15517      if (item.previousIndex == null) {
15518        // NgForOf is never "null" or "undefined" here because the differ detected
15519        // that a new item needs to be inserted from the iterable. This implies that
15520        // there is an iterable value for "_ngForOf".
15521        viewContainer.createEmbeddedView(this._template, new NgForOfContext(item.item, this._ngForOf, -1, -1), currentIndex === null ? undefined : currentIndex);
15522      } else if (currentIndex == null) {
15523        viewContainer.remove(adjustedPreviousIndex === null ? undefined : adjustedPreviousIndex);
15524      } else if (adjustedPreviousIndex !== null) {
15525        const view = viewContainer.get(adjustedPreviousIndex);
15526        viewContainer.move(view, currentIndex);
15527        applyViewChange(view, item);
15528      }
15529    });
15530
15531    for (let i = 0, ilen = viewContainer.length; i < ilen; i++) {
15532      const viewRef = viewContainer.get(i);
15533      const context = viewRef.context;
15534      context.index = i;
15535      context.count = ilen;
15536      context.ngForOf = this._ngForOf;
15537    }
15538
15539    changes.forEachIdentityChange(record => {
15540      const viewRef = viewContainer.get(record.currentIndex);
15541      applyViewChange(viewRef, record);
15542    });
15543  }
15544  /**
15545   * Asserts the correct type of the context for the template that `NgForOf` will render.
15546   *
15547   * The presence of this method is a signal to the Ivy template type-check compiler that the
15548   * `NgForOf` structural directive renders its template with a specific context type.
15549   */
15550
15551
15552  static ngTemplateContextGuard(dir, ctx) {
15553    return true;
15554  }
15555
15556}
15557
15558NgForOf.ɵfac = function NgForOf_Factory(t) {
15559  return new (t || NgForOf)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.IterableDiffers));
15560};
15561
15562NgForOf.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
15563  type: NgForOf,
15564  selectors: [["", "ngFor", "", "ngForOf", ""]],
15565  inputs: {
15566    ngForOf: "ngForOf",
15567    ngForTrackBy: "ngForTrackBy",
15568    ngForTemplate: "ngForTemplate"
15569  },
15570  standalone: true
15571});
15572
15573(function () {
15574  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgForOf, [{
15575    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
15576    args: [{
15577      selector: '[ngFor][ngForOf]',
15578      standalone: true
15579    }]
15580  }], function () {
15581    return [{
15582      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
15583    }, {
15584      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
15585    }, {
15586      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.IterableDiffers
15587    }];
15588  }, {
15589    ngForOf: [{
15590      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15591    }],
15592    ngForTrackBy: [{
15593      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15594    }],
15595    ngForTemplate: [{
15596      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15597    }]
15598  });
15599})();
15600
15601function applyViewChange(view, record) {
15602  view.context.$implicit = record.item;
15603}
15604
15605function getTypeName(type) {
15606  return type['name'] || typeof type;
15607}
15608/**
15609 * @license
15610 * Copyright Google LLC All Rights Reserved.
15611 *
15612 * Use of this source code is governed by an MIT-style license that can be
15613 * found in the LICENSE file at https://angular.io/license
15614 */
15615
15616/**
15617 * A structural directive that conditionally includes a template based on the value of
15618 * an expression coerced to Boolean.
15619 * When the expression evaluates to true, Angular renders the template
15620 * provided in a `then` clause, and when  false or null,
15621 * Angular renders the template provided in an optional `else` clause. The default
15622 * template for the `else` clause is blank.
15623 *
15624 * A [shorthand form](guide/structural-directives#asterisk) of the directive,
15625 * `*ngIf="condition"`, is generally used, provided
15626 * as an attribute of the anchor element for the inserted template.
15627 * Angular expands this into a more explicit version, in which the anchor element
15628 * is contained in an `<ng-template>` element.
15629 *
15630 * Simple form with shorthand syntax:
15631 *
15632 * ```
15633 * <div *ngIf="condition">Content to render when condition is true.</div>
15634 * ```
15635 *
15636 * Simple form with expanded syntax:
15637 *
15638 * ```
15639 * <ng-template [ngIf]="condition"><div>Content to render when condition is
15640 * true.</div></ng-template>
15641 * ```
15642 *
15643 * Form with an "else" block:
15644 *
15645 * ```
15646 * <div *ngIf="condition; else elseBlock">Content to render when condition is true.</div>
15647 * <ng-template #elseBlock>Content to render when condition is false.</ng-template>
15648 * ```
15649 *
15650 * Shorthand form with "then" and "else" blocks:
15651 *
15652 * ```
15653 * <div *ngIf="condition; then thenBlock else elseBlock"></div>
15654 * <ng-template #thenBlock>Content to render when condition is true.</ng-template>
15655 * <ng-template #elseBlock>Content to render when condition is false.</ng-template>
15656 * ```
15657 *
15658 * Form with storing the value locally:
15659 *
15660 * ```
15661 * <div *ngIf="condition as value; else elseBlock">{{value}}</div>
15662 * <ng-template #elseBlock>Content to render when value is null.</ng-template>
15663 * ```
15664 *
15665 * @usageNotes
15666 *
15667 * The `*ngIf` directive is most commonly used to conditionally show an inline template,
15668 * as seen in the following  example.
15669 * The default `else` template is blank.
15670 *
15671 * {@example common/ngIf/ts/module.ts region='NgIfSimple'}
15672 *
15673 * ### Showing an alternative template using `else`
15674 *
15675 * To display a template when `expression` evaluates to false, use an `else` template
15676 * binding as shown in the following example.
15677 * The `else` binding points to an `<ng-template>`  element labeled `#elseBlock`.
15678 * The template can be defined anywhere in the component view, but is typically placed right after
15679 * `ngIf` for readability.
15680 *
15681 * {@example common/ngIf/ts/module.ts region='NgIfElse'}
15682 *
15683 * ### Using an external `then` template
15684 *
15685 * In the previous example, the then-clause template is specified inline, as the content of the
15686 * tag that contains the `ngIf` directive. You can also specify a template that is defined
15687 * externally, by referencing a labeled `<ng-template>` element. When you do this, you can
15688 * change which template to use at runtime, as shown in the following example.
15689 *
15690 * {@example common/ngIf/ts/module.ts region='NgIfThenElse'}
15691 *
15692 * ### Storing a conditional result in a variable
15693 *
15694 * You might want to show a set of properties from the same object. If you are waiting
15695 * for asynchronous data, the object can be undefined.
15696 * In this case, you can use `ngIf` and store the result of the condition in a local
15697 * variable as shown in the following example.
15698 *
15699 * {@example common/ngIf/ts/module.ts region='NgIfAs'}
15700 *
15701 * This code uses only one `AsyncPipe`, so only one subscription is created.
15702 * The conditional statement stores the result of `userStream|async` in the local variable `user`.
15703 * You can then bind the local `user` repeatedly.
15704 *
15705 * The conditional displays the data only if `userStream` returns a value,
15706 * so you don't need to use the
15707 * safe-navigation-operator (`?.`)
15708 * to guard against null values when accessing properties.
15709 * You can display an alternative template while waiting for the data.
15710 *
15711 * ### Shorthand syntax
15712 *
15713 * The shorthand syntax `*ngIf` expands into two separate template specifications
15714 * for the "then" and "else" clauses. For example, consider the following shorthand statement,
15715 * that is meant to show a loading page while waiting for data to be loaded.
15716 *
15717 * ```
15718 * <div class="hero-list" *ngIf="heroes else loading">
15719 *  ...
15720 * </div>
15721 *
15722 * <ng-template #loading>
15723 *  <div>Loading...</div>
15724 * </ng-template>
15725 * ```
15726 *
15727 * You can see that the "else" clause references the `<ng-template>`
15728 * with the `#loading` label, and the template for the "then" clause
15729 * is provided as the content of the anchor element.
15730 *
15731 * However, when Angular expands the shorthand syntax, it creates
15732 * another `<ng-template>` tag, with `ngIf` and `ngIfElse` directives.
15733 * The anchor element containing the template for the "then" clause becomes
15734 * the content of this unlabeled `<ng-template>` tag.
15735 *
15736 * ```
15737 * <ng-template [ngIf]="heroes" [ngIfElse]="loading">
15738 *  <div class="hero-list">
15739 *   ...
15740 *  </div>
15741 * </ng-template>
15742 *
15743 * <ng-template #loading>
15744 *  <div>Loading...</div>
15745 * </ng-template>
15746 * ```
15747 *
15748 * The presence of the implicit template object has implications for the nesting of
15749 * structural directives. For more on this subject, see
15750 * [Structural Directives](guide/structural-directives#one-per-element).
15751 *
15752 * @ngModule CommonModule
15753 * @publicApi
15754 */
15755
15756
15757class NgIf {
15758  constructor(_viewContainer, templateRef) {
15759    this._viewContainer = _viewContainer;
15760    this._context = new NgIfContext();
15761    this._thenTemplateRef = null;
15762    this._elseTemplateRef = null;
15763    this._thenViewRef = null;
15764    this._elseViewRef = null;
15765    this._thenTemplateRef = templateRef;
15766  }
15767  /**
15768   * The Boolean expression to evaluate as the condition for showing a template.
15769   */
15770
15771
15772  set ngIf(condition) {
15773    this._context.$implicit = this._context.ngIf = condition;
15774
15775    this._updateView();
15776  }
15777  /**
15778   * A template to show if the condition expression evaluates to true.
15779   */
15780
15781
15782  set ngIfThen(templateRef) {
15783    assertTemplate('ngIfThen', templateRef);
15784    this._thenTemplateRef = templateRef;
15785    this._thenViewRef = null; // clear previous view if any.
15786
15787    this._updateView();
15788  }
15789  /**
15790   * A template to show if the condition expression evaluates to false.
15791   */
15792
15793
15794  set ngIfElse(templateRef) {
15795    assertTemplate('ngIfElse', templateRef);
15796    this._elseTemplateRef = templateRef;
15797    this._elseViewRef = null; // clear previous view if any.
15798
15799    this._updateView();
15800  }
15801
15802  _updateView() {
15803    if (this._context.$implicit) {
15804      if (!this._thenViewRef) {
15805        this._viewContainer.clear();
15806
15807        this._elseViewRef = null;
15808
15809        if (this._thenTemplateRef) {
15810          this._thenViewRef = this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
15811        }
15812      }
15813    } else {
15814      if (!this._elseViewRef) {
15815        this._viewContainer.clear();
15816
15817        this._thenViewRef = null;
15818
15819        if (this._elseTemplateRef) {
15820          this._elseViewRef = this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
15821        }
15822      }
15823    }
15824  }
15825  /**
15826   * Asserts the correct type of the context for the template that `NgIf` will render.
15827   *
15828   * The presence of this method is a signal to the Ivy template type-check compiler that the
15829   * `NgIf` structural directive renders its template with a specific context type.
15830   */
15831
15832
15833  static ngTemplateContextGuard(dir, ctx) {
15834    return true;
15835  }
15836
15837}
15838
15839NgIf.ɵfac = function NgIf_Factory(t) {
15840  return new (t || NgIf)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
15841};
15842
15843NgIf.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
15844  type: NgIf,
15845  selectors: [["", "ngIf", ""]],
15846  inputs: {
15847    ngIf: "ngIf",
15848    ngIfThen: "ngIfThen",
15849    ngIfElse: "ngIfElse"
15850  },
15851  standalone: true
15852});
15853
15854(function () {
15855  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgIf, [{
15856    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
15857    args: [{
15858      selector: '[ngIf]',
15859      standalone: true
15860    }]
15861  }], function () {
15862    return [{
15863      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
15864    }, {
15865      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
15866    }];
15867  }, {
15868    ngIf: [{
15869      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15870    }],
15871    ngIfThen: [{
15872      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15873    }],
15874    ngIfElse: [{
15875      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
15876    }]
15877  });
15878})();
15879/**
15880 * @publicApi
15881 */
15882
15883
15884class NgIfContext {
15885  constructor() {
15886    this.$implicit = null;
15887    this.ngIf = null;
15888  }
15889
15890}
15891
15892function assertTemplate(property, templateRef) {
15893  const isTemplateRefOrNull = !!(!templateRef || templateRef.createEmbeddedView);
15894
15895  if (!isTemplateRefOrNull) {
15896    throw new Error(`${property} must be a TemplateRef, but received '${(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵstringify"])(templateRef)}'.`);
15897  }
15898}
15899/**
15900 * @license
15901 * Copyright Google LLC All Rights Reserved.
15902 *
15903 * Use of this source code is governed by an MIT-style license that can be
15904 * found in the LICENSE file at https://angular.io/license
15905 */
15906
15907
15908class SwitchView {
15909  constructor(_viewContainerRef, _templateRef) {
15910    this._viewContainerRef = _viewContainerRef;
15911    this._templateRef = _templateRef;
15912    this._created = false;
15913  }
15914
15915  create() {
15916    this._created = true;
15917
15918    this._viewContainerRef.createEmbeddedView(this._templateRef);
15919  }
15920
15921  destroy() {
15922    this._created = false;
15923
15924    this._viewContainerRef.clear();
15925  }
15926
15927  enforceState(created) {
15928    if (created && !this._created) {
15929      this.create();
15930    } else if (!created && this._created) {
15931      this.destroy();
15932    }
15933  }
15934
15935}
15936/**
15937 * @ngModule CommonModule
15938 *
15939 * @description
15940 * The `[ngSwitch]` directive on a container specifies an expression to match against.
15941 * The expressions to match are provided by `ngSwitchCase` directives on views within the container.
15942 * - Every view that matches is rendered.
15943 * - If there are no matches, a view with the `ngSwitchDefault` directive is rendered.
15944 * - Elements within the `[NgSwitch]` statement but outside of any `NgSwitchCase`
15945 * or `ngSwitchDefault` directive are preserved at the location.
15946 *
15947 * @usageNotes
15948 * Define a container element for the directive, and specify the switch expression
15949 * to match against as an attribute:
15950 *
15951 * ```
15952 * <container-element [ngSwitch]="switch_expression">
15953 * ```
15954 *
15955 * Within the container, `*ngSwitchCase` statements specify the match expressions
15956 * as attributes. Include `*ngSwitchDefault` as the final case.
15957 *
15958 * ```
15959 * <container-element [ngSwitch]="switch_expression">
15960 *    <some-element *ngSwitchCase="match_expression_1">...</some-element>
15961 * ...
15962 *    <some-element *ngSwitchDefault>...</some-element>
15963 * </container-element>
15964 * ```
15965 *
15966 * ### Usage Examples
15967 *
15968 * The following example shows how to use more than one case to display the same view:
15969 *
15970 * ```
15971 * <container-element [ngSwitch]="switch_expression">
15972 *   <!-- the same view can be shown in more than one case -->
15973 *   <some-element *ngSwitchCase="match_expression_1">...</some-element>
15974 *   <some-element *ngSwitchCase="match_expression_2">...</some-element>
15975 *   <some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
15976 *   <!--default case when there are no matches -->
15977 *   <some-element *ngSwitchDefault>...</some-element>
15978 * </container-element>
15979 * ```
15980 *
15981 * The following example shows how cases can be nested:
15982 * ```
15983 * <container-element [ngSwitch]="switch_expression">
15984 *       <some-element *ngSwitchCase="match_expression_1">...</some-element>
15985 *       <some-element *ngSwitchCase="match_expression_2">...</some-element>
15986 *       <some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
15987 *       <ng-container *ngSwitchCase="match_expression_3">
15988 *         <!-- use a ng-container to group multiple root nodes -->
15989 *         <inner-element></inner-element>
15990 *         <inner-other-element></inner-other-element>
15991 *       </ng-container>
15992 *       <some-element *ngSwitchDefault>...</some-element>
15993 *     </container-element>
15994 * ```
15995 *
15996 * @publicApi
15997 * @see `NgSwitchCase`
15998 * @see `NgSwitchDefault`
15999 * @see [Structural Directives](guide/structural-directives)
16000 *
16001 */
16002
16003
16004class NgSwitch {
16005  constructor() {
16006    this._defaultUsed = false;
16007    this._caseCount = 0;
16008    this._lastCaseCheckIndex = 0;
16009    this._lastCasesMatched = false;
16010  }
16011
16012  set ngSwitch(newValue) {
16013    this._ngSwitch = newValue;
16014
16015    if (this._caseCount === 0) {
16016      this._updateDefaultCases(true);
16017    }
16018  }
16019  /** @internal */
16020
16021
16022  _addCase() {
16023    return this._caseCount++;
16024  }
16025  /** @internal */
16026
16027
16028  _addDefault(view) {
16029    if (!this._defaultViews) {
16030      this._defaultViews = [];
16031    }
16032
16033    this._defaultViews.push(view);
16034  }
16035  /** @internal */
16036
16037
16038  _matchCase(value) {
16039    const matched = value == this._ngSwitch;
16040    this._lastCasesMatched = this._lastCasesMatched || matched;
16041    this._lastCaseCheckIndex++;
16042
16043    if (this._lastCaseCheckIndex === this._caseCount) {
16044      this._updateDefaultCases(!this._lastCasesMatched);
16045
16046      this._lastCaseCheckIndex = 0;
16047      this._lastCasesMatched = false;
16048    }
16049
16050    return matched;
16051  }
16052
16053  _updateDefaultCases(useDefault) {
16054    if (this._defaultViews && useDefault !== this._defaultUsed) {
16055      this._defaultUsed = useDefault;
16056
16057      for (let i = 0; i < this._defaultViews.length; i++) {
16058        const defaultView = this._defaultViews[i];
16059        defaultView.enforceState(useDefault);
16060      }
16061    }
16062  }
16063
16064}
16065
16066NgSwitch.ɵfac = function NgSwitch_Factory(t) {
16067  return new (t || NgSwitch)();
16068};
16069
16070NgSwitch.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
16071  type: NgSwitch,
16072  selectors: [["", "ngSwitch", ""]],
16073  inputs: {
16074    ngSwitch: "ngSwitch"
16075  },
16076  standalone: true
16077});
16078
16079(function () {
16080  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSwitch, [{
16081    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
16082    args: [{
16083      selector: '[ngSwitch]',
16084      standalone: true
16085    }]
16086  }], null, {
16087    ngSwitch: [{
16088      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
16089    }]
16090  });
16091})();
16092/**
16093 * @ngModule CommonModule
16094 *
16095 * @description
16096 * Provides a switch case expression to match against an enclosing `ngSwitch` expression.
16097 * When the expressions match, the given `NgSwitchCase` template is rendered.
16098 * If multiple match expressions match the switch expression value, all of them are displayed.
16099 *
16100 * @usageNotes
16101 *
16102 * Within a switch container, `*ngSwitchCase` statements specify the match expressions
16103 * as attributes. Include `*ngSwitchDefault` as the final case.
16104 *
16105 * ```
16106 * <container-element [ngSwitch]="switch_expression">
16107 *   <some-element *ngSwitchCase="match_expression_1">...</some-element>
16108 *   ...
16109 *   <some-element *ngSwitchDefault>...</some-element>
16110 * </container-element>
16111 * ```
16112 *
16113 * Each switch-case statement contains an in-line HTML template or template reference
16114 * that defines the subtree to be selected if the value of the match expression
16115 * matches the value of the switch expression.
16116 *
16117 * Unlike JavaScript, which uses strict equality, Angular uses loose equality.
16118 * This means that the empty string, `""` matches 0.
16119 *
16120 * @publicApi
16121 * @see `NgSwitch`
16122 * @see `NgSwitchDefault`
16123 *
16124 */
16125
16126
16127class NgSwitchCase {
16128  constructor(viewContainer, templateRef, ngSwitch) {
16129    this.ngSwitch = ngSwitch;
16130
16131    if ((typeof ngDevMode === 'undefined' || ngDevMode) && !ngSwitch) {
16132      throwNgSwitchProviderNotFoundError('ngSwitchCase', 'NgSwitchCase');
16133    }
16134
16135    ngSwitch._addCase();
16136
16137    this._view = new SwitchView(viewContainer, templateRef);
16138  }
16139  /**
16140   * Performs case matching. For internal use only.
16141   * @nodoc
16142   */
16143
16144
16145  ngDoCheck() {
16146    this._view.enforceState(this.ngSwitch._matchCase(this.ngSwitchCase));
16147  }
16148
16149}
16150
16151NgSwitchCase.ɵfac = function NgSwitchCase_Factory(t) {
16152  return new (t || NgSwitchCase)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgSwitch, 9));
16153};
16154
16155NgSwitchCase.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
16156  type: NgSwitchCase,
16157  selectors: [["", "ngSwitchCase", ""]],
16158  inputs: {
16159    ngSwitchCase: "ngSwitchCase"
16160  },
16161  standalone: true
16162});
16163
16164(function () {
16165  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSwitchCase, [{
16166    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
16167    args: [{
16168      selector: '[ngSwitchCase]',
16169      standalone: true
16170    }]
16171  }], function () {
16172    return [{
16173      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
16174    }, {
16175      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
16176    }, {
16177      type: NgSwitch,
16178      decorators: [{
16179        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
16180      }, {
16181        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
16182      }]
16183    }];
16184  }, {
16185    ngSwitchCase: [{
16186      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
16187    }]
16188  });
16189})();
16190/**
16191 * @ngModule CommonModule
16192 *
16193 * @description
16194 *
16195 * Creates a view that is rendered when no `NgSwitchCase` expressions
16196 * match the `NgSwitch` expression.
16197 * This statement should be the final case in an `NgSwitch`.
16198 *
16199 * @publicApi
16200 * @see `NgSwitch`
16201 * @see `NgSwitchCase`
16202 *
16203 */
16204
16205
16206class NgSwitchDefault {
16207  constructor(viewContainer, templateRef, ngSwitch) {
16208    if ((typeof ngDevMode === 'undefined' || ngDevMode) && !ngSwitch) {
16209      throwNgSwitchProviderNotFoundError('ngSwitchDefault', 'NgSwitchDefault');
16210    }
16211
16212    ngSwitch._addDefault(new SwitchView(viewContainer, templateRef));
16213  }
16214
16215}
16216
16217NgSwitchDefault.ɵfac = function NgSwitchDefault_Factory(t) {
16218  return new (t || NgSwitchDefault)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgSwitch, 9));
16219};
16220
16221NgSwitchDefault.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
16222  type: NgSwitchDefault,
16223  selectors: [["", "ngSwitchDefault", ""]],
16224  standalone: true
16225});
16226
16227(function () {
16228  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSwitchDefault, [{
16229    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
16230    args: [{
16231      selector: '[ngSwitchDefault]',
16232      standalone: true
16233    }]
16234  }], function () {
16235    return [{
16236      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
16237    }, {
16238      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
16239    }, {
16240      type: NgSwitch,
16241      decorators: [{
16242        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
16243      }, {
16244        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
16245      }]
16246    }];
16247  }, null);
16248})();
16249
16250function throwNgSwitchProviderNotFoundError(attrName, directiveName) {
16251  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2000
16252  /* RuntimeErrorCode.PARENT_NG_SWITCH_NOT_FOUND */
16253  , `An element with the "${attrName}" attribute ` + `(matching the "${directiveName}" directive) must be located inside an element with the "ngSwitch" attribute ` + `(matching "NgSwitch" directive)`);
16254}
16255/**
16256 * @license
16257 * Copyright Google LLC All Rights Reserved.
16258 *
16259 * Use of this source code is governed by an MIT-style license that can be
16260 * found in the LICENSE file at https://angular.io/license
16261 */
16262
16263/**
16264 * @ngModule CommonModule
16265 *
16266 * @usageNotes
16267 * ```
16268 * <some-element [ngPlural]="value">
16269 *   <ng-template ngPluralCase="=0">there is nothing</ng-template>
16270 *   <ng-template ngPluralCase="=1">there is one</ng-template>
16271 *   <ng-template ngPluralCase="few">there are a few</ng-template>
16272 * </some-element>
16273 * ```
16274 *
16275 * @description
16276 *
16277 * Adds / removes DOM sub-trees based on a numeric value. Tailored for pluralization.
16278 *
16279 * Displays DOM sub-trees that match the switch expression value, or failing that, DOM sub-trees
16280 * that match the switch expression's pluralization category.
16281 *
16282 * To use this directive you must provide a container element that sets the `[ngPlural]` attribute
16283 * to a switch expression. Inner elements with a `[ngPluralCase]` will display based on their
16284 * expression:
16285 * - if `[ngPluralCase]` is set to a value starting with `=`, it will only display if the value
16286 *   matches the switch expression exactly,
16287 * - otherwise, the view will be treated as a "category match", and will only display if exact
16288 *   value matches aren't found and the value maps to its category for the defined locale.
16289 *
16290 * See http://cldr.unicode.org/index/cldr-spec/plural-rules
16291 *
16292 * @publicApi
16293 */
16294
16295
16296class NgPlural {
16297  constructor(_localization) {
16298    this._localization = _localization;
16299    this._caseViews = {};
16300  }
16301
16302  set ngPlural(value) {
16303    this._switchValue = value;
16304
16305    this._updateView();
16306  }
16307
16308  addCase(value, switchView) {
16309    this._caseViews[value] = switchView;
16310  }
16311
16312  _updateView() {
16313    this._clearViews();
16314
16315    const cases = Object.keys(this._caseViews);
16316    const key = getPluralCategory(this._switchValue, cases, this._localization);
16317
16318    this._activateView(this._caseViews[key]);
16319  }
16320
16321  _clearViews() {
16322    if (this._activeView) this._activeView.destroy();
16323  }
16324
16325  _activateView(view) {
16326    if (view) {
16327      this._activeView = view;
16328
16329      this._activeView.create();
16330    }
16331  }
16332
16333}
16334
16335NgPlural.ɵfac = function NgPlural_Factory(t) {
16336  return new (t || NgPlural)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgLocalization));
16337};
16338
16339NgPlural.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
16340  type: NgPlural,
16341  selectors: [["", "ngPlural", ""]],
16342  inputs: {
16343    ngPlural: "ngPlural"
16344  },
16345  standalone: true
16346});
16347
16348(function () {
16349  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgPlural, [{
16350    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
16351    args: [{
16352      selector: '[ngPlural]',
16353      standalone: true
16354    }]
16355  }], function () {
16356    return [{
16357      type: NgLocalization
16358    }];
16359  }, {
16360    ngPlural: [{
16361      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
16362    }]
16363  });
16364})();
16365/**
16366 * @ngModule CommonModule
16367 *
16368 * @description
16369 *
16370 * Creates a view that will be added/removed from the parent {@link NgPlural} when the
16371 * given expression matches the plural expression according to CLDR rules.
16372 *
16373 * @usageNotes
16374 * ```
16375 * <some-element [ngPlural]="value">
16376 *   <ng-template ngPluralCase="=0">...</ng-template>
16377 *   <ng-template ngPluralCase="other">...</ng-template>
16378 * </some-element>
16379 *```
16380 *
16381 * See {@link NgPlural} for more details and example.
16382 *
16383 * @publicApi
16384 */
16385
16386
16387class NgPluralCase {
16388  constructor(value, template, viewContainer, ngPlural) {
16389    this.value = value;
16390    const isANumber = !isNaN(Number(value));
16391    ngPlural.addCase(isANumber ? `=${value}` : value, new SwitchView(viewContainer, template));
16392  }
16393
16394}
16395
16396NgPluralCase.ɵfac = function NgPluralCase_Factory(t) {
16397  return new (t || NgPluralCase)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('ngPluralCase'), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgPlural, 1));
16398};
16399
16400NgPluralCase.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
16401  type: NgPluralCase,
16402  selectors: [["", "ngPluralCase", ""]],
16403  standalone: true
16404});
16405
16406(function () {
16407  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgPluralCase, [{
16408    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
16409    args: [{
16410      selector: '[ngPluralCase]',
16411      standalone: true
16412    }]
16413  }], function () {
16414    return [{
16415      type: undefined,
16416      decorators: [{
16417        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
16418        args: ['ngPluralCase']
16419      }]
16420    }, {
16421      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
16422    }, {
16423      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
16424    }, {
16425      type: NgPlural,
16426      decorators: [{
16427        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
16428      }]
16429    }];
16430  }, null);
16431})();
16432/**
16433 * @license
16434 * Copyright Google LLC All Rights Reserved.
16435 *
16436 * Use of this source code is governed by an MIT-style license that can be
16437 * found in the LICENSE file at https://angular.io/license
16438 */
16439
16440/**
16441 * @ngModule CommonModule
16442 *
16443 * @usageNotes
16444 *
16445 * Set the font of the containing element to the result of an expression.
16446 *
16447 * ```
16448 * <some-element [ngStyle]="{'font-style': styleExp}">...</some-element>
16449 * ```
16450 *
16451 * Set the width of the containing element to a pixel value returned by an expression.
16452 *
16453 * ```
16454 * <some-element [ngStyle]="{'max-width.px': widthExp}">...</some-element>
16455 * ```
16456 *
16457 * Set a collection of style values using an expression that returns key-value pairs.
16458 *
16459 * ```
16460 * <some-element [ngStyle]="objExp">...</some-element>
16461 * ```
16462 *
16463 * @description
16464 *
16465 * An attribute directive that updates styles for the containing HTML element.
16466 * Sets one or more style properties, specified as colon-separated key-value pairs.
16467 * The key is a style name, with an optional `.<unit>` suffix
16468 * (such as 'top.px', 'font-style.em').
16469 * The value is an expression to be evaluated.
16470 * The resulting non-null value, expressed in the given unit,
16471 * is assigned to the given style property.
16472 * If the result of evaluation is null, the corresponding style is removed.
16473 *
16474 * @publicApi
16475 */
16476
16477
16478class NgStyle {
16479  constructor(_ngEl, _differs, _renderer) {
16480    this._ngEl = _ngEl;
16481    this._differs = _differs;
16482    this._renderer = _renderer;
16483    this._ngStyle = null;
16484    this._differ = null;
16485  }
16486
16487  set ngStyle(values) {
16488    this._ngStyle = values;
16489
16490    if (!this._differ && values) {
16491      this._differ = this._differs.find(values).create();
16492    }
16493  }
16494
16495  ngDoCheck() {
16496    if (this._differ) {
16497      const changes = this._differ.diff(this._ngStyle);
16498
16499      if (changes) {
16500        this._applyChanges(changes);
16501      }
16502    }
16503  }
16504
16505  _setStyle(nameAndUnit, value) {
16506    const [name, unit] = nameAndUnit.split('.');
16507    const flags = name.indexOf('-') === -1 ? undefined : _angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererStyleFlags2.DashCase;
16508
16509    if (value != null) {
16510      this._renderer.setStyle(this._ngEl.nativeElement, name, unit ? `${value}${unit}` : value, flags);
16511    } else {
16512      this._renderer.removeStyle(this._ngEl.nativeElement, name, flags);
16513    }
16514  }
16515
16516  _applyChanges(changes) {
16517    changes.forEachRemovedItem(record => this._setStyle(record.key, null));
16518    changes.forEachAddedItem(record => this._setStyle(record.key, record.currentValue));
16519    changes.forEachChangedItem(record => this._setStyle(record.key, record.currentValue));
16520  }
16521
16522}
16523
16524NgStyle.ɵfac = function NgStyle_Factory(t) {
16525  return new (t || NgStyle)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2));
16526};
16527
16528NgStyle.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
16529  type: NgStyle,
16530  selectors: [["", "ngStyle", ""]],
16531  inputs: {
16532    ngStyle: "ngStyle"
16533  },
16534  standalone: true
16535});
16536
16537(function () {
16538  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgStyle, [{
16539    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
16540    args: [{
16541      selector: '[ngStyle]',
16542      standalone: true
16543    }]
16544  }], function () {
16545    return [{
16546      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
16547    }, {
16548      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers
16549    }, {
16550      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
16551    }];
16552  }, {
16553    ngStyle: [{
16554      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
16555      args: ['ngStyle']
16556    }]
16557  });
16558})();
16559/**
16560 * @license
16561 * Copyright Google LLC All Rights Reserved.
16562 *
16563 * Use of this source code is governed by an MIT-style license that can be
16564 * found in the LICENSE file at https://angular.io/license
16565 */
16566
16567/**
16568 * @ngModule CommonModule
16569 *
16570 * @description
16571 *
16572 * Inserts an embedded view from a prepared `TemplateRef`.
16573 *
16574 * You can attach a context object to the `EmbeddedViewRef` by setting `[ngTemplateOutletContext]`.
16575 * `[ngTemplateOutletContext]` should be an object, the object's keys will be available for binding
16576 * by the local template `let` declarations.
16577 *
16578 * @usageNotes
16579 * ```
16580 * <ng-container *ngTemplateOutlet="templateRefExp; context: contextExp"></ng-container>
16581 * ```
16582 *
16583 * Using the key `$implicit` in the context object will set its value as default.
16584 *
16585 * ### Example
16586 *
16587 * {@example common/ngTemplateOutlet/ts/module.ts region='NgTemplateOutlet'}
16588 *
16589 * @publicApi
16590 */
16591
16592
16593class NgTemplateOutlet {
16594  constructor(_viewContainerRef) {
16595    this._viewContainerRef = _viewContainerRef;
16596    this._viewRef = null;
16597    /**
16598     * A context object to attach to the {@link EmbeddedViewRef}. This should be an
16599     * object, the object's keys will be available for binding by the local template `let`
16600     * declarations.
16601     * Using the key `$implicit` in the context object will set its value as default.
16602     */
16603
16604    this.ngTemplateOutletContext = null;
16605    /**
16606     * A string defining the template reference and optionally the context object for the template.
16607     */
16608
16609    this.ngTemplateOutlet = null;
16610    /** Injector to be used within the embedded view. */
16611
16612    this.ngTemplateOutletInjector = null;
16613  }
16614  /** @nodoc */
16615
16616
16617  ngOnChanges(changes) {
16618    if (changes['ngTemplateOutlet'] || changes['ngTemplateOutletInjector']) {
16619      const viewContainerRef = this._viewContainerRef;
16620
16621      if (this._viewRef) {
16622        viewContainerRef.remove(viewContainerRef.indexOf(this._viewRef));
16623      }
16624
16625      if (this.ngTemplateOutlet) {
16626        const {
16627          ngTemplateOutlet: template,
16628          ngTemplateOutletContext: context,
16629          ngTemplateOutletInjector: injector
16630        } = this;
16631        this._viewRef = viewContainerRef.createEmbeddedView(template, context, injector ? {
16632          injector
16633        } : undefined);
16634      } else {
16635        this._viewRef = null;
16636      }
16637    } else if (this._viewRef && changes['ngTemplateOutletContext'] && this.ngTemplateOutletContext) {
16638      this._viewRef.context = this.ngTemplateOutletContext;
16639    }
16640  }
16641
16642}
16643
16644NgTemplateOutlet.ɵfac = function NgTemplateOutlet_Factory(t) {
16645  return new (t || NgTemplateOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef));
16646};
16647
16648NgTemplateOutlet.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
16649  type: NgTemplateOutlet,
16650  selectors: [["", "ngTemplateOutlet", ""]],
16651  inputs: {
16652    ngTemplateOutletContext: "ngTemplateOutletContext",
16653    ngTemplateOutlet: "ngTemplateOutlet",
16654    ngTemplateOutletInjector: "ngTemplateOutletInjector"
16655  },
16656  standalone: true,
16657  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
16658});
16659
16660(function () {
16661  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgTemplateOutlet, [{
16662    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
16663    args: [{
16664      selector: '[ngTemplateOutlet]',
16665      standalone: true
16666    }]
16667  }], function () {
16668    return [{
16669      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
16670    }];
16671  }, {
16672    ngTemplateOutletContext: [{
16673      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
16674    }],
16675    ngTemplateOutlet: [{
16676      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
16677    }],
16678    ngTemplateOutletInjector: [{
16679      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
16680    }]
16681  });
16682})();
16683/**
16684 * @license
16685 * Copyright Google LLC All Rights Reserved.
16686 *
16687 * Use of this source code is governed by an MIT-style license that can be
16688 * found in the LICENSE file at https://angular.io/license
16689 */
16690
16691/**
16692 * A collection of Angular directives that are likely to be used in each and every Angular
16693 * application.
16694 */
16695
16696
16697const COMMON_DIRECTIVES = [NgClass, NgComponentOutlet, NgForOf, NgIf, NgTemplateOutlet, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgPlural, NgPluralCase];
16698/**
16699 * @license
16700 * Copyright Google LLC All Rights Reserved.
16701 *
16702 * Use of this source code is governed by an MIT-style license that can be
16703 * found in the LICENSE file at https://angular.io/license
16704 */
16705
16706function invalidPipeArgumentError(type, value) {
16707  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2100
16708  /* RuntimeErrorCode.INVALID_PIPE_ARGUMENT */
16709  , ngDevMode && `InvalidPipeArgument: '${value}' for pipe '${(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵstringify"])(type)}'`);
16710}
16711/**
16712 * @license
16713 * Copyright Google LLC All Rights Reserved.
16714 *
16715 * Use of this source code is governed by an MIT-style license that can be
16716 * found in the LICENSE file at https://angular.io/license
16717 */
16718
16719
16720class SubscribableStrategy {
16721  createSubscription(async, updateLatestValue) {
16722    return async.subscribe({
16723      next: updateLatestValue,
16724      error: e => {
16725        throw e;
16726      }
16727    });
16728  }
16729
16730  dispose(subscription) {
16731    subscription.unsubscribe();
16732  }
16733
16734}
16735
16736class PromiseStrategy {
16737  createSubscription(async, updateLatestValue) {
16738    return async.then(updateLatestValue, e => {
16739      throw e;
16740    });
16741  }
16742
16743  dispose(subscription) {}
16744
16745}
16746
16747const _promiseStrategy = new PromiseStrategy();
16748
16749const _subscribableStrategy = new SubscribableStrategy();
16750/**
16751 * @ngModule CommonModule
16752 * @description
16753 *
16754 * Unwraps a value from an asynchronous primitive.
16755 *
16756 * The `async` pipe subscribes to an `Observable` or `Promise` and returns the latest value it has
16757 * emitted. When a new value is emitted, the `async` pipe marks the component to be checked for
16758 * changes. When the component gets destroyed, the `async` pipe unsubscribes automatically to avoid
16759 * potential memory leaks. When the reference of the expression changes, the `async` pipe
16760 * automatically unsubscribes from the old `Observable` or `Promise` and subscribes to the new one.
16761 *
16762 * @usageNotes
16763 *
16764 * ### Examples
16765 *
16766 * This example binds a `Promise` to the view. Clicking the `Resolve` button resolves the
16767 * promise.
16768 *
16769 * {@example common/pipes/ts/async_pipe.ts region='AsyncPipePromise'}
16770 *
16771 * It's also possible to use `async` with Observables. The example below binds the `time` Observable
16772 * to the view. The Observable continuously updates the view with the current time.
16773 *
16774 * {@example common/pipes/ts/async_pipe.ts region='AsyncPipeObservable'}
16775 *
16776 * @publicApi
16777 */
16778
16779
16780class AsyncPipe {
16781  constructor(ref) {
16782    this._latestValue = null;
16783    this._subscription = null;
16784    this._obj = null;
16785    this._strategy = null; // Assign `ref` into `this._ref` manually instead of declaring `_ref` in the constructor
16786    // parameter list, as the type of `this._ref` includes `null` unlike the type of `ref`.
16787
16788    this._ref = ref;
16789  }
16790
16791  ngOnDestroy() {
16792    if (this._subscription) {
16793      this._dispose();
16794    } // Clear the `ChangeDetectorRef` and its association with the view data, to mitigate
16795    // potential memory leaks in Observables that could otherwise cause the view data to
16796    // be retained.
16797    // https://github.com/angular/angular/issues/17624
16798
16799
16800    this._ref = null;
16801  }
16802
16803  transform(obj) {
16804    if (!this._obj) {
16805      if (obj) {
16806        this._subscribe(obj);
16807      }
16808
16809      return this._latestValue;
16810    }
16811
16812    if (obj !== this._obj) {
16813      this._dispose();
16814
16815      return this.transform(obj);
16816    }
16817
16818    return this._latestValue;
16819  }
16820
16821  _subscribe(obj) {
16822    this._obj = obj;
16823    this._strategy = this._selectStrategy(obj);
16824    this._subscription = this._strategy.createSubscription(obj, value => this._updateLatestValue(obj, value));
16825  }
16826
16827  _selectStrategy(obj) {
16828    if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisPromise"])(obj)) {
16829      return _promiseStrategy;
16830    }
16831
16832    if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisSubscribable"])(obj)) {
16833      return _subscribableStrategy;
16834    }
16835
16836    throw invalidPipeArgumentError(AsyncPipe, obj);
16837  }
16838
16839  _dispose() {
16840    // Note: `dispose` is only called if a subscription has been initialized before, indicating
16841    // that `this._strategy` is also available.
16842    this._strategy.dispose(this._subscription);
16843
16844    this._latestValue = null;
16845    this._subscription = null;
16846    this._obj = null;
16847  }
16848
16849  _updateLatestValue(async, value) {
16850    if (async === this._obj) {
16851      this._latestValue = value; // Note: `this._ref` is only cleared in `ngOnDestroy` so is known to be available when a
16852      // value is being updated.
16853
16854      this._ref.markForCheck();
16855    }
16856  }
16857
16858}
16859
16860AsyncPipe.ɵfac = function AsyncPipe_Factory(t) {
16861  return new (t || AsyncPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef, 16));
16862};
16863
16864AsyncPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
16865  name: "async",
16866  type: AsyncPipe,
16867  pure: false,
16868  standalone: true
16869});
16870
16871(function () {
16872  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AsyncPipe, [{
16873    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
16874    args: [{
16875      name: 'async',
16876      pure: false,
16877      standalone: true
16878    }]
16879  }], function () {
16880    return [{
16881      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
16882    }];
16883  }, null);
16884})();
16885/**
16886 * @license
16887 * Copyright Google LLC All Rights Reserved.
16888 *
16889 * Use of this source code is governed by an MIT-style license that can be
16890 * found in the LICENSE file at https://angular.io/license
16891 */
16892
16893/**
16894 * Transforms text to all lower case.
16895 *
16896 * @see `UpperCasePipe`
16897 * @see `TitleCasePipe`
16898 * @usageNotes
16899 *
16900 * The following example defines a view that allows the user to enter
16901 * text, and then uses the pipe to convert the input text to all lower case.
16902 *
16903 * <code-example path="common/pipes/ts/lowerupper_pipe.ts" region='LowerUpperPipe'></code-example>
16904 *
16905 * @ngModule CommonModule
16906 * @publicApi
16907 */
16908
16909
16910class LowerCasePipe {
16911  transform(value) {
16912    if (value == null) return null;
16913
16914    if (typeof value !== 'string') {
16915      throw invalidPipeArgumentError(LowerCasePipe, value);
16916    }
16917
16918    return value.toLowerCase();
16919  }
16920
16921}
16922
16923LowerCasePipe.ɵfac = function LowerCasePipe_Factory(t) {
16924  return new (t || LowerCasePipe)();
16925};
16926
16927LowerCasePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
16928  name: "lowercase",
16929  type: LowerCasePipe,
16930  pure: true,
16931  standalone: true
16932});
16933
16934(function () {
16935  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LowerCasePipe, [{
16936    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
16937    args: [{
16938      name: 'lowercase',
16939      standalone: true
16940    }]
16941  }], null, null);
16942})(); //
16943// Regex below matches any Unicode word and number compatible with ES5. In ES2018 the same result
16944// can be achieved by using /[0-9\p{L}]\S*/gu and also known as Unicode Property Escapes
16945// (https://2ality.com/2017/07/regexp-unicode-property-escapes.html). Since there is no
16946// transpilation of this functionality down to ES5 without external tool, the only solution is
16947// to use already transpiled form. Example can be found here -
16948// https://mothereff.in/regexpu#input=var+regex+%3D+%2F%5B0-9%5Cp%7BL%7D%5D%5CS*%2Fgu%3B%0A%0A&unicodePropertyEscape=1
16949//
16950
16951
16952const unicodeWordMatch = /(?:[0-9A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u
169520EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDF70-\uDF81\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE70-\uDEBE\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])\S*/g;
16953/**
16954 * Transforms text to title case.
16955 * Capitalizes the first letter of each word and transforms the
16956 * rest of the word to lower case.
16957 * Words are delimited by any whitespace character, such as a space, tab, or line-feed character.
16958 *
16959 * @see `LowerCasePipe`
16960 * @see `UpperCasePipe`
16961 *
16962 * @usageNotes
16963 * The following example shows the result of transforming various strings into title case.
16964 *
16965 * <code-example path="common/pipes/ts/titlecase_pipe.ts" region='TitleCasePipe'></code-example>
16966 *
16967 * @ngModule CommonModule
16968 * @publicApi
16969 */
16970
16971class TitleCasePipe {
16972  transform(value) {
16973    if (value == null) return null;
16974
16975    if (typeof value !== 'string') {
16976      throw invalidPipeArgumentError(TitleCasePipe, value);
16977    }
16978
16979    return value.replace(unicodeWordMatch, txt => txt[0].toUpperCase() + txt.slice(1).toLowerCase());
16980  }
16981
16982}
16983
16984TitleCasePipe.ɵfac = function TitleCasePipe_Factory(t) {
16985  return new (t || TitleCasePipe)();
16986};
16987
16988TitleCasePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
16989  name: "titlecase",
16990  type: TitleCasePipe,
16991  pure: true,
16992  standalone: true
16993});
16994
16995(function () {
16996  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](TitleCasePipe, [{
16997    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
16998    args: [{
16999      name: 'titlecase',
17000      standalone: true
17001    }]
17002  }], null, null);
17003})();
17004/**
17005 * Transforms text to all upper case.
17006 * @see `LowerCasePipe`
17007 * @see `TitleCasePipe`
17008 *
17009 * @ngModule CommonModule
17010 * @publicApi
17011 */
17012
17013
17014class UpperCasePipe {
17015  transform(value) {
17016    if (value == null) return null;
17017
17018    if (typeof value !== 'string') {
17019      throw invalidPipeArgumentError(UpperCasePipe, value);
17020    }
17021
17022    return value.toUpperCase();
17023  }
17024
17025}
17026
17027UpperCasePipe.ɵfac = function UpperCasePipe_Factory(t) {
17028  return new (t || UpperCasePipe)();
17029};
17030
17031UpperCasePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
17032  name: "uppercase",
17033  type: UpperCasePipe,
17034  pure: true,
17035  standalone: true
17036});
17037
17038(function () {
17039  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UpperCasePipe, [{
17040    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
17041    args: [{
17042      name: 'uppercase',
17043      standalone: true
17044    }]
17045  }], null, null);
17046})();
17047/**
17048 * @license
17049 * Copyright Google LLC All Rights Reserved.
17050 *
17051 * Use of this source code is governed by an MIT-style license that can be
17052 * found in the LICENSE file at https://angular.io/license
17053 */
17054
17055/**
17056 * Optionally-provided default timezone to use for all instances of `DatePipe` (such as `'+0430'`).
17057 * If the value isn't provided, the `DatePipe` will use the end-user's local system timezone.
17058 */
17059
17060
17061const DATE_PIPE_DEFAULT_TIMEZONE = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('DATE_PIPE_DEFAULT_TIMEZONE'); // clang-format off
17062
17063/**
17064 * @ngModule CommonModule
17065 * @description
17066 *
17067 * Formats a date value according to locale rules.
17068 *
17069 * `DatePipe` is executed only when it detects a pure change to the input value.
17070 * A pure change is either a change to a primitive input value
17071 * (such as `String`, `Number`, `Boolean`, or `Symbol`),
17072 * or a changed object reference (such as `Date`, `Array`, `Function`, or `Object`).
17073 *
17074 * Note that mutating a `Date` object does not cause the pipe to be rendered again.
17075 * To ensure that the pipe is executed, you must create a new `Date` object.
17076 *
17077 * Only the `en-US` locale data comes with Angular. To localize dates
17078 * in another language, you must import the corresponding locale data.
17079 * See the [I18n guide](guide/i18n-common-format-data-locale) for more information.
17080 *
17081 * The time zone of the formatted value can be specified either by passing it in as the second
17082 * parameter of the pipe, or by setting the default through the `DATE_PIPE_DEFAULT_TIMEZONE`
17083 * injection token. The value that is passed in as the second parameter takes precedence over
17084 * the one defined using the injection token.
17085 *
17086 * @see `formatDate()`
17087 *
17088 *
17089 * @usageNotes
17090 *
17091 * The result of this pipe is not reevaluated when the input is mutated. To avoid the need to
17092 * reformat the date on every change-detection cycle, treat the date as an immutable object
17093 * and change the reference when the pipe needs to run again.
17094 *
17095 * ### Pre-defined format options
17096 *
17097 * | Option        | Equivalent to                       | Examples (given in `en-US` locale)              |
17098 * |---------------|-------------------------------------|-------------------------------------------------|
17099 * | `'short'`     | `'M/d/yy, h:mm a'`                  | `6/15/15, 9:03 AM`                              |
17100 * | `'medium'`    | `'MMM d, y, h:mm:ss a'`             | `Jun 15, 2015, 9:03:01 AM`                      |
17101 * | `'long'`      | `'MMMM d, y, h:mm:ss a z'`          | `June 15, 2015 at 9:03:01 AM GMT+1`             |
17102 * | `'full'`      | `'EEEE, MMMM d, y, h:mm:ss a zzzz'` | `Monday, June 15, 2015 at 9:03:01 AM GMT+01:00` |
17103 * | `'shortDate'` | `'M/d/yy'`                          | `6/15/15`                                       |
17104 * | `'mediumDate'`| `'MMM d, y'`                        | `Jun 15, 2015`                                  |
17105 * | `'longDate'`  | `'MMMM d, y'`                       | `June 15, 2015`                                 |
17106 * | `'fullDate'`  | `'EEEE, MMMM d, y'`                 | `Monday, June 15, 2015`                         |
17107 * | `'shortTime'` | `'h:mm a'`                          | `9:03 AM`                                       |
17108 * | `'mediumTime'`| `'h:mm:ss a'`                       | `9:03:01 AM`                                    |
17109 * | `'longTime'`  | `'h:mm:ss a z'`                     | `9:03:01 AM GMT+1`                              |
17110 * | `'fullTime'`  | `'h:mm:ss a zzzz'`                  | `9:03:01 AM GMT+01:00`                          |
17111 *
17112 * ### Custom format options
17113 *
17114 * You can construct a format string using symbols to specify the components
17115 * of a date-time value, as described in the following table.
17116 * Format details depend on the locale.
17117 * Fields marked with (*) are only available in the extra data set for the given locale.
17118 *
17119 *  | Field type          | Format      | Description                                                   | Example Value                                              |
17120 *  |-------------------- |-------------|---------------------------------------------------------------|------------------------------------------------------------|
17121 *  | Era                 | G, GG & GGG | Abbreviated                                                   | AD                                                         |
17122 *  |                     | GGGG        | Wide                                                          | Anno Domini                                                |
17123 *  |                     | GGGGG       | Narrow                                                        | A                                                          |
17124 *  | Year                | y           | Numeric: minimum digits                                       | 2, 20, 201, 2017, 20173                                    |
17125 *  |                     | yy          | Numeric: 2 digits + zero padded                               | 02, 20, 01, 17, 73                                         |
17126 *  |                     | yyy         | Numeric: 3 digits + zero padded                               | 002, 020, 201, 2017, 20173                                 |
17127 *  |                     | yyyy        | Numeric: 4 digits or more + zero padded                       | 0002, 0020, 0201, 2017, 20173                              |
17128 *  | Week-numbering year | Y           | Numeric: minimum digits                                       | 2, 20, 201, 2017, 20173                                    |
17129 *  |                     | YY          | Numeric: 2 digits + zero padded                               | 02, 20, 01, 17, 73                                         |
17130 *  |                     | YYY         | Numeric: 3 digits + zero padded                               | 002, 020, 201, 2017, 20173                                 |
17131 *  |                     | YYYY        | Numeric: 4 digits or more + zero padded                       | 0002, 0020, 0201, 2017, 20173                              |
17132 *  | Month               | M           | Numeric: 1 digit                                              | 9, 12                                                      |
17133 *  |                     | MM          | Numeric: 2 digits + zero padded                               | 09, 12                                                     |
17134 *  |                     | MMM         | Abbreviated                                                   | Sep                                                        |
17135 *  |                     | MMMM        | Wide                                                          | September                                                  |
17136 *  |                     | MMMMM       | Narrow                                                        | S                                                          |
17137 *  | Month standalone    | L           | Numeric: 1 digit                                              | 9, 12                                                      |
17138 *  |                     | LL          | Numeric: 2 digits + zero padded                               | 09, 12                                                     |
17139 *  |                     | LLL         | Abbreviated                                                   | Sep                                                        |
17140 *  |                     | LLLL        | Wide                                                          | September                                                  |
17141 *  |                     | LLLLL       | Narrow                                                        | S                                                          |
17142 *  | Week of year        | w           | Numeric: minimum digits                                       | 1... 53                                                    |
17143 *  |                     | ww          | Numeric: 2 digits + zero padded                               | 01... 53                                                   |
17144 *  | Week of month       | W           | Numeric: 1 digit                                              | 1... 5                                                     |
17145 *  | Day of month        | d           | Numeric: minimum digits                                       | 1                                                          |
17146 *  |                     | dd          | Numeric: 2 digits + zero padded                               | 01                                                         |
17147 *  | Week day            | E, EE & EEE | Abbreviated                                                   | Tue                                                        |
17148 *  |                     | EEEE        | Wide                                                          | Tuesday                                                    |
17149 *  |                     | EEEEE       | Narrow                                                        | T                                                          |
17150 *  |                     | EEEEEE      | Short                                                         | Tu                                                         |
17151 *  | Week day standalone | c, cc       | Numeric: 1 digit                                              | 2                                                          |
17152 *  |                     | ccc         | Abbreviated                                                   | Tue                                                        |
17153 *  |                     | cccc        | Wide                                                          | Tuesday                                                    |
17154 *  |                     | ccccc       | Narrow                                                        | T                                                          |
17155 *  |                     | cccccc      | Short                                                         | Tu                                                         |
17156 *  | Period              | a, aa & aaa | Abbreviated                                                   | am/pm or AM/PM                                             |
17157 *  |                     | aaaa        | Wide (fallback to `a` when missing)                           | ante meridiem/post meridiem                                |
17158 *  |                     | aaaaa       | Narrow                                                        | a/p                                                        |
17159 *  | Period*             | B, BB & BBB | Abbreviated                                                   | mid.                                                       |
17160 *  |                     | BBBB        | Wide                                                          | am, pm, midnight, noon, morning, afternoon, evening, night |
17161 *  |                     | BBBBB       | Narrow                                                        | md                                                         |
17162 *  | Period standalone*  | b, bb & bbb | Abbreviated                                                   | mid.                                                       |
17163 *  |                     | bbbb        | Wide                                                          | am, pm, midnight, noon, morning, afternoon, evening, night |
17164 *  |                     | bbbbb       | Narrow                                                        | md                                                         |
17165 *  | Hour 1-12           | h           | Numeric: minimum digits                                       | 1, 12                                                      |
17166 *  |                     | hh          | Numeric: 2 digits + zero padded                               | 01, 12                                                     |
17167 *  | Hour 0-23           | H           | Numeric: minimum digits                                       | 0, 23                                                      |
17168 *  |                     | HH          | Numeric: 2 digits + zero padded                               | 00, 23                                                     |
17169 *  | Minute              | m           | Numeric: minimum digits                                       | 8, 59                                                      |
17170 *  |                     | mm          | Numeric: 2 digits + zero padded                               | 08, 59                                                     |
17171 *  | Second              | s           | Numeric: minimum digits                                       | 0... 59                                                    |
17172 *  |                     | ss          | Numeric: 2 digits + zero padded                               | 00... 59                                                   |
17173 *  | Fractional seconds  | S           | Numeric: 1 digit                                              | 0... 9                                                     |
17174 *  |                     | SS          | Numeric: 2 digits + zero padded                               | 00... 99                                                   |
17175 *  |                     | SSS         | Numeric: 3 digits + zero padded (= milliseconds)              | 000... 999                                                 |
17176 *  | Zone                | z, zz & zzz | Short specific non location format (fallback to O)            | GMT-8                                                      |
17177 *  |                     | zzzz        | Long specific non location format (fallback to OOOO)          | GMT-08:00                                                  |
17178 *  |                     | Z, ZZ & ZZZ | ISO8601 basic format                                          | -0800                                                      |
17179 *  |                     | ZZZZ        | Long localized GMT format                                     | GMT-8:00                                                   |
17180 *  |                     | ZZZZZ       | ISO8601 extended format + Z indicator for offset 0 (= XXXXX)  | -08:00                                                     |
17181 *  |                     | O, OO & OOO | Short localized GMT format                                    | GMT-8                                                      |
17182 *  |                     | OOOO        | Long localized GMT format                                     | GMT-08:00                                                  |
17183 *
17184 *
17185 * ### Format examples
17186 *
17187 * These examples transform a date into various formats,
17188 * assuming that `dateObj` is a JavaScript `Date` object for
17189 * year: 2015, month: 6, day: 15, hour: 21, minute: 43, second: 11,
17190 * given in the local time for the `en-US` locale.
17191 *
17192 * ```
17193 * {{ dateObj | date }}               // output is 'Jun 15, 2015'
17194 * {{ dateObj | date:'medium' }}      // output is 'Jun 15, 2015, 9:43:11 PM'
17195 * {{ dateObj | date:'shortTime' }}   // output is '9:43 PM'
17196 * {{ dateObj | date:'mm:ss' }}       // output is '43:11'
17197 * ```
17198 *
17199 * ### Usage example
17200 *
17201 * The following component uses a date pipe to display the current date in different formats.
17202 *
17203 * ```
17204 * @Component({
17205 *  selector: 'date-pipe',
17206 *  template: `<div>
17207 *    <p>Today is {{today | date}}</p>
17208 *    <p>Or if you prefer, {{today | date:'fullDate'}}</p>
17209 *    <p>The time is {{today | date:'h:mm a z'}}</p>
17210 *  </div>`
17211 * })
17212 * // Get the current date and time as a date-time value.
17213 * export class DatePipeComponent {
17214 *   today: number = Date.now();
17215 * }
17216 * ```
17217 *
17218 * @publicApi
17219 */
17220// clang-format on
17221
17222class DatePipe {
17223  constructor(locale, defaultTimezone) {
17224    this.locale = locale;
17225    this.defaultTimezone = defaultTimezone;
17226  }
17227
17228  transform(value, format = 'mediumDate', timezone, locale) {
17229    if (value == null || value === '' || value !== value) return null;
17230
17231    try {
17232      return formatDate(value, format, locale || this.locale, timezone ?? this.defaultTimezone ?? undefined);
17233    } catch (error) {
17234      throw invalidPipeArgumentError(DatePipe, error.message);
17235    }
17236  }
17237
17238}
17239
17240DatePipe.ɵfac = function DatePipe_Factory(t) {
17241  return new (t || DatePipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID, 16), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](DATE_PIPE_DEFAULT_TIMEZONE, 24));
17242};
17243
17244DatePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
17245  name: "date",
17246  type: DatePipe,
17247  pure: true,
17248  standalone: true
17249});
17250
17251(function () {
17252  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DatePipe, [{
17253    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
17254    args: [{
17255      name: 'date',
17256      pure: true,
17257      standalone: true
17258    }]
17259  }], function () {
17260    return [{
17261      type: undefined,
17262      decorators: [{
17263        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
17264        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
17265      }]
17266    }, {
17267      type: undefined,
17268      decorators: [{
17269        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
17270        args: [DATE_PIPE_DEFAULT_TIMEZONE]
17271      }, {
17272        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
17273      }]
17274    }];
17275  }, null);
17276})();
17277/**
17278 * @license
17279 * Copyright Google LLC All Rights Reserved.
17280 *
17281 * Use of this source code is governed by an MIT-style license that can be
17282 * found in the LICENSE file at https://angular.io/license
17283 */
17284
17285
17286const _INTERPOLATION_REGEXP = /#/g;
17287/**
17288 * @ngModule CommonModule
17289 * @description
17290 *
17291 * Maps a value to a string that pluralizes the value according to locale rules.
17292 *
17293 * @usageNotes
17294 *
17295 * ### Example
17296 *
17297 * {@example common/pipes/ts/i18n_pipe.ts region='I18nPluralPipeComponent'}
17298 *
17299 * @publicApi
17300 */
17301
17302class I18nPluralPipe {
17303  constructor(_localization) {
17304    this._localization = _localization;
17305  }
17306  /**
17307   * @param value the number to be formatted
17308   * @param pluralMap an object that mimics the ICU format, see
17309   * https://unicode-org.github.io/icu/userguide/format_parse/messages/.
17310   * @param locale a `string` defining the locale to use (uses the current {@link LOCALE_ID} by
17311   * default).
17312   */
17313
17314
17315  transform(value, pluralMap, locale) {
17316    if (value == null) return '';
17317
17318    if (typeof pluralMap !== 'object' || pluralMap === null) {
17319      throw invalidPipeArgumentError(I18nPluralPipe, pluralMap);
17320    }
17321
17322    const key = getPluralCategory(value, Object.keys(pluralMap), this._localization, locale);
17323    return pluralMap[key].replace(_INTERPOLATION_REGEXP, value.toString());
17324  }
17325
17326}
17327
17328I18nPluralPipe.ɵfac = function I18nPluralPipe_Factory(t) {
17329  return new (t || I18nPluralPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgLocalization, 16));
17330};
17331
17332I18nPluralPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
17333  name: "i18nPlural",
17334  type: I18nPluralPipe,
17335  pure: true,
17336  standalone: true
17337});
17338
17339(function () {
17340  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](I18nPluralPipe, [{
17341    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
17342    args: [{
17343      name: 'i18nPlural',
17344      pure: true,
17345      standalone: true
17346    }]
17347  }], function () {
17348    return [{
17349      type: NgLocalization
17350    }];
17351  }, null);
17352})();
17353/**
17354 * @license
17355 * Copyright Google LLC All Rights Reserved.
17356 *
17357 * Use of this source code is governed by an MIT-style license that can be
17358 * found in the LICENSE file at https://angular.io/license
17359 */
17360
17361/**
17362 * @ngModule CommonModule
17363 * @description
17364 *
17365 * Generic selector that displays the string that matches the current value.
17366 *
17367 * If none of the keys of the `mapping` match the `value`, then the content
17368 * of the `other` key is returned when present, otherwise an empty string is returned.
17369 *
17370 * @usageNotes
17371 *
17372 * ### Example
17373 *
17374 * {@example common/pipes/ts/i18n_pipe.ts region='I18nSelectPipeComponent'}
17375 *
17376 * @publicApi
17377 */
17378
17379
17380class I18nSelectPipe {
17381  /**
17382   * @param value a string to be internationalized.
17383   * @param mapping an object that indicates the text that should be displayed
17384   * for different values of the provided `value`.
17385   */
17386  transform(value, mapping) {
17387    if (value == null) return '';
17388
17389    if (typeof mapping !== 'object' || typeof value !== 'string') {
17390      throw invalidPipeArgumentError(I18nSelectPipe, mapping);
17391    }
17392
17393    if (mapping.hasOwnProperty(value)) {
17394      return mapping[value];
17395    }
17396
17397    if (mapping.hasOwnProperty('other')) {
17398      return mapping['other'];
17399    }
17400
17401    return '';
17402  }
17403
17404}
17405
17406I18nSelectPipe.ɵfac = function I18nSelectPipe_Factory(t) {
17407  return new (t || I18nSelectPipe)();
17408};
17409
17410I18nSelectPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
17411  name: "i18nSelect",
17412  type: I18nSelectPipe,
17413  pure: true,
17414  standalone: true
17415});
17416
17417(function () {
17418  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](I18nSelectPipe, [{
17419    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
17420    args: [{
17421      name: 'i18nSelect',
17422      pure: true,
17423      standalone: true
17424    }]
17425  }], null, null);
17426})();
17427/**
17428 * @license
17429 * Copyright Google LLC All Rights Reserved.
17430 *
17431 * Use of this source code is governed by an MIT-style license that can be
17432 * found in the LICENSE file at https://angular.io/license
17433 */
17434
17435/**
17436 * @ngModule CommonModule
17437 * @description
17438 *
17439 * Converts a value into its JSON-format representation.  Useful for debugging.
17440 *
17441 * @usageNotes
17442 *
17443 * The following component uses a JSON pipe to convert an object
17444 * to JSON format, and displays the string in both formats for comparison.
17445 *
17446 * {@example common/pipes/ts/json_pipe.ts region='JsonPipe'}
17447 *
17448 * @publicApi
17449 */
17450
17451
17452class JsonPipe {
17453  /**
17454   * @param value A value of any type to convert into a JSON-format string.
17455   */
17456  transform(value) {
17457    return JSON.stringify(value, null, 2);
17458  }
17459
17460}
17461
17462JsonPipe.ɵfac = function JsonPipe_Factory(t) {
17463  return new (t || JsonPipe)();
17464};
17465
17466JsonPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
17467  name: "json",
17468  type: JsonPipe,
17469  pure: false,
17470  standalone: true
17471});
17472
17473(function () {
17474  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](JsonPipe, [{
17475    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
17476    args: [{
17477      name: 'json',
17478      pure: false,
17479      standalone: true
17480    }]
17481  }], null, null);
17482})();
17483/**
17484 * @license
17485 * Copyright Google LLC All Rights Reserved.
17486 *
17487 * Use of this source code is governed by an MIT-style license that can be
17488 * found in the LICENSE file at https://angular.io/license
17489 */
17490
17491
17492function makeKeyValuePair(key, value) {
17493  return {
17494    key: key,
17495    value: value
17496  };
17497}
17498/**
17499 * @ngModule CommonModule
17500 * @description
17501 *
17502 * Transforms Object or Map into an array of key value pairs.
17503 *
17504 * The output array will be ordered by keys.
17505 * By default the comparator will be by Unicode point value.
17506 * You can optionally pass a compareFn if your keys are complex types.
17507 *
17508 * @usageNotes
17509 * ### Examples
17510 *
17511 * This examples show how an Object or a Map can be iterated by ngFor with the use of this
17512 * keyvalue pipe.
17513 *
17514 * {@example common/pipes/ts/keyvalue_pipe.ts region='KeyValuePipe'}
17515 *
17516 * @publicApi
17517 */
17518
17519
17520class KeyValuePipe {
17521  constructor(differs) {
17522    this.differs = differs;
17523    this.keyValues = [];
17524    this.compareFn = defaultComparator;
17525  }
17526
17527  transform(input, compareFn = defaultComparator) {
17528    if (!input || !(input instanceof Map) && typeof input !== 'object') {
17529      return null;
17530    }
17531
17532    if (!this.differ) {
17533      // make a differ for whatever type we've been passed in
17534      this.differ = this.differs.find(input).create();
17535    }
17536
17537    const differChanges = this.differ.diff(input);
17538    const compareFnChanged = compareFn !== this.compareFn;
17539
17540    if (differChanges) {
17541      this.keyValues = [];
17542      differChanges.forEachItem(r => {
17543        this.keyValues.push(makeKeyValuePair(r.key, r.currentValue));
17544      });
17545    }
17546
17547    if (differChanges || compareFnChanged) {
17548      this.keyValues.sort(compareFn);
17549      this.compareFn = compareFn;
17550    }
17551
17552    return this.keyValues;
17553  }
17554
17555}
17556
17557KeyValuePipe.ɵfac = function KeyValuePipe_Factory(t) {
17558  return new (t || KeyValuePipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers, 16));
17559};
17560
17561KeyValuePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
17562  name: "keyvalue",
17563  type: KeyValuePipe,
17564  pure: false,
17565  standalone: true
17566});
17567
17568(function () {
17569  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](KeyValuePipe, [{
17570    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
17571    args: [{
17572      name: 'keyvalue',
17573      pure: false,
17574      standalone: true
17575    }]
17576  }], function () {
17577    return [{
17578      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers
17579    }];
17580  }, null);
17581})();
17582
17583function defaultComparator(keyValueA, keyValueB) {
17584  const a = keyValueA.key;
17585  const b = keyValueB.key; // if same exit with 0;
17586
17587  if (a === b) return 0; // make sure that undefined are at the end of the sort.
17588
17589  if (a === undefined) return 1;
17590  if (b === undefined) return -1; // make sure that nulls are at the end of the sort.
17591
17592  if (a === null) return 1;
17593  if (b === null) return -1;
17594
17595  if (typeof a == 'string' && typeof b == 'string') {
17596    return a < b ? -1 : 1;
17597  }
17598
17599  if (typeof a == 'number' && typeof b == 'number') {
17600    return a - b;
17601  }
17602
17603  if (typeof a == 'boolean' && typeof b == 'boolean') {
17604    return a < b ? -1 : 1;
17605  } // `a` and `b` are of different types. Compare their string values.
17606
17607
17608  const aString = String(a);
17609  const bString = String(b);
17610  return aString == bString ? 0 : aString < bString ? -1 : 1;
17611}
17612/**
17613 * @license
17614 * Copyright Google LLC All Rights Reserved.
17615 *
17616 * Use of this source code is governed by an MIT-style license that can be
17617 * found in the LICENSE file at https://angular.io/license
17618 */
17619
17620/**
17621 * @ngModule CommonModule
17622 * @description
17623 *
17624 * Formats a value according to digit options and locale rules.
17625 * Locale determines group sizing and separator,
17626 * decimal point character, and other locale-specific configurations.
17627 *
17628 * @see `formatNumber()`
17629 *
17630 * @usageNotes
17631 *
17632 * ### digitsInfo
17633 *
17634 * The value's decimal representation is specified by the `digitsInfo`
17635 * parameter, written in the following format:<br>
17636 *
17637 * ```
17638 * {minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}
17639 * ```
17640 *
17641 *  - `minIntegerDigits`:
17642 * The minimum number of integer digits before the decimal point.
17643 * Default is 1.
17644 *
17645 * - `minFractionDigits`:
17646 * The minimum number of digits after the decimal point.
17647 * Default is 0.
17648 *
17649 *  - `maxFractionDigits`:
17650 * The maximum number of digits after the decimal point.
17651 * Default is 3.
17652 *
17653 * If the formatted value is truncated it will be rounded using the "to-nearest" method:
17654 *
17655 * ```
17656 * {{3.6 | number: '1.0-0'}}
17657 * <!--will output '4'-->
17658 *
17659 * {{-3.6 | number:'1.0-0'}}
17660 * <!--will output '-4'-->
17661 * ```
17662 *
17663 * ### locale
17664 *
17665 * `locale` will format a value according to locale rules.
17666 * Locale determines group sizing and separator,
17667 * decimal point character, and other locale-specific configurations.
17668 *
17669 * When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default.
17670 *
17671 * See [Setting your app locale](guide/i18n-common-locale-id).
17672 *
17673 * ### Example
17674 *
17675 * The following code shows how the pipe transforms values
17676 * according to various format specifications,
17677 * where the caller's default locale is `en-US`.
17678 *
17679 * <code-example path="common/pipes/ts/number_pipe.ts" region='NumberPipe'></code-example>
17680 *
17681 * @publicApi
17682 */
17683
17684
17685class DecimalPipe {
17686  constructor(_locale) {
17687    this._locale = _locale;
17688  }
17689  /**
17690   * @param value The value to be formatted.
17691   * @param digitsInfo Sets digit and decimal representation.
17692   * [See more](#digitsinfo).
17693   * @param locale Specifies what locale format rules to use.
17694   * [See more](#locale).
17695   */
17696
17697
17698  transform(value, digitsInfo, locale) {
17699    if (!isValue(value)) return null;
17700    locale = locale || this._locale;
17701
17702    try {
17703      const num = strToNumber(value);
17704      return formatNumber(num, locale, digitsInfo);
17705    } catch (error) {
17706      throw invalidPipeArgumentError(DecimalPipe, error.message);
17707    }
17708  }
17709
17710}
17711
17712DecimalPipe.ɵfac = function DecimalPipe_Factory(t) {
17713  return new (t || DecimalPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID, 16));
17714};
17715
17716DecimalPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
17717  name: "number",
17718  type: DecimalPipe,
17719  pure: true,
17720  standalone: true
17721});
17722
17723(function () {
17724  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DecimalPipe, [{
17725    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
17726    args: [{
17727      name: 'number',
17728      standalone: true
17729    }]
17730  }], function () {
17731    return [{
17732      type: undefined,
17733      decorators: [{
17734        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
17735        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
17736      }]
17737    }];
17738  }, null);
17739})();
17740/**
17741 * @ngModule CommonModule
17742 * @description
17743 *
17744 * Transforms a number to a percentage
17745 * string, formatted according to locale rules that determine group sizing and
17746 * separator, decimal-point character, and other locale-specific
17747 * configurations.
17748 *
17749 * @see `formatPercent()`
17750 *
17751 * @usageNotes
17752 * The following code shows how the pipe transforms numbers
17753 * into text strings, according to various format specifications,
17754 * where the caller's default locale is `en-US`.
17755 *
17756 * <code-example path="common/pipes/ts/percent_pipe.ts" region='PercentPipe'></code-example>
17757 *
17758 * @publicApi
17759 */
17760
17761
17762class PercentPipe {
17763  constructor(_locale) {
17764    this._locale = _locale;
17765  }
17766  /**
17767   *
17768   * @param value The number to be formatted as a percentage.
17769   * @param digitsInfo Decimal representation options, specified by a string
17770   * in the following format:<br>
17771   * <code>{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}</code>.
17772   *   - `minIntegerDigits`: The minimum number of integer digits before the decimal point.
17773   * Default is `1`.
17774   *   - `minFractionDigits`: The minimum number of digits after the decimal point.
17775   * Default is `0`.
17776   *   - `maxFractionDigits`: The maximum number of digits after the decimal point.
17777   * Default is `0`.
17778   * @param locale A locale code for the locale format rules to use.
17779   * When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default.
17780   * See [Setting your app locale](guide/i18n-common-locale-id).
17781   */
17782
17783
17784  transform(value, digitsInfo, locale) {
17785    if (!isValue(value)) return null;
17786    locale = locale || this._locale;
17787
17788    try {
17789      const num = strToNumber(value);
17790      return formatPercent(num, locale, digitsInfo);
17791    } catch (error) {
17792      throw invalidPipeArgumentError(PercentPipe, error.message);
17793    }
17794  }
17795
17796}
17797
17798PercentPipe.ɵfac = function PercentPipe_Factory(t) {
17799  return new (t || PercentPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID, 16));
17800};
17801
17802PercentPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
17803  name: "percent",
17804  type: PercentPipe,
17805  pure: true,
17806  standalone: true
17807});
17808
17809(function () {
17810  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PercentPipe, [{
17811    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
17812    args: [{
17813      name: 'percent',
17814      standalone: true
17815    }]
17816  }], function () {
17817    return [{
17818      type: undefined,
17819      decorators: [{
17820        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
17821        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
17822      }]
17823    }];
17824  }, null);
17825})();
17826/**
17827 * @ngModule CommonModule
17828 * @description
17829 *
17830 * Transforms a number to a currency string, formatted according to locale rules
17831 * that determine group sizing and separator, decimal-point character,
17832 * and other locale-specific configurations.
17833 *
17834 * {@a currency-code-deprecation}
17835 * <div class="alert is-helpful">
17836 *
17837 * **Deprecation notice:**
17838 *
17839 * The default currency code is currently always `USD` but this is deprecated from v9.
17840 *
17841 * **In v11 the default currency code will be taken from the current locale identified by
17842 * the `LOCALE_ID` token. See the [i18n guide](guide/i18n-common-locale-id) for
17843 * more information.**
17844 *
17845 * If you need the previous behavior then set it by creating a `DEFAULT_CURRENCY_CODE` provider in
17846 * your application `NgModule`:
17847 *
17848 * ```ts
17849 * {provide: DEFAULT_CURRENCY_CODE, useValue: 'USD'}
17850 * ```
17851 *
17852 * </div>
17853 *
17854 * @see `getCurrencySymbol()`
17855 * @see `formatCurrency()`
17856 *
17857 * @usageNotes
17858 * The following code shows how the pipe transforms numbers
17859 * into text strings, according to various format specifications,
17860 * where the caller's default locale is `en-US`.
17861 *
17862 * <code-example path="common/pipes/ts/currency_pipe.ts" region='CurrencyPipe'></code-example>
17863 *
17864 * @publicApi
17865 */
17866
17867
17868class CurrencyPipe {
17869  constructor(_locale, _defaultCurrencyCode = 'USD') {
17870    this._locale = _locale;
17871    this._defaultCurrencyCode = _defaultCurrencyCode;
17872  }
17873  /**
17874   *
17875   * @param value The number to be formatted as currency.
17876   * @param currencyCode The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code,
17877   * such as `USD` for the US dollar and `EUR` for the euro. The default currency code can be
17878   * configured using the `DEFAULT_CURRENCY_CODE` injection token.
17879   * @param display The format for the currency indicator. One of the following:
17880   *   - `code`: Show the code (such as `USD`).
17881   *   - `symbol`(default): Show the symbol (such as `$`).
17882   *   - `symbol-narrow`: Use the narrow symbol for locales that have two symbols for their
17883   * currency.
17884   * For example, the Canadian dollar CAD has the symbol `CA$` and the symbol-narrow `$`. If the
17885   * locale has no narrow symbol, uses the standard symbol for the locale.
17886   *   - String: Use the given string value instead of a code or a symbol.
17887   * For example, an empty string will suppress the currency & symbol.
17888   *   - Boolean (marked deprecated in v5): `true` for symbol and false for `code`.
17889   *
17890   * @param digitsInfo Decimal representation options, specified by a string
17891   * in the following format:<br>
17892   * <code>{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}</code>.
17893   *   - `minIntegerDigits`: The minimum number of integer digits before the decimal point.
17894   * Default is `1`.
17895   *   - `minFractionDigits`: The minimum number of digits after the decimal point.
17896   * Default is `2`.
17897   *   - `maxFractionDigits`: The maximum number of digits after the decimal point.
17898   * Default is `2`.
17899   * If not provided, the number will be formatted with the proper amount of digits,
17900   * depending on what the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) specifies.
17901   * For example, the Canadian dollar has 2 digits, whereas the Chilean peso has none.
17902   * @param locale A locale code for the locale format rules to use.
17903   * When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default.
17904   * See [Setting your app locale](guide/i18n-common-locale-id).
17905   */
17906
17907
17908  transform(value, currencyCode = this._defaultCurrencyCode, display = 'symbol', digitsInfo, locale) {
17909    if (!isValue(value)) return null;
17910    locale = locale || this._locale;
17911
17912    if (typeof display === 'boolean') {
17913      if ((typeof ngDevMode === 'undefined' || ngDevMode) && console && console.warn) {
17914        console.warn(`Warning: the currency pipe has been changed in Angular v5. The symbolDisplay option (third parameter) is now a string instead of a boolean. The accepted values are "code", "symbol" or "symbol-narrow".`);
17915      }
17916
17917      display = display ? 'symbol' : 'code';
17918    }
17919
17920    let currency = currencyCode || this._defaultCurrencyCode;
17921
17922    if (display !== 'code') {
17923      if (display === 'symbol' || display === 'symbol-narrow') {
17924        currency = getCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow', locale);
17925      } else {
17926        currency = display;
17927      }
17928    }
17929
17930    try {
17931      const num = strToNumber(value);
17932      return formatCurrency(num, locale, currency, currencyCode, digitsInfo);
17933    } catch (error) {
17934      throw invalidPipeArgumentError(CurrencyPipe, error.message);
17935    }
17936  }
17937
17938}
17939
17940CurrencyPipe.ɵfac = function CurrencyPipe_Factory(t) {
17941  return new (t || CurrencyPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID, 16), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_CURRENCY_CODE, 16));
17942};
17943
17944CurrencyPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
17945  name: "currency",
17946  type: CurrencyPipe,
17947  pure: true,
17948  standalone: true
17949});
17950
17951(function () {
17952  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CurrencyPipe, [{
17953    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
17954    args: [{
17955      name: 'currency',
17956      standalone: true
17957    }]
17958  }], function () {
17959    return [{
17960      type: undefined,
17961      decorators: [{
17962        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
17963        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
17964      }]
17965    }, {
17966      type: undefined,
17967      decorators: [{
17968        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
17969        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_CURRENCY_CODE]
17970      }]
17971    }];
17972  }, null);
17973})();
17974
17975function isValue(value) {
17976  return !(value == null || value === '' || value !== value);
17977}
17978/**
17979 * Transforms a string into a number (if needed).
17980 */
17981
17982
17983function strToNumber(value) {
17984  // Convert strings to numbers
17985  if (typeof value === 'string' && !isNaN(Number(value) - parseFloat(value))) {
17986    return Number(value);
17987  }
17988
17989  if (typeof value !== 'number') {
17990    throw new Error(`${value} is not a number`);
17991  }
17992
17993  return value;
17994}
17995/**
17996 * @license
17997 * Copyright Google LLC All Rights Reserved.
17998 *
17999 * Use of this source code is governed by an MIT-style license that can be
18000 * found in the LICENSE file at https://angular.io/license
18001 */
18002
18003/**
18004 * @ngModule CommonModule
18005 * @description
18006 *
18007 * Creates a new `Array` or `String` containing a subset (slice) of the elements.
18008 *
18009 * @usageNotes
18010 *
18011 * All behavior is based on the expected behavior of the JavaScript API `Array.prototype.slice()`
18012 * and `String.prototype.slice()`.
18013 *
18014 * When operating on an `Array`, the returned `Array` is always a copy even when all
18015 * the elements are being returned.
18016 *
18017 * When operating on a blank value, the pipe returns the blank value.
18018 *
18019 * ### List Example
18020 *
18021 * This `ngFor` example:
18022 *
18023 * {@example common/pipes/ts/slice_pipe.ts region='SlicePipe_list'}
18024 *
18025 * produces the following:
18026 *
18027 * ```html
18028 * <li>b</li>
18029 * <li>c</li>
18030 * ```
18031 *
18032 * ### String Examples
18033 *
18034 * {@example common/pipes/ts/slice_pipe.ts region='SlicePipe_string'}
18035 *
18036 * @publicApi
18037 */
18038
18039
18040class SlicePipe {
18041  transform(value, start, end) {
18042    if (value == null) return null;
18043
18044    if (!this.supports(value)) {
18045      throw invalidPipeArgumentError(SlicePipe, value);
18046    }
18047
18048    return value.slice(start, end);
18049  }
18050
18051  supports(obj) {
18052    return typeof obj === 'string' || Array.isArray(obj);
18053  }
18054
18055}
18056
18057SlicePipe.ɵfac = function SlicePipe_Factory(t) {
18058  return new (t || SlicePipe)();
18059};
18060
18061SlicePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
18062  name: "slice",
18063  type: SlicePipe,
18064  pure: false,
18065  standalone: true
18066});
18067
18068(function () {
18069  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SlicePipe, [{
18070    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
18071    args: [{
18072      name: 'slice',
18073      pure: false,
18074      standalone: true
18075    }]
18076  }], null, null);
18077})();
18078/**
18079 * @license
18080 * Copyright Google LLC All Rights Reserved.
18081 *
18082 * Use of this source code is governed by an MIT-style license that can be
18083 * found in the LICENSE file at https://angular.io/license
18084 */
18085
18086/**
18087 * A collection of Angular pipes that are likely to be used in each and every application.
18088 */
18089
18090
18091const COMMON_PIPES = [AsyncPipe, UpperCasePipe, LowerCasePipe, JsonPipe, SlicePipe, DecimalPipe, PercentPipe, TitleCasePipe, CurrencyPipe, DatePipe, I18nPluralPipe, I18nSelectPipe, KeyValuePipe];
18092/**
18093 * @license
18094 * Copyright Google LLC All Rights Reserved.
18095 *
18096 * Use of this source code is governed by an MIT-style license that can be
18097 * found in the LICENSE file at https://angular.io/license
18098 */
18099// Note: This does not contain the location providers,
18100// as they need some platform specific implementations to work.
18101
18102/**
18103 * Exports all the basic Angular directives and pipes,
18104 * such as `NgIf`, `NgForOf`, `DecimalPipe`, and so on.
18105 * Re-exported by `BrowserModule`, which is included automatically in the root
18106 * `AppModule` when you create a new app with the CLI `new` command.
18107 *
18108 * @publicApi
18109 */
18110
18111class CommonModule {}
18112
18113CommonModule.ɵfac = function CommonModule_Factory(t) {
18114  return new (t || CommonModule)();
18115};
18116
18117CommonModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
18118  type: CommonModule,
18119  imports: [NgClass, NgComponentOutlet, NgForOf, NgIf, NgTemplateOutlet, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgPlural, NgPluralCase, AsyncPipe, UpperCasePipe, LowerCasePipe, JsonPipe, SlicePipe, DecimalPipe, PercentPipe, TitleCasePipe, CurrencyPipe, DatePipe, I18nPluralPipe, I18nSelectPipe, KeyValuePipe],
18120  exports: [NgClass, NgComponentOutlet, NgForOf, NgIf, NgTemplateOutlet, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgPlural, NgPluralCase, AsyncPipe, UpperCasePipe, LowerCasePipe, JsonPipe, SlicePipe, DecimalPipe, PercentPipe, TitleCasePipe, CurrencyPipe, DatePipe, I18nPluralPipe, I18nSelectPipe, KeyValuePipe]
18121});
18122CommonModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
18123
18124(function () {
18125  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CommonModule, [{
18126    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
18127    args: [{
18128      imports: [COMMON_DIRECTIVES, COMMON_PIPES],
18129      exports: [COMMON_DIRECTIVES, COMMON_PIPES]
18130    }]
18131  }], null, null);
18132})();
18133/**
18134 * @license
18135 * Copyright Google LLC All Rights Reserved.
18136 *
18137 * Use of this source code is governed by an MIT-style license that can be
18138 * found in the LICENSE file at https://angular.io/license
18139 */
18140
18141
18142const PLATFORM_BROWSER_ID = 'browser';
18143const PLATFORM_SERVER_ID = 'server';
18144const PLATFORM_WORKER_APP_ID = 'browserWorkerApp';
18145const PLATFORM_WORKER_UI_ID = 'browserWorkerUi';
18146/**
18147 * Returns whether a platform id represents a browser platform.
18148 * @publicApi
18149 */
18150
18151function isPlatformBrowser(platformId) {
18152  return platformId === PLATFORM_BROWSER_ID;
18153}
18154/**
18155 * Returns whether a platform id represents a server platform.
18156 * @publicApi
18157 */
18158
18159
18160function isPlatformServer(platformId) {
18161  return platformId === PLATFORM_SERVER_ID;
18162}
18163/**
18164 * Returns whether a platform id represents a web worker app platform.
18165 * @publicApi
18166 */
18167
18168
18169function isPlatformWorkerApp(platformId) {
18170  return platformId === PLATFORM_WORKER_APP_ID;
18171}
18172/**
18173 * Returns whether a platform id represents a web worker UI platform.
18174 * @publicApi
18175 */
18176
18177
18178function isPlatformWorkerUi(platformId) {
18179  return platformId === PLATFORM_WORKER_UI_ID;
18180}
18181/**
18182 * @license
18183 * Copyright Google LLC All Rights Reserved.
18184 *
18185 * Use of this source code is governed by an MIT-style license that can be
18186 * found in the LICENSE file at https://angular.io/license
18187 */
18188
18189/**
18190 * @publicApi
18191 */
18192
18193
18194const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Version('14.2.10');
18195/**
18196 * @license
18197 * Copyright Google LLC All Rights Reserved.
18198 *
18199 * Use of this source code is governed by an MIT-style license that can be
18200 * found in the LICENSE file at https://angular.io/license
18201 */
18202
18203/**
18204 * Defines a scroll position manager. Implemented by `BrowserViewportScroller`.
18205 *
18206 * @publicApi
18207 */
18208
18209class ViewportScroller {} // De-sugared tree-shakable injection
18210// See #23917
18211
18212/** @nocollapse */
18213
18214
18215ViewportScroller.ɵprov = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"])({
18216  token: ViewportScroller,
18217  providedIn: 'root',
18218  factory: () => new BrowserViewportScroller((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"])(DOCUMENT), window)
18219}
18219);
18220/**
18221 * Manages the scroll position for a browser window.
18222 */
18223
18224class BrowserViewportScroller {
18225  constructor(document, window) {
18226    this.document = document;
18227    this.window = window;
18228
18229    this.offset = () => [0, 0];
18230  }
18231  /**
18232   * Configures the top offset used when scrolling to an anchor.
18233   * @param offset A position in screen coordinates (a tuple with x and y values)
18234   * or a function that returns the top offset position.
18235   *
18236   */
18237
18238
18239  setOffset(offset) {
18240    if (Array.isArray(offset)) {
18241      this.offset = () => offset;
18242    } else {
18243      this.offset = offset;
18244    }
18245  }
18246  /**
18247   * Retrieves the current scroll position.
18248   * @returns The position in screen coordinates.
18249   */
18250
18251
18252  getScrollPosition() {
18253    if (this.supportsScrolling()) {
18254      return [this.window.pageXOffset, this.window.pageYOffset];
18255    } else {
18256      return [0, 0];
18257    }
18258  }
18259  /**
18260   * Sets the scroll position.
18261   * @param position The new position in screen coordinates.
18262   */
18263
18264
18265  scrollToPosition(position) {
18266    if (this.supportsScrolling()) {
18267      this.window.scrollTo(position[0], position[1]);
18268    }
18269  }
18270  /**
18271   * Scrolls to an element and attempts to focus the element.
18272   *
18273   * Note that the function name here is misleading in that the target string may be an ID for a
18274   * non-anchor element.
18275   *
18276   * @param target The ID of an element or name of the anchor.
18277   *
18278   * @see https://html.spec.whatwg.org/#the-indicated-part-of-the-document
18279   * @see https://html.spec.whatwg.org/#scroll-to-fragid
18280   */
18281
18282
18283  scrollToAnchor(target) {
18284    if (!this.supportsScrolling()) {
18285      return;
18286    }
18287
18288    const elSelected = findAnchorFromDocument(this.document, target);
18289
18290    if (elSelected) {
18291      this.scrollToElement(elSelected); // After scrolling to the element, the spec dictates that we follow the focus steps for the
18292      // target. Rather than following the robust steps, simply attempt focus.
18293      //
18294      // @see https://html.spec.whatwg.org/#get-the-focusable-area
18295      // @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/focus
18296      // @see https://html.spec.whatwg.org/#focusable-area
18297
18298      elSelected.focus();
18299    }
18300  }
18301  /**
18302   * Disables automatic scroll restoration provided by the browser.
18303   */
18304
18305
18306  setHistoryScrollRestoration(scrollRestoration) {
18307    if (this.supportScrollRestoration()) {
18308      const history = this.window.history;
18309
18310      if (history && history.scrollRestoration) {
18311        history.scrollRestoration = scrollRestoration;
18312      }
18313    }
18314  }
18315  /**
18316   * Scrolls to an element using the native offset and the specified offset set on this scroller.
18317   *
18318   * The offset can be used when we know that there is a floating header and scrolling naively to an
18319   * element (ex: `scrollIntoView`) leaves the element hidden behind the floating header.
18320   */
18321
18322
18323  scrollToElement(el) {
18324    const rect = el.getBoundingClientRect();
18325    const left = rect.left + this.window.pageXOffset;
18326    const top = rect.top + this.window.pageYOffset;
18327    const offset = this.offset();
18328    this.window.scrollTo(left - offset[0], top - offset[1]);
18329  }
18330  /**
18331   * We only support scroll restoration when we can get a hold of window.
18332   * This means that we do not support this behavior when running in a web worker.
18333   *
18334   * Lifting this restriction right now would require more changes in the dom adapter.
18335   * Since webworkers aren't widely used, we will lift it once RouterScroller is
18336   * battle-tested.
18337   */
18338
18339
18340  supportScrollRestoration() {
18341    try {
18342      if (!this.supportsScrolling()) {
18343        return false;
18344      } // The `scrollRestoration` property could be on the `history` instance or its prototype.
18345
18346
18347      const scrollRestorationDescriptor = getScrollRestorationProperty(this.window.history) || getScrollRestorationProperty(Object.getPrototypeOf(this.window.history)); // We can write to the `scrollRestoration` property if it is a writable data field or it has a
18348      // setter function.
18349
18350      return !!scrollRestorationDescriptor && !!(scrollRestorationDescriptor.writable || scrollRestorationDescriptor.set);
18351    } catch {
18352      return false;
18353    }
18354  }
18355
18356  supportsScrolling() {
18357    try {
18358      return !!this.window && !!this.window.scrollTo && 'pageXOffset' in this.window;
18359    } catch {
18360      return false;
18361    }
18362  }
18363
18364}
18365
18366function getScrollRestorationProperty(obj) {
18367  return Object.getOwnPropertyDescriptor(obj, 'scrollRestoration');
18368}
18369
18370function findAnchorFromDocument(document, target) {
18371  const documentResult = document.getElementById(target) || document.getElementsByName(target)[0];
18372
18373  if (documentResult) {
18374    return documentResult;
18375  } // `getElementById` and `getElementsByName` won't pierce through the shadow DOM so we
18376  // have to traverse the DOM manually and do the lookup through the shadow roots.
18377
18378
18379  if (typeof document.createTreeWalker === 'function' && document.body && (document.body.createShadowRoot || document.body.attachShadow)) {
18380    const treeWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT);
18381    let currentNode = treeWalker.currentNode;
18382
18383    while (currentNode) {
18384      const shadowRoot = currentNode.shadowRoot;
18385
18386      if (shadowRoot) {
18387        // Note that `ShadowRoot` doesn't support `getElementsByName`
18388        // so we have to fall back to `querySelector`.
18389        const result = shadowRoot.getElementById(target) || shadowRoot.querySelector(`[name="${target}"]`);
18390
18391        if (result) {
18392          return result;
18393        }
18394      }
18395
18396      currentNode = treeWalker.nextNode();
18397    }
18398  }
18399
18400  return null;
18401}
18402/**
18403 * Provides an empty implementation of the viewport scroller.
18404 */
18405
18406
18407class NullViewportScroller {
18408  /**
18409   * Empty implementation
18410   */
18411  setOffset(offset) {}
18412  /**
18413   * Empty implementation
18414   */
18415
18416
18417  getScrollPosition() {
18418    return [0, 0];
18419  }
18420  /**
18421   * Empty implementation
18422   */
18423
18424
18425  scrollToPosition(position) {}
18426  /**
18427   * Empty implementation
18428   */
18429
18430
18431  scrollToAnchor(anchor) {}
18432  /**
18433   * Empty implementation
18434   */
18435
18436
18437  setHistoryScrollRestoration(scrollRestoration) {}
18438
18439}
18440/**
18441 * @license
18442 * Copyright Google LLC All Rights Reserved.
18443 *
18444 * Use of this source code is governed by an MIT-style license that can be
18445 * found in the LICENSE file at https://angular.io/license
18446 */
18447
18448/**
18449 * A wrapper around the `XMLHttpRequest` constructor.
18450 *
18451 * @publicApi
18452 */
18453
18454
18455class XhrFactory {}
18456/**
18457 * @license
18458 * Copyright Google LLC All Rights Reserved.
18459 *
18460 * Use of this source code is governed by an MIT-style license that can be
18461 * found in the LICENSE file at https://angular.io/license
18462 */
18463
18464/**
18465 * Asserts that the application is in development mode. Throws an error if the application is in
18466 * production mode. This assert can be used to make sure that there is no dev-mode code invoked in
18467 * the prod mode accidentally.
18468 */
18469
18470
18471function assertDevMode(checkName) {
18472  if (!ngDevMode) {
18473    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2958
18474    /* RuntimeErrorCode.UNEXPECTED_DEV_MODE_CHECK_IN_PROD_MODE */
18475    , `Unexpected invocation of the ${checkName} in the prod mode. ` + `Please make sure that the prod mode is enabled for production builds.`);
18476  }
18477}
18478/**
18479 * @license
18480 * Copyright Google LLC All Rights Reserved.
18481 *
18482 * Use of this source code is governed by an MIT-style license that can be
18483 * found in the LICENSE file at https://angular.io/license
18484 */
18485// Assembles directive details string, useful for error messages.
18486
18487
18488function imgDirectiveDetails(ngSrc, includeNgSrc = true) {
18489  const ngSrcInfo = includeNgSrc ? `(activated on an <img> element with the \`ngSrc="${ngSrc}"\`) ` : '';
18490  return `The NgOptimizedImage directive ${ngSrcInfo}has detected that`;
18491}
18492/**
18493 * @license
18494 * Copyright Google LLC All Rights Reserved.
18495 *
18496 * Use of this source code is governed by an MIT-style license that can be
18497 * found in the LICENSE file at https://angular.io/license
18498 */
18499// Converts a string that represents a URL into a URL class instance.
18500
18501
18502function getUrl(src, win) {
18503  // Don't use a base URL is the URL is absolute.
18504  return isAbsoluteUrl(src) ? new URL(src) : new URL(src, win.location.href);
18505} // Checks whether a URL is absolute (i.e. starts with `http://` or `https://`).
18506
18507
18508function isAbsoluteUrl(src) {
18509  return /^https?:\/\//.test(src);
18510} // Given a URL, extract the hostname part.
18511// If a URL is a relative one - the URL is returned as is.
18512
18513
18514function extractHostname(url) {
18515  return isAbsoluteUrl(url) ? new URL(url).hostname : url;
18516}
18517
18518function isValidPath(path) {
18519  const isString = typeof path === 'string';
18520
18521  if (!isString || path.trim() === '') {
18522    return false;
18523  } // Calling new URL() will throw if the path string is malformed
18524
18525
18526  try {
18527    const url = new URL(path);
18528    return true;
18529  } catch {
18530    return false;
18531  }
18532}
18533
18534function normalizePath(path) {
18535  return path.endsWith('/') ? path.slice(0, -1) : path;
18536}
18537
18538function normalizeSrc(src) {
18539  return src.startsWith('/') ? src.slice(1) : src;
18540}
18541/**
18542 * @license
18543 * Copyright Google LLC All Rights Reserved.
18544 *
18545 * Use of this source code is governed by an MIT-style license that can be
18546 * found in the LICENSE file at https://angular.io/license
18547 */
18548// Set of origins that are always excluded from the preconnect checks.
18549
18550
18551const INTERNAL_PRECONNECT_CHECK_BLOCKLIST = new Set(['localhost', '127.0.0.1', '0.0.0.0']);
18552/**
18553 * Multi-provider injection token to configure which origins should be excluded
18554 * from the preconnect checks. It can either be a single string or an array of strings
18555 * to represent a group of origins, for example:
18556 *
18557 * ```typescript
18558 *  {provide: PRECONNECT_CHECK_BLOCKLIST, multi: true, useValue: 'https://your-domain.com'}
18559 * ```
18560 *
18561 * or:
18562 *
18563 * ```typescript
18564 *  {provide: PRECONNECT_CHECK_BLOCKLIST, multi: true,
18565 *   useValue: ['https://your-domain-1.com', 'https://your-domain-2.com']}
18566 * ```
18567 *
18568 * @publicApi
18569 * @developerPreview
18570 */
18571
18572const PRECONNECT_CHECK_BLOCKLIST = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('PRECONNECT_CHECK_BLOCKLIST');
18573/**
18574 * Contains the logic to detect whether an image, marked with the "priority" attribute
18575 * has a corresponding `<link rel="preconnect">` tag in the `document.head`.
18576 *
18577 * Note: this is a dev-mode only class, which should not appear in prod bundles,
18578 * thus there is no `ngDevMode` use in the code.
18579 */
18580
18581class PreconnectLinkChecker {
18582  constructor() {
18583    this.document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DOCUMENT);
18584    /**
18585     * Set of <link rel="preconnect"> tags found on this page.
18586     * The `null` value indicates that there was no DOM query operation performed.
18587     */
18588
18589    this.preconnectLinks = null;
18590    /*
18591     * Keep track of all already seen origin URLs to avoid repeating the same check.
18592     */
18593
18594    this.alreadySeen = new Set();
18595    this.window = null;
18596    this.blocklist = new Set(INTERNAL_PRECONNECT_CHECK_BLOCKLIST);
18597    assertDevMode('preconnect link checker');
18598    const win = this.document.defaultView;
18599
18600    if (typeof win !== 'undefined') {
18601      this.window = win;
18602    }
18603
18604    const blocklist = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(PRECONNECT_CHECK_BLOCKLIST, {
18605      optional: true
18606    });
18607
18608    if (blocklist) {
18609      this.populateBlocklist(blocklist);
18610    }
18611  }
18612
18613  populateBlocklist(origins) {
18614    if (Array.isArray(origins)) {
18615      deepForEach(origins, origin => {
18616        this.blocklist.add(extractHostname(origin));
18617      });
18618    } else {
18619      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2957
18620      /* RuntimeErrorCode.INVALID_PRECONNECT_CHECK_BLOCKLIST */
18621      , `The blocklist for the preconnect check was not provided as an array. ` + `Check that the \`PRECONNECT_CHECK_BLOCKLIST\` token is configured as a \`multi: true\` provider.`);
18622    }
18623  }
18624  /**
18625   * Checks that a preconnect resource hint exists in the head fo rthe
18626   * given src.
18627   *
18628   * @param rewrittenSrc src formatted with loader
18629   * @param originalNgSrc ngSrc value
18630   */
18631
18632
18633  assertPreconnect(rewrittenSrc, originalNgSrc) {
18634    if (!this.window) return;
18635    const imgUrl = getUrl(rewrittenSrc, this.window);
18636    if (this.blocklist.has(imgUrl.hostname) || this.alreadySeen.has(imgUrl.origin)) return; // Register this origin as seen, so we don't check it again later.
18637
18638    this.alreadySeen.add(imgUrl.origin);
18639
18640    if (!this.preconnectLinks) {
18641      // Note: we query for preconnect links only *once* and cache the results
18642      // for the entire lifespan of an application, since it's unlikely that the
18643      // list would change frequently. This allows to make sure there are no
18644      // performance implications of making extra DOM lookups for each image.
18645      this.preconnectLinks = this.queryPreconnectLinks();
18646    }
18647
18648    if (!this.preconnectLinks.has(imgUrl.origin)) {
18649      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2956
18650      /* RuntimeErrorCode.PRIORITY_IMG_MISSING_PRECONNECT_TAG */
18651      , `${imgDirectiveDetails(originalNgSrc)} there is no preconnect tag present for this ` + `image. Preconnecting to the origin(s) that serve priority images ensures that these ` + `images are delivered as soon as possible. To fix this, please add the following ` + `element into the <head>
18651 of the document:\n` + `  <link rel="preconnect" href="${imgUrl.origin}">`));
18652    }
18653  }
18654
18655  queryPreconnectLinks() {
18656    const preconnectUrls = new Set();
18657    const selector = 'link[rel=preconnect]';
18658    const links = Array.from(this.document.querySelectorAll(selector));
18659
18660    for (let link of links) {
18661      const url = getUrl(link.href, this.window);
18662      preconnectUrls.add(url.origin);
18663    }
18664
18665    return preconnectUrls;
18666  }
18667
18668  ngOnDestroy() {
18669    this.preconnectLinks?.clear();
18670    this.alreadySeen.clear();
18671  }
18672
18673}
18674
18675PreconnectLinkChecker.ɵfac = function PreconnectLinkChecker_Factory(t) {
18676  return new (t || PreconnectLinkChecker)();
18677};
18678
18679PreconnectLinkChecker.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
18680  token: PreconnectLinkChecker,
18681  factory: PreconnectLinkChecker.ɵfac,
18682  providedIn: 'root'
18683});
18684
18685(function () {
18686  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PreconnectLinkChecker, [{
18687    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
18688    args: [{
18689      providedIn: 'root'
18690    }]
18691  }], function () {
18692    return [];
18693  }, null);
18694})();
18695/**
18696 * Invokes a callback for each element in the array. Also invokes a callback
18697 * recursively for each nested array.
18698 */
18699
18700
18701function deepForEach(input, fn) {
18702  for (let value of input) {
18703    Array.isArray(value) ? deepForEach(value, fn) : fn(value);
18704  }
18705}
18706/**
18707 * @license
18708 * Copyright Google LLC All Rights Reserved.
18709 *
18710 * Use of this source code is governed by an MIT-style license that can be
18711 * found in the LICENSE file at https://angular.io/license
18712 */
18713
18714/**
18715 * Noop image loader that does no transformation to the original src and just returns it as is.
18716 * This loader is used as a default one if more specific logic is not provided in an app config.
18717 *
18718 * @see `ImageLoader`
18719 * @see `NgOptimizedImage`
18720 */
18721
18722
18723const noopImageLoader = config => config.src;
18724/**
18725 * Injection token that configures the image loader function.
18726 *
18727 * @see `ImageLoader`
18728 * @see `NgOptimizedImage`
18729 * @publicApi
18730 * @developerPreview
18731 */
18732
18733
18734const IMAGE_LOADER = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('ImageLoader', {
18735  providedIn: 'root',
18736  factory: () => noopImageLoader
18737});
18738/**
18739 * Internal helper function that makes it easier to introduce custom image loaders for the
18740 * `NgOptimizedImage` directive. It is enough to specify a URL builder function to obtain full DI
18741 * configuration for a given loader: a DI token corresponding to the actual loader function, plus DI
18742 * tokens managing preconnect check functionality.
18743 * @param buildUrlFn a function returning a full URL based on loader's configuration
18744 * @param exampleUrls example of full URLs for a given loader (used in error messages)
18745 * @returns a set of DI providers corresponding to the configured image loader
18746 */
18747
18748function createImageLoader(buildUrlFn, exampleUrls) {
18749  return function provideImageLoader(path, options = {
18750    ensurePreconnect: true
18751  }) {
18752    if (!isValidPath(path)) {
18753      throwInvalidPathError(path, exampleUrls || []);
18754    } // The trailing / is stripped (if provided) to make URL construction (concatenation) easier in
18755    // the individual loader functions.
18756
18757
18758    path = normalizePath(path);
18759
18760    const loaderFn = config => {
18761      if (isAbsoluteUrl(config.src)) {
18762        // Image loader functions expect an image file name (e.g. `my-image.png`)
18763        // or a relative path + a file name (e.g. `/a/b/c/my-image.png`) as an input,
18764        // so the final absolute URL can be constructed.
18765        // When an absolute URL is provided instead - the loader can not
18766        // build a final URL, thus the error is thrown to indicate that.
18767        throwUnexpectedAbsoluteUrlError(path, config.src);
18768      }
18769
18770      return buildUrlFn(path, { ...config,
18771        src: normalizeSrc(config.src)
18772      });
18773    };
18774
18775    const providers = [{
18776      provide: IMAGE_LOADER,
18777      useValue: loaderFn
18778    }];
18779
18780    if (ngDevMode && options.ensurePreconnect === false) {
18781      providers.push({
18782        provide: PRECONNECT_CHECK_BLOCKLIST,
18783        useValue: [path],
18784        multi: true
18785      });
18786    }
18787
18788    return providers;
18789  };
18790}
18791
18792function throwInvalidPathError(path, exampleUrls) {
18793  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2959
18794  /* RuntimeErrorCode.INVALID_LOADER_ARGUMENTS */
18795  , ngDevMode && `Image loader has detected an invalid path (\`${path}\`). ` + `To fix this, supply a path using one of the following formats: ${exampleUrls.join(' or ')}`);
18796}
18797
18798function throwUnexpectedAbsoluteUrlError(path, url) {
18799  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2959
18800  /* RuntimeErrorCode.INVALID_LOADER_ARGUMENTS */
18801  , ngDevMode && `Image loader has detected a \`<img>\` tag with an invalid \`ngSrc\` attribute: ${url}. ` + `This image loader expects \`ngSrc\` to be a relative URL - ` + `however the provided value is an absolute URL. ` + `To fix this, provide \`ngSrc\` as a path relative to the base URL ` + `configured for this loader (\`${path}\`).`);
18802}
18803/**
18804 * @license
18805 * Copyright Google LLC All Rights Reserved.
18806 *
18807 * Use of this source code is governed by an MIT-style license that can be
18808 * found in the LICENSE file at https://angular.io/license
18809 */
18810
18811/**
18812 * Function that generates an ImageLoader for [Cloudflare Image
18813 * Resizing](https://developers.cloudflare.com/images/image-resizing/) and turns it into an Angular
18814 * provider. Note: Cloudflare has multiple image products - this provider is specifically for
18815 * Cloudflare Image Resizing; it will not work with Cloudflare Images or Cloudflare Polish.
18816 *
18817 * @param path Your domain name, e.g. https://mysite.com
18818 * @param options An object with extra configuration:
18819 * - `ensurePreconnect`: boolean flag indicating whether the NgOptimizedImage directive
18820 *                       should verify that there is a corresponding `<link rel="preconnect">`
18821 *                       present in the document's `<head>`.
18822 * @returns Provider that provides an ImageLoader function
18823 *
18824 * @publicApi
18825 * @developerPreview
18826 */
18827
18828
18829const provideCloudflareLoader = createImageLoader(createCloudflareUrl, ngDevMode ? ['https://<ZONE>/cdn-cgi/image/<OPTIONS>/<SOURCE-IMAGE>'] : undefined);
18830
18831function createCloudflareUrl(path, config) {
18832  let params = `format=auto`;
18833
18834  if (config.width) {
18835    params += `,width=${config.width}`;
18836  } // Cloudflare image URLs format:
18837  // https://developers.cloudflare.com/images/image-resizing/url-format/
18838
18839
18840  return `${path}/cdn-cgi/image/${params}/${config.src}`;
18841}
18842/**
18843 * @license
18844 * Copyright Google LLC All Rights Reserved.
18845 *
18846 * Use of this source code is governed by an MIT-style license that can be
18847 * found in the LICENSE file at https://angular.io/license
18848 */
18849
18850/**
18851 * Function that generates an ImageLoader for Cloudinary and turns it into an Angular provider.
18852 *
18853 * @param path Base URL of your Cloudinary images
18854 * This URL should match one of the following formats:
18855 * https://res.cloudinary.com/mysite
18856 * https://mysite.cloudinary.com
18857 * https://subdomain.mysite.com
18858 * @param options An object with extra configuration:
18859 * - `ensurePreconnect`: boolean flag indicating whether the NgOptimizedImage directive
18860 *                       should verify that there is a corresponding `<link rel="preconnect">`
18861 *                       present in the document's `<head>`.
18862 * @returns Set of providers to configure the Cloudinary loader.
18863 *
18864 * @publicApi
18865 * @developerPreview
18866 */
18867
18868
18869const provideCloudinaryLoader = createImageLoader(createCloudinaryUrl, ngDevMode ? ['https://res.cloudinary.com/mysite', 'https://mysite.cloudinary.com', 'https://subdomain.mysite.com'] : undefined);
18870
18871function createCloudinaryUrl(path, config) {
18872  // Cloudinary image URLformat:
18873  // https://cloudinary.com/documentation/image_transformations#transformation_url_structure
18874  // Example of a Cloudinary image URL:
18875  // https://res.cloudinary.com/mysite/image/upload/c_scale,f_auto,q_auto,w_600/marketing/tile-topics-m.png
18876  let params = `f_auto,q_auto`; // sets image format and quality to "auto"
18877
18878  if (config.width) {
18879    params += `,w_${config.width}`;
18880  }
18881
18882  return `${path}/image/upload/${params}/${config.src}`;
18883}
18884/**
18885 * @license
18886 * Copyright Google LLC All Rights Reserved.
18887 *
18888 * Use of this source code is governed by an MIT-style license that can be
18889 * found in the LICENSE file at https://angular.io/license
18890 */
18891
18892/**
18893 * Function that generates an ImageLoader for ImageKit and turns it into an Angular provider.
18894 *
18895 * @param path Base URL of your ImageKit images
18896 * This URL should match one of the following formats:
18897 * https://ik.imagekit.io/myaccount
18898 * https://subdomain.mysite.com
18899 * @param options An object with extra configuration:
18900 * - `ensurePreconnect`: boolean flag indicating whether the NgOptimizedImage directive
18901 *                       should verify that there is a corresponding `<link rel="prec
18901onnect">`
18902 *                       present in the document's `<head>`.
18903 * @returns Set of providers to configure the ImageKit loader.
18904 *
18905 * @publicApi
18906 * @developerPreview
18907 */
18908
18909
18910const provideImageKitLoader = createImageLoader(createImagekitUrl, ngDevMode ? ['https://ik.imagekit.io/mysite', 'https://subdomain.mysite.com'] : undefined);
18911
18912function createImagekitUrl(path, config) {
18913  // Example of an ImageKit image URL:
18914  // https://ik.imagekit.io/demo/tr:w-300,h-300/medium_cafe_B1iTdD0C.jpg
18915  let params = `tr:q-auto`; // applies the "auto quality" transformation
18916
18917  if (config.width) {
18918    params += `,w-${config.width}`;
18919  }
18920
18921  return `${path}/${params}/${config.src}`;
18922}
18923/**
18924 * @license
18925 * Copyright Google LLC All Rights Reserved.
18926 *
18927 * Use of this source code is governed by an MIT-style license that can be
18928 * found in the LICENSE file at https://angular.io/license
18929 */
18930
18931/**
18932 * Function that generates an ImageLoader for Imgix and turns it into an Angular provider.
18933 *
18934 * @param path path to the desired Imgix origin,
18935 * e.g. https://somepath.imgix.net or https://images.mysite.com
18936 * @param options An object with extra configuration:
18937 * - `ensurePreconnect`: boolean flag indicating whether the NgOptimizedImage directive
18938 *                       should verify that there is a corresponding `<link rel="preconnect">`
18939 *                       present in the document's `<head>`.
18940 * @returns Set of providers to configure the Imgix loader.
18941 *
18942 * @publicApi
18943 * @developerPreview
18944 */
18945
18946
18947const provideImgixLoader = createImageLoader(createImgixUrl, ngDevMode ? ['https://somepath.imgix.net/'] : undefined);
18948
18949function createImgixUrl(path, config) {
18950  const url = new URL(`${path}/${config.src}`); // This setting ensures the smallest allowable format is set.
18951
18952  url.searchParams.set('auto', 'format');
18953
18954  if (config.width) {
18955    url.searchParams.set('w', config.width.toString());
18956  }
18957
18958  return url.href;
18959}
18960/**
18961 * @license
18962 * Copyright Google LLC All Rights Reserved.
18963 *
18964 * Use of this source code is governed by an MIT-style license that can be
18965 * found in the LICENSE file at https://angular.io/license
18966 */
18967
18968/**
18969 * Observer that detects whether an image with `NgOptimizedImage`
18970 * is treated as a Largest Contentful Paint (LCP) element. If so,
18971 * asserts that the image has the `priority` attribute.
18972 *
18973 * Note: this is a dev-mode only class and it does not appear in prod bundles,
18974 * thus there is no `ngDevMode` use in the code.
18975 *
18976 * Based on https://web.dev/lcp/#measure-lcp-in-javascript.
18977 */
18978
18979
18980class LCPImageObserver {
18981  constructor() {
18982    // Map of full image URLs -> original `ngSrc` values.
18983    this.images = new Map(); // Keep track of images for which `console.warn` was produced.
18984
18985    this.alreadyWarned = new Set();
18986    this.window = null;
18987    this.observer = null;
18988    assertDevMode('LCP checker');
18989    const win = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DOCUMENT).defaultView;
18990
18991    if (typeof win !== 'undefined' && typeof PerformanceObserver !== 'undefined') {
18992      this.window = win;
18993      this.observer = this.initPerformanceObserver();
18994    }
18995  }
18996  /**
18997   * Inits PerformanceObserver and subscribes to LCP events.
18998   * Based on https://web.dev/lcp/#measure-lcp-in-javascript
18999   */
19000
19001
19002  initPerformanceObserver() {
19003    const observer = new PerformanceObserver(entryList => {
19004      const entries = entryList.getEntries();
19005      if (entries.length === 0) return; // We use the latest entry produced by the `PerformanceObserver` as the best
19006      // signal on which element is actually an LCP one. As an example, the first image to load on
19007      // a page, by virtue of being the only thing on the page so far, is often a LCP candidate
19008      // and gets reported by PerformanceObserver, but isn't necessarily the LCP element.
19009
19010      const lcpElement = entries[entries.length - 1]; // Cast to `any` due to missing `element` on the `LargestContentfulPaint` type of entry.
19011      // See https://developer.mozilla.org/en-US/docs/Web/API/LargestContentfulPaint
19012
19013      const imgSrc = lcpElement.element?.src ?? ''; // Exclude `data:` and `blob:` URLs, since they are not supported by the directive.
19014
19015      if (imgSrc.startsWith('data:') || imgSrc.startsWith('blob:')) return;
19016      const imgNgSrc = this.images.get(imgSrc);
19017
19018      if (imgNgSrc && !this.alreadyWarned.has(imgSrc)) {
19019        this.alreadyWarned.add(imgSrc);
19020        logMissingPriorityWarning(imgSrc);
19021      }
19022    });
19023    observer.observe({
19024      type: 'largest-contentful-paint',
19025      buffered: true
19026    });
19027    return observer;
19028  }
19029
19030  registerImage(rewrittenSrc, originalNgSrc) {
19031    if (!this.observer) return;
19032    this.images.set(getUrl(rewrittenSrc, this.window).href, originalNgSrc);
19033  }
19034
19035  unregisterImage(rewrittenSrc) {
19036    if (!this.observer) return;
19037    this.images.delete(getUrl(rewrittenSrc, this.window).href);
19038  }
19039
19040  ngOnDestroy() {
19041    if (!this.observer) return;
19042    this.observer.disconnect();
19043    this.images.clear();
19044    this.alreadyWarned.clear();
19045  }
19046
19047}
19048
19049LCPImageObserver.ɵfac = function LCPImageObserver_Factory(t) {
19050  return new (t || LCPImageObserver)();
19051};
19052
19053LCPImageObserver.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
19054  token: LCPImageObserver,
19055  factory: LCPImageObserver.ɵfac,
19056  providedIn: 'root'
19057});
19058
19059(function () {
19060  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LCPImageObserver, [{
19061    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
19062    args: [{
19063      providedIn: 'root'
19064    }]
19065  }], function () {
19066    return [];
19067  }, null);
19068})();
19069
19070function logMissingPriorityWarning(ngSrc) {
19071  const directiveDetails = imgDirectiveDetails(ngSrc);
19072  console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2955
19073  /* RuntimeErrorCode.LCP_IMG_MISSING_PRIORITY */
19074  , `${directiveDetails} this image is the Largest Contentful Paint (LCP) ` + `element but was not marked "priority". This image should be marked ` + `"priority" in order to prioritize its loading. ` + `To fix this, add the "priority" attribute.`));
19075}
19076/**
19077 * @license
19078 * Copyright Google LLC All Rights Reserved.
19079 *
19080 * Use of this source code is governed by an MIT-style license that can be
19081 * found in the LICENSE file at https://angular.io/license
19082 */
19083
19084/**
19085 * When a Base64-encoded image is passed as an input to the `NgOptimizedImage` directive,
19086 * an error is thrown. The image content (as a string) might be very long, thus making
19087 * it hard to read an error message if the entire string is included. This const defines
19088 * the number of characters that should be included into the error message. The rest
19089 * of the content is truncated.
19090 */
19091
19092
19093const BASE64_IMG_MAX_LENGTH_IN_ERROR = 50;
19094/**
19095 * RegExpr to determine whether a src in a srcset is using width descriptors.
19096 * Should match something like: "100w, 200w".
19097 */
19098
19099const VALID_WIDTH_DESCRIPTOR_SRCSET = /^((\s*\d+w\s*(,|$)){1,})$/;
19100/**
19101 * RegExpr to determine whether a src in a srcset is using density descriptors.
19102 * Should match something like: "1x, 2x, 50x". Also supports decimals like "1.5x, 1.50x".
19103 */
19104
19105const VALID_DENSITY_DESCRIPTOR_SRCSET = /^((\s*\d+(\.\d+)?x\s*(,|$)){1,})$/;
19106/**
19107 * Srcset values with a density descriptor higher than this value will actively
19108 * throw an error. Such densities are not permitted as they cause image sizes
19109 * to be unreasonably large and slow down LCP.
19110 */
19111
19112const ABSOLUTE_SRCSET_DENSITY_CAP = 3;
19113/**
19114 * Used only in error message text to communicate best practices, as we will
19115 * only throw based on the slightly more conservative ABSOLUTE_SRCSET_DENSITY_CAP.
19116 */
19117
19118const RECOMMENDED_SRCSET_DENSITY_CAP = 2;
19119/**
19120 * Used to determine whether two aspect ratios are similar in value.
19121 */
19122
19123const ASPECT_RATIO_TOLERANCE = .1;
19124/**
19125 * Used to determine whether the image has been requested at an overly
19126 * large size compared to the actual rendered image size (after taking
19127 * into account a typical device pixel ratio). In pixels.
19128 */
19129
19130const OVERSIZED_IMAGE_TOLERANCE = 1000;
19131/**
19132 * Directive that improves image loading performance by enforcing best practices.
19133 *
19134 * `NgOptimizedImage` ensures that the loading of the Largest Contentful Paint (LCP) image is
19135 * prioritized by:
19136 * - Automatically setting the `fetchpriority` attribute on the `<img>` tag
19137 * - Lazy loading non-priority images by default
19138 * - Asserting that there is a corresponding preconnect link tag in the document head
19139 *
19140 * In addition, the directive:
19141 * - Generates appropriate asset URLs if a corresponding `ImageLoader` function is provided
19142 * - Requires that `width` and `height` are set
19143 * - Warns if `width` or `height` have been set incorrectly
19144 * - Warns if the image will be visually distorted when rendered
19145 *
19146 * @usageNotes
19147 * The `NgOptimizedImage` directive is marked as [standalone](guide/standalone-components) and can
19148 * be imported directly.
19149 *
19150 * Follow the steps below to enable and use the directive:
19151 * 1. Import it into the necessary NgModule or a standalone Component.
19152 * 2. Optionally provide an `ImageLoader` if you use an image hosting service.
19153 * 3. Update the necessary `<img>` tags in templates and replace `src` attributes with `ngSrc`.
19154 * Using a `ngSrc` allows the directive to control when the `src` gets set, which triggers an image
19155 * download.
19156 *
19157 * Step 1: import the `NgOptimizedImage` directive.
19158 *
19159 * ```typescript
19160 * import { NgOptimizedImage } from '@angular/common';
19161 *
19162 * // Include it into the necessary NgModule
19163 * @NgModule({
19164 *   imports: [NgOptimizedImage],
19165 * })
19166 * class AppModule {}
19167 *
19168 * // ... or a standalone Component
19169 * @Component({
19170 *   standalone: true
19171 *   imports: [NgOptimizedImage],
19172 * })
19173 * class MyStandaloneComponent {}
19174 * ```
19175 *
19176 * Step 2: configure a loader.
19177 *
19178 * To use the **default loader**: no additional code changes are necessary. The URL returned by the
19179 * generic loader will always match the value of "src". In other words, this loader applies no
19180 * transformations to the resource URL and the value of the `ngSrc` attribute will be used as is.
19181 *
19182 * To use an existing loader for a **third-party image service**: add the provider factory for your
19183 * chosen service to the `providers` array. In the example below, the Imgix loader is used:
19184 *
19185 * ```typescript
19186 * import {provideImgixLoader} from '@angular/common';
19187 *
19188 * // Call the function and add the result to the `providers` array:
19189 * providers: [
19190 *   provideImgixLoader("https://my.base.url/"),
19191 * ],
19192 * ```
19193 *
19194 * The `NgOptimizedImage` directive provides the following functions:
19195 * - `provideCloudflareLoader`
19196 * - `provideCloudinaryLoader`
19197 * - `provideImageKitLoader`
19198 * - `provideImgixLoader`
19199 *
19200 * If you use a different image provider, you can create a custom loader function as described
19201 * below.
19202 *
19203 * To use a **custom loader**: provide your loader function as a value for the `IMAGE_LOADER` DI
19204 * token.
19205 *
19206 * ```typescript
19207 * import {IMAGE_LOADER, ImageLoaderConfig} from '@angular/common';
19208 *
19209 * // Configure the loader using the `IMAGE_LOADER` token.
19210 * providers: [
19211 *   {
19212 *      provide: IMAGE_LOADER,
19213 *      useValue: (config: ImageLoaderConfig) => {
19214 *        return `https://example.com/${config.src}-${config.width}.jpg}`;
19215 *      }
19216 *   },
19217 * ],
19218 * ```
19219 *
19220 * Step 3: update `<img>` tags in templates to use `ngSrc` instead of `src`.
19221 *
19222 * ```
19223 * <img ngSrc="logo.png" width="200" height="100">
19224 * ```
19225 *
19226 * @publicApi
19227 * @developerPreview
19228 */
19229
19230class NgOptimizedImage {
19231  constructor() {
19232    this.imageLoader = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(IMAGE_LOADER);
19233    this.renderer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2);
19234    this.imgElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
19235    this.injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector); // a LCP image observer - should be injected only in the dev mode
19236
19237    this.lcpObserver = ngDevMode ? this.injector.get(LCPImageObserver) : null;
19238    /**
19239     * Calculate the rewritten `src` once and store it.
19240     * This is needed to avoid repetitive calculations and make sure the directive cleanup in the
19241     * `ngOnDestroy` does not rely on the `IMAGE_LOADER` logic (which in turn can rely on some other
19242     * instance that might be already destroyed).
19243     */
19244
19245    this._renderedSrc = null;
19246    this._priority = false;
19247  }
19248  /**
19249   * Previously, the `rawSrc` attribute was used to activate the directive.
19250   * The attribute was renamed to `ngSrc` and this input just produces an error,
19251   * suggesting to switch to `ngSrc` instead.
19252   *
19253   * This error should be removed in v15.
19254   *
19255   * @nodoc
19256   * @deprecated Use `ngSrc` instead.
19257   */
19258
19259
19260  set rawSrc(value) {
19261    if (ngDevMode) {
19262      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952
19263      /* RuntimeErrorCode.INVALID_INPUT */
19264      , `${imgDirectiveDetails(value, false)} the \`rawSrc\` attribute was used ` + `to activate the directive. Newer version of the directive uses the \`ngSrc\` ` + `attribute instead. Please replace \`rawSrc\` with \`ngSrc\` and ` + `\`rawSrcset\` with \`ngSrcset\` attributes in the template to ` + `enable image optimizations.`);
19265    }
19266  }
19267  /**
19268   * The intrinsic width of the image in pixels.
19269   */
19270
19271
19272  set width(value) {
19273    ngDevMode && assertGreaterThanZero(this, value, 'width');
19274    this._width = inputToInteger(value);
19275  }
19276
19277  get width() {
19278    return this._width;
19279  }
19280  /**
19281   * The intrinsic height of the image in pixels.
19282   */
19283
19284
19285  set height(value) {
19286    ngDevMode && assertGreaterThanZero(this, value, 'height');
19287    this._height = inputToInteger(value);
19288  }
19289
19290  get height() {
19291    return this._height;
19292  }
19293  /**
19294   * Indicates whether this image should have a high priority.
19295   */
19296
19297
19298  set priority(value) {
19299    this._priority = inputToBoolean(value);
19300  }
19301
19302  get priority() {
19303    return this._priority;
19304  }
19305
19306  ngOnInit() {
19307    if (ngDevMode) {
19308      assertNonEmptyInput(this, 'ngSrc', this.ngSrc);
19309      assertValidNgSrcset(this, this.ngSrcset);
19310      assertNoConflictingSrc(this);
19311      assertNoConflictingSrcset(this);
19312      assertNotBase64Image(this);
19313      assertNotBlobUrl(this);
19314      assertNonEmptyWidthAndHeight(this);
19315      assertValidLoadingInput(this);
19316      assertNoImageDistortion(this, this.imgElement, this.renderer);
19317
19318      if (this.priority) {
19319        const checker = this.injector.get(PreconnectLinkChecker);
19320        checker.assertPreconnect(this.getRewrittenSrc(), this.ngSrc);
19321      } else {
19322        // Monitor whether an image is an LCP element only in case
19323        // the `priority` attribute is missing. Otherwise, an image
19324        // has the necessary settings and no extra checks are required.
19325        if (this.lcpObserver !== null) {
19326          const ngZone = this.injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
19327          ngZone.runOutsideAngular(() => {
19328            this.lcpObserver.registerImage(this.getRewrittenSrc(), this.ngSrc);
19329          });
19330        }
19331      }
19332    }
19333
19334    this.setHostAttributes();
19335  }
19336
19337  setHostAttributes() {
19338    // Must set width/height explicitly in case they are bound (in which case they will
19339    // only be reflected and not found by the browser)
19340    this.setHostAttribute('width', this.width.toString());
19341    this.setHostAttribute('height', this.height.toString());
19342    this.setHostAttribute('loading', this.getLoadingBehavior());
19343    this.setHostAttribute('fetchpriority', this.getFetchPriority()); // The `src` and `srcset` attributes should be set last since other attributes
19344    // could affect the image's loading behavior.
19345
19346    this.setHostAttribute('src', this.getRewrittenSrc());
19347
19348    if (this.ngSrcset) {
19349      this.setHostAttribute('srcset', this.getRewrittenSrcset());
19350    }
19351  }
19352
19353  ngOnChanges(changes) {
19354    if (ngDevMode) {
19355      assertNoPostInitInputChange(this, changes, ['ngSrc', 'ngSrcset', 'width', 'height', 'priority']);
19356    }
19357  }
19358
19359  getLoadingBehavior() {
19360    if (!this.priority && this.loading !== undefined) {
19361      return this.loading;
19362    }
19363
19364    return this.priority ? 'eager' : 'lazy';
19365  }
19366
19367  getFetchPriority() {
19368    return this.priority ? 'high' : 'auto';
19369  }
19370
19371  getRewrittenSrc() {
19372    // ImageLoaderConfig supports setting a width property. However, we're not setting width here
19373    // because if the developer uses rendered width instead of intrinsic width in the HTML width
19374    // attribute, the image requested may be too small for 2x+ screens.
19375    if (!this._renderedSrc) {
19376      const imgConfig = {
19377        src: this.ngSrc
19378      }; // Cache calculated image src to reuse it later in the code.
19379
19380      this._renderedSrc = this.imageLoader(imgConfig);
19381    }
19382
19383    return this._renderedSrc;
19384  }
19385
19386  getRewrittenSrcset() {
19387    const widthSrcSet = VALID_WIDTH_DESCRIPTOR_SRCSET.test(this.ngSrcset);
19388    const finalSrcs = this.ngSrcset.split(',').filter(src => src !== '').map(srcStr => {
19389      srcStr = srcStr.trim();
19390      const width = widthSrcSet ? parseFloat(srcStr) : parseFloat(srcStr) * this.width;
19391      return `${this.imageLoader({
19392        src: this.ngSrc,
19393        width
19394      })} ${srcStr}`;
19395    });
19396    return finalSrcs.join(', ');
19397  }
19398
19399  ngOnDestroy() {
19400    if (ngDevMode) {
19401      if (!this.priority && this._renderedSrc !== null && this.lcpObserver !== null) {
19402        this.lcpObserver.unregisterImage(this._renderedSrc);
19403      }
19404    }
19405  }
19406
19407  setHostAttribute(name, value) {
19408    this.renderer.setAttribute(this.imgElement, name, value);
19409  }
19410
19411}
19412
19413NgOptimizedImage.ɵfac = function NgOptimizedImage_Factory(t) {
19414  return new (t || NgOptimizedImage)();
19415};
19416
19417NgOptimizedImage.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
19418  type: NgOptimizedImage,
19419  selectors: [["img", "ngSrc", ""], ["img", "rawSrc", ""]],
19420  inputs: {
19421    rawSrc: "rawSrc",
19422    ngSrc: "ngSrc",
19423    ngSrcset: "ngSrcset",
19424    width: "width",
19425    height: "height",
19426    loading: "loading",
19427    priority: "priority",
19428    src: "src",
19429    srcset: "srcset"
19430  },
19431  standalone: true,
19432  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
19433});
19434
19435(function () {
19436  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgOptimizedImage, [{
19437    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
19438    args: [{
19439      standalone: true,
19440      selector: 'img[ngSrc],img[rawSrc]'
19441    }]
19442  }], null, {
19443    rawSrc: [{
19444      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
19445    }],
19446    ngSrc: [{
19447      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
19448    }],
19449    ngSrcset: [{
19450      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
19451    }],
19452    width: [{
19453      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
19454    }],
19455    height: [{
19456      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
19457    }],
19458    loading: [{
19459      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
19460    }],
19461    priority: [{
19462      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
19463    }],
19464    src: [{
19465      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
19466    }],
19467    srcset: [{
19468      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
19469    }]
19470  });
19471})();
19472/***** Helpers *****/
19473
19474/**
19475 * Convert input value to integer.
19476 */
19477
19478
19479function inputToInteger(value) {
19480  return typeof value === 'string' ? parseInt(value, 10) : value;
19481}
19482/**
19483 * Convert input value to boolean.
19484 */
19485
19486
19487function inputToBoolean(value) {
19488  return value != null && `${value}` !== 'false';
19489}
19490/***** Assert functions *****/
19491
19492/**
19493 * Verifies that there is no `src` set on a host element.
19494 */
19495
19496
19497function assertNoConflictingSrc(dir) {
19498  if (dir.src) {
19499    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2950
19500    /* RuntimeErrorCode.UNEXPECTED_SRC_ATTR */
19501    , `${imgDirectiveDetails(dir.ngSrc)} both \`src\` and \`ngSrc\` have been set. ` + `Supplying both of these attributes breaks lazy loading. ` + `The NgOptimizedImage directive sets \`src\` itself based on the value of \`ngSrc\`. ` + `To fix this, please remove the \`src\` attribute.`);
19502  }
19503}
19504/**
19505 * Verifies that there is no `srcset` set on a host element.
19506 */
19507
19508
19509function assertNoConflictingSrcset(dir) {
19510  if (dir.srcset) {
19511    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2951
19512    /* RuntimeErrorCode.UNEXPECTED_SRCSET_ATTR */
19513    , `${imgDirectiveDetails(dir.ngSrc)} both \`srcset\` and \`ngSrcset\` have been set. ` + `Supplying both of these attributes breaks lazy loading. ` + `The NgOptimizedImage directive sets \`srcset\` itself based on the value of ` + `\`ngSrcset\`. To fix this, please remove the \`srcset\` attribute.`);
19514  }
19515}
19516/**
19517 * Verifies that the `ngSrc` is not a Base64-encoded image.
19518 */
19519
19520
19521function assertNotBase64Image(dir) {
19522  let ngSrc = dir.ngSrc.trim();
19523
19524  if (ngSrc.startsWith('data:')) {
19525    if (ngSrc.length > BASE64_IMG_MAX_LENGTH_IN_ERROR) {
19526      ngSrc = ngSrc.substring(0, BASE64_IMG_MAX_LENGTH_IN_ERROR) + '...';
19527    }
19528
19529    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952
19530    /* RuntimeErrorCode.INVALID_INPUT */
19531    , `${imgDirectiveDetails(dir.ngSrc, false)} \`ngSrc\` is a Base64-encoded string ` + `(${ngSrc}). NgOptimizedImage does not support Base64-encoded strings. ` + `To fix this, disable the NgOptimizedImage directive for this element ` + `by removing \`ngSrc\` and using a standard \`src\` attribute instead.`);
19532  }
19533}
19534/**
19535 * Verifies that the `ngSrc` is not a Blob URL.
19536 */
19537
19538
19539function assertNotBlobUrl(dir) {
19540  const ngSrc = dir.ngSrc.trim();
19541
19542  if (ngSrc.startsWith('blob:')) {
19543    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952
19544    /* RuntimeErrorCode.INVALID_INPUT */
19545    , `${imgDirectiveDetails(dir.ngSrc)} \`ngSrc\` was set to a blob URL (${ngSrc}). ` + `Blob URLs are not supported by the NgOptimizedImage directive. ` + `To fix this, disable the NgOptimizedImage directive for this element ` + `by removing \`ngSrc\` and using a regular \`src\` attribute instead.`);
19546  }
19547}
19548/**
19549 * Verifies that the input is set to a non-empty string.
19550 */
19551
19552
19553function assertNonEmptyInput(dir, name, value) {
19554  const isString = typeof value === 'string';
19555  const isEmptyString = isString && value.trim() === '';
19556
19557  if (!isString || isEmptyString) {
19558    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952
19559    /* RuntimeErrorCode.INVALID_INPUT */
19560    , `${imgDirectiveDetails(dir.ngSrc)} \`${name}
19560\` has an invalid value ` + `(\`${value}\`). To fix this, change the value to a non-empty string.`);
19561  }
19562}
19563/**
19564 * Verifies that the `ngSrcset` is in a valid format, e.g. "100w, 200w" or "1x, 2x".
19565 */
19566
19567
19568function assertValidNgSrcset(dir, value) {
19569  if (value == null) return;
19570  assertNonEmptyInput(dir, 'ngSrcset', value);
19571  const stringVal = value;
19572  const isValidWidthDescriptor = VALID_WIDTH_DESCRIPTOR_SRCSET.test(stringVal);
19573  const isValidDensityDescriptor = VALID_DENSITY_DESCRIPTOR_SRCSET.test(stringVal);
19574
19575  if (isValidDensityDescriptor) {
19576    assertUnderDensityCap(dir, stringVal);
19577  }
19578
19579  const isValidSrcset = isValidWidthDescriptor || isValidDensityDescriptor;
19580
19581  if (!isValidSrcset) {
19582    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952
19583    /* RuntimeErrorCode.INVALID_INPUT */
19584    , `${imgDirectiveDetails(dir.ngSrc)} \`ngSrcset\` has an invalid value (\`${value}\`). ` + `To fix this, supply \`ngSrcset\` using a comma-separated list of one or more width ` + `descriptors (e.g. "100w, 200w") or density descriptors (e.g. "1x, 2x").`);
19585  }
19586}
19587
19588function assertUnderDensityCap(dir, value) {
19589  const underDensityCap = value.split(',').every(num => num === '' || parseFloat(num) <= ABSOLUTE_SRCSET_DENSITY_CAP);
19590
19591  if (!underDensityCap) {
19592    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952
19593    /* RuntimeErrorCode.INVALID_INPUT */
19594    , `${imgDirectiveDetails(dir.ngSrc)} the \`ngSrcset\` contains an unsupported image density:` + `\`${value}\`. NgOptimizedImage generally recommends a max image density of ` + `${RECOMMENDED_SRCSET_DENSITY_CAP}x but supports image densities up to ` + `${ABSOLUTE_SRCSET_DENSITY_CAP}x. The human eye cannot distinguish between image densities ` + `greater than ${RECOMMENDED_SRCSET_DENSITY_CAP}x - which makes them unnecessary for ` + `most use cases. Images that will be pinch-zoomed are typically the primary use case for ` + `${ABSOLUTE_SRCSET_DENSITY_CAP}x images. Please remove the high density descriptor and try again.`);
19595  }
19596}
19597/**
19598 * Creates a `RuntimeError` instance to represent a situation when an input is set after
19599 * the directive has initialized.
19600 */
19601
19602
19603function postInitInputChangeError(dir, inputName) {
19604  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2953
19605  /* RuntimeErrorCode.UNEXPECTED_INPUT_CHANGE */
19606  , `${imgDirectiveDetails(dir.ngSrc)} \`${inputName}\` was updated after initialization. ` + `The NgOptimizedImage directive will not react to this input change. ` + `To fix this, switch \`${inputName}\` a static value or wrap the image element ` + `in an *ngIf that is gated on the necessary value.`);
19607}
19608/**
19609 * Verify that none of the listed inputs has changed.
19610 */
19611
19612
19613function assertNoPostInitInputChange(dir, changes, inputs) {
19614  inputs.forEach(input => {
19615    const isUpdated = changes.hasOwnProperty(input);
19616
19617    if (isUpdated && !changes[input].isFirstChange()) {
19618      if (input === 'ngSrc') {
19619        // When the `ngSrc` input changes, we detect that only in the
19620        // `ngOnChanges` hook, thus the `ngSrc` is already set. We use
19621        // `ngSrc` in the error message, so we use a previous value, but
19622        // not the updated one in it.
19623        dir = {
19624          ngSrc: changes[input].previousValue
19625        };
19626      }
19627
19628      throw postInitInputChangeError(dir, input);
19629    }
19630  });
19631}
19632/**
19633 * Verifies that a specified input is a number greater than 0.
19634 */
19635
19636
19637function assertGreaterThanZero(dir, inputValue, inputName) {
19638  const validNumber = typeof inputValue === 'number' && inputValue > 0;
19639  const validString = typeof inputValue === 'string' && /^\d+$/.test(inputValue.trim()) && parseInt(inputValue) > 0;
19640
19641  if (!validNumber && !validString) {
19642    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952
19643    /* RuntimeErrorCode.INVALID_INPUT */
19644    , `${imgDirectiveDetails(dir.ngSrc)} \`${inputName}\` has an invalid value ` + `(\`${inputValue}\`). To fix this, provide \`${inputName}\` ` + `as a number greater than 0.`);
19645  }
19646}
19647/**
19648 * Verifies that the rendered image is not visually distorted. Effectively this is checking:
19649 * - Whether the "width" and "height" attributes reflect the actual dimensions of the image.
19650 * - Whether image styling is "correct" (see below for a longer explanation).
19651 */
19652
19653
19654function assertNoImageDistortion(dir, img, renderer) {
19655  const removeListenerFn = renderer.listen(img, 'load', () => {
19656    removeListenerFn(); // TODO: `clientWidth`, `clientHeight`, `naturalWidth` and `naturalHeight`
19657    // are typed as number, but we run `parseFloat` (which accepts strings only).
19658    // Verify whether `parseFloat` is needed in the cases below.
19659
19660    const renderedWidth = parseFloat(img.clientWidth);
19661    const renderedHeight = parseFloat(img.clientHeight);
19662    const renderedAspectRatio = renderedWidth / renderedHeight;
19663    const nonZeroRenderedDimensions = renderedWidth !== 0 && renderedHeight !== 0;
19664    const intrinsicWidth = parseFloat(img.naturalWidth);
19665    const intrinsicHeight = parseFloat(img.naturalHeight);
19666    const intrinsicAspectRatio = intrinsicWidth / intrinsicHeight;
19667    const suppliedWidth = dir.width;
19668    const suppliedHeight = dir.height;
19669    const suppliedAspectRatio = suppliedWidth / suppliedHeight; // Tolerance is used to account for the impact of subpixel rendering.
19670    // Due to subpixel rendering, the rendered, intrinsic, and supplied
19671    // aspect ratios of a correctly configured image may not exactly match.
19672    // For example, a `width=4030 height=3020` image might have a rendered
19673    // size of "1062w, 796.48h". (An aspect ratio of 1.334... vs. 1.333...)
19674
19675    const inaccurateDimensions = Math.abs(suppliedAspectRatio - intrinsicAspectRatio) > ASPECT_RATIO_TOLERANCE;
19676    const stylingDistortion = nonZeroRenderedDimensions && Math.abs(intrinsicAspectRatio - renderedAspectRatio) > ASPECT_RATIO_TOLERANCE;
19677
19678    if (inaccurateDimensions) {
19679      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2952
19680      /* RuntimeErrorCode.INVALID_INPUT */
19681      , `${imgDirectiveDetails(dir.ngSrc)} the aspect ratio of the image does not match ` + `the aspect ratio indicated by the width and height attributes. ` + `\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h ` + `(aspect-ratio: ${intrinsicAspectRatio}). \nSupplied width and height attributes: ` + `${suppliedWidth}w x ${suppliedHeight}h (aspect-ratio: ${suppliedAspectRatio}). ` + `\nTo fix this, update the width and height attributes.`));
19682    } else if (stylingDistortion) {
19683      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2952
19684      /* RuntimeErrorCode.INVALID_INPUT */
19685      , `${imgDirectiveDetails(dir.ngSrc)} the aspect ratio of the rendered image ` + `does not match the image's intrinsic aspect ratio. ` + `\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h ` + `(aspect-ratio: ${intrinsicAspectRatio}). \nRendered image size: ` + `${renderedWidth}w x ${renderedHeight}h (aspect-ratio: ` + `${renderedAspectRatio}). \nThis issue can occur if "width" and "height" ` + `attributes are added to an image without updating the corresponding ` + `image styling. To fix this, adju
19685st image styling. In most cases, ` + `adding "height: auto" or "width: auto" to the image styling will fix ` + `this issue.`));
19686    } else if (!dir.ngSrcset && nonZeroRenderedDimensions) {
19687      // If `ngSrcset` hasn't been set, sanity check the intrinsic size.
19688      const recommendedWidth = RECOMMENDED_SRCSET_DENSITY_CAP * renderedWidth;
19689      const recommendedHeight = RECOMMENDED_SRCSET_DENSITY_CAP * renderedHeight;
19690      const oversizedWidth = intrinsicWidth - recommendedWidth >= OVERSIZED_IMAGE_TOLERANCE;
19691      const oversizedHeight = intrinsicHeight - recommendedHeight >= OVERSIZED_IMAGE_TOLERANCE;
19692
19693      if (oversizedWidth || oversizedHeight) {
19694        console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2960
19695        /* RuntimeErrorCode.OVERSIZED_IMAGE */
19696        , `${imgDirectiveDetails(dir.ngSrc)} the intrinsic image is significantly ` + `larger than necessary. ` + `\nRendered image size: ${renderedWidth}w x ${renderedHeight}h. ` + `\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h. ` + `\nRecommended intrinsic image size: ${recommendedWidth}w x ${recommendedHeight}h. ` + `\nNote: Recommended intrinsic image size is calculated assuming a maximum DPR of ` + `${RECOMMENDED_SRCSET_DENSITY_CAP}. To improve loading time, resize the image ` + `or consider using the "ngSrcset" and "sizes" attributes.`));
19697      }
19698    }
19699  });
19700}
19701/**
19702 * Verifies that a specified input is set.
19703 */
19704
19705
19706function assertNonEmptyWidthAndHeight(dir) {
19707  let missingAttributes = [];
19708  if (dir.width === undefined) missingAttributes.push('width');
19709  if (dir.height === undefined) missingAttributes.push('height');
19710
19711  if (missingAttributes.length > 0) {
19712    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2954
19713    /* RuntimeErrorCode.REQUIRED_INPUT_MISSING */
19714    , `${imgDirectiveDetails(dir.ngSrc)} these required attributes ` + `are missing: ${missingAttributes.map(attr => `"${attr}"`).join(', ')}. ` + `Including "width" and "height" attributes will prevent image-related layout shifts. ` + `To fix this, include "width" and "height" attributes on the image tag.`);
19715  }
19716}
19717/**
19718 * Verifies that the `loading` attribute is set to a valid input &
19719 * is not used on priority images.
19720 */
19721
19722
19723function assertValidLoadingInput(dir) {
19724  if (dir.loading && dir.priority) {
19725    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952
19726    /* RuntimeErrorCode.INVALID_INPUT */
19727    , `${imgDirectiveDetails(dir.ngSrc)} the \`loading\` attribute ` + `was used on an image that was marked "priority". ` + `Setting \`loading\` on priority images is not allowed ` + `because these images will always be eagerly loaded. ` + `To fix this, remove the “loading” attribute from the priority image.`);
19728  }
19729
19730  const validInputs = ['auto', 'eager', 'lazy'];
19731
19732  if (typeof dir.loading === 'string' && !validInputs.includes(dir.loading)) {
19733    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952
19734    /* RuntimeErrorCode.INVALID_INPUT */
19735    , `${imgDirectiveDetails(dir.ngSrc)} the \`loading\` attribute ` + `has an invalid value (\`${dir.loading}\`). ` + `To fix this, provide a valid value ("lazy", "eager", or "auto").`);
19736  }
19737}
19738/**
19739 * @license
19740 * Copyright Google LLC All Rights Reserved.
19741 *
19742 * Use of this source code is governed by an MIT-style license that can be
19743 * found in the LICENSE file at https://angular.io/license
19744 */
19745
19746/**
19747 * @license
19748 * Copyright Google LLC All Rights Reserved.
19749 *
19750 * Use of this source code is governed by an MIT-style license that can be
19751 * found in the LICENSE file at https://angular.io/license
19752 */
19753
19754/**
19755 * @license
19756 * Copyright Google LLC All Rights Reserved.
19757 *
19758 * Use of this source code is governed by an MIT-style license that can be
19759 * found in the LICENSE file at https://angular.io/license
19760 */
19761// This file only reexports content of the `src` folder. Keep it that way.
19762
19763/**
19764 * @license
19765 * Copyright Google LLC All Rights Reserved.
19766 *
19767 * Use of this source code is governed by an MIT-style license that can be
19768 * found in the LICENSE file at https://angular.io/license
19769 */
19770
19771/**
19772 * Generated bundle index. Do not edit.
19773 */
19774
19775
19776
19777
19778/***/ }),
19779
19780/***/ 8987:
19781/*!********************************************************!*\
19782  !*** ./node_modules/@angular/common/fesm2020/http.mjs ***!
19783  \********************************************************/
19784/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
19785
19786__webpack_require__.r(__webpack_exports__);
19787/* harmony export */ __webpack_require__.d(__webpack_exports__, {
19788/* harmony export */   "HTTP_INTERCEPTORS": () => (/* binding */ HTTP_INTERCEPTORS),
19789/* harmony export */   "HttpBackend": () => (/* binding */ HttpBackend),
19790/* harmony export */   "HttpClient": () => (/* binding */ HttpClient),
19791/* harmony export */   "HttpClientJsonpModule": () => (/* binding */ HttpClientJsonpModule),
19792/* harmony export */   "HttpClientModule": () => (/* binding */ HttpClientModule),
19793/* harmony export */   "HttpClientXsrfModule": () => (/* binding */ HttpClientXsrfModule),
19794/* harmony export */   "HttpContext": () => (/* binding */ HttpContext),
19795/* harmony export */   "HttpContextToken": () => (/* binding */ HttpContextToken),
19796/* harmony export */   "HttpErrorResponse": () => (/* binding */ HttpErrorResponse),
19797/* harmony export */   "HttpEventType": () => (/* binding */ HttpEventType),
19798/* harmony export */   "HttpHandler": () => (/* binding */ HttpHandler),
19799/* harmony export */   "HttpHeaderResponse": () => (/* binding */ HttpHeaderResponse),
19800/* harmony export */   "HttpHeaders": () => (/* binding */ HttpHeaders),
19801/* harmony export */   "HttpParams": () => (/* binding */ HttpParams),
19802/* harmony export */   "HttpRequest": () => (/* binding */ HttpRequest),
19803/* harmony export */   "HttpResponse": () => (/* binding */ HttpResponse),
19804/* harmony export */   "HttpResponseBase": () => (/* binding */ HttpResponseBase),
19805/* harmony export */   "HttpUrlEncodingCodec": () => (/* binding */ HttpUrlEncodingCodec),
19806/* harmony export */   "HttpXhrBackend": () => (/* binding */ HttpXhrBackend),
19807/* harmony export */   "HttpXsrfTokenExtractor": () => (/* binding */ HttpXsrfTokenExtractor),
19808/* harmony export */   "JsonpClientBackend": () => (/* binding */ JsonpClientBackend),
19809/* harmony export */   "JsonpInterceptor": () => (/* binding */ JsonpInterceptor),
19810/* harmony export */   "XhrFactory": () => (/* binding */ XhrFactory),
19811/* harmony export */   "ɵHttpInterceptingHandler": () => (/* binding */ HttpInterceptingHandler)
19812/* harmony export */ });
19813/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @angular/common */ 4666);
19814/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/core */ 2560);
19815/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rxjs */ 4139);
19816/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 2378);
19817/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs/operators */ 1133);
19818/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs/operators */ 9151);
19819/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs/operators */ 6942);
19820/**
19821 * @license Angular v14.2.10
19822 * (c) 2010-2022 Google LLC. https://angular.io/
19823 * License: MIT
19824 */
19825
19826
19827
19828
19829
19830
19831/**
19832 * @license
19833 * Copyright Google LLC All Rights Reserved.
19834 *
19835 * Use of this source code is governed by an MIT-style license that can be
19836 * found in the LICENSE file at https://angular.io/license
19837 */
19838
19839/**
19840 * Transforms an `HttpRequest` into a stream of `HttpEvent`s, one of which will likely be a
19841 * `HttpResponse`.
19842 *
19843 * `HttpHandler` is injectable. When injected, the handler instance dispatches requests to the
19844 * first interceptor in the chain, which dispatches to the second, etc, eventually reaching the
19845 * `HttpBackend`.
19846 *
19847 * In an `HttpInterceptor`, the `HttpHandler` parameter is the next interceptor in the chain.
vendor: 16,594 bytes, lines 19848-20515
19848 *
19849 * @publicApi
19850 */
19851
19852class HttpHandler {}
19853/**
19854 * A final `HttpHandler` which will dispatch the request via browser HTTP APIs to a backend.
19855 *
19856 * Interceptors sit between the `HttpClient` interface and the `HttpBackend`.
19857 *
19858 * When injected, `HttpBackend` dispatches requests directly to the backend, without going
19859 * through the interceptor chain.
19860 *
19861 * @publicApi
19862 */
19863
19864
19865class HttpBackend {}
19866/**
19867 * @license
19868 * Copyright Google LLC All Rights Reserved.
19869 *
19870 * Use of this source code is governed by an MIT-style license that can be
19871 * found in the LICENSE file at https://angular.io/license
19872 */
19873
19874/**
19875 * Represents the header configuration options for an HTTP request.
19876 * Instances are immutable. Modifying methods return a cloned
19877 * instance with the change. The original object is never changed.
19878 *
19879 * @publicApi
19880 */
19881
19882
19883class HttpHeaders {
19884  /**  Constructs a new HTTP header object with the given values.*/
19885  constructor(headers) {
19886    /**
19887     * Internal map of lowercased header names to the normalized
19888     * form of the name (the form seen first).
19889     */
19890    this.normalizedNames = new Map();
19891    /**
19892     * Queued updates to be materialized the next initialization.
19893     */
19894
19895    this.lazyUpdate = null;
19896
19897    if (!headers) {
19898      this.headers = new Map();
19899    } else if (typeof headers === 'string') {
19900      this.lazyInit = () => {
19901        this.headers = new Map();
19902        headers.split('\n').forEach(line => {
19903          const index = line.indexOf(':');
19904
19905          if (index > 0) {
19906            const name = line.slice(0, index);
19907            const key = name.toLowerCase();
19908            const value = line.slice(index + 1).trim();
19909            this.maybeSetNormalizedName(name, key);
19910
19911            if (this.headers.has(key)) {
19912              this.headers.get(key).push(value);
19913            } else {
19914              this.headers.set(key, [value]);
19915            }
19916          }
19917        });
19918      };
19919    } else {
19920      this.lazyInit = () => {
19921        if (typeof ngDevMode === 'undefined' || ngDevMode) {
19922          assertValidHeaders(headers);
19923        }
19924
19925        this.headers = new Map();
19926        Object.keys(headers).forEach(name => {
19927          let values = headers[name];
19928          const key = name.toLowerCase();
19929
19930          if (typeof values === 'string') {
19931            values = [values];
19932          }
19933
19934          if (values.length > 0) {
19935            this.headers.set(key, values);
19936            this.maybeSetNormalizedName(name, key);
19937          }
19938        });
19939      };
19940    }
19941  }
19942  /**
19943   * Checks for existence of a given header.
19944   *
19945   * @param name The header name to check for existence.
19946   *
19947   * @returns True if the header exists, false otherwise.
19948   */
19949
19950
19951  has(name) {
19952    this.init();
19953    return this.headers.has(name.toLowerCase());
19954  }
19955  /**
19956   * Retrieves the first value of a given header.
19957   *
19958   * @param name The header name.
19959   *
19960   * @returns The value string if the header exists, null otherwise
19961   */
19962
19963
19964  get(name) {
19965    this.init();
19966    const values = this.headers.get(name.toLowerCase());
19967    return values && values.length > 0 ? values[0] : null;
19968  }
19969  /**
19970   * Retrieves the names of the headers.
19971   *
19972   * @returns A list of header names.
19973   */
19974
19975
19976  keys() {
19977    this.init();
19978    return Array.from(this.normalizedNames.values());
19979  }
19980  /**
19981   * Retrieves a list of values for a given header.
19982   *
19983   * @param name The header name from which to retrieve values.
19984   *
19985   * @returns A string of values if the header exists, null otherwise.
19986   */
19987
19988
19989  getAll(name) {
19990    this.init();
19991    return this.headers.get(name.toLowerCase()) || null;
19992  }
19993  /**
19994   * Appends a new value to the existing set of values for a header
19995   * and returns them in a clone of the original instance.
19996   *
19997   * @param name The header name for which to append the values.
19998   * @param value The value to append.
19999   *
20000   * @returns A clone of the HTTP headers object with the value appended to the given header.
20001   */
20002
20003
20004  append(name, value) {
20005    return this.clone({
20006      name,
20007      value,
20008      op: 'a'
20009    });
20010  }
20011  /**
20012   * Sets or modifies a value for a given header in a clone of the original instance.
20013   * If the header already exists, its value is replaced with the given value
20014   * in the returned object.
20015   *
20016   * @param name The header name.
20017   * @param value The value or values to set or override for the given header.
20018   *
20019   * @returns A clone of the HTTP headers object with the newly set header value.
20020   */
20021
20022
20023  set(name, value) {
20024    return this.clone({
20025      name,
20026      value,
20027      op: 's'
20028    });
20029  }
20030  /**
20031   * Deletes values for a given header in a clone of the original instance.
20032   *
20033   * @param name The header name.
20034   * @param value The value or values to delete for the given header.
20035   *
20036   * @returns A clone of the HTTP headers object with the given value deleted.
20037   */
20038
20039
20040  delete(name, value) {
20041    return this.clone({
20042      name,
20043      value,
20044      op: 'd'
20045    });
20046  }
20047
20048  maybeSetNormalizedName(name, lcName) {
20049    if (!this.normalizedNames.has(lcName)) {
20050      this.normalizedNames.set(lcName, name);
20051    }
20052  }
20053
20054  init() {
20055    if (!!this.lazyInit) {
20056      if (this.lazyInit instanceof HttpHeaders) {
20057        this.copyFrom(this.lazyInit);
20058      } else {
20059        this.lazyInit();
20060      }
20061
20062      this.lazyInit = null;
20063
20064      if (!!this.lazyUpdate) {
20065        this.lazyUpdate.forEach(update => this.applyUpdate(update));
20066        this.lazyUpdate = null;
20067      }
20068    }
20069  }
20070
20071  copyFrom(other) {
20072    other.init();
20073    Array.from(other.headers.keys()).forEach(key => {
20074      this.headers.set(key, other.headers.get(key));
20075      this.normalizedNames.set(key, other.normalizedNames.get(key));
20076    });
20077  }
20078
20079  clone(update) {
20080    const clone = new HttpHeaders();
20081    clone.lazyInit = !!this.lazyInit && this.lazyInit instanceof HttpHeaders ? this.lazyInit : this;
20082    clone.lazyUpdate = (this.lazyUpdate || []).concat([update]);
20083    return clone;
20084  }
20085
20086  applyUpdate(update) {
20087    const key = update.name.toLowerCase();
20088
20089    switch (update.op) {
20090      case 'a':
20091      case 's':
20092        let value = update.value;
20093
20094        if (typeof value === 'string') {
20095          value = [value];
20096        }
20097
20098        if (value.length === 0) {
20099          return;
20100        }
20101
20102        this.maybeSetNormalizedName(update.name, key);
20103        const base = (update.op === 'a' ? this.headers.get(key) : undefined) || [];
20104        base.push(...value);
20105        this.headers.set(key, base);
20106        break;
20107
20108      case 'd':
20109        const toDelete = update.value;
20110
20111        if (!toDelete) {
20112          this.headers.delete(key);
20113          this.normalizedNames.delete(key);
20114        } else {
20115          let existing = this.headers.get(key);
20116
20117          if (!existing) {
20118            return;
20119          }
20120
20121          existing = existing.filter(value => toDelete.indexOf(value) === -1);
20122
20123          if (existing.length === 0) {
20124            this.headers.delete(key);
20125            this.normalizedNames.delete(key);
20126          } else {
20127            this.headers.set(key, existing);
20128          }
20129        }
20130
20131        break;
20132    }
20133  }
20134  /**
20135   * @internal
20136   */
20137
20138
20139  forEach(fn) {
20140    this.init();
20141    Array.from(this.normalizedNames.keys()).forEach(key => fn(this.normalizedNames.get(key), this.headers.get(key)));
20142  }
20143
20144}
20145/**
20146 * Verifies that the headers object has the right shape: the values
20147 * must be either strings or arrays. Throws an error if an invalid
20148 * header value is present.
20149 */
20150
20151
20152function assertValidHeaders(headers) {
20153  for (const [key, value] of Object.entries(headers)) {
20154    if (typeof value !== 'string' && !Array.isArray(value)) {
20155      throw new Error(`Unexpected value of the \`${key}\` header provided. ` + `Expecting either a string or an array, but got: \`${value}\`.`);
20156    }
20157  }
20158}
20159/**
20160 * @license
20161 * Copyright Google LLC All Rights Reserved.
20162 *
20163 * Use of this source code is governed by an MIT-style license that can be
20164 * found in the LICENSE file at https://angular.io/license
20165 */
20166
20167/**
20168 * Provides encoding and decoding of URL parameter and query-string values.
20169 *
20170 * Serializes and parses URL parameter keys and values to encode and decode them.
20171 * If you pass URL query parameters without encoding,
20172 * the query parameters can be misinterpreted at the receiving end.
20173 *
20174 *
20175 * @publicApi
20176 */
20177
20178
20179class HttpUrlEncodingCodec {
20180  /**
20181   * Encodes a key name for a URL parameter or query-string.
20182   * @param key The key name.
20183   * @returns The encoded key name.
20184   */
20185  encodeKey(key) {
20186    return standardEncoding(key);
20187  }
20188  /**
20189   * Encodes the value of a URL parameter or query-string.
20190   * @param value The value.
20191   * @returns The encoded value.
20192   */
20193
20194
20195  encodeValue(value) {
20196    return standardEncoding(value);
20197  }
20198  /**
20199   * Decodes an encoded URL parameter or query-string key.
20200   * @param key The encoded key name.
20201   * @returns The decoded key name.
20202   */
20203
20204
20205  decodeKey(key) {
20206    return decodeURIComponent(key);
20207  }
20208  /**
20209   * Decodes an encoded URL parameter or query-string value.
20210   * @param value The encoded value.
20211   * @returns The decoded value.
20212   */
20213
20214
20215  decodeValue(value) {
20216    return decodeURIComponent(value);
20217  }
20218
20219}
20220
20221function paramParser(rawParams, codec) {
20222  const map = new Map();
20223
20224  if (rawParams.length > 0) {
20225    // The `window.location.search` can be used while creating an instance of the `HttpParams` class
20226    // (e.g. `new HttpParams({ fromString: window.location.search })`). The `window.location.search`
20227    // may start with the `?` char, so we strip it if it's present.
20228    const params = rawParams.replace(/^\?/, '').split('&');
20229    params.forEach(param => {
20230      const eqIdx = param.indexOf('=');
20231      const [key, val] = eqIdx == -1 ? [codec.decodeKey(param), ''] : [codec.decodeKey(param.slice(0, eqIdx)), codec.decodeValue(param.slice(eqIdx + 1))];
20232      const list = map.get(key) || [];
20233      list.push(val);
20234      map.set(key, list);
20235    });
20236  }
20237
20238  return map;
20239}
20240/**
20241 * Encode input string with standard encodeURIComponent and then un-encode specific characters.
20242 */
20243
20244
20245const STANDARD_ENCODING_REGEX = /%(\d[a-f0-9])/gi;
20246const STANDARD_ENCODING_REPLACEMENTS = {
20247  '40': '@',
20248  '3A': ':',
20249  '24': '$',
20250  '2C': ',',
20251  '3B': ';',
20252  '3D': '=',
20253  '3F': '?',
20254  '2F': '/'
20255};
20256
20257function standardEncoding(v) {
20258  return encodeURIComponent(v).replace(STANDARD_ENCODING_REGEX, (s, t) => STANDARD_ENCODING_REPLACEMENTS[t] ?? s);
20259}
20260
20261function valueToString(value) {
20262  return `${value}`;
20263}
20264/**
20265 * An HTTP request/response body that represents serialized parameters,
20266 * per the MIME type `application/x-www-form-urlencoded`.
20267 *
20268 * This class is immutable; all mutation operations return a new instance.
20269 *
20270 * @publicApi
20271 */
20272
20273
20274class HttpParams {
20275  constructor(options = {}) {
20276    this.updates = null;
20277    this.cloneFrom = null;
20278    this.encoder = options.encoder || new HttpUrlEncodingCodec();
20279
20280    if (!!options.fromString) {
20281      if (!!options.fromObject) {
20282        throw new Error(`Cannot specify both fromString and fromObject.`);
20283      }
20284
20285      this.map = paramParser(options.fromString, this.encoder);
20286    } else if (!!options.fromObject) {
20287      this.map = new Map();
20288      Object.keys(options.fromObject).forEach(key => {
20289        const value = options.fromObject[key]; // convert the values to strings
20290
20291        const values = Array.isArray(value) ? value.map(valueToString) : [valueToString(value)];
20292        this.map.set(key, values);
20293      });
20294    } else {
20295      this.map = null;
20296    }
20297  }
20298  /**
20299   * Reports whether the body includes one or more values for a given parameter.
20300   * @param param The parameter name.
20301   * @returns True if the parameter has one or more values,
20302   * false if it has no value or is not present.
20303   */
20304
20305
20306  has(param) {
20307    this.init();
20308    return this.map.has(param);
20309  }
20310  /**
20311   * Retrieves the first value for a parameter.
20312   * @param param The parameter name.
20313   * @returns The first value of the given parameter,
20314   * or `null` if the parameter is not present.
20315   */
20316
20317
20318  get(param) {
20319    this.init();
20320    const res = this.map.get(param);
20321    return !!res ? res[0] : null;
20322  }
20323  /**
20324   * Retrieves all values for a  parameter.
20325   * @param param The parameter name.
20326   * @returns All values in a string array,
20327   * or `null` if the parameter not present.
20328   */
20329
20330
20331  getAll(param) {
20332    this.init();
20333    return this.map.get(param) || null;
20334  }
20335  /**
20336   * Retrieves all the parameters for this body.
20337   * @returns The parameter names in a string array.
20338   */
20339
20340
20341  keys() {
20342    this.init();
20343    return Array.from(this.map.keys());
20344  }
20345  /**
20346   * Appends a new value to existing values for a parameter.
20347   * @param param The parameter name.
20348   * @param value The new value to add.
20349   * @return A new body with the appended value.
20350   */
20351
20352
20353  append(param, value) {
20354    return this.clone({
20355      param,
20356      value,
20357      op: 'a'
20358    });
20359  }
20360  /**
20361   * Constructs a new body with appended values for the given parameter name.
20362   * @param params parameters and values
20363   * @return A new body with the new value.
20364   */
20365
20366
20367  appendAll(params) {
20368    const updates = [];
20369    Object.keys(params).forEach(param => {
20370      const value = params[param];
20371
20372      if (Array.isArray(value)) {
20373        value.forEach(_value => {
20374          updates.push({
20375            param,
20376            value: _value,
20377            op: 'a'
20378          });
20379        });
20380      } else {
20381        updates.push({
20382          param,
20383          value: value,
20384          op: 'a'
20385        });
20386      }
20387    });
20388    return this.clone(updates);
20389  }
20390  /**
20391   * Replaces the value for a parameter.
20392   * @param param The parameter name.
20393   * @param value The new value.
20394   * @return A new body with the new value.
20395   */
20396
20397
20398  set(param, value) {
20399    return this.clone({
20400      param,
20401      value,
20402      op: 's'
20403    });
20404  }
20405  /**
20406   * Removes a given value or all values from a parameter.
20407   * @param param The parameter name.
20408   * @param value The value to remove, if provided.
20409   * @return A new body with the given value removed, or with all values
20410   * removed if no value is specified.
20411   */
20412
20413
20414  delete(param, value) {
20415    return this.clone({
20416      param,
20417      value,
20418      op: 'd'
20419    });
20420  }
20421  /**
20422   * Serializes the body to an encoded string, where key-value pairs (separated by `=`) are
20423   * separated by `&`s.
20424   */
20425
20426
20427  toString() {
20428    this.init();
20429    return this.keys().map(key => {
20430      const eKey = this.encoder.encodeKey(key); // `a: ['1']` produces `'a=1'`
20431      // `b: []` produces `''`
20432      // `c: ['1', '2']` produces `'c=1&c=2'`
20433
20434      return this.map.get(key).map(value => eKey + '=' + this.encoder.encodeValue(value)).join('&');
20435    }) // filter out empty values because `b: []` produces `''`
20436    // which results in `a=1&&c=1&c=2` instead of `a=1&c=1&c=2` if we don't
20437    .filter(param => param !== '').join('&');
20438  }
20439
20440  clone(update) {
20441    const clone = new HttpParams({
20442      encoder: this.encoder
20443    });
20444    clone.cloneFrom = this.cloneFrom || this;
20445    clone.updates = (this.updates || []).concat(update);
20446    return clone;
20447  }
20448
20449  init() {
20450    if (this.map === null) {
20451      this.map = new Map();
20452    }
20453
20454    if (this.cloneFrom !== null) {
20455      this.cloneFrom.init();
20456      this.cloneFrom.keys().forEach(key => this.map.set(key, this.cloneFrom.map.get(key)));
20457      this.updates.forEach(update => {
20458        switch (update.op) {
20459          case 'a':
20460          case 's':
20461            const base = (update.op === 'a' ? this.map.get(update.param) : undefined) || [];
20462            base.push(valueToString(update.value));
20463            this.map.set(update.param, base);
20464            break;
20465
20466          case 'd':
20467            if (update.value !== undefined) {
20468              let base = this.map.get(update.param) || [];
20469              const idx = base.indexOf(valueToString(update.value));
20470
20471              if (idx !== -1) {
20472                base.splice(idx, 1);
20473              }
20474
20475              if (base.length > 0) {
20476                this.map.set(update.param, base);
20477              } else {
20478                this.map.delete(update.param);
20479              }
20480            } else {
20481              this.map.delete(update.param);
20482              break;
20483            }
20484
20485        }
20486      });
20487      this.cloneFrom = this.updates = null;
20488    }
20489  }
20490
20491}
20492/**
20493 * @license
20494 * Copyright Google LLC All Rights Reserved.
20495 *
20496 * Use of this source code is governed by an MIT-style license that can be
20497 * found in the LICENSE file at https://angular.io/license
20498 */
20499
20500/**
20501 * A token used to manipulate and access values stored in `HttpContext`.
20502 *
20503 * @publicApi
20504 */
20505
20506
20507class HttpContextToken {
20508  constructor(defaultValue) {
20509    this.defaultValue = defaultValue;
20510  }
20511
20512}
20513/**
20514 * Http context stores arbitrary user defined values and ensures type safety without
20515 * actually knowing the types. It is backed by a `Map` and guarantees that keys do n
20515ot clash.
20516 *
20517 * This context is mutable and is shared between cloned requests unless explicitly specified.
20518 *
20519 * @usageNotes
20520 *
20521 * ### Usage Example
20522 *
20523 * ```typescript
20524 * // inside cache.interceptors.ts
20525 * export const IS_CACHE_ENABLED = new HttpContextToken<boolean>(() => false);
20526 *
20527 * export class CacheInterceptor implements HttpInterceptor {
20528 *
20529 *   intercept(req: HttpRequest<any>, delegate: HttpHandler): Observable<HttpEvent<any>> {
20530 *     if (req.context.get(IS_CACHE_ENABLED) === true) {
20531 *       return ...;
20532 *     }
20533 *     return delegate.handle(req);
20534 *   }
20535 * }
20536 *
20537 * // inside a service
20538 *
20539 * this.httpClient.get('/api/weather', {
20540 *   context: new HttpContext().set(IS_CACHE_ENABLED, true)
20541 * }).subscribe(...);
20542 * ```
20543 *
20544 * @publicApi
20545 */
20546
20547
20548class HttpContext {
20549  constructor() {
20550    this.map = new Map();
20551  }
20552  /**
20553   * Store a value in the context. If a value is already present it will be overwritten.
20554   *
20555   * @param token The reference to an instance of `HttpContextToken`.
20556   * @param value The value to store.
20557   *
20558   * @returns A reference to itself for easy chaining.
20559   */
20560
20561
20562  set(token, value) {
20563    this.map.set(token, value);
20564    return this;
20565  }
20566  /**
20567   * Retrieve the value associated with the given token.
20568   *
20569   * @param token The reference to an instance of `HttpContextToken`.
20570   *
20571   * @returns The stored value or default if one is defined.
20572   */
20573
20574
20575  get(token) {
20576    if (!this.map.has(token)) {
20577      this.map.set(token, token.defaultValue());
20578    }
20579
20580    return this.map.get(token);
20581  }
20582  /**
20583   * Delete the value associated with the given token.
20584   *
20585   * @param token The reference to an instance of `HttpContextToken`.
20586   *
20587   * @returns A reference to itself for easy chaining.
20588   */
20589
20590
20591  delete(token) {
20592    this.map.delete(token);
20593    return this;
20594  }
20595  /**
20596   * Checks for existence of a given token.
20597   *
20598   * @param token The reference to an instance of `HttpContextToken`.
20599   *
20600   * @returns True if the token exists, false otherwise.
20601   */
20602
20603
20604  has(token) {
20605    return this.map.has(token);
20606  }
20607  /**
20608   * @returns a list of tokens currently stored in the context.
20609   */
20610
20611
20612  keys() {
20613    return this.map.keys();
20614  }
20615
20616}
20617/**
20618 * @license
20619 * Copyright Google LLC All Rights Reserved.
20620 *
20621 * Use of this source code is governed by an MIT-style license that can be
20622 * found in the LICENSE file at https://angular.io/license
20623 */
20624
20625/**
20626 * Determine whether the given HTTP method may include a body.
20627 */
20628
20629
20630function mightHaveBody(method) {
20631  switch (method) {
20632    case 'DELETE':
20633    case 'GET':
20634    case 'HEAD':
20635    case 'OPTIONS':
20636    case 'JSONP':
20637      return false;
20638
20639    default:
20640      return true;
20641  }
20642}
20643/**
20644 * Safely assert whether the given value is an ArrayBuffer.
20645 *
20646 * In some execution environments ArrayBuffer is not defined.
20647 */
20648
20649
20650function isArrayBuffer(value) {
20651  return typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer;
20652}
20653/**
20654 * Safely assert whether the given value is a Blob.
20655 *
20656 * In some execution environments Blob is not defined.
20657 */
20658
20659
20660function isBlob(value) {
20661  return typeof Blob !== 'undefined' && value instanceof Blob;
20662}
20663/**
20664 * Safely assert whether the given value is a FormData instance.
20665 *
20666 * In some execution environments FormData is not defined.
20667 */
20668
20669
20670function isFormData(value) {
20671  return typeof FormData !== 'undefined' && value instanceof FormData;
20672}
20673/**
20674 * Safely assert whether the given value is a URLSearchParams instance.
20675 *
20676 * In some execution environments URLSearchParams is not defined.
20677 */
20678
20679
20680function isUrlSearchParams(value) {
20681  return typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams;
20682}
20683/**
20684 * An outgoing HTTP request with an optional typed body.
20685 *
20686 * `HttpRequest` represents an outgoing request, including URL, method,
20687 * headers, body, and other request configuration options. Instances should be
20688 * assumed to be immutable. To modify a `HttpRequest`, the `clone`
20689 * method should be used.
20690 *
20691 * @publicApi
20692 */
20693
20694
20695class HttpRequest {
20696  constructor(method, url, third, fourth) {
20697    this.url = url;
20698    /**
20699     * The request body, or `null` if one isn't set.
20700     *
20701     * Bodies are not enforced to be immutable, as they can include a reference to any
20702     * user-defined data type. However, interceptors should take care to preserve
20703     * idempotence by treating them as such.
20704     */
20705
20706    this.body = null;
20707    /**
20708     * Whether this request should be made in a way that exposes progress events.
20709     *
20710     * Progress events are expensive (change detection runs on each event) and so
20711     * they should only be requested if the consumer intends to monitor them.
20712     */
20713
20714    this.reportProgress = false;
vendor: 11,869 bytes, lines 20715-21089
20715    /**
20716     * Whether this request should be sent with outgoing credentials (cookies).
20717     */
20718
20719    this.withCredentials = false;
20720    /**
20721     * The expected response type of the server.
20722     *
20723     * This is used to parse the response appropriately before returning it to
20724     * the requestee.
20725     */
20726
20727    this.responseType = 'json';
20728    this.method = method.toUpperCase(); // Next, need to figure out which argument holds the HttpRequestInit
20729    // options, if any.
20730
20731    let options; // Check whether a body argument is expected. The only valid way to omit
20732    // the body argument is to use a known no-body method like GET.
20733
20734    if (mightHaveBody(this.method) || !!fourth) {
20735      // Body is the third argument, options are the fourth.
20736      this.body = third !== undefined ? third : null;
20737      options = fourth;
20738    } else {
20739      // No body required, options are the third argument. The body stays null.
20740      options = third;
20741    } // If options have been passed, interpret them.
20742
20743
20744    if (options) {
20745      // Normalize reportProgress and withCredentials.
20746      this.reportProgress = !!options.reportProgress;
20747      this.withCredentials = !!options.withCredentials; // Override default response type of 'json' if one is provided.
20748
20749      if (!!options.responseType) {
20750        this.responseType = options.responseType;
20751      } // Override headers if they're provided.
20752
20753
20754      if (!!options.headers) {
20755        this.headers = options.headers;
20756      }
20757
20758      if (!!options.context) {
20759        this.context = options.context;
20760      }
20761
20762      if (!!options.params) {
20763        this.params = options.params;
20764      }
20765    } // If no headers have been passed in, construct a new HttpHeaders instance.
20766
20767
20768    if (!this.headers) {
20769      this.headers = new HttpHeaders();
20770    } // If no context have been passed in, construct a new HttpContext instance.
20771
20772
20773    if (!this.context) {
20774      this.context = new HttpContext();
20775    } // If no parameters have been passed in, construct a new HttpUrlEncodedParams instance.
20776
20777
20778    if (!this.params) {
20779      this.params = new HttpParams();
20780      this.urlWithParams = url;
20781    } else {
20782      // Encode the parameters to a string in preparation for inclusion in the URL.
20783      const params = this.params.toString();
20784
20785      if (params.length === 0) {
20786        // No parameters, the visible URL is just the URL given at creation time.
20787        this.urlWithParams = url;
20788      } else {
20789        // Does the URL already have query parameters? Look for '?'.
20790        const qIdx = url.indexOf('?'); // There are 3 cases to handle:
20791        // 1) No existing parameters -> append '?' followed by params.
20792        // 2) '?' exists and is followed by existing query string ->
20793        //    append '&' followed by params.
20794        // 3) '?' exists at the end of the url -> append params directly.
20795        // This basically amounts to determining the character, if any, with
20796        // which to join the URL and parameters.
20797
20798        const sep = qIdx === -1 ? '?' : qIdx < url.length - 1 ? '&' : '';
20799        this.urlWithParams = url + sep + params;
20800      }
20801    }
20802  }
20803  /**
20804   * Transform the free-form body into a serialized format suitable for
20805   * transmission to the server.
20806   */
20807
20808
20809  serializeBody() {
20810    // If no body is present, no need to serialize it.
20811    if (this.body === null) {
20812      return null;
20813    } // Check whether the body is already in a serialized form. If so,
20814    // it can just be returned directly.
20815
20816
20817    if (isArrayBuffer(this.body) || isBlob(this.body) || isFormData(this.body) || isUrlSearchParams(this.body) || typeof this.body === 'string') {
20818      return this.body;
20819    } // Check whether the body is an instance of HttpUrlEncodedParams.
20820
20821
20822    if (this.body instanceof HttpParams) {
20823      return this.body.toString();
20824    } // Check whether the body is an object or array, and serialize with JSON if so.
20825
20826
20827    if (typeof this.body === 'object' || typeof this.body === 'boolean' || Array.isArray(this.body)) {
20828      return JSON.stringify(this.body);
20829    } // Fall back on toString() for everything else.
20830
20831
20832    return this.body.toString();
20833  }
20834  /**
20835   * Examine the body and attempt to infer an appropriate MIME type
20836   * for it.
20837   *
20838   * If no such type can be inferred, this method will return `null`.
20839   */
20840
20841
20842  detectContentTypeHeader() {
20843    // An empty body has no content type.
20844    if (this.body === null) {
20845      return null;
20846    } // FormData bodies rely on the browser's content type assignment.
20847
20848
20849    if (isFormData(this.body)) {
20850      return null;
20851    } // Blobs usually have their own content type. If it doesn't, then
20852    // no type can be inferred.
20853
20854
20855    if (isBlob(this.body)) {
20856      return this.body.type || null;
20857    } // Array buffers have unknown contents and thus no type can be inferred.
20858
20859
20860    if (isArrayBuffer(this.body)) {
20861      return null;
20862    } // Technically, strings could be a form of JSON data, but it's safe enough
20863    // to assume they're plain strings.
20864
20865
20866    if (typeof this.body === 'string') {
20867      return 'text/plain';
20868    } // `HttpUrlEncodedParams` has its own content-type.
20869
20870
20871    if (this.body instanceof HttpParams) {
20872      return 'application/x-www-form-urlencoded;charset=UTF-8';
20873    } // Arrays, objects, boolean and numbers will be encoded as JSON.
20874
20875
20876    if (typeof this.body === 'object' || typeof this.body === 'number' || typeof this.body === 'boolean') {
20877      return 'application/json';
20878    } // No type could be inferred.
20879
20880
20881    return null;
20882  }
20883
20884  clone(update = {}) {
20885    // For method, url, and responseType, take the current value unless
20886    // it is overridden in the update hash.
20887    const method = update.method || this.method;
20888    const url = update.url || this.url;
20889    const responseType = update.responseType || this.responseType; // The body is somewhat special - a `null` value in update.body means
20890    // whatever current body is present is being overridden with an empty
20891    // body, whereas an `undefined` value in update.body implies no
20892    // override.
20893
20894    const body = update.body !== undefined ? update.body : this.body; // Carefully handle the boolean options to differentiate between
20895    // `false` and `undefined` in the update args.
20896
20897    const withCredentials = update.withCredentials !== undefined ? update.withCredentials : this.withCredentials;
20898    const reportProgress = update.reportProgress !== undefined ? update.reportProgress : this.reportProgress; // Headers and params may be appended to if `setHeaders` or
20899    // `setParams` are used.
20900
20901    let headers = update.headers || this.headers;
20902    let params = update.params || this.params; // Pass on context if needed
20903
20904    const context = update.context ?? this.context; // Check whether the caller has asked to add headers.
20905
20906    if (update.setHeaders !== undefined) {
20907      // Set every requested header.
20908      headers = Object.keys(update.setHeaders).reduce((headers, name) => headers.set(name, update.setHeaders[name]), headers);
20909    } // Check whether the caller has asked to set params.
20910
20911
20912    if (update.setParams) {
20913      // Set every requested param.
20914      params = Object.keys(update.setParams).reduce((params, param) => params.set(param, update.setParams[param]), params);
20915    } // Finally, construct the new HttpRequest using the pieces from above.
20916
20917
20918    return new HttpRequest(method, url, body, {
20919      params,
20920      headers,
20921      context,
20922      reportProgress,
20923      responseType,
20924      withCredentials
20925    });
20926  }
20927
20928}
20929/**
20930 * @license
20931 * Copyright Google LLC All Rights Reserved.
20932 *
20933 * Use of this source code is governed by an MIT-style license that can be
20934 * found in the LICENSE file at https://angular.io/license
20935 */
20936
20937/**
20938 * Type enumeration for the different kinds of `HttpEvent`.
20939 *
20940 * @publicApi
20941 */
20942
20943
20944var HttpEventType;
20945
20946(function (HttpEventType) {
20947  /**
20948   * The request was sent out over the wire.
20949   */
20950  HttpEventType[HttpEventType["Sent"] = 0] = "Sent";
20951  /**
20952   * An upload progress event was received.
20953   */
20954
20955  HttpEventType[HttpEventType["UploadProgress"] = 1] = "UploadProgress";
20956  /**
20957   * The response status code and headers were received.
20958   */
20959
20960  HttpEventType[HttpEventType["ResponseHeader"] = 2] = "ResponseHeader";
20961  /**
20962   * A download progress event was received.
20963   */
20964
20965  HttpEventType[HttpEventType["DownloadProgress"] = 3] = "DownloadProgress";
20966  /**
20967   * The full response including the body was received.
20968   */
20969
20970  HttpEventType[HttpEventType["Response"] = 4] = "Response";
20971  /**
20972   * A custom event from an interceptor or a backend.
20973   */
20974
20975  HttpEventType[HttpEventType["User"] = 5] = "User";
20976})(HttpEventType || (HttpEventType = {}));
20977/**
20978 * Base class for both `HttpResponse` and `HttpHeaderResponse`.
20979 *
20980 * @publicApi
20981 */
20982
20983
20984class HttpResponseBase {
20985  /**
20986   * Super-constructor for all responses.
20987   *
20988   * The single parameter accepted is an initialization hash. Any properties
20989   * of the response passed there will override the default values.
20990   */
20991  constructor(init, defaultStatus = 200
20992  /* HttpStatusCode.Ok */
20993  , defaultStatusText = 'OK') {
20994    // If the hash has values passed, use them to initialize the response.
20995    // Otherwise use the default values.
20996    this.headers = init.headers || new HttpHeaders();
20997    this.status = init.status !== undefined ? init.status : defaultStatus;
20998    this.statusText = init.statusText || defaultStatusText;
20999    this.url = init.url || null; // Cache the ok value to avoid defining a getter.
21000
21001    this.ok = this.status >= 200 && this.status < 300;
21002  }
21003
21004}
21005/**
21006 * A partial HTTP response which only includes the status and header data,
21007 * but no response body.
21008 *
21009 * `HttpHeaderResponse` is a `HttpEvent` available on the response
21010 * event stream, only when progress events are requested.
21011 *
21012 * @publicApi
21013 */
21014
21015
21016class HttpHeaderResponse extends HttpResponseBase {
21017  /**
21018   * Create a new `HttpHeaderResponse` with the given parameters.
21019   */
21020  constructor(init = {}) {
21021    super(init);
21022    this.type = HttpEventType.ResponseHeader;
21023  }
21024  /**
21025   * Copy this `HttpHeaderResponse`, overriding its contents with the
21026   * given parameter hash.
21027   */
21028
21029
21030  clone(update = {}) {
21031    // Perform a straightforward initialization of the new HttpHeaderResponse,
21032    // overriding the current parameters with new ones if given.
21033    return new HttpHeaderResponse({
21034      headers: update.headers || this.headers,
21035      status: update.status !== undefined ? update.status : this.status,
21036      statusText: update.statusText || this.statusText,
21037      url: update.url || this.url || undefined
21038    });
21039  }
21040
21041}
21042/**
21043 * A full HTTP response, including a typed response body (which may be `null`
21044 * if one was not returned).
21045 *
21046 * `HttpResponse` is a `HttpEvent` available on the response event
21047 * stream.
21048 *
21049 * @publicApi
21050 */
21051
21052
21053class HttpResponse extends HttpResponseBase {
21054  /**
21055   * Construct a new `HttpResponse`.
21056   */
21057  constructor(init = {}) {
21058    super(init);
21059    this.type = HttpEventType.Response;
21060    this.body = init.body !== undefined ? init.body : null;
21061  }
21062
21063  clone(update = {}) {
21064    return new HttpResponse({
21065      body: update.body !== undefined ? update.body : this.body,
21066      headers: update.headers || this.headers,
21067      status: update.status !== undefined ? update.status : this.status,
21068      statusText: update.statusText || this.statusText,
21069      url: update.url || this.url || undefined
21070    });
21071  }
21072
21073}
21074/**
21075 * A response that represents an error or failure, either from a
21076 * non-successful HTTP status, an error while executing the request,
21077 * or some other failure which occurred during the parsing of the response.
21078 *
21079 * Any error returned on the `Observable` response stream will be
21080 * wrapped in an `HttpErrorResponse` to provide additional context about
21081 * the state of the HTTP layer when the error occurred. The error property
21082 * will contain either a wrapped Error object or the error response returned
21083 * from the server.
21084 *
21085 * @publicApi
21086 */
21087
21088
21089class HttpErrorResponse extends HttpResponseBase {
21090  constructor(init) {
21091    // Initialize with a default status of 0 / Unknown Error.
21092    super(init, 0, 'Unknown Error');
21093    this.name = 'HttpErrorResponse';
21094    /**
21095     * Errors are never okay, even when the status code is in the 2xx success range.
21096     */
21097
21098    this.ok = false; // If the response was successful, then this was a parse error. Otherwise, it was
21099    // a protocol-level failure of some sort. Either the request failed in transit
21100    // or the server returned an unsuccessful status code.
21101
21102    if (this.status >= 200 && this.status < 300) {
21103      this.message = `Http failure during parsing for ${init.url || '(unknown url)'}`;
21104    } else {
21105      this.message = `Http failure response for ${init.url || '(unknown url)'}: ${init.status} ${init.statusText}`;
21106    }
21107
21108    this.error = init.error || null;
21109  }
21110
21111}
21112/**
21113 * @license
21114 * Copyright Google LLC All Rights Reserved.
21115 *
21116 * Use of this source code is governed by an MIT-style license that can be
21117 * found in the LICENSE file at https://angular.io/license
21118 */
21119
21120/**
21121 * Constructs an instance of `HttpRequestOptions<T>` from a source `HttpMethodOptions` and
21122 * the given `body`. This function clones the object and adds the body.
21123 *
21124 * Note that the `responseType` *options* value is a String that identifies the
21125 * single data type of the response.
21126 * A single overload version of the method handles each response type.
21127 * The value of `responseType` cannot be a union, as the combined signature could imply.
21128 *
21129 */
21130
21131
21132function addBody(options, body) {
21133  return {
21134    body,
21135    headers: options.headers,
21136    context: options.context,
21137    observe: options.observe,
21138    params: options.params,
21139    reportProgress: options.reportProgress,
21140    responseType: options.responseType,
21141    withCredentials: options.withCredentials
21142  };
21143}
21144/**
21145 * Performs HTTP requests.
21146 * This service is available as an injectable class, with methods to perform HTTP requests.
21147 * Each request method has multiple signatures, and the return type varies based on
21148 * the signature that is called (mainly the values of `observe` and `responseType`).
21149 *
21150 * Note that the `responseType` *options* value is a String that identifies the
21151 * single data type of the response.
21152 * A single overload version of the method handles each response type.
21153 * The value of `responseType` cannot be a union, as the combined signature could imply.
21154
21155 *
21156 * @usageNotes
21157 * Sample HTTP requests for the [Tour of Heroes](/tutorial/toh-pt0) application.
21158 *
21159 * ### HTTP Request Example
21160 *
21161 * ```
21162 *  // GET heroes whose name contains search term
21163 * searchHeroes(term: string): observable<Hero[]>{
21164 *
21165 *  const params = new HttpParams({fromString: 'name=term'});
21166 *    return this.httpClient.request('GET', this.heroesUrl, {responseType:'json', params});
21167 * }
21168 * ```
21169 *
21170 * Alternatively, the parameter string can be used without invoking HttpParams
21171 * by directly joining to the URL.
21172 * ```
21173 * this.httpClient.request('GET', this.heroesUrl + '?' + 'name=term', {responseType:'json'});
21174 * ```
21175 *
21176 *
21177 * ### JSONP Example
21178 * ```
21179 * requestJsonp(url, callback = 'callback') {
21180 *  return this.httpClient.jsonp(this.heroesURL, callback);
21181 * }
21182 * ```
21183 *
21184 * ### PATCH Example
21185 * ```
21186 * // PATCH one of the heroes' name
21187 * patchHero (id: number, heroName: string): Observable<{}> {
21188 * const url = `${this.heroesUrl}/${id}`;   // PATCH api/heroes/42
21189 *  return this.httpClient.patch(url, {name: heroName}, httpOptions)
21190 *    .pipe(catchError(this.handleError('patchHero')));
21191 * }
21192 * ```
21193 *
21194 * @see [HTTP Guide](guide/http)
21195 * @see [HTTP Request](api/common/http/HttpRequest)
21196 *
21197 * @publicApi
21198 */
21199
21200
21201class HttpClient {
21202  constructor(handler) {
21203    this.handler = handler;
21204  }
21205  /**
21206   * Constructs an observable for a generic HTTP request that, when subscribed,
21207   * fires the request through the chain of registered interceptors and on to the
21208   * server.
21209   *
21210   * You can pass an `HttpRequest` directly as the only parameter. In this case,
21211   * the call returns an observable of the raw `HttpEvent` stream.
21212   *
21213   * Alternatively you can pass an HTTP method as the first parameter,
21214   * a URL string as the second, and an options hash containing the request body as the third.
21215   * See `addBody()`. In this case, the specified `responseType` and `observe` options determine the
21216   * type of returned observable.
21217   *   * The `responseType` value determines how a successful response body is parsed.
21218   *   * If `responseType` is the default `json`, you can pass a type interface for the resulting
21219   * object as a type parameter to the call.
21220   *
21221   * The `observe` value determines the return type, according to what you are interested in
21222   * observing.
21223   *   * An `observe` value of events returns an observable of the raw `HttpEvent` stream, including
21224   * progress events by default.
21225   *   * An `observe` value of response returns an observable of `HttpResponse<T>`,
21226   * where the `T` parameter depends on the `responseType` and any optionally provided type
21227   * parameter.
21228   *   * An `observe` value of body returns an observable of `<T>` with the same `T` body type.
21229   *
21230   */
21231
21232
21233  request(first, url, options = {}) {
21234    let req; // First, check whether the primary argument is an instance of `HttpRequest`.
21235
21236    if (first instanceof HttpRequest) {
21237      // It is. The other arguments must be undefined (per the signatures) and can be
21238      // ignored.
21239      req = first;
21240    } else {
21241      // It's a string, so it represents a URL. Construct a request based on it,
21242      // and incorporate the remaining arguments (assuming `GET` unless a method is
21243      // provided.
21244      // Figure out the headers.
21245      let headers = undefined;
21246
21247      if (options.headers instanceof HttpHeaders) {
21248        headers = options.headers;
21249      } else {
21250        headers = new HttpHeaders(options.headers);
21251      } // Sort out parameters.
21252
21253
21254      let params = undefined;
21255
21256      if (!!options.params) {
21257        if (options.params instanceof HttpParams) {
21258          params = options.params;
21259        } else {
21260          params = new HttpParams({
21261            fromObject: options.params
21262          });
21263        }
21264      } // Construct the request.
21265
21266
21267      req = new HttpRequest(first, url, options.body !== undefined ? options.body : null, {
21268        headers,
21269        context: options.context,
21270        params,
21271        reportProgress: options.reportProgress,
21272        // By default, JSON is assumed to be returned for all calls.
21273        responseType: options.responseType || 'json',
21274        withCredentials: options.withCredentials
21275      });
21276    } // Start with an Observable.of() the initial request, and run the handler (which
21277    // includes all interceptors) inside a concatMap(). This way, the handler runs
21278    // inside an Observable chain, which causes interceptors to be re-run on every
21279    // subscription (this also makes retries re-run the handler, including interceptors).
21280
21281
21282    const events$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)(req).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_1__.concatMap)(req => this.handler.handle(req))); // If coming via the API signature which accepts a previously constructed HttpRequest,
21283    // the only option is to get the event stream. Otherwise, return the event stream if
21284    // that is what was requested.
21285
21286    if (first instanceof HttpRequest || options.observe === 'events') {
21287      return events$;
21288    } // The requested stream contains either the full response or the body. In either
21289    // case, the first step is to filter the event stream to extract a stream of
21290    // responses(s).
21291
21292
21293    const res$ = events$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.filter)(event => event instanceof HttpResponse)); // Decide which stream to return.
21294
21295    switch (options.observe || 'body') {
21296      case 'body':
21297        // The requested stream is the body. Map the response stream to the response
21298        // body. This could be done more simply, but a misbehaving interceptor might
21299        // transform the response body into a different format and ignore the requested
21300        // responseType. Guard against this by validating that the response is of the
21301        // requested type.
21302        switch (req.responseType) {
21303          case 'arraybuffer':
21304            return res$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(res => {
21305              // Validate that the body is an ArrayBuffer.
21306              if (res.body !== null && !(res.body instanceof ArrayBuffer)) {
21307                throw new Error('Response is not an ArrayBuffer.');
21308              }
21309
21310              return res.body;
21311            }));
21312
21313          case 'blob':
21314            return res$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(res => {
21315              // Validate that the body is a Blob.
21316              if (res.body !== null && !(res.body instanceof Blob)) {
21317                throw new Error('Response is not a Blob.');
21318              }
21319
21320              return res.body;
21321            }));
21322
21323          case 'text':
21324            return res$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(res => {
21325              // Validate that the body is a string.
21326              if (res.body !== null && typeof res.body !== 'string') {
21327                throw new Error('Response is not a string.');
21328              }
21329
21330              return res.body;
21331            }));
21332
21333          case 'json':
21334          default:
21335            // No validation needed for JSON responses, as they can be of any type.
21336            return res$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(res => res.body));
21337        }
21338
21339      case 'response':
21340        // The response stream was requested directly, so return it.
21341        return res$;
21342
21343      default:
21344        // Guard against new future observe types being added.
21345        throw new Error(`Unreachable: unhandled observe type ${options.observe}}`);
21346    }
21347  }
21348  /**
21349   * Constructs an observable that, when subscribed, causes the configured
21350   * `DELETE` request to execute on the server. See the individual overloads for
21351   * details on the return type.
21352   *
21353   * @param url     The endpoint URL.
21354   * @param options The HTTP options to send with the request.
21355   *
21356   */
21357
21358
21359  delete(url, options = {}) {
21360    return this.request('DELETE', url, options);
21361  }
21362  /**
21363   * Constructs an observable that, when subscribed, causes the configured
21364   * `GET` request to execute on the server. See the individual overloads for
21365   * details on the return type.
21366   */
21367
21368
21369  get(url, options = {}) {
21370    return this.request('GET', url, options);
21371  }
21372  /**
21373   * Constructs an observable that, when subscribed, causes the configured
21374   * `HEAD` request to execute on the server. The `HEAD` method returns
21375   * meta information about the resource without transferring the
21376   * resource itself. See the individual overloads for
21377   * details on the return type.
21378   */
21379
21380
21381  head(url, options = {}) {
21382    return this.request('HEAD', url, options);
21383  }
21384  /**
21385   * Constructs an `Observable` that, when subscribed, causes a request with the special method
21386   * `JSONP` to be dispatched via the interceptor pipeline.
21387   * The [JSONP pattern](https://en.wikipedia.org/wiki/JSONP) works around limitations of certain
21388   * API endpoints that don't support newer,
21389   * and preferable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) protocol.
21390   * JSONP treats the endpoint API as a JavaScript file and tricks the browser to process the
21391   * requests even if the API endpoint is not located on the same domain (origin) as the client-side
21392   * application making the request.
21393   * The endpoint API must support JSONP callback for JSONP requests to work.
21394   * The resource API returns the JSON response wrapped in a callback function.
21395   * You can pass the callback function name as one of the query parameters.
21396   * Note that JSONP requests can only be used with `GET` requests.
21397   *
21398   * @param url The resource URL.
21399   * @param callbackParam The callback function name.
21400   *
21401   */
21402
21403
21404  jsonp(url, callbackParam) {
21405    return this.request('JSONP', url, {
21406      params: new HttpParams().append(callbackParam, 'JSONP_CALLBACK'),
21407      observe: 'body',
21408      responseType: 'json'
21409    });
21410  }
21411  /**
21412   * Constructs an `Observable` that, when subscribed, causes the configured
21413   * `OPTIONS` request to execute on the server. This method allows the client
21414   * to determine the supported HTTP methods and other capabilities of an endpoint,
21415   * without implying a resource action. See the individual overloads for
21416   * details on the return type.
21417   */
21418
21419
21420  options(url, options = {}) {
21421    return this.request('OPTIONS', url, options);
21422  }
21423  /**
21424   * Constructs an observable that, when subscribed, causes the configured
21425   * `PATCH` request to execute on the server. See the individual overloads for
21426   * details on the return type.
21427   */
21428
21429
21430  patch(url, body, options = {}) {
21431    return this.request('PATCH', url, addBody(options, body));
21432  }
21433  /**
21434   * Constructs an observable that, when subscribed, causes the configured
21435   * `POST` request to execute on the server. The server responds with the location of
21436   * the replaced resource. See the individual overloads for
21437   * details on the return type.
21438   */
21439
21440
21441  post(url, body, options = {}) {
21442    return this.request('POST', url, addBody(options, body));
21443  }
21444  /**
21445   * Constructs an observable that, when subscribed, causes the configured
21446   * `PUT` request to execute on the server. The `PUT` method replaces an existing resource
21447   * with a new set of values.
21448   * See the individual overloads for details on the return type.
21449   */
21450
21451
21452  put(url, body, options = {}) {
21453    return this.request('PUT', url, addBody(options, body));
21454  }
21455
21456}
21457
21458HttpClient.ɵfac = function HttpClient_Factory(t) {
21459  return new (t || HttpClient)(_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](HttpHandler));
21460};
21461
21462HttpClient.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjectable"]({
21463  token: HttpClient,
21464  factory: HttpClient.ɵfac
21465});
21466
21467(function () {
21468  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](HttpClient, [{
21469    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injectable
21470  }], function () {
21471    return [{
21472      type: HttpHandler
21473    }];
21474  }, null);
21475})();
21476/**
21477 * @license
21478 * Copyright Google LLC All Rights Reserved.
21479 *
21480 * Use of this source code is governed by an MIT-style license that can be
21481 * found in the LICENSE file at https://angular.io/license
21482 */
21483
21484/**
21485 * `HttpHandler` which applies an `HttpInterceptor` to an `HttpRequest`.
21486 *
21487 *
21488 */
21489
21490
21491class HttpInterceptorHandler {
21492  constructor(next, interceptor) {
21493    this.next = next;
21494    this.interceptor = interceptor;
21495  }
21496
21497  handle(req) {
21498    return this.interceptor.intercept(req, this.next);
21499  }
21500
21501}
21502/**
21503 * A multi-provider token that represents the array of registered
21504 * `HttpInterceptor` objects.
21505 *
21506 * @publicApi
21507 */
21508
21509
21510const HTTP_INTERCEPTORS = new _angular_core__WEBPACK_IMPORTED_MODULE_4__.InjectionToken('HTTP_INTERCEPTORS');
21511
21512class NoopInterceptor {
21513  intercept(req, next) {
21514    return next.handle(req);
21515  }
21516
21517}
21518
21519NoopInterceptor.ɵfac = function NoopInterceptor_Factory(t) {
21520  return new (t || NoopInterceptor)();
21521};
21522
21523NoopInterceptor.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjectable"]({
21524  token: NoopInterceptor,
21525  factory: NoopInterceptor.ɵfac
21526});
21527
21528(function () {
21529  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](NoopInterceptor, [{
21530    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injectable
21531  }], null, null);
21532})();
21533/**
21534 * @license
21535 * Copyright Google LLC All Rights Reserved.
21536 *
21537 * Use of this source code is governed by an MIT-style license that can be
21538 * found in the LICENSE file at https://angular.io/license
21539 */
21540// Every request made through JSONP needs a callback name that's unique across the
21541// whole page. Each request is assigned an id and the callback name is constructed
21542// from that. The next id to be assigned is tracked in a global variable here that
21543// is shared among all applications on the page.
21544
21545
21546let nextRequestId = 0;
21547/**
21548 * When a pending <script> is unsubscribed we'll move it to this document, so it won't be
21549 * executed.
21550 */
21551
21552let foreignDocument; // Error text given when a JSONP script is injected, but doesn't invoke the callback
21553// passed in its URL.
21554
21555const JSONP_ERR_NO_CALLBACK = 'JSONP injected script did not invoke callback.'; // Error text given when a request is passed to the JsonpClientBackend that doesn't
21556// have a request method JSONP.
21557
21558const JSONP_ERR_WRONG_METHOD = 'JSONP requests must use JSONP request method.';
21559const JSONP_ERR_WRONG_RESPONSE_TYPE = 'JSONP requests must use Json response type.'; // Error text given when a request is passed to the JsonpClientBackend that has
21560// headers set
21561
21562const JSONP_ERR_HEADERS_NOT_SUPPORTED = 'JSONP requests do not support headers.';
21563/**
21564 * DI token/abstract type representing a map of JSONP callbacks.
21565 *
21566 * In the browser, this should always be the `window` object.
21567 *
21568 *
21569 */
21570
21571class JsonpCallbackContext {}
21572/**
21573 * Processes an `HttpRequest` with the JSONP method,
21574 * by performing JSONP style requests.
21575 * @see `HttpHandler`
21576 * @see `HttpXhrBackend`
21577 *
21578 * @publicApi
21579 */
21580
21581
21582class JsonpClientBackend {
21583  constructor(callbackMap, document) {
21584    this.callbackMap = callbackMap;
21585    this.document = document;
21586    /**
21587     * A resolved promise that can be used to schedule microtasks in the event handlers.
21588     */
21589
21590    this.resolvedPromise = Promise.resolve();
21591  }
21592  /**
21593   * Get the name of the next callback method, by incrementing the global `nextRequestId`.
21594   */
21595
21596
21597  nextCallback() {
21598    return `ng_jsonp_callback_${nextRequestId++}`;
21599  }
21600  /**
21601   * Processes a JSONP request and returns an event stream of the results.
21602   * @param req The request object.
21603   * @returns An observable of the response events.
21604   *
21605   */
21606
21607
21608  handle(req) {
21609    // Firstly, check both the method and response type. If either doesn't match
21610    // then the request was improperly routed here and cannot be handled.
21611    if (req.method !== 'JSONP') {
21612      throw new Error(JSONP_ERR_WRONG_METHOD);
21613    } else if (req.responseType !== 'json') {
21614      throw new Error(JSONP_ERR_WRONG_RESPONSE_TYPE);
21615    } // Check the request headers. JSONP doesn't support headers and
21616    // cannot set any that were supplied.
21617
21618
21619    if (req.headers.keys().length > 0) {
21620      throw new Error(JSONP_ERR_HEADERS_NOT_SUPPORTED);
21621    } // Everything else happens inside the Observable boundary.
21622
21623
21624    return new rxjs__WEBPACK_IMPORTED_MODULE_5__.Observable(observer => {
21625      // The first step to make a request is to generate the callback name, and replace the
21626      // callback placeholder in the URL with the name. Care has to be taken here to ensure
21627      // a trailing &, if matched, gets inserted back into the URL in the correct place.
21628      const callback = this.nextCallback();
21629      const url = req.urlWithParams.replace(/=JSONP_CALLBACK(&|$)/, `=${callback}$1`); // Construct the <script> tag and point it at the URL.
21630
21631      const node = this.document.createElement('script');
21632      node.src = url; // A JSONP request requires waiting for multiple callbacks. These variables
21633      // are closed over and track state across those callbacks.
21634      // The response object, if one has been received, or null otherwise.
21635
21636      let body = null; // Whether the response callback has been called.
21637
21638      let finished = false; // Set the response callback in this.callbackMap (which will be the window
21639      // object in the browser. The script being loaded via the <script> tag will
21640      // eventually call this callback.
21641
21642      this.callbackMap[callback] = data => {
21643        // Data has been received from the JSONP script. Firstly, delete this callback.
21644        delete this.callbackMap[callback]; // Set state to indicate data was received.
21645
21646        body = data;
21647        finished = true;
21648      }; // cleanup() is a utility closure that removes the <script> from the page and
21649      // the response callback from the window. This logic is used in both the
21650      // success, error, and cancellation paths, so it's extracted out for convenience.
21651
21652
21653      const cleanup = () => {
21654        // Remove the <script> tag if it's still on the page.
21655        if (node.parentNode) {
21656          node.parentNode.removeChild(node);
21657        } // Remove the response callback from the callbackMap (window object in the
21658        // browser).
21659
21660
21661        delete this.callbackMap[callback];
21662      }; // onLoad() is the success callback which runs after the response callback
21663      // if the JSONP script loads successfully. The event itself is unimportant.
21664      // If something went wrong, onLoad() may run without the response callback
21665      // having been invoked.
21666
21667
21668      const onLoad = event => {
21669        // We wrap it in an extra Promise, to ensure the microtask
21670        // is scheduled after the loaded endpoint has executed any potential microtask itself,
21671        // which is not guaranteed in Internet Explorer and EdgeHTML. See issue #39496
21672        this.resolvedPromise.then(() => {
21673          // Cleanup the page.
21674          cleanup(); // Check whether the response callback has run.
21675
21676          if (!finished) {
21677            // It hasn't, something went wrong with the request. Return an error via
21678            // the Observable error path. All JSONP errors have status 0.
21679            observer.error(new HttpErrorResponse({
21680              url,
21681              status: 0,
21682              statusText: 'JSONP Error',
21683              error: new Error(JSONP_ERR_NO_CALLBACK)
21684            }));
21685            return;
21686          } // Success. body either contains the response body or null if none was
21687          // returned.
21688
21689
21690          observer.next(new HttpResponse({
21691            body,
21692            status: 200
21693            /* HttpStatusCode.Ok */
21694            ,
21695            statusText: 'OK',
21696            url
21697          })); // Complete the stream, the response is over.
21698
21699          observer.complete();
21700        });
21701      }; // onError() is the error callback, which runs if the script returned generates
21702      // a Javascript error. It emits the error via the Observable error channel as
21703      // a HttpErrorResponse.
21704
21705
21706      const onError = error => {
21707        cleanup(); // Wrap the error in a HttpErrorResponse.
21708
21709        observer.error(new HttpErrorResponse({
21710          error,
21711          status: 0,
21712          statusText: 'JSONP Error',
21713          url
21714        }));
21715      }; // Subscribe to both the success (load) and error events on the <script> tag,
21716      // and add it to the page.
21717
21718
21719      node.addEventListener('load', onLoad);
21720      node.addEventListener('error', onError);
21721      this.document.body.appendChild(node); // The request has now been successfully sent.
21722
21723      observer.next({
21724        type: HttpEventType.Sent
21725      }); // Cancellation handler.
21726
21727      return () => {
21728        if (!finished) {
21729          this.removeListeners(node);
21730        } // And finally, clean up the page.
21731
21732
21733        cleanup();
21734      };
21735    });
21736  }
21737
21738  removeListeners(script) {
21739    // Issue #34818
21740    // Changing <script>'s ownerDocument will prevent it from execution.
21741    // https://html.spec.whatwg.org/multipage/scripting.html#execute-the-script-block
21742    if (!foreignDocument) {
21743      foreignDocument = this.document.implementation.createHTMLDocument();
21744    }
21745
21746    foreignDocument.adoptNode(script);
21747  }
21748
21749}
21750
21751JsonpClientBackend.ɵfac = function JsonpClientBackend_Factory(t) {
21752  return new (t || JsonpClientBackend)(_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](JsonpCallbackContext), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_6__.DOCUMENT));
21753};
21754
21755JsonpClientBackend.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjectable"]({
21756  token: JsonpClientBackend,
21757  factory: JsonpClientBackend.ɵfac
21758});
21759
21760(function () {
21761  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](JsonpClientBackend, [{
21762    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injectable
21763  }], function () {
21764    return [{
21765      type: JsonpCallbackContext
21766    }, {
21767      type: undefined,
21768      decorators: [{
21769        type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Inject,
21770        args: [_angular_common__WEBPACK_IMPORTED_MODULE_6__.DOCUMENT]
21771      }]
21772    }];
21773  }, null);
21774})();
21775/**
21776 * Identifies requests with the method JSONP and
21777 * shifts them to the `JsonpClientBackend`.
21778 *
21779 * @see `HttpInterceptor`
21780 *
21781 * @publicApi
21782 */
21783
21784
21785class JsonpInterceptor {
21786  constructor(jsonp) {
21787    this.jsonp = jsonp;
21788  }
21789  /**
21790   * Identifies and handles a given JSONP request.
21791   * @param req The outgoing request object to handle.
21792   * @param next The next interceptor in the chain, or the backend
21793   * if no interceptors remain in the chain.
21794   * @returns An observable of the event stream.
21795   */
21796
21797
21798  intercept(req, next) {
21799    if (req.method === 'JSONP') {
21800      return this.jsonp.handle(req);
21801    } // Fall through for normal HTTP requests.
21802
21803
21804    return next.handle(req);
21805  }
21806
21807}
21808
21809JsonpInterceptor.ɵfac = function JsonpInterceptor_Factory(t) {
21810  return new (t || JsonpInterceptor)(_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](JsonpClientBackend));
21811};
21812
21813JsonpInterceptor.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjectable"]({
21814  token: JsonpInterceptor,
21815  factory: JsonpInterceptor.ɵfac
21816});
21817
21818(function () {
21819  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](JsonpInterceptor, [{
21820    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injectable
21821  }], function () {
21822    return [{
21823      type: JsonpClientBackend
21824    }];
21825  }, null);
21826})();
21827/**
21828 * @license
21829 * Copyright Google LLC All Rights Reserved.
21830 *
21831 * Use of this source code is governed by an MIT-style license that can be
21832 * found in the LICENSE file at https://angular.io/license
21833 */
21834
21835
21836const XSSI_PREFIX = /^\)\]\}',?\n/;
21837/**
21838 * Determine an appropriate URL for the response, by checking either
21839 * XMLHttpRequest.responseURL or the X-Request-URL header.
21840 */
21841
21842function getResponseUrl(xhr) {
21843  if ('responseURL' in xhr && xhr.responseURL) {
21844    return xhr.responseURL;
21845  }
21846
21847  if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
21848    return xhr.getResponseHeader('X-Request-URL');
21849  }
21850
21851  return null;
21852}
21853/**
21854 * Uses `XMLHttpRequest` to send requests to a backend server.
21855 * @see `HttpHandler`
21856 * @see `JsonpClientBackend`
21857 *
21858 * @publicApi
21859 */
21860
21861
21862class HttpXhrBackend {
21863  constructor(xhrFactory) {
21864    this.xhrFactory = xhrFactory;
21865  }
21866  /**
21867   * Processes a request and returns a stream of response events.
21868   * @param req The request object.
21869   * @returns An observable of the response events.
21870   */
21871
21872
21873  handle(req) {
21874    // Quick check to give a better error message when a user attempts to use
21875    // HttpClient.jsonp() without installing the HttpClientJsonpModule
21876    if (req.method === 'JSONP') {
21877      throw new Error(`Attempted to construct Jsonp request without HttpClientJsonpModule installed.`);
21878    } // Everything happens on Observable subscription.
21879
21880
21881    return new rxjs__WEBPACK_IMPORTED_MODULE_5__.Observable(observer => {
21882      // Start by setting up the XHR object with request method, URL, and withCredentials flag.
21883      const xhr = this.xhrFactory.build();
21884      xhr.open(req.method, req.urlWithParams);
21885
21886      if (!!req.withCredentials) {
21887        xhr.withCredentials = true;
21888      } // Add all the requested headers.
21889
21890
21891      req.headers.forEach((name, values) => xhr.setRequestHeader(name, values.join(','))); // Add an Accept header if one isn't present already.
21892
21893      if (!req.headers.has('Accept')) {
21894        xhr.setRequestHeader('Accept', 'application/json, text/plain, */*');
21895      } // Auto-detect the Content-Type header if one isn't present already.
21896
21897
21898      if (!req.headers.has('Content-Type')) {
21899        const detectedType = req.detectContentTypeHeader(); // Sometimes Content-Type detection fails.
21900
21901        if (detectedType !== null) {
21902          xhr.setRequestHeader('Content-Type', detectedType);
21903        }
21904      } // Set the responseType if one was requested.
21905
21906
21907      if (req.responseType) {
21908        const responseType = req.responseType.toLowerCase(); // JSON responses need to be processed as text. This is because if the server
21909        // returns an XSSI-prefixed JSON response, the browser will fail to parse it,
21910        // xhr.response will be null, and xhr.responseText cannot be accessed to
21911        // retrieve the prefixed JSON data in order to strip the prefix. Thus, all JSON
21912        // is parsed by first requesting text and then applying JSON.parse.
21913
21914        xhr.responseType = responseType !== 'json' ? responseType : 'text';
21915      } // Serialize the request body if one is present. If not, this will be set to null.
21916
21917
21918      const reqBody = req.serializeBody(); // If progress events are enabled, response headers will be delivered
21919      // in two events - the HttpHeaderResponse event and the full HttpResponse
21920      // event. However, since response headers don't change in between these
21921      // two events, it doesn't make sense to parse them twice. So headerResponse
21922      // caches the data extracted from the response whenever it's first parsed,
21923      // to ensure parsing isn't duplicated.
21924
21925      let headerResponse = null; // partialFromXhr extracts the HttpHeaderResponse from the current XMLHttpRequest
21926      // state, and memoizes it into headerResponse.
21927
21928      const partialFromXhr = () => {
21929        if (headerResponse !== null) {
21930          return headerResponse;
21931        }
21932
21933        const statusText = xhr.statusText || 'OK'; // Parse headers from XMLHttpRequest - this step is lazy.
21934
21935        const headers = new HttpHeaders(xhr.getAllResponseHeaders()); // Read the response URL from the XMLHttpResponse instance and fall back on the
21936        // request URL.
21937
21938        const url = getResponseUrl(xhr) || req.url; // Construct the HttpHeaderResponse and memoize it.
21939
21940        headerResponse = new HttpHeaderResponse({
21941          headers,
21942          status: xhr.status,
21943          statusText,
21944          url
21945        });
21946        return headerResponse;
21947      }; // Next, a few closures are defined for the various events which XMLHttpRequest can
21948      // emit. This allows them to be unregistered as event listeners later.
21949      // First up is the load event, which represents a response being fully available.
21950
21951
21952      const onLoad = () => {
21953        // Read response state from the memoized partial data.
21954        let {
21955          headers,
21956          status,
21957          statusText,
21958          url
21959        } = partialFromXhr(); // The body will be read out if present.
21960
21961        let body = null;
21962
21963        if (status !== 204
21964        /* HttpStatusCode.NoContent */
21965        ) {
21966          // Use XMLHttpRequest.response if set, responseText otherwise.
21967          body = typeof xhr.response === 'undefined' ? xhr.responseText : xhr.response;
21968        } // Normalize another potential bug (this one comes from CORS).
21969
21970
21971        if (status === 0) {
21972          status = !!body ? 200
21973          /* HttpStatusCode.Ok */
21974          : 0;
21975        } // ok determines whether the response will be transmitted on the event or
21976        // error channel. Unsuccessful status codes (not 2xx) will always be errors,
21977        // but a successful status code can still result in an error if the user
21978        // asked for JSON data and the body cannot be parsed as such.
21979
21980
21981        let ok = status >= 200 && status < 300; // Check whether the body needs to be parsed as JSON (in many cases the browser
21982        // will have done that already).
21983
21984        if (req.responseType === 'json' && typeof body === 'string') {
21985          // Save the original body, before attempting XSSI prefix stripping.
21986          const originalBody = body;
21987          body = body.replace(XSSI_PREFIX, '');
21988
21989          try {
21990            // Attempt the parse. If it fails, a parse error should be delivered to the user.
21991            body = body !== '' ? JSON.parse(body) : null;
21992          } catch (error) {
21993            // Since the JSON.parse failed, it's reasonable to assume this might not have been a
21994            // JSON response. Restore the original body (including any XSSI prefix) to deliver
21995            // a better error response.
21996            body = originalBody; // If this was an error request to begin with, leave it as a string, it probably
21997            // just isn't JSON. Otherwise, deliver the parsing error to the user.
21998
21999            if (ok) {
22000              // Even though the response status was 2xx, this is still an error.
22001              ok = false; // The parse error contains the text of the body that failed to parse.
22002
22003              body = {
22004                error,
22005                text: body
22006              };
22007            }
22008          }
22009        }
22010
22011        if (ok) {
22012          // A successful response is delivered on the event stream.
22013          observer.next(new HttpResponse({
22014            body,
22015            headers,
22016            status,
22017            statusText,
22018            url: url || undefined
22019          })); // The full body has been received and delivered, no further events
22020          // are possible. This request is complete.
22021
22022          observer.complete();
22023        } else {
22024          // An unsuccessful request is delivered on the error channel.
22025          observer.error(new HttpErrorResponse({
22026            // The error in this case is the response body (error from the server).
22027            error: body,
22028            headers,
22029            status,
22030            statusText,
22031            url: url || undefined
22032          }));
22033        }
22034      }; // The onError callback is called when something goes wrong at the network level.
22035      // Connection timeout, DNS error, offline, etc. These are actual errors, and are
22036      // transmitted on the error channel.
22037
22038
22039      const onError = error => {
22040        const {
22041          url
22042        } = partialFromXhr();
22043        const res = new HttpErrorResponse({
22044          error,
22045          status: xhr.status || 0,
22046          statusText: xhr.statusText || 'Unknown Error',
22047          url: url || undefined
22048        });
22049        observer.error(res);
22050      }; // The sentHeaders flag tracks whether the HttpResponseHeaders event
22051      // has been sent on the stream. This is necessary to track if progress
22052      // is enabled since the event will be sent on only the first download
22053      // progress event.
22054
22055
22056      let sentHeaders = false; // The download progress event handler, which is only registered if
22057      // progress events are enabled.
22058
22059      const onDownProgress = event => {
22060        // Send the HttpResponseHeaders event if it hasn't been sent already.
22061        if (!sentHeaders) {
22062          observer.next(partialFromXhr());
22063          sentHeaders = true;
22064        } // Start building the download progress event to deliver on the response
22065        // event stream.
22066
22067
22068        let progressEvent = {
22069          type: HttpEventType.DownloadProgress,
22070          loaded: event.loaded
22071        }; // Set the total number of bytes in the event if it's available.
22072
22073        if (event.lengthComputable) {
22074          progressEvent.total = event.total;
22075        } // If the request was for text content and a partial response is
22076        // available on XMLHttpRequest, include it in the progress event
22077        // to allow for streaming reads.
22078
22079
22080        if (req.responseType === 'text' && !!xhr.responseText) {
22081          progressEvent.partialText = xhr.responseText;
22082        } // Finally, fire the event.
22083
22084
22085        observer.next(progressEvent);
22086      }; // The upload progress event handler, which is only registered if
22087      // progress events are enabled.
22088
22089
22090      const onUpProgress = event => {
22091        // Upload progress events are simpler. Begin building the progress
22092        // event.
22093        let progress = {
22094          type: HttpEventType.UploadProgress,
22095          loaded: event.loaded
22096        }; // If the total number of bytes being uploaded is available, include
22097        // it.
22098
22099        if (event.lengthComputable) {
22100          progress.total = event.total;
22101        } // Send the event.
22102
22103
22104        observer.next(progress);
22105      }; // By default, register for load and error events.
22106
22107
22108      xhr.addEventListener('load', onLoad);
22109      xhr.addEventListener('error', onError);
22110      xhr.addEventListener('timeout', onError);
22111      xhr.addEventListener('abort', onError); // Progress events are only enabled if requested.
22112
22113      if (req.reportProgress) {
22114        // Download progress is always enabled if requested.
22115        xhr.addEventListener('progress', onDownProgress); // Upload progress depends on whether there is a body to upload.
22116
22117        if (reqBody !== null && xhr.upload) {
22118          xhr.upload.addEventListener('progress', onUpProgress);
22119        }
22120      } // Fire the request, and notify the event stream that it was fired.
22121
22122
22123      xhr.send(reqBody);
22124      observer.next({
22125        type: HttpEventType.Sent
22126      }); // This is the return from the Observable function, which is the
22127      // request cancellation handler.
22128
22129      return () => {
22130        // On a cancellation, remove all registered event listeners.
22131        xhr.removeEventListener('error', onError);
22132        xhr.removeEventListener('abort', onError);
22133        xhr.removeEventListener('load', onLoad);
22134        xhr.removeEventListener('timeout', onError);
22135
22136        if (req.reportProgress) {
22137          xhr.removeEventListener('progress', onDownProgress);
22138
22139          if (reqBody !== null && xhr.upload) {
22140            xhr.upload.removeEventListener('progress', onUpProgress);
22141          }
22142        } // Finally, abort the in-flight request.
22143
22144
22145        if (xhr.readyState !== xhr.DONE) {
22146          xhr.abort();
22147        }
22148      };
22149    });
22150  }
22151
22152}
22153
22154HttpXhrBackend.ɵfac = function HttpXhrBackend_Factory(t) {
22155  return new (t || HttpXhrBackend)(_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_6__.XhrFactory)
22155);
22156};
22157
22158HttpXhrBackend.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjectable"]({
22159  token: HttpXhrBackend,
22160  factory: HttpXhrBackend.ɵfac
22161});
22162
22163(function () {
22164  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](HttpXhrBackend, [{
22165    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injectable
22166  }], function () {
22167    return [{
22168      type: _angular_common__WEBPACK_IMPORTED_MODULE_6__.XhrFactory
22169    }];
22170  }, null);
22171})();
22172/**
22173 * @license
22174 * Copyright Google LLC All Rights Reserved.
22175 *
22176 * Use of this source code is governed by an MIT-style license that can be
22177 * found in the LICENSE file at https://angular.io/license
22178 */
22179
22180
22181const XSRF_COOKIE_NAME = new _angular_core__WEBPACK_IMPORTED_MODULE_4__.InjectionToken('XSRF_COOKIE_NAME');
22182const XSRF_HEADER_NAME = new _angular_core__WEBPACK_IMPORTED_MODULE_4__.InjectionToken('XSRF_HEADER_NAME');
22183/**
22184 * Retrieves the current XSRF token to use with the next outgoing request.
22185 *
22186 * @publicApi
22187 */
22188
22189class HttpXsrfTokenExtractor {}
22190/**
22191 * `HttpXsrfTokenExtractor` which retrieves the token from a cookie.
22192 */
22193
22194
22195class HttpXsrfCookieExtractor {
22196  constructor(doc, platform, cookieName) {
22197    this.doc = doc;
22198    this.platform = platform;
22199    this.cookieName = cookieName;
22200    this.lastCookieString = '';
22201    this.lastToken = null;
22202    /**
22203     * @internal for testing
22204     */
22205
22206    this.parseCount = 0;
22207  }
22208
22209  getToken() {
22210    if (this.platform === 'server') {
22211      return null;
22212    }
22213
22214    const cookieString = this.doc.cookie || '';
22215
22216    if (cookieString !== this.lastCookieString) {
22217      this.parseCount++;
22218      this.lastToken = (0,_angular_common__WEBPACK_IMPORTED_MODULE_6__["ɵparseCookieValue"])(cookieString, this.cookieName);
22219      this.lastCookieString = cookieString;
22220    }
22221
22222    return this.lastToken;
22223  }
22224
22225}
22226
22227HttpXsrfCookieExtractor.ɵfac = function HttpXsrfCookieExtractor_Factory(t) {
22228  return new (t || HttpXsrfCookieExtractor)(_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_6__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_4__.PLATFORM_ID), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](XSRF_COOKIE_NAME));
22229};
22230
22231HttpXsrfCookieExtractor.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjectable"]({
22232  token: HttpXsrfCookieExtractor,
22233  factory: HttpXsrfCookieExtractor.ɵfac
22234});
22235
22236(function () {
22237  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](HttpXsrfCookieExtractor, [{
22238    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injectable
22239  }], function () {
22240    return [{
22241      type: undefined,
22242      decorators: [{
22243        type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Inject,
22244        args: [_angular_common__WEBPACK_IMPORTED_MODULE_6__.DOCUMENT]
22245      }]
22246    }, {
22247      type: undefined,
22248      decorators: [{
22249        type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Inject,
22250        args: [_angular_core__WEBPACK_IMPORTED_MODULE_4__.PLATFORM_ID]
22251      }]
22252    }, {
22253      type: undefined,
22254      decorators: [{
22255        type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Inject,
22256        args: [XSRF_COOKIE_NAME]
22257      }]
22258    }];
22259  }, null);
22260})();
22261/**
22262 * `HttpInterceptor` which adds an XSRF token to eligible outgoing requests.
22263 */
22264
22265
22266class HttpXsrfInterceptor {
22267  constructor(tokenService, headerName) {
22268    this.tokenService = tokenService;
22269    this.headerName = headerName;
22270  }
22271
22272  intercept(req, next) {
22273    const lcUrl = req.url.toLowerCase(); // Skip both non-mutating requests and absolute URLs.
22274    // Non-mutating requests don't require a token, and absolute URLs require special handling
22275    // anyway as the cookie set
22276    // on our origin is not the same as the token expected by another origin.
22277
22278    if (req.method === 'GET' || req.method === 'HEAD' || lcUrl.startsWith('http://') || lcUrl.startsWith('https://')) {
22279      return next.handle(req);
22280    }
22281
22282    const token = this.tokenService.getToken(); // Be careful not to overwrite an existing header of the same name.
22283
22284    if (token !== null && !req.headers.has(this.headerName)) {
22285      req = req.clone({
22286        headers: req.headers.set(this.headerName, token)
22287      });
22288    }
22289
22290    return next.handle(req);
22291  }
22292
22293}
22294
22295HttpXsrfInterceptor.ɵfac = function HttpXsrfInterceptor_Factory(t) {
22296  return new (t || HttpXsrfInterceptor)(_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](HttpXsrfTokenExtractor), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](XSRF_HEADER_NAME));
22297};
22298
22299HttpXsrfInterceptor.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjectable"]({
22300  token: HttpXsrfInterceptor,
22301  factory: HttpXsrfInterceptor.ɵfac
22302});
22303
22304(function () {
22305  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](HttpXsrfInterceptor, [{
22306    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injectable
22307  }], function () {
22308    return [{
22309      type: HttpXsrfTokenExtractor
22310    }, {
22311      type: undefined,
22312      decorators: [{
22313        type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Inject,
22314        args: [XSRF_HEADER_NAME]
22315      }]
22316    }];
22317  }, null);
22318})();
22319/**
22320 * @license
22321 * Copyright Google LLC All Rights Reserved.
22322 *
22323 * Use of this source code is governed by an MIT-style license that can be
22324 * found in the LICENSE file at https://angular.io/license
22325 */
22326
22327/**
22328 * An injectable `HttpHandler` that applies multiple interceptors
22329 * to a request before passing it to the given `HttpBackend`.
22330 *
22331 * The interceptors are loaded lazily from the injector, to allow
22332 * interceptors to themselves inject classes depending indirectly
22333 * on `HttpInterceptingHandler` itself.
22334 * @see `HttpInterceptor`
22335 */
22336
22337
22338class HttpInterceptingHandler {
22339  constructor(backend, injector) {
22340    this.backend = backend;
22341    this.injector = injector;
22342    this.chain = null;
22343  }
22344
22345  handle(req) {
22346    if (this.chain === null) {
22347      const interceptors = this.injector.get(HTTP_INTERCEPTORS, []);
22348      this.chain = interceptors.reduceRight((next, interceptor) => new HttpInterceptorHandler(next, interceptor), this.backend);
22349    }
22350
22351    return this.chain.handle(req);
22352  }
22353
22354}
22355
22356HttpInterceptingHandler.ɵfac = function HttpInterceptingHandler_Factory(t) {
22357  return new (t || HttpInterceptingHandler)(_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](HttpBackend), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_4__.Injector));
22358};
22359
22360HttpInterceptingHandler.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjectable"]({
22361  token: HttpInterceptingHandler,
22362  factory: HttpInterceptingHandler.ɵfac
22363});
22364
22365(function () {
22366  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](HttpInterceptingHandler, [{
22367    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injectable
22368  }], function () {
22369    return [{
22370      type: HttpBackend
22371    }, {
22372      type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injector
22373    }];
22374  }, null);
22375})();
22376/**
22377 * Constructs an `HttpHandler` that applies interceptors
22378 * to a request before passing it to the given `HttpBackend`.
22379 *
22380 * Use as a factory function within `HttpClientModule`.
22381 *
22382 *
22383 */
22384
22385
22386function interceptingHandler(backend, interceptors = []) {
22387  if (!interceptors) {
22388    return backend;
22389  }
22390
22391  return interceptors.reduceRight((next, interceptor) => new HttpInterceptorHandler(next, interceptor), backend);
22392}
22393/**
22394 * Factory function that determines where to store JSONP callbacks.
22395 *
22396 * Ordinarily JSONP callbacks are stored on the `window` object, but this may not exist
22397 * in test environments. In that case, callbacks are stored on an anonymous object instead.
22398 *
22399 *
22400 */
22401
22402
22403function jsonpCallbackContext() {
22404  if (typeof window === 'object') {
22405    return window;
22406  }
22407
22408  return {};
22409}
22410/**
22411 * Configures XSRF protection support for outgoing requests.
22412 *
22413 * For a server that supports a cookie-based XSRF protection system,
22414 * use directly to configure XSRF protection with the correct
22415 * cookie and header names.
22416 *
22417 * If no names are supplied, the default cookie name is `XSRF-TOKEN`
22418 * and the default header name is `X-XSRF-TOKEN`.
22419 *
22420 * @publicApi
22421 */
22422
22423
22424class HttpClientXsrfModule {
22425  /**
22426   * Disable the default XSRF protection.
22427   */
22428  static disable() {
22429    return {
22430      ngModule: HttpClientXsrfModule,
22431      providers: [{
22432        provide: HttpXsrfInterceptor,
22433        useClass: NoopInterceptor
22434      }]
22435    };
22436  }
22437  /**
22438   * Configure XSRF protection.
22439   * @param options An object that can specify either or both
22440   * cookie name or header name.
22441   * - Cookie name default is `XSRF-TOKEN`.
22442   * - Header name default is `X-XSRF-TOKEN`.
22443   *
22444   */
22445
22446
22447  static withOptions(options = {}) {
22448    return {
22449      ngModule: HttpClientXsrfModule,
22450      providers: [options.cookieName ? {
22451        provide: XSRF_COOKIE_NAME,
22452        useValue: options.cookieName
22453      } : [], options.headerName ? {
22454        provide: XSRF_HEADER_NAME,
22455        useValue: options.headerName
22456      } : []]
22457    };
22458  }
22459
22460}
22461
22462HttpClientXsrfModule.ɵfac = function HttpClientXsrfModule_Factory(t) {
22463  return new (t || HttpClientXsrfModule)();
22464};
22465
22466HttpClientXsrfModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineNgModule"]({
22467  type: HttpClientXsrfModule
22468});
22469HttpClientXsrfModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjector"]({
22470  providers: [HttpXsrfInterceptor, {
22471    provide: HTTP_INTERCEPTORS,
22472    useExisting: HttpXsrfInterceptor,
22473    multi: true
22474  }, {
22475    provide: HttpXsrfTokenExtractor,
22476    useClass: HttpXsrfCookieExtractor
22477  }, {
22478    provide: XSRF_COOKIE_NAME,
22479    useValue: 'XSRF-TOKEN'
22480  }, {
22481    provide: XSRF_HEADER_NAME,
22482    useValue: 'X-XSRF-TOKEN'
22483  }]
22484});
22485
22486(function () {
22487  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](HttpCl
22487ientXsrfModule, [{
22488    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.NgModule,
22489    args: [{
22490      providers: [HttpXsrfInterceptor, {
22491        provide: HTTP_INTERCEPTORS,
22492        useExisting: HttpXsrfInterceptor,
22493        multi: true
22494      }, {
22495        provide: HttpXsrfTokenExtractor,
22496        useClass: HttpXsrfCookieExtractor
22497      }, {
22498        provide: XSRF_COOKIE_NAME,
22499        useValue: 'XSRF-TOKEN'
22500      }, {
22501        provide: XSRF_HEADER_NAME,
22502        useValue: 'X-XSRF-TOKEN'
22503      }]
22504    }]
22505  }], null, null);
22506})();
22507/**
22508 * Configures the [dependency injector](guide/glossary#injector) for `HttpClient`
22509 * with supporting services for XSRF. Automatically imported by `HttpClientModule`.
22510 *
22511 * You can add interceptors to the chain behind `HttpClient` by binding them to the
22512 * multiprovider for built-in [DI token](guide/glossary#di-token) `HTTP_INTERCEPTORS`.
22513 *
22514 * @publicApi
22515 */
22516
22517
22518class HttpClientModule {}
22519
22520HttpClientModule.ɵfac = function HttpClientModule_Factory(t) {
22521  return new (t || HttpClientModule)();
22522};
22523
22524HttpClientModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineNgModule"]({
22525  type: HttpClientModule,
22526  imports: [HttpClientXsrfModule]
22527});
22528HttpClientModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjector"]({
22529  providers: [HttpClient, {
22530    provide: HttpHandler,
22531    useClass: HttpInterceptingHandler
22532  }, HttpXhrBackend, {
22533    provide: HttpBackend,
22534    useExisting: HttpXhrBackend
22535  }],
22536  imports: [HttpClientXsrfModule.withOptions({
22537    cookieName: 'XSRF-TOKEN',
22538    headerName: 'X-XSRF-TOKEN'
22539  })]
22540});
22541
22542(function () {
22543  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](HttpClientModule, [{
22544    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.NgModule,
22545    args: [{
22546      /**
22547       * Optional configuration for XSRF protection.
22548       */
22549      imports: [HttpClientXsrfModule.withOptions({
22550        cookieName: 'XSRF-TOKEN',
22551        headerName: 'X-XSRF-TOKEN'
22552      })],
22553
22554      /**
22555       * Configures the [dependency injector](guide/glossary#injector) where it is imported
22556       * with supporting services for HTTP communications.
22557       */
22558      providers: [HttpClient, {
22559        provide: HttpHandler,
22560        useClass: HttpInterceptingHandler
22561      }, HttpXhrBackend, {
22562        provide: HttpBackend,
22563        useExisting: HttpXhrBackend
22564      }]
22565    }]
22566  }], null, null);
22567})();
22568/**
22569 * Configures the [dependency injector](guide/glossary#injector) for `HttpClient`
22570 * with supporting services for JSONP.
22571 * Without this module, Jsonp requests reach the backend
22572 * with method JSONP, where they are rejected.
22573 *
22574 * You can add interceptors to the chain behind `HttpClient` by binding them to the
22575 * multiprovider for built-in [DI token](guide/glossary#di-token) `HTTP_INTERCEPTORS`.
22576 *
22577 * @publicApi
22578 */
22579
22580
22581class HttpClientJsonpModule {}
22582
22583HttpClientJsonpModule.ɵfac = function HttpClientJsonpModule_Factory(t) {
22584  return new (t || HttpClientJsonpModule)();
22585};
22586
22587HttpClientJsonpModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineNgModule"]({
22588  type: HttpClientJsonpModule
22589});
22590HttpClientJsonpModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjector"]({
22591  providers: [JsonpClientBackend, {
22592    provide: JsonpCallbackContext,
22593    useFactory: jsonpCallbackContext
22594  }, {
22595    provide: HTTP_INTERCEPTORS,
22596    useClass: JsonpInterceptor,
22597    multi: true
22598  }]
22599});
22600
22601(function () {
22602  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](HttpClientJsonpModule, [{
22603    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.NgModule,
22604    args: [{
22605      providers: [JsonpClientBackend, {
22606        provide: JsonpCallbackContext,
22607        useFactory: jsonpCallbackContext
22608      }, {
22609        provide: HTTP_INTERCEPTORS,
22610        useClass: JsonpInterceptor,
22611        multi: true
22612      }]
22613    }]
22614  }], null, null);
22615})();
22616/**
22617 * @license
22618 * Copyright Google LLC All Rights Reserved.
22619 *
22620 * Use of this source code is governed by an MIT-style license that can be
22621 * found in the LICENSE file at https://angular.io/license
22622 */
22623
22624/**
22625 * A wrapper around the `XMLHttpRequest` constructor.
22626 *
22627 * @publicApi
22628 * @see `XhrFactory`
22629 * @deprecated
22630 * `XhrFactory` has moved, please import `XhrFactory` from `@angular/common` instead.
22631 */
22632
22633
22634const XhrFactory = _angular_common__WEBPACK_IMPORTED_MODULE_6__.XhrFactory;
22635/**
22636 * @license
22637 * Copyright Google LLC All Rights Reserved.
22638 *
22639 * Use of this source code is governed by an MIT-style license that can be
22640 * found in the LICENSE file at https://angular.io/license
22641 */
22642
22643/**
22644 * Generated bundle index. Do not edit.
22645 */
22646
22647
22648
22649/***/ }),
22650
22651/***/ 8781:
22652/*!**************************************************************!*\
22653  !*** ./node_modules/@angular/compiler/fesm2020/compiler.mjs ***!
22654  \**************************************************************/
22655/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
22656
22657__webpack_require__.r(__webpack_exports__);
22658/* harmony export */ __webpack_require__.d(__webpack_exports__, {
22659/* harmony export */   "AST": () => (/* binding */ AST),
22660/* harmony export */   "ASTWithName": () => (/* binding */ ASTWithName),
22661/* harmony export */   "ASTWithSource": () => (/* binding */ ASTWithSource),
22662/* harmony export */   "AbsoluteSourceSpan": () => (/* binding */ AbsoluteSourceSpan),
22663/* harmony export */   "ArrayType": () => (/* binding */ ArrayType),
22664/* harmony export */   "AstMemoryEfficientTransformer": () => (/* binding */ AstMemoryEfficientTransformer),
22665/* harmony export */   "AstTransformer": () => (/* binding */ AstTransformer),
22666/* harmony export */   "Attribute": () => (/* binding */ Attribute),
22667/* harmony export */   "Binary": () => (/* binding */ Binary),
22668/* harmony export */   "BinaryOperator": () => (/* binding */ BinaryOperator),
22669/* harmony export */   "BinaryOperatorExpr": () => (/* binding */ BinaryOperatorExpr),
22670/* harmony export */   "BindingPipe": () => (/* binding */ BindingPipe),
22671/* harmony export */   "BoundElementProperty": () => (/* binding */ BoundElementProperty),
22672/* harmony export */   "BuiltinType": () => (/* binding */ BuiltinType),
22673/* harmony export */   "BuiltinTypeName": () => (/* binding */ BuiltinTypeName),
22674/* harmony export */   "CUSTOM_ELEMENTS_SCHEMA": () => (/* binding */ CUSTOM_ELEMENTS_SCHEMA),
22675/* harmony export */   "Call": () => (/* binding */ Call),
22676/* harmony export */   "Chain": () => (/* binding */ Chain),
22677/* harmony export */   "ChangeDetectionStrategy": () => (/* binding */ ChangeDetectionStrategy),
22678/* harmony export */   "CommaExpr": () => (/* binding */ CommaExpr),
22679/* harmony export */   "Comment": () => (/* binding */ Comment),
22680/* harmony export */   "CompilerConfig": () => (/* binding */ CompilerConfig),
22681/* harmony export */   "Conditional": () => (/* binding */ Conditional),
22682/* harmony export */   "ConditionalExpr": () => (/* binding */ ConditionalExpr),
22683/* harmony export */   "ConstantPool": () => (/* binding */ ConstantPool),
22684/* harmony export */   "CssSelector": () => (/* binding */ CssSelector),
22685/* harmony export */   "DEFAULT_INTERPOLATION_CONFIG": () => (/* binding */ DEFAULT_INTERPOLATION_CONFIG),
22686/* harmony export */   "DYNAMIC_TYPE": () => (/* binding */ DYNAMIC_TYPE),
22687/* harmony export */   "DeclareFunctionStmt": () => (/* binding */ DeclareFunctionStmt),
22688/* harmony export */   "DeclareVarStmt": () => (/* binding */ DeclareVarStmt),
22689/* harmony export */   "DomElementSchemaRegistry": () => (/* binding */ DomElementSchemaRegistry),
22690/* harmony export */   "EOF": () => (/* binding */ EOF),
22691/* harmony export */   "Element": () => (/* binding */ Element),
22692/* harmony export */   "ElementSchemaRegistry": () => (/* binding */ ElementSchemaRegistry),
22693/* harmony export */   "EmitterVisitorContext": () => (/* binding */ EmitterVisitorContext),
22694/* harmony export */   "EmptyExpr": () => (/* binding */ EmptyExpr),
22695/* harmony export */   "Expansion": () => (/* binding */ Expansion),
22696/* harmony export */   "ExpansionCase": () => (/* binding */ ExpansionCase),
22697/* harmony export */   "Expression": () => (/* binding */ Expression),
22698/* harmony export */   "ExpressionBinding": () => (/* binding */ ExpressionBinding),
22699/* harmony export */   "ExpressionStatement": () => (/* binding */ ExpressionStatement),
22700/* harmony export */   "ExpressionType": () => (/* binding */ ExpressionType),
22701/* harmony export */   "ExternalExpr": () => (/* binding */ ExternalExpr),
22702/* harmony export */   "ExternalReference": () => (/* binding */ ExternalReference),
22703/* harmony export */   "FactoryTarget": () => (/* binding */ FactoryTarget$1),
22704/* harmony export */   "FunctionExpr": () => (/* binding */ FunctionExpr),
22705/* harmony export */   "HtmlParser": () => (/* binding */ HtmlParser),
22706/* harmony export */   "HtmlTagDefinition": () => (/* binding */ HtmlTagDefinition),
22707/* harmony export */   "I18NHtmlParser": () => (/* binding */ I18NHtmlParser),
22708/* harmony export */   "IfStmt": () => (/* binding */ IfStmt),
22709/* harmony export */   "ImplicitReceiver": () => (/* binding */ ImplicitReceiver),
22710/* harmony export */   "InstantiateExpr": () => (/* binding */ InstantiateExpr),
22711/* harmony export */   "Interpolation": () => (/* binding */ Interpolation),
22712/* harmony export */   "InterpolationConfig": () => (/* binding */ InterpolationConfig),
22713/* harmony export */   "InvokeFunctionExpr": () => (/* binding */ InvokeFunctionExpr),
22714/* harmony export */   "JSDocComment": () => (/* binding */ JSDocComment),
22715/* harmony export */   "JitEvaluator": () => (/* binding */ JitEvaluator),
22716/* harmony export */   "KeyedRead": () => (/* binding */ KeyedRead),
22717/* harmony export */   "KeyedWrite": () => (/* binding */ KeyedWrite),
22718/* harmony export */   "LeadingComment": () => (/* binding */ LeadingComment),
22719/* harmony export */   "Lexer": () => (/* binding */ Lexer),
22720/* harmony export */   "LiteralArray": () => (/* binding */ LiteralArray),
22721/* harmony export */   "LiteralArrayExpr": () => (/* binding */ LiteralArrayExpr),
22722/* harmony export */   "LiteralExpr": () => (/* binding */ LiteralExpr),
22723/* harmony export */   "LiteralMap": () => (/* binding */ LiteralMap),
22724/* harmony export */   "LiteralMapExpr": () => (/* binding */ LiteralMapExpr),
22725/* harmony export */   "LiteralPrimitive": () => (/* binding */ LiteralPrimitive),
22726/* harmony export */   "LocalizedString": () => (/* binding */ LocalizedString),
22727/* harmony export */   "MapType": () => (/* binding */ MapType),
22728/* harmony export */   "MessageBundle": () => (/* binding */ MessageBundle),
22729/* harmony export */   "NONE_TYPE": () => (/* binding */ NONE_TYPE),
22730/* harmony export */   "NO_ERRORS_SCHEMA": () => (/* binding */ NO_ERRORS_SCHEMA),
22731/* harmony export */   "NodeWithI18n": () => (/* binding */ NodeWithI18n),
22732/* harmony export */   "NonNullAssert": () => (/* binding */ NonNullAssert),
22733/* harmony export */   "NotExpr": () => (/* binding */ NotExpr),
22734/* harmony export */   "ParseError": () => (/* binding */ ParseError),
22735/* harmony export */   "ParseErrorLevel": () => (/* binding */ ParseErrorLevel),
22736/* harmony export */   "ParseLocation": () => (/* binding */ ParseLocation),
22737/* harmony export */   "ParseSourceFile": () => (/* binding */ ParseSourceFile),
22738/* harmony export */   "ParseSourceSpan": () => (/* binding */ ParseSourceSpan),
22739/* harmony export */   "ParseSpan": () => (/* binding */ ParseSpan),
22740/* harmony export */   "ParseTreeResult": () => (/* binding */ ParseTreeResult),
22741/* harmony export */   "ParsedEvent": () => (/* binding */ ParsedEvent),
22742/* harmony export */   "ParsedProperty": () => (/* binding */ ParsedProperty),
22743/* harmony export */   "ParsedPropertyType": () => (/* binding */ ParsedPropertyType),
22744/* harmony export */   "ParsedVariable": () => (/* binding */ ParsedVariable),
22745/* harmony export */   "Parser": () => (/* binding */ Parser$1),
22746/* harmony export */   "ParserError": () => (/* binding */ ParserError),
22747/* harmony export */   "PrefixNot": () => (/* binding */ PrefixNot),
22748/* harmony export */   "PropertyRead": () => (/* binding */ PropertyRead),
22749/* harmony export */   "PropertyWrite": () => (/* binding */ PropertyWrite),
22750/* harmony export */   "R3BoundTarget": () => (/* binding */ R3BoundTarget),
22751/* harmony export */   "R3Identifiers": () => (/* binding */ Identifiers),
22752/* harmony export */   "R3SelectorScopeMode": () => (/* binding */ R3SelectorScopeMode),
22753/* harmony export */   "R3TargetBinder": () => (/* binding */ R3TargetBinder),
22754/* harmony export */   "R3TemplateDependencyKind": () => (/* binding */ R3TemplateDependencyKind),
22755/* harmony export */   "ReadKeyExpr": () => (/* binding */ ReadKeyExpr),
22756/* harmony export */   "ReadPropExpr": () => (/* binding */ ReadPropExpr),
22757/* harmony export */   "ReadVarExpr": () => (/* binding */ ReadVarExpr),
22758/* harmony export */   "RecursiveAstVisitor": () => (/* binding */ RecursiveAstVisitor),
22759/* harmony export */   "RecursiveVisitor": () => (/* binding */ RecursiveVisitor),
22760/* harmony export */   "ResourceLoader": () => (/* binding */ ResourceLoader),
22761/* harmony export */   "ReturnStatement": () => (/* binding */ ReturnStatement),
22762/* harmony export */   "STRING_TYPE": () => (/* binding */ STRING_TYPE),
22763/* harmony export */   "SafeCall": () => (/* binding */ SafeCall),
22764/* harmony export */   "SafeKeyedRead": () => (/* binding */ SafeKeyedRead),
22765/* harmony export */   "SafePropertyRead": () => (/* binding */ SafePropertyRead),
22766/* harmony export */   "SelectorContext": () => (/* binding */ SelectorContext),
22767/* harmony export */   "SelectorListContext": () => (/* binding */ SelectorListContext),
22768/* harmony export */   "SelectorMatcher": () => (/* binding */ SelectorMatcher),
22769/* harmony export */   "Serializer": () => (/* binding */ Serializer),
22770/* harmony export */   "SplitInterpolation": () => (/* binding */ SplitInterpolation),
22771/* harmony export */   "Statement": () => (/* binding */ Statement),
22772/* harmony export */   "StmtModifier": () => (/* binding */ StmtModifier),
22773/* harmony export */   "TagContentType": () => (/* binding */ TagContentType),
22774/* harmony export */   "TaggedTemplateExpr": () => (/* binding */ TaggedTemplateExpr),
22775/* harmony export */   "TemplateBindingParseResult": () => (/* binding */ TemplateBindingParseResult),
22776/* harmony export */   "TemplateLiteral": () => (/* binding */ TemplateLiteral),
22777/* harmony export */   "TemplateLiteralElement": () => (/* binding */ TemplateLiteralElement),
22778/* harmony export */   "Text": () => (/* binding */ Text),
22779/* harmony export */   "ThisReceiver": () => (/* binding */ ThisReceiver),
22780/* harmony export */   "TmplAstBoundAttribute": () => (/* binding */ BoundAttribute),
22781/* harmony export */   "TmplAstBoundEvent": () => (/* binding */ BoundEvent),
22782/* harmony export */   "TmplAstBoundText": () => (/* binding */ BoundText),
22783/* harmony export */   "TmplAstContent": () => (/* binding */ Content),
22784/* harmony export */   "TmplAstElement": () => (/* binding */ Element$1),
22785/* harmony export */   "TmplAstIcu": () => (/* binding */ Icu$1),
22786/* harmony export */   "TmplAstRecursiveVisitor": () => (/* binding */ RecursiveVisitor$1),
22787/* harmony export */   "TmplAstReference": () => (/* binding */ Reference),
22788/* harmony export */   "TmplAstTemplate": () => (/* binding */ Template),
22789/* harmony export */   "TmplAstText": () => (/* binding */ Text$3),
22790/* harmony export */   "TmplAstTextAttribute": () => (/* binding */ TextAttribute),
22791/* harmony export */   "TmplAstVariable": () => (/* binding */ Variable),
22792/* harmony export */   "Token": () => (/* binding */ Token),
22793/* harmony export */   "TokenType": () => (/* binding */ TokenType),
22794/* harmony export */   "TreeError": () => (/* binding */ TreeError),
22795/* harmony export */   "Type": () => (/* binding */ Type),
22796/* harmony export */   "TypeModifier": () => (/* binding */ TypeModifier),
22797/* harmony export */   "TypeofExpr": () => (/* binding */ TypeofExpr),
22798/* harmony export */   "Unary": () => (/* binding */ Unary),
22799/* harmony export */   "UnaryOperator": () => (/* binding */ UnaryOperator),
22800/* harmony export */   "UnaryOperatorExpr": () => (/* binding */ UnaryOperatorExpr),
22801/* harmony export */   "VERSION": () => (/* binding */ VERSION),
22802/* harmony export */   "VariableBinding": () => (/* binding */ VariableBinding),
22803/* harmony export */   "Version": () => (/* binding */ Version),
22804/* harmony export */   "ViewEncapsulation": () => (/* binding */ ViewEncapsulation),
22805/* harmony export */   "WrappedNodeExpr": () => (/* binding */ WrappedNodeExpr),
22806/* harmony export */   "WriteKeyExpr": () => (/* binding */ WriteKeyExpr),
22807/* harmony export */   "WritePropExpr": () => (/* binding */ WritePropExpr),
22808/* harmony export */   "WriteVarExpr": () => (/* binding */ WriteVarExpr),
22809/* harmony export */   "Xliff": () => (/* binding */ Xliff),
22810/* harmony export */   "Xliff2": () => (/* binding */ Xliff2),
22811/* harmony export */   "Xmb": () => (/* binding */ Xmb),
22812/* harmony export */   "XmlParser": () => (/* binding */ XmlParser),
22813/* harmony export */   "Xtb": () => (/* binding */ Xtb),
22814/* harmony export */   "_ParseAST": () => (/* binding */ _ParseAST),
22815/* harmony export */   "compileClassMetadata": () => (/* binding */ compileClassMetadata),
22816/* harmony export */   "compileComponentFromMetadata": () => (/* binding */ compileComponentFromMetadata),
22817/* harmony export */   "compileDeclareClassMetadata": () => (/* binding */ compileDeclareClassMetadata),
22818/* harmony export */   "compileDeclareComponentFromMetadata": () => (/* binding */ compileDeclareComponentFromMetadata),
22819/* harmony export */   "compileDeclareDirectiveFromMetadata": () => (/* binding */ compileDeclareDirectiveFromMetadata),
22820/* harmony export */   "compileDeclareFactoryFunction": () => (/* binding */ compileDeclareFactoryFunction),
22821/* harmony export */   "compileDeclareInjectableFromMetadata": () => (/* binding */ compileDeclareInjectableFromMetadata),
22822/* harmony export */   "compileDeclareInjectorFromMetadata": () => (/* binding */ compileDeclareInjectorFromMetadata),
22823/* harmony export */   "compileDeclareNgModuleFromMetadata": () => (/* binding */ compileDeclareNgModuleFromMetadata),
22824/* harmony export */   "compileDeclarePipeFromMetadata": () => (/* binding */ compileDeclarePipeFromMetadata),
22825/* harmony export */   "compileDirectiveFromMetadata": () => (/* binding */ compileDirectiveFromMetadata),
22826/* harmony export */   "compileFactoryFunction": () => (/* binding */ compileFactoryFunction),
22827/* harmony export */   "compileInjectable": () => (/* binding */ compileInjectable),
22828/* harmony export */   "compileInjector": () => (/* binding */ compileInjector),
22829/* harmony export */   "compileNgModule": () => (/* binding */ compileNgModule),
22830/* harmony export */   "compilePipeFromMetadata": () => (/* binding */ compilePipeFromMetadata),
22831/* harmony export */   "computeMsgId": () => (/* binding */ computeMsgId),
22832/* harmony export */   "core": () => (/* binding */ core),
22833/* harmony export */   "createInjectableType": () => (/* binding */ createInjectableType),
22834/* harmony export */   "createMayBeForwardRefExpression": () => (/* binding */ createMayBeForwardRefExpression),
22835/* harmony export */   "devOnlyGuardedExpression": () => (/* binding */ devOnlyGuardedExpression),
22836/* harmony export */   "emitDistinctChangesOnlyDefaultValue": () => (/* binding */ emitDistinctChangesOnlyDefaultValue),
22837/* harmony export */   "getHtmlTagDefinition": () => (/* binding */ getHtmlTagDefinition),
22838/* harmony export */   "getNsPrefix": () => (/* binding */ getNsPrefix),
22839/* harmony export */   "getSafePropertyAccessString": () => (/* binding */ getSafePropertyAccessString),
22840/* harmony export */   "identifierName": () => (/* binding */ identifierName),
22841/* harmony export */   "isIdentifier": () => (/* binding */ isIdentifier),
22842/* harmony export */   "isNgContainer": () => (/* binding */ isNgContainer),
22843/* harmony export */   "isNgContent": () => (/* binding */ isNgContent),
22844/* harmony export */   "isNgTemplate": () => (/* binding */ isNgTemplate),
22845/* harmony export */   "jsDocComment": () => (/* binding */ jsDocComment),
22846/* harmony export */   "leadingComment": () => (/* binding */ leadingComment),
22847/* harmony export */   "literalMap": () => (/* binding */ literalMap),
22848/* harmony export */   "makeBindingParser": () => (/* binding */ makeBindingParser),
22849/* harmony export */   "mergeNsAndName": () => (/* binding */ mergeNsAndName),
22850/* harmony export */   "outputAst": () => (/* binding */ output_ast),
22851/* harmony export */   "parseHostBindings": () => (/* binding */ parseHostBindings),
22852/* harmony export */   "parseTemplate": () => (/* binding */ parseTemplate),
22853/* harmony export */   "preserveWhitespacesDefault": () => (/* binding */ preserveWhitespacesDefault),
22854/* harmony export */   "publishFacade": () => (/* binding */ publishFacade),
22855/* harmony export */   "r3JitTypeSourceSpan": () => (/* binding */ r3JitTypeSourceSpan),
22856/* harmony export */   "sanitizeIdentifier": () => (/* binding */ sanitizeIdentifier),
22857/* harmony export */   "splitNsName": () => (/* binding */ splitNsName),
22858/* harmony export */   "verifyHostBindings": () => (/* binding */ verifyHostBindings),
22859/* harmony export */   "visitAll": () => (/* binding */ visitAll)
22860/* harmony export */ });
22861/**
22862 * @license Angular v14.2.10
22863 * (c) 2010-2022 Google LLC. https://angular.io/
22864 * License: MIT
22865 */
22866
22867/**
22868 * @license
22869 * Copyright Google LLC All Rights Reserved.
22870 *
22871 * Use of this source code is governed by an MIT-style license that can be
22872 * found in the LICENSE file at https://angular.io/license
22873 */
22874var TagContentType;
22875
22876(function (TagContentType) {
22877  TagContentType[TagContentType["RAW_TEXT"] = 0] = "RAW_TEXT";
22878  TagContentType[TagContentType["ESCAPABLE_RAW_TEXT"] = 1] = "ESCAPABLE_RAW_TEXT";
22879  TagContentType[TagContentType["PARSABLE_DATA"] = 2] = "PARSABLE_DATA";
22880})(TagContentType || (TagContentType = {}));
22881
22882function splitNsName(elementName) {
22883  if (elementName[0] != ':') {
22884    return [null, elementName];
22885  }
22886
22887  const colonIndex = elementName.indexOf(':', 1);
22888
22889  if (colonIndex === -1) {
22890    throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
22891  }
22892
22893  return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
22894} // `<ng-container>` tags work the same regardless the namespace
22895
22896
22897function isNgContainer(tagName) {
22898  return splitNsName(tagName)[1] === 'ng-container';
22899} // `<ng-content>` tags work the same regardless the namespace
22900
22901
22902function isNgContent(tagName) {
22903  return splitNsName(tagName)[1] === 'ng-content';
22904} // `<ng-template>` tags work the same regardless the namespace
22905
22906
22907function isNgTemplate(tagName) {
22908  return splitNsName(tagName)[1] === 'ng-template';
22909}
22910
22911function getNsPrefix(fullName) {
22912  return fullName === null ? null : splitNsName(fullName)[0];
22913}
22914
22915function mergeNsAndName(prefix, localName) {
22916  return prefix ? `:${prefix}:${localName}` : localName;
22917}
22918/**
22919 * @license
22920 * Copyright Google LLC All Rights Reserved.
22921 *
22922 * Use of this source code is governed by an MIT-style license that can be
22923 * found in the LICENSE file at https://angular.io/license
22924 */
22925
22926
22927class HtmlTagDefinition {
22928  constructor({
22929    closedByChildren,
22930    implicitNamespacePrefix,
22931    contentType = TagContentType.PARSABLE_DATA,
22932    closedByParent = false,
22933    isVoid = false,
22934    ignoreFirstLf = false,
22935    preventNamespaceInheritance = false
22936  }
22936 = {}) {
22937    this.closedByChildren = {};
22938    this.closedByParent = false;
22939    this.canSelfClose = false;
22940
22941    if (closedByChildren && closedByChildren.length > 0) {
22942      closedByChildren.forEach(tagName => this.closedByChildren[tagName] = true);
22943    }
22944
22945    this.isVoid = isVoid;
22946    this.closedByParent = closedByParent || isVoid;
22947    this.implicitNamespacePrefix = implicitNamespacePrefix || null;
22948    this.contentType = contentType;
22949    this.ignoreFirstLf = ignoreFirstLf;
22950    this.preventNamespaceInheritance = preventNamespaceInheritance;
22951  }
22952
22953  isClosedByChild(name) {
22954    return this.isVoid || name.toLowerCase() in this.closedByChildren;
22955  }
22956
22957  getContentType(prefix) {
22958    if (typeof this.contentType === 'object') {
22959      const overrideType = prefix === undefined ? undefined : this.contentType[prefix];
22960      return overrideType ?? this.contentType.default;
22961    }
22962
22963    return this.contentType;
22964  }
22965
22966}
22967
22968let _DEFAULT_TAG_DEFINITION; // see https://www.w3.org/TR/html51/syntax.html#optional-tags
22969// This implementation does not fully conform to the HTML5 spec.
22970
22971
22972let TAG_DEFINITIONS;
22973
22974function getHtmlTagDefinition(tagName) {
22975  if (!TAG_DEFINITIONS) {
22976    _DEFAULT_TAG_DEFINITION = new HtmlTagDefinition();
22977    TAG_DEFINITIONS = {
22978      'base': new HtmlTagDefinition({
22979        isVoid: true
22980      }),
22981      'meta': new HtmlTagDefinition({
22982        isVoid: true
22983      }),
22984      'area': new HtmlTagDefinition({
22985        isVoid: true
22986      }),
22987      'embed': new HtmlTagDefinition({
22988        isVoid: true
22989      }),
22990      'link': new HtmlTagDefinition({
22991        isVoid: true
22992      }),
22993      'img': new HtmlTagDefinition({
22994        isVoid: true
22995      }),
22996      'input': new HtmlTagDefinition({
22997        isVoid: true
22998      }),
22999      'param': new HtmlTagDefinition({
23000        isVoid: true
23001      }),
23002      'hr': new HtmlTagDefinition({
23003        isVoid: true
23004      }),
23005      'br': new HtmlTagDefinition({
23006        isVoid: true
23007      }),
23008      'source': new HtmlTagDefinition({
23009        isVoid: true
23010      }),
23011      'track': new HtmlTagDefinition({
23012        isVoid: true
23013      }),
23014      'wbr': new HtmlTagDefinition({
23015        isVoid: true
23016      }),
23017      'p': new HtmlTagDefinition({
23018        closedByChildren: ['address', 'article', 'aside', 'blockquote', 'div', 'dl', 'fieldset', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'],
23019        closedByParent: true
23020      }),
23021      'thead': new HtmlTagDefinition({
23022        closedByChildren: ['tbody', 'tfoot']
23023      }),
23024      'tbody': new HtmlTagDefinition({
23025        closedByChildren: ['tbody', 'tfoot'],
23026        closedByParent: true
23027      }),
23028      'tfoot': new HtmlTagDefinition({
23029        closedByChildren: ['tbody'],
23030        closedByParent: true
23031      }),
23032      'tr': new HtmlTagDefinition({
23033        closedByChildren: ['tr'],
23034        closedByParent: true
23035      }),
23036      'td': new HtmlTagDefinition({
23037        closedByChildren: ['td', 'th'],
23038        closedByParent: true
23039      }),
23040      'th': new HtmlTagDefinition({
23041        closedByChildren: ['td', 'th'],
23042        closedByParent: true
23043      }),
23044      'col': new HtmlTagDefinition({
23045        isVoid: true
23046      }),
23047      'svg': new HtmlTagDefinition({
23048        implicitNamespacePrefix: 'svg'
23049      }),
23050      'foreignObject': new HtmlTagDefinition({
23051        // Usually the implicit namespace here would be redundant since it will be inherited from
23052        // the parent `svg`, but we have to do it for `foreignObject`, because the way the parser
23053        // works is that the parent node of an end tag is its own start tag which means that
23054        // the `preventNamespaceInheritance` on `foreignObject` would have it default to the
23055        // implicit namespace which is `html`, unless specified otherwise.
23056        implicitNamespacePrefix: 'svg',
23057        // We want to prevent children of foreignObject from inheriting its namespace, because
23058        // the point of the element is to allow nodes from other namespaces to be inserted.
23059        preventNamespaceInheritance: true
23060      }),
23061      'math': new HtmlTagDefinition({
23062        implicitNamespacePrefix: 'math'
23063      }),
23064      'li': new HtmlTagDefinition({
23065        closedByChildren: ['li'],
23066        closedByParent: true
23067      }),
23068      'dt': new HtmlTagDefinition({
23069        closedByChildren: ['dt', 'dd']
23070      }),
23071      'dd': new HtmlTagDefinition({
23072        closedByChildren: ['dt', 'dd'],
23073        closedByParent: true
23074      }),
23075      'rb': new HtmlTagDefinition({
23076        closedByChildren: ['rb', 'rt', 'rtc', 'rp'],
23077        closedByParent: true
23078      }),
23079      'rt': new HtmlTagDefinition({
23080        closedByChildren: ['rb', 'rt', 'rtc', 'rp'],
23081        closedByParent: true
23082      }),
23083      'rtc': new HtmlTagDefinition({
23084        closedByChildren: ['rb', 'rtc', 'rp'],
23085        closedByParent: true
23086      }),
23087      'rp': new HtmlTagDefinition({
23088        closedByChildren: ['rb', 'rt', 'rtc', 'rp'],
23089        closedByParent: true
23090      }),
23091      'optgroup': new HtmlTagDefinition({
23092        closedByChildren: ['optgroup'],
23093        closedByParent: true
23094      }),
23095      'option': new HtmlTagDefinition({
23096        closedByChildren: ['option', 'optgroup'],
23097        closedByParent: true
23098      }),
23099      'pre': new HtmlTagDefinition({
23100        ignoreFirstLf: true
23101      }),
23102      'listing': new HtmlTagDefinition({
23103        ignoreFirstLf: true
23104      }),
23105      'style': new HtmlTagDefinition({
23106        contentType: TagContentType.RAW_TEXT
23107      }),
23108      'script': new HtmlTagDefinition({
23109        contentType: TagContentType.RAW_TEXT
23110      }),
23111      'title': new HtmlTagDefinition({
23112        // The browser supports two separate `title` tags which have to use
23113        // a different content type: `HTMLTitleElement` and `SVGTitleElement`
23114        contentType: {
23115          default: TagContentType.ESCAPABLE_RAW_TEXT,
23116          svg: TagContentType.PARSABLE_DATA
23117        }
23118      }),
23119      'textarea': new HtmlTagDefinition({
23120        contentType: TagContentType.ESCAPABLE_RAW_TEXT,
23121        ignoreFirstLf: true
23122      })
23123    };
23124  } // We have to make both a case-sensitive and a case-insensitive lookup, because
23125  // HTML tag names are case insensitive, whereas some SVG tags are case sensitive.
23126
23127
23128  return TAG_DEFINITIONS[tagName] ?? TAG_DEFINITIONS[tagName.toLowerCase()] ?? _DEFAULT_TAG_DEFINITION;
23129}
23130/**
23131 * @license
23132 * Copyright Google LLC All Rights Reserved.
23133 *
23134 * Use of this source code is governed by an MIT-style license that can be
23135 * found in the LICENSE file at https://angular.io/license
23136 */
23137
23138
23139const _SELECTOR_REGEXP = new RegExp('(\\:not\\()|' + // 1: ":not("
23140'(([\\.\\#]?)[-\\w]+)|' + // 2: "tag"; 3: "."/"#";
23141// "-" should appear first in the regexp below as FF31 parses "[.-\w]" as a range
23142// 4: attribute; 5: attribute_string; 6: attribute_value
23143'(?:\\[([-.\\w*\\\\$]+)(?:=([\"\']?)([^\\]\"\']*)\\5)?\\])|' + // "[name]", "[name=value]",
23144// "[name="value"]",
23145// "[name='value']"
23146'(\\))|' + // 7: ")"
23147'(\\s*,\\s*)', // 8: ","
23148'g');
23149/**
23150 * A css selector contains an element name,
23151 * css classes and attribute/value pairs with the purpose
23152 * of selecting subsets out of them.
23153 */
23154
23155
23156class CssSelector {
23157  constructor() {
23158    this.element = null;
23159    this.classNames = [];
23160    /**
23161     * The selectors are encoded in pairs where:
23162     * - even locations are attribute names
23163     * - odd locations are attribute values.
23164     *
23165     * Example:
23166     * Selector: `[key1=value1][key2]` would parse to:
23167     * ```
23168     * ['key1', 'value1', 'key2', '']
23169     * ```
23170     */
23171
23172    this.attrs = [];
23173    this.notSelectors = [];
23174  }
23175
23176  static parse(selector) {
23177    const results = [];
23178
23179    const _addResult = (res, cssSel) => {
23180      if (cssSel.notSelectors.length > 0 && !cssSel.element && cssSel.classNames.length == 0 && cssSel.attrs.length == 0) {
23181        cssSel.element = '*';
23182      }
23183
23184      res.push(cssSel);
23185    };
23186
23187    let cssSelector = new CssSelector();
23188    let match;
23189    let current = cssSelector;
23190    let inNot = false;
23191    _SELECTOR_REGEXP.lastIndex = 0;
23192
23193    while (match = _SELECTOR_REGEXP.exec(selector)) {
23194      if (match[1
23195      /* SelectorRegexp.NOT */
23196      ]) {
23197        if (inNot) {
23198          throw new Error('Nesting :not in a selector is not allowed');
23199        }
23200
23201        inNot = true;
23202        current = new CssSelector();
23203        cssSelector.notSelectors.push(current);
23204      }
23205
23206      const tag = match[2
23207      /* SelectorRegexp.TAG */
23208      ];
23209
23210      if (tag) {
23211        const prefix = match[3
23212        /* SelectorRegexp.PREFIX */
23213        ];
23214
23215        if (prefix === '#') {
23216          // #hash
23217          current.addAttribute('id', tag.slice(1));
23218        } else if (prefix === '.') {
23219          // Class
23220          current.addClassName(tag.slice(1));
23221        } else {
23222          // Element
23223          current.setElement(tag);
23224        }
23225      }
23226
23227      const attribute = match[4
23228      /* SelectorRegexp.ATTRIBUTE */
23229      ];
23230
23231      if (attribute) {
23232        current.addAttribute(current.unescapeAttribute(attribute), match[6
23233        /* SelectorRegexp.ATTRIBUTE_VALUE */
23234        ]);
23235      }
23236
23237      if (match[7
23238      /* SelectorRegexp.NOT_END */
23239      ]) {
23240        inNot = false;
23241        current = cssSelector;
23242      }
23243
23244      if (match[8
23245      /* SelectorRegexp.SEPARATOR */
23246      ]) {
23247        if (inNot) {
23248          throw new Error('Multiple selectors in :not are not supported');
23249        }
23250
23251        _addResult(results, cssSelector);
23252
23253        cssSelector = current = new CssSelector();
23254      }
23255    }
23256
23257    _addResult(results, cssSelector);
23258
23259    return results;
23260  }
23261  /**
23262   * Unescape `\$` sequences from the CSS attribute selector.
23263   *
23264   * This is needed because `$` can have a special meaning in CSS selectors,
23265   * but we might want to match an attribute that contains `$`.
23266   * [MDN web link for more
23267   * info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).
23268   * @param attr the attribute to unescape.
23269   * @returns the unescaped string.
23270   */
23271
23272
23273  unescapeAttribute(attr) {
23274    let result = '';
23275    let escaping = false;
23276
23277    for (let i = 0; i < attr.length; i++) {
23278      const char = attr.charAt(i);
23279
23280      if (char === '\\') {
23281        escaping = true;
23282        continue;
23283      }
23284
23285      if (char === '$' && !escaping) {
23286        throw new Error(`Error in attribute selector "${attr}". ` + `Unescaped "$" is not supported. Please escape with "\\$".`);
23287      }
23288
23289      escaping = false;
23290      result += char;
23291    }
23292
23293    return result;
23294  }
23295  /**
23296   * Escape `$` sequences from the CSS attribute selector.
23297   *
23298   * This is needed because `$` can have a special meaning in CSS selectors,
23299   * with this method we are escaping `$` with `\$'.
23300   * [MDN web link for more
23301   * info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).
23302   * @param attr the attribute to escape.
23303   * @returns the escaped string.
23304   */
23305
23306
23307  escapeAttribute(attr) {
23308    return attr.replace(/\\/g, '\\\\').replace(/\$/g, '\\$');
23309  }
23310
23311  isElementSelector() {
23312    return this.hasElementSelector() && this.classNames.length == 0 && this.attrs.length == 0 && this.notSelectors.length === 0;
23313  }
23314
23315  hasElementSelector() {
23316    return !!this.element;
23317  }
23318
23319  setElement(element = null) {
23320    this.element = element;
23321  }
23322  /** Gets a template string for an element that matches the selector. */
23323
23324
23325  getMatchingElementTemplate() {
23326    const tagName = this.element || 'div';
23327    const classAttr = this.classNames.length > 0 ? ` class="${this.classNames.join(' ')}"` : '';
23328    let attrs = '';
23329
23330    for (let i = 0; i < this.attrs.length; i += 2) {
23331      const attrName = this.attrs[i];
23332      const attrValue = this.attrs[i + 1] !== '' ? `="${this.attrs[i + 1]}"` : '';
23333      attrs += ` ${attrName}${attrValue}`;
23334    }
23335
23336    return getHtmlTagDefinition(tagName).isVoid ? `<${tagName}${classAttr}${attrs}/>` : `<${tagName}${classAttr}${attrs}></${tagName}>`;
23337  }
23338
23339  getAttrs() {
23340    const result = [];
23341
23342    if (this.classNames.length > 0) {
23343      result.push('class', this.classNames.join(' '));
23344    }
23345
23346    return result.concat(this.attrs);
23347  }
23348
23349  addAttribute(name, value = '') {
23350    this.attrs.push(name, value && value.toLowerCase() || '');
23351  }
23352
23353  addClassName(name) {
23354    this.classNames.push(name.toLowerCase());
23355  }
23356
23357  toString() {
23358    let res = this.element || '';
23359
23360    if (this.classNames) {
23361      this.classNames.forEach(klass => res += `.${klass}`);
23362    }
23363
23364    if (this.attrs) {
23365      for (let i = 0; i < this.attrs.length; i += 2) {
23366        const name = this.escapeAttribute(this.attrs[i]);
23367        const value = this.attrs[i + 1];
23368        res += `[${name}${value ? '=' + value : ''}]`;
23369      }
23370    }
23371
23372    this.notSelectors.forEach(notSelector => res += `:not(${notSelector})`);
23373    return res;
23374  }
23375
23376}
23377/**
23378 * Reads a list of CssSelectors and allows to calculate which ones
23379 * are contained in a given CssSelector.
23380 */
23381
23382
23383class SelectorMatcher {
23384  constructor() {
23385    this._elementMap = new Map();
23386    this._elementPartialMap = new Map();
23387    this._classMap = new Map();
23388    this._classPartialMap = new Map();
23389    this._attrValueMap = new Map();
23390    this._attrValuePartialMap = new Map();
23391    this._listContexts = [];
23392  }
23393
23394  static createNotMatcher(notSelectors) {
23395    const notMatcher = new SelectorMatcher();
23396    notMatcher.addSelectables(notSelectors, null);
23397    return notMatcher;
23398  }
23399
23400  addSelectables(cssSelectors, callbackCtxt) {
23401    let listContext = null;
23402
23403    if (cssSelectors.length > 1) {
23404      listContext = new SelectorListContext(cssSelectors);
23405
23406      this._listContexts.push(listContext);
23407    }
23408
23409    for (let i = 0; i < cssSelectors.length; i++) {
23410      this._addSelectable(cssSelectors[i], callbackCtxt, listContext);
23411    }
23412  }
23413  /**
23414   * Add an object that can be found later on by calling `match`.
23415   * @param cssSelector A css selector
23416   * @param callbackCtxt An opaque object that will be given to the callback of the `match` function
23417   */
23418
23419
23420  _addSelectable(cssSelector, callbackCtxt, listContext) {
23421    let matcher = this;
23422    const element = cssSelector.element;
23423    const classNames = cssSelector.classNames;
23424    const attrs = cssSelector.attrs;
23425    const selectable = new SelectorContext(cssSelector, callbackCtxt, listContext);
23426
23427    if (element) {
23428      const isTerminal = attrs.length === 0 && classNames.length === 0;
23429
23430      if (isTerminal) {
23431        this._addTerminal(matcher._elementMap, element, selectable);
23432      } else {
23433        matcher = this._addPartial(matcher._elementPartialMap, element);
23434      }
23435    }
23436
23437    if (classNames) {
23438      for (let i = 0; i < classNames.length; i++) {
23439        const isTerminal = attrs.length === 0 && i === classNames.length - 1;
23440        const className = classNames[i];
23441
23442        if (isTerminal) {
23443          this._addTerminal(matcher._classMap, className, selectable);
23444        } else {
23445          matcher = this._addPartial(matcher._classPartialMap, className);
23446        }
23447      }
23448    }
23449
23450    if (attrs) {
23451      for (let i = 0; i < attrs.length; i += 2) {
23452        const isTerminal = i === attrs.length - 2;
23453        const name = attrs[i];
23454        const value = attrs[i + 1];
23455
23456        if (isTerminal) {
23457          const terminalMap = matcher._attrValueMap;
23458          let terminalValuesMap = terminalMap.get(name);
23459
23460          if (!terminalValuesMap) {
23461            terminalValuesMap = new Map();
23462            terminalMap.set(name, terminalValuesMap);
23463          }
23464
23465          this._addTerminal(terminalValuesMap, value, selectable);
23466        } else {
23467          const partialMap = matcher._attrValuePartialMap;
23468          let partialValuesMap = partialMap.get(name);
23469
23470          if (!partialValuesMap) {
23471            partialValuesMap = new Map();
23472            partialMap.set(name, partialValuesMap);
23473          }
23474
23475          matcher = this._addPartial(partialValuesMap, value);
23476        }
23477      }
23478    }
23479  }
23480
23481  _addTerminal(map, name, selectable) {
23482    let terminalList = map.get(name);
23483
23484    if (!terminalList) {
23485      terminalList = [];
23486      map.set(name, terminalList);
23487    }
23488
23489    terminalList.push(selectable);
23490  }
23491
23492  _addPartial(map, name) {
23493    let matcher = map.get(name);
23494
23495    if (!matcher) {
23496      matcher = new SelectorMatcher();
23497      map.set(name, matcher);
23498    }
23499
23500    return matcher;
23501  }
23502  /**
23503   * Find the objects that have been added via `addSelectable`
23504   * whose css selector is contained in the given css selector.
23505   * @param cssSelector A css selector
23506   * @param matchedCallback This callback will be called with the object handed into `addSelectable`
23507   * @return boolean true if a match was found
23508   */
23509
23510
23511  match(cssSelector, matchedCallback) {
23512    let result = false;
23513    const element = cssSelector.element;
23514    const classNames = cssSelector.classNames;
23515    const attrs = cssSelector.attrs;
23516
23517    for (let i = 0; i < this._listContexts.length; i++) {
23518      this._listContexts[i].alreadyMatched = false;
23519    }
23520
23521    result = this._matchTerminal(this._elementMap, element, cssSelector, matchedCallback) || result;
23522    result = this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) || result;
23523
23524    if (classNames) {
23525      for (let i = 0; i < classNames.length; i++) {
23526        const className = classNames[i];
23527        result = this._matchTerminal(this._classMap, className, cssSelector, matchedCallback) || result;
23528        result = this._matchPartial(this._classPartialMap, className, cssSelector, matchedCallback) || result;
23529      }
23530    }
23531
23532    if (attrs) {
23533      for (let i = 0; i < attrs.length; i += 2) {
23534        const name = attrs[i];
23535        const value = attrs[i + 1];
23536
23537        const terminalValuesMap = this._attrValueMap.get(name);
23538
23539        if (value) {
23540          result = this._matchTerminal(terminalValuesMap, '', cssSelector, matchedCallback) || result;
23541        }
23542
23543        result = this._matchTerminal(terminalValuesMap, value, cssSelector, matchedCallback) || result;
23544
23545        const partialValuesMap = this._attrValuePartialMap.get(name);
23546
23547        if (value) {
23548          result = this._matchPartial(partialValuesMap, '', cssSelector, matchedCallback) || result;
23549        }
23550
23551        result = this._matchPartial(partialValuesMap, value, cssSelector, matchedCallback) || result;
23552      }
23553    }
23554
23555    return result;
23556  }
23557  /** @internal */
23558
23559
23560  _matchTerminal(map, name, cssSelector, matchedCallback) {
23561    if (!map || typeof name !== 'string') {
23562      return false;
23563    }
23564
23565    let selectables = map.get(name) || [];
23566    const starSelectables = map.get('*');
23567
23568    if (starSelectables) {
23569      selectables = selectables.concat(starSelectables);
23570    }
23571
23572    if (selectables.length === 0) {
23573      return false;
23574    }
23575
23576    let selectable;
23577    let result = false;
23578
23579    for (let i = 0; i < selectables.length; i++) {
23580      selectable = selectables[i];
23581      result = selectable.finalize(cssSelector, matchedCallback) || result;
23582    }
23583
23584    return result;
23585  }
23586  /** @internal */
23587
23588
23589  _matchPartial(map, name, cssSelector, matchedCallback) {
23590    if (!map || typeof name !== 'string') {
23591      return false;
23592    }
23593
23594    const nestedSelector = map.get(name);
23595
23596    if (!nestedSelector) {
23597      return false;
23598    } // TODO(perf): get rid of recursion and measure again
23599    // TODO(perf): don't pass the whole selector into the recursion,
23600    // but only the not processed parts
23601
23602
23603    return nestedSelector.match(cssSelector, matchedCallback);
23604  }
23605
23606}
23607
23608class SelectorListContext {
23609  constructor(selectors) {
23610    this.selectors = selectors;
23611    this.alreadyMatched = false;
23612  }
23613
23614} // Store context to pass back selector and context when a selector is matched
23615
23616
23617class SelectorContext {
23618  constructor(selector, cbContext, listContext) {
23619    this.selector = selector;
23620    this.cbContext = cbContext;
23621    this.listContext = listContext;
23622    this.notSelectors = selector.notSelectors;
23623  }
23624
23625  finalize(cssSelector, callback) {
23626    let result = true;
23627
23628    if (this.notSelectors.length > 0 && (!this.listContext || !this.listContext.alreadyMatched)) {
23629      const notMatcher = SelectorMatcher.createNotMatcher(this.notSelectors);
23630      result = !notMatcher.match(cssSelector, null);
23631    }
23632
23633    if (result && callback && (!this.listContext || !this.listContext.alreadyMatched)) {
23634      if (this.listContext) {
23635        this.listContext.alreadyMatched = true;
23636      }
23637
23638      callback(this.selector, this.cbContext);
23639    }
23640
23641    return result;
23642  }
23643
23644}
23645/**
23646 * @license
23647 * Copyright Google LLC All Rights Reserved.
23648 *
23649 * Use of this source code is governed by an MIT-style license that can be
23650 * found in the LICENSE file at https://angular.io/license
23651 */
23652// Stores the default value of `emitDistinctChangesOnly` when the `emitDistinctChangesOnly` is not
23653// explicitly set.
23654
23655
23656const emitDistinctChangesOnlyDefaultValue = true;
23657var ViewEncapsulation;
23658
23659(function (ViewEncapsulation) {
23660  ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated"; // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
23661
23662  ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
23663  ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
23664})(ViewEncapsulation || (ViewEncapsulation = {}));
23665
23666var ChangeDetectionStrategy;
23667
23668(function (ChangeDetectionStrategy) {
23669  ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
23670  ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
23671})(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));
23672
23673const CUSTOM_ELEMENTS_SCHEMA = {
23674  name: 'custom-elements'
23675};
23676const NO_ERRORS_SCHEMA = {
23677  name: 'no-errors-schema'
23678};
23679const Type$1 = Function;
23680var SecurityContext;
23681
23682(function (SecurityContext) {
23683  SecurityContext[SecurityContext["NONE"] = 0] = "NONE";
23684  SecurityContext[SecurityContext["HTML"] = 1] = "HTML";
23685  SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE";
23686  SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
23687  SecurityContext[SecurityContext["URL"] = 4] = "URL";
23688  SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
23689})(SecurityContext || (SecurityContext = {}));
23690
23691var MissingTranslationStrategy;
23692
23693(function (MissingTranslationStrategy) {
23694  MissingTranslationStrategy[MissingTranslationStrategy["Error"] = 0] = "Error";
23695  MissingTranslationStrategy[MissingTranslationStrategy["Warning"] = 1] = "Warning";
23696  MissingTranslationStrategy[MissingTranslationStrategy["Ignore"] = 2] = "Ignore";
23697})(MissingTranslationStrategy || (MissingTranslationStrategy = {}));
23698
23699function parserSelectorToSimpleSelector(selector) {
23700  const classes = selector.classNames && selector.classNames.length ? [8
23701  /* SelectorFlags.CLASS */
23702  , ...selector.classNames] : [];
23703  const elementName = selector.element && selector.element !== '*' ? selector.element : '';
23704  return [elementName, ...selector.attrs, ...classes];
23705}
23706
23707function parserSelectorToNegativeSelector(selector) {
23708  const classes = selector.classNames && selector.classNames.length ? [8
23709  /* SelectorFlags.CLASS */
23710  , ...selector.classNames] : [];
23711
23712  if (selector.element) {
23713    return [1
23714    /* SelectorFlags.NOT */
23715    | 4
23716    /* SelectorFlags.ELEMENT */
23717    , selector.element, ...selector.attrs, ...classes];
23718  } else if (selector.attrs.length) {
23719    return [1
23720    /* SelectorFlags.NOT */
23721    | 2
23722    /* SelectorFlags.ATTRIBUTE */
23723    , ...selector.attrs, ...classes];
23724  } else {
23725    return selector.classNames && selector.classNames.length ? [1
23726    /* SelectorFlags.NOT */
23727    | 8
23728    /* SelectorFlags.CLASS */
23729    , ...selector.classNames] : [];
23730  }
23731}
23732
23733function parserSelectorToR3Selector(selector) {
23734  const positive = parserSelectorToSimpleSelector(selector);
23735  const negative = selector.notSelectors && selector.notSelectors.length ? selector.notSelectors.map(notSelector => parserSelectorToNegativeSelector(notSelector)) : [];
23736  return positive.concat(...negative);
23737}
23738
23739function parseSelectorToR3Selector(selector) {
23740  return selector ? CssSelector.parse(selector).map(parserSelectorToR3Selector) : [];
23741}
23742
23743var core = /*#__PURE__*/Object.freeze({
23744  __proto__: null,
23745  emitDistinctChangesOnlyDefaultValue: emitDistinctChangesOnlyDefaultValue,
23746
23747  get ViewEncapsulation() {
23748    return ViewEncapsulation;
23749  },
23750
23751  get ChangeDetectionStrategy() {
23752    return ChangeDetectionStrategy;
23753  },
23754
23755  CUSTOM_ELEMENTS_SCHEMA: CUSTOM_ELEMENTS_SCHEMA,
23756  NO_ERRORS_SCHEMA: NO_ERRORS_SCHEMA,
23757  Type: Type$1,
23758
23759  get SecurityContext() {
23760    return SecurityContext;
23761  },
23762
23763  get MissingTranslationStrategy() {
23764    return MissingTranslationStrategy;
23765  },
23766
23767  parseSelectorToR3Selector: parseSelectorToR3Selector
23768});
23769/**
23770 * @license
23771 * Copyright Google LLC All Rights Reserved.
23772 *
23773 * Use of this source code is governed by an MIT-style license that can be
23774 * found in the LICENSE file at https://angular.io/license
23775 */
23776
23777const DASH_CASE_REGEXP = /-+([a-z0-9])/g;
23778
23779function dashCaseToCamelCase(input) {
23780  return input.replace(DASH_CASE_REGEXP, (...m) => m[1].toUpperCase());
23781}
23782
23783function splitAtColon(input, defaultValues) {
23784  return _splitAt(input, ':', defaultValues);
23785}
23786
23787function splitAtPeriod(input, defaultValues) {
23788  return _splitAt(input, '.', defaultValues);
23789}
23790
23791function _splitAt(input, character, defaultValues) {
23792  const characterIndex = input.indexOf(character);
23793  if (characterIndex == -1) return defaultValues;
23794  return [input.slice(0, characterIndex).trim(), input.slice(characterIndex + 1).trim()];
23795}
23796
23797function noUndefined(val) {
23798  return val === undefined ? null : val;
23799}
23800
23801function error(msg) {
23802  throw new Error(`Internal Error: ${msg}`);
23803} // Escape characters that have a special meaning in Regular Expressions
23804
23805
23806function escapeRegExp(s) {
23807  return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
23808}
23809
23810function utf8Encode(str) {
23811  let encoded = [];
23812
23813  for (let index = 0; index < str.length; index++) {
23814    let codePoint = str.charCodeAt(index); // decode surrogate
23815    // see https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
23816
23817    if (codePoint >= 0xd800 && codePoint <= 0xdbff && str.length > index + 1) {
23818      const low = str.charCodeAt(index + 1);
23819
23820      if (low >= 0xdc00 && low <= 0xdfff) {
23821        index++;
23822        codePoint = (codePoint - 0xd800 << 10) + low - 0xdc00 + 0x10000;
23823      }
23824    }
23825
23826    if (codePoint <= 0x7f) {
23827      encoded.push(codePoint);
23828    } else if (codePoint <= 0x7ff) {
23829      encoded.push(codePoint >> 6 & 0x1F | 0xc0, codePoint & 0x3f | 0x80);
23830    } else if (codePoint <= 0xffff) {
23831      encoded.push(codePoint >> 12 | 0xe0, codePoint >> 6 & 0x3f | 0x80, codePoint & 0x3f | 0x80);
23832    } else if (codePoint <= 0x1fffff) {
23833      encoded.push(codePoint >> 18 & 0x07 | 0xf0, codePoint >> 12 & 0x3f | 0x80, codePoint >> 6 & 0x3f | 0x80, codePoint & 0x3f | 0x80);
23834    }
23835  }
23836
23837  return encoded;
23838}
23839
23840function stringify(token) {
23841  if (typeof token === 'string') {
23842    return token;
23843  }
23844
23845  if (Array.isArray(token)) {
23846    return '[' + token.map(stringify).join(', ') + ']';
23847  }
23848
23849  if (token == null) {
23850    return '' + token;
23851  }
23852
23853  if (token.overriddenName) {
23854    return `${token.overriddenName}`;
23855  }
23856
23857  if (token.name) {
23858    return `${token.name}`;
23859  }
23860
23861  if (!token.toString) {
23862    return 'object';
23863  } // WARNING: do not try to `JSON.stringify(token)` here
23864  // see https://github.com/angular/angular/issues/23440
23865
23866
23867  const res = token.toString();
23868
23869  if (res == null) {
23870    return '' + res;
23871  }
23872
23873  const newLineIndex = res.indexOf('\n');
23874  return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
23875}
23876
23877class Version {
23878  constructor(full) {
23879    this.full = full;
23880    const splits = full.split('.');
23881    this.major = splits[0];
23882    this.minor = splits[1];
23883    this.patch = splits.slice(2).join('.');
23884  }
23885
23886} // Check `global` first, because in Node tests both `global` and `window` may be defined and our
23887// `_global` variable should point to the NodeJS `global` in that case. Note: Typeof/Instanceof
23888// checks are considered side-effects in Terser. We explicitly mark this as side-effect free:
23889// https://github.com/terser/terser/issues/250.
23890
23891
23892const _global = /* @__PURE__ */(() => typeof global !== 'undefined' && global || typeof window !== 'undefined' && window || typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope && self)();
23893
23894function newArray(size, value) {
23895  const list = [];
23896
23897  for (let i = 0; i < size; i++) {
23898    list.push(value);
23899  }
23900
23901  return list;
23902}
23903/**
23904 * Partitions a given array into 2 arrays, based on a boolean value returned by the condition
23905 * function.
23906 *
23907 * @param arr Input array that should be partitioned
23908 * @param conditionFn Condition function that is called for each item in a given array and returns a
23909 * boolean value.
23910 */
23911
23912
23913function partitionArray(arr, conditionFn) {
23914  const truthy = [];
23915  const falsy = [];
23916
23917  for (const item of arr) {
23918    (conditionFn(item) ? truthy : falsy).push(item);
23919  }
23920
23921  return [truthy, falsy];
23922}
23923/**
23924 * @license
23925 * Copyright Google LLC All Rights Reserved.
23926 *
23927 * Use of this source code is governed by an MIT-style license that can be
23928 * found in the LICENSE file at https://angular.io/license
23929 */
23930
23931/**
23932 * Represents a big integer using a buffer of its individual digits, with the least significant
23933 * digit stored at the beginning of the array (little endian).
23934 *
23935 * For performance reasons, each instance is mutable. The addition operation can be done in-place
23936 * to reduce memory pressure of allocation for the digits array.
23937 */
23938
23939
23940class BigInteger {
23941  /**
23942   * Creates a big integer using its individual digits in little endian storage.
23943   */
23944  constructor(digits) {
23945    this.digits = digits;
23946  }
23947
23948  static zero() {
23949    return new BigInteger([0]);
23950  }
23951
23952  static one() {
23953    return new BigInteger([1]);
23954  }
23955  /**
23956   * Creates a clone of this instance.
23957   */
23958
23959
23960  clone() {
23961    return new BigInteger(this.digits.slice());
23962  }
23963  /**
23964   * Returns a new big integer with the sum of `this` and `other` as its value. This does not mutate
23965   * `this` but instead returns a new instance, unlike `addToSelf`.
23966   */
23967
23968
23969  add(other) {
23970    const result = this.clone();
23971    result.addToSelf(other);
23972    return result;
23973  }
23974  /**
23975   * Adds `other` to the instance itself, thereby mutating its value.
23976   */
23977
23978
23979  addToSelf(other) {
23980    const maxNrOfDigits = Math.max(this.digits.length, other.digits.length);
23981    let carry = 0;
23982
23983    for (let i = 0; i < maxNrOfDigits; i++) {
23984      let digitSum = carry;
23985
23986      if (i < this.digits.length) {
23987        digitSum += this.digits[i];
23988      }
23989
23990      if (i < other.digits.length) {
23991        digitSum += other.digits[i];
23992      }
23993
23994      if (digitSum >= 10) {
23995        this.digits[i] = digitSum - 10;
23996        carry = 1;
23997      } else {
23998        this.digits[i] = digitSum;
23999        carry = 0;
24000      }
24001    } // Apply a remaining carry if needed.
24002
24003
24004    if (carry > 0) {
24005      this.digits[maxNrOfDigits] = 1;
24006    }
24007  }
24008  /**
24009   * Builds the decimal string representation of the big integer. As this is stored in
24010   * little endian, the digits are concatenated in reverse order.
24011   */
24012
24013
24014  toString() {
24015    let res = '';
24016
24017    for (let i = this.digits.length - 1; i >= 0; i--) {
24018      res += this.digits[i];
24019    }
24020
24021    return res;
24022  }
24023
24024}
24025/**
24026 * Represents a big integer which is optimized for multiplication operations, as its power-of-twos
24027 * are memoized. See `multiplyBy()` for details on the multiplication algorithm.
24028 */
24029
24030
24031class BigIntForMultiplication {
24032  constructor(value) {
24033    this.powerOfTwos = [value];
24034  }
24035  /**
24036   * Returns the big integer itself.
24037   */
24038
24039
24040  getValue() {
24041    return this.powerOfTwos[0];
24042  }
24043  /**
24044   * Computes the value for `num * b`, where `num` is a JS number and `b` is a big integer. The
24045   * value for `b` is represented by a storage model that is optimized for this computation.
24046   *
24047   * This operation is implemented in N(log2(num)) by continuous halving of the number, where the
24048   * least-significant bit (LSB) is tested in each iteration. If the bit is set, the bit's index is
24049   * used as exponent into the power-of-two multiplication of `b`.
24050   *
24051   * As an example, consider the multiplication num=42, b=1337. In binary 42 is 0b00101010 and the
24052   * algorithm unrolls into the following iterations:
24053   *
24054   *  Iteration | num        | LSB  | b * 2^iter | Add? | product
24055   * -----------|------------|------|------------|------|--------
24056   *  0         | 0b00101010 | 0    | 1337       | No   | 0
24057   *  1         | 0b00010101 | 1    | 2674       | Yes  | 2674
24058   *  2         | 0b00001010 | 0    | 5348       | No   | 2674
24059   *  3         | 0b00000101 | 1    | 10696      | Yes  | 13370
24060   *  4         | 0b00000010 | 0    | 21392      | No   | 13370
24061   *  5         | 0b00000001 | 1    | 42784      | Yes  | 56154
24062   *  6         | 0b00000000 | 0    | 85568      | No   | 56154
24063   *
24064   * The computed product of 56154 is indeed the correct result.
24065   *
24066   * The `BigIntForMultiplication` representation for a big integer provides memoized access to the
24067   * power-of-two values to reduce the workload in computing those values.
24068   */
24069
24070
24071  multiplyBy(num) {
24072    const product = BigInteger.zero();
24073    this.multiplyByAndAddTo(num, product);
24074    return product;
24075  }
24076  /**
24077   * See `multiplyBy()` for details. This function allows for the computed product to be added
24078   * directly to the provided result big integer.
24079   */
24080
24081
24082  multiplyByAndAddTo(num, result) {
24083    for (let exponent = 0; num !== 0; num = num >>> 1, exponent++) {
24084      if (num & 1) {
24085        const value = this.getMultipliedByPowerOfTwo(exponent);
24086        result.addToSelf(value);
24087      }
24088    }
24089  }
24090  /**
24091   * Computes and memoizes the big integer value for `this.number * 2^exponent`.
24092   */
24093
24094
24095  getMultipliedByPowerOfTwo(exponent) {
24096    // Compute the powers up until the requested exponent, where each value is computed from its
24097    // predecessor. This is simple as `this.number * 2^(exponent - 1)` only has to be doubled (i.e.
24098    // added to itself) to reach `this.number * 2^exponent`.
24099    for (let i = this.powerOfTwos.length; i <= exponent; i++) {
24100      const previousPower = this.powerOfTwos[i - 1];
24101      this.powerOfTwos[i] = previousPower.add(previousPower);
24102    }
24103
24104    return this.powerOfTwos[exponent];
24105  }
24106
24107}
24108/**
24109 * Represents an exponentiation operation for the provided base, of which exponents are computed and
24110 * memoized. The results are represented by a `BigIntForMultiplication` which is tailored for
24111 * multiplication operations by memoizing the power-of-twos. This effectively results in a matrix
24112 * representation that is lazily computed upon request.
24113 */
24114
24115
24116class BigIntExponentiation {
24117  constructor(base) {
24118    this.base = base;
24119    this.exponents = [new BigIntForMultiplication(BigInteger.one())];
24120  }
24121  /**
24122   * Compute the value for `this.base^exponent`, resulting in a big integer that is optimized for
24123   * further multiplication operations.
24124   */
24125
24126
24127  toThePowerOf(exponent) {
24128    // Compute the results up until the requested exponent, where every value is computed from its
24129    // predecessor. This is because `this.base^(exponent - 1)` only has to be multiplied by `base`
24130    // to reach `this.base^exponent`.
24131    for (let i = this.exponents.length; i <= exponent; i++) {
24132      const value = this.exponents[i - 1].multiplyBy(this.base);
24133      this.exponents[i] = new BigIntForMultiplication(value);
24134    }
24135
24136    return this.exponents[exponent];
24137  }
24138
24139}
24140/**
24141 * @license
24142 * Copyright Google LLC All Rights Reserved.
24143 *
24144 * Use of this source code is governed by an MIT-style license that can be
24145 * found in the LICENSE file at https://angular.io/license
24146 */
24147
24148/**
24149 * Return the message id or compute it using the XLIFF1 digest.
24150 */
24151
24152
24153function digest$1(message) {
24154  return message.id || computeDigest(message);
24155}
24156/**
24157 * Compute the message id using the XLIFF1 digest.
24158 */
24159
24160
24161function computeDigest(message) {
24162  return sha1(serializeNodes(message.nodes).join('') + `[${message.meaning}]`);
24163}
24164/**
24165 * Return the message id or compute it using the XLIFF2/XMB/$localize digest.
24166 */
24167
24168
24169function decimalDigest(message) {
24170  return message.id || computeDecimalDigest(message);
24171}
24172/**
24173 * Compute the message id using the XLIFF2/XMB/$localize digest.
24174 */
24175
24176
24177function computeDecimalDigest(message) {
24178  const visitor = new _SerializerIgnoreIcuExpVisitor();
24179  const parts = message.nodes.map(a => a.visit(visitor, null));
24180  return computeMsgId(parts.join(''), message.meaning);
24181}
24182/**
24183 * Serialize the i18n ast to something xml-like in order to generate an UID.
24184 *
24185 * The visitor is also used in the i18n parser tests
24186 *
24187 * @internal
24188 */
24189
24190
24191class _SerializerVisitor {
24192  visitText(text, context) {
24193    return text.value;
24194  }
24195
24196  visitContainer(container, context) {
24197    return `[${container.children.map(child => child.visit(this)).join(', ')}]`;
24198  }
24199
24200  visitIcu(icu, context) {
24201    const strCases = Object.keys(icu.cases).map(k => `${k} {${icu.cases[k].visit(this)}}`);
24202    return `{${icu.expression}, ${icu.type}, ${strCases.join(', ')}}`;
24203  }
24204
24205  visitTagPlaceholder(ph, context) {
24206    return ph.isVoid ? `<ph tag name="${ph.startName}"/>` : `<ph tag name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`;
24207  }
24208
24209  visitPlaceholder(ph, context) {
24210    return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`;
24211  }
24212
24213  visitIcuPlaceholder(ph, context) {
24214    return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`;
24215  }
24216
24217}
24218
24219const serializerVisitor$1 = new _SerializerVisitor();
24220
24221function serializeNodes(nodes) {
24222  return nodes.map(a => a.visit(serializerVisitor$1, null));
24223}
24224/**
24225 * Serialize the i18n ast to something xml-like in order to generate an UID.
24226 *
24227 * Ignore the ICU expressions so that message IDs stays identical if only the expression changes.
24228 *
24229 * @internal
24230 */
24231
24232
24233class _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor {
24234  visitIcu(icu, context) {
24235    let strCases = Object.keys(icu.cases).map(k => `${k} {${icu.cases[k].visit(this)}}`); // Do not take the expression into account
24236
24237    return `{${icu.type}, ${strCases.join(', ')}}`;
24238  }
24239
24240}
24241/**
24242 * Compute the SHA1 of the given string
24243 *
24244 * see https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
24245 *
24246 * WARNING: this function has not been designed not tested with security in mind.
24247 *          DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT.
24248 */
24249
24250
24251function sha1(str) {
24252  const utf8 = utf8Encode(str);
24253  const words32 = bytesToWords32(utf8, Endian.Big);
24254  const len = utf8.length * 8;
24255  const w = newArray(80);
24256  let a = 0x67452301,
24257      b = 0xefcdab89,
24258      c = 0x98badcfe,
24259      d = 0x10325476,
24260      e = 0xc3d2e1f0;
24261  words32[len >> 5] |= 0x80 << 24 - len % 32;
24262  words32[(len + 64 >> 9 << 4) + 15] = len;
24263
24264  for (let i = 0; i < words32.length; i += 16) {
24265    const h0 = a,
24266          h1 = b,
24267          h2 = c,
24268          h3 = d,
24269          h4 = e;
24270
24271    for (let j = 0; j < 80; j++) {
24272      if (j < 16) {
24273        w[j] = words32[i + j];
24274      } else {
24275        w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
24276      }
24277
24278      const fkVal = fk(j, b, c, d);
24279      const f = fkVal[0];
24280      const k = fkVal[1];
24281      const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32);
24282      e = d;
24283      d = c;
24284      c = rol32(b, 30);
24285      b = a;
24286      a = temp;
24287    }
24288
24289    a = add32(a, h0);
24290    b = add32(b, h1);
24291    c = add32(c, h2);
24292    d = add32(d, h3);
24293    e = add32(e, h4);
24294  }
24295
24296  return bytesToHexString(words32ToByteString([a, b, c, d, e]));
24297}
24298
24299function fk(index, b, c, d) {
24300  if (index < 20) {
24301    return [b & c | ~b & d, 0x5a827999];
24302  }
24303
24304  if (index < 40) {
24305    return [b ^ c ^ d, 0x6ed9eba1];
24306  }
24307
24308  if (index < 60) {
24309    return [b & c | b & d | c & d, 0x8f1bbcdc];
24310  }
24311
24312  return [b ^ c ^ d, 0xca62c1d6];
24313}
24314/**
24315 * Compute the fingerprint of the given string
24316 *
24317 * The output is 64 bit number encoded as a decimal string
24318 *
24319 * based on:
24320 * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java
24321 */
24322
24323
24324function fingerprint(str) {
24325  const utf8 = utf8Encode(str);
24326  let hi = hash32(utf8, 0);
24327  let lo = hash32(utf8, 102072);
24328
24329  if (hi == 0 && (lo == 0 || lo == 1)) {
24330    hi = hi ^ 0x130f9bef;
24331    lo = lo ^ -0x6b5f56d8;
24332  }
24333
24334  return [hi, lo];
24335}
24336
24337function computeMsgId(msg, meaning = '') {
24338  let msgFingerprint = fingerprint(msg);
24339
24340  if (meaning) {
24341    const meaningFingerprint = fingerprint(meaning);
24342    msgFingerprint = add64(rol64(msgFingerprint, 1), meaningFingerprint);
24343  }
24344
24345  const hi = msgFingerprint[0];
24346  const lo = msgFingerprint[1];
24347  return wordsToDecimalString(hi & 0x7fffffff, lo);
24348}
24349
24350function hash32(bytes, c) {
24351  let a = 0x9e3779b9,
24352      b = 0x9e3779b9;
24353  let i;
24354  const len = bytes.length;
24355
24356  for (i = 0; i + 12 <= len; i += 12) {
24357    a = add32(a, wordAt(bytes, i, Endian.Little));
24358    b = add32(b, wordAt(bytes, i + 4, Endian.Little));
24359    c = add32(c, wordAt(bytes, i + 8, Endian.Little));
24360    const res = mix(a, b, c);
24361    a = res[0], b = res[1], c = res[2];
24362  }
24363
24364  a = add32(a, wordAt(bytes, i, Endian.Little));
24365  b = add32(b, wordAt(bytes, i + 4, Endian.Little)); // the first byte of c is reserved for the length
24366
24367  c = add32(c, len);
24368  c = add32(c, wordAt(bytes, i + 8, Endian.Little) << 8);
24369  return mix(a, b, c)[2];
24370} // clang-format off
24371
24372
24373function mix(a, b, c) {
24374  a = sub32(a, b);
24375  a = sub32(a, c);
24376  a ^= c >>> 13;
24377  b = sub32(b, c);
24378  b = sub32(b, a);
24379  b ^= a << 8;
24380  c = sub32(c, a);
24381  c = sub32(c, b);
24382  c ^= b >>> 13;
24383  a = sub32(a, b);
24384  a = sub32(a, c);
24385  a ^= c >>> 12;
24386  b = sub32(b, c);
24387  b = sub32(b, a);
24388  b ^= a << 16;
24389  c = sub32(c, a);
24390  c = sub32(c, b);
24391  c ^= b >>> 5;
24392  a = sub32(a, b);
24393  a = sub32(a, c);
24394  a ^= c >>> 3;
24395  b = sub32(b, c);
24396  b = sub32(b, a);
24397  b ^= a << 10;
24398  c = sub32(c, a);
24399  c = sub32(c, b);
24400  c ^= b >>> 15;
24401  return [a, b, c];
24402} // clang-format on
24403// Utils
24404
24405
24406var Endian;
24407
24408(function (Endian) {
24409  Endian[Endian["Little"] = 0] = "Little";
24410  Endian[Endian["Big"] = 1] = "Big";
24411})(Endian || (Endian = {}));
24412
24413function add32(a, b) {
24414  return add32to64(a, b)[1];
24415}
24416
24417function add32to64(a, b) {
24418  const low = (a & 0xffff) + (b & 0xffff);
24419  const high = (a >>> 16) + (b >>> 16) + (low >>> 16);
24420  return [high >>> 16, high << 16 | low & 0xffff];
24421}
24422
24423function add64(a, b) {
24424  const ah = a[0],
24425        al = a[1];
24426  const bh = b[0],
24427        bl = b[1];
24428  const result = add32to64(al, bl);
24429  const carry = result[0];
24430  const l = result[1];
24431  const h = add32(add32(ah, bh), carry);
24432  return [h, l];
24433}
24434
24435function sub32(a, b) {
24436  const low = (a & 0xffff) - (b & 0xffff);
24437  const high = (a >> 16) - (b >> 16) + (low >> 16);
24438  return high << 16 | low & 0xffff;
24439} // Rotate a 32b number left `count` position
24440
24441
24442function rol32(a, count) {
24443  return a << count | a >>> 32 - count;
24444} // Rotate a 64b number left `count` position
24445
24446
24447function rol64(num, count) {
24448  const hi = num[0],
24449        lo = num[1];
24450  const h = hi << count | lo >>> 32 - count;
24451  const l = lo << count | hi >>> 32 - count;
24452  return [h, l];
24453}
24454
24455function bytesToWords32(bytes, endian) {
24456  const size = bytes.length + 3 >>> 2;
24457  const words32 = [];
24458
24459  for (let i = 0; i < size; i++) {
24460    words32[i] = wordAt(bytes, i * 4, endian);
24461  }
24462
24463  return words32;
24464}
24465
24466function byteAt(bytes, index) {
24467  return index >= bytes.length ? 0 : bytes[index];
24468}
24469
24470function wordAt(bytes, index, endian) {
24471  let word = 0;
24472
24473  if (endian === Endian.Big) {
24474    for (let i = 0; i < 4; i++) {
24475      word += byteAt(bytes, index + i) << 24 - 8 * i;
24476    }
24477  } else {
24478    for (let i = 0; i < 4; i++) {
24479      word += byteAt(bytes, index + i) << 8 * i;
24480    }
24481  }
24482
24483  return word;
24484}
24485
24486function words32ToByteString(words32) {
24487  return words32.reduce((bytes, word) => bytes.concat(word32ToByteString(word)), []);
24488}
24489
24490function word32ToByteString(word) {
24491  let bytes = [];
24492
24493  for (let i = 0; i < 4; i++) {
24494    bytes.push(word >>> 8 * (3 - i) & 0xff);
24495  }
24496
24497  return bytes;
24498}
24499
24500function bytesToHexString(bytes) {
24501  let hex = '';
24502
24503  for (let i = 0; i < bytes.length; i++) {
24504    const b = byteAt(bytes, i);
24505    hex += (b >>> 4).toString(16) + (b & 0x0f).toString(16);
24506  }
24507
24508  return hex.toLowerCase();
24509}
24510/**
24511 * Create a shared exponentiation pool for base-256 computations. This shared pool provides memoized
24512 * power-of-256 results with memoized power-of-two computations for efficient multiplication.
24513 *
24514 * For our purposes, this can be safely stored as a global without memory concerns. The reason is
24515 * that we encode two words, so only need the 0th (for the low word) and 4th (for the high word)
24516 * exponent.
24517 */
24518
24519
24520const base256 = new BigIntExponentiation(256);
24521/**
24522 * Represents two 32-bit words as a single decimal number. This requires a big integer storage
24523 * model as JS numbers are not accurate enough to represent the 64-bit number.
24524 *
24525 * Based on https://www.danvk.org/hex2dec.html
24526 */
24527
24528function wordsToDecimalString(hi, lo) {
24529  // Encode the four bytes in lo in the lower digits of the decimal number.
24530  // Note: the multiplication results in lo itself but represented by a big integer using its
24531  // decimal digits.
24532  const decimal = base256.toThePowerOf(0).multiplyBy(lo); // Encode the four bytes in hi above the four lo bytes. lo is a maximum of (2^8)^4, which is why
24533  // this multiplication factor is applied.
24534
24535  base256.toThePowerOf(4).multiplyByAndAddTo(hi, decimal);
24536  return decimal.toString();
24537}
24538/**
24539 * @license
24540 * Copyright Google LLC All Rights Reserved.
24541 *
24542 * Use of this source code is governed by an MIT-style license that can be
24543 * found in the LICENSE file at https://angular.io/license
24544 */
24545//// Types
24546
24547
24548var TypeModifier;
24549
24550(function (TypeModifier) {
24551  TypeModifier[TypeModifier["None"] = 0] = "None";
24552  TypeModifier[TypeModifier["Const"] = 1] = "Const";
24553})(TypeModifier || (TypeModifier = {}));
24554
24555class Type {
24556  constructor(modifiers = TypeModifier.None) {
24557    this.modifiers = modifiers;
24558  }
24559
24560  hasModifier(modifier) {
24561    return (this.modifiers & modifier) !== 0;
24562  }
24563
24564}
24565
24566var BuiltinTypeName;
24567
24568(function (BuiltinTypeName) {
24569  BuiltinTypeName[BuiltinTypeName["Dynamic"] = 0] = "Dynamic";
24570  BuiltinTypeName[BuiltinTypeName["Bool"] = 1] = "Bool";
24571  BuiltinTypeName[BuiltinTypeName["String"] = 2] = "String";
24572  BuiltinTypeName[BuiltinTypeName["Int"] = 3] = "Int";
24573  BuiltinTypeName[BuiltinTypeName["Number"] = 4] = "Number";
24574  BuiltinTypeName[BuiltinTypeName["Function"] = 5] = "Function";
24575  BuiltinTypeName[BuiltinTypeName["Inferred"] = 6] = "Inferred";
24576  BuiltinTypeName[BuiltinTypeName["None"] = 7] = "None";
24577})(BuiltinTypeName || (BuiltinTypeName = {}));
24578
24579class BuiltinType extends Type {
24580  constructor(name, modifiers) {
24581    super(modifiers);
24582    this.name = name;
24583  }
24584
24585  visitType(visitor, context) {
24586    return visitor.visitBuiltinType(this, context);
24587  }
24588
24589}
24590
24591class ExpressionType extends Type {
24592  constructor(value, modifiers, typeParams = null) {
24593    super(modifiers);
24594    this.value = value;
24595    this.typeParams = typeParams;
24596  }
24597
24598  visitType(visitor, context) {
24599    return visitor.visitExpressionType(this, context);
24600  }
24601
24602}
24603
24604class ArrayType extends Type {
24605  constructor(of, modifiers) {
24606    super(modifiers);
24607    this.of = of;
24608  }
24609
24610  visitType(visitor, context) {
24611    return visitor.visitArrayType(this, context);
24612  }
24613
24614}
24615
24616class MapType extends Type {
24617  constructor(valueType, modifiers) {
24618    super(modifiers);
24619    this.valueType = valueType || null;
24620  }
24621
24622  visitType(visitor, context) {
24623    return visitor.visitMapType(this, context);
24624  }
24625
24626}
24627
24628const DYNAMIC_TYPE = new BuiltinType(BuiltinTypeName.Dynamic);
24629const INFERRED_TYPE = new BuiltinType(BuiltinTypeName.Inferred);
24630const BOOL_TYPE = new BuiltinType(BuiltinTypeName.Bool);
24631const INT_TYPE = new BuiltinType(BuiltinTypeName.Int);
24632const NUMBER_TYPE = new BuiltinType(BuiltinTypeName.Number);
24633const STRING_TYPE = new BuiltinType(BuiltinTypeName.String);
24634const FUNCTION_TYPE = new BuiltinType(BuiltinTypeName.Function);
24635const NONE_TYPE = new BuiltinType(BuiltinTypeName.None); ///// Expressions
24636
24637var UnaryOperator;
24638
24639(function (UnaryOperator) {
24640  UnaryOperator[UnaryOperator["Minus"] = 0] = "Minus";
24641  UnaryOperator[UnaryOperator["Plus"] = 1] = "Plus";
24642})(UnaryOperator || (UnaryOperator = {}));
24643
24644var BinaryOperator;
24645
24646(function (BinaryOperator) {
24647  BinaryOperator[BinaryOperator["Equals"] = 0] = "Equals";
24648  BinaryOperator[BinaryOperator["NotEquals"] = 1] = "NotEquals";
24649  BinaryOperator[BinaryOperator["Identical"] = 2] = "Identical";
24650  BinaryOperator[BinaryOperator["NotIdentical"] = 3] = "NotIdentical";
24651  BinaryOperator[BinaryOperator["Minus"] = 4] = "Minus";
24652  BinaryOperator[BinaryOperator["Plus"] = 5] = "Plus";
24653  BinaryOperator[BinaryOperator["Divide"] = 6] = "Divide";
24654  BinaryOperator[BinaryOperator["Multiply"] = 7] = "Multiply";
24655  BinaryOperator[BinaryOperator["Modulo"] = 8] = "Modulo";
24656  BinaryOperator[BinaryOperator["And"] = 9] = "And";
24657  BinaryOperator[BinaryOperator["Or"] = 10] = "Or";
24658  BinaryOperator[BinaryOperator["BitwiseAnd"] = 11] = "BitwiseAnd";
24659  BinaryOperator[BinaryOperator["Lower"] = 12] = "Lower";
24660  BinaryOperator[BinaryOperator["LowerEquals"] = 13] = "LowerEquals";
24661  BinaryOperator[BinaryOperator["Bigger"] = 14] = "Bigger";
24662  BinaryOperator[BinaryOperator["BiggerEquals"] = 15] = "BiggerEquals";
24663  BinaryOperator[BinaryOperator["NullishCoalesce"] = 16] = "NullishCoalesce";
24664})(BinaryOperator || (BinaryOperator = {}));
24665
24666function nullSafeIsEquivalent(base, other) {
24667  if (base == null || other == null) {
24668    return base == other;
24669  }
24670
24671  return base.isEquivalent(other);
24672}
24673
24674function areAllEquivalentPredicate(base, other, equivalentPredicate) {
24675  const len = base.length;
24676
24677  if (len !== other.length) {
24678    return false;
24679  }
24680
24681  for (let i = 0; i < len; i++) {
24682    if (!equivalentPredicate(base[i], other[i])) {
24683      return false;
24684    }
24685  }
24686
24687  return true;
24688}
24689
24690function areAllEquivalent(base, other) {
24691  return areAllEquivalentPredicate(base, other, (baseElement, otherElement) => baseElement.isEquivalent(otherElement));
24692}
24693
24694class Expression {
24695  constructor(type, sourceSpan) {
24696    this.type = type || null;
24697    this.sourceSpan = sourceSpan || null;
24698  }
24699
24700  prop(name, sourceSpan) {
24701    return new ReadPropExpr(this, name, null, sourceSpan);
24702  }
24703
24704  key(index, type, sourceSpan) {
24705    return new ReadKeyExpr(this, index, type, sourceSpan);
24706  }
24707
24708  callFn(params, sourceSpan, pure) {
24709    return new InvokeFunctionExpr(this, params, null, sourceSpan, pure);
24710  }
24711
24712  instantiate(params, type, sourceSpan) {
24713    return new InstantiateExpr(this, params, type, sourceSpan);
24714  }
24715
24716  conditional(trueCase, falseCase = null, sourceSpan) {
24717    return new ConditionalExpr(this, trueCase, falseCase, null, sourceSpan);
24718  }
24719
24720  equals(rhs, sourceSpan) {
24721    return new BinaryOperatorExpr(BinaryOperator.Equals, this, rhs, null, sourceSpan);
24722  }
24723
24724  notEquals(rhs, sourceSpan) {
24725    return new BinaryOperatorExpr(BinaryOperator.NotEquals, this, rhs, null, sourceSpan);
24726  }
24727
24728  identical(rhs, sourceSpan) {
24729    return new BinaryOperatorExpr(BinaryOperator.Identical, this, rhs, null, sourceSpan);
24730  }
24731
24732  notIdentical(rhs, sourceSpan) {
24733    return new BinaryOperatorExpr(BinaryOperator.NotIdentical, this, rhs, null, sourceSpan);
24734  }
24735
24736  minus(rhs, sourceSpan) {
24737    return new BinaryOperatorExpr(BinaryOperator.Minus, this, rhs, null, sourceSpan);
24738  }
24739
24740  plus(rhs, sourceSpan) {
24741    return new BinaryOperatorExpr(BinaryOperator.Plus, this, rhs, null, sourceSpan);
24742  }
24743
24744  divide(rhs, sourceSpan) {
24745    return new BinaryOperatorExpr(BinaryOperator.Divide, this, rhs, null, sourceSpan);
24746  }
24747
24748  multiply(rhs, sourceSpan) {
24749    return new BinaryOperatorExpr(BinaryOperator.Multiply, this, rhs, null, sourceSpan);
24750  }
24751
24752  modulo(rhs, sourceSpan) {
24753    return new BinaryOperatorExpr(BinaryOperator.Modulo, this, rhs, null, sourceSpan);
24754  }
24755
24756  and(rhs, sourceSpan) {
24757    return new BinaryOperatorExpr(BinaryOperator.And, this, rhs, null, sourceSpan);
24758  }
24759
24760  bitwiseAnd(rhs, sourceSpan, parens = true) {
24761    return new BinaryOperatorExpr(BinaryOperator.BitwiseAnd, this, rhs, null, sourceSpan, parens);
24762  }
24763
24764  or(rhs, sourceSpan) {
24765    return new BinaryOperatorExpr(BinaryOperator.Or, this, rhs, null, sourceSpan);
24766  }
24767
24768  lower(rhs, sourceSpan) {
24769    return new BinaryOperatorExpr(BinaryOperator.Lower, this, rhs, null, sourceSpan);
24770  }
24771
24772  lowerEquals(rhs, sourceSpan) {
24773    return new BinaryOperatorExpr(BinaryOperator.LowerEquals, this, rhs, null, sourceSpan);
24774  }
24775
24776  bigger(rhs, sourceSpan) {
24777    return new BinaryOperatorExpr(BinaryOperator.Bigger, this, rhs, null, sourceSpan);
24778  }
24779
24780  biggerEquals(rhs, sourceSpan) {
24781    return new BinaryOperatorExpr(BinaryOperator.BiggerEquals, this, rhs, null, sourceSpan);
24782  }
24783
24784  isBlank(sourceSpan) {
24785    // Note: We use equals by purpose here to compare to null and undefined in JS.
24786    // We use the typed null to allow strictNullChecks to narrow types.
24787    return this.equals(TYPED_NULL_EXPR, sourceSpan);
24788  }
24789
24790  nullishCoalesce(rhs, sourceSpan) {
24791    return new BinaryOperatorExpr(BinaryOperator.NullishCoalesce, this, rhs, null, sourceSpan);
24792  }
24793
24794  toStmt() {
24795    return new ExpressionStatement(this, null);
24796  }
24797
24798}
24799
24800class ReadVarExpr extends Expression {
24801  constructor(name, type, sourceSpan) {
24802    super(type, sourceSpan);
24803    this.name = name;
24804  }
24805
24806  isEquivalent(e) {
24807    return e instanceof ReadVarExpr && this.name === e.name;
24808  }
24809
24810  isConstant() {
24811    return false;
24812  }
24813
24814  visitExpression(visitor, context) {
24815    return visitor.visitReadVarExpr(this, context);
24816  }
24817
24818  set(value) {
24819    return new WriteVarExpr(this.name, value, null, this.sourceSpan);
24820  }
24821
24822}
24823
24824class TypeofExpr extends Expression {
24825  constructor(expr, type, sourceSpan) {
24826    super(type, sourceSpan);
24827    this.expr = expr;
24828  }
24829
24830  visitExpression(visitor, context) {
24831    return visitor.visitTypeofExpr(this, context);
24832  }
24833
24834  isEquivalent(e) {
24835    return e instanceof TypeofExpr && e.expr.isEquivalent(this.expr);
24836  }
24837
24838  isConstant() {
24839    return this.expr.isConstant();
24840  }
24841
24842}
24843
24844class WrappedNodeExpr extends Expression {
24845  constructor(node, type, sourceSpan) {
24846    super(type, sourceSpan);
24847    this.node = node;
24848  }
24849
24850  isEquivalent(e) {
24851    return e instanceof WrappedNodeExpr && this.node === e.node;
24852  }
24853
24854  isConstant() {
24855    return false;
24856  }
24857
24858  visitExpression(visitor, context) {
24859    return visitor.visitWrappedNodeExpr(this, context);
24860  }
24861
24862}
24863
24864class WriteVarExpr extends Expression {
24865  constructor(name, value, type, sourceSpan) {
24866    super(type || value.type, sourceSpan);
24867    this.name = name;
24868    this.value = value;
24869  }
24870
24871  isEquivalent(e) {
24872    return e instanceof WriteVarExpr && this.name === e.name && this.value.isEquivalent(e.value);
24873  }
24874
24875  isConstant() {
24876    return false;
24877  }
24878
24879  visitExpression(visitor, context) {
24880    return visitor.visitWriteVarExpr(this, context);
24881  }
24882
24883  toDeclStmt(type, modifiers) {
24884    return new DeclareVarStmt(this.name, this.value, type, modifiers, this.sourceSpan);
24885  }
24886
24887  toConstDecl() {
24888    return this.toDeclStmt(INFERRED_TYPE, StmtModifier.Final);
24889  }
24890
24891}
24892
24893class WriteKeyExpr extends Expression {
24894  constructor(receiver, index, value, type, sourceSpan) {
24895    super(type || value.type, sourceSpan);
24896    this.receiver = receiver;
24897    this.index = index;
24898    this.value = value;
24899  }
24900
24901  isEquivalent(e) {
24902    return e instanceof WriteKeyExpr && this.receiver.isEquivalent(e.receiver) && this.index.isEquivalent(e.index) && this.value.isEquivalent(e.value);
24903  }
24904
24905  isConstant() {
24906    return false;
24907  }
24908
24909  visitExpression(visitor, context) {
24910    return visitor.visitWriteKeyExpr(this, context);
24911  }
24912
24913}
24914
24915class WritePropExpr extends Expression {
24916  constructor(receiver, name, value, type, sourceSpan) {
24917    super(type || value.type, sourceSpan);
24918    this.receiver = receiver;
24919    this.name = name;
24920    this.value = value;
24921  }
24922
24923  isEquivalent(e) {
24924    return e instanceof WritePropExpr && this.receiver.isEquivalent(e.receiver) && this.name === e.name && this.value.isEquivalent(e.value);
24925  }
24926
24927  isConstant() {
24928    return false;
24929  }
24930
24931  visitExpression(visitor, context) {
24932    return visitor.visitWritePropExpr(this, context);
24933  }
24934
24935}
24936
24937class InvokeFunctionExpr extends Expression {
24938  constructor(fn, args, type, sourceSpan, pure = false) {
24939    super(type, sourceSpan);
24940    this.fn = fn;
24941    this.args = args;
24942    this.pure = pure;
24943  }
24944
24945  isEquivalent(e) {
24946    return e instanceof InvokeFunctionExpr && this.fn.isEquivalent(e.fn) && areAllEquivalent(this.args, e.args) && this.pure === e.pure;
24947  }
24948
24949  isConstant() {
24950    return false;
24951  }
24952
24953  visitExpression(visitor, context) {
24954    return visitor.visitInvokeFunctionExpr(this, context);
24955  }
24956
24957}
24958
24959class TaggedTemplateExpr extends Expression {
24960  constructor(tag, template, type, sourceSpan) {
24961    super(type, sourceSpan);
24962    this.tag = tag;
24963    this.template = template;
24964  }
24965
24966  isEquivalent(e) {
24967    return e instanceof TaggedTemplateExpr && this.tag.isEquivalent(e.tag) && areAllEquivalentPredicate(this.template.elements, e.template.elements, (a, b) => a.text === b.text) && areAllEquivalent(this.template.expressions, e.template.expressions);
24968  }
24969
24970  isConstant() {
24971    return false;
24972  }
24973
24974  visitExpression(visitor, context) {
24975    return visitor.visitTaggedTemplateExpr(this, context);
24976  }
24977
24978}
24979
24980class InstantiateExpr extends Expression {
24981  constructor(classExpr, args, type, sourceSpan) {
24982    super(type, sourceSpan);
24983    this.classExpr = classExpr;
24984    this.args = args;
24985  }
24986
24987  isEquivalent(e) {
24988    return e instanceof InstantiateExpr && this.classExpr.isEquivalent(e.classExpr) && areAllEquivalent(this.args, e.args);
24989  }
24990
24991  isConstant() {
24992    return false;
24993  }
24994
24995  visitExpression(visitor, context) {
24996    return visitor.visitInstantiateExpr(this, context);
24997  }
24998
24999}
25000
25001class LiteralExpr extends Expression {
25002  constructor(value, type, sourceSpan) {
25003    super(type, sourceSpan);
25004    this.value = value;
25005  }
25006
25007  isEquivalent(e) {
25008    return e instanceof LiteralExpr && this.value === e.value;
25009  }
25010
25011  isConstant() {
25012    return true;
25013  }
25014
25015  visitExpression(visitor, context) {
25016    return visitor.visitLiteralExpr(this, context);
25017  }
25018
25019}
25020
25021class TemplateLiteral {
25022  constructor(elements, expressions) {
25023    this.elements = elements;
25024    this.expressions = expressions;
25025  }
25026
25027}
25028
25029class TemplateLiteralElement {
25030  constructor(text, sourceSpan, rawText) {
25031    this.text = text;
25032    this.sourceSpan = sourceSpan; // If `rawText` is not provided, try to extract the raw string from its
25033    // associated `sourceSpan`. If that is also not available, "fake" the raw
25034    // string instead by escaping the following control sequences:
25035    // - "\" would otherwise indicate that the next character is a control character.
25036    // - "`" and "${" are template string control sequences that would otherwise prematurely
25037    // indicate the end of the template literal element.
25038
25039    this.rawText = rawText ?? sourceSpan?.toString() ?? escapeForTemplateLiteral(escapeSlashes(text));
25040  }
25041
25042}
25043
25044class LiteralPiece {
25045  constructor(text, sourceSpan) {
25046    this.text = text;
25047    this.sourceSpan = sourceSpan;
25048  }
25049
25050}
25051
25052class PlaceholderPiece {
25053  /**
25054   * Create a new instance of a `PlaceholderPiece`.
25055   *
25056   * @param text the name of this placeholder (e.g. `PH_1`).
25057   * @param sourceSpan the location of this placeholder in its localized message the source code.
25058   * @param associatedMessage reference to another message that this placeholder is associated with.
25059   * The `associatedMessage` is mainly used to provide a relationship to an ICU message that has
25060   * been extracted out from the message containing the placeholder.
25061   */
25062  constructor(text, sourceSpan, associatedMessage) {
25063    this.text = text;
25064    this.sourceSpan = sourceSpan;
25065    this.associatedMessage = associatedMessage;
25066  }
25067
25068}
25069
25070const MEANING_SEPARATOR$1 = '|';
25071const ID_SEPARATOR$1 = '@@';
25072const LEGACY_ID_INDICATOR = '␟';
25073
25074class LocalizedString extends Expression {
25075  constructor(metaBlock, messageParts, placeHolderNames, expressions, sourceSpan) {
25076    super(STRING_TYPE, sourceSpan);
25077    this.metaBlock = metaBlock;
25078    this.messageParts = messageParts;
25079    this.placeHolderNames = placeHolderNames;
25080    this.expressions = expressions;
25081  }
25082
25083  isEquivalent(e) {
25084    // return e instanceof LocalizedString && this.message === e.message;
25085    return false;
25086  }
25087
25088  isConstant() {
25089    return false;
25090  }
25091
25092  visitExpression(visitor, context) {
25093    return visitor.visitLocalizedString(this, context);
25094  }
25095  /**
25096   * Serialize the given `meta` and `messagePart` into "cooked" and "raw" strings that can be used
25097   * in a `$localize` tagged string. The format of the metadata is the same as that parsed by
25098   * `parseI18nMeta()`.
25099   *
25100   * @param meta The metadata to serialize
25101   * @param messagePart The first part of the tagged string
25102   */
25103
25104
25105  serializeI18nHead() {
25106    let metaBlock = this.metaBlock.description || '';
25107
25108    if (this.metaBlock.meaning) {
25109      metaBlock = `${this.metaBlock.meaning}${MEANING_SEPARATOR$1}${metaBlock}`;
25110    }
25111
25112    if (this.metaBlock.customId) {
25113      metaBlock = `${metaBlock}${ID_SEPARATOR$1}${this.metaBlock.customId}`;
25114    }
25115
25116    if (this.metaBlock.legacyIds) {
25117      this.metaBlock.legacyIds.forEach(legacyId => {
25118        metaBlock = `${metaBlock}${LEGACY_ID_INDICATOR}${legacyId}`;
25119      });
25120    }
25121
25122    return createCookedRawString(metaBlock, this.messageParts[0].text, this.getMessagePartSourceSpan(0));
25123  }
25124
25125  getMessagePartSourceSpan(i) {
25126    return this.messageParts[i]?.sourceSpan ?? this.sourceSpan;
25127  }
25128
25129  getPlaceholderSourceSpan(i) {
25130    return this.placeHolderNames[i]?.sourceSpan ?? this.expressions[i]?.sourceSpan ?? this.sourceSpan;
25131  }
25132  /**
25133   * Serialize the given `placeholderName` and `messagePart` into "cooked" and "raw" strings that
25134   * can be used in a `$localize` tagged string.
25135   *
25136   * The format is `:<placeholder-name>[@@<associated-id>]:`.
25137   *
25138   * The `associated-id` is the message id of the (usually an ICU) message to which this placeholder
25139   * refers.
25140   *
25141   * @param partIndex The index of the message part to serialize.
25142   */
25143
25144
25145  serializeI18nTemplatePart(partIndex) {
25146    const placeholder = this.placeHolderNames[partIndex - 1];
25147    const messagePart = this.messageParts[partIndex];
25148    let metaBlock = placeholder.text;
25149
25150    if (placeholder.associatedMessage?.legacyIds.length === 0) {
25151      metaBlock += `${ID_SEPARATOR$1}${computeMsgId(placeholder.associatedMessage.messageString, placeholder.associatedMessage.meaning)}`;
25152    }
25153
25154    return createCookedRawString(metaBlock, messagePart.text, this.getMessagePartSourceSpan(partIndex));
25155  }
25156
25157}
25158
25159const escapeSlashes = str => str.replace(/\\/g, '\\\\');
25160
25161const escapeStartingColon = str => str.replace(/^:/, '\\:');
25162
25163const escapeColons = str => str.replace(/:/g, '\\:');
25164
25165const escapeForTemplateLiteral = str => str.replace(/`/g, '\\`').replace(/\${/g, '$\\{');
25166/**
25167 * Creates a `{cooked, raw}` object from the `metaBlock` and `messagePart`.
25168 *
25169 * The `raw` text must have various character sequences escaped:
25170 * * "\" would otherwise indicate that the next character is a control character.
25171 * * "`" and "${" are template string control sequences that would otherwise prematurely indicate
25172 *   the end of a message part.
25173 * * ":" inside a metablock would prematurely indicate the end of the metablock.
25174 * * ":" at the start of a messagePart with no metablock would erroneously indicate the start of a
25175 *   metablock.
25176 *
25177 * @param metaBlock Any metadata that should be prepended to the string
25178 * @param messagePart The message part of the string
25179 */
25180
25181
25182function createCookedRawString(metaBlock, messagePart, range) {
25183  if (metaBlock === '') {
25184    return {
25185      cooked: messagePart,
25186      raw: escapeForTemplateLiteral(escapeStartingColon(escapeSlashes(messagePart))),
25187      range
25188    };
25189  } else {
25190    return {
25191      cooked: `:${metaBlock}:${messagePart}`,
25192      raw: escapeForTemplateLiteral(`:${escapeColons(escapeSlashes(metaBlock))}:${escapeSlashes(messagePart)}`),
25193      range
25194    };
25195  }
25196}
25197
25198class ExternalExpr extends Expression {
25199  constructor(value, type, typeParams = null, sourceSpan) {
25200    super(type, sourceSpan);
25201    this.value = value;
25202    this.typeParams = typeParams;
25203  }
25204
25205  isEquivalent(e) {
25206    return e instanceof ExternalExpr && this.value.name === e.value.name && this.value.moduleName === e.value.moduleName && this.value.runtime === e.value.runtime;
25207  }
25208
25209  isConstant() {
25210    return false;
25211  }
25212
25213  visitExpression(visitor, context) {
25214    return visitor.visitExternalExpr(this, context);
25215  }
25216
25217}
25218
25219class ExternalReference {
25220  constructor(moduleName, name, runtime) {
25221    this.moduleName = moduleName;
25222    this.name = name;
25223    this.runtime = runtime;
25224  }
25225
25226}
25227
25228class ConditionalExpr extends Expression {
25229  constructor(condition, trueCase, falseCase = null, type, sourceSpan) {
25230    super(type || trueCase.type, sourceSpan);
25231    this.condition = condition;
25232    this.falseCase = falseCase;
25233    this.trueCase = trueCase;
25234  }
25235
25236  isEquivalent(e) {
25237    return e instanceof ConditionalExpr && this.condition.isEquivalent(e.condition) && this.trueCase.isEquivalent(e.trueCase) && nullSafeIsEquivalent(this.falseCase, e.falseCase);
25238  }
25239
25240  isConstant() {
25241    return false;
25242  }
25243
25244  visitExpression(visitor, context) {
25245    return visitor.visitConditionalExpr(this, context);
25246  }
25247
25248}
25249
25250class NotExpr extends Expression {
25251  constructor(condition, sourceSpan) {
25252    super(BOOL_TYPE, sourceSpan);
25253    this.condition = condition;
25254  }
25255
25256  isEquivalent(e) {
25257    return e instanceof NotExpr && this.condition.isEquivalent(e.condition);
25258  }
25259
25260  isConstant() {
25261    return false;
25262  }
25263
25264  visitExpression(visitor, context) {
25265    return visitor.visitNotExpr(this, context);
25266  }
25267
25268}
25269
25270class FnParam {
25271  constructor(name, type = null) {
25272    this.name = name;
25273    this.type = type;
25274  }
25275
25276  isEquivalent(param) {
25277    return this.name === param.name;
25278  }
25279
25280}
25281
25282class FunctionExpr extends Expression {
25283  constructor(params, statements, type, sourceSpan, name) {
25284    super(type, sourceSpan);
25285    this.params = params;
25286    this.statements = statements;
25287    this.name = name;
25288  }
25289
25290  isEquivalent(e) {
25291    return e instanceof FunctionExpr && areAllEquivalent(this.params, e.params) && areAllEquivalent(this.statements, e.statements);
25292  }
25293
25294  isConstant() {
25295    return false;
25296  }
25297
25298  visitExpression(visitor, context) {
25299    return visitor.visitFunctionExpr(this, context);
25300  }
25301
25302  toDeclStmt(name, modifiers) {
25303    return new DeclareFunctionStmt(name, this.params, this.statements, this.type, modifiers, this.sourceSpan);
25304  }
25305
25306}
25307
25308class UnaryOperatorExpr extends Expression {
25309  constructor(operator, expr, type, sourceSpan, parens = true) {
25310    super(type || NUMBER_TYPE, sourceSpan);
25311    this.operator = operator;
25312    this.expr = expr;
25313    this.parens = parens;
25314  }
25315
25316  isEquivalent(e) {
25317    return e instanceof UnaryOperatorExpr && this.operator === e.operator && this.expr.isEquivalent(e.expr);
25318  }
25319
25320  isConstant() {
25321    return false;
25322  }
25323
25324  visitExpression(visitor, context) {
25325    return visitor.visitUnaryOperatorExpr(this, context);
25326  }
25327
25328}
25329
25330class BinaryOperatorExpr extends Expression {
25331  constructor(operator, lhs, rhs, type, sourceSpan, parens = true) {
25332    super(type || lhs.type, sourceSpan);
25333    this.operator = operator;
25334    this.rhs = rhs;
25335    this.parens = parens;
25336    this.lhs = lhs;
25337  }
25338
25339  isEquivalent(e) {
25340    return e instanceof BinaryOperatorExpr && this.operator === e.operator && this.lhs.isEquivalent(e.lhs) && this.rhs.isEquivalent(e.rhs);
25341  }
25342
25343  isConstant() {
25344    return false;
25345  }
25346
25347  visitExpression(visitor, context) {
25348    return visitor.visitBinaryOperatorExpr(this, context);
25349  }
25350
25351}
25352
25353class ReadPropExpr extends Expression {
25354  constructor(receiver, name, type, sourceSpan) {
25355    super(type, sourceSpan);
25356    this.receiver = receiver;
25357    this.name = name;
25358  }
25359
25360  isEquivalent(e) {
25361    return e instanceof ReadPropExpr && this.receiver.isEquivalent(e.receiver) && this.name === e.name;
25362  }
25363
25364  isConstant() {
25365    return false;
25366  }
25367
25368  visitExpression(visitor, context) {
25369    return visitor.visitReadPropExpr(this, context);
25370  }
25371
25372  set(value) {
25373    return new WritePropExpr(this.receiver, this.name, value, null, this.sourceSpan);
25374  }
25375
25376}
25377
25378class ReadKeyExpr extends Expression {
25379  constructor(receiver, index, type, sourceSpan) {
25380    super(type, sourceSpan);
25381    this.receiver = receiver;
25382    this.index = index;
25383  }
25384
25385  isEquivalent(e) {
25386    return e instanceof ReadKeyExpr && this.receiver.isEquivalent(e.receiver) && this.index.isEquivalent(e.index);
25387  }
25388
25389  isConstant() {
25390    return false;
25391  }
25392
25393  visitExpression(visitor, context) {
25394    return visitor.visitReadKeyExpr(this, context);
25395  }
25396
25397  set(value) {
25398    return new WriteKeyExpr(this.receiver, this.index, value, null, this.sourceSpan);
25399  }
25400
25401}
25402
25403class LiteralArrayExpr extends Expression {
25404  constructor(entries, type, sourceSpan) {
25405    super(type, sourceSpan);
25406    this.entries = entries;
25407  }
25408
25409  isConstant() {
25410    return this.entries.every(e => e.isConstant());
25411  }
25412
25413  isEquivalent(e) {
25414    return e instanceof LiteralArrayExpr && areAllEquivalent(this.entries, e.entries);
25415  }
25416
25417  visitExpression(visitor, context) {
25418    return visitor.visitLiteralArrayExpr(this, context);
25419  }
25420
25421}
25422
25423class LiteralMapEntry {
25424  constructor(key, value, quoted) {
25425    this.key = key;
25426    this.value = value;
25427    this.quoted = quoted;
25428  }
25429
25430  isEquivalent(e) {
25431    return this.key === e.key && this.value.isEquivalent(e.value);
25432  }
25433
25434}
25435
25436class LiteralMapExpr extends Expression {
25437  constructor(entries, type, sourceSpan) {
25438    super(type, sourceSpan);
25439    this.entries = entries;
25440    this.valueType = null;
25441
25442    if (type) {
25443      this.valueType = type.valueType;
25444    }
25445  }
25446
25447  isEquivalent(e) {
25448    return e instanceof LiteralMapExpr && areAllEquivalent(this.entries, e.entries);
25449  }
25450
25451  isConstant() {
25452    return this.entries.every(e => e.value.isConstant());
25453  }
25454
25455  visitExpression(visitor, context) {
25456    return visitor.visitLiteralMapExpr(this, context);
25457  }
25458
25459}
25460
25461class CommaExpr extends Expression {
25462  constructor(parts, sourceSpan) {
25463    super(parts[parts.length - 1].type, sourceSpan);
25464    this.parts = parts;
25465  }
25466
25467  isEquivalent(e) {
25468    return e instanceof CommaExpr && areAllEquivalent(this.parts, e.parts);
25469  }
25470
25471  isConstant() {
25472    return false;
25473  }
25474
25475  visitExpression(visitor, context) {
25476    return visitor.visitCommaExpr(this, context);
25477  }
25478
25479}
25480
25481const NULL_EXPR = new LiteralExpr(null, null, null);
25482const TYPED_NULL_EXPR = new LiteralExpr(null, INFERRED_TYPE, null); //// Statements
25483
25484var StmtModifier;
25485
25486(function (StmtModifier) {
25487  StmtModifier[StmtModifier["None"] = 0] = "None";
25488  StmtModifier[StmtModifier["Final"] = 1] = "Final";
25489  StmtModifier[StmtModifier["Private"] = 2] = "Private";
25490  StmtModifier[StmtModifier["Exported"] = 4] = "Exported";
25491  StmtModifier[StmtModifier["Static"] = 8] = "Static";
25492})(StmtModifier || (StmtModifier = {}));
25493
25494class LeadingComment {
25495  constructor(text, multiline, trailingNewline) {
25496    this.text = text;
25497    this.multiline = multiline;
25498    this.trailingNewline = trailingNewline;
25499  }
25500
25501  toString() {
25502    return this.multiline ? ` ${this.text} ` : this.text;
25503  }
25504
25505}
25506
25507class JSDocComment extends LeadingComment {
25508  constructor(tags) {
25509    super('',
25510    /* multiline */
25511    true,
25512    /* trailingNewline */
25513    true);
25514    this.tags = tags;
25515  }
25516
25517  toString() {
25518    return serializeTags(this.tags);
25519  }
25520
25521}
25522
25523class Statement {
25524  constructor(modifiers = StmtModifier.None, sourceSpan = null, leadingComments) {
25525    this.modifiers = modifiers;
25526    this.sourceSpan = sourceSpan;
25527    this.leadingComments = leadingComments;
25528  }
25529
25530  hasModifier(modifier) {
25531    return (this.modifiers & modifier) !== 0;
25532  }
25533
25534  addLeadingComment(leadingComment) {
25535    this.leadingComments = this.leadingComments ?? [];
25536    this.leadingComments.push(leadingComment);
25537  }
25538
25539}
25540
25541class DeclareVarStmt extends Statement {
25542  constructor(name, value, type, modifiers, sourceSpan, leadingComments) {
25543    super(modifiers, sourceSpan, leadingComments);
25544    this.name = name;
25545    this.value = value;
25546    this.type = type || value && value.type || null;
25547  }
25548
25549  isEquivalent(stmt) {
25550    return stmt instanceof DeclareVarStmt && this.name === stmt.name && (this.value ? !!stmt.value && this.value.isEquivalent(stmt.value) : !stmt.value);
25551  }
25552
25553  visitStatement(visitor, context) {
25554    return visitor.visitDeclareVarStmt(this, context);
25555  }
25556
25557}
25558
25559class DeclareFunctionStmt extends Statement {
25560  constructor(name, params, statements, type, modifiers, sourceSpan, leadingComments) {
25561    super(modifiers, sourceSpan, leadingComments);
25562    this.name = name;
25563    this.params = params;
25564    this.statements = statements;
25565    this.type = type || null;
25566  }
25567
25568  isEquivalent(stmt) {
25569    return stmt instanceof DeclareFunctionStmt && areAllEquivalent(this.params, stmt.params) && areAllEquivalent(this.statements, stmt.statements);
25570  }
25571
25572  visitStatement(visitor, context) {
25573    return visitor.visitDeclareFunctionStmt(this, context);
25574  }
25575
25576}
25577
25578class ExpressionStatement extends Statement {
25579  constructor(expr, sourceSpan, leadingComments) {
25580    super(StmtModifier.None, sourceSpan, leadingComments);
25581    this.expr = expr;
25582  }
25583
25584  isEquivalent(stmt) {
25585    return stmt instanceof ExpressionStatement && this.expr.isEquivalent(stmt.expr);
25586  }
25587
25588  visitStatement(visitor, context) {
25589    return visitor.visitExpressionStmt(this, context);
25590  }
25591
25592}
25593
25594class ReturnStatement extends Statement {
25595  constructor(value, sourceSpan = null, leadingComments) {
25596    super(StmtModifier.None, sourceSpan, leadingComments);
25597    this.value = value;
25598  }
25599
25600  isEquivalent(stmt) {
25601    return stmt instanceof ReturnStatement && this.value.isEquivalent(stmt.value);
25602  }
25603
25604  visitStatement(visitor, context) {
25605    return visitor.visitReturnStmt(this, context);
25606  }
25607
25608}
25609
25610class IfStmt extends Statement {
25611  constructor(condition, trueCase, falseCase = [], sourceSpan, leadingComments) {
25612    super(StmtModifier.None, sourceSpan, leadingComments);
25613    this.condition = condition;
25614    this.trueCase = trueCase;
25615    this.falseCase = falseCase;
25616  }
25617
25618  isEquivalent(stmt) {
25619    return stmt instanceof IfStmt && this.condition.isEquivalent(stmt.condition) && areAllEquivalent(this.trueCase, stmt.trueCase) && areAllEquivalent(this.falseCase, stmt.falseCase);
25620  }
25621
25622  visitStatement(visitor, context) {
25623    return visitor.visitIfStmt(this, context);
25624  }
25625
25626}
25627
25628class RecursiveAstVisitor$1 {
25629  visitType(ast, context) {
25630    return ast;
25631  }
25632
25633  visitExpression(ast, context) {
25634    if (ast.type) {
25635      ast.type.visitType(this, context);
25636    }
25637
25638    return ast;
25639  }
25640
25641  visitBuiltinType(type, context) {
25642    return this.visitType(type, context);
25643  }
25644
25645  visitExpressionType(type, context) {
25646    type.value.visitExpression(this, context);
25647
25648    if (type.typeParams !== null) {
25649      type.typeParams.forEach(param => this.visitType(param, context));
25650    }
25651
25652    return this.visitType(type, context);
25653  }
25654
25655  visitArrayType(type, context) {
25656    return this.visitType(type, context);
25657  }
25658
25659  visitMapType(type, context) {
25660    return this.visitType(type, context);
25661  }
25662
25663  visitWrappedNodeExpr(ast, context) {
25664    return ast;
25665  }
25666
25667  visitTypeofExpr(ast, context) {
25668    return this.visitExpression(ast, context);
25669  }
25670
25671  visitReadVarExpr(ast, context) {
25672    return this.visitExpression(ast, context);
25673  }
25674
25675  visitWriteVarExpr(ast, context) {
25676    ast.value.visitExpression(this, context);
25677    return this.visitExpression(ast, context);
25678  }
25679
25680  visitWriteKeyExpr(ast, context) {
25681    ast.receiver.visitExpression(this, context);
25682    ast.index.visitExpression(this, context);
25683    ast.value.visitExpression(this, context);
25684    return this.visitExpression(ast, context);
25685  }
25686
25687  visitWritePropExpr(ast, context) {
25688    ast.receiver.visitExpression(this, context);
25689    ast.value.visitExpression(this, context);
25690    return this.visitExpression(ast, context);
25691  }
25692
25693  visitInvokeFunctionExpr(ast, context) {
25694    ast.fn.visitExpression(this, context);
25695    this.visitAllExpressions(ast.args, context);
25696    return this.visitExpression(ast, context);
25697  }
25698
25699  visitTaggedTemplateExpr(ast, context) {
25700    ast.tag.visitExpression(this, context);
25701    this.visitAllExpressions(ast.template.expressions, context);
25702    return this.visitExpression(ast, context);
25703  }
25704
25705  visitInstantiateExpr(ast, context) {
25706    ast.classExpr.visitExpression(this, context);
25707    this.visitAllExpressions(ast.args, context);
25708    return this.visitExpression(ast, context);
25709  }
25710
25711  visitLiteralExpr(ast, context) {
25712    return this.visitExpression(ast, context);
25713  }
25714
25715  visitLocalizedString(ast, context) {
25716    return this.visitExpression(ast, context);
25717  }
25718
25719  visitExternalExpr(ast, context) {
25720    if (ast.typeParams) {
25721      ast.typeParams.forEach(type => type.visitType(this, context));
25722    }
25723
25724    return this.visitExpression(ast, context);
25725  }
25726
25727  visitConditionalExpr(ast, context) {
25728    ast.condition.visitExpression(this, context);
25729    ast.trueCase.visitExpression(this, context);
25730    ast.falseCase.visitExpression(this, context);
25731    return this.visitExpression(ast, context);
25732  }
25733
25734  visitNotExpr(ast, context) {
25735    ast.condition.visitExpression(this, context);
25736    return this.visitExpression(ast, context);
25737  }
25738
25739  visitFunctionExpr(ast, context) {
25740    this.visitAllStatements(ast.statements, context);
25741    return this.visitExpression(ast, context);
25742  }
25743
25744  visitUnaryOperatorExpr(ast, context) {
25745    ast.expr.visitExpression(this, context);
25746    return this.visitExpression(ast, context);
25747  }
25748
25749  visitBinaryOperatorExpr(ast, context) {
25750    ast.lhs.visitExpression(this, context);
25751    ast.rhs.visitExpression(this, context);
25752    return this.visitExpression(ast, context);
25753  }
25754
25755  visitReadPropExpr(ast, context) {
25756    ast.receiver.visitExpression(this, context);
25757    return this.visitExpression(ast, context);
25758  }
25759
25760  visitReadKeyExpr(ast, context) {
25761    ast.receiver.visitExpression(this, context);
25762    ast.index.visitExpression(this, context);
25763    return this.visitExpression(ast, context);
25764  }
25765
25766  visitLiteralArrayExpr(ast, context) {
25767    this.visitAllExpressions(ast.entries, context);
25768    return this.visitExpression(ast, context);
25769  }
25770
25771  visitLiteralMapExpr(ast, context) {
25772    ast.entries.forEach(entry => entry.value.visitExpression(this, context));
25773    return this.visitExpression(ast, context);
25774  }
25775
25776  visitCommaExpr(ast, context) {
25777    this.visitAllExpressions(ast.parts, context);
25778    return this.visitExpression(ast, context);
25779  }
25780
25781  visitAllExpressions(exprs, context) {
25782    exprs.forEach(expr => expr.visitExpression(this, context));
25783  }
25784
25785  visitDeclareVarStmt(stmt, context) {
25786    if (stmt.value) {
25787      stmt.value.visitExpression(this, context);
25788    }
25789
25790    if (stmt.type) {
25791      stmt.type.visitType(this, context);
25792    }
25793
25794    return stmt;
25795  }
25796
25797  visitDeclareFunctionStmt(stmt, context) {
25798    this.visitAllStatements(stmt.statements, context);
25799
25800    if (stmt.type) {
25801      stmt.type.visitType(this, context);
25802    }
25803
25804    return stmt;
25805  }
25806
25807  visitExpressionStmt(stmt, context) {
25808    stmt.expr.visitExpression(this, context);
25809    return stmt;
25810  }
25811
25812  visitReturnStmt(stmt, context) {
25813    stmt.value.visitExpression(this, context);
25814    return stmt;
25815  }
25816
25817  visitIfStmt(stmt, context) {
25818    stmt.condition.visitExpression(this, context);
25819    this.visitAllStatements(stmt.trueCase, context);
25820    this.visitAllStatements(stmt.falseCase, context);
25821    return stmt;
25822  }
25823
25824  visitAllStatements(stmts, context) {
25825    stmts.forEach(stmt => stmt.visitStatement(this, context));
25826  }
25827
25828}
25829
25830function leadingComment(text, multiline = false, trailingNewline = true) {
25831  return new LeadingComment(text, multiline, trailingNewline);
25832}
25833
25834function jsDocComment(tags = []) {
25835  return new JSDocComment(tags);
25836}
25837
25838function variable(name, type, sourceSpan) {
25839  return new ReadVarExpr(name, type, sourceSpan);
25840}
25841
25842function importExpr(id, typeParams = null, sourceSpan) {
25843  return new ExternalExpr(id, null, typeParams, sourceSpan);
25844}
25845
25846function importType(id, typeParams, typeModifiers) {
25847  return id != null ? expressionType(importExpr(id, typeParams, null), typeModifiers) : null;
25848}
25849
25850function expressionType(expr, typeModifiers, typeParams) {
25851  return new ExpressionType(expr, typeModifiers, typeParams);
25852}
25853
25854function typeofExpr(expr) {
25855  return new TypeofExpr(expr);
25856}
25857
25858function literalArr(values, type, sourceSpan) {
25859  return new LiteralArrayExpr(values, type, sourceSpan);
25860}
25861
25862function literalMap(values, type = null) {
25863  return new LiteralMapExpr(values.map(e => new LiteralMapEntry(e.key, e.value, e.quoted)), type, null);
25864}
25865
25866function unary(operator, expr, type, sourceSpan) {
25867  return new UnaryOperatorExpr(operator, expr, type, sourceSpan);
25868}
25869
25870function not(expr, sourceSpan) {
25871  return new NotExpr(expr, sourceSpan);
25872}
25873
25874function fn(params, body, type, sourceSpan, name) {
25875  return new FunctionExpr(params, body, type, sourceSpan, name);
25876}
25877
25878function ifStmt(condition, thenClause, elseClause, sourceSpan, leadingComments) {
25879  return new IfStmt(condition, thenClause, elseClause, sourceSpan, leadingComments);
25880}
25881
25882function taggedTemplate(tag, template, type, sourceSpan) {
25883  return new TaggedTemplateExpr(tag, template, type, sourceSpan);
25884}
25885
25886function literal(value, type, sourceSpan) {
25887  return new LiteralExpr(value, type, sourceSpan);
25888}
25889
25890function localizedString(metaBlock, messageParts, placeholderNames, expressions, sourceSpan) {
25891  return new LocalizedString(metaBlock, messageParts, placeholderNames, expressions, sourceSpan);
25892}
25893
25894function isNull(exp) {
25895  return exp instanceof LiteralExpr && exp.value === null;
25896}
25897/*
25898 * Serializes a `Tag` into a string.
25899 * Returns a string like " @foo {bar} baz" (note the leading whitespace before `@foo`).
25900 */
25901
25902
25903function tagToString(tag) {
25904  let out = '';
25905
25906  if (tag.tagName) {
25907    out += ` @${tag.tagName}`;
25908  }
25909
25910  if (tag.text) {
25911    if (tag.text.match(/\/\*|\*\//)) {
25912      throw new Error('JSDoc text cannot contain "/*" and "*/"');
25913    }
25914
25915    out += ' ' + tag.text.replace(/@/g, '\\@');
25916  }
25917
25918  return out;
25919}
25920
25921function serializeTags(tags) {
25922  if (tags.length === 0) return '';
25923
25924  if (tags.length === 1 && tags[0].tagName && !tags[0].text) {
25925    // The JSDOC comment is a single simple tag: e.g `/** @tagname */`.
25926    return `*${tagToString(tags[0])} `;
25927  }
25928
25929  let out = '*\n';
25930
25931  for (const tag of tags) {
25932    out += ' *'; // If the tagToString is multi-line, insert " * " prefixes on lines.
25933
25934    out += tagToString(tag).replace(/\n/g, '\n * ');
25935    out += '\n';
25936  }
25937
25938  out += ' ';
25939  return out;
25940}
25941
25942var output_ast = /*#__PURE__*/Object.freeze({
25943  __proto__: null,
25944
25945  get TypeModifier() {
25946    return TypeModifier;
25947  },
25948
25949  Type: Type,
25950
25951  get BuiltinTypeName() {
25952    return BuiltinTypeName;
25953  },
25954
25955  BuiltinType: BuiltinType,
25956  ExpressionType: ExpressionType,
25957  ArrayType: ArrayType,
25958  MapType: MapType,
25959  DYNAMIC_TYPE: DYNAMIC_TYPE,
25960  INFERRED_TYPE: INFERRED_TYPE,
25961  BOOL_TYPE: BOOL_TYPE,
25962  INT_TYPE: INT_TYPE,
25963  NUMBER_TYPE: NUMBER_TYPE,
25964  STRING_TYPE: STRING_TYPE,
25965  FUNCTION_TYPE: FUNCTION_TYPE,
25966  NONE_TYPE: NONE_TYPE,
25967
25968  get UnaryOperator() {
25969    return UnaryOperator;
25970  },
25971
25972  get BinaryOperator() {
25973    return BinaryOperator;
25974  },
25975
25976  nullSafeIsEquivalent: nullSafeIsEquivalent,
25977  areAllEquivalent: areAllEquivalent,
25978  Expression: Expression,
25979  ReadVarExpr: ReadVarExpr,
25980  TypeofExpr: TypeofExpr,
25981  WrappedNodeExpr: WrappedNodeExpr,
25982  WriteVarExpr: WriteVarExpr,
25983  WriteKeyExpr: WriteKeyExpr,
25984  WritePropExpr: WritePropExpr,
25985  InvokeFunctionExpr: InvokeFunctionExpr,
25986  TaggedTemplateExpr: TaggedTemplateExpr,
25987  InstantiateExpr: InstantiateExpr,
25988  LiteralExpr: LiteralExpr,
25989  TemplateLiteral: TemplateLiteral,
25990  TemplateLiteralElement: TemplateLiteralElement,
25991  LiteralPiece: LiteralPiece,
25992  PlaceholderPiece: PlaceholderPiece,
25993  LocalizedString: LocalizedString,
25994  ExternalExpr: ExternalExpr,
25995  ExternalReference: ExternalReference,
25996  ConditionalExpr: ConditionalExpr,
25997  NotExpr: NotExpr,
25998  FnParam: FnParam,
25999  FunctionExpr: FunctionExpr,
26000  UnaryOperatorExpr: UnaryOperatorExpr,
26001  BinaryOperatorExpr: BinaryOperatorExpr,
26002  ReadPropExpr: ReadPropExpr,
26003  ReadKeyExpr: ReadKeyExpr,
26004  LiteralArrayExpr: LiteralArrayExpr,
26005  LiteralMapEntry: LiteralMapEntry,
26006  LiteralMapExpr: LiteralMapExpr,
26007  CommaExpr: CommaExpr,
26008  NULL_EXPR: NULL_EXPR,
26009  TYPED_NULL_EXPR: TYPED_NULL_EXPR,
26010
26011  get StmtModifier() {
26012    return StmtModifier;
26013  },
26014
26015  LeadingComment: LeadingComment,
26016  JSDocComment: JSDocComment,
26017  Statement: Statement,
26018  DeclareVarStmt: DeclareVarStmt,
26019  DeclareFunctionStmt: DeclareFunctionStmt,
26020  ExpressionStatement: ExpressionStatement,
26021  ReturnStatement: ReturnStatement,
26022  IfStmt: IfStmt,
26023  RecursiveAstVisitor: RecursiveAstVisitor$1,
26024  leadingComment: leadingComment,
26025  jsDocComment: jsDocComment,
26026  variable: variable,
26027  importExpr: importExpr,
26028  importType: importType,
26029  expressionType: expressionType,
26030  typeofExpr: typeofExpr,
26031  literalArr: literalArr,
26032  literalMap: literalMap,
26033  unary: unary,
26034  not: not,
26035  fn: fn,
26036  ifStmt: ifStmt,
26037  taggedTemplate: taggedTemplate,
26038  literal: literal,
26039  localizedString: localizedString,
26040  isNull: isNull
26041});
26042/**
26043 * @license
26044 * Copyright Google LLC All Rights Reserved.
26045 *
26046 * Use of this source code is governed by an MIT-style license that can be
26047 * found in the LICENSE file at https://angular.io/license
26048 */
26049
26050const CONSTANT_PREFIX = '_c';
26051/**
26052 * `ConstantPool` tries to reuse literal factories when two or more literals are identical.
26053 * We determine whether literals are identical by creating a key out of their AST using the
26054 * `KeyVisitor`. This constant is used to replace dynamic expressions which can't be safely
26055 * converted into a key. E.g. given an expression `{foo: bar()}`, since we don't know what
26056 * the result of `bar` will be, we create a key that looks like `{foo: <unknown>}`. Note
26057 * that we use a variable, rather than something like `null` in order to avoid collisions.
26058 */
26059
26060const UNKNOWN_VALUE_KEY = variable('<unknown>');
26061/**
26062 * Context to use when producing a key.
26063 *
26064 * This ensures we see the constant not the reference variable when producing
26065 * a key.
26066 */
26067
26068const KEY_CONTEXT = {};
26069/**
26070 * Generally all primitive values are excluded from the `ConstantPool`, but there is an exclusion
26071 * for strings that reach a certain length threshold. This constant defines the length threshold for
26072 * strings.
26073 */
26074
26075const POOL_INCLUSION_LENGTH_THRESHOLD_FOR_STRINGS = 50;
26076/**
26077 * A node that is a place-holder that allows the node to be replaced when the actual
26078 * node is known.
26079 *
26080 * This allows the constant pool to change an expression from a direct reference to
26081 * a constant to a shared constant. It returns a fix-up node that is later allowed to
26082 * change the referenced expression.
26083 */
26084
26085class FixupExpression extends Expression {
26086  constructor(resolved) {
26087    super(resolved.type);
26088    this.resolved = resolved;
26089    this.original = resolved;
26090  }
26091
26092  visitExpression(visitor, context) {
26093    if (context === KEY_CONTEXT) {
26094      // When producing a key we want to traverse the constant not the
26095      // variable used to refer to it.
26096      return this.original.visitExpression(visitor, context);
26097    } else {
26098      return this.resolved.visitExpression(visitor, context);
26099    }
26100  }
26101
26102  isEquivalent(e) {
26103    return e instanceof FixupExpression && this.resolved.isEquivalent(e.resolved);
26104  }
26105
26106  isConstant() {
26107    return true;
26108  }
26109
26110  fixup(expression) {
26111    this.resolved = expression;
26112    this.shared = true;
26113  }
26114
26115}
26116/**
26117 * A constant pool allows a code emitter to share constant in an output context.
26118 *
26119 * The constant pool also supports sharing access to ivy definitions references.
26120 */
26121
26122
26123class ConstantPool {
26124  constructor(isClosureCompilerEnabled = false) {
26125    this.isClosureCompilerEnabled = isClosureCompilerEnabled;
26126    this.statements = [];
26127    this.literals = new Map();
26128    this.literalFactories = new Map();
26129    this.nextNameIndex = 0;
26130  }
26131
26132  getConstLiteral(literal, forceShared) {
26133    if (literal instanceof LiteralExpr && !isLongStringLiteral(literal) || literal instanceof FixupExpression) {
26134      // Do no put simple literals into the constant pool or try to produce a constant for a
26135      // reference to a constant.
26136      return literal;
26137    }
26138
26139    const key = this.keyOf(literal);
26140    let fixup = this.literals.get(key);
26141    let newValue = false;
26142
26143    if (!fixup) {
26144      fixup = new FixupExpression(literal);
26145      this.literals.set(key, fixup);
26146      newValue = true;
26147    }
26148
26149    if (!newValue && !fixup.shared || newValue && forceShared) {
26150      // Replace the expression with a variable
26151      const name = this.freshName();
26152      let definition;
26153      let usage;
26154
26155      if (this.isClosureCompilerEnabled && isLongStringLiteral(literal)) {
26156        // For string literals, Closure will **always** inline the string at
26157        // **all** usages, duplicating it each time. For large strings, this
26158        // unnecessarily bloats bundle size. To work around this restriction, we
26159        // wrap the string in a function, and call that function for each usage.
26160        // This tricks Closure into using inline logic for functions instead of
26161        // string literals. Function calls are only inlined if the body is small
26162        // enough to be worth it. By doing this, very large strings will be
26163        // shared across multiple usages, rather than duplicating the string at
26164        // each usage site.
26165        //
26166        // const myStr = function() { return "very very very long string"; };
26167        // const usage1 = myStr();
26168        // const usage2 = myStr();
26169        definition = variable(name).set(new FunctionExpr([], // Params.
26170        [// Statements.
26171        new ReturnStatement(literal)]));
26172        usage = variable(name).callFn([]);
26173      } else {
26174        // Just declare and use the variable directly, without a function call
26175        // indirection. This saves a few bytes and avoids an unnecessary call.
26176        definition = variable(name).set(literal);
26177        usage = variable(name);
26178      }
26179
26180      this.statements.push(definition.toDeclStmt(INFERRED_TYPE, StmtModifier.Final));
26181      fixup.fixup(usage);
26182    }
26183
26184    return fixup;
26185  }
26186
26187  getLiteralFactory(literal) {
26188    // Create a pure function that builds an array of a mix of constant and variable expressions
26189    if (literal instanceof LiteralArrayExpr) {
26190      const argumentsForKey = literal.entries.map(e => e.isConstant() ? e : UNKNOWN_VALUE_KEY);
26191      const key = this.keyOf(literalArr(argumentsForKey));
26192      return this._getLiteralFactory(key, literal.entries, entries => literalArr(entries));
26193    } else {
26194      const expressionForKey = literalMap(literal.entries.map(e => ({
26195        key: e.key,
26196        value: e.value.isConstant() ? e.value : UNKNOWN_VALUE_KEY,
26197        quoted: e.quoted
26198      })));
26199      const key = this.keyOf(expressionForKey);
26200      return this._getLiteralFactory(key, literal.entries.map(e => e.value), entries => literalMap(entries.map((value, index) => ({
26201        key: literal.entries[index].key,
26202        value,
26203        quoted: literal.entries[index].quoted
26204      }))));
26205    }
26206  }
26207
26208  _getLiteralFactory(key, values, resultMap) {
26209    let literalFactory = this.literalFactories.get(key);
26210    const literalFactoryArguments = values.filter(e => !e.isConstant());
26211
26212    if (!literalFactory) {
26213      const resultExpressions = values.map((e, index) => e.isConstant() ? this.getConstLiteral(e, true) : variable(`a${index}`));
26214      const parameters = resultExpressions.filter(isVariable).map(e => new FnParam(e.name, DYNAMIC_TYPE));
26215      const pureFunctionDeclaration = fn(parameters, [new ReturnStatement
26215(resultMap(resultExpressions))], INFERRED_TYPE);
26216      const name = this.freshName();
26217      this.statements.push(variable(name).set(pureFunctionDeclaration).toDeclStmt(INFERRED_TYPE, StmtModifier.Final));
26218      literalFactory = variable(name);
26219      this.literalFactories.set(key, literalFactory);
26220    }
26221
26222    return {
26223      literalFactory,
26224      literalFactoryArguments
26225    };
26226  }
26227  /**
26228   * Produce a unique name.
26229   *
26230   * The name might be unique among different prefixes if any of the prefixes end in
26231   * a digit so the prefix should be a constant string (not based on user input) and
26232   * must not end in a digit.
26233   */
26234
26235
26236  uniqueName(prefix) {
26237    return `${prefix}${this.nextNameIndex++}`;
26238  }
26239
26240  freshName() {
26241    return this.uniqueName(CONSTANT_PREFIX);
26242  }
26243
26244  keyOf(expression) {
26245    return expression.visitExpression(new KeyVisitor(), KEY_CONTEXT);
26246  }
26247
26248}
26249/**
26250 * Visitor used to determine if 2 expressions are equivalent and can be shared in the
26251 * `ConstantPool`.
26252 *
26253 * When the id (string) generated by the visitor is equal, expressions are considered equivalent.
26254 */
26255
26256
26257class KeyVisitor {
26258  constructor() {
26259    this.visitWrappedNodeExpr = invalid$1;
26260    this.visitWriteVarExpr = invalid$1;
26261    this.visitWriteKeyExpr = invalid$1;
26262    this.visitWritePropExpr = invalid$1;
26263    this.visitInvokeFunctionExpr = invalid$1;
26264    this.visitTaggedTemplateExpr = invalid$1;
26265    this.visitInstantiateExpr = invalid$1;
26266    this.visitConditionalExpr = invalid$1;
26267    this.visitNotExpr = invalid$1;
26268    this.visitAssertNotNullExpr = invalid$1;
26269    this.visitCastExpr = invalid$1;
26270    this.visitFunctionExpr = invalid$1;
26271    this.visitUnaryOperatorExpr = invalid$1;
26272    this.visitBinaryOperatorExpr = invalid$1;
26273    this.visitReadPropExpr = invalid$1;
26274    this.visitReadKeyExpr = invalid$1;
26275    this.visitCommaExpr = invalid$1;
26276    this.visitLocalizedString = invalid$1;
26277  }
26278
26279  visitLiteralExpr(ast) {
26280    return `${typeof ast.value === 'string' ? '"' + ast.value + '"' : ast.value}`;
26281  }
26282
26283  visitLiteralArrayExpr(ast, context) {
26284    return `[${ast.entries.map(entry => entry.visitExpression(this, context)).join(',')}]`;
26285  }
26286
26287  visitLiteralMapExpr(ast, context) {
26288    const mapKey = entry => {
26289      const quote = entry.quoted ? '"' : '';
26290      return `${quote}${entry.key}${quote}`;
26291    };
26292
26293    const mapEntry = entry => `${mapKey(entry)}:${entry.value.visitExpression(this, context)}`;
26294
26295    return `{${ast.entries.map(mapEntry).join(',')}`;
26296  }
26297
26298  visitExternalExpr(ast) {
26299    return ast.value.moduleName ? `EX:${ast.value.moduleName}:${ast.value.name}` : `EX:${ast.value.runtime.name}`;
26300  }
26301
26302  visitReadVarExpr(node) {
26303    return `VAR:${node.name}`;
26304  }
26305
26306  visitTypeofExpr(node, context) {
26307    return `TYPEOF:${node.expr.visitExpression(this, context)}`;
26308  }
26309
26310}
26311
26312function invalid$1(arg) {
26313  throw new Error(`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
26314}
26315
26316function isVariable(e) {
26317  return e instanceof ReadVarExpr;
26318}
26319
26320function isLongStringLiteral(expr) {
26321  return expr instanceof LiteralExpr && typeof expr.value === 'string' && expr.value.length >= POOL_INCLUSION_LENGTH_THRESHOLD_FOR_STRINGS;
26322}
26323/**
26324 * @license
26325 * Copyright Google LLC All Rights Reserved.
26326 *
26327 * Use of this source code is governed by an MIT-style license that can be
26328 * found in the LICENSE file at https://angular.io/license
26329 */
26330
26331
26332const CORE = '@angular/core';
26333
26334class Identifiers {}
26335/* Methods */
26336
26337
26338Identifiers.NEW_METHOD = 'factory';
26339Identifiers.TRANSFORM_METHOD = 'transform';
26340Identifiers.PATCH_DEPS = 'patchedDeps';
26341Identifiers.core = {
26342  name: null,
26343  moduleName: CORE
26344};
26345/* Instructions */
26346
26347Identifiers.namespaceHTML = {
26348  name: 'ɵɵnamespaceHTML',
26349  moduleName: CORE
26350};
26351Identifiers.namespaceMathML = {
26352  name: 'ɵɵnamespaceMathML',
26353  moduleName: CORE
26354};
26355Identifiers.namespaceSVG = {
26356  name: 'ɵɵnamespaceSVG',
26357  moduleName: CORE
26358};
26359Identifiers.element = {
26360  name: 'ɵɵelement',
26361  moduleName: CORE
26362};
26363Identifiers.elementStart = {
26364  name: 'ɵɵelementStart',
26365  moduleName: CORE
26366};
26367Identifiers.elementEnd = {
26368  name: 'ɵɵelementEnd',
26369  moduleName: CORE
26370};
26371Identifiers.advance = {
26372  name: 'ɵɵadvance',
26373  moduleName: CORE
26374};
26375Identifiers.syntheticHostProperty = {
26376  name: 'ɵɵsyntheticHostProperty',
26377  moduleName: CORE
26378};
26379Identifiers.syntheticHostListener = {
26380  name: 'ɵɵsyntheticHostListener',
26381  moduleName: CORE
26382};
26383Identifiers.attribute = {
26384  name: 'ɵɵattribute',
26385  moduleName: CORE
26386};
26387Identifiers.attributeInterpolate1 = {
26388  name: 'ɵɵattributeInterpolate1',
26389  moduleName: CORE
26390};
26391Identifiers.attributeInterpolate2 = {
26392  name: 'ɵɵattributeInterpolate2',
26393  moduleName: CORE
26394};
26395Identifiers.attributeInterpolate3 = {
26396  name: 'ɵɵattributeInterpolate3',
26397  moduleName: CORE
26398};
26399Identifiers.attributeInterpolate4 = {
26400  name: 'ɵɵattributeInterpolate4',
26401  moduleName: CORE
26402};
26403Identifiers.attributeInterpolate5 = {
26404  name: 'ɵɵattributeInterpolate5',
26405  moduleName: CORE
26406};
26407Identifiers.attributeInterpolate6 = {
26408  name: 'ɵɵattributeInterpolate6',
26409  moduleName: CORE
26410};
26411Identifiers.attributeInterpolate7 = {
26412  name: 'ɵɵattributeInterpolate7',
26413  moduleName: CORE
26414};
26415Identifiers.attributeInterpolate8 = {
26416  name: 'ɵɵattributeInterpolate8',
26417  moduleName: CORE
26418};
26419Identifiers.attributeInterpolateV = {
26420  name: 'ɵɵattributeInterpolateV',
26421  moduleName: CORE
26422};
26423Identifiers.classProp = {
26424  name: 'ɵɵclassProp',
26425  moduleName: CORE
26426};
26427Identifiers.elementContainerStart = {
26428  name: 'ɵɵelementContainerStart',
26429  moduleName: CORE
26430};
26431Identifiers.elementContainerEnd = {
26432  name: 'ɵɵelementContainerEnd',
26433  moduleName: CORE
26434};
26435Identifiers.elementContainer = {
26436  name: 'ɵɵelementContainer',
26437  moduleName: CORE
26438};
26439Identifiers.styleMap = {
26440  name: 'ɵɵstyleMap',
26441  moduleName: CORE
26442};
26443Identifiers.styleMapInterpolate1 = {
26444  name: 'ɵɵstyleMapInterpolate1',
26445  moduleName: CORE
26446};
26447Identifiers.styleMapInterpolate2 = {
26448  name: 'ɵɵstyleMapInterpolate2',
26449  moduleName: CORE
26450};
26451Identifiers.styleMapInterpolate3 = {
26452  name: 'ɵɵstyleMapInterpolate3',
26453  moduleName: CORE
26454};
26455Identifiers.styleMapInterpolate4 = {
26456  name: 'ɵɵstyleMapInterpolate4',
26457  moduleName: CORE
26458};
26459Identifiers.styleMapInterpolate5 = {
26460  name: 'ɵɵstyleMapInterpolate5',
26461  moduleName: CORE
26462};
26463Identifiers.styleMapInterpolate6 = {
26464  name: 'ɵɵstyleMapInterpolate6',
26465  moduleName: CORE
26466};
26467Identifiers.styleMapInterpolate7 = {
26468  name: 'ɵɵstyleMapInterpolate7',
26469  moduleName: CORE
26470};
26471Identifiers.styleMapInterpolate8 = {
26472  name: 'ɵɵstyleMapInterpolate8',
26473  moduleName: CORE
26474};
26475Identifiers.styleMapInterpolateV = {
26476  name: 'ɵɵstyleMapInterpolateV',
26477  moduleName: CORE
26478};
26479Identifiers.classMap = {
26480  name: 'ɵɵclassMap',
26481  moduleName: CORE
26482};
26483Identifiers.classMapInterpolate1 = {
26484  name: 'ɵɵclassMapInterpolate1',
26485  moduleName: CORE
26486};
26487Identifiers.classMapInterpolate2 = {
26488  name: 'ɵɵclassMapInterpolate2',
26489  moduleName: CORE
26490};
26491Identifiers.classMapInterpolate3 = {
26492  name: 'ɵɵclassMapInterpolate3',
26493  moduleName: CORE
26494};
26495Identifiers.classMapInterpolate4 = {
26496  name: 'ɵɵclassMapInterpolate4',
26497  moduleName: CORE
26498};
26499Identifiers.classMapInterpolate5 = {
26500  name: 'ɵɵclassMapInterpolate5',
26501  moduleName: CORE
26502};
26503Identifiers.classMapInterpolate6 = {
26504  name: 'ɵɵclassMapInterpolate6',
26505  moduleName: CORE
26506};
26507Identifiers.classMapInterpolate7 = {
26508  name: 'ɵɵclassMapInterpolate7',
26509  moduleName: CORE
26510};
26511Identifiers.classMapInterpolate8 = {
26512  name: 'ɵɵclassMapInterpolate8',
26513  moduleName: CORE
26514};
26515Identifiers.classMapInterpolateV = {
26516  name: 'ɵɵclassMapInterpolateV',
26517  moduleName: CORE
26518};
26519Identifiers.styleProp = {
26520  name: 'ɵɵstyleProp',
26521  moduleName: CORE
26522};
26523Identifiers.stylePropInterpolate1 = {
26524  name: 'ɵɵstylePropInterpolate1',
26525  moduleName: CORE
26526};
26527Identifiers.stylePropInterpolate2 = {
26528  name: 'ɵɵstylePropInterpolate2',
26529  moduleName: CORE
26530};
26531Identifiers.stylePropInterpolate3 = {
26532  name: 'ɵɵstylePropInterpolate3',
26533  moduleName: CORE
26534};
26535Identifiers.stylePropInterpolate4 = {
26536  name: 'ɵɵstylePropInterpolate4',
26537  moduleName: CORE
26538};
26539Identifiers.stylePropInterpolate5 = {
26540  name: 'ɵɵstylePropInterpolate5',
26541  moduleName: CORE
26542};
26543Identifiers.stylePropInterpolate6 = {
26544  name: 'ɵɵstylePropInterpolate6',
26545  moduleName: CORE
26546};
26547Identifiers.stylePropInterpolate7 = {
26548  name: 'ɵɵstylePropInterpolate7',
26549  moduleName: CORE
26550};
26551Identifiers.stylePropInterpolate8 = {
26552  name: 'ɵɵstylePropInterpolate8',
26553  moduleName: CORE
26554};
26555Identifiers.stylePropInterpolateV = {
26556  name: 'ɵɵstylePropInterpolateV',
26557  moduleName: CORE
26558};
26559Identifiers.nextContext = {
26560  name: 'ɵɵnextContext',
26561  moduleName: CORE
26562};
26563Identifiers.resetView = {
26564  name: 'ɵɵresetView',
26565  moduleName: CORE
26566};
26567Identifiers.templateCreate = {
26568  name: 'ɵɵtemplate',
26569  moduleName: CORE
26570};
26571Identifiers.text = {
26572  name: 'ɵɵtext',
26573  moduleName: CORE
26574};
26575Identifiers.enableBindings = {
26576  name: 'ɵɵenableBindings',
26577  moduleName: CORE
26578};
26579Identifiers.disableBindings = {
26580  name: 'ɵɵdisableBindings',
26581  moduleName: CORE
26582};
26583Identifiers.getCurrentView = {
26584  name: 'ɵɵgetCurrentView',
26585  moduleName: CORE
26586};
26587Identifiers.textInterpolate = {
26588  name: 'ɵɵtextInterpolate',
26589  moduleName: CORE
26590};
26591Identifiers.textInterpolate1 = {
26592  name: 'ɵɵtextInterpolate1',
26593  moduleName: CORE
26594};
26595Identifiers.textInterpolate2 = {
26596  name: 'ɵɵtextInterpolate2',
26597  moduleName: CORE
26598};
26599Identifiers.textInterpolate3 = {
26600  name: 'ɵɵtextInterpolate3',
26601  moduleName: CORE
26602};
26603Identifiers.textInterpolate4 = {
26604  name: 'ɵɵtextInterpolate4',
26605  moduleName: CORE
26606};
26607Identifiers.textInterpolate5 = {
26608  name: 'ɵɵtextInterpolate5',
26609  moduleName: CORE
26610};
26611Identifiers.textInterpolate6 = {
26612  name: 'ɵɵtextInterpolate6',
26613  moduleName: CORE
26614};
26615Identifiers.textInterpolate7 = {
26616  name: 'ɵɵtextInterpolate7',
26617  moduleName: CORE
26618};
26619Identifiers.textInterpolate8 = {
26620  name: 'ɵɵtextInterpolate8',
26621  moduleName: CORE
26622};
26623Identifiers.textInterpolateV = {
26624  name: 'ɵɵtextInterpolateV',
26625  moduleName: CORE
26626};
26627Identifiers.restoreView = {
26628  name: 'ɵɵrestoreView',
26629  moduleName: CORE
26630};
26631Identifiers.pureFunction0 = {
26632  name: 'ɵɵpureFunction0',
26633  moduleName: CORE
26634};
26635Identifiers.pureFunction1 = {
26636  name: 'ɵɵpureFunction1',
26637  moduleName: CORE
26638};
26639Identifiers.pureFunction2 = {
26640  name: 'ɵɵpureFunction2',
26641  moduleName: CORE
26642};
26643Identifiers.pureFunction3 = {
26644  name: 'ɵɵpureFunction3',
26645  moduleName: CORE
26646};
26647Identifiers.pureFunction4 = {
26648  name: 'ɵɵpureFunction4',
26649  moduleName: CORE
26650};
26651Identifiers.pureFunction5 = {
26652  name: 'ɵɵpureFunction5',
26653  moduleName: CORE
26654};
26655Identifiers.pureFunction6 = {
26656  name: 'ɵɵpureFunction6',
26657  moduleName: CORE
26658};
26659Identifiers.pureFunction7 = {
26660  name: 'ɵɵpureFunction7',
26661  moduleName: CORE
26662};
26663Identifiers.pureFunction8 = {
26664  name: 'ɵɵpureFunction8',
26665  moduleName: CORE
26666};
26667Identifiers.pureFunctionV = {
26668  name: 'ɵɵpureFunctionV',
26669  moduleName: CORE
26670};
26671Identifiers.pipeBind1 = {
26672  name: 'ɵɵpipeBind1',
26673  moduleName: CORE
26674};
26675Identifiers.pipeBind2 = {
26676  name: 'ɵɵpipeBind2',
26677  moduleName: CORE
26678};
26679Identifiers.pipeBind3 = {
26680  name: 'ɵɵpipeBind3',
26681  moduleName: CORE
26682};
26683Identifiers.pipeBind4 = {
26684  name: 'ɵɵpipeBind4',
26685  moduleName: CORE
26686};
26687Identifiers.pipeBindV = {
26688  name: 'ɵɵpipeBindV',
26689  moduleName: CORE
26690};
26691Identifiers.hostProperty = {
26692  name: 'ɵɵhostProperty',
26693  moduleName: CORE
26694};
26695Identifiers.property = {
26696  name: 'ɵɵproperty',
26697  moduleName: CORE
26698};
26699Identifiers.propertyInterpolate = {
26700  name: 'ɵɵpropertyInterpolate',
26701  moduleName: CORE
26702};
26703Identifiers.propertyInterpolate1 = {
26704  name: 'ɵɵpropertyInterpolate1',
26705  moduleName: CORE
26706};
26707Identifiers.propertyInterpolate2 = {
26708  name: 'ɵɵpropertyInterpolate2',
26709  moduleName: CORE
26710};
26711Identifiers.propertyInterpolate3 = {
26712  name: 'ɵɵpropertyInterpolate3',
26713  moduleName: CORE
26714};
26715Identifiers.propertyInterpolate4 = {
26716  name: 'ɵɵpropertyInterpolate4',
26717  moduleName: CORE
26718};
26719Identifiers.propertyInterpolate5 = {
26720  name: 'ɵɵpropertyInterpolate5',
26721  moduleName: CORE
26722};
26723Identifiers.propertyInterpolate6 = {
26724  name: 'ɵɵpropertyInterpolate6',
26725  moduleName: CORE
26726};
26727Identifiers.propertyInterpolate7 = {
26728  name: 'ɵɵpropertyInterpolate7',
26729  moduleName: CORE
26730};
26731Identifiers.propertyInterpolate8 = {
26732  name: 'ɵɵpropertyInterpolate8',
26733  moduleName: CORE
26734};
26735Identifiers.propertyInterpolateV = {
26736  name: 'ɵɵpropertyInterpolateV',
26737  moduleName: CORE
26738};
26739Identifiers.i18n = {
26740  name: 'ɵɵi18n',
26741  moduleName: CORE
26742};
26743Identifiers.i18nAttributes = {
26744  name: 'ɵɵi18nAttributes',
26745  moduleName: CORE
26746};
26747Identifiers.i18nExp = {
26748  name: 'ɵɵi18nExp',
26749  moduleName: CORE
26750};
26751Identifiers.i18nStart = {
26752  name: 'ɵɵi18nStart',
26753  moduleName: CORE
26754};
26755Identifiers.i18nEnd = {
26756  name: 'ɵɵi18nEnd',
26757  moduleName: CORE
26758};
26759Identifiers.i18nApply = {
26760  name: 'ɵɵi18nApply',
26761  moduleName: CORE
26762};
26763Identifiers.i18nPostprocess = {
26764  name: 'ɵɵi18nPostprocess',
26765  moduleName: CORE
26766};
26767Identifiers.pipe = {
26768  name: 'ɵɵpipe',
26769  moduleName: CORE
26770};
26771Identifiers.projection = {
26772  name: 'ɵɵprojection',
26773  moduleName: CORE
26774};
26775Identifiers.projectionDef = {
26776  name: 'ɵɵprojectionDef',
26777  moduleName: CORE
26778};
26779Identifiers.reference = {
26780  name: 'ɵɵreference',
26781  moduleName: CORE
26782};
26783Identifiers.inject = {
26784  name: 'ɵɵinject',
26785  moduleName: CORE
26786};
26787Identifiers.injectAttribute = {
26788  name: 'ɵɵinjectAttribute',
26789  moduleName: CORE
26790};
26791Identifiers.directiveInject = {
26792  name: 'ɵɵdirectiveInject',
26793  moduleName: CORE
26794};
26795Identifiers.invalidFactory = {
26796  name: 'ɵɵinvalidFactory',
26797  moduleName: CORE
26798};
26799Identifiers.invalidFactoryDep = {
26800  name: 'ɵɵinvalidFactoryDep',
26801  moduleName: CORE
26802};
26803Identifiers.templateRefExtractor = {
26804  name: 'ɵɵtemplateRefExtractor',
26805  moduleName: CORE
26806};
26807Identifiers.forwardRef = {
26808  name: 'forwardRef',
26809  moduleName: CORE
26810};
26811Identifiers.resolveForwardRef = {
26812  name: 'resolveForwardRef',
26813  moduleName: CORE
26814};
26815Identifiers.ɵɵdefineInjectable = {
26816  name: 'ɵɵdefineInjectable',
26817  moduleName: CORE
26818};
26819Identifiers.declareInjectable = {
26820  name: 'ɵɵngDeclareInjectable',
26821  moduleName: CORE
26822};
26823Identifiers.InjectableDeclaration = {
26824  name: 'ɵɵInjectableDeclaration',
26825  moduleName: CORE
26826};
26827Identifiers.resolveWindow = {
26828  name: 'ɵɵresolveWindow',
26829  moduleName: CORE
26830};
26831Identifiers.resolveDocument = {
26832  name: 'ɵɵresolveDocument',
26833  moduleName: CORE
26834};
26835Identifiers.resolveBody = {
26836  name: 'ɵɵresolveBody',
26837  moduleName: CORE
26838};
26839Identifiers.defineComponent = {
26840  name: 'ɵɵdefineComponent',
26841  moduleName: CORE
26842};
26843Identifiers.declareComponent = {
26844  name: 'ɵɵngDeclareComponent',
26845  moduleName: CORE
26846};
26847Identifiers.setComponentScope = {
26848  name: 'ɵɵsetComponentScope',
26849  moduleName: CORE
26850};
26851Identifiers.ChangeDetectionStrategy = {
26852  name: 'ChangeDetectionStrategy',
26853  moduleName: CORE
26854};
26855Identifiers.ViewEncapsulation = {
26856  name: 'ViewEncapsulation',
26857  moduleName: CORE
26858};
26859Identifiers.ComponentDeclaration = {
26860  name: 'ɵɵComponentDeclaration',
26861  moduleName: CORE
26862};
26863Identifiers.FactoryDeclaration = {
26864  name: 'ɵɵFactoryDeclaration',
26865  moduleName: CORE
26866};
26867Identifiers.declareFactory = {
26868  name: 'ɵɵngDeclareFactory',
26869  moduleName: CORE
26870};
26871Identifiers.FactoryTarget = {
26872  name: 'ɵɵFactoryTarget',
26873  moduleName: CORE
26874};
26875Identifiers.defineDirective = {
26876  name: 'ɵɵdefineDirective',
26877  moduleName: CORE
26878};
26879Identifiers.declareDirective = {
26880  name: 'ɵɵngDeclareDirective',
26881  moduleName: CORE
26882};
26883Identifiers.DirectiveDeclaration = {
26884  name: 'ɵɵDirectiveDeclaration',
26885  moduleName: CORE
26886};
26887Identifiers.InjectorDef = {
26888  name: 'ɵɵInjectorDef',
26889  moduleName: CORE
26890};
26891Identifiers.InjectorDeclaration = {
26892  name: 'ɵɵInjectorDeclaration',
26893  moduleName: CORE
26894};
26895Identifiers.defineInjector = {
26896  name: 'ɵɵdefineInjector',
26897  moduleName: CORE
26898};
26899Identifiers.declareInjector = {
26900  name: 'ɵɵngDeclareInjector',
26901  moduleName: CORE
26902};
26903Identifiers.NgModuleDeclaration = {
26904  name: 'ɵɵNgModuleDeclaration',
26905  moduleName: CORE
26906};
26907Identifiers.ModuleWithProviders = {
26908  name: 'ModuleWithProviders',
26909  moduleName: CORE
26910};
26911Identifiers.defineNgModule = {
26912  name: 'ɵɵdefineNgModule',
26913  moduleName: CORE
26914};
26915Identifiers.declareNgModule = {
26916  name: 'ɵɵngDeclareNgModule',
26917  moduleName: CORE
26918};
26919Identifiers.setNgModuleScope = {
26920  name: 'ɵɵsetNgModuleScope',
26921  moduleName: CORE
26922};
26923Identifiers.registerNgModuleType = {
26924  name: 'ɵɵregisterNgModuleType',
26925  moduleName: CORE
26926};
26927Identifiers.PipeDeclaration = {
26928  name: 'ɵɵPipeDeclaration',
26929  moduleName: CORE
26930};
26931Identifiers.definePipe = {
26932  name: 'ɵɵdefinePipe',
26933  moduleName: CORE
26934};
26935Identifiers.declarePipe = {
26936  name: 'ɵɵngDeclarePipe',
26937  moduleName: CORE
26938};
26939Identifiers.declareClassMetadata = {
26940  name: 'ɵɵngDeclareClassMetadata',
26941  moduleName: CORE
26942};
26943Identifiers.setClassMetadata = {
26944  name: 'ɵsetClassMetadata',
26945  moduleName: CORE
26946};
26947Identifiers.queryRefresh = {
26948  name: 'ɵɵqueryRefresh',
26949  moduleName: CORE
26950};
26951Identifiers.viewQuery = {
26952  name: 'ɵɵviewQuery',
26953  moduleName: CORE
26954};
26955Identifiers.loadQuery = {
26956  name: 'ɵɵloadQuery',
26957  moduleName: CORE
26958};
26959Identifiers.contentQuery = {
26960  name: 'ɵɵcontentQuery',
26961  moduleName: CORE
26962};
26963Identifiers.NgOnChangesFeature = {
26964  name: 'ɵɵNgOnChangesFeature',
26965  moduleName: CORE
26966};
26967Identifiers.InheritDefinitionFeature = {
26968  name: 'ɵɵInheritDefinitionFeature',
26969  moduleName: CORE
26970};
26971Identifiers.CopyDefinitionFeature = {
26972  name: 'ɵɵCopyDefinitionFeature',
26973  moduleName: CORE
26974};
26975Identifiers.StandaloneFeature = {
26976  name: 'ɵɵStandaloneFeature',
26977  moduleName: CORE
26978};
26979Identifiers.ProvidersFeature = {
26980  name: 'ɵɵProvidersFeature',
26981  moduleName: CORE
26982};
26983Identifiers.listener = {
26984  name: 'ɵɵlistener',
26985  moduleName: CORE
26986};
26987Identifiers.getInheritedFactory = {
26988  name: 'ɵɵgetInheritedFactory',
26989  moduleName: CORE
26990}; // sanitization-related functions
26991
26992Identifiers.sanitizeHtml = {
26993  name: 'ɵɵsanitizeHtml',
26994  moduleName: CORE
26995};
26996Identifiers.sanitizeStyle = {
26997  name: 'ɵɵsanitizeStyle',
26998  moduleName: CORE
26999};
27000Identifiers.sanitizeResourceUrl = {
27001  name: 'ɵɵsanitizeResourceUrl',
27002  moduleName: CORE
27003};
27004Identifiers.sanitizeScript = {
27005  name: 'ɵɵsanitizeScript',
27006  moduleName: CORE
27007};
27008Identifiers.sanitizeUrl = {
27009  name: 'ɵɵsanitizeUrl',
27010  moduleName: CORE
27011};
27012Identifiers.sanitizeUrlOrResourceUrl = {
27013  name: 'ɵɵsanitizeUrlOrResourceUrl',
27014  moduleName: CORE
27015};
27016Identifiers.trustConstantHtml = {
27017  name: 'ɵɵtrustConstantHtml',
27018  moduleName: CORE
27019};
27020Identifiers.trustConstantResourceUrl = {
27021  name: 'ɵɵtrustConstantResourceUrl',
27022  moduleName: CORE
27023};
27024/**
27025 * @license
27026 * Copyright Google LLC All Rights Reserved.
27027 *
27028 * Use of this source code is governed by an MIT-style license that can be
27029 * found in the LICENSE file at https://angular.io/license
27030 */
27031// https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
27032
27033const VERSION$1 = 3;
27034const JS_B64_PREFIX = '# sourceMappingURL=data:application/json;base64,';
27035
27036class SourceMapGenerator {
27037  constructor(file = null) {
27038    this.file = file;
27039    this.sourcesContent = new Map();
27040    this.lines = [];
27041    this.lastCol0 = 0;
27042    this.hasMappings = false;
27043  } // The content is `null` when the content is expected to be loaded using the URL
27044
27045
27046  addSource(url, content = null) {
27047    if (!this.sourcesContent.has(url)) {
27048      this.sourcesContent.set(url, content);
27049    }
27050
27051    return this;
27052  }
27053
27054  addLine() {
27055    this.lines.push([]);
27056    this.lastCol0 = 0;
27057    return this;
27058  }
27059
27060  addMapping(col0, sourceUrl, sourceLine0, sourceCol0) {
27061    if (!this.currentLine) {
27062      throw new Error(`A line must be added before mappings can be added`);
27063    }
27064
27065    if (sourceUrl != null && !this.sourcesContent.has(sourceUrl)) {
27066      throw new Error(`Unknown source file "${sourceUrl}"`);
27067    }
27068
27069    if (col0 == null) {
27070      throw new Error(`The column in the generated code must be provided`);
27071    }
27072
27073    if (col0 < this.lastCol0) {
27074      throw new Error(`Mapping should be added in output order`);
27075    }
27076
27077    if (sourceUrl && (sourceLine0 == null || sourceCol0 == null)) {
27078      throw new Error(`The source location must be provided when a source url is provided`);
27079    }
27080
27081    this.hasMappings = true;
27082    this.lastCol0 = col0;
27083    this.currentLine.push({
27084      col0,
27085      sourceUrl,
27086      sourceLine0,
27087      sourceCol0
27088    });
27089    return this;
27090  }
27091  /**
27092   * @internal strip this from published d.ts files due to
27093   * https://github.com/microsoft/TypeScript/issues/36216
27094   */
27095
27096
27097  get currentLine() {
27098    return this.lines.slice(-1)[0];
27099  }
27100
27101  toJSON() {
27102    if (!this.hasMappings) {
27103      return null;
27104    }
27105
27106    const sourcesIndex = new Map();
27107    const sources = [];
27108    const sourcesContent = [];
27109    Array.from(this.sourcesContent.keys()).forEach((url, i) => {
27110      sourcesIndex.set(url, i);
27111      sources.push(url);
27112      sourcesContent.push(this.sourcesContent.get(url) || null);
27113    });
27114    let mappings = '';
27115    let lastCol0 = 0;
27116    let lastSourceIndex = 0;
27117    let lastSourceLine0 = 0;
27118    let lastSourceCol0 = 0;
27119    this.lines.forEach(segments => {
27120      lastCol0 = 0;
27121      mappings += segments.map(segment => {
27122        // zero-based starting column of the line in the generated code
27123        let segAsStr = toBase64VLQ(segment.col0 - lastCol0);
27124        lastCol0 = segment.col0;
27125
27126        if (segment.sourceUrl != null) {
27127          // zero-based index into the “sources” list
27128          segAsStr += toBase64VLQ(sourcesIndex.get(segment.sourceUrl) - lastSourceIndex);
27129          lastSourceIndex = sourcesIndex.get(segment.sourceUrl); // the zero-based starting line in the original source
27130
27131          segAsStr += toBase64VLQ(segment.sourceLine0 - lastSourceLine0);
27132          lastSourceLine0 = segment.sourceLine0; // the zero-based starting column in the original source
27133
27134          segAsStr += toBase64VLQ(segment.sourceCol0 - lastSourceCol0);
27135          lastSourceCol0 = segment.sourceCol0;
27136        }
27137
27138        return segAsStr;
27139      }).join(',');
27140      mappings += ';';
27141    });
27142    mappings = mappings.slice(0, -1);
27143    return {
27144      'file': this.file || '',
27145      'version': VERSION$1,
27146      'sourceRoot': '',
27147      'sources': sources,
27148      'sourcesContent': sourcesContent,
27149      'mappings': mappings
27150    };
27151  }
27152
27153  toJsComment() {
27154    return this.hasMappings ? '//' + JS_B64_PREFIX + toBase64String(JSON.stringify(this, null, 0)) : '';
27155  }
27156
27157}
27158
27159function toBase64String(value) {
27160  let b64 = '';
27161  const encoded = utf8Encode(value);
27162
27163  for (let i = 0; i < encoded.length;) {
27164    const i1 = encoded[i++];
27165    const i2 = i < encoded.length ? encoded[i++] : null;
27166    const i3 = i < encoded.length ? encoded[i++] : null;
27167    b64 += toBase64Digit(i1 >> 2);
27168    b64 += toBase64Digit((i1 & 3) << 4 | (i2 === null ? 0 : i2 >> 4));
27169    b64 += i2 === null ? '=' : toBase64Digit((i2 & 15) << 2 | (i3 === null ? 0 : i3 >> 6));
27170    b64 += i2 === null || i3 === null ? '=' : toBase64Digit(i3 & 63);
27171  }
27172
27173  return b64;
27174}
27175
27176function toBase64VLQ(value) {
27177  value = value < 0 ? (-value << 1) + 1 : value << 1;
27178  let out = '';
27179
27180  do {
27181    let digit = value & 31;
27182    value = value >> 5;
27183
27184    if (value > 0) {
27185      digit = digit | 32;
27186    }
27187
27188    out += toBase64Digit(digit);
27189  } while (value > 0);
27190
27191  return out;
27192}
27193
27194const B64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
27194+/';
27195
27196function toBase64Digit(value) {
27197  if (value < 0 || value >= 64) {
27198    throw new Error(`Can only encode value in the range [0, 63]`);
27199  }
27200
27201  return B64_DIGITS[value];
27202}
27203/**
27204 * @license
27205 * Copyright Google LLC All Rights Reserved.
27206 *
27207 * Use of this source code is governed by an MIT-style license that can be
27208 * found in the LICENSE file at https://angular.io/license
27209 */
27210
27211
27212const _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g;
27213const _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i;
27214const _INDENT_WITH = '  ';
27215
27216class _EmittedLine {
27217  constructor(indent) {
27218    this.indent = indent;
27219    this.partsLength = 0;
27220    this.parts = [];
27221    this.srcSpans = [];
27222  }
27223
27224}
27225
27226class EmitterVisitorContext {
27227  constructor(_indent) {
27228    this._indent = _indent;
27229    this._lines = [new _EmittedLine(_indent)];
27230  }
27231
27232  static createRoot() {
27233    return new EmitterVisitorContext(0);
27234  }
27235  /**
27236   * @internal strip this from published d.ts files due to
27237   * https://github.com/microsoft/TypeScript/issues/36216
27238   */
27239
27240
27241  get _currentLine() {
27242    return this._lines[this._lines.length - 1];
27243  }
27244
27245  println(from, lastPart = '') {
27246    this.print(from || null, lastPart, true);
27247  }
27248
27249  lineIsEmpty() {
27250    return this._currentLine.parts.length === 0;
27251  }
27252
27253  lineLength() {
27254    return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength;
27255  }
27256
27257  print(from, part, newLine = false) {
27258    if (part.length > 0) {
27259      this._currentLine.parts.push(part);
27260
27261      this._currentLine.partsLength += part.length;
27262
27263      this._currentLine.srcSpans.push(from && from.sourceSpan || null);
27264    }
27265
27266    if (newLine) {
27267      this._lines.push(new _EmittedLine(this._indent));
27268    }
27269  }
27270
27271  removeEmptyLastLine() {
27272    if (this.lineIsEmpty()) {
27273      this._lines.pop();
27274    }
27275  }
27276
27277  incIndent() {
27278    this._indent++;
27279
27280    if (this.lineIsEmpty()) {
27281      this._currentLine.indent = this._indent;
27282    }
27283  }
27284
27285  decIndent() {
27286    this._indent--;
27287
27288    if (this.lineIsEmpty()) {
27289      this._currentLine.indent = this._indent;
27290    }
27291  }
27292
27293  toSource() {
27294    return this.sourceLines.map(l => l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : '').join('\n');
27295  }
27296
27297  toSourceMapGenerator(genFilePath, startsAtLine = 0) {
27298    const map = new SourceMapGenerator(genFilePath);
27299    let firstOffsetMapped = false;
27300
27301    const mapFirstOffsetIfNeeded = () => {
27302      if (!firstOffsetMapped) {
27303        // Add a single space so that tools won't try to load the file from disk.
27304        // Note: We are using virtual urls like `ng:///`, so we have to
27305        // provide a content here.
27306        map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0);
27307        firstOffsetMapped = true;
27308      }
27309    };
27310
27311    for (let i = 0; i < startsAtLine; i++) {
27312      map.addLine();
27313      mapFirstOffsetIfNeeded();
27314    }
27315
27316    this.sourceLines.forEach((line, lineIdx) => {
27317      map.addLine();
27318      const spans = line.srcSpans;
27319      const parts = line.parts;
27320      let col0 = line.indent * _INDENT_WITH.length;
27321      let spanIdx = 0; // skip leading parts without source spans
27322
27323      while (spanIdx < spans.length && !spans[spanIdx]) {
27324        col0 += parts[spanIdx].length;
27325        spanIdx++;
27326      }
27327
27328      if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) {
27329        firstOffsetMapped = true;
27330      } else {
27331        mapFirstOffsetIfNeeded();
27332      }
27333
27334      while (spanIdx < spans.length) {
27335        const span = spans[spanIdx];
27336        const source = span.start.file;
27337        const sourceLine = span.start.line;
27338        const sourceCol = span.start.col;
27339        map.addSource(source.url, source.content).addMapping(col0, source.url, sourceLine, sourceCol);
27340        col0 += parts[spanIdx].length;
27341        spanIdx++; // assign parts without span or the same span to the previous segment
27342
27343        while (spanIdx < spans.length && (span === spans[spanIdx] || !spans[spanIdx])) {
27344          col0 += parts[spanIdx].length;
27345          spanIdx++;
27346        }
27347      }
27348    });
27349    return map;
27350  }
27351
27352  spanOf(line, column) {
27353    const emittedLine = this._lines[line];
27354
27355    if (emittedLine) {
27356      let columnsLeft = column - _createIndent(emittedLine.indent).length;
27357
27358      for (let partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) {
27359        const part = emittedLine.parts[partIndex];
27360
27361        if (part.length > columnsLeft) {
27362          return emittedLine.srcSpans[partIndex];
27363        }
27364
27365        columnsLeft -= part.length;
27366      }
27367    }
27368
27369    return null;
27370  }
27371  /**
27372   * @internal strip this from published d.ts files due to
27373   * https://github.com/microsoft/TypeScript/issues/36216
27374   */
27375
27376
27377  get sourceLines() {
27378    if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) {
27379      return this._lines.slice(0, -1);
27380    }
27381
27382    return this._lines;
27383  }
27384
27385}
27386
27387class AbstractEmitterVisitor {
27388  constructor(_escapeDollarInStrings) {
27389    this._escapeDollarInStrings = _escapeDollarInStrings;
27390  }
27391
27392  printLeadingComments(stmt, ctx) {
27393    if (stmt.leadingComments === undefined) {
27394      return;
27395    }
27396
27397    for (const comment of stmt.leadingComments) {
27398      if (comment instanceof JSDocComment) {
27399        ctx.print(stmt, `/*${comment.toString()}*/`, comment.trailingNewline);
27400      } else {
27401        if (comment.multiline) {
27402          ctx.print(stmt, `/* ${comment.text} */`, comment.trailingNewline);
27403        } else {
27404          comment.text.split('\n').forEach(line => {
27405            ctx.println(stmt, `// ${line}`);
27406          });
27407        }
27408      }
27409    }
27410  }
27411
27412  visitExpressionStmt(stmt, ctx) {
27413    this.printLeadingComments(stmt, ctx);
27414    stmt.expr.visitExpression(this, ctx);
27415    ctx.println(stmt, ';');
27416    return null;
27417  }
27418
27419  visitReturnStmt(stmt, ctx) {
27420    this.printLeadingComments(stmt, ctx);
27421    ctx.print(stmt, `return `);
27422    stmt.value.visitExpression(this, ctx);
27423    ctx.println(stmt, ';');
27424    return null;
27425  }
27426
27427  visitIfStmt(stmt, ctx) {
27428    this.printLeadingComments(stmt, ctx);
27429    ctx.print(stmt, `if (`);
27430    stmt.condition.visitExpression(this, ctx);
27431    ctx.print(stmt, `) {`);
27432    const hasElseCase = stmt.falseCase != null && stmt.falseCase.length > 0;
27433
27434    if (stmt.trueCase.length <= 1 && !hasElseCase) {
27435      ctx.print(stmt, ` `);
27436      this.visitAllStatements(stmt.trueCase, ctx);
27437      ctx.removeEmptyLastLine();
27438      ctx.print(stmt, ` `);
27439    } else {
27440      ctx.println();
27441      ctx.incIndent();
27442      this.visitAllStatements(stmt.trueCase, ctx);
27443      ctx.decIndent();
27444
27445      if (hasElseCase) {
27446        ctx.println(stmt, `} else {`);
27447        ctx.incIndent();
27448        this.visitAllStatements(stmt.falseCase, ctx);
27449        ctx.decIndent();
27450      }
27451    }
27452
27453    ctx.println(stmt, `}`);
27454    return null;
27455  }
27456
27457  visitWriteVarExpr(expr, ctx) {
27458    const lineWasEmpty = ctx.lineIsEmpty();
27459
27460    if (!lineWasEmpty) {
27461      ctx.print(expr, '(');
27462    }
27463
27464    ctx.print(expr, `${expr.name} = `);
27465    expr.value.visitExpression(this, ctx);
27466
27467    if (!lineWasEmpty) {
27468      ctx.print(expr, ')');
27469    }
27470
27471    return null;
27472  }
27473
27474  visitWriteKeyExpr(expr, ctx) {
27475    const lineWasEmpty = ctx.lineIsEmpty();
27476
27477    if (!lineWasEmpty) {
27478      ctx.print(expr, '(');
27479    }
27480
27481    expr.receiver.visitExpression(this, ctx);
27482    ctx.print(expr, `[`);
27483    expr.index.visitExpression(this, ctx);
27484    ctx.print(expr, `] = `);
27485    expr.value.visitExpression(this, ctx);
27486
27487    if (!lineWasEmpty) {
27488      ctx.print(expr, ')');
27489    }
27490
27491    return null;
27492  }
27493
27494  visitWritePropExpr(expr, ctx) {
27495    const lineWasEmpty = ctx.lineIsEmpty();
27496
27497    if (!lineWasEmpty) {
27498      ctx.print(expr, '(');
27499    }
27500
27501    expr.receiver.visitExpression(this, ctx);
27502    ctx.print(expr, `.${expr.name} = `);
27503    expr.value.visitExpression(this, ctx);
27504
27505    if (!lineWasEmpty) {
27506      ctx.print(expr, ')');
27507    }
27508
27509    return null;
27510  }
27511
27512  visitInvokeFunctionExpr(expr, ctx) {
27513    expr.fn.visitExpression(this, ctx);
27514    ctx.print(expr, `(`);
27515    this.visitAllExpressions(expr.args, ctx, ',');
27516    ctx.print(expr, `)`);
27517    return null;
27518  }
27519
27520  visitTaggedTemplateExpr(expr, ctx) {
27521    expr.tag.visitExpression(this, ctx);
27522    ctx.print(expr, '`' + expr.template.elements[0].rawText);
27523
27524    for (let i = 1; i < expr.template.elements.length; i++) {
27525      ctx.print(expr, '${');
27526      expr.template.expressions[i - 1].visitExpression(this, ctx);
27527      ctx.print(expr, `}${expr.template.elements[i].rawText}`);
27528    }
27529
27530    ctx.print(expr, '`');
27531    return null;
27532  }
27533
27534  visitWrappedNodeExpr(ast, ctx) {
27535    throw new Error('Abstract emitter cannot visit WrappedNodeExpr.');
27536  }
27537
27538  visitTypeofExpr(expr, ctx) {
27539    ctx.print(expr, 'typeof ');
27540    expr.expr.visitExpression(this, ctx);
27541  }
27542
27543  visitReadVarExpr(ast, ctx) {
27544    ctx.print(ast, ast.name);
27545    return null;
27546  }
27547
27548  visitInstantiateExpr(ast, ctx) {
27549    ctx.print(ast, `new `);
27550    ast.classExpr.visitExpression(this, ctx);
27551    ctx.print(ast, `(`);
27552    this.visitAllExpressions(ast.args, ctx, ',');
27553    ctx.print(ast, `)`);
27554    return null;
27555  }
27556
27557  visitLiteralExpr(ast, ctx) {
27558    const value = ast.value;
27559
27560    if (typeof value === 'string') {
27561      ctx.print(ast, escapeIdentifier(value, this._escapeDollarInStrings));
27562    } else {
27563      ctx.print(ast, `${value}`);
27564    }
27565
27566    return null;
27567  }
27568
27569  visitLocalizedString(ast, ctx) {
27570    const head = ast.serializeI18nHead();
27571    ctx.print(ast, '$localize `' + head.raw);
27572
27573    for (let i = 1; i < ast.messageParts.length; i++) {
27574      ctx.print(ast, '${');
27575      ast.expressions[i - 1].visitExpression(this, ctx);
27576      ctx.print(ast, `}${ast.serializeI18nTemplatePart(i).raw}`);
27577    }
27578
27579    ctx.print(ast, '`');
27580    return null;
27581  }
27582
27583  visitConditionalExpr(ast, ctx) {
27584    ctx.print(ast, `(`);
27585    ast.condition.visitExpression(this, ctx);
27586    ctx.print(ast, '? ');
27587    ast.trueCase.visitExpression(this, ctx);
27588    ctx.print(ast, ': ');
27589    ast.falseCase.visitExpression(this, ctx);
27590    ctx.print(ast, `)`);
27591    return null;
27592  }
27593
27594  visitNotExpr(ast, ctx) {
27595    ctx.print(ast, '!');
27596    ast.condition.visitExpression(this, ctx);
27597    return null;
27598  }
27599
27600  visitUnaryOperatorExpr(ast, ctx) {
27601    let opStr;
27602
27603    switch (ast.operator) {
27604      case UnaryOperator.Plus:
27605        opStr = '+';
27606        break;
27607
27608      case UnaryOperator.Minus:
27609        opStr = '-';
27610        break;
27611
27612      default:
27613        throw new Error(`Unknown operator ${ast.operator}`);
27614    }
27615
27616    if (ast.parens) ctx.print(ast, `(`);
27617    ctx.print(ast, opStr);
27618    ast.expr.visitExpression(this, ctx);
27619    if (ast.parens) ctx.print(ast, `)`);
27620    return null;
27621  }
27622
27623  visitBinaryOperatorExpr(ast, ctx) {
27624    let opStr;
27625
27626    switch (ast.operator) {
27627      case BinaryOperator.Equals:
27628        opStr = '==';
27629        break;
27630
27631      case BinaryOperator.Identical:
27632        opStr = '===';
27633        break;
27634
27635      case BinaryOperator.NotEquals:
27636        opStr = '!=';
27637        break;
27638
27639      case BinaryOperator.NotIdentical:
27640        opStr = '!==';
27641        break;
27642
27643      case BinaryOperator.And:
27644        opStr = '&&';
27645        break;
27646
27647      case BinaryOperator.BitwiseAnd:
27648        opStr = '&';
27649        break;
27650
27651      case BinaryOperator.Or:
27652        opStr = '||';
27653        break;
27654
27655      case BinaryOperator.Plus:
27656        opStr = '+';
27657        break;
27658
27659      case BinaryOperator.Minus:
27660        opStr = '-';
27661        break;
27662
27663      case BinaryOperator.Divide:
27664        opStr = '/';
27665        break;
27666
27667      case BinaryOperator.Multiply:
27668        opStr = '*';
27669        break;
27670
27671      case BinaryOperator.Modulo:
27672        opStr = '%';
27673        break;
27674
27675      case BinaryOperator.Lower:
27676        opStr = '<';
27677        break;
27678
27679      case BinaryOperator.LowerEquals:
27680        opStr = '<=';
27681        break;
27682
27683      case BinaryOperator.Bigger:
27684        opStr = '>';
27685        break;
27686
27687      case BinaryOperator.BiggerEquals:
27688        opStr = '>=';
27689        break;
27690
27691      case BinaryOperator.NullishCoalesce:
27692        opStr = '??';
27693        break;
27694
27695      default:
27696        throw new Error(`Unknown operator ${ast.operator}`);
27697    }
27698
27699    if (ast.parens) ctx.print(ast, `(`);
27700    ast.lhs.visitExpression(this, ctx);
27701    ctx.print(ast, ` ${opStr} `);
27702    ast.rhs.visitExpression(this, ctx);
27703    if (ast.parens) ctx.print(ast, `)`);
27704    return null;
27705  }
27706
27707  visitReadPropExpr(ast, ctx) {
27708    ast.receiver.visitExpression(this, ctx);
27709    ctx.print(ast, `.`);
27710    ctx.print(ast, ast.name);
27711    return null;
27712  }
27713
27714  visitReadKeyExpr(ast, ctx) {
27715    ast.receiver.visitExpression(this, ctx);
27716    ctx.print(ast, `[`);
27717    ast.index.visitExpression(this, ctx);
27718    ctx.print(ast, `]`);
27719    return null;
27720  }
27721
27722  visitLiteralArrayExpr(ast, ctx) {
27723    ctx.print(ast, `[`);
27724    this.visitAllExpressions(ast.entries, ctx, ',');
27725    ctx.print(ast, `]`);
27726    return null;
27727  }
27728
27729  visitLiteralMapExpr(ast, ctx) {
27730    ctx.print(ast, `{`);
27731    this.visitAllObjects(entry => {
27732      ctx.print(ast, `${escapeIdentifier(entry.key, this._escapeDollarInStrings, entry.quoted)}:`);
27733      entry.value.visitExpression(this, ctx);
27734    }, ast.entries, ctx, ',');
27735    ctx.print(ast, `}`);
27736    return null;
27737  }
27738
27739  visitCommaExpr(ast, ctx) {
27740    ctx.print(ast, '(');
27741    this.visitAllExpressions(ast.parts, ctx, ',');
27742    ctx.print(ast, ')');
27743    return null;
27744  }
27745
27746  visitAllExpressions(expressions, ctx, separator) {
27747    this.visitAllObjects(expr => expr.visitExpression(this, ctx), expressions, ctx, separator);
27748  }
27749
27750  visitAllObjects(handler, expressions, ctx, separator) {
27751    let incrementedIndent = false;
27752
27753    for (let i = 0; i < expressions.length; i++) {
27754      if (i > 0) {
27755        if (ctx.lineLength() > 80) {
27756          ctx.print(null, separator, true);
27757
27758          if (!incrementedIndent) {
27759            // continuation are marked with double indent.
27760            ctx.incIndent();
27761            ctx.incIndent();
27762            incrementedIndent = true;
27763          }
27764        } else {
27765          ctx.print(null, separator, false);
27766        }
27767      }
27768
27769      handler(expressions[i]);
27770    }
27771
27772    if (incrementedIndent) {
27773      // continuation are marked with double indent.
27774      ctx.decIndent();
27775      ctx.decIndent();
27776    }
27777  }
27778
27779  visitAllStatements(statements, ctx) {
27780    statements.forEach(stmt => stmt.visitStatement(this, ctx));
27781  }
27782
27783}
27784
27785function escapeIdentifier(input, escapeDollar, alwaysQuote = true) {
27786  if (input == null) {
27787    return null;
27788  }
27789
27790  const body = input.replace(_SINGLE_QUOTE_ESCAPE_STRING_RE, (...match) => {
27791    if (match[0] == '$') {
27792      return escapeDollar ? '\\$' : '$';
27793    } else if (match[0] == '\n') {
27794      return '\\n';
27795    } else if (match[0] == '\r') {
27796      return '\\r';
27797    } else {
27798      return `\\${match[0]}`;
27799    }
27800  });
27801  const requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body);
27802  return requiresQuotes ? `'${body}'` : body;
27803}
27804
27805function _createIndent(count) {
27806  let res = '';
27807
27808  for (let i = 0; i < count; i++) {
27809    res += _INDENT_WITH;
27810  }
27811
27812  return res;
27813}
27814/**
27815 * @license
27816 * Copyright Google LLC All Rights Reserved.
27817 *
27818 * Use of this source code is governed by an MIT-style license that can be
27819 * found in the LICENSE file at https://angular.io/license
27820 */
27821
27822
27823function typeWithParameters(type, numParams) {
27824  if (numParams === 0) {
27825    return expressionType(type);
27826  }
27827
27828  const params = [];
27829
27830  for (let i = 0; i < numParams; i++) {
27831    params.push(DYNAMIC_TYPE);
27832  }
27833
27834  return expressionType(type, undefined, params);
27835}
27836
27837const ANIMATE_SYMBOL_PREFIX = '@';
27838
27839function prepareSyntheticPropertyName(name) {
27840  return `${ANIMATE_SYMBOL_PREFIX}${name}`;
27841}
27842
27843function prepareSyntheticListenerName(name, phase) {
27844  return `${ANIMATE_SYMBOL_PREFIX}${name}.${phase}`;
27845}
27846
27847function getSafePropertyAccessString(accessor, name) {
27848  const escapedName = escapeIdentifier(name, false, false);
27849  return escapedName !== name ? `${accessor}[${escapedName}]` : `${accessor}.${name}`;
27850}
27851
27852function prepareSyntheticListenerFunctionName(name, phase) {
27853  return `animation_${name}_${phase}`;
27854}
27855
27856function jitOnlyGuardedExpression(expr) {
27857  return guardedExpression('ngJitMode', expr);
27858}
27859
27860function devOnlyGuardedExpression(expr) {
27861  return guardedExpression('ngDevMode', expr);
27862}
27863
27864function guardedExpression(guard, expr) {
27865  const guardExpr = new ExternalExpr({
27866    name: guard,
27867    moduleName: null
27868  });
27869  const guardNotDefined = new BinaryOperatorExpr(BinaryOperator.Identical, new TypeofExpr(guardExpr), literal('undefined'));
27870  const guardUndefinedOrTrue = new BinaryOperatorExpr(BinaryOperator.Or, guardNotDefined, guardExpr,
27871  /* type */
27872  undefined,
27873  /* sourceSpan */
27874  undefined, true);
27875  return new BinaryOperatorExpr(BinaryOperator.And, guardUndefinedOrTrue, expr);
27876}
27877
27878function wrapReference(value) {
27879  const wrapped = new WrappedNodeExpr(value);
27880  return {
27881    value: wrapped,
27882    type: wrapped
27883  };
27884}
27885
27886function refsToArray(refs, shouldForwardDeclare) {
27887  const values = literalArr(refs.map(ref => ref.value));
27888  return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
27889}
27890
27891function createMayBeForwardRefExpression(expression, forwardRef) {
27892  return {
27893    expression,
27894    forwardRef
27895  };
27896}
27897/**
27898 * Convert a `MaybeForwardRefExpression` to an `Expression`, possibly wrapping its expression in a
27899 * `forwardRef()` call.
27900 *
27901 * If `MaybeForwardRefExpression.forwardRef` is `ForwardRefHandling.Unwrapped` then the expression
27902 * was originally wrapped in a `forwardRef()` call to prevent the value from being eagerly evaluated
27903 * in the code.
27904 *
27905 * See `packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts` and
27906 * `packages/compiler/src/jit_compiler_facade.ts` for more information.
27907 */
27908
27909
27910function convertFromMaybeForwardRefExpression({
27911  expression,
27912  forwardRef
27913}) {
27914  switch (forwardRef) {
27915    case 0
27916    /* ForwardRefHandling.None */
27917    :
27918    case 1
27919    /* ForwardRefHandling.Wrapped */
27920    :
27921      return expression;
27922
27923    case 2
27924    /* ForwardRefHandling.Unwrapped */
27925    :
27926      return generateForwardRef(expression);
27927  }
27928}
27929/**
27930 * Generate an expression that has the given `expr` wrapped in the following form:
27931 *
27932 * ```
27933 * forwardRef(() => expr)
27934 * ```
27935 */
27936
27937
27938function generateForwardRef(expr) {
27939  return importExpr(Identifiers.forwardRef).callFn([fn([], [new ReturnStatement
27939(expr)])]);
27940}
27941
27942var R3FactoryDelegateType;
27943
27944(function (R3FactoryDelegateType) {
27945  R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class";
27946  R3FactoryDelegateType[R3FactoryDelegateType["Function"] = 1] = "Function";
27947})(R3FactoryDelegateType || (R3FactoryDelegateType = {}));
27948
27949var FactoryTarget$1;
27950
27951(function (FactoryTarget) {
27952  FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
27953  FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
27954  FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
27955  FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
27956  FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
27957})(FactoryTarget$1 || (FactoryTarget$1 = {}));
27958/**
27959 * Construct a factory function expression for the given `R3FactoryMetadata`.
27960 */
27961
27962
27963function compileFactoryFunction(meta) {
27964  const t = variable('t');
27965  let baseFactoryVar = null; // The type to instantiate via constructor invocation. If there is no delegated factory, meaning
27966  // this type is always created by constructor invocation, then this is the type-to-create
27967  // parameter provided by the user (t) if specified, or the current type if not. If there is a
27968  // delegated factory (which is used to create the current type) then this is only the type-to-
27969  // create parameter (t).
27970
27971  const typeForCtor = !isDelegatedFactoryMetadata(meta) ? new BinaryOperatorExpr(BinaryOperator.Or, t, meta.internalType) : t;
27972  let ctorExpr = null;
27973
27974  if (meta.deps !== null) {
27975    // There is a constructor (either explicitly or implicitly defined).
27976    if (meta.deps !== 'invalid') {
27977      ctorExpr = new InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target));
27978    }
27979  } else {
27980    // There is no constructor, use the base class' factory to construct typeForCtor.
27981    baseFactoryVar = variable(`ɵ${meta.name}_BaseFactory`);
27982    ctorExpr = baseFactoryVar.callFn([typeForCtor]);
27983  }
27984
27985  const body = [];
27986  let retExpr = null;
27987
27988  function makeConditionalFactory(nonCtorExpr) {
27989    const r = variable('r');
27990    body.push(r.set(NULL_EXPR).toDeclStmt());
27991    const ctorStmt = ctorExpr !== null ? r.set(ctorExpr).toStmt() : importExpr(Identifiers.invalidFactory).callFn([]).toStmt();
27992    body.push(ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()]));
27993    return r;
27994  }
27995
27996  if (isDelegatedFactoryMetadata(meta)) {
27997    // This type is created with a delegated factory. If a type parameter is not specified, call
27998    // the factory instead.
27999    const delegateArgs = injectDependencies(meta.delegateDeps, meta.target); // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType.
28000
28001    const factoryExpr = new (meta.delegateType === R3FactoryDelegateType.Class ? InstantiateExpr : InvokeFunctionExpr)(meta.delegate, delegateArgs);
28002    retExpr = makeConditionalFactory(factoryExpr);
28003  } else if (isExpressionFactoryMetadata(meta)) {
28004    // TODO(alxhub): decide whether to lower the value here or in the caller
28005    retExpr = makeConditionalFactory(meta.expression);
28006  } else {
28007    retExpr = ctorExpr;
28008  }
28009
28010  if (retExpr === null) {
28011    // The expression cannot be formed so render an `ɵɵinvalidFactory()` call.
28012    body.push(importExpr(Identifiers.invalidFactory).callFn([]).toStmt());
28013  } else if (baseFactoryVar !== null) {
28014    // This factory uses a base factory, so call `ɵɵgetInheritedFactory()` to compute it.
28015    const getInheritedFactoryCall = importExpr(Identifiers.getInheritedFactory).callFn([meta.internalType]); // Memoize the base factoryFn: `baseFactory || (baseFactory = ɵɵgetInheritedFactory(...))`
28016
28017    const baseFactory = new BinaryOperatorExpr(BinaryOperator.Or, baseFactoryVar, baseFactoryVar.set(getInheritedFactoryCall));
28018    body.push(new ReturnStatement(baseFactory.callFn([typeForCtor])));
28019  } else {
28020    // This is straightforward factory, just return it.
28021    body.push(new ReturnStatement(retExpr));
28022  }
28023
28024  let factoryFn = fn([new FnParam('t', DYNAMIC_TYPE)], body, INFERRED_TYPE, undefined, `${meta.name}_Factory`);
28025
28026  if (baseFactoryVar !== null) {
28027    // There is a base factory variable so wrap its declaration along with the factory function into
28028    // an IIFE.
28029    factoryFn = fn([], [new DeclareVarStmt(baseFactoryVar.name), new ReturnStatement(factoryFn)]).callFn([],
28030    /* sourceSpan */
28031    undefined,
28032    /* pure */
28033    true);
28034  }
28035
28036  return {
28037    expression: factoryFn,
28038    statements: [],
28039    type: createFactoryType(meta)
28040  };
28041}
28042
28043function createFactoryType(meta) {
28044  const ctorDepsType = meta.deps !== null && meta.deps !== 'invalid' ? createCtorDepsType(meta.deps) : NONE_TYPE;
28045  return expressionType(importExpr(Identifiers.FactoryDeclaration, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType]));
28046}
28047
28048function injectDependencies(deps, target) {
28049  return deps.map((dep, index) => compileInjectDependency(dep, target, index));
28050}
28051
28052function compileInjectDependency(dep, target, index) {
28053  // Interpret the dependency according to its resolved type.
28054  if (dep.token === null) {
28055    return importExpr(Identifiers.invalidFactoryDep).callFn([literal(index)]);
28056  } else if (dep.attributeNameType === null) {
28057    // Build up the injection flags according to the metadata.
28058    const flags = 0
28059    /* InjectFlags.Default */
28060    | (dep.self ? 2
28061    /* InjectFlags.Self */
28062    : 0) | (dep.skipSelf ? 4
28063    /* InjectFlags.SkipSelf */
28064    : 0) | (dep.host ? 1
28065    /* InjectFlags.Host */
28066    : 0) | (dep.optional ? 8
28067    /* InjectFlags.Optional */
28068    : 0) | (target === FactoryTarget$1.Pipe ? 16
28069    /* InjectFlags.ForPipe */
28070    : 0); // If this dependency is optional or otherwise has non-default flags, then additional
28071    // parameters describing how to inject the dependency must be passed to the inject function
28072    // that's being used.
28073
28074    let flagsParam = flags !== 0
28075    /* InjectFlags.Default */
28076    || dep.optional ? literal(flags) : null; // Build up the arguments to the injectFn call.
28077
28078    const injectArgs = [dep.token];
28079
28080    if (flagsParam) {
28081      injectArgs.push(flagsParam);
28082    }
28083
28084    const injectFn = getInjectFn(target);
28085    return importExpr(injectFn).callFn(injectArgs);
28086  } else {
28087    // The `dep.attributeTypeName` value is defined, which indicates that this is an `@Attribute()`
28088    // type dependency. For the generated JS we still want to use the `dep.token` value in case the
28089    // name given for the attribute is not a string literal. For example given `@Attribute(foo())`,
28090    // we want to generate `ɵɵinjectAttribute(foo())`.
28091    //
28092    // The `dep.attributeTypeName` is only actually used (in `createCtorDepType()`) to generate
28093    // typings.
28094    return importExpr(Identifiers.injectAttribute).callFn([dep.token]);
28095  }
28096}
28097
28098function createCtorDepsType(deps) {
28099  let hasTypes = false;
28100  const attributeTypes = deps.map(dep => {
28101    const type = createCtorDepType(dep);
28102
28103    if (type !== null) {
28104      hasTypes = true;
28105      return type;
28106    } else {
28107      return literal(null);
28108    }
28109  });
28110
28111  if (hasTypes) {
28112    return expressionType(literalArr(attributeTypes));
28113  } else {
28114    return NONE_TYPE;
28115  }
28116}
28117
28118function createCtorDepType(dep) {
28119  const entries = [];
28120
28121  if (dep.attributeNameType !== null) {
28122    entries.push({
28123      key: 'attribute',
28124      value: dep.attributeNameType,
28125      quoted: false
28126    });
28127  }
28128
28129  if (dep.optional) {
28130    entries.push({
28131      key: 'optional',
28132      value: literal(true),
28133      quoted: false
28134    });
28135  }
28136
28137  if (dep.host) {
28138    entries.push({
28139      key: 'host',
28140      value: literal(true),
28141      quoted: false
28142    });
28143  }
28144
28145  if (dep.self) {
28146    entries.push({
28147      key: 'self',
28148      value: literal(true),
28149      quoted: false
28150    });
28151  }
28152
28153  if (dep.skipSelf) {
28154    entries.push({
28155      key: 'skipSelf',
28156      value: literal(true),
28157      quoted: false
28158    });
28159  }
28160
28161  return entries.length > 0 ? literalMap(entries) : null;
28162}
28163
28164function isDelegatedFactoryMetadata(meta) {
28165  return meta.delegateType !== undefined;
28166}
28167
28168function isExpressionFactoryMetadata(meta) {
28169  return meta.expression !== undefined;
28170}
28171
28172function getInjectFn(target) {
28173  switch (target) {
28174    case FactoryTarget$1.Component:
28175    case FactoryTarget$1.Directive:
28176    case FactoryTarget$1.Pipe:
28177      return Identifiers.directiveInject;
28178
28179    case FactoryTarget$1.NgModule:
28180    case FactoryTarget$1.Injectable:
28181    default:
28182      return Identifiers.inject;
28183  }
28184}
28185/**
28186 * @license
28187 * Copyright Google LLC All Rights Reserved.
28188 *
28189 * Use of this source code is governed by an MIT-style license that can be
28190 * found in the LICENSE file at https://angular.io/license
28191 */
28192
28193/**
28194 * This is an R3 `Node`-like wrapper for a raw `html.Comment` node. We do not currently
28195 * require the implementation of a visitor for Comments as they are only collected at
28196 * the top-level of the R3 AST, and only if `Render3ParseOptions['collectCommentNodes']`
28197 * is true.
28198 */
28199
28200
28201class Comment$1 {
28202  constructor(value, sourceSpan) {
28203    this.value = value;
28204    this.sourceSpan = sourceSpan;
28205  }
28206
28207  visit(_visitor) {
28208    throw new Error('visit() not implemented for Comment');
28209  }
28210
28211}
28212
28213class Text$3 {
28214  constructor(value, sourceSpan) {
28215    this.value = value;
28216    this.sourceSpan = sourceSpan;
28217  }
28218
28219  visit(visitor) {
28220    return visitor.visitText(this);
28221  }
28222
28223}
28224
28225class BoundText {
28226  constructor(value, sourceSpan, i18n) {
28227    this.value = value;
28228    this.sourceSpan = sourceSpan;
28229    this.i18n = i18n;
28230  }
28231
28232  visit(visitor) {
28233    return visitor.visitBoundText(this);
28234  }
28235
28236}
28237/**
28238 * Represents a text attribute in the template.
28239 *
28240 * `valueSpan` may not be present in cases where there is no value `<div a></div>`.
28241 * `keySpan` may also not be present for synthetic attributes from ICU expansions.
28242 */
28243
28244
28245class TextAttribute {
28246  constructor(name, value, sourceSpan, keySpan, valueSpan, i18n) {
28247    this.name = name;
28248    this.value = value;
28249    this.sourceSpan = sourceSpan;
28250    this.keySpan = keySpan;
28251    this.valueSpan = valueSpan;
28252    this.i18n = i18n;
28253  }
28254
28255  visit(visitor) {
28256    return visitor.visitTextAttribute(this);
28257  }
28258
28259}
28260
28261class BoundAttribute {
28262  constructor(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan, i18n) {
28263    this.name = name;
28264    this.type = type;
28265    this.securityContext = securityContext;
28266    this.value = value;
28267    this.unit = unit;
28268    this.sourceSpan = sourceSpan;
28269    this.keySpan = keySpan;
28270    this.valueSpan = valueSpan;
28271    this.i18n = i18n;
28272  }
28273
28274  static fromBoundElementProperty(prop, i18n) {
28275    if (prop.keySpan === undefined) {
28276      throw new Error(`Unexpected state: keySpan must be defined for bound attributes but was not for ${prop.name}: ${prop.sourceSpan}`);
28277    }
28278
28279    return new BoundAttribute(prop.name, prop.type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n);
28280  }
28281
28282  visit(visitor) {
28283    return visitor.visitBoundAttribute(this);
28284  }
28285
28286}
28287
28288class BoundEvent {
28289  constructor(name, type, handler, target, phase, sourceSpan, handlerSpan, keySpan) {
28290    this.name = name;
28291    this.type = type;
28292    this.handler = handler;
28293    this.target = target;
28294    this.phase = phase;
28295    this.sourceSpan = sourceSpan;
28296    this.handlerSpan = handlerSpan;
28297    this.keySpan = keySpan;
28298  }
28299
28300  static fromParsedEvent(event) {
28301    const target = event.type === 0
28302    /* ParsedEventType.Regular */
28303    ? event.targetOrPhase : null;
28304    const phase = event.type === 1
28305    /* ParsedEventType.Animation */
28306    ? event.targetOrPhase : null;
28307
28308    if (event.keySpan === undefined) {
28309      throw new Error(`Unexpected state: keySpan must be defined for bound event but was not for ${event.name}: ${event.sourceSpan}`);
28310    }
28311
28312    return new BoundEvent(event.name, event.type, event.handler, target, phase, event.sourceSpan, event.handlerSpan, event.keySpan);
28313  }
28314
28315  visit(visitor) {
28316    return visitor.visitBoundEvent(this);
28317  }
28318
28319}
28320
28321class Element$1 {
28322  constructor(name, attributes, inputs, outputs, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
28323    this.name = name;
28324    this.attributes = attributes;
28325    this.inputs = inputs;
28326    this.outputs = outputs;
28327    this.children = children;
28328    this.references = references;
28329    this.sourceSpan = sourceSpan;
28330    this.startSourceSpan = startSourceSpan;
28331    this.endSourceSpan = endSourceSpan;
28332    this.i18n = i18n;
28333  }
28334
28335  visit(visitor) {
28336    return visitor.visitElement(this);
28337  }
28338
28339}
28340
28341class Template {
28342  constructor( // tagName is the name of the container element, if applicable.
28343  // `null` is a special case for when there is a structural directive on an `ng-template` so
28344  // the renderer can differentiate between the synthetic template and the one written in the
28345  // file.
28346  tagName, attributes, inputs, outputs, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
28347    this.tagName = tagName;
28348    this.attributes = attributes;
28349    this.inputs = inputs;
28350    this.outputs = outputs;
28351    this.templateAttrs = templateAttrs;
28352    this.children = children;
28353    this.references = references;
28354    this.variables = variables;
28355    this.sourceSpan = sourceSpan;
28356    this.startSourceSpan = startSourceSpan;
28357    this.endSourceSpan = endSourceSpan;
28358    this.i18n = i18n;
28359  }
28360
28361  visit(visitor) {
28362    return visitor.visitTemplate(this);
28363  }
28364
28365}
28366
28367class Content {
28368  constructor(selector, attributes, sourceSpan, i18n) {
28369    this.selector = selector;
28370    this.attributes = attributes;
28371    this.sourceSpan = sourceSpan;
28372    this.i18n = i18n;
28373    this.name = 'ng-content';
28374  }
28375
28376  visit(visitor) {
28377    return visitor.visitContent(this);
28378  }
28379
28380}
28381
28382class Variable {
28383  constructor(name, value, sourceSpan, keySpan, valueSpan) {
28384    this.name = name;
28385    this.value = value;
28386    this.sourceSpan = sourceSpan;
28387    this.keySpan = keySpan;
28388    this.valueSpan = valueSpan;
28389  }
28390
28391  visit(visitor) {
28392    return visitor.visitVariable(this);
28393  }
28394
28395}
28396
28397class Reference {
28398  constructor(name, value, sourceSpan, keySpan, valueSpan) {
28399    this.name = name;
28400    this.value = value;
28401    this.sourceSpan = sourceSpan;
28402    this.keySpan = keySpan;
28403    this.valueSpan = valueSpan;
28404  }
28405
28406  visit(visitor) {
28407    return visitor.visitReference(this);
28408  }
28409
28410}
28411
28412class Icu$1 {
28413  constructor(vars, placeholders, sourceSpan, i18n) {
28414    this.vars = vars;
28415    this.placeholders = placeholders;
28416    this.sourceSpan = sourceSpan;
28417    this.i18n = i18n;
28418  }
28419
28420  visit(visitor) {
28421    return visitor.visitIcu(this);
28422  }
28423
28424}
28425
28426class NullVisitor {
28427  visitElement(element) {}
28428
28429  visitTemplate(template) {}
28430
28431  visitContent(content) {}
28432
28433  visitVariable(variable) {}
28434
28435  visitReference(reference) {}
28436
28437  visitTextAttribute(attribute) {}
28438
28439  visitBoundAttribute(attribute) {}
28440
28441  visitBoundEvent(attribute) {}
28442
28443  visitText(text) {}
28444
28445  visitBoundText(text) {}
28446
28447  visitIcu(icu) {}
28448
28449}
28450
28451class RecursiveVisitor$1 {
28452  visitElement(element) {
28453    visitAll$1(this, element.attributes);
28454    visitAll$1(this, element.inputs);
28455    visitAll$1(this, element.outputs);
28456    visitAll$1(this, element.children);
28457    visitAll$1(this, element.references);
28458  }
28459
28460  visitTemplate(template) {
28461    visitAll$1(this, template.attributes);
28462    visitAll$1(this, template.inputs);
28463    visitAll$1(this, template.outputs);
28464    visitAll$1(this, template.children);
28465    visitAll$1(this, template.references);
28466    visitAll$1(this, template.variables);
28467  }
28468
28469  visitContent(content) {}
28470
28471  visitVariable(variable) {}
28472
28473  visitReference(reference) {}
28474
28475  visitTextAttribute(attribute) {}
28476
28477  visitBoundAttribute(attribute) {}
28478
28479  visitBoundEvent(attribute) {}
28480
28481  visitText(text) {}
28482
28483  visitBoundText(text) {}
28484
28485  visitIcu(icu) {}
28486
28487}
28488
28489class TransformVisitor {
28490  visitElement(element) {
28491    const newAttributes = transformAll(this, element.attributes);
28492    const newInputs = transformAll(this, element.inputs);
28493    const newOutputs = transformAll(this, element.outputs);
28494    const newChildren = transformAll(this, element.children);
28495    const newReferences = transformAll(this, element.references);
28496
28497    if (newAttributes != element.attributes || newInputs != element.inputs || newOutputs != element.outputs || newChildren != element.children || newReferences != element.references) {
28498      return new Element$1(element.name, newAttributes, newInputs, newOutputs, newChildren, newReferences, element.sourceSpan, element.startSourceSpan, element.endSourceSpan);
28499    }
28500
28501    return element;
28502  }
28503
28504  visitTemplate(template) {
28505    const newAttributes = transformAll(this, template.attributes);
28506    const newInputs = transformAll(this, template.inputs);
28507    const newOutputs = transformAll(this, template.outputs);
28508    const newTemplateAttrs = transformAll(this, template.templateAttrs);
28509    const newChildren = transformAll(this, template.children);
28510    const newReferences = transformAll(this, template.references);
28511    const newVariables = transformAll(this, template.variables);
28512
28513    if (newAttributes != template.attributes || newInputs != template.inputs || newOutputs != template.outputs || newTemplateAttrs != template.templateAttrs || newChildren != template.children || newReferences != template.references || newVariables != template.variables) {
28514      return new Template(template.tagName, newAttributes, newInputs, newOutputs, newTemplateAttrs, newChildren, newReferences, newVariables, template.sourceSpan, template.startSourceSpan, template.endSourceSpan);
28515    }
28516
28517    return template;
28518  }
28519
28520  visitContent(content) {
28521    return content;
28522  }
28523
28524  visitVariable(variable) {
28525    return variable;
28526  }
28527
28528  visitReference(reference) {
28529    return reference;
28530  }
28531
28532  visitTextAttribute(attribute) {
28533    return attribute;
28534  }
28535
28536  visitBoundAttribute(attribute) {
28537    return attribute;
28538  }
28539
28540  visitBoundEvent(attribute) {
28541    return attribute;
28542  }
28543
28544  visitText(text) {
28545    return text;
28546  }
28547
28548  visitBoundText(text) {
28549    return text;
28550  }
28551
28552  visitIcu(icu) {
28553    return icu;
28554  }
28555
28556}
28557
28558function visitAll$1(visitor, nodes) {
28559  const result = [];
28560
28561  if (visitor.visit) {
28562    for (const node of nodes) {
28563      const newNode = visitor.visit(node) || node.visit(visitor);
28564    }
28565  } else {
28566    for (const node of nodes) {
28567      const newNode = node.visit(visitor);
28568
28569      if (newNode) {
28570        result.push(newNode);
28571      }
28572    }
28573  }
28574
28575  return result;
28576}
28577
28578function transformAll(visitor, nodes) {
28579  const result = [];
28580  let changed = false;
28581
28582  for (const node of nodes) {
28583    const newNode = node.visit(visitor);
28584
28585    if (newNode) {
28586      result.push(newNode);
28587    }
28588
28589    changed = changed || newNode != node;
28590  }
28591
28592  return changed ? result : nodes;
28593}
28594/**
28595 * @license
28596 * Copyright Google LLC All Rights Reserved.
28597 *
28598 * Use of this source code is governed by an MIT-style license that can be
28599 * found in the LICENSE file at https://angular.io/license
28600 */
28601
28602
28603class Message {
28604  /**
28605   * @param nodes message AST
28606   * @param placeholders maps placeholder names to static content and their source spans
28607   * @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages)
28608   * @param meaning
28609   * @param description
28610   * @param customId
28611   */
28612  constructor(nodes, placeholders, placeholderToMessage, meaning, description, customId) {
28613    this.nodes = nodes;
28614    this.placeholders = placeholders;
28615    this.placeholderToMessage = placeholderToMessage;
28616    this.meaning = meaning;
28617    this.description = description;
28618    this.customId = customId;
28619    this.id = this.customId;
28620    /** The ids to use if there are no custom id and if `i18nLegacyMessageIdFormat` is not empty */
28621
28622    this.legacyIds = [];
28623    this.messageString = serializeMessage(this.nodes);
28624
28625    if (nodes.length) {
28626      this.sources = [{
28627        filePath: nodes[0].sourceSpan.start.file.url,
28628        startLine: nodes[0].sourceSpan.start.line + 1,
28629        startCol: nodes[0].sourceSpan.start.col + 1,
28630        endLine: nodes[nodes.length - 1].sourceSpan.end.line + 1,
28631        endCol: nodes[0].sourceSpan.start.col + 1
28632      }];
28633    } else {
28634      this.sources = [];
28635    }
28636  }
28637
28638}
28639
28640class Text$2 {
28641  constructor(value, sourceSpan) {
28642    this.value = value;
28643    this.sourceSpan = sourceSpan;
28644  }
28645
28646  visit(visitor, context) {
28647    return visitor.visitText(this, context);
28648  }
28649
28650} // TODO(vicb): do we really need this node (vs an array) ?
28651
28652
28653class Container {
28654  constructor(children, sourceSpan) {
28655    this.children = children;
28656    this.sourceSpan = sourceSpan;
28657  }
28658
28659  visit(visitor, context) {
28660    return visitor.visitContainer(this, context);
28661  }
28662
28663}
28664
28665class Icu {
28666  constructor(expression, type, cases, sourceSpan) {
28667    this.expression = expression;
28668    this.type = type;
28669    this.cases = cases;
28670    this.sourceSpan = sourceSpan;
28671  }
28672
28673  visit(visitor, context) {
28674    return visitor.visitIcu(this, context);
28675  }
28676
28677}
28678
28679class TagPlaceholder {
28680  constructor(tag, attrs, startName, closeName, children, isVoid, // TODO sourceSpan should cover all (we need a startSourceSpan and endSourceSpan)
28681  sourceSpan, startSourceSpan, endSourceSpan) {
28682    this.tag = tag;
28683    this.attrs = attrs;
28684    this.startName = startName;
28685    this.closeName = closeName;
28686    this.children = children;
28687    this.isVoid = isVoid;
28688    this.sourceSpan = sourceSpan;
28689    this.startSourceSpan = startSourceSpan;
28690    this.endSourceSpan = endSourceSpan;
28691  }
28692
28693  visit(visitor, context) {
28694    return visitor.visitTagPlaceholder(this, context);
28695  }
28696
28697}
28698
28699class Placeholder {
28700  constructor(value, name, sourceSpan) {
28701    this.value = value;
28702    this.name = name;
28703    this.sourceSpan = sourceSpan;
28704  }
28705
28706  visit(visitor, context) {
28707    return visitor.visitPlaceholder(this, context);
28708  }
28709
28710}
28711
28712class IcuPlaceholder {
28713  constructor(value, name, sourceSpan) {
28714    this.value = value;
28715    this.name = name;
28716    this.sourceSpan = sourceSpan;
28717  }
28718
28719  visit(visitor, context) {
28720    return visitor.visitIcuPlaceholder(this, context);
28721  }
28722
28723} // Clone the AST
28724
28725
28726class CloneVisitor {
28727  visitText(text, context) {
28728    return new Text$2(text.value, text.sourceSpan);
28729  }
28730
28731  visitContainer(container, context) {
28732    const children = container.children.map(n => n.visit(this, context));
28733    return new Container(children, container.sourceSpan);
28734  }
28735
28736  visitIcu(icu, context) {
28737    const cases = {};
28738    Object.keys(icu.cases).forEach(key => cases[key] = icu.cases[key].visit(this, context));
28739    const msg = new Icu(icu.expression, icu.type, cases, icu.sourceSpan);
28740    msg.expressionPlaceholder = icu.expressionPlaceholder;
28741    return msg;
28742  }
28743
28744  visitTagPlaceholder(ph, context) {
28745    const children = ph.children.map(n => n.visit(this, context));
28746    return new TagPlaceholder(ph.tag, ph.attrs, ph.startName, ph.closeName, children, ph.isVoid, ph.sourceSpan, ph.startSourceSpan, ph.endSourceSpan);
28747  }
28748
28749  visitPlaceholder(ph, context) {
28750    return new Placeholder(ph.value, ph.name, ph.sourceSpan);
28751  }
28752
28753  visitIcuPlaceholder(ph, context) {
28754    return new IcuPlaceholder(ph.value, ph.name, ph.sourceSpan);
28755  }
28756
28757} // Visit all the nodes recursively
28758
28759
28760class RecurseVisitor {
28761  visitText(text, context) {}
28762
28763  visitContainer(container, context) {
28764    container.children.forEach(child => child.visit(this));
28765  }
28766
28767  visitIcu(icu, context) {
28768    Object.keys(icu.cases).forEach(k => {
28769      icu.cases[k].visit(this);
28770    });
28771  }
28772
28773  visitTagPlaceholder(ph, context) {
28774    ph.children.forEach(child => child.visit(this));
28775  }
28776
28777  visitPlaceholder(ph, context) {}
28778
28779  visitIcuPlaceholder(ph, context) {}
28780
28781}
28782/**
28783 * Serialize the message to the Localize backtick string format that would appear in compiled code.
28784 */
28785
28786
28787function serializeMessage(messageNodes) {
28788  const visitor = new LocalizeMessageStringVisitor();
28789  const str = messageNodes.map(n => n.visit(visitor)).join('');
28790  return str;
28791}
28792
28793class LocalizeMessageStringVisitor {
28794  visitText(text) {
28795    return text.value;
28796  }
28797
28798  visitContainer(container) {
28799    return container.children.map(child => child.visit(this)).join('');
28800  }
28801
28802  visitIcu(icu) {
28803    const strCases = Object.keys(icu.cases).map(k => `${k} {${icu.cases[k].visit(this)}}`);
28804    return `{${icu.expressionPlaceholder}, ${icu.type}, ${strCases.join(' ')}}`;
28805  }
28806
28807  visitTagPlaceholder(ph) {
28808    const children = ph.children.map(child => child.visit(this)).join('');
28809    return `{$${ph.startName}}${children}{$${ph.closeName}}`;
28810  }
28811
28812  visitPlaceholder(ph) {
28813    return `{$${ph.name}}`;
28814  }
28815
28816  visitIcuPlaceholder(ph) {
28817    return `{$${ph.name}}`;
28818  }
28819
28820}
28821/**
28822 * @license
28823 * Copyright Google LLC All Rights Reserved.
28824 *
28825 * Use of this source code is governed by an MIT-style license that can be
28826 * found in the LICENSE file at https://angular.io/license
28827 */
28828
28829
28830class Serializer {
28831  // Creates a name mapper, see `PlaceholderMapper`
28832  // Returning `null` means that no name mapping is used.
28833  createNameMapper(message) {
28834    return null;
28835  }
28836
28837}
28838/**
28839 * A simple mapper that take a function to transform an internal name to a public name
28840 */
28841
28842
28843class SimplePlaceholderMapper extends RecurseVisitor {
28844  // create a mapping from the message
28845  constructor(message, mapName) {
28846    super();
28847    this.mapName = mapName;
28848    this.internalToPublic = {};
28849    this.publicToNextId = {};
28850    this.publicToInternal = {};
28851    message.nodes.forEach(node => node.visit(this));
28852  }
28853
28854  toPublicName(internalName) {
28855    return this.internalToPublic.hasOwnProperty(internalName) ? this.internalToPublic[internalName] : null;
28856  }
28857
28858  toInternalName(publicName) {
28859    return this.publicToInternal.hasOwnProperty(publicName) ? this.publicToInternal[publicName] : null;
28860  }
28861
28862  visitText(text, context) {
28863    return null;
28864  }
28865
28866  visitTagPlaceholder(ph, context) {
28867    this.visitPlaceholderName(ph.startName);
28868    super.visitTagPlaceholder(ph, context);
28869    this.visitPlaceholderName(ph.closeName);
28870  }
28871
28872  visitPlaceholder(ph, context) {
28873    this.visitPlaceholderName(ph.name);
28874  }
28875
28876  visitIcuPlaceholder(ph, context) {
28877    this.visitPlaceholderName(ph.name);
28878  } // XMB placeholders could only contains A-Z, 0-9 and _
28879
28880
28881  visitPlaceholderName(internalName) {
28882    if (!internalName || this.internalToPublic.hasOwnProperty(internalName)) {
28883      return;
28884    }
28885
28886    let publicName = this.mapName(internalName);
28887
28888    if (this.publicToInternal.hasOwnProperty(publicName)) {
28889      // Create a new XMB when it has already been used
28890      const nextId = this.publicToNextId[publicName];
28891      this.publicToNextId[publicName] = nextId + 1;
28892      publicName = `${publicName}_${nextId}`;
28893    } else {
28894      this.publicToNextId[publicName] = 1;
28895    }
28896
28897    this.internalToPublic[internalName] = publicName;
28898    this.publicToInternal[publicName] = internalName;
28899  }
28900
28901}
28902/**
28903 * @license
28904 * Copyright Google LLC All Rights Reserved.
28905 *
28906 * Use of this source code is governed by an MIT-style license that can be
28907 * found in the LICENSE file at https://angular.io/license
28908 */
28909
28910
28911class _Visitor$2 {
28912  visitTag(tag) {
28913    const strAttrs = this._serializeAttributes(tag.attrs);
28914
28915    if (tag.children.length == 0) {
28916      return `<${tag.name}${strAttrs}/>`;
28917    }
28918
28919    const strChildren = tag.children.map(node =>
28919 node.visit(this));
28920    return `<${tag.name}${strAttrs}>${strChildren.join('')}</${tag.name}>`;
28921  }
28922
28923  visitText(text) {
28924    return text.value;
28925  }
28926
28927  visitDeclaration(decl) {
28928    return `<?xml${this._serializeAttributes(decl.attrs)} ?>`;
28929  }
28930
28931  _serializeAttributes(attrs) {
28932    const strAttrs = Object.keys(attrs).map(name => `${name}="${attrs[name]}"`).join(' ');
28933    return strAttrs.length > 0 ? ' ' + strAttrs : '';
28934  }
28935
28936  visitDoctype(doctype) {
28937    return `<!DOCTYPE ${doctype.rootTag} [\n${doctype.dtd}\n]>`;
28938  }
28939
28940}
28941
28942const _visitor = new _Visitor$2();
28943
28944function serialize(nodes) {
28945  return nodes.map(node => node.visit(_visitor)).join('');
28946}
28947
28948class Declaration {
28949  constructor(unescapedAttrs) {
28950    this.attrs = {};
28951    Object.keys(unescapedAttrs).forEach(k => {
28952      this.attrs[k] = escapeXml(unescapedAttrs[k]);
28953    });
28954  }
28955
28956  visit(visitor) {
28957    return visitor.visitDeclaration(this);
28958  }
28959
28960}
28961
28962class Doctype {
28963  constructor(rootTag, dtd) {
28964    this.rootTag = rootTag;
28965    this.dtd = dtd;
28966  }
28967
28968  visit(visitor) {
28969    return visitor.visitDoctype(this);
28970  }
28971
28972}
28973
28974class Tag {
28975  constructor(name, unescapedAttrs = {}, children = []) {
28976    this.name = name;
28977    this.children = children;
28978    this.attrs = {};
28979    Object.keys(unescapedAttrs).forEach(k => {
28980      this.attrs[k] = escapeXml(unescapedAttrs[k]);
28981    });
28982  }
28983
28984  visit(visitor) {
28985    return visitor.visitTag(this);
28986  }
28987
28988}
28989
28990class Text$1 {
28991  constructor(unescapedValue) {
28992    this.value = escapeXml(unescapedValue);
28993  }
28994
28995  visit(visitor) {
28996    return visitor.visitText(this);
28997  }
28998
28999}
29000
29001class CR extends Text$1 {
29002  constructor(ws = 0) {
29003    super(`\n${new Array(ws + 1).join(' ')}`);
29004  }
29005
29006}
29007
29008const _ESCAPED_CHARS = [[/&/g, '&amp;'], [/"/g, '&quot;'], [/'/g, '&apos;'], [/</g, '&lt;'], [/>/g, '&gt;']]; // Escape `_ESCAPED_CHARS` characters in the given text with encoded entities
29009
29010function escapeXml(text) {
29011  return _ESCAPED_CHARS.reduce((text, entry) => text.replace(entry[0], entry[1]), text);
29012}
29013/**
29014 * @license
29015 * Copyright Google LLC All Rights Reserved.
29016 *
29017 * Use of this source code is governed by an MIT-style license that can be
29018 * found in the LICENSE file at https://angular.io/license
29019 */
29020
29021
29022const _MESSAGES_TAG = 'messagebundle';
29023const _MESSAGE_TAG = 'msg';
29024const _PLACEHOLDER_TAG$3 = 'ph';
29025const _EXAMPLE_TAG = 'ex';
29026const _SOURCE_TAG$2 = 'source';
29027const _DOCTYPE = `<!ELEMENT messagebundle (msg)*>
29028<!ATTLIST messagebundle class CDATA #IMPLIED>
29029
29030<!ELEMENT msg (#PCDATA|ph|source)*>
29031<!ATTLIST msg id CDATA #IMPLIED>
29032<!ATTLIST msg seq CDATA #IMPLIED>
29033<!ATTLIST msg name CDATA #IMPLIED>
29034<!ATTLIST msg desc CDATA #IMPLIED>
29035<!ATTLIST msg meaning CDATA #IMPLIED>
29036<!ATTLIST msg obsolete (obsolete) #IMPLIED>
29037<!ATTLIST msg xml:space (default|preserve) "default">
29038<!ATTLIST msg is_hidden CDATA #IMPLIED>
29039
29040<!ELEMENT source (#PCDATA)>
29041
29042<!ELEMENT ph (#PCDATA|ex)*>
29043<!ATTLIST ph name CDATA #REQUIRED>
29044
29045<!ELEMENT ex (#PCDATA)>`;
29046
29047class Xmb extends Serializer {
29048  write(messages, locale) {
29049    const exampleVisitor = new ExampleVisitor();
29050    const visitor = new _Visitor$1();
29051    let rootNode = new Tag(_MESSAGES_TAG);
29052    messages.forEach(message => {
29053      const attrs = {
29054        id: message.id
29055      };
29056
29057      if (message.description) {
29058        attrs['desc'] = message.description;
29059      }
29060
29061      if (message.meaning) {
29062        attrs['meaning'] = message.meaning;
29063      }
29064
29065      let sourceTags = [];
29066      message.sources.forEach(source => {
29067        sourceTags.push(new Tag(_SOURCE_TAG$2, {}, [new Text$1(`${source.filePath}:${source.startLine}${source.endLine !== source.startLine ? ',' + source.endLine : ''}`)]));
29068      });
29069      rootNode.children.push(new CR(2), new Tag(_MESSAGE_TAG, attrs, [...sourceTags, ...visitor.serialize(message.nodes)]));
29070    });
29071    rootNode.children.push(new CR());
29072    return serialize([new Declaration({
29073      version: '1.0',
29074      encoding: 'UTF-8'
29075    }), new CR(), new Doctype(_MESSAGES_TAG, _DOCTYPE), new CR(), exampleVisitor.addDefaultExamples(rootNode), new CR()]);
29076  }
29077
29078  load(content, url) {
29079    throw new Error('Unsupported');
29080  }
29081
29082  digest(message) {
29083    return digest(message);
29084  }
29085
29086  createNameMapper(message) {
29087    return new SimplePlaceholderMapper(message, toPublicName);
29088  }
29089
29090}
29091
29092class _Visitor$1 {
29093  visitText(text, context) {
29094    return [new Text$1(text.value)];
29095  }
29096
29097  visitContainer(container, context) {
29098    const nodes = [];
29099    container.children.forEach(node => nodes.push(...node.visit(this)));
29100    return nodes;
29101  }
29102
29103  visitIcu(icu, context) {
29104    const nodes = [new Text$1(`{${icu.expressionPlaceholder}, ${icu.type}, `)];
29105    Object.keys(icu.cases).forEach(c => {
29106      nodes.push(new Text$1(`${c} {`), ...icu.cases[c].visit(this), new Text$1(`} `));
29107    });
29108    nodes.push(new Text$1(`}`));
29109    return nodes;
29110  }
29111
29112  visitTagPlaceholder(ph, context) {
29113    const startTagAsText = new Text$1(`<${ph.tag}>`);
29114    const startEx = new Tag(_EXAMPLE_TAG, {}, [startTagAsText]); // TC requires PH to have a non empty EX, and uses the text node to show the "original" value.
29115
29116    const startTagPh = new Tag(_PLACEHOLDER_TAG$3, {
29117      name: ph.startName
29118    }, [startEx, startTagAsText]);
29119
29120    if (ph.isVoid) {
29121      // void tags have no children nor closing tags
29122      return [startTagPh];
29123    }
29124
29125    const closeTagAsText = new Text$1(`</${ph.tag}>`);
29126    const closeEx = new Tag(_EXAMPLE_TAG, {}, [closeTagAsText]); // TC requires PH to have a non empty EX, and uses the text node to show the "original" value.
29127
29128    const closeTagPh = new Tag(_PLACEHOLDER_TAG$3, {
29129      name: ph.closeName
29130    }, [closeEx, closeTagAsText]);
29131    return [startTagPh, ...this.serialize(ph.children), closeTagPh];
29132  }
29133
29134  visitPlaceholder(ph, context) {
29135    const interpolationAsText = new Text$1(`{{${ph.value}}}`); // Example tag needs to be not-empty for TC.
29136
29137    const exTag = new Tag(_EXAMPLE_TAG, {}, [interpolationAsText]);
29138    return [// TC requires PH to have a non empty EX, and uses the text node to show the "original" value.
29139    new Tag(_PLACEHOLDER_TAG$3, {
29140      name: ph.name
29141    }, [exTag, interpolationAsText])];
29142  }
29143
29144  visitIcuPlaceholder(ph, context) {
29145    const icuExpression = ph.value.expression;
29146    const icuType = ph.value.type;
29147    const icuCases = Object.keys(ph.value.cases).map(value => value + ' {...}').join(' ');
29148    const icuAsText = new Text$1(`{${icuExpression}, ${icuType}, ${icuCases}}`);
29149    const exTag = new Tag(_EXAMPLE_TAG, {}, [icuAsText]);
29150    return [// TC requires PH to have a non empty EX, and uses the text node to show the "original" value.
29151    new Tag(_PLACEHOLDER_TAG$3, {
29152      name: ph.name
29153    }, [exTag, icuAsText])];
29154  }
29155
29156  serialize(nodes) {
29157    return [].concat(...nodes.map(node => node.visit(this)));
29158  }
29159
29160}
29161
29162function digest(message) {
29163  return decimalDigest(message);
29164} // TC requires at least one non-empty example on placeholders
29165
29166
29167class ExampleVisitor {
29168  addDefaultExamples(node) {
29169    node.visit(this);
29170    return node;
29171  }
29172
29173  visitTag(tag) {
29174    if (tag.name === _PLACEHOLDER_TAG$3) {
29175      if (!tag.children || tag.children.length == 0) {
29176        const exText = new Text$1(tag.attrs['name'] || '...');
29177        tag.children = [new Tag(_EXAMPLE_TAG, {}, [exText])];
29178      }
29179    } else if (tag.children) {
29180      tag.children.forEach(node => node.visit(this));
29181    }
29182  }
29183
29184  visitText(text) {}
29185
29186  visitDeclaration(decl) {}
29187
29188  visitDoctype(doctype) {}
29189
29190} // XMB/XTB placeholders can only contain A-Z, 0-9 and _
29191
29192
29193function toPublicName(internalName) {
29194  return internalName.toUpperCase().replace(/[^A-Z0-9_]/g, '_');
29195}
29196/**
29197 * @license
29198 * Copyright Google LLC All Rights Reserved.
29199 *
29200 * Use of this source code is governed by an MIT-style license that can be
29201 * found in the LICENSE file at https://angular.io/license
29202 */
29203
29204/* Closure variables holding messages must be named `MSG_[A-Z0-9]+` */
29205
29206
29207const CLOSURE_TRANSLATION_VAR_PREFIX = 'MSG_';
29208/**
29209 * Prefix for non-`goog.getMsg` i18n-related vars.
29210 * Note: the prefix uses lowercase characters intentionally due to a Closure behavior that
29211 * considers variables like `I18N_0` as constants and throws an error when their value changes.
29212 */
29213
29214const TRANSLATION_VAR_PREFIX = 'i18n_';
29215/** Name of the i18n attributes **/
29216
29217const I18N_ATTR = 'i18n';
29218const I18N_ATTR_PREFIX = 'i18n-';
29219/** Prefix of var expressions used in ICUs */
29220
29221const I18N_ICU_VAR_PREFIX = 'VAR_';
29222/** Prefix of ICU expressions for post processing */
29223
29224const I18N_ICU_MAPPING_PREFIX = 'I18N_EXP_';
29225/** Placeholder wrapper for i18n expressions **/
29226
29227const I18N_PLACEHOLDER_SYMBOL = '�';
29228
29229function isI18nAttribute(name) {
29230  return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX);
29231}
29232
29233function isI18nRootNode(meta) {
29234  return meta instanceof Message;
29235}
29236
29237function isSingleI18nIcu(meta) {
29238  return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu;
29239}
29240
29241function hasI18nMeta(node) {
29242  return !!node.i18n;
29243}
29244
29245function hasI18nAttrs(element) {
29246  return element.attrs.some(attr => isI18nAttribute(attr.name));
29247}
29248
29249function icuFromI18nMessage(message) {
29250  return message.nodes[0];
29251}
29252
29253function wrapI18nPlaceholder(content, contextId = 0) {
29254  const blockId = contextId > 0 ? `:${contextId}` : '';
29255  return `${I18N_PLACEHOLDER_SYMBOL}${content}${blockId}${I18N_PLACEHOLDER_SYMBOL}`;
29256}
29257
29258function assembleI18nBoundString(strings, bindingStartIndex = 0, contextId = 0) {
29259  if (!strings.length) return '';
29260  let acc = '';
29261  const lastIdx = strings.length - 1;
29262
29263  for (let i = 0; i < lastIdx; i++) {
29264    acc += `${strings[i]}${wrapI18nPlaceholder(bindingStartIndex + i, contextId)}`;
29265  }
29266
29267  acc += strings[lastIdx];
29268  return acc;
29269}
29270
29271function getSeqNumberGenerator(startsAt = 0) {
29272  let current = startsAt;
29273  return () => current++;
29274}
29275
29276function placeholdersToParams(placeholders) {
29277  const params = {};
29278  placeholders.forEach((values, key) => {
29279    params[key] = literal(values.length > 1 ? `[${values.join('|')}]` : values[0]);
29280  });
29281  return params;
29282}
29283
29284function updatePlaceholderMap(map, name, ...values) {
29285  const current = map.get(name) || [];
29286  current.push(...values);
29287  map.set(name, current);
29288}
29289
29290function assembleBoundTextPlaceholders(meta, bindingStartIndex = 0, contextId = 0) {
29291  const startIdx = bindingStartIndex;
29292  const placeholders = new Map();
29293  const node = meta instanceof Message ? meta.nodes.find(node => node instanceof Container) : meta;
29294
29295  if (node) {
29296    node.children.filter(child => child instanceof Placeholder).forEach((child, idx) => {
29297      const content = wrapI18nPlaceholder(startIdx + idx, contextId);
29298      updatePlaceholderMap(placeholders, child.name, content);
29299    });
29300  }
29301
29302  return placeholders;
29303}
29304/**
29305 * Format the placeholder names in a map of placeholders to expressions.
29306 *
29307 * The placeholder names are converted from "internal" format (e.g. `START_TAG_DIV_1`) to "external"
29308 * format (e.g. `startTagDiv_1`).
29309 *
29310 * @param params A map of placeholder names to expressions.
29311 * @param useCamelCase whether to camelCase the placeholder name when formatting.
29312 * @returns A new map of formatted placeholder names to expressions.
29313 */
29314
29315
29316function formatI18nPlaceholderNamesInMap(params = {}, useCamelCase) {
29317  const _params = {};
29318
29319  if (params && Object.keys(params).length) {
29320    Object.keys(params).forEach(key => _params[formatI18nPlaceholderName(key, useCamelCase)] = params[key]);
29321  }
29322
29323  return _params;
29324}
29325/**
29326 * Converts internal placeholder names to public-facing format
29327 * (for example to use in goog.getMsg call).
29328 * Example: `START_TAG_DIV_1` is converted to `startTagDiv_1`.
29329 *
29330 * @param name The placeholder name that should be formatted
29331 * @returns Formatted placeholder name
29332 */
29333
29334
29335function formatI18nPlaceholderName(name, useCamelCase = true) {
29336  const publicName = toPublicName(name);
29337
29338  if (!useCamelCase) {
29339    return publicName;
29340  }
29341
29342  const chunks = publicName.split('_');
29343
29344  if (chunks.length === 1) {
29345    // if no "_" found - just lowercase the value
29346    return name.toLowerCase();
29347  }
29348
29349  let postfix; // eject last element if it's a number
29350
29351  if (/^\d+$/.test(chunks[chunks.length - 1])) {
29352    postfix = chunks.pop();
29353  }
29354
29355  let raw = chunks.shift().toLowerCase();
29356
29357  if (chunks.length) {
29358    raw += chunks.map(c => c.charAt(0).toUpperCase() + c.slice(1).toLowerCase()).join('');
29359  }
29360
29361  return postfix ? `${raw}_${postfix}` : raw;
29362}
29363/**
29364 * Generates a prefix for translation const name.
29365 *
29366 * @param extra Additional local prefix that should be injected into translation var name
29367 * @returns Complete translation const prefix
29368 */
29369
29370
29371function getTranslationConstPrefix(extra) {
29372  return `${CLOSURE_TRANSLATION_VAR_PREFIX}${extra}`.toUpperCase();
29373}
29374/**
29375 * Generate AST to declare a variable. E.g. `var I18N_1;`.
29376 * @param variable the name of the variable to declare.
29377 */
29378
29379
29380function declareI18nVariable(variable) {
29381  return new DeclareVarStmt(variable.name, undefined, INFERRED_TYPE, undefined, variable.sourceSpan);
29382}
29383/**
29384 * @license
29385 * Copyright Google LLC All Rights Reserved.
29386 *
29387 * Use of this source code is governed by an MIT-style license that can be
29388 * found in the LICENSE file at https://angular.io/license
29389 */
29390
29391/**
29392 * Checks whether an object key contains potentially unsafe chars, thus the key should be wrapped in
29393 * quotes. Note: we do not wrap all keys into quotes, as it may have impact on minification and may
29394 * bot work in some cases when object keys are mangled by minifier.
29395 *
29396 * TODO(FW-1136): this is a temporary solution, we need to come up with a better way of working with
29397 * inputs that contain potentially unsafe chars.
29398 */
29399
29400
29401const UNSAFE_OBJECT_KEY_NAME_REGEXP = /[-.]/;
29402/** Name of the temporary to use during data binding */
29403
29404const TEMPORARY_NAME = '_t';
29405/** Name of the context parameter passed into a template function */
29406
29407const CONTEXT_NAME = 'ctx';
29408/** Name of the RenderFlag passed into a template function */
29409
29410const RENDER_FLAGS = 'rf';
29411/** The prefix reference variables */
29412
29413const REFERENCE_PREFIX = '_r';
29414/** The name of the implicit context reference */
29415
29416const IMPLICIT_REFERENCE = '$implicit';
29417/** Non bindable attribute name **/
29418
29419const NON_BINDABLE_ATTR = 'ngNonBindable';
29420/** Name for the variable keeping track of the context returned by `ɵɵrestoreView`. */
29421
29422const RESTORED_VIEW_CONTEXT_NAME = 'restoredCtx';
29423/**
29424 * Maximum length of a single instruction chain. Because our output AST uses recursion, we're
29425 * limited in how many expressions we can nest before we reach the call stack limit. This
29426 * length is set very conservatively in order to reduce the chance of problems.
29427 */
29428
29429const MAX_CHAIN_LENGTH = 500;
29430/** Instructions that support chaining. */
29431
29432const CHAINABLE_INSTRUCTIONS = new Set([Identifiers.element, Identifiers.elementStart, Identifiers.elementEnd, Identifiers.elementContainer, Identifiers.elementContainerStart, Identifiers.elementContainerEnd, Identifiers.i18nExp, Identifiers.listener, Identifiers.classProp, Identifiers.syntheticHostListener, Identifiers.hostProperty, Identifiers.syntheticHostProperty, Identifiers.property, Identifiers.propertyInterpolate1, Identifiers.propertyInterpolate2, Identifiers.propertyInterpolate3, Identifiers.propertyInterpolate4, Identifiers.propertyInterpolate5, Identifiers.propertyInterpolate6, Identifiers.propertyInterpolate7, Identifiers.propertyInterpolate8, Identifiers.propertyInterpolateV, Identifiers.attribute, Identifiers.attributeInterpolate1, Identifiers.attributeInterpolate2, Identifiers.attributeInterpolate3, Identifiers.attributeInterpolate4, Identifiers.attributeInterpolate5, Identifiers.attributeInterpolate6, Identifiers.attributeInterpolate7, Identifiers.attributeInterpolate8, Identifiers.attributeInterpolateV, Identifiers.styleProp, Identifiers.stylePropInterpolate1, Identifiers.stylePropInterpolate2, Identifiers.stylePropInterpolate3, Identifiers.stylePropInterpolate4, Identifiers.stylePropInterpolate5, Identifiers.stylePropInterpolate6, Identifiers.stylePropInterpolate7, Identifiers.stylePropInterpolate8, Identifiers.stylePropInterpolateV, Identifiers.textInterpolate, Identifiers.textInterpolate1, Identifiers.textInterpolate2, Identifiers.textInterpolate3, Identifiers.textInterpolate4, Identifiers.textInterpolate5, Identifiers.textInterpolate6, Identifiers.textInterpolate7, Identifiers.textInterpolate8, Identifiers.textInterpolateV]);
29433/** Generates a call to a single instruction. */
29434
29435function invokeInstruction(span, reference, params) {
29436  return importExpr(reference, null, span).callFn(params, span);
29437}
29438/**
29439 * Creates an allocator for a temporary variable.
29440 *
29441 * A variable declaration is added to the statements the first time the allocator is invoked.
29442 */
29443
29444
29445function temporaryAllocator(statements, name) {
29446  let temp = null;
29447  return () => {
29448    if (!temp) {
29449      statements.push(new DeclareVarStmt(TEMPORARY_NAME, undefined, DYNAMIC_TYPE));
29450      temp = variable(name);
29451    }
29452
29453    return temp;
29454  };
29455}
29456
29457function invalid(arg) {
29458  throw new Error(`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
29459}
29460
29461function asLiteral(value) {
29462  if (Array.isArray(value)) {
29463    return literalArr(value.map(asLiteral));
29464  }
29465
29466  return literal(value, INFERRED_TYPE);
29467}
29468
29469function conditionallyCreateMapObjectLiteral(keys, keepDeclared) {
29470  if (Object.getOwnPropertyNames(keys).length > 0) {
29471    return mapToExpression(keys, keepDeclared);
29472  }
29473
29474  return null;
29475}
29476
29477function mapToExpression(map, keepDeclared) {
29478  return literalMap(Object.getOwnPropertyNames(map).map(key => {
29479    // canonical syntax: `dirProp: publicProp`
29480    const value = map[key];
29481    let declaredName;
29482    let publicName;
29483    let minifiedName;
29484    let needsDeclaredName;
29485
29486    if (Array.isArray(value)) {
29487      [publicName, declaredName] = value;
29488      minifiedName = key;
29489      needsDeclaredName = publicName !== declaredName;
29490    } else {
29491      minifiedName = declaredName = key;
29492      publicName = value;
29493      needsDeclaredName = false;
29494    }
29495
29496    return {
29497      key: minifiedName,
29498      // put quotes around keys that contain potentially unsafe characters
29499      quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(minifiedName),
29500      value: keepDeclared && needsDeclaredName ? literalArr([asLiteral(publicName), asLiteral(declaredName)]) : asLiteral(publicName)
29501    };
29502  }));
29503}
29504/**
29505 *  Remove trailing null nodes as they are implied.
29506 */
29507
29508
29509function trimTrailingNulls(parameters) {
29510  while (isNull(parameters[parameters.length - 1])) {
29511    parameters.pop();
29512  }
29513
29514  return parameters;
29515}
29516
29517function getQueryPredicate(query, constantPool) {
29518  if (Array.isArray(query.predicate)) {
29519    let predicate = [];
29520    query.predicate.forEach(selector => {
29521      // Each item in predicates array may contain strings with comma-separated refs
29522      // (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them
29523      // as separate array entities
29524      const selectors = selector.split(',').map(token => literal(token.trim()));
29525      predicate.push(...selectors);
29526    });
29527    return constantPool.getConstLiteral(literalArr(predicate), true);
29528  } else {
29529    // The original predicate may have been wrapped in a `forwardRef()` call.
29530    switch (query.predicate.forwardRef) {
29531      case 0
29532      /* ForwardRefHandling.None */
29533      :
29534      case 2
29535      /* ForwardRefHandling.Unwrapped */
29536      :
29537        return query.predicate.expression;
29538
29539      case 1
29540      /* ForwardRefHandling.Wrapped */
29541      :
29542        return importExpr(Identifiers.resolveForwardRef).callFn([query.predicate.expression]);
29543    }
29544  }
29545}
29546/**
29547 * A representation for an object literal used during codegen of definition objects. The generic
29548 * type `T` allows to reference a documented type of the generated structure, such that the
29549 * property names that are set can be resolved to their documented declaration.
29550 */
29551
29552
29553class DefinitionMap {
29554  constructor() {
29555    this.values = [];
29556  }
29557
29558  set(key, value) {
29559    if (value) {
29560      this.values.push({
29561        key: key,
29562        value,
29563        quoted: false
29564      });
29565    }
29566  }
29567
29568  toLiteralMap() {
29569    return literalMap(this.values);
29570  }
29571
29572}
29573/**
29574 * Extract a map of properties to values for a given element or template node, which can be used
29575 * by the directive matching machinery.
29576 *
29577 * @param elOrTpl the element or template in question
29578 * @return an object set up for directive matching. For attributes on the element/template, this
29579 * object maps a property name to its (static) value. For any bindings, this map simply maps the
29580 * property name to an empty string.
29581 */
29582
29583
29584function getAttrsForDirectiveMatching(elOrTpl) {
29585  const attributesMap = {};
29586
29587  if (elOrTpl instanceof Template && elOrTpl.tagName !== 'ng-template') {
29588    elOrTpl.templateAttrs.forEach(a => attributesMap[a.name] = '');
29589  } else {
29590    elOrTpl.attributes.forEach(a => {
29591      if (!isI18nAttribute(a.name)) {
29592        attributesMap[a.name] = a.value;
29593      }
29594    });
29595    elOrTpl.inputs.forEach(i => {
29596      attributesMap[i.name] = '';
29597    });
29598    elOrTpl.outputs.forEach(o => {
29599      attributesMap[o.name] = '';
29600    });
29601  }
29602
29603  return attributesMap;
29604}
29605/**
29606 * Gets the number of arguments expected to be passed to a generated instruction in the case of
29607 * interpolation instructions.
29608 * @param interpolation An interpolation ast
29609 */
29610
29611
29612function getInterpolationArgsLength(interpolation) {
29613  const {
29614    expressions,
29615    strings
29616  } = interpolation;
29617
29618  if (expressions.length === 1 && strings.length === 2 && strings[0] === '' && strings[1] === '') {
29619    // If the interpolation has one interpolated value, but the prefix and suffix are both empty
29620    // strings, we only pass one argument, to a special instruction like `propertyInterpolate` or
29621    // `textInterpolate`.
29622    return 1;
29623  } else {
29624    return expressions.length + strings.length;
29625  }
29626}
29627/**
29628 * Generates the final instruction call statements based on the passed in configuration.
29629 * Will try to chain instructions as much as possible, if chaining is supported.
29630 */
29631
29632
29633function getInstructionStatements(instructions) {
29634  const statements = [];
29635  let pendingExpression = null;
29636  let pendingExpressionType = null;
29637  let chainLength = 0;
29638
29639  for (const current of instructions) {
29640    const resolvedParams = (typeof current.paramsOrFn === 'function' ? current.paramsOrFn() : current.paramsOrFn) ?? [];
29641    const params = Array.isArray(resolvedParams) ? resolvedParams : [resolvedParams]; // If the current instruction is the same as the previous one
29642    // and it can be chained, add another call to the chain.
29643
29644    if (chainLength < MAX_CHAIN_LENGTH && pendingExpressionType === current.reference && CHAINABLE_INSTRUCTIONS.has(pendingExpressionType)) {
29645      // We'll always have a pending expression when there's a pending expression type.
29646      pendingExpression = pendingExpression.callFn(params, pendingExpression.sourceSpan);
29647      chainLength++;
29648    } else {
29649      if (pendingExpression !== null) {
29650        statements.push(pendingExpression.toStmt());
29651      }
29652
29653      pendingExpression = invokeInstruction(current.span, current.reference, params);
29654      pendingExpressionType = current.reference;
29655      chainLength = 0;
29656    }
29657  } // Since the current instruction adds the previous one to the statements,
29658  // we may be left with the final one at the end that is still pending.
29659
29660
29661  if (pendingExpression !== null) {
29662    statements.push(pendingExpression.toStmt());
29663  }
29664
29665  return statements;
29666}
29667/**
29668 * @license
29669 * Copyright Google LLC All Rights Reserved.
29670 *
29671 * Use of this source code is governed by an MIT-style license that can be
29672 * found in the LICENSE file at https://angular.io/license
29673 */
29674
29675
29676function compileInjectable(meta, resolveForwardRefs) {
29677  let result = null;
29678  const factoryMeta = {
29679    name: meta.name,
29680    type: meta.type,
29681    internalType: meta.internalType,
29682    typeArgumentCount: meta.typeArgumentCount,
29683    deps: [],
29684    target: FactoryTarget$1.Injectable
29685  };
29686
29687  if (meta.useClass !== undefined) {
29688    // meta.useClass has two modes of operation. Either deps are specified, in which case `new` is
29689    // used to instantiate the class with dependencies injected, or deps are not specified and
29690    // the factory of the class is used to instantiate it.
29691    //
29692    // A special case exists for useClass: Type where Type is the injectable type itself and no
29693    // deps are specified, in which case 'useClass' is effectively ignored.
29694    const useClassOnSelf = meta.useClass.expression.isEquivalent(meta.internalType);
29695    let deps = undefined;
29696
29697    if (meta.deps !== undefined) {
29698      deps = meta.deps;
29699    }
29700
29701    if (deps !== undefined) {
29702      // factory: () => new meta.useClass(...deps)
29703      result = compileFactoryFunction({ ...factoryMeta,
29704        delegate: meta.useClass.expression,
29705        delegateDeps: deps,
29706        delegateType: R3FactoryDelegateType.Class
29707      });
29708    } else if (useClassOnSelf) {
29709      result = compileFactoryFunction(factoryMeta);
29710    } else {
29711      result = {
29712        statements: [],
29713        expression: delegateToFactory(meta.type.value, meta.useClass.expression, resolveForwardRefs)
29714      };
29715    }
29716  } else if (meta.useFactory !== undefined) {
29717    if (meta.deps !== undefined) {
29718      result = compileFactoryFunction({ ...factoryMeta,
29719        delegate: meta.useFactory,
29720        delegateDeps: meta.deps || [],
29721        delegateType: R3FactoryDelegateType.Function
29722      });
29723    } else {
29724      result = {
29725        statements: [],
29726        expression: fn([], [new ReturnStatement(meta.useFactory.callFn([]))])
29727      };
29728    }
29729  } else if (meta.useValue !== undefined) {
29730    // Note: it's safe to use `meta.useValue` instead of the `USE_VALUE in meta` check used for
29731    // client code because meta.useValue is an Expression which will be defined even if the actual
29732    // value is undefined.
29733    result = compileFactoryFunction({ ...factoryMeta,
29734      expression: meta.useValue.expression
29735    });
29736  } else if (meta.useExisting !== undefined) {
29737    // useExisting is an `inject` call on the existing token.
29738    result = compileFactoryFunction({ ...factoryMeta,
29739      expression: importExpr(Identifiers.inject).callFn([meta.useExisting.expression])
29740    });
29741  } else {
29742    result = {
29743      statements: [],
29744      expression: delegateToFactory(meta.type.value, meta.internalType, resolveForwardRefs)
29745    };
29746  }
29747
29748  const token = meta.internalType;
29749  const injectableProps = new DefinitionMap();
29750  injectableProps.set('token', token);
29751  injectableProps.set('factory', result.expression); // Only generate providedIn property if it has a non-null value
29752
29753  if (meta.providedIn.expression.value !== null) {
29754    injectableProps.set('providedIn', convertFromMaybeForwardRefExpression(meta.providedIn));
29755  }
29756
29757  const expression = importExpr(Identifiers.ɵɵdefineInjectable).callFn([injectableProps.toLiteralMap()], undefined, true);
29758  return {
29759    expression,
29760    type: createInjectableType(meta),
29761    statements: result.statements
29762  };
29763}
29764
29765function createInjectableType(meta) {
29766  return new ExpressionType(importExpr(Identifiers.InjectableDeclaration, [typeWithParameters(meta.type.type, meta.typeArgumentCount)]));
29767}
29768
29769function delegateToFactory(type, internalType, unwrapForwardRefs) {
29770  if (type.node === internalType.node) {
29771    // The types are the same, so we can simply delegate directly to the type's factory.
29772    // ```
29773    // factory: type.ɵfac
29774    // ```
29775    return internalType.prop('ɵfac');
29776  }
29777
29778  if (!unwrapForwardRefs) {
29779    // The type is not wrapped in a `forwardRef()`, so we create a simple factory function that
29780    // accepts a sub-type as an argument.
29781    // ```
29782    // factory: function(t) { return internalType.ɵfac(t); }
29783    // ```
29784    return createFactoryFunction(internalType);
29785  } // The internalType is actually wrapped in a `forwardRef()` so we need to resolve that before
29786  // calling its factory.
29787  // ```
29788  // factory: function(t) { return core.resolveForwardRef(type).ɵfac(t); }
29789  // ```
29790
29791
29792  const unwrappedType = importExpr(Identifiers.resolveForwardRef).callFn([internalType]);
29793  return createFactoryFunction(unwrappedType);
29794}
29795
29796function createFactoryFunction(type) {
29797  return fn([new FnParam('t', DYNAMIC_TYPE)], [new ReturnStatement
29797(type.prop('ɵfac').callFn([variable('t')]))]);
29798}
29799/**
29800 * @license
29801 * Copyright Google LLC All Rights Reserved.
29802 *
29803 * Use of this source code is governed by an MIT-style license that can be
29804 * found in the LICENSE file at https://angular.io/license
29805 */
29806
29807
29808const UNUSABLE_INTERPOLATION_REGEXPS = [/^\s*$/, /[<>]/, /^[{}]$/, /&(#|[a-z])/i, /^\/\// // comment
29809];
29810
29811function assertInterpolationSymbols(identifier, value) {
29812  if (value != null && !(Array.isArray(value) && value.length == 2)) {
29813    throw new Error(`Expected '${identifier}' to be an array, [start, end].`);
29814  } else if (value != null) {
29815    const start = value[0];
29816    const end = value[1]; // Check for unusable interpolation symbols
29817
29818    UNUSABLE_INTERPOLATION_REGEXPS.forEach(regexp => {
29819      if (regexp.test(start) || regexp.test(end)) {
29820        throw new Error(`['${start}', '${end}'] contains unusable interpolation symbol.`);
29821      }
29822    });
29823  }
29824}
29825/**
29826 * @license
29827 * Copyright Google LLC All Rights Reserved.
29828 *
29829 * Use of this source code is governed by an MIT-style license that can be
29830 * found in the LICENSE file at https://angular.io/license
29831 */
29832
29833
29834class InterpolationConfig {
29835  constructor(start, end) {
29836    this.start = start;
29837    this.end = end;
29838  }
29839
29840  static fromArray(markers) {
29841    if (!markers) {
29842      return DEFAULT_INTERPOLATION_CONFIG;
29843    }
29844
29845    assertInterpolationSymbols('interpolation', markers);
29846    return new InterpolationConfig(markers[0], markers[1]);
29847  }
29848
29849}
29850
29851const DEFAULT_INTERPOLATION_CONFIG = new InterpolationConfig('{{', '}}');
29852/**
29853 * @license
29854 * Copyright Google LLC All Rights Reserved.
29855 *
29856 * Use of this source code is governed by an MIT-style license that can be
29857 * found in the LICENSE file at https://angular.io/license
29858 */
29859
29860const $EOF = 0;
29861const $BSPACE = 8;
29862const $TAB = 9;
29863const $LF = 10;
29864const $VTAB = 11;
29865const $FF = 12;
29866const $CR = 13;
29867const $SPACE = 32;
29868const $BANG = 33;
29869const $DQ = 34;
29870const $HASH = 35;
29871const $$ = 36;
29872const $PERCENT = 37;
29873const $AMPERSAND = 38;
29874const $SQ = 39;
29875const $LPAREN = 40;
29876const $RPAREN = 41;
29877const $STAR = 42;
29878const $PLUS = 43;
29879const $COMMA = 44;
29880const $MINUS = 45;
29881const $PERIOD = 46;
29882const $SLASH = 47;
29883const $COLON = 58;
29884const $SEMICOLON = 59;
29885const $LT = 60;
29886const $EQ = 61;
29887const $GT = 62;
29888const $QUESTION = 63;
29889const $0 = 48;
29890const $7 = 55;
29891const $9 = 57;
29892const $A = 65;
29893const $E = 69;
29894const $F = 70;
29895const $X = 88;
29896const $Z = 90;
29897const $LBRACKET = 91;
29898const $BACKSLASH = 92;
29899const $RBRACKET = 93;
29900const $CARET = 94;
29901const $_ = 95;
29902const $a = 97;
29903const $b = 98;
29904const $e = 101;
29905const $f = 102;
29906const $n = 110;
29907const $r = 114;
29908const $t = 116;
29909const $u = 117;
29910const $v = 118;
29911const $x = 120;
29912const $z = 122;
29913const $LBRACE = 123;
29914const $BAR = 124;
29915const $RBRACE = 125;
29916const $NBSP = 160;
29917const $PIPE = 124;
29918const $TILDA = 126;
29919const $AT = 64;
29920const $BT = 96;
29921
29922function isWhitespace(code) {
29923  return code >= $TAB && code <= $SPACE || code == $NBSP;
29924}
29925
29926function isDigit(code) {
29927  return $0 <= code && code <= $9;
29928}
29929
29930function isAsciiLetter(code) {
29931  return code >= $a && code <= $z || code >= $A && code <= $Z;
29932}
29933
29934function isAsciiHexDigit(code) {
29935  return code >= $a && code <= $f || code >= $A && code <= $F || isDigit(code);
29936}
29937
29938function isNewLine(code) {
29939  return code === $LF || code === $CR;
29940}
29941
29942function isOctalDigit(code) {
29943  return $0 <= code && code <= $7;
29944}
29945
29946function isQuote(code) {
29947  return code === $SQ || code === $DQ || code === $BT;
29948}
29949/**
29950 * @license
29951 * Copyright Google LLC All Rights Reserved.
29952 *
29953 * Use of this source code is governed by an MIT-style license that can be
29954 * found in the LICENSE file at https://angular.io/license
29955 */
29956
29957
29958class ParseLocation {
29959  constructor(file, offset, line, col) {
29960    this.file = file;
29961    this.offset = offset;
29962    this.line = line;
29963    this.col = col;
29964  }
29965
29966  toString() {
29967    return this.offset != null ? `${this.file.url}@${this.line}:${this.col}` : this.file.url;
29968  }
29969
29970  moveBy(delta) {
29971    const source = this.file.content;
29972    const len = source.length;
29973    let offset = this.offset;
29974    let line = this.line;
29975    let col = this.col;
29976
29977    while (offset > 0 && delta < 0) {
29978      offset--;
29979      delta++;
29980      const ch = source.charCodeAt(offset);
29981
29982      if (ch == $LF) {
29983        line--;
29984        const priorLine = source.substring(0, offset - 1).lastIndexOf(String.fromCharCode($LF));
29985        col = priorLine > 0 ? offset - priorLine : offset;
29986      } else {
29987        col--;
29988      }
29989    }
29990
29991    while (offset < len && delta > 0) {
29992      const ch = source.charCodeAt(offset);
29993      offset++;
29994      delta--;
29995
29996      if (ch == $LF) {
29997        line++;
29998        col = 0;
29999      } else {
30000        col++;
30001      }
30002    }
30003
30004    return new ParseLocation(this.file, offset, line, col);
30005  } // Return the source around the location
30006  // Up to `maxChars` or `maxLines` on each side of the location
30007
30008
30009  getContext(maxChars, maxLines) {
30010    const content = this.file.content;
30011    let startOffset = this.offset;
30012
30013    if (startOffset != null) {
30014      if (startOffset > content.length - 1) {
30015        startOffset = content.length - 1;
30016      }
30017
30018      let endOffset = startOffset;
30019      let ctxChars = 0;
30020      let ctxLines = 0;
30021
30022      while (ctxChars < maxChars && startOffset > 0) {
30023        startOffset--;
30024        ctxChars++;
30025
30026        if (content[startOffset] == '\n') {
30027          if (++ctxLines == maxLines) {
30028            break;
30029          }
30030        }
30031      }
30032
30033      ctxChars = 0;
30034      ctxLines = 0;
30035
30036      while (ctxChars < maxChars && endOffset < content.length - 1) {
30037        endOffset++;
30038        ctxChars++;
30039
30040        if (content[endOffset] == '\n') {
30041          if (++ctxLines == maxLines) {
30042            break;
30043          }
30044        }
30045      }
30046
30047      return {
30048        before: content.substring(startOffset, this.offset),
30049        after: content.substring(this.offset, endOffset + 1)
30050      };
30051    }
30052
30053    return null;
30054  }
30055
30056}
30057
30058class ParseSourceFile {
30059  constructor(content, url) {
30060    this.content = content;
30061    this.url = url;
30062  }
30063
30064}
30065
30066class ParseSourceSpan {
30067  /**
30068   * Create an object that holds information about spans of tokens/nodes captured during
30069   * lexing/parsing of text.
30070   *
30071   * @param start
30072   * The location of the start of the span (having skipped leading trivia).
30073   * Skipping leading trivia makes source-spans more "user friendly", since things like HTML
30074   * elements will appear to begin at the start of the opening tag, rather than at the start of any
30075   * leading trivia, which could include newlines.
30076   *
30077   * @param end
30078   * The location of the end of the span.
30079   *
30080   * @param fullStart
30081   * The start of the token without skipping the leading trivia.
30082   * This is used by tooling that splits tokens further, such as extracting Angular interpolations
30083   * from text tokens. Such tooling creates new source-spans relative to the original token's
30084   * source-span. If leading trivia characters have been skipped then the new source-spans may be
30085   * incorrectly offset.
30086   *
30087   * @param details
30088   * Additional information (such as identifier names) that should be associated with the span.
30089   */
30090  constructor(start, end, fullStart = start, details = null) {
30091    this.start = start;
30092    this.end = end;
30093    this.fullStart = fullStart;
30094    this.details = details;
30095  }
30096
30097  toString() {
30098    return this.start.file.content.substring(this.start.offset, this.end.offset);
30099  }
30100
30101}
30102
30103var ParseErrorLevel;
30104
30105(function (ParseErrorLevel) {
30106  ParseErrorLevel[ParseErrorLevel["WARNING"] = 0] = "WARNING";
30107  ParseErrorLevel[ParseErrorLevel["ERROR"] = 1] = "ERROR";
30108})(ParseErrorLevel || (ParseErrorLevel = {}));
30109
30110class ParseError {
30111  constructor(span, msg, level = ParseErrorLevel.ERROR) {
30112    this.span = span;
30113    this.msg = msg;
30114    this.level = level;
30115  }
30116
30117  contextualMessage() {
30118    const ctx = this.span.start.getContext(100, 3);
30119    return ctx ? `${this.msg} ("${ctx.before}[${ParseErrorLevel[this.level]} ->]${ctx.after}")` : this.msg;
30120  }
30121
30122  toString() {
30123    const details = this.span.details ? `, ${this.span.details}` : '';
30124    return `${this.contextualMessage()}: ${this.span.start}${details}`;
30125  }
30126
30127}
30128/**
30129 * Generates Source Span object for a given R3 Type for JIT mode.
30130 *
30131 * @param kind Component or Directive.
30132 * @param typeName name of the Component or Directive.
30133 * @param sourceUrl reference to Component or Directive source.
30134 * @returns instance of ParseSourceSpan that represent a given Component or Directive.
30135 */
30136
30137
30138function r3JitTypeSourceSpan(kind, typeName, sourceUrl) {
30139  const sourceFileName = `in ${kind} ${typeName} in ${sourceUrl}`;
30140  const sourceFile = new ParseSourceFile('', sourceFileName);
30141  return new ParseSourceSpan(new ParseLocation(sourceFile, -1, -1, -1), new ParseLocation(sourceFile, -1, -1, -1));
30142}
30143
30144let _anonymousTypeIndex = 0;
30145
30146function identifierName(compileIdentifier) {
30147  if (!compileIdentifier || !compileIdentifier.reference) {
30148    return null;
30149  }
30150
30151  const ref = compileIdentifier.reference;
30152
30153  if (ref['__anonymousType']) {
30154    return ref['__anonymousType'];
30155  }
30156
30157  if (ref['__forward_ref__']) {
30158    // We do not want to try to stringify a `forwardRef()` function because that would cause the
30159    // inner function to be evaluated too early, defeating the whole point of the `forwardRef`.
30160    return '__forward_ref__';
30161  }
30162
30163  let identifier = stringify(ref);
30164
30165  if (identifier.indexOf('(') >= 0) {
30166    // case: anonymous functions!
30167    identifier = `anonymous_${_anonymousTypeIndex++}`;
30168    ref['__anonymousType'] = identifier;
30169  } else {
30170    identifier = sanitizeIdentifier(identifier);
30171  }
30172
30173  return identifier;
30174}
30175
30176function sanitizeIdentifier(name) {
30177  return name.replace(/\W/g, '_');
30178}
30179/**
30180 * @license
30181 * Copyright Google LLC All Rights Reserved.
30182 *
30183 * Use of this source code is governed by an MIT-style license that can be
30184 * found in the LICENSE file at https://angular.io/license
30185 */
30186
30187/**
30188 * In TypeScript, tagged template functions expect a "template object", which is an array of
30189 * "cooked" strings plus a `raw` property that contains an array of "raw" strings. This is
30190 * typically constructed with a function called `__makeTemplateObject(cooked, raw)`, but it may not
30191 * be available in all environments.
30192 *
30193 * This is a JavaScript polyfill that uses __makeTemplateObject when it's available, but otherwise
30194 * creates an inline helper with the same functionality.
30195 *
30196 * In the inline function, if `Object.defineProperty` is available we use that to attach the `raw`
30197 * array.
30198 */
30199
30200
30201const makeTemplateObjectPolyfill = '(this&&this.__makeTemplateObject||function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e})';
30202
30203class AbstractJsEmitterVisitor extends AbstractEmitterVisitor {
30204  constructor() {
30205    super(false);
30206  }
30207
30208  visitWrappedNodeExpr(ast, ctx) {
30209    throw new Error('Cannot emit a WrappedNodeExpr in Javascript.');
30210  }
30211
30212  visitDeclareVarStmt(stmt, ctx) {
30213    ctx.print(stmt, `var ${stmt.name}`);
30214
30215    if (stmt.value) {
30216      ctx.print(stmt, ' = ');
30217      stmt.value.visitExpression(this, ctx);
30218    }
30219
30220    ctx.println(stmt, `;`);
30221    return null;
30222  }
30223
30224  visitTaggedTemplateExpr(ast, ctx) {
30225    // The following convoluted piece of code is effectively the downlevelled equivalent of
30226    // ```
30227    // tag`...`
30228    // ```
30229    // which is effectively like:
30230    // ```
30231    // tag(__makeTemplateObject(cooked, raw), expression1, expression2, ...);
30232    // ```
30233    const elements = ast.template.elements;
30234    ast.tag.visitExpression(this, ctx);
30235    ctx.print(ast, `(${makeTemplateOb
30235jectPolyfill}(`);
30236    ctx.print(ast, `[${elements.map(part => escapeIdentifier(part.text, false)).join(', ')}], `);
30237    ctx.print(ast, `[${elements.map(part => escapeIdentifier(part.rawText, false)).join(', ')}])`);
30238    ast.template.expressions.forEach(expression => {
30239      ctx.print(ast, ', ');
30240      expression.visitExpression(this, ctx);
30241    });
30242    ctx.print(ast, ')');
30243    return null;
30244  }
30245
30246  visitFunctionExpr(ast, ctx) {
30247    ctx.print(ast, `function${ast.name ? ' ' + ast.name : ''}(`);
30248
30249    this._visitParams(ast.params, ctx);
30250
30251    ctx.println(ast, `) {`);
30252    ctx.incIndent();
30253    this.visitAllStatements(ast.statements, ctx);
30254    ctx.decIndent();
30255    ctx.print(ast, `}`);
30256    return null;
30257  }
30258
30259  visitDeclareFunctionStmt(stmt, ctx) {
30260    ctx.print(stmt, `function ${stmt.name}(`);
30261
30262    this._visitParams(stmt.params, ctx);
30263
30264    ctx.println(stmt, `) {`);
30265    ctx.incIndent();
30266    this.visitAllStatements(stmt.statements, ctx);
30267    ctx.decIndent();
30268    ctx.println(stmt, `}`);
30269    return null;
30270  }
30271
30272  visitLocalizedString(ast, ctx) {
30273    // The following convoluted piece of code is effectively the downlevelled equivalent of
30274    // ```
30275    // $localize `...`
30276    // ```
30277    // which is effectively like:
30278    // ```
30279    // $localize(__makeTemplateObject(cooked, raw), expression1, expression2, ...);
30280    // ```
30281    ctx.print(ast, `$localize(${makeTemplateObjectPolyfill}(`);
30282    const parts = [ast.serializeI18nHead()];
30283
30284    for (let i = 1; i < ast.messageParts.length; i++) {
30285      parts.push(ast.serializeI18nTemplatePart(i));
30286    }
30287
30288    ctx.print(ast, `[${parts.map(part => escapeIdentifier(part.cooked, false)).join(', ')}], `);
30289    ctx.print(ast, `[${parts.map(part => escapeIdentifier(part.raw, false)).join(', ')}])`);
30290    ast.expressions.forEach(expression => {
30291      ctx.print(ast, ', ');
30292      expression.visitExpression(this, ctx);
30293    });
30294    ctx.print(ast, ')');
30295    return null;
30296  }
30297
30298  _visitParams(params, ctx) {
30299    this.visitAllObjects(param => ctx.print(null, param.name), params, ctx, ',');
30300  }
30301
30302}
30303/**
30304 * @license
30305 * Copyright Google LLC All Rights Reserved.
30306 *
30307 * Use of this source code is governed by an MIT-style license that can be
30308 * found in the LICENSE file at https://angular.io/license
30309 */
30310
30311/**
30312 * The Trusted Types policy, or null if Trusted Types are not
30313 * enabled/supported, or undefined if the policy has not been created yet.
30314 */
30315
30316
30317let policy;
30318/**
30319 * Returns the Trusted Types policy, or null if Trusted Types are not
30320 * enabled/supported. The first call to this function will create the policy.
30321 */
30322
30323function getPolicy() {
30324  if (policy === undefined) {
30325    policy = null;
30326
30327    if (_global.trustedTypes) {
30328      try {
30329        policy = _global.trustedTypes.createPolicy('angular#unsafe-jit', {
30330          createScript: s => s
30331        });
30332      } catch {// trustedTypes.createPolicy throws if called with a name that is
30333        // already registered, even in report-only mode. Until the API changes,
30334        // catch the error not to break the applications functionally. In such
30335        // cases, the code will fall back to using strings.
30336      }
30337    }
30338  }
30339
30340  return policy;
30341}
30342/**
30343 * Unsafely promote a string to a TrustedScript, falling back to strings when
30344 * Trusted Types are not available.
30345 * @security In particular, it must be assured that the provided string will
30346 * never cause an XSS vulnerability if used in a context that will be
30347 * interpreted and executed as a script by a browser, e.g. when calling eval.
30348 */
30349
30350
30351function trustedScriptFromString(script) {
30352  return getPolicy()?.createScript(script) || script;
30353}
30354/**
30355 * Unsafely call the Function constructor with the given string arguments.
30356 * @security This is a security-sensitive function; any use of this function
30357 * must go through security review. In particular, it must be assured that it
30358 * is only called from the JIT compiler, as use in other code can lead to XSS
30359 * vulnerabilities.
30360 */
30361
30362
30363function newTrustedFunctionForJIT(...args) {
30364  if (!_global.trustedTypes) {
30365    // In environments that don't support Trusted Types, fall back to the most
30366    // straightforward implementation:
30367    return new Function(...args);
30368  } // Chrome currently does not support passing TrustedScript to the Function
30369  // constructor. The following implements the workaround proposed on the page
30370  // below, where the Chromium bug is also referenced:
30371  // https://github.com/w3c/webappsec-trusted-types/wiki/Trusted-Types-for-function-constructor
30372
30373
30374  const fnArgs = args.slice(0, -1).join(',');
30375  const fnBody = args[args.length - 1];
30376  const body = `(function anonymous(${fnArgs}
30377) { ${fnBody}
30378})`; // Using eval directly confuses the compiler and prevents this module from
30379  // being stripped out of JS binaries even if not used. The global['eval']
30380  // indirection fixes that.
30381
30382  const fn = _global['eval'](trustedScriptFromString(body));
30383
30384  if (fn.bind === undefined) {
30385    // Workaround for a browser bug that only exists in Chrome 83, where passing
30386    // a TrustedScript to eval just returns the TrustedScript back without
30387    // evaluating it. In that case, fall back to the most straightforward
30388    // implementation:
30389    return new Function(...args);
30390  } // To completely mimic the behavior of calling "new Function", two more
30391  // things need to happen:
30392  // 1. Stringifying the resulting function should return its source code
30393
30394
30395  fn.toString = () => body; // 2. When calling the resulting function, `this` should refer to `global`
30396
30397
30398  return fn.bind(_global); // When Trusted Types support in Function constructors is widely available,
30399  // the implementation of this function can be simplified to:
30400  // return new Function(...args.map(a => trustedScriptFromString(a)));
30401}
30402/**
30403 * @license
30404 * Copyright Google LLC All Rights Reserved.
30405 *
30406 * Use of this source code is governed by an MIT-style license that can be
30407 * found in the LICENSE file at https://angular.io/license
30408 */
30409
30410/**
30411 * A helper class to manage the evaluation of JIT generated code.
30412 */
30413
30414
30415class JitEvaluator {
30416  /**
30417   *
30418   * @param sourceUrl The URL of the generated code.
30419   * @param statements An array of Angular statement AST nodes to be evaluated.
30420   * @param refResolver Resolves `o.ExternalReference`s into values.
30421   * @param createSourceMaps If true then create a source-map for the generated code and include it
30422   * inline as a source-map comment.
30423   * @returns A map of all the variables in the generated code.
30424   */
30425  evaluateStatements(sourceUrl, statements, refResolver, createSourceMaps) {
30426    const converter = new JitEmitterVisitor(refResolver);
30427    const ctx = EmitterVisitorContext.createRoot(); // Ensure generated code is in strict mode
30428
30429    if (statements.length >
30429 0 && !isUseStrictStatement(statements[0])) {
30430      statements = [literal('use strict').toStmt(), ...statements];
30431    }
30432
30433    converter.visitAllStatements(statements, ctx);
30434    converter.createReturnStmt(ctx);
30435    return this.evaluateCode(sourceUrl, ctx, converter.getArgs(), createSourceMaps);
30436  }
30437  /**
30438   * Evaluate a piece of JIT generated code.
30439   * @param sourceUrl The URL of this generated code.
30440   * @param ctx A context object that contains an AST of the code to be evaluated.
30441   * @param vars A map containing the names and values of variables that the evaluated code might
30442   * reference.
30443   * @param createSourceMap If true then create a source-map for the generated code and include it
30444   * inline as a source-map comment.
30445   * @returns The result of evaluating the code.
30446   */
30447
30448
30449  evaluateCode(sourceUrl, ctx, vars, createSourceMap) {
30450    let fnBody = `"use strict";${ctx.toSource()}\n//# sourceURL=${sourceUrl}`;
30451    const fnArgNames = [];
30452    const fnArgValues = [];
30453
30454    for (const argName in vars) {
30455      fnArgValues.push(vars[argName]);
30456      fnArgNames.push(argName);
30457    }
30458
30459    if (createSourceMap) {
30460      // using `new Function(...)` generates a header, 1 line of no arguments, 2 lines otherwise
30461      // E.g. ```
30462      // function anonymous(a,b,c
30463      // /**/) { ... }```
30464      // We don't want to hard code this fact, so we auto detect it via an empty function first.
30465      const emptyFn = newTrustedFunctionForJIT(...fnArgNames.concat('return null;')).toString();
30466      const headerLines = emptyFn.slice(0, emptyFn.indexOf('return null;')).split('\n').length - 1;
30467      fnBody += `\n${ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment()}`;
30468    }
30469
30470    const fn = newTrustedFunctionForJIT(...fnArgNames.concat(fnBody));
30471    return this.executeFunction(fn, fnArgValues);
30472  }
30473  /**
30474   * Execute a JIT generated function by calling it.
30475   *
30476   * This method can be overridden in tests to capture the functions that are generated
30477   * by this `JitEvaluator` class.
30478   *
30479   * @param fn A function to execute.
30480   * @param args The arguments to pass to the function being executed.
30481   * @returns The return value of the executed function.
30482   */
30483
30484
30485  executeFunction(fn, args) {
30486    return fn(...args);
30487  }
30488
30489}
30490/**
30491 * An Angular AST visitor that converts AST nodes into executable JavaScript code.
30492 */
30493
30494
30495class JitEmitterVisitor extends AbstractJsEmitterVisitor {
30496  constructor(refResolver) {
30497    super();
30498    this.refResolver = refResolver;
30499    this._evalArgNames = [];
30500    this._evalArgValues = [];
30501    this._evalExportedVars = [];
30502  }
30503
30504  createReturnStmt(ctx) {
30505    const stmt = new ReturnStatement(new LiteralMapExpr(this._evalExportedVars.map(resultVar => new LiteralMapEntry(resultVar, variable(resultVar), false))));
30506    stmt.visitStatement(this, ctx);
30507  }
30508
30509  getArgs() {
30510    const result = {};
30511
30512    for (let i = 0; i < this._evalArgNames.length; i++) {
30513      result[this._evalArgNames[i]] = this._evalArgValues[i];
30514    }
30515
30516    return result;
30517  }
30518
30519  visitExternalExpr(ast, ctx) {
30520    this._emitReferenceToExternal(ast, this.refResolver.resolveExternalReference(ast.value), ctx);
30521
30522    return null;
30523  }
30524
30525  visitWrappedNodeExpr(ast, ctx) {
30526    this._emitReferenceToExternal(ast, ast.node, ctx);
30527
30528    return null;
30529  }
30530
30531  visitDeclareVarStmt(stmt, ctx) {
30532    if (stmt.hasModifier(StmtModifier.Exported)) {
30533      this._evalExportedVars.push(stmt.name);
30534    }
30535
30536    return super.visitDeclareVarStmt(stmt, ctx);
30537  }
30538
30539  visitDeclareFunctionStmt(stmt, ctx) {
30540    if (stmt.hasModifier(StmtModifier.Exported)) {
30541      this._evalExportedVars.push(stmt.name);
30542    }
30543
30544    return super.visitDeclareFunctionStmt(stmt, ctx);
30545  }
30546
30547  _emitReferenceToExternal(ast, value, ctx) {
30548    let id = this._evalArgValues.indexOf(value);
30549
30550    if (id === -1) {
30551      id = this._evalArgValues.length;
30552
30553      this._evalArgValues.push(value);
30554
30555      const name = identifierName({
30556        reference: value
30557      }) || 'val';
30558
30559      this._evalArgNames.push(`jit_${name}_${id}`);
30560    }
30561
30562    ctx.print(ast, this._evalArgNames[id]);
30563  }
30564
30565}
30566
30567function isUseStrictStatement(statement) {
30568  return statement.isEquivalent(literal('use strict').toStmt());
30569}
30570/**
30571 * @license
30572 * Copyright Google LLC All Rights Reserved.
30573 *
30574 * Use of this source code is governed by an MIT-style license that can be
30575 * found in the LICENSE file at https://angular.io/license
30576 */
30577
30578
30579function compileInjector(meta) {
30580  const definitionMap = new DefinitionMap();
30581
30582  if (meta.providers !== null) {
30583    definitionMap.set('providers', meta.providers);
30584  }
30585
30586  if (meta.imports.length > 0) {
30587    definitionMap.set('imports', literalArr(meta.imports));
30588  }
30589
30590  const expression = importExpr(Identifiers.defineInjector).callFn([definitionMap.toLiteralMap()], undefined, true);
30591  const type = createInjectorType(meta);
30592  return {
30593    expression,
30594    type,
30595    statements: []
30596  };
30597}
30598
30599function createInjectorType(meta) {
30600  return new ExpressionType(importExpr(Identifiers.InjectorDeclaration, [new ExpressionType(meta.type.type)]));
30601}
30602/**
30603 * @license
30604 * Copyright Google LLC All Rights Reserved.
30605 *
30606 * Use of this source code is governed by an MIT-style license that can be
30607 * found in the LICENSE file at https://angular.io/license
30608 */
30609
30610/**
30611 * Implementation of `CompileReflector` which resolves references to @angular/core
30612 * symbols at runtime, according to a consumer-provided mapping.
30613 *
30614 * Only supports `resolveExternalReference`, all other methods throw.
30615 */
30616
30617
30618class R3JitReflector {
30619  constructor(context) {
30620    this.context = context;
30621  }
30622
30623  resolveExternalReference(ref) {
30624    // This reflector only handles @angular/core imports.
30625    if (ref.moduleName !== '@angular/core') {
30626      throw new Error(`Cannot resolve external reference to ${ref.moduleName}, only references to @angular/core are supported.`);
30627    }
30628
30629    if (!this.context.hasOwnProperty(ref.name)) {
30630      throw new Error(`No value provided for @angular/core symbol '${ref.name}'.`);
30631    }
30632
30633    return this.context[ref.name];
30634  }
30635
30636}
30637/**
30638 * @license
30639 * Copyright Google LLC All Rights Reserved.
30640 *
30641 * Use of this source code is governed by an MIT-style license that can be
30642 * found in the LICENSE file at https://angular.io/license
30643 */
30644
30645/**
30646 * How the selector scope of an NgModule (its declarations, imports, and exports) should be emitted
30647 * as a part of the NgModule definition.
30648 */
30649
30650
30651var R3SelectorScopeMode;
30652
30653(function (R3SelectorScopeMode) {
30654  /**
30655   * Emit the declarations inline into the module definition.
30656   *
30657   * This option is useful in certain contexts where it's known that JIT support is required. The
30658   * tradeoff here is that this emit style prevents directives and pipes from being tree-shaken if
30659   * they are unused, but the NgModule is used.
30660   */
30661  R3SelectorScopeMode[R3SelectorScopeMode["Inline"] = 0] = "Inline";
30662  /**
30663   * Emit the declarations using a side effectful function call, `ɵɵsetNgModuleScope`, that is
30664   * guarded with the `ngJitMode` flag.
30665   *
30666   * This form of emit supports JIT and can be optimized away if the `ngJitMode` flag is set to
30667   * false, which allows unused directives and pipes to be tree-shaken.
30668   */
30669
30670  R3SelectorScopeMode[R3SelectorScopeMode["SideEffect"] = 1] = "SideEffect";
30671  /**
30672   * Don't generate selector scopes at all.
30673   *
30674   * This is useful for contexts where JIT support is known to be unnecessary.
30675   */
30676
30677  R3SelectorScopeMode[R3SelectorScopeMode["Omit"] = 2] = "Omit";
30678})(R3SelectorScopeMode || (R3SelectorScopeMode = {}));
30679/**
30680 * Construct an `R3NgModuleDef` for the given `R3NgModuleMetadata`.
30681 */
30682
30683
30684function compileNgModule(meta) {
30685  const {
30686    adjacentType,
30687    internalType,
30688    bootstrap,
30689    declarations,
30690    imports,
30691    exports,
30692    schemas,
30693    containsForwardDecls,
30694    selectorScopeMode,
30695    id
30696  } = meta;
30697  const statements = [];
30698  const definitionMap = new DefinitionMap();
30699  definitionMap.set('type', internalType);
30700
30701  if (bootstrap.length > 0) {
30702    definitionMap.set('bootstrap', refsToArray(bootstrap, containsForwardDecls));
30703  }
30704
30705  if (selectorScopeMode === R3SelectorScopeMode.Inline) {
30706    // If requested to emit scope information inline, pass the `declarations`, `imports` and
30707    // `exports` to the `ɵɵdefineNgModule()` call directly.
30708    if (declarations.length > 0) {
30709      definitionMap.set('declarations', refsToArray(declarations, containsForwardDecls));
30710    }
30711
30712    if (imports.length > 0) {
30713      definitionMap.set('imports', refsToArray(imports, containsForwardDecls));
30714    }
30715
30716    if (exports.length > 0) {
30717      definitionMap.set('exports', refsToArray(exports, containsForwardDecls));
30718    }
30719  } else if (selectorScopeMode === R3SelectorScopeMode.SideEffect) {
30720    // In this mode, scope information is not passed into `ɵɵdefineNgModule` as it
30721    // would prevent tree-shaking of the declarations, imports and exports references. Instead, it's
30722    // patched onto the NgModule definition with a `ɵɵsetNgModuleScope` call that's guarded by the
30723    // `ngJitMode` flag.
30724    const setNgModuleScopeCall = generateSetNgModuleScopeCall(meta);
30725
30726    if (setNgModuleScopeCall !== null) {
30727      statements.push(setNgModuleScopeCall);
30728    }
30729  } else {// Selector scope emit was not requested, so skip it.
30730  }
30731
30732  if (schemas !== null && schemas.length > 0) {
30733    definitionMap.set('schemas', literalArr(schemas.map(ref => ref.value)));
30734  }
30735
30736  if (id !== null) {
30737    definitionMap.set('id', id); // Generate a side-effectful call to register this NgModule by its id, as per the semantics of
30738    // NgModule ids.
30739
30740    statements.push(importExpr(Identifiers.registerNgModuleType).callFn([adjacentType, id]).toStmt());
30741  }
30742
30743  const expression = importExpr(Identifiers.defineNgModule).callFn([definitionMap.toLiteralMap()], undefined, true);
30744  const type = createNgModuleType(meta);
30745  return {
30746    expression,
30747    type,
30748    statements
30749  };
30750}
30751/**
30752 * This function is used in JIT mode to generate the call to `ɵɵdefineNgModule()` from a call to
30753 * `ɵɵngDeclareNgModule()`.
30754 */
30755
30756
30757function compileNgModuleDeclarationExpression(meta) {
30758  const definitionMap = new DefinitionMap();
30759  definitionMap.set('type', new WrappedNodeExpr(meta.type));
30760
30761  if (meta.bootstrap !== undefined) {
30762    definitionMap.set('bootstrap', new WrappedNodeExpr(meta.bootstrap));
30763  }
30764
30765  if (meta.declarations !== undefined) {
30766    definitionMap.set('declarations', new WrappedNodeExpr(meta.declarations));
30767  }
30768
30769  if (meta.imports !== undefined) {
30770    definitionMap.set('imports', new WrappedNodeExpr(meta.imports));
30771  }
30772
30773  if (meta.exports !== undefined) {
30774    definitionMap.set('exports', new WrappedNodeExpr(meta.exports));
30775  }
30776
30777  if (meta.schemas !== undefined) {
30778    definitionMap.set('schemas', new WrappedNodeExpr(meta.schemas));
30779  }
30780
30781  if (meta.id !== undefined) {
30782    definitionMap.set('id', new WrappedNodeExpr(meta.id));
30783  }
30784
30785  return importExpr(Identifiers.defineNgModule).callFn([definitionMap.toLiteralMap()]);
30786}
30787
30788function createNgModuleType({
30789  type: moduleType,
30790  declarations,
30791  exports,
30792  imports,
30793  includeImportTypes,
30794  publicDeclarationTypes
30795}) {
30796  return new ExpressionType(importExpr(Identifiers.NgModuleDeclaration, [new ExpressionType(moduleType.type), publicDeclarationTypes === null ? tupleTypeOf(declarations) : tupleOfTypes(publicDeclarationTypes), includeImportTypes ? tupleTypeOf(imports) : NONE_TYPE, tupleTypeOf(exports)]));
30797}
30798/**
30799 * Generates a function call to `ɵɵsetNgModuleScope` with all necessary information so that the
30800 * transitive module scope can be computed during runtime in JIT mode. This call is marked pure
30801 * such that the references to declarations, imports and exports may be elided causing these
30802 * symbols to become tree-shakeable.
30803 */
30804
30805
30806function generateSetNgModuleScopeCall(meta) {
30807  const {
30808    adjacentType: moduleType,
30809    declarations,
30810    imports,
30811    exports,
30812    containsForwardDecls
30813  } = meta;
30814  const scopeMap = new DefinitionMap();
30815
30816  if (declarations.length > 0) {
30817    scopeMap.set('declarations', refsToArray(declarations, containsForwardDecls));
30818  }
30819
30820  if (imports.length > 0) {
30821    scopeMap.set('imports', refsToArray(imports, containsForwardDecls));
30822  }
30823
30824  if (exports.length > 0) {
30825    scopeMap.set('exports', refsToArray(exports, containsForwardDecls));
30826  }
30827
30828  if (Object.keys(scopeMap.values).length === 0) {
30829    return null;
30830  } // setNgModuleScope(...)
30831
30832
30833  const fnCall = new InvokeFunctionExpr(
30834  /* fn */
30835  importExpr(Identifiers.setNgModuleScope),
30836  /* args */
30837  [moduleType, scopeMap.toLiteralMap()]); // (ngJitMode guard) && setNgModuleScope(...)
30838
30839  const guardedCall = jitOnlyGuardedExpression(fnCall); // function() { (ngJitMode guard) && setNgModuleScope(...); }
30840
30841  const iife = new FunctionExpr(
30842  /* params */
30843  [],
30844  /* statements */
30845  [guardedCall.toStmt()]); // (function() { (ngJitMode guard) && setNgModuleScope(...); })()
30846
30847  const iifeCall = new InvokeFunctionExpr(
30848  /* fn */
30849  iife,
30850  /* args */
30851  []);
30852  return iifeCall.toStmt();
30853}
30854
30855function tupleTypeOf(exp) {
30856  const types = exp.map(ref => typeofExpr(ref.type));
30857  return exp.length > 0 ? expressionType(literalArr(types)) : NONE_TYPE;
30858}
30859
30860function tupleOfTypes(types) {
30861  const typeofTypes = types.map(type => typeofExpr(type));
30862  return types.length > 0 ? expressionType(literalArr(typeofTypes)) : NONE_TYPE;
30863}
30864/**
30865 * @license
30866 * Copyright Google LLC All Rights Reserved.
30867 *
30868 * Use of this source code is governed by an MIT-style license that can be
30869 * found in the LICENSE file at https://angular.io/license
30870 */
30871
30872
30873function compilePipeFromMetadata(metadata) {
30874  const definitionMapValues = []; // e.g. `name: 'myPipe'`
30875
30876  definitionMapValues.push({
30877    key: 'name',
30878    value: literal(metadata.pipeName),
30879    quoted: false
30880  }); // e.g. `type: MyPipe`
30881
30882  definitionMapValues.push({
30883    key: 'type',
30884    value: metadata.type.value,
30885    quoted: false
30886  }); // e.g. `pure: true`
30887
30888  definitionMapValues.push({
30889    key: 'pure',
30890    value: literal(metadata.pure),
30891    quoted: false
30892  });
30893
30894  if (metadata.isStandalone) {
30895    definitionMapValues.push({
30896      key: 'standalone',
30897      value: literal(true),
30898      quoted: false
30899    });
30900  }
30901
30902  const expression = importExpr(Identifiers.definePipe).callFn([literalMap(definitionMapValues)], undefined, true);
30903  const type = createPipeType(metadata);
30904  return {
30905    expression,
30906    type,
30907    statements: []
30908  };
30909}
30910
30911function createPipeType(metadata) {
30912  return new ExpressionType(importExpr(Identifiers.PipeDeclaration, [typeWithParameters(metadata.type.type, metadata.typeArgumentCount), new ExpressionType(new LiteralExpr(metadata.pipeName)), new ExpressionType(new LiteralExpr(metadata.isStandalone))]));
30913}
30914/**
30915 * @license
30916 * Copyright Google LLC All Rights Reserved.
30917 *
30918 * Use of this source code is governed by an MIT-style license that can be
30919 * found in the LICENSE file at https://angular.io/license
30920 */
30921
30922
30923var R3TemplateDependencyKind;
30924
30925(function (R3TemplateDependencyKind) {
30926  R3TemplateDependencyKind[R3TemplateDependencyKind["Directive"] = 0] = "Directive";
30927  R3TemplateDependencyKind[R3TemplateDependencyKind["Pipe"] = 1] = "Pipe";
30928  R3TemplateDependencyKind[R3TemplateDependencyKind["NgModule"] = 2] = "NgModule";
30929})(R3TemplateDependencyKind || (R3TemplateDependencyKind = {}));
30930/**
30931 * @license
30932 * Copyright Google LLC All Rights Reserved.
30933 *
30934 * Use of this source code is governed by an MIT-style license that can be
30935 * found in the LICENSE file at https://angular.io/license
30936 */
30937
30938
30939class ParserError {
30940  constructor(message, input, errLocation, ctxLocation) {
30941    this.input = input;
30942    this.errLocation = errLocation;
30943    this.ctxLocation = ctxLocation;
30944    this.message = `Parser Error: ${message} ${errLocation} [${input}] in ${ctxLocation}`;
30945  }
30946
30947}
30948
30949class ParseSpan {
30950  constructor(start, end) {
30951    this.start = start;
30952    this.end = end;
30953  }
30954
30955  toAbsolute(absoluteOffset) {
30956    return new AbsoluteSourceSpan(absoluteOffset + this.start, absoluteOffset + this.end);
30957  }
30958
30959}
30960
30961class AST {
30962  constructor(span,
30963  /**
30964   * Absolute location of the expression AST in a source code file.
30965   */
30966  sourceSpan) {
30967    this.span = span;
30968    this.sourceSpan = sourceSpan;
30969  }
30970
30971  toString() {
30972    return 'AST';
30973  }
30974
30975}
30976
30977class ASTWithName extends AST {
30978  constructor(span, sourceSpan, nameSpan) {
30979    super(span, sourceSpan);
30980    this.nameSpan = nameSpan;
30981  }
30982
30983}
30984
30985class EmptyExpr extends AST {
30986  visit(visitor, context = null) {// do nothing
30987  }
30988
30989}
30990
30991class ImplicitReceiver extends AST {
30992  visit(visitor, context = null) {
30993    return visitor.visitImplicitReceiver(this, context);
30994  }
30995
30996}
30997/**
30998 * Receiver when something is accessed through `this` (e.g. `this.foo`). Note that this class
30999 * inherits from `ImplicitReceiver`, because accessing something through `this` is treated the
31000 * same as accessing it implicitly inside of an Angular template (e.g. `[attr.title]="this.title"`
31001 * is the same as `[attr.title]="title"`.). Inheriting allows for the `this` accesses to be treated
31002 * the same as implicit ones, except for a couple of exceptions like `$event` and `$any`.
31003 * TODO: we should find a way for this class not to extend from `ImplicitReceiver` in the future.
31004 */
31005
31006
31007class ThisReceiver extends ImplicitReceiver {
31008  visit(visitor, context = null) {
31009    return visitor.visitThisReceiver?.(this, context);
31010  }
31011
31012}
31013/**
31014 * Multiple expressions separated by a semicolon.
31015 */
31016
31017
31018class Chain extends AST {
31019  constructor(span, sourceSpan, expressions) {
31020    super(span, sourceSpan);
31021    this.expressions = expressions;
31022  }
31023
31024  visit(visitor, context = null) {
31025    return visitor.visitChain(this, context);
31026  }
31027
31028}
31029
31030class Conditional extends AST {
31031  constructor(span, sourceSpan, condition, trueExp, falseExp) {
31032    super(span, sourceSpan);
31033    this.condition = condition;
31034    this.trueExp = trueExp;
31035    this.falseExp = falseExp;
31036  }
31037
31038  visit(visitor, context = null) {
31039    return visitor.visitConditional(this, context);
31040  }
31041
31042}
31043
31044class PropertyRead extends ASTWithName {
31045  constructor(span, sourceSpan, nameSpan, receiver, name) {
31046    super(span, sourceSpan, nameSpan);
31047    this.receiver = receiver;
31048    this.name = name;
31049  }
31050
31051  visit(visitor, context = null) {
31052    return visitor.visitPropertyRead(this, context);
31053  }
31054
31055}
31056
31057class PropertyWrite extends ASTWithName {
31058  constructor(span, sourceSpan, nameSpan, receiver, name, value) {
31059    super(span, sourceSpan, nameSpan);
31060    this.receiver = receiver;
31061    this.name = name;
31062    this.value = value;
31063  }
31064
31065  visit(visitor, context = null) {
31066    return visitor.visitPropertyWrite(this, context);
31067  }
31068
31069}
31070
31071class SafePropertyRead extends ASTWithName {
31072  constructor(span, sourceSpan, nameSpan, receiver, name) {
31073    super(span, sourceSpan, nameSpan);
31074    this.receiver = receiver;
31075    this.name = name;
31076  }
31077
31078  visit(visitor, context = null) {
31079    return visitor.visitSafePropertyRead(this, context);
31080  }
31081
31082}
31083
31084class KeyedRead extends AST {
31085  constructor(span, sourceSpan, receiver, key) {
31086    super(span, sourceSpan);
31087    this.receiver = receiver;
31088    this.key = key;
31089  }
31090
31091  visit(visitor, context = null) {
31092    return visitor.visitKeyedRead(this, context);
31093  }
31094
31095}
31096
31097class SafeKeyedRead extends AST {
31098  constructor(span, sourceSpan, receiver, key) {
31099    super(span, sourceSpan);
31100    this.receiver = receiver;
31101    this.key = key;
31102  }
31103
31104  visit(visitor, context = null) {
31105    return visitor.visitSafeKeyedRead(this, context);
31106  }
31107
31108}
31109
31110class KeyedWrite extends AST {
31111  constructor(span, sourceSpan, receiver, key, value) {
31112    super(span, sourceSpan);
31113    this.receiver = receiver;
31114    this.key = key;
31115    this.value = value;
31116  }
31117
31118  visit(visitor, context = null) {
31119    return visitor.visitKeyedWrite(this, context);
31120  }
31121
31122}
31123
31124class BindingPipe extends ASTWithName {
31125  constructor(span, sourceSpan, exp, name, args, nameSpan) {
31126    super(span, sourceSpan, nameSpan);
31127    this.exp = exp;
31128    this.name = name;
31129    this.args = args;
31130  }
31131
31132  visit(visitor, context = null) {
31133    return visitor.visitPipe(this, context);
31134  }
31135
31136}
31137
31138class LiteralPrimitive extends AST {
31139  constructor(span, sourceSpan, value) {
31140    super(span, sourceSpan);
31141    this.value = value;
31142  }
31143
31144  visit(visitor, context = null) {
31145    return visitor.visitLiteralPrimitive(this, context);
31146  }
31147
31148}
31149
31150class LiteralArray extends AST {
31151  constructor(span, sourceSpan, expressions) {
31152    super(span, sourceSpan);
31153    this.expressions = expressions;
31154  }
31155
31156  visit(visitor, context = null) {
31157    return visitor.visitLiteralArray(this, context);
31158  }
31159
31160}
31161
31162class LiteralMap extends AST {
31163  constructor(span, sourceSpan, keys, values) {
31164    super(span, sourceSpan);
31165    this.keys = keys;
31166    this.values = values;
31167  }
31168
31169  visit(visitor, context = null) {
31170    return visitor.visitLiteralMap(this, context);
31171  }
31172
31173}
31174
31175class Interpolation extends AST {
31176  constructor(span, sourceSpan, strings, expressions) {
31177    super(span, sourceSpan);
31178    this.strings = strings;
31179    this.expressions = expressions;
31180  }
31181
31182  visit(visitor, context = null) {
31183    return visitor.visitInterpolation(this, context);
31184  }
31185
31186}
31187
31188class Binary extends AST {
31189  constructor(span, sourceSpan, operation, left, right) {
31190    super(span, sourceSpan);
31191    this.operation = operation;
31192    this.left = left;
31193    this.right = right;
31194  }
31195
31196  visit(visitor, context = null) {
31197    return visitor.visitBinary(this, context);
31198  }
31199
31200}
31201/**
31202 * For backwards compatibility reasons, `Unary` inherits from `Binary` and mimics the binary AST
31203 * node that was originally used. This inheritance relation can be deleted in some future major,
31204 * after consumers have been given a chance to fully support Unary.
31205 */
31206
31207
31208class Unary extends Binary {
31209  /**
31210   * During the deprecation period this constructor is private, to avoid consumers from creating
31211   * a `Unary` with the fallback properties for `Binary`.
31212   */
31213  constructor(span, sourceSpan, operator, expr, binaryOp, binaryLeft, binaryRight) {
31214    super(span, sourceSpan, binaryOp, binaryLeft, binaryRight);
31215    this.operator = operator;
31216    this.expr = expr; // Redeclare the properties that are inherited from `Binary` as `never`, as consumers should not
31217    // depend on these fields when operating on `Unary`.
31218
31219    this.left = null;
31220    this.right = null;
31221    this.operation = null;
31222  }
31223  /**
31224   * Creates a unary minus expression "-x", represented as `Binary` using "0 - x".
31225   */
31226
31227
31228  static createMinus(span, sourceSpan, expr) {
31229    return new Unary(span, sourceSpan, '-', expr, '-', new LiteralPrimitive(span, sourceSpan, 0), expr);
31230  }
31231  /**
31232   * Creates a unary plus expression "+x", represented as `Binary` using "x - 0".
31233   */
31234
31235
31236  static createPlus(span, sourceSpan, expr) {
31237    return new Unary(span, sourceSpan, '+', expr, '-', expr, new LiteralPrimitive(span, sourceSpan, 0));
31238  }
31239
31240  visit(visitor, context = null) {
31241    if (visitor.visitUnary !== undefined) {
31242      return visitor.visitUnary(this, context);
31243    }
31244
31245    return visitor.visitBinary(this, context);
31246  }
31247
31248}
31249
31250class PrefixNot extends AST {
31251  constructor(span, sourceSpan, expression) {
31252    super(span, sourceSpan);
31253    this.expression = expression;
31254  }
31255
31256  visit(visitor, context = null) {
31257    return visitor.visitPrefixNot(this, context);
31258  }
31259
31260}
31261
31262class NonNullAssert extends AST {
31263  constructor(span, sourceSpan, expression) {
31264    super(span, sourceSpan);
31265    this.expression = expression;
31266  }
31267
31268  visit(visitor, context = null) {
31269    return visitor.visitNonNullAssert(this, context);
31270  }
31271
31272}
31273
31274class Call extends AST {
31275  constructor(span, sourceSpan, receiver, args, argumentSpan) {
31276    super(span, sourceSpan);
31277    this.receiver = receiver;
31278    this.args = args;
31279    this.argumentSpan = argumentSpan;
31280  }
31281
31282  visit(visitor, context = null) {
31283    return visitor.visitCall(this, context);
31284  }
31285
31286}
31287
31288class SafeCall extends AST {
31289  constructor(span, sourceSpan, receiver, args, argumentSpan) {
31290    super(span, sourceSpan);
31291    this.receiver = receiver;
31292    this.args = args;
31293    this.argumentSpan = argumentSpan;
31294  }
31295
31296  visit(visitor, context = null) {
31297    return visitor.visitSafeCall(this, context);
31298  }
31299
31300}
31301/**
31302 * Records the absolute position of a text span in a source file, where `start` and `end` are the
31303 * starting and ending byte offsets, respectively, of the text span in a source file.
31304 */
31305
31306
31307class AbsoluteSourceSpan {
31308  constructor(start, end) {
31309    this.start = start;
31310    this.end = end;
31311  }
31312
31313}
31314
31315class ASTWithSource extends AST {
31316  constructor(ast, source, location, absoluteOffset, errors) {
31317    super(new ParseSpan(0, source === null ? 0 : source.length), new AbsoluteSourceSpan(absoluteOffset, source === null ? absoluteOffset : absoluteOffset + source.length));
31318    this.ast = ast;
31319    this.source = source;
31320    this.location = location;
31321    this.errors = errors;
31322  }
31323
31324  visit(visitor, context = null) {
31325    if (visitor.visitASTWithSource) {
31326      return visitor.visitASTWithSource(this, context);
31327    }
31328
31329    return this.ast.visit(visitor, context);
31330  }
31331
31332  toString() {
31333    return `${this.source} in ${this.location}`;
31334  }
31335
31336}
31337
31338class VariableBinding {
31339  /**
31340   * @param sourceSpan entire span of the binding.
31341   * @param key name of the LHS along with its span.
31342   * @param value optional value for the RHS along with its span.
31343   */
31344  constructor(sourceSpan, key, value) {
31345    this.sourceSpan = sourceSpan;
31346    this.key = key;
31347    this.value = value;
31348  }
31349
31350}
31351
31352class ExpressionBinding {
31353  /**
31354   * @param sourceSpan entire span of the binding.
31355   * @param key binding name, like ngForOf, ngForTrackBy, ngIf, along with its
31356   * span. Note that the length of the span may not be the same as
31357   * `key.source.length`. For example,
31358   * 1. key.source = ngFor, key.span is for "ngFor"
31359   * 2. key.source = ngForOf, key.span is for "of"
31360   * 3. key.source = ngForTrackBy, key.span is for "trackBy"
31361   * @param value optional expression for the RHS.
31362   */
31363  constructor(sourceSpan, key, value) {
31364    this.sourceSpan = sourceSpan;
31365    this.key = key;
31366    this.value = value;
31367  }
31368
31369}
31370
31371class RecursiveAstVisitor {
31372  visit(ast, context) {
31373    // The default implementation just visits every node.
31374    // Classes that extend RecursiveAstVisitor should override this function
31375    // to selectively visit the specified node.
31376    ast.visit(this, context);
31377  }
31378
31379  visitUnary(ast, context) {
31380    this.visit(ast.expr, context);
31381  }
31382
31383  visitBinary(ast, context) {
31384    this.visit(ast.left, context);
31385    this.visit(ast.right, context);
31386  }
31387
31388  visitChain(ast, context) {
31389    this.visitAll(ast.expressions, context);
31390  }
31391
31392  visitConditional(ast, context) {
31393    this.visit(ast.condition, context);
31394    this.visit(ast.trueExp, context);
31395    this.visit(ast.falseExp, context);
31396  }
31397
31398  visitPipe(ast, context) {
31399    this.visit(ast.exp, context);
31400    this.visitAll(ast.args, context);
31401  }
31402
31403  visitImplicitReceiver(ast, context) {}
31404
31405  visitThisReceiver(ast, context) {}
31406
31407  visitInterpolation(ast, context) {
31408    this.visitAll(ast.expressions, context);
31409  }
31410
31411  visitKeyedRead(ast, context) {
31412    this.visit(ast.receiver, context);
31413    this.visit(ast.key, context);
31414  }
31415
31416  visitKeyedWrite(ast, context) {
31417    this.visit(ast.receiver, context);
31418    this.visit(ast.key, context);
31419    this.visit(ast.value, context);
31420  }
31421
31422  visitLiteralArray(ast, context) {
31423    this.visitAll(ast.expressions, context);
31424  }
31425
31426  visitLiteralMap(ast, context) {
31427    this.visitAll(ast.values, context);
31428  }
31429
31430  visitLiteralPrimitive(ast, context) {}
31431
31432  visitPrefixNot(ast, context) {
31433    this.visit(ast.expression, context);
31434  }
31435
31436  visitNonNullAssert(ast, context) {
31437    this.visit(ast.expression, context);
31438  }
31439
31440  visitPropertyRead(ast, context) {
31441    this.visit(ast.receiver, context);
31442  }
31443
31444  visitPropertyWrite(ast, context) {
31445    this.visit(ast.receiver, context);
31446    this.visit(ast.value, context);
31447  }
31448
31449  visitSafePropertyRead(ast, context) {
31450    this.visit(ast.receiver, context);
31451  }
31452
31453  visitSafeKeyedRead(ast, context) {
31454    this.visit(ast.receiver, context);
31455    this.visit(ast.key, context);
31456  }
31457
31458  visitCall(ast, context) {
31459    this.visit(ast.receiver, context);
31460    this.visitAll(ast.args, context);
31461  }
31462
31463  visitSafeCall(ast, context) {
31464    this.visit(ast.receiver, context);
31465    this.visitAll(ast.args, context);
31466  } // This is not part of the AstVisitor interface, just a helper method
31467
31468
31469  visitAll(asts, context) {
31470    for (const ast of asts) {
31471      this.visit(ast, context);
31472    }
31473  }
31474
31475}
31476
31477class AstTransformer {
31478  visitImplicitReceiver(ast, context) {
31479    return ast;
31480  }
31481
31482  visitThisReceiver(ast, context) {
31483    return ast;
31484  }
31485
31486  visitInterpolation(ast, context) {
31487    return new Interpolation(ast.span, ast.sourceSpan, ast.strings, this.visitAll(ast.expressions));
31488  }
31489
31490  visitLiteralPrimitive(ast, context) {
31491    return new LiteralPrimitive(ast.span, ast.sourceSpan, ast.value);
31492  }
31493
31494  visitPropertyRead(ast, context) {
31495    return new PropertyRead(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name);
31496  }
31497
31498  visitPropertyWrite(ast, context) {
31499    return new PropertyWrite(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name, ast.value.visit(this));
31500  }
31501
31502  visitSafePropertyRead(ast, context) {
31503    return new SafePropertyRead(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name);
31504  }
31505
31506  visitLiteralArray(ast, context) {
31507    return new LiteralArray(ast.span, ast.sourceSpan, this.visitAll(ast.expressions));
31508  }
31509
31510  visitLiteralMap(ast, context) {
31511    return new LiteralMap(ast.span, ast.sourceSpan, ast.keys, this.visitAll(ast.values));
31512  }
31513
31514  visitUnary(ast, context) {
31515    switch (ast.operator) {
31516      case '+':
31517        return Unary.createPlus(ast.span, ast.sourceSpan, ast.expr.visit(this));
31518
31519      case '-':
31520        return Unary.createMinus(ast.span, ast.sourceSpan, ast.expr.visit(this));
31521
31522      default:
31523        throw new Error(`Unknown unary operator ${ast.operator}`);
31524    }
31525  }
31526
31527  visitBinary(ast, context) {
31528    return new Binary(ast.span, ast.sourceSpan, ast.operation, ast.left.visit(this), ast.right.visit(this));
31529  }
31530
31531  visitPrefixNot(ast, context) {
31532    return new PrefixNot(ast.span, ast.sourceSpan, ast.expression.visit(this));
31533  }
31534
31535  visitNonNullAssert(ast, context) {
31536    return new NonNullAssert(ast.span, ast.sourceSpan, ast.expression.visit(this));
31537  }
31538
31539  visitConditional(ast, context) {
31540    return new Conditional(ast.span, ast.sourceSpan, ast.condition.visit(this), ast.trueExp.visit(this), ast.falseExp.visit(this));
31541  }
31542
31543  visitPipe(ast, context) {
31544    return new BindingPipe(ast.span, ast.sourceSpan, ast.exp.visit(this), ast.name, this.visitAll(ast.args), ast.nameSpan);
31545  }
31546
31547  visitKeyedRead(ast, context) {
31548    return new KeyedRead(ast.span, ast.sourceSpan, ast.receiver.visit(this), ast.key.visit(this));
31549  }
31550
31551  visitKeyedWrite(ast, context) {
31552    return new KeyedWrite(ast.span, ast.sourceSpan, ast.receiver.visit(this), ast.key.visit(this), ast.value.visit(this));
31553  }
31554
31555  visitCall(ast, context) {
31556    return new Call(ast.span, ast.sourceSpan, ast.receiver.visit(this), this.visitAll(ast.args), ast.argumentSpan);
31557  }
31558
31559  visitSafeCall(ast, context) {
31560    return new SafeCall(ast.span, ast.sourceSpan, ast.receiver.visit(this), this.visitAll(ast.args), ast.argumentSpan);
31561  }
31562
31563  visitAll(asts) {
31564    const res = [];
31565
31566    for (let i = 0; i < asts.length; ++i) {
31567      res[i] = asts[i].visit(this);
31568    }
31569
31570    return res;
31571  }
31572
31573  visitChain(ast, context) {
31574    return new Chain(ast.span, ast.sourceSpan, this.visitAll(ast.expressions));
31575  }
31576
31577  visitSafeKeyedRead(ast, context) {
31578    return new SafeKeyedRead(ast.span, ast.sourceSpan, ast.receiver.visit(this), ast.key.visit(this));
31579  }
31580
31581} // A transformer that only creates new nodes if the transformer makes a change or
31582// a change is made a child node.
31583
31584
31585class AstMemoryEfficientTransformer {
31586  visitImplicitReceiver(ast, context) {
31587    return ast;
31588  }
31589
31590  visitThisReceiver(ast, context) {
31591    return ast;
31592  }
31593
31594  visitInterpolation(ast, context) {
31595    const expressions = this.visitAll(ast.expressions);
31596    if (expressions !== ast.expressions) return new Interpolation(ast.span, ast.sourceSpan, ast.strings, expressions);
31597    return ast;
31598  }
31599
31600  visitLiteralPrimitive(ast, context) {
31601    return ast;
31602  }
31603
31604  visitPropertyRead(ast, context) {
31605    const receiver = ast.receiver.visit(this);
31606
31607    if (receiver !== ast.receiver) {
31608      return new PropertyRead(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name);
31609    }
31610
31611    return ast;
31612  }
31613
31614  visitPropertyWrite(ast, context) {
31615    const receiver = ast.receiver.visit(this);
31616    const value = ast.value.visit(this);
31617
31618    if (receiver !== ast.receiver || value !== ast.value) {
31619      return new PropertyWrite(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name, value);
31620    }
31621
31622    return ast;
31623  }
31624
31625  visitSafePropertyRead(ast, context) {
31626    const receiver = ast.receiver.visit(this);
31627
31628    if (receiver !== ast.receiver) {
31629      return new SafePropertyRead(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name);
31630    }
31631
31632    return ast;
31633  }
31634
31635  visitLiteralArray(ast, context) {
31636    const expressions = this.visitAll(ast.expressions);
31637
31638    if (expressions !== ast.expressions) {
31639      return new LiteralArray(ast.span, ast.sourceSpan, expressions);
31640    }
31641
31642    return ast;
31643  }
31644
31645  visitLiteralMap(ast, context) {
31646    const values = this.visitAll(ast.values);
31647
31648    if (values !== ast.values) {
31649      return new LiteralMap(ast.span, ast.sourceSpan, ast.keys, values);
31650    }
31651
31652    return ast;
31653  }
31654
31655  visitUnary(ast, context) {
31656    const expr = ast.expr.visit(this);
31657
31658    if (expr !== ast.expr) {
31659      switch (ast.operator) {
31660        case '+':
31661          return Unary.createPlus(ast.span, ast.sourceSpan, expr);
31662
31663        case '-':
31664          return Unary.createMinus(ast.span, ast.sourceSpan, expr);
31665
31666        default:
31667          throw new Error(`Unknown unary operator ${ast.operator}`);
31668      }
31669    }
31670
31671    return ast;
31672  }
31673
31674  visitBinary(ast, context) {
31675    const left = ast.left.visit(this);
31676    const right = ast.right.visit(this);
31677
31678    if (left !== ast.left || right !== ast.right) {
31679      return new Binary(ast.span, ast.sourceSpan, ast.operation, left, right);
31680    }
31681
31682    return ast;
31683  }
31684
31685  visitPrefixNot(ast, context) {
31686    const expression = ast.expression.visit(this);
31687
31688    if (expression !== ast.expression) {
31689      return new PrefixNot(ast.span, ast.sourceSpan, expression);
31690    }
31691
31692    return ast;
31693  }
31694
31695  visitNonNullAssert(ast, context) {
31696    const expression = ast.expression.visit(this);
31697
31698    if (expression !== ast.expression) {
31699      return new NonNullAssert(ast.span, ast.sourceSpan, expression);
31700    }
31701
31702    return ast;
31703  }
31704
31705  visitConditional(ast, context) {
31706    const condition = ast.condition.visit(this);
31707    const trueExp = ast.trueExp.visit(this);
31708    const falseExp = ast.falseExp.visit(this);
31709
31710    if (condition !== ast.condition || trueExp !== ast.trueExp || falseExp !== ast.falseExp) {
31711      return new Conditional(ast.span, ast.sourceSpan, condition, trueExp, falseExp);
31712    }
31713
31714    return ast;
31715  }
31716
31717  visitPipe(ast, context) {
31718    const exp = ast.exp.visit(this);
31719    const args = this.visitAll(ast.args);
31720
31721    if (exp !== ast.exp || args !== ast.args) {
31722      return new BindingPipe(ast.span, ast.sourceSpan, exp, ast.name, args, ast.nameSpan);
31723    }
31724
31725    return ast;
31726  }
31727
31728  visitKeyedRead(ast, context) {
31729    const obj = ast.receiver.visit(this);
31730    const key = ast.key.visit(this);
31731
31732    if (obj !== ast.receiver || key !== ast.key) {
31733      return new KeyedRead(ast.span, ast.sourceSpan, obj, key);
31734    }
31735
31736    return ast;
31737  }
31738
31739  visitKeyedWrite(ast, context) {
31740    const obj = ast.receiver.visit(this);
31741    const key = ast.key.visit(this);
31742    const value = ast.value.visit(this);
31743
31744    if (obj !== ast.receiver || key !== ast.key || value !== ast.value) {
31745      return new KeyedWrite(ast.span, ast.sourceSpan, obj, key, value);
31746    }
31747
31748    return ast;
31749  }
31750
31751  visitAll(asts) {
31752    const res = [];
31753    let modified = false;
31754
31755    for (let i = 0; i < asts.length; ++i) {
31756      const original = asts[i];
31757      const value = original.visit(this);
31758      res[i] = value;
31759      modified = modified || value !== original;
31760    }
31761
31762    return modified ? res : asts;
31763  }
31764
31765  visitChain(ast, context) {
31766    const expressions = this.visitAll(ast.expressions);
31767
31768    if (expressions !== ast.expressions) {
31769      return new Chain(ast.span, ast.sourceSpan, expressions);
31770    }
31771
31772    return ast;
31773  }
31774
31775  visitCall(ast, context) {
31776    const receiver = ast.receiver.visit(this);
31777    const args = this.visitAll(ast.args);
31778
31779    if (receiver !== ast.receiver || args !== ast.args) {
31780      return new Call(ast.span, ast.sourceSpan, receiver, args, ast.argumentSpan);
31781    }
31782
31783    return ast;
31784  }
31785
31786  visitSafeCall(ast, context) {
31787    const receiver = ast.receiver.visit(this);
31788    const args = this.visitAll(ast.args);
31789
31790    if (receiver !== ast.receiver || args !== ast.args) {
31791      return new SafeCall(ast.span, ast.sourceSpan, receiver, args, ast.argumentSpan);
31792    }
31793
31794    return ast;
31795  }
31796
31797  visitSafeKeyedRead(ast, context) {
31798    const obj = ast.receiver.visit(this);
31799    const key = ast.key.visit(this);
31800
31801    if (obj !== ast.receiver || key !== ast.key) {
31802      return new SafeKeyedRead(ast.span, ast.sourceSpan, obj, key);
31803    }
31804
31805    return ast;
31806  }
31807
31808} // Bindings
31809
31810
31811class ParsedProperty {
31812  constructor(name, expression, type, sourceSpan, keySpan, valueSpan) {
31813    this.name = name;
31814    this.expression = expression;
31815    this.type = type;
31816    this.sourceSpan = sourceSpan;
31817    this.keySpan = keySpan;
31818    this.valueSpan = valueSpan;
31819    this.isLiteral = this.type === ParsedPropertyType.LITERAL_ATTR;
31820    this.isAnimation = this.type === ParsedPropertyType.ANIMATION;
31821  }
31822
31823}
31824
31825var ParsedPropertyType;
31826
31827(function (ParsedPropertyType) {
31828  ParsedPropertyType[ParsedPropertyType["DEFAULT"] = 0] = "DEFAULT";
31829  ParsedPropertyType[ParsedPropertyType["LITERAL_ATTR"] = 1] = "LITERAL_ATTR";
31830  ParsedPropertyType[ParsedPropertyType["ANIMATION"] = 2] = "ANIMATION";
31831})(ParsedPropertyType || (ParsedPropertyType = {}));
31832
31833class ParsedEvent {
31834  // Regular events have a target
31835  // Animation events have a phase
31836  constructor(name, targetOrPhase, type, handler, sourceSpan, handlerSpan, keySpan) {
31837    this.name = name;
31838    this.targetOrPhase = targetOrPhase;
31839    this.type = type;
31840    this.handler = handler;
31841    this.sourceSpan = sourceSpan;
31842    this.handlerSpan = handlerSpan;
31843    this.keySpan = keySpan;
31844  }
31845
31846}
31847/**
31848 * ParsedVariable represents a variable declaration in a microsyntax expression.
31849 */
31850
31851
31852class ParsedVariable {
31853  constructor(name, value, sourceSpan, keySpan, valueSpan) {
31854    this.name = name;
31855    this.value = value;
31856    this.sourceSpan = sourceSpan;
31857    this.keySpan = keySpan;
31858    this.valueSpan = valueSpan;
31859  }
31860
31861}
31862
31863class BoundElementProperty {
31864  constructor(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan) {
31865    this.name = name;
31866    this.type = type;
31867    this.securityContext = securityContext;
31868    this.value = value;
31869    this.unit = unit;
31870    this.sourceSpan = sourceSpan;
31871    this.keySpan = keySpan;
31872    this.valueSpan = valueSpan;
31873  }
31874
31875}
31876/**
31877 * @license
31878 * Copyright Google LLC All Rights Reserved.
31879 *
31880 * Use of this source code is governed by an MIT-style license that can be
31881 * found in the LICENSE file at https://angular.io/license
31882 */
31883
31884
31885class EventHandlerVars {}
31886
31887EventHandlerVars.event = variable('$event');
31888/**
31889 * Converts the given expression AST into an executable output AST, assuming the expression is
31890 * used in an action binding (e.g. an event handler).
31891 */
31892
31893function convertActionBinding(localResolver, implicitReceiver, action, bindingId, baseSourceSpan, implicitReceiverAccesses, globals) {
31894  if (!localResolver) {
31895    localResolver = new DefaultLocalResolver(globals);
31896  }
31897
31898  const actionWithoutBuiltins = convertPropertyBindingBuiltins({
31899    createLiteralArrayConverter: argCount => {
31900      // Note: no caching for literal arrays in actions.
31901      return args => literalArr(args);
31902    },
31903    createLiteralMapConverter: keys => {
31904      // Note: no caching for literal maps in actions.
31905      return values => {
31906        const entries = keys.map((k, i) => ({
31907          key: k.key,
31908          value: values[i],
31909          quoted: k.quoted
31910        }));
31911        return literalMap(entries);
31912      };
31913    },
31914    createPipeConverter: name => {
31915      throw new Error(`Illegal State: Actions are not allowed to contain pipes. Pipe: ${name}`);
31916    }
31917  }, action);
31918  const visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId,
31919  /* supportsInterpolation */
31920  false, baseSourceSpan, implicitReceiverAccesses);
31921  const actionStmts = [];
31922  flattenStatements(actionWithoutBuiltins.visit(visitor, _Mode.Statement), actionStmts);
31923  prependTemporaryDecls(visitor.temporaryCount, bindingId, actionStmts);
31924
31925  if (visitor.usesImplicitReceiver) {
31926    localResolver.notifyImplicitReceiverUse();
31927  }
31928
31929  const lastIndex = actionStmts.length - 1;
31930
31931  if (lastIndex >= 0) {
31932    const lastStatement = actionStmts[lastIndex]; // Ensure that the value of the last expression statement is returned
31933
31934    if (lastStatement instanceof ExpressionStatement) {
31935      actionStmts[lastIndex] = new ReturnStatement(lastStatement.expr);
31936    }
31937  }
31938
31939  return actionStmts;
31940}
31941
31942function convertPropertyBindingBuiltins(converterFactory, ast) {
31943  return convertBuiltins(converterFactory, ast);
31944}
31945
31946class ConvertPropertyBindingResult {
31947  constructor(stmts, currValExpr) {
31948    this.stmts = stmts;
31949    this.currValExpr = currValExpr;
31950  }
31951
31952}
31953/**
31954 * Converts the given expression AST into an executable output AST, assuming the expression
31955 * is used in property binding. The expression has to be preprocessed via
31956 * `convertPropertyBindingBuiltins`.
31957 */
31958
31959
31960function convertPropertyBinding(localResolver, implicitReceiver, expressionWithoutBuiltins, bindingId) {
31961  if (!localResolver) {
31962    localResolver = new DefaultLocalResolver();
31963  }
31964
31965  const visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId,
31966  /* supportsInterpolation */
31967  false);
31968  const outputExpr = expressionWithoutBuiltins.visit(visitor, _Mode.Expression);
31969  const stmts = getStatementsFromVisitor(visitor, bindingId);
31970
31971  if (visitor.usesImplicitReceiver) {
31972    localResolver.notifyImplicitReceiverUse();
31973  }
31974
31975  return new ConvertPropertyBindingResult(stmts, outputExpr);
31976}
31977/**
31978 * Given some expression, such as a binding or interpolation expression, and a context expression to
31979 * look values up on, visit each facet of the given expression resolving values from the context
31980 * expression such that a list of arguments can be derived from the found values that can be used as
31981 * arguments to an external update instruction.
31982 *
31983 * @param localResolver The resolver to use to look up expressions by name appropriately
31984 * @param contextVariableExpression The expression representing the context variable used to create
31985 * the final argument expressions
31986 * @param expressionWithArgumentsToExtract The expression to visit to figure out what values need to
31987 * be resolved and what arguments list to build.
31988 * @param bindingId A name prefix used to create temporary variable names if they're needed for the
31989 * arguments generated
31990 * @returns An array of expressions that can be passed as arguments to instruction expressions like
31991 * `o.importExpr(R3.propertyInterpolate).callFn(result)`
31992 */
31993
31994
31995function convertUpdateArguments(localResolver, contextVariableExpression, expressionWithArgumentsToExtract, bindingId) {
31996  const visitor = new _AstToIrVisitor(localResolver, contextVariableExpression, bindingId,
31997  /* supportsInterpolation */
31998  true);
31999  const outputExpr = visitor.visitInterpolation(expressionWithArgumentsToExtract, _Mode.Expression);
32000
32001  if (visitor.usesImplicitReceiver) {
32002    localResolver.notifyImplicitReceiverUse();
32003  }
32004
32005  const stmts = getStatementsFromVisitor(visitor, bindingId);
32006  const args = outputExpr.args;
32007  return {
32008    stmts,
32009    args
32010  };
32011}
32012
32013function getStatementsFromVisitor(visitor, bindingId) {
32014  const stmts = [];
32015
32016  for (let i = 0; i < visitor.temporaryCount; i++) {
32017    stmts.push(temporaryDeclaration(bindingId, i));
32018  }
32019
32020  return stmts;
32021}
32022
32023function convertBuiltins(converterFactory, ast) {
32024  const visitor = new _BuiltinAstConverter(converterFactory);
32025  return ast.visit(visitor);
32026}
32027
32028function temporaryName(bindingId, temporaryNumber) {
32029  return `tmp_${bindingId}_${temporaryNumber}`;
32030}
32031
32032function temporaryDeclaration(bindingId, temporaryNumber) {
32033  return new DeclareVarStmt(temporaryName(bindingId, temporaryNumber));
32034}
32035
32036function prependTemporaryDecls(temporaryCount, bindingId, statements) {
32037  for (let i = temporaryCount - 1; i >= 0; i--) {
32038    statements.unshift(temporaryDeclaration(bindingId, i));
32039  }
32040}
32041
32042var _Mode;
32043
32044(function (_Mode) {
32045  _Mode[_Mode["Statement"] = 0] = "Statement";
32046  _Mode[_Mode["Expression"] = 1] = "Expression";
32047})(_Mode || (_Mode = {}));
32048
32049function ensureStatementMode(mode, ast) {
32050  if (mode !== _Mode.Statement) {
32051    throw new Error(`Expected a statement, but saw ${ast}`);
32052  }
32053}
32054
32055function ensureExpressionMode(mode, ast) {
32056  if (mode !== _Mode.Expression) {
32057    throw new Error(`Expected an expression, but saw ${ast}`);
32058  }
32059}
32060
32061function convertToStatementIfNeeded(mode, expr) {
32062  if (mode === _Mode.Statement) {
32063    return expr.toStmt();
32064  } else {
32065    return expr;
32066  }
32067}
32068
32069class _BuiltinAstConverter extends AstTransformer {
32070  constructor(_converterFactory) {
32071    super();
32072    this._converterFactory = _converterFactory;
32073  }
32074
32075  visitPipe(ast, context) {
32076    const args = [ast.exp, ...ast.args].map(ast => ast.visit(this, context));
32077    return new BuiltinFunctionCall(ast.span, ast.sourceSpan, args, this._converterFactory.createPipeConverter(ast.name, args.length));
32078  }
32079
32080  visitLiteralArray(ast, context) {
32081    const args = ast.expressions.map(ast => ast.visit(this, context));
32082    return new BuiltinFunctionCall(ast.span, ast.sourceSpan, args, this._converterFactory.createLiteralArrayConverter(ast.expressions.length));
32083  }
32084
32085  visitLiteralMap(ast, context) {
32086    const args = ast.values.map(ast => ast.visit(this, context));
32087    return new BuiltinFunctionCall(ast.span, ast.sourceSpan, args, this._converterFactory.createLiteralMapConverter(ast.keys));
32088  }
32089
32090}
32091
32092class _AstToIrVisitor {
32093  constructor(_localResolver, _implicitReceiver, bindingId, supportsInterpolation, baseSourceSpan, implicitReceiverAccesses) {
32094    this._localResolver = _localResolver;
32095    this._implicitReceiver = _implicitReceiver;
32096    this.bindingId = bindingId;
32097    this.supportsInterpolation = supportsInterpolation;
32098    this.baseSourceSpan = baseSourceSpan;
32099    this.implicitReceiverAccesses = implicitReceiverAccesses;
32100    this._nodeMap = new Map();
32101    this._resultMap = new Map();
32102    this._currentTemporary = 0;
32103    this.temporaryCount = 0;
32104    this.usesImplicitReceiver = false;
32105  }
32106
32107  visitUnary(ast, mode) {
32108    let op;
32109
32110    switch (ast.operator) {
32111      case '+':
32112        op = UnaryOperator.Plus;
32113        break;
32114
32115      case '-':
32116        op = UnaryOperator.Minus;
32117        break;
32118
32119      default:
32120        throw new Error(`Unsupported operator ${ast.operator}`);
32121    }
32122
32123    return convertToStatementIfNeeded(mode, new UnaryOperatorExpr(op, this._visit(ast.expr, _Mode.Expression), undefined, this.convertSourceSpan(ast.span)));
32124  }
32125
32126  visitBinary(ast, mode) {
32127    let op;
32128
32129    switch (ast.operation) {
32130      case '+':
32131        op = BinaryOperator.Plus;
32132        break;
32133
32134      case '-':
32135        op = BinaryOperator.Minus;
32136        break;
32137
32138      case '*':
32139        op = BinaryOperator.Multiply;
32140        break;
32141
32142      case '/':
32143        op = BinaryOperator.Divide;
32144        break;
32145
32146      case '%':
32147        op = BinaryOperator.Modulo;
32148        break;
32149
32150      case '&&':
32151        op = BinaryOperator.And;
32152        break;
32153
32154      case '||':
32155        op = BinaryOperator.Or;
32156        break;
32157
32158      case '==':
32159        op = BinaryOperator.Equals;
32160        break;
32161
32162      case '!=':
32163        op = BinaryOperator.NotEquals;
32164        break;
32165
32166      case '===':
32167        op = BinaryOperator.Identical;
32168        break;
32169
32170      case '!==':
32171        op = BinaryOperator.NotIdentical;
32172        break;
32173
32174      case '<':
32175        op = BinaryOperator.Lower;
32176        break;
32177
32178      case '>':
32179        op = BinaryOperator.Bigger;
32180        break;
32181
32182      case '<=':
32183        op = BinaryOperator.LowerEquals;
32184        break;
32185
32186      case '>=':
32187        op = BinaryOperator.BiggerEquals;
32188        break;
32189
32190      case '??':
32191        return this.convertNullishCoalesce(ast, mode);
32192
32193      default:
32194        throw new Error(`Unsupported operation ${ast.operation}`);
32195    }
32196
32197    return convertToStatementIfNeeded(mode, new BinaryOperatorExpr(op, this._visit(ast.left, _Mode.Expression), this._visit(ast.right, _Mode.Expression), undefined, this.convertSourceSpan(ast.span)));
32198  }
32199
32200  visitChain(ast, mode) {
32201    ensureStatementMode(mode, ast);
32202    return this.visitAll(ast.expressions, mode);
32203  }
32204
32205  visitConditional(ast, mode) {
32206    const value = this._visit(ast.condition, _Mode.Expression);
32207
32208    return convertToStatementIfNeeded(mode, value.conditional(this._visit(ast.trueExp, _Mode.Expression), this._visit(ast.falseExp, _Mode.Expression), this.convertSourceSpan(ast.span)));
32209  }
32210
32211  visitPipe(ast, mode) {
32212    throw new Error(`Illegal state: Pipes should have been converted into functions. Pipe: ${ast.name}`);
32213  }
32214
32215  visitImplicitReceiver(ast, mode) {
32216    ensureExpressionMode(mode, ast);
32217    this.usesImplicitReceiver = true;
32218    return this._implicitReceiver;
32219  }
32220
32221  visitThisReceiver(ast, mode) {
32222    return this.visitImplicitReceiver(ast, mode);
32223  }
32224
32225  visitInterpolation(ast, mode) {
32226    if (!this.supportsInterpolation) {
32227      throw new Error('Unexpected interpolation');
32228    }
32229
32230    ensureExpressionMode(mode, ast);
32231    let args = [];
32232
32233    for (let i = 0; i < ast.strings.length - 1; i++) {
32234      args.push(literal(ast.strings[i]));
32235      args.push(this._visit(ast.expressions[i], _Mode.Expression));
32236    }
32237
32238    args.push(literal(ast.strings[ast.strings.length - 1])); // If we're dealing with an interpolation of 1 value with an empty prefix and suffix, reduce the
32239    // args returned to just the value, because we're going to pass it to a special instruction.
32240
32241    const strings = ast.strings;
32242
32243    if (strings.length === 2 && strings[0] === '' && strings[1] === '') {
32244      // Single argument interpolate instructions.
32245      args = [args[1]];
32246    } else if (ast.expressions.length >= 9) {
32247      // 9 or more arguments must be passed to the `interpolateV`-style instructions, which accept
32248      // an array of arguments
32249      args = [literalArr(args)];
32250    }
32251
32252    return new InterpolationExpression(args);
32253  }
32254
32255  visitKeyedRead(ast, mode) {
32256    const leftMostSafe = this.leftMostSafeNode(ast);
32257
32258    if (leftMostSafe) {
32259      return this.convertSafeAccess(ast, leftMostSafe, mode);
32260    } else {
32261      return convertToStatementIfNeeded(mode, this._visit(ast.receiver, _Mode.Expression).key(this._visit(ast.key, _Mode.Expression)));
32262    }
32263  }
32264
32265  visitKeyedWrite(ast, mode) {
32266    const obj = this._visit(ast.receiver, _Mode.Expression);
32267
32268    const key = this._visit(ast.key, _Mode.Expression);
32269
32270    const value = this._visit(ast.value, _Mode.Expression);
32271
32272    if (obj === this._implicitReceiver) {
32273      this._localResolver.maybeRestoreView();
32274    }
32275
32276    return convertToStatementIfNeeded(mode, obj.key(key).set(value));
32277  }
32278
32279  visitLiteralArray(ast, mode) {
32280    throw new Error(`Illegal State: literal arrays should have been converted into functions`);
32281  }
32282
32283  visitLiteralMap(ast, mode) {
32284    throw new Error(`Illegal State: literal maps should have been converted into functions`);
32285  }
32286
32287  visitLiteralPrimitive(ast, mode) {
32288    // For literal values of null, undefined, true, or false allow type interference
32289    // to infer the type.
32290    const type = ast.value === null || ast.value === undefined || ast.value === true || ast.value === true ? INFERRED_TYPE : undefined;
32291    return convertToStatementIfNeeded(mode, literal(ast.value, type, this.convertSourceSpan(ast.span)));
32292  }
32293
32294  _getLocal(name, receiver) {
32295    if (this._localResolver.globals?.has(name) && receiver instanceof ThisReceiver) {
32296      return null;
32297    }
32298
32299    return this._localResolver.getLocal(name);
32300  }
32301
32302  visitPrefixNot(ast, mode) {
32303    return convertToStatementIfNeeded(mode, not(this._visit(ast.expression, _Mode.Expression)));
32304  }
32305
32306  visitNonNullAssert(ast, mode) {
32307    return convertToStatementIfNeeded(mode, this._visit(ast.expression, _Mode.Expression));
32308  }
32309
32310  visitPropertyRead(ast, mode) {
32311    const leftMostSafe = this.leftMostSafeNode(ast);
32312
32313    if (leftMostSafe) {
32314      return this.convertSafeAccess(ast, leftMostSafe, mode);
32315    } else {
32316      let result = null;
32317      const prevUsesImplicitReceiver = this.usesImplicitReceiver;
32318
32319      const receiver = this._visit(ast.receiver, _Mode.Expression);
32320
32321      if (receiver === this._implicitReceiver) {
32322        result = this._getLocal(ast.name, ast.receiver);
32323
32324        if (result) {
32325          // Restore the previous "usesImplicitReceiver" state since the implicit
32326          // receiver has been replaced with a resolved local expression.
32327          this.usesImplicitReceiver = prevUsesImplicitReceiver;
32328          this.addImplicitReceiverAccess(ast.name);
32329        }
32330      }
32331
32332      if (result == null) {
32333        result = receiver.prop(ast.name, this.convertSourceSpan(ast.span));
32334      }
32335
32336      return convertToStatementIfNeeded(mode, result);
32337    }
32338  }
32339
32340  visitPropertyWrite(ast, mode) {
32341    const receiver = this._visit(ast.receiver, _Mode.Expression);
32342
32343    const prevUsesImplicitReceiver = this.usesImplicitReceiver;
32344    let varExpr = null;
32345
32346    if (receiver === this._implicitReceiver) {
32347      const localExpr = this._getLocal(ast.name, ast.receiver);
32348
32349      if (localExpr) {
32350        if (localExpr instanceof ReadPropExpr) {
32351          // If the local variable is a property read expression, it's a reference
32352          // to a 'context.property' value and will be used as the target of the
32353          // write expression.
32354          varExpr = localExpr; // Restore the previous "usesImplicitReceiver" state since the implicit
32355          // receiver has been replaced with a resolved local expression.
32356
32357          this.usesImplicitReceiver = prevUsesImplicitReceiver;
32358          this.addImplicitReceiverAccess(ast.name);
32359        } else {
32360          // Otherwise it's an error.
32361          const receiver = ast.name;
32362          const value = ast.value instanceof PropertyRead ? ast.value.name : undefined;
32363          throw new Error(`Cannot assign value "${value}" to template variable "${receiver}". Template variables are read-only.`);
32364        }
32365      }
32366    } // If no local expression could be produced, use the original receiver's
32367    // property as the target.
32368
32369
32370    if (varExpr === null) {
32371      varExpr = receiver.prop(ast.name, this.convertSourceSpan(ast.span));
32372    }
32373
32374    return convertToStatementIfNeeded(mode, varExpr.set(this._visit(ast.value, _Mode.Expression)));
32375  }
32376
32377  visitSafePropertyRead(ast, mode) {
32378    return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode);
32379  }
32380
32381  visitSafeKeyedRead(ast, mode) {
32382    return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode);
32383  }
32384
32385  visitAll(asts, mode) {
32386    return asts.map(ast => this._visit(ast, mode));
32387  }
32388
32389  visitCall(ast, mode) {
32390    const leftMostSafe = this.leftMostSafeNode(ast);
32391
32392    if (leftMostSafe) {
32393      return this.convertSafeAccess(ast, leftMostSafe, mode);
32394    }
32395
32396    const convertedArgs = this.visitAll(ast.args, _Mode.Expression);
32397
32398    if (ast instanceof BuiltinFunctionCall) {
32399      return convertToStatementIfNeeded(mode, ast.converter(convertedArgs));
32400    }
32401
32402    const receiver = ast.receiver;
32403
32404    if (receiver instanceof PropertyRead && receiver.receiver instanceof ImplicitReceiver && !(receiver.receiver instanceof ThisReceiver) && receiver.name === '$any') {
32405      if (convertedArgs.length !== 1) {
32406        throw new Error(`Invalid call to $any, expected 1 argument but received ${convertedArgs.length || 'none'}`);
32407      }
32408
32409      return convertToStatementIfNeeded(mode, convertedArgs[0]);
32410    }
32411
32412    const call = this._visit(receiver, _Mode.Expression).callFn(convertedArgs, this.convertSourceSpan(ast.span));
32413
32414    return convertToStatementIfNeeded(mode, call);
32415  }
32416
32417  visitSafeCall(ast, mode) {
32418    return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode);
32419  }
32420
32421  _visit(ast, mode) {
32422    const result = this._resultMap.get(ast);
32423
32424    if (result) return result;
32425    return (this._nodeMap.get(ast) || ast).visit(this, mode);
32426  }
32427
32428  convertSafeAccess(ast, leftMostSafe, mode) {
32429    // If the expression contains a safe access node on the left it needs to be converted to
32430    // an expression that guards the access to the member by checking the receiver for blank. As
32431    // execution proceeds from left to right, the left most part of the expression must be guarded
32432    // first but, because member access is left associative, the right side of the expression is at
32433    // the top of the AST. The desired result requires lifting a copy of the left part of the
32434    // expression up to test it for blank before generating the unguarded version.
32435    // Consider, for example the following expression: a?.b.c?.d.e
32436    // This results in the ast:
32437    //         .
32438    //        / \
32439    //       ?.   e
32440    //      /  \
32441    //     .    d
32442    //    / \
32443    //   ?.  c
32444    //  /  \
32445    // a    b
32446    // The following tree should be generated:
32447    //
32448    //        /---- ? ----\
32449    //       /      |      \
32450    //     a   /--- ? ---\  null
32451    //        /     |     \
32452    //       .      .     null
32453    //      / \    / \
32454    //     .  c   .   e
32455    //    / \    / \
32456    //   a   b  .   d
32457    //         / \
32458    //        .   c
32459    //       / \
32460    //      a   b
32461    //
32462    // Notice that the first guard condition is the left hand of the left most safe access node
32463    // which comes in as leftMostSafe to this routine.
32464    let guardedExpression = this._visit(leftMostSafe.receiver, _Mode.Expression);
32465
32466    let temporary = undefined;
32467
32468    if (this.needsTemporaryInSafeAccess(leftMostSafe.receiver)) {
32469      // If the expression has method calls or pipes then we need to save the result into a
32470      // temporary variable to avoid calling stateful or impure code more than once.
32471      temporary = this.allocateTemporary(); // Preserve the result in the temporary variable
32472
32473      guardedExpression = temporary.set(guardedExpression); // Ensure all further references to the guarded expression refer to the temporary instead.
32474
32475      this._resultMap.set(leftMostSafe.receiver, temporary);
32476    }
32477
32478    const condition = guardedExpression.isBlank(); // Convert the ast to an unguarded access to the receiver's member. The map will substitute
32479    // leftMostNode with its unguarded version in the call to `this.visit()`.
32480
32481    if (leftMostSafe instanceof SafeCall) {
32482      this._nodeMap.set(leftMostSafe, new Call(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.receiver, leftMostSafe.args, leftMostSafe.argumentSpan));
32483    } else if (leftMostSafe instanceof SafeKeyedRead) {
32484      this._nodeMap.set(leftMostSafe, new KeyedRead(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.receiver, leftMostSafe.key));
32485    } else {
32486      this._nodeMap.set(leftMostSafe, new PropertyRead(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.nameSpan, leftMostSafe.receiver, leftMostSafe.name));
32487    } // Recursively convert the node now without the guarded member access.
32488
32489
32490    const access = this._visit(ast, _Mode.Expression); // Remove the mapping. This is not strictly required as the converter only traverses each node
32491    // once but is safer if the conversion is changed to traverse the nodes more than once.
32492
32493
32494    this._nodeMap.delete(leftMostSafe); // If we allocated a temporary, release it.
32495
32496
32497    if (temporary) {
32498      this.releaseTemporary(temporary);
32499    } // Produce the conditional
32500
32501
32502    return convertToStatementIfNeeded(mode, condition.conditional(NULL_EXPR, access));
32503  }
32504
32505  convertNullishCoalesce(ast, mode) {
32506    const left = this._visit(ast.left, _Mode.Expression);
32507
32508    const right = this._visit(ast.right, _Mode.Expression);
32509
32510    const temporary = this.allocateTemporary();
32511    this.releaseTemporary(temporary); // Generate the following expression. It is identical to how TS
32512    // transpiles binary expressions with a nullish coalescing operator.
32513    // let temp;
32514    // (temp = a) !== null && temp !== undefined ? temp : b;
32515
32516    return convertToStatementIfNeeded(mode, temporary.set(left).notIdentical(NULL_EXPR).and(temporary.notIdentical(literal(undefined))).conditional(temporary, right));
32517  } // Given an expression of the form a?.b.c?.d.e then the left most safe node is
32518  // the (a?.b). The . and ?. are left associative thus can be rewritten as:
32519  // ((((a?.c).b).c)?.d).e. This returns the most deeply nested safe read or
32520  // safe method call as this needs to be transformed initially to:
32521  //   a == null ? null : a.c.b.c?.d.e
32522  // then to:
32523  //   a == null ? null : a.b.c == null ? null : a.b.c.d.e
32524
32525
32526  leftMostSafeNode(ast) {
32527    const visit = (visitor, ast) => {
32528      return (this._nodeMap.get(ast) || ast).visit(visitor);
32529    };
32530
32531    return ast.visit({
32532      visitUnary(ast) {
32533        return null;
32534      },
32535
32536      visitBinary(ast) {
32537        return null;
32538      },
32539
32540      visitChain(ast) {
32541        return null;
32542      },
32543
32544      visitConditional(ast) {
32545        return null;
32546      },
32547
32548      visitCall(ast) {
32549        return visit(this, ast.receiver);
32550      },
32551
32552      visitSafeCall(ast) {
32553        return visit(this, ast.receiver) || ast;
32554      },
32555
32556      visitImplicitReceiver(ast) {
32557        return null;
32558      },
32559
32560      visitThisReceiver(ast) {
32561        return null;
32562      },
32563
32564      visitInterpolation(ast) {
32565        return null;
32566      },
32567
32568      visitKeyedRead(ast) {
32569        return visit(this, ast.receiver);
32570      },
32571
32572      visitKeyedWrite(ast) {
32573        return null;
32574      },
32575
32576      visitLiteralArray(ast) {
32577        return null;
32578      },
32579
32580      visitLiteralMap(ast) {
32581        return null;
32582      },
32583
32584      visitLiteralPrimitive(ast) {
32585        return null;
32586      },
32587
32588      visitPipe(ast) {
32589        return null;
32590      },
32591
32592      visitPrefixNot(ast) {
32593        return null;
32594      },
32595
32596      visitNonNullAssert(ast) {
32597        return null;
32598      },
32599
32600      visitPropertyRead(ast) {
32601        return visit(this, ast.receiver);
32602      },
32603
32604      visitPropertyWrite(ast) {
32605        return null;
32606      },
32607
32608      visitSafePropertyRead(ast) {
32609        return visit(this, ast.receiver) || ast;
32610      },
32611
32612      visitSafeKeyedRead(ast) {
32613        return visit(this, ast.receiver) || ast;
32614      }
32615
32616    });
32617  } // Returns true of the AST includes a method or a pipe indicating that, if the
32618  // expression is used as the target of a safe property or method access then
32619  // the expression should be stored into a temporary variable.
32620
32621
32622  needsTemporaryInSafeAccess(ast) {
32623    const visit = (visitor, ast) => {
32624      return ast && (this._nodeMap.get(ast) || ast).visit(visitor);
32625    };
32626
32627    const visitSome = (visitor, ast) => {
32628      return ast.some(ast => visit(visitor, ast));
32629    };
32630
32631    return ast.visit({
32632      visitUnary(ast) {
32633        return visit(this, ast.expr);
32634      },
32635
32636      visitBinary(ast) {
32637        return visit(this, ast.left) || visit(this, ast.right);
32638      },
32639
32640      visitChain(ast) {
32641        return false;
32642      },
32643
32644      visitConditional(ast) {
32645        return visit(this, ast.condition) || visit(this, ast.trueExp) || visit(this, ast.falseExp);
32646      },
32647
32648      visitCall(ast) {
32649        return true;
32650      },
32651
32652      visitSafeCall(ast) {
32653        return true;
32654      },
32655
32656      visitImplicitReceiver(ast) {
32657        return false;
32658      },
32659
32660      visitThisReceiver(ast) {
32661        return false;
32662      },
32663
32664      visitInterpolation(ast) {
32665        return visitSome(this, ast.expressions);
32666      },
32667
32668      visitKeyedRead(ast) {
32669        return false;
32670      },
32671
32672      visitKeyedWrite(ast) {
32673        return false;
32674      },
32675
32676      visitLiteralArray(ast) {
32677        return true;
32678      },
32679
32680      visitLiteralMap(ast) {
32681        return true;
32682      },
32683
32684      visitLiteralPrimitive(ast) {
32685        return false;
32686      },
32687
32688      visitPipe(ast) {
32689        return true;
32690      },
32691
32692      visitPrefixNot(ast) {
32693        return visit(this, ast.expression);
32694      },
32695
32696      visitNonNullAssert(ast) {
32697        return visit(this, ast.expression);
32698      },
32699
32700      visitPropertyRead(ast) {
32701        return false;
32702      },
32703
32704      visitPropertyWrite(ast) {
32705        return false;
32706      },
32707
32708      visitSafePropertyRead(ast) {
32709        return false;
32710      },
32711
32712      visitSafeKeyedRead(ast) {
32713        return false;
32714      }
32715
32716    });
32717  }
32718
32719  allocateTemporary() {
32720    const tempNumber = this._currentTemporary++;
32721    this.temporaryCount = Math.max(this._currentTemporary, this.temporaryCount);
32722    return new ReadVarExpr(temporaryName(this.bindingId, tempNumber));
32723  }
32724
32725  releaseTemporary(temporary) {
32726    this._currentTemporary--;
32727
32728    if (temporary.name != temporaryName(this.bindingId, this._currentTemporary)) {
32729      throw new Error(`Temporary ${temporary.name} released out of order`);
32730    }
32731  }
32732  /**
32733   * Creates an absolute `ParseSourceSpan` from the relative `ParseSpan`.
32734   *
32735   * `ParseSpan` objects are relative to the start of the expression.
32736   * This method converts these to full `ParseSourceSpan` objects that
32737   * show where the span is within the overall source file.
32738   *
32739   * @param span the relative span to convert.
32740   * @returns a `ParseSourceSpan` for the given span or null if no
32741   * `baseSourceSpan` was provided to this class.
32742   */
32743
32744
32745  convertSourceSpan(span) {
32746    if (this.baseSourceSpan) {
32747      const start = this.baseSourceSpan.start.moveBy(span.start);
32748      const end = this.baseSourceSpan.start.moveBy(span.end);
32749      const fullStart = this.baseSourceSpan.fullStart.moveBy(span.start);
32750      return new ParseSourceSpan(start, end, fullStart);
32751    } else {
32752      return null;
32753    }
32754  }
32755  /** Adds the name of an AST to the list of implicit receiver accesses. */
32756
32757
32758  addImplicitReceiverAccess(name) {
32759    if (this.implicitReceiverAccesses) {
32760      this.implicitReceiverAccesses.add(name);
32761    }
32762  }
32763
32764}
32765
32766function flattenStatements(arg, output) {
32767  if (Array.isArray(arg)) {
32768    arg.forEach(entry => flattenStatements(entry, output));
32769  } else {
32770    output.push(arg);
32771  }
32772}
32773
32774function unsupported() {
32775  throw new Error('Unsupported operation');
32776}
32777
32778class InterpolationExpression extends Expression {
32779  constructor(args) {
32780    super(null, null);
32781    this.args = args;
32782    this.isConstant = unsupported;
32783    this.isEquivalent = unsupported;
32784    this.visitExpression = unsupported;
32785  }
32786
32787}
32788
32789class DefaultLocalResolver {
32790  constructor(globals) {
32791    this.globals = globals;
32792  }
32793
32794  notifyImplicitReceiverUse() {}
32795
32796  maybeRestoreView() {}
32797
32798  getLocal(name) {
32799    if (name === EventHandlerVars.event.name) {
32800      return EventHandlerVars.event;
32801    }
32802
32803    return null;
32804  }
32805
32806}
32807
32808class BuiltinFunctionCall extends Call {
32809  constructor(span, sourceSpan, args, converter) {
32810    super(span, sourceSpan, new EmptyExpr(span, sourceSpan), args, null);
32811    this.converter = converter;
32812  }
32813
32814}
32815/**
32816 * @license
32817 * Copyright Google LLC All Rights Reserved.
32818 *
32819 * Use of this source code is governed by an MIT-style license that can be
32820 * found in the LICENSE file at https://angular.io/license
32821 */
32822
32823/**
32824 * This file is a port of shadowCSS from webcomponents.js to TypeScript.
32825 *
32826 * Please make sure to keep to edits in sync with the source file.
32827 *
32828 * Source:
32829 * https://github.com/webcomponents/webcomponentsjs/blob/4efecd7e0e/src/ShadowCSS/ShadowCSS.js
32830 *
32831 * The original file level comment is reproduced below
32832 */
32833
32834/*
32835  This is a limited shim for ShadowDOM css styling.
32836  https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#styles
32837
32838  The intention here is to support only the styling features which can be
32839  relatively simply implemented. The goal is to allow users to avoid the
32840  most obvious pitfalls and do so without compromising performance significantly.
32841  For ShadowDOM styling that's not covered here, a set of best practices
32842  can be provided that should allow users to accomplish more complex styling.
32843
32844  The following is a list of specific ShadowDOM styling features and a brief
32845  discussion of the approach used to shim.
32846
32847  Shimmed features:
32848
32849  * :host, :host-context: ShadowDOM allows styling of the shadowRoot's host
32850  element using the :host rule. To shim this feature, the :host styles are
32851  reformatted and prefixed with a given scope name and promoted to a
32852  document level stylesheet.
32853  For example, given a scope name of .foo, a rule like this:
32854
32855    :host {
32856        background: red;
32857      }
32858    }
32859
32860  becomes:
32861
32862    .foo {
32863      background: red;
32864    }
32865
32866  * encapsulation: Styles defined within ShadowDOM, apply only to
32867  dom inside the ShadowDOM. Polymer uses one of two techniques to implement
32868  this feature.
32869
32870  By default, rules are prefixed with the host element tag name
32871  as a descendant selector. This ensures styling does not leak out of the 'top'
32872  of the element's ShadowDOM. For example,
32873
32874  div {
32875      font-weight: bold;
32876    }
32877
32878  becomes:
32879
32880  x-foo div {
32881      font-weight: bold;
32882    }
32883
32884  becomes:
32885
32886
32887  Alternatively, if WebComponents.ShadowCSS.strictStyling is set to true then
32888  selectors are scoped by adding an attribute selector suffix to each
32889  simple selector that contains the host element tag name. Each element
32890  in the element's ShadowDOM template is also given the scope attribute.
32891  Thus, these rules match only elements that have the scope attribute.
32892  For example, given a scope name of x-foo, a rule like this:
32893
32894    div {
32895      font-weight: bold;
32896    }
32897
32898  becomes:
32899
32900    div[x-foo] {
32901      font-weight: bold;
32902    }
32903
32904  Note that elements that are dynamically added to a scope must have the scope
32905  selector added to them manually.
32906
32907  * upper/lower bound encapsulation: Styles which are defined outside a
32908  shadowRoot should not cross the ShadowDOM boundary and should not apply
32909  inside a shadowRoot.
32910
32911  This styling behavior is not emulated. Some possible ways to do this that
32912  were rejected due to complexity and/or performance concerns include: (1) reset
32913  every possible property for every possible selector for a given scope name;
32914  (2) re-implement css in javascript.
32915
32916  As an alternative, users should make sure to use selectors
32917  specific to the scope in which they are working.
32918
32919  * ::distributed: This behavior is not emulated. It's often not necessary
32920  to style the contents of a specific insertion point and instead, descendants
32921  of the host element can be styled selectively. Users can also create an
32922  extra node around an insertion point and style that node's contents
32923  via descendent selectors. For example, with a shadowRoot like this:
32924
32925    <style>
32926      ::content(div) {
32927        background: red;
32928      }
32929    </style>
32930    <content></content>
32931
32932  could become:
32933
32934    <style>
32935      / *@polyfill .content-container div * /
32936      ::content(div) {
32937        background: red;
32938      }
32939    </style>
32940    <div class="content-container">
32941      <content></content>
32942    </div>
32943
32944  Note the use of @polyfill in the comment above a ShadowDOM specific style
32945  declaration. This is a directive to the styling shim to use the selector
32946  in comments in lieu of the next selector when running under polyfill.
32947*/
32948
32949
32950class ShadowCss {
32951  constructor() {
32952    this.strictStyling = true;
32953  }
32954  /*
32955   * Shim some cssText with the given selector. Returns cssText that can
32956   * be included in the document via WebComponents.ShadowCSS.addCssToDocument(css).
32957   *
32958   * When strictStyling is true:
32959   * - selector is the attribute added to all elements inside the host,
32960   * - hostSelector is the attribute added to the host itself.
32961   */
32962
32963
32964  shimCssText(cssText, selector, hostSelector = '') {
32965    const commentsWithHash = extractCommentsWithHash(cssText);
32966    cssText = stripComments(cssText);
32967    cssText = this._insertDirectives(cssText);
32968
32969    const scopedCssText = this._scopeCssText(cssText, selector, hostSelector);
32970
32971    return [scopedCssText, ...commentsWithHash].join('\n');
32972  }
32973
32974  _insertDirectives(cssText) {
32975    cssText = this._insertPolyfillDirectivesInCssText(cssText);
32976    return this._insertPolyfillRulesInCssText(cssText);
32977  }
32978  /*
32979   * Process styles to convert native ShadowDOM rules that will trip
32980   * up the css parser; we rely on decorating the stylesheet with inert rules.
32981   *
32982   * For example, we convert this rule:
32983   *
32984   * polyfill-next-selector { content: ':host menu-item'; }
32985   * ::content menu-item {
32986   *
32987   * to this:
32988   *
32989   * scopeName menu-item {
32990   *
32991   **/
32992
32993
32994  _insertPolyfillDirectivesInCssText(cssText) {
32995    // Difference with webcomponents.js: does not handle comments
32996    return cssText.replace(_cssContentNextSelectorRe, function (...m) {
32997      return m[2] + '{';
32998    });
32999  }
33000  /*
33001   * Process styles to add rules which will only apply under the polyfill
33002   *
33003   * For example, we convert this rule:
33004   *
33005   * polyfill-rule {
33006   *   content: ':host menu-item';
33007   * ...
33008   * }
33009   *
33010   * to this:
33011   *
33012   * scopeName menu-item {...}
33013   *
33014   **/
33015
33016
33017  _insertPolyfillRulesInCssText(cssText) {
33018    // Difference with webcomponents.js: does not handle comments
33019    return cssText.replace(_cssContentRuleRe, (...m) => {
33020      const rule = m[0].replace(m[1], '').replace(m[2], '');
33021      return m[4] + rule;
33022    });
33023  }
33024  /* Ensure styles are scoped. Pseudo-scoping takes a rule like:
33025   *
33026   *  .foo {... }
33027   *
33028   *  and converts this to
33029   *
33030   *  scopeName .foo { ... }
33031   */
33032
33033
33034  _scopeCssText(cssText, scopeSelector, hostSelector) {
33035    const unscopedRules = this._extractUnscopedRulesFromCssText(cssText); // replace :host and :host-context -shadowcsshost and -shadowcsshost respectively
33036
33037
33038    cssText = this._insertPolyfillHostInCssText(cssText);
33039    cssText = this._convertColonHost(cssText);
33040    cssText = this._convertColonHostContext(cssText);
33041    cssText = this._convertShadowDOMSelectors(cssText);
33042
33043    if (scopeSelector) {
33044      cssText = this._scopeSelectors(cssText, scopeSelector, hostSelector);
33045    }
33046
33047    cssText = cssText + '\n' + unscopedRules;
33048    return cssText.trim();
33049  }
33050  /*
33051   * Process styles to add rules which will only apply under the polyfill
33052   * and do not process via CSSOM. (CSSOM is destructive to rules on rare
33053   * occasions, e.g. -webkit-calc on Safari.)
33054   * For example, we convert this rule:
33055   *
33056   * @polyfill-unscoped-rule {
33057   *   content: 'menu-item';
33058   * ... }
33059   *
33060   * to this:
33061   *
33062   * menu-item {...}
33063   *
33064   **/
33065
33066
33067  _extractUnscopedRulesFromCssText(cssText) {
33068    // Difference with webcomponents.js: does not handle comments
33069    let r = '';
33070    let m;
33071    _cssContentUnscopedRuleRe.lastIndex = 0;
33072
33073    while ((m = _cssContentUnscopedRuleRe.exec(cssText)) !== null) {
33074      const rule = m[0].replace(m[2], '').replace(m[1], m[4]);
33075      r += rule + '\n\n';
33076    }
33077
33078    return r;
33079  }
33080  /*
33081   * convert a rule like :host(.foo) > .bar { }
33082   *
33083   * to
33084   *
33085   * .foo<scopeName> > .bar
33086   */
33087
33088
33089  _convertColonHost(cssText) {
33090    return cssText.replace(_cssColonHostRe, (_, hostSelectors, otherSelectors) => {
33091      if (hostSelectors) {
33092        const convertedSelectors = [];
33093        const hostSelectorArray = hostSelectors.split(',').map(p => p.trim());
33094
33095        for (const hostSelector of hostSelectorArray) {
33096          if (!hostSelector) break;
33097          const convertedSelector = _polyfillHostNoCombinator + hostSelector.replace(_polyfillHost, '') + otherSelectors;
33098          convertedSelectors.push(convertedSelector);
33099        }
33100
33101        return convertedSelectors.join(',');
33102      } else {
33103        return _polyfillHostNoCombinator + otherSelectors;
33104      }
33105    });
33106  }
33107  /*
33108   * convert a rule like :host-context(.foo) > .bar { }
33109   *
33110   * to
33111   *
33112   * .foo<scopeName> > .bar, .foo <scopeName> > .bar { }
33113   *
33114   * and
33115   *
33116   * :host-context(.foo:host) .bar { ... }
33117   *
33118   * to
33119   *
33120   * .foo<scopeName> .bar { ... }
33121   */
33122
33123
33124  _convertColonHostContext(cssText) {
33125    return cssText.replace(_cssColonHostContextReGlobal, selectorText => {
33126      // We have captured a selector that contains a `:host-context` rule.
33127      // For backward compatibility `:host-context` may contain a comma separated list of selectors.
33128      // Each context selector group will contain a list of host-context selectors that must match
33129      // an ancestor of the host.
33130      // (Normally `contextSelectorGroups` will only contain a single array of context selectors.)
33131      const contextSelectorGroups = [[]]; // There may be more than `:host-context` in this selector so `selectorText` could look like:
33132      // `:host-context(.one):host-context(.two)`.
33133      // Execute `_cssColonHostContextRe` over and over until we have extracted all the
33134      // `:host-context` selectors from this selector.
33135
33136      let match;
33137
33138      while (match = _cssColonHostContextRe.exec(selectorText)) {
33139        // `match` = [':host-context(<selectors>)<rest>', <selectors>, <rest>]
33140        // The `<selectors>` could actually be a comma separated list: `:host-context(.one, .two)`.
33141        const newContextSelectors = (match[1] ?? '').trim().split(',').map(m => m.trim()).filter(m => m !== ''); // We must duplicate the current selector group for each of these new selectors.
33142        // For example if the current groups are:
33143        // ```
33144        // [
33145        //   ['a', 'b', 'c'],
33146        //   ['x', 'y', 'z'],
33147        // ]
33148        // ```
33149        // And we have a new set of comma separated selectors: `:host-context(m,n)` then the new
33150        // groups are:
33151        // ```
33152        // [
33153        //   ['a', 'b', 'c', 'm'],
33154        //   ['x', 'y', 'z', 'm'],
33155        //   ['a', 'b', 'c', 'n'],
33156        //   ['x', 'y', 'z', 'n'],
33157        // ]
33158        // ```
33159
33160        const contextSelectorGroupsLength = contextSelectorGroups.length;
33161        repeatGroups(contextSelectorGroups, newContextSelectors.length);
33162
33163        for (let i = 0; i < newContextSelectors.length; i++) {
33164          for (let j = 0; j < contextSelectorGroupsLength; j++) {
33165            contextSelectorGroups[j + i * contextSelectorGroupsLength].push(newContextSelectors[i]);
33166          }
33167        } // Update the `selectorText` and see repeat to see if there are more `:host-context`s.
33168
33169
33170        selectorText = match[2];
33171      } // The context selectors now must be combined with each other to capture all the possible
33172      // selectors that `:host-context` can match. See `combineHostContextSelectors()` for more
33173      // info about how this is done.
33174
33175
33176      return contextSelectorGroups.map(contextSelectors => combineHostContextSelectors(contextSelectors, selectorText)).join(', ');
33177    });
33178  }
33179  /*
33180   * Convert combinators like ::shadow and pseudo-elements like ::content
33181   * by replacing with space.
33182   */
33183
33184
33185  _convertShadowDOMSelectors(cssText) {
33186    return _shadowDOMSelectorsRe.reduce((result, pattern) => result.replace(pattern, ' '), cssText);
33187  } // change a selector like 'div' to 'name div'
33188
33189
33190  _scopeSelectors(cssText, scopeSelector, hostSelector) {
33191    return processRules(cssText, rule => {
33192      let selector = rule.selector;
33193      let content = rule.content;
33194
33195      if (rule.selector[0] !== '@') {
33196        selector = this._scopeSelector(rule.selector, scopeSelector, hostSelector, this.strictStyling);
33197      } else if (rule.selector.startsWith('@media') || rule.selector.startsWith('@supports') || rule.selector.startsWith('@document') || rule.selector.startsWith('@layer')) {
33198        content = this._scopeSelectors(rule.content, scopeSelector, hostSelector);
33199      } else if (rule.selector.startsWith('@font-face') || rule.selector.startsWith('@page')) {
33200        content = this._stripScopingSelectors(rule.content);
33201      }
33202
33203      return new CssRule(selector, content);
33204    });
33205  }
33206  /**
33207   * Handle a css text that is within a rule that should not contain scope selectors by simply
33208   * removing them! An example of such a rule is `@font-face`.
33209   *
33210   * `@font-face` rules cannot contain nested selectors. Nor can they be nested under a selector.
33211   * Normally this would be a syntax error by the author of the styles. But in some rare cases, such
33212   * as importing styles from a library, and applying `:host ::ng-deep` to the imported styles, we
33213   * can end up with broken css if the imported styles happen to contain @font-face rules.
33214   *
33215   * For example:
33216   *
33217   * ```
33218   * :host ::ng-deep {
33219   *   import 'some/lib/containing/font-face';
33220   * }
33221   *
33222   * Similar logic applies to `@page` rules which can contain a particular set of properties,
33223   * as well as some specific at-rules. Since they can't be encapsulated, we have to strip
33224   * any scoping selectors from them. For more information: https://www.w3.org/TR/css-page-3
33225   * ```
33226   */
33227
33228
33229  _stripScopingSelectors(cssText) {
33230    return processRules(cssText, rule => {
33231      const selector = rule.selector.replace(_shadowDeepSelectors, ' ').replace(_polyfillHostNoCombinatorRe, ' ');
33232      return new CssRule(selector, rule.content);
33233    });
33234  }
33235
33236  _scopeSelector(selector, scopeSelector, hostSelector, strict) {
33237    return selector.split(',').map(part => part.trim().split(_shadowDeepSelectors)).map(deepParts => {
33238      const [shallowPart, ...otherParts] = deepParts;
33239
33240      const applyScope = shallowPart => {
33241        if (this._selectorNeedsScoping(shallowPart, scopeSelector)) {
33242          return strict ? this._applyStrictSelectorScope(shallowPart, scopeSelector, hostSelector) : this._applySelectorScope(shallowPart, scopeSelector, hostSelector);
33243        } else {
33244          return shallowPart;
33245        }
33246      };
33247
33248      return [applyScope(shallowPart), ...otherParts].join(' ');
33249    }).join(', ');
33250  }
33251
33252  _selectorNeedsScoping(selector, scopeSelector) {
33253    const re = this._makeScopeMatcher(scopeSelector);
33254
33255    return !re.test(selector);
33256  }
33257
33258  _makeScopeMatcher(scopeSelector) {
33259    const lre = /\[/g;
33260    const rre = /\]/g;
33261    scopeSelector = scopeSelector.replace(lre, '\\[').replace(rre, '\\]');
33262    return new RegExp('^(' + scopeSelector + ')' + _selectorReSuffix, 'm');
33263  }
33264
33265  _applySelectorScope(selector, scopeSelector, hostSelector) {
33266    // Difference from webcomponents.js: scopeSelector could not be an array
33267    return this._applySimpleSelectorScope(selector, scopeSelector, hostSelector);
33268  } // scope via name and [is=name]
33269
33270
33271  _applySimpleSelectorScope(selector, scopeSelector, hostSelector) {
33272    // In Android browser, the lastIndex is not reset when the regex is used in String.replace()
33273    _polyfillHostRe.lastIndex = 0;
33274
33275    if (_polyfillHostRe.test(selector)) {
33276      const replaceBy = this.strictStyling ? `[${hostSelector}]` : scopeSelector;
33277      return selector.replace(_polyfillHostNoCombinatorRe, (hnc, selector) => {
33278        return selector.replace(/([^:]*)(:*)(.*)/, (_, before, colon, after) => {
33279          return before + replaceBy + colon + after;
33280        });
33281      }).replace(_polyfillHostRe, replaceBy + ' ');
33282    }
33283
33284    return scopeSelector + ' ' + selector;
33285  } // return a selector with [name] suffix on each simple selector
33286  // e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name]  /** @internal */
33287
33288
33289  _applyStrictSelectorScope(selector, scopeSelector, hostSelector) {
33290    const isRe = /\[is=([^\]]*)\]/g;
33291    scopeSelector = scopeSelector.replace(isRe, (_, ...parts) => parts[0]);
33292    const attrName = '[' + scopeSelector + ']';
33293
33294    const _scopeSelectorPart = p => {
33295      let scopedP = p.trim();
33296
33297      if (!scopedP) {
33298        return '';
33299      }
33300
33301      if (p.indexOf(_polyfillHostNoCombinator) > -1) {
33302        scopedP = this._applySimpleSelectorScope(p, scopeSelector, hostSelector);
33303      } else {
33304        // remove :host since it should be unnecessary
33305        const t = p.replace(_polyfillHostRe, '');
33306
33307        if (t.length > 0) {
33308          const matches = t.match(/([^:]*)(:*)(.*)/);
33309
33310          if (matches) {
33311            scopedP = matches[1] + attrName + matches[2] + matches[3];
33312          }
33313        }
33314      }
33315
33316      return scopedP;
33317    };
33318
33319    const safeContent = new SafeSelector(selector);
33320    selector = safeContent.content();
33321    let scopedSelector = '';
33322    let startIndex = 0;
33323    let res;
33324    const sep = /( |>|\+|~(?!=))\s*/g; // If a selector appears before :host it should not be shimmed as it
33325    // matches on ancestor elements and not on elements in the host's shadow
33326    // `:host-context(div)` is transformed to
33327    // `-shadowcsshost-no-combinatordiv, div -shadowcsshost-no-combinator`
33328    // the `div` is not part of the component in the 2nd selectors and should not be scoped.
33329    // Historically `component-tag:host` was matching the component so we also want to preserve
33330    // this behavior to avoid breaking legacy apps (it should not match).
33331    // The behavior should be:
33332    // - `tag:host` -> `tag[h]` (this is to avoid breaking legacy apps, should not match anything)
33333    // - `tag :host` -> `tag [h]` (`tag` is not scoped because it's considered part of a
33334    //   `:host-context(tag)`)
33335
33336    const hasHost = selector.indexOf(_polyfillHostNoCombinator) > -1; // Only scope parts after the first `-shadowcsshost-no-combinator` when it is present
33337
33338    let shouldScope = !hasHost;
33339
33340    while ((res = sep.exec(selector)) !== null) {
33341      const separator = res[1];
33342      const part = selector.slice(startIndex, res.index).trim();
33343      shouldScope = shouldScope || part.indexOf(_polyfillHostNoCombinator) > -1;
33344      const scopedPart = shouldScope ? _scopeSelectorPart(part) : part;
33345      scopedSelector += `${scopedPart} ${separator} `;
33346      startIndex = sep.lastIndex;
33347    }
33348
33349    const part = selector.substring(startIndex);
33350    shouldScope = shouldScope || part.indexOf(_polyfillHostNoCombinator) > -1;
33351    scopedSelector += shouldScope ? _scopeSelectorPart(part) : part; // replace the placeholders with their original values
33352
33353    return safeContent.restore(scopedSelector);
33354  }
33355
33356  _insertPolyfillHostInCssText(selector) {
33357    return selector.replace(_colonHostContextRe, _polyfillHostContext).replace(_colonHostRe, _polyfillHost);
33358  }
33359
33360}
33361
33362class SafeSelector {
33363  constructor(selector) {
33364    this.placeholders = [];
33365    this.index = 0; // Replaces attribute selectors with placeholders.
33366    // The WS in [attr="va lue"] would otherwise be interpreted as a selector separator.
33367
33368    selector = this._escapeRegexMatches(selector, /(\[[^\]]*\])/g); // CSS allows for certain special characters to be used in selectors if they're escaped.
33369    // E.g. `.foo:blue` won't match a class called `foo:blue`, because the colon denotes a
33370    // pseudo-class, but writing `.foo\:blue` will match, because the colon was escaped.
33371    // Replace all escape sequences (`\` followed by a character) with a placeholder so
33372    // that our handling of pseudo-selectors doesn't mess with them.
33373
33374    selector = this._escapeRegexMatches(selector, /(\\.)/g); // Replaces the expression in `:nth-child(2n + 1)` with a placeholder.
33375    // WS and "+" would otherwise be interpreted as selector separators.
33376
33377    this._content = selector.replace(/(:nth-[-\w]+)(\([^)]+\))/g, (_, pseudo, exp) => {
33378      const replaceBy = `__ph-${this.index}__`;
33379      this.placeholders.push(exp);
33380      this.index++;
33381      return pseudo + replaceBy;
33382    });
33383  }
33384
33385  restore(content) {
33386    return content.replace(/__ph-(\d+)__/g, (_ph, index) => this.placeholders[+index]);
33387  }
33388
33389  content() {
33390    return this._content;
33391  }
33392  /**
33393   * Replaces all of the substrings that match a regex within a
33394   * special string (e.g. `__ph-0__`, `__ph-1__`, etc).
33395   */
33396
33397
33398  _escapeRegexMatches(content, pattern) {
33399    return content.replace(pattern, (_, keep) => {
33400      const replaceBy = `__ph-${this.index}__`;
33401      this.placeholders.push(keep);
33402      this.index++;
33403      return replaceBy;
33404    });
33405  }
33406
33407}
33408
33409const _cssContentNextSelectorRe = /polyfill-next-selector[^}]*content:[\s]*?(['"])(.*?)\1[;\s]*}([^{]*?){/gim;
33410const _cssContentRuleRe = /(polyfill-rule)[^}]*(content:[\s]*(['"])(.*?)\3)[;\s]*[^}]*}/gim;
33411const _cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content:[\s]*(['"])(.*?)\3)[;\s]*[^}]*}/gim;
33412const _polyfillHost = '-shadowcsshost'; // note: :host-context pre-processed to -shadowcsshostcontext.
33413
33414const _polyfillHostContext = '-shadowcsscontext';
33415
33416const _parenSuffix = '(?:\\((' + '(?:\\([^)(]*\\)|[^)(]*)+?' + ')\\))?([^,{]*)';
33417
33418const _cssColonHostRe = new RegExp(_polyfillHost + _parenSuffix, 'gim');
33419
33420const _cssColonHostContextReGlobal = new RegExp(_polyfillHostContext + _parenSuffix, 'gim');
33421
33422const _cssColonHostContextRe = new RegExp(_polyfillHostContext + _parenSuffix, 'im');
33423
33424const _polyfillHostNoCombinator = _polyfillHost + '-no-combinator';
33425
33426const _polyfillHostNoCombinatorRe = /-shadowcsshost-no-combinator([^\s]*)/;
33427const _shadowDOMSelectorsRe = [/::shadow/g, /::content/g, // Deprecated selectors
33428/\/shadow-deep\//g, /\/shadow\//g]; // The deep combinator is deprecated in the CSS spec
33429// Support for `>>>`, `deep`, `::ng-deep` is then also deprecated and will be removed in the future.
33430// see https://github.com/angular/angular/pull/17677
33431
33432const _shadowDeepSelectors = /(?:>>>)|(?:\/deep\/)|(?:::ng-deep)/g;
33433const _selectorReSuffix = '([>\\s~+[.,{:][\\s\\S]*)?$';
33434const _polyfillHostRe = /-shadowcsshost/gim;
33435const _colonHostRe = /:host/gim;
33436const _colonHostContextRe = /:host-context/gim;
33437const _commentRe = /\/\*[\s\S]*?\*\//g;
33438
33439function stripComments(input) {
33440  return input.replace(_commentRe, '');
33441}
33442
33443const _commentWithHashRe = /\/\*\s*#\s*source(Mapping)?URL=[\s\S]+?\*\//g;
33444
33445function extractCommentsWithHash(input) {
33446  return input.match(_commentWithHashRe) || [];
33447}
33448
33449const BLOCK_PLACEHOLDER = '%BLOCK%';
33450const QUOTE_PLACEHOLDER = '%QUOTED%';
33451const _ruleRe = /(\s*)([^;\{\}]+?)(\s*)((?:{%BLOCK%}?\s*;?)|(?:\s*;))/g;
33452const _quotedRe = /%QUOTED%/g;
33453const CONTENT_PAIRS = new Map([['{', '}']]);
33454const QUOTE_PAIRS = new Map([[`"`, `"`], [`'`, `'`]]);
33455
33456class CssRule {
33457  constructor(selector, content) {
33458    this.selector = selector;
33459    this.content = content;
33460  }
33461
33462}
33463
33464function processRules(input, ruleCallback) {
33465  const inputWithEscapedQuotes = escapeBlocks(input, QUOTE_PAIRS, QUOTE_PLACEHOLDER);
33466  const inputWithEscapedBlocks = escapeBlocks(inputWithEscapedQuotes.escapedString, CONTENT_PAIRS, BLOCK_PLACEHOLDER);
33467  let nextBlockIndex = 0;
33468  let nextQuoteIndex = 0;
33469  return inputWithEscapedBlocks.escapedString.replace(_ruleRe, (...m) => {
33470    const selector = m[2];
33471    let content = '';
33472    let suffix = m[4];
33473    let contentPrefix = '';
33474
33475    if (suffix && suffix.startsWith('{' + BLOCK_PLACEHOLDER)) {
33476      content = inputWithEscapedBlocks.blocks[nextBlockIndex++];
33477      suffix = suffix.substring(BLOCK_PLACEHOLDER.length + 1);
33478      contentPrefix = '{';
33479    }
33480
33481    const rule = ruleCallback(new CssRule(selector, content));
33482    return `${m[1]}${rule.selector}${m[3]}${contentPrefix}${rule.content}${suffix}`;
33483  }).replace(_quotedRe, () => inputWithEscapedQuotes.blocks[nextQuoteIndex++]);
33484}
33485
33486class StringWithEscapedBlocks {
33487  constructor(escapedString, blocks) {
33488    this.escapedString = escapedString;
33489    this.blocks = blocks;
33490  }
33491
33492}
33493
33494function escapeBlocks(input, charPairs, placeholder) {
33495  const resultParts = [];
33496  const escapedBlocks = [];
33497  let openCharCount = 0;
33498  let nonBlockStartIndex = 0;
33499  let blockStartIndex = -1;
33500  let openChar;
33501  let closeChar;
33502
33503  for (let i = 0; i < input.length; i++) {
33504    const char = input[i];
33505
33506    if (char === '\\') {
33507      i++;
33508    } else if (char === closeChar) {
33509      openCharCount--;
33510
33511      if (openCharCount === 0) {
33512        escapedBlocks.push(input.substring(blockStartIndex, i));
33513        resultParts.push(placeholder);
33514        nonBlockStartIndex = i;
33515        blockStartIndex = -1;
33516        openChar = closeChar = undefined;
33517      }
33518    } else if (char === openChar) {
33519      openCharCount++;
33520    } else if (openCharCount === 0 && charPairs.has(char)) {
33521      openChar = char;
33522      closeChar = charPairs.get(char);
33523      openCharCount = 1;
33524      blockStartIndex = i + 1;
33525      resultParts.push(input.substring(nonBlockStartIndex, blockStartIndex));
33526    }
33527  }
33528
33529  if (blockStartIndex !== -1) {
33530    escapedBlocks.push(input.substring(blockStartIndex));
33531    resultParts.push(placeholder);
33532  } else {
33533    resultParts.push(input.substring(nonBlockStartIndex));
33534  }
33535
33536  return new StringWithEscapedBlocks(resultParts.join(''), escapedBlocks);
33537}
33538/**
33539 * Combine the `contextSelectors` with the `hostMarker` and the `otherSelectors`
33540 * to create a selector that matches the same as `:host-context()`.
33541 *
33542 * Given a single context selector `A` we need to output selectors that match on the host and as an
33543 * ancestor of the host:
33544 *
33545 * ```
33546 * A <hostMarker>, A<hostMarker> {}
33547 * ```
33548 *
33549 * When there is more than one context selector we also have to create combinations of those
33550 * selectors with each other. For example if there are `A` and `B` selectors the output is:
33551 *
33552 * ```
33553 * AB<hostMarker>, AB <hostMarker>, A B<hostMarker>,
33554 * B A<hostMarker>, A B <hostMarker>, B A <hostMarker> {}
33555 * ```
33556 *
33557 * And so on...
33558 *
33559 * @param hostMarker the string that selects the host element.
33560 * @param contextSelectors an array of context selectors that will be combined.
33561 * @param otherSelectors the rest of the selectors that are not context selectors.
33562 */
33563
33564
33565function combineHostContextSelectors(contextSelectors, otherSelectors) {
33566  const hostMarker = _polyfillHostNoCombinator;
33567  _polyfillHostRe.lastIndex = 0; // reset the regex to ensure we get an accurate test
33568
33569  const otherSelectorsHasHost = _polyfillHostRe.test(otherSelectors); // If there are no context selectors then just output a host marker
33570
33571
33572  if (contextSelectors.length === 0) {
33573    return hostMarker + otherSelectors;
33574  }
33575
33576  const combined = [contextSelectors.pop() || ''];
33577
33578  while (contextSelectors.length > 0) {
33579    const length = combined.length;
33580    const contextSelector = contextSelectors.pop();
33581
33582    for (let i = 0; i < length; i++) {
33583      const previousSelectors = combined[i]; // Add the new selector as a descendant of the previous selectors
33584
33585      combined[length * 2 + i] = previousSelectors + ' ' + contextSelector; // Add the new selector as an ancestor of the previous selectors
33586
33587      combined[length + i] = contextSelector + ' ' + previousSelectors; // Add the new selector to act on the same element as the previous selectors
33588
33589      combined[i] = contextSelector + previousSelectors;
33590    }
33591  } // Finally connect the selector to the `hostMarker`s: either acting directly on the host
33592  // (A<hostMarker>) or as an ancestor (A <hostMarker>).
33593
33594
33595  return combined.map(s => otherSelectorsHasHost ? `${s}${otherSelectors}` : `${s}${hostMarker}${otherSelectors}, ${s} ${hostMarker}${otherSelectors}`).join(',');
33596}
33597/**
33598 * Mutate the given `groups` array so that there are `multiples` clones of the original array
33599 * stored.
33600 *
33601 * For example `repeatGroups([a, b], 3)` will result in `[a, b, a, b, a, b]` - but importantly the
33602 * newly added groups will be clones of the original.
33603 *
33604 * @param groups An array of groups of strings that will be repeated. This array is mutated
33605 *     in-place.
33606 * @param multiples The number of times the current groups should appear.
33607 */
33608
33609
33610function repeatGroups(groups, multiples) {
33611  const length = groups.length;
33612
33613  for (let i = 1; i < multiples; i++) {
33614    for (let j = 0; j < length; j++) {
33615      groups[j + i * length] = groups[j].slice(0);
33616    }
33617  }
33618}
33619/**
33620 * @license
33621 * Copyright Google LLC All Rights Reserved.
33622 *
33623 * Use of this source code is governed by an MIT-style license that can be
33624 * found in the LICENSE file at https://angular.io/license
33625 */
33626
33627/**
33628 * Parses string representation of a style and converts it into object literal.
33629 *
33630 * @param value string representation of style as used in the `style` attribute in HTML.
33631 *   Example: `color: red; height: auto`.
33632 * @returns An array of style property name and value pairs, e.g. `['color', 'red', 'height',
33633 * 'auto']`
33634 */
33635
33636
33637function parse(value) {
33638  // we use a string array here instead of a string map
33639  // because a string-map is not guaranteed to retain the
33640  // order of the entries whereas a string array can be
33641  // constructed in a [key, value, key, value] format.
33642  const styles = [];
33643  let i = 0;
33644  let parenDepth = 0;
33645  let quote = 0
33646  /* Char.QuoteNone */
33647  ;
33648  let valueStart = 0;
33649  let propStart = 0;
33650  let currentProp = null;
33651  let valueHasQuotes = false;
33652
33653  while (i < value.length) {
33654    const token = value.charCodeAt(i++);
33655
33656    switch (token) {
33657      case 40
33658      /* Char.OpenParen */
33659      :
33660        parenDepth++;
33661        break;
33662
33663      case 41
33664      /* Char.CloseParen */
33665      :
33666        parenDepth--;
33667        break;
33668
33669      case 39
33670      /* Char.QuoteSingle */
33671      :
33672        // valueStart needs to be there since prop values don't
33673        // have quotes in CSS
33674        valueHasQuotes = valueHasQuotes || valueStart > 0;
33675
33676        if (quote === 0
33677        /* Char.QuoteNone */
33678        ) {
33679          quote = 39
33680          /* Char.QuoteSingle */
33681          ;
33682        } else if (quote === 39
33683        /* Char.QuoteSingle */
33684        && value.charCodeAt(i - 1) !== 92
33685        /* Char.BackSlash */
33686        ) {
33687          quote = 0
33688          /* Char.QuoteNone */
33689          ;
33690        }
33691
33692        break;
33693
33694      case 34
33695      /* Char.QuoteDouble */
33696      :
33697        // same logic as above
33698        valueHasQuotes = valueHasQuotes || valueStart > 0;
33699
33700        if (quote === 0
33701        /* Char.QuoteNone */
33702        ) {
33703          quote = 34
33704          /* Char.QuoteDouble */
33705          ;
33706        } else if (quote === 34
33707        /* Char.QuoteDouble */
33708        && value.charCodeAt(i - 1) !== 92
33709        /* Char.BackSlash */
33710        ) {
33711          quote = 0
33712          /* Char.QuoteNone */
33713          ;
33714        }
33715
33716        break;
33717
33718      case 58
33719      /* Char.Colon */
33720      :
33721        if (!currentProp && parenDepth === 0 && quote === 0
33722        /* Char.QuoteNone */
33723        ) {
33724          currentProp = hyphenate(value.substring(propStart, i - 1).trim());
33725          valueStart = i;
33726        }
33727
33728        break;
33729
33730      case 59
33731      /* Char.Semicolon */
33732      :
33733        if (currentProp && valueStart > 0 && parenDepth === 0 && quote === 0
33734        /* Char.QuoteNone */
33735        ) {
33736          const styleVal = value.substring(valueStart, i - 1).trim();
33737          styles.push(currentProp, valueHasQuotes ? stripUnnecessaryQuotes(styleVal) : styleVal);
33738          propStart = i;
33739          valueStart = 0;
33740          currentProp = null;
33741          valueHasQuotes = false;
33742        }
33743
33744        break;
33745    }
33746  }
33747
33748  if (currentProp && valueStart) {
33749    const styleVal = value.slice(valueStart).trim();
33750    styles.push(currentProp, valueHasQuotes ? stripUnnecessaryQuotes(styleVal) : styleVal);
33751  }
33752
33753  return styles;
33754}
33755
33756function stripUnnecessaryQuotes(value) {
33757  const qS = value.charCodeAt(0);
33758  const qE = value.charCodeAt(value.length - 1);
33759
33760  if (qS == qE && (qS == 39
33761  /* Char.QuoteSingle */
33762  || qS == 34
33763  /* Char.QuoteDouble */
33764  )) {
33765    const tempValue = value.substring(1, value.length - 1); // special case to avoid using a multi-quoted string that was just chomped
33766    // (e.g. `font-family: "Verdana", "sans-serif"`)
33767
33768    if (tempValue.indexOf('\'') == -1 && tempValue.indexOf('"') == -1) {
33769      value = tempValue;
33770    }
33771  }
33772
33773  return value;
33774}
33775
33776function hyphenate(value) {
33777  return value.replace(/[a-z][A-Z]/g, v => {
33778    return v.charAt(0) + '-' + v.charAt(1);
33779  }).toLowerCase();
33780}
33781
33782const IMPORTANT_FLAG = '!important';
33783/**
33784 * Minimum amount of binding slots required in the runtime for style/class bindings.
33785 *
33786 * Styling in Angular uses up two slots in the runtime LView/TData data structures to
33787 * record binding data, property information and metadata.
33788 *
33789 * When a binding is registered it will place the following information in the `LView`:
33790 *
33791 * slot 1) binding value
33792 * slot 2) cached value (all other values collected before it in string form)
33793 *
33794 * When a binding is registered it will place the following information in the `TData`:
33795 *
33796 * slot 1) prop name
33797 * slot 2) binding index that points to the previous style/class binding (and some extra config
33798 * values)
33799 *
33800 * Let's imagine we have a binding that looks like so:
33801 *
33802 * ```
33803 * <div [style.width]="x" [style.height]="y">
33804 * ```
33805 *
33806 * Our `LView` and `TData` data-structures look like so:
33807 *
33808 * ```typescript
33809 * LView = [
33810 *   // ...
33811 *   x, // value of x
33812 *   "width: x",
33813 *
33814 *   y, // value of y
33815 *   "width: x; height: y",
33816 *   // ...
33817 * ];
33818 *
33819 * TData = [
33820 *   // ...
33821 *   "width", // binding slot 20
33822 *   0,
33823 *
33824 *   "height",
33825 *   20,
33826 *   // ...
33827 * ];
33828 * ```
33829 *
33830 * */
33831
33832const MIN_STYLING_BINDING_SLOTS_REQUIRED = 2;
33833/**
33834 * Produces creation/update instructions for all styling bindings (class and style)
33835 *
33836 * It also produces the creation instruction to register all initial styling values
33837 * (which are all the static class="..." and style="..." attribute values that exist
33838 * on an element within a template).
33839 *
33840 * The builder class below handles producing instructions for the following cases:
33841 *
33842 * - Static style/class attributes (style="..." and class="...")
33843 * - Dynamic style/class map bindings ([style]="map" and [class]="map|string")
33844 * - Dynamic style/class property bindings ([style.prop]="exp" and [class.name]="exp")
33845 *
33846 * Due to the complex relationship of all of these cases, the instructions generated
33847 * for these attributes/properties/bindings must be done so in the correct order. The
33848 * order which these must be generated is as follows:
33849 *
33850 * if (createMode) {
33851 *   styling(...)
33852 * }
33853 * if (updateMode) {
33854 *   styleMap(...)
33855 *   classMap(...)
33856 *   styleProp(...)
33857 *   classProp(...)
33858 * }
33859 *
33860 * The creation/update methods within the builder class produce these instructions.
33861 */
33862
33863class StylingBuilder {
33864  constructor(_directiveExpr) {
33865    this._directiveExpr = _directiveExpr;
33866    /** Whether or not there are any static styling values present */
33867
33868    this._hasInitialValues = false;
33869    /**
33870     *  Whether or not there are any styling bindings present
33871     *  (i.e. `[style]`, `[class]`, `[style.prop]` or `[class.name]`)
33872     */
33873
33874    this.hasBindings = false;
33875    this.hasBindingsWithPipes = false;
33876    /** the input for [class] (if it exists) */
33877
33878    this._classMapInput = null;
33879    /** the input for [style] (if it exists) */
33880
33881    this._styleMapInput = null;
33882    /** an array of each [style.prop] input */
33883
33884    this._singleStyleInputs = null;
33885    /** an array of each [class.name] input */
33886
33887    this._singleClassInputs = null;
33888    this._lastStylingInput = null;
33889    this._firstStylingInput = null; // maps are used instead of hash maps because a Map will
33890    // retain the ordering of the keys
33891
33892    /**
33893     * Represents the location of each style binding in the template
33894     * (e.g. `<div [style.width]="w" [style.height]="h">` implies
33895     * that `width=0` and `height=1`)
33896     */
33897
33898    this._stylesIndex = new Map();
33899    /**
33900     * Represents the location of each class binding in the template
33901     * (e.g. `<div [class.big]="b" [class.hidden]="h">` implies
33902     * that `big=0` and `hidden=1`)
33903     */
33904
33905    this._classesIndex = new Map();
33906    this._initialStyleValues = [];
33907    this._initialClassValues = [];
33908  }
33909  /**
33910   * Registers a given input to the styling builder to be later used when producing AOT code.
33911   *
33912   * The code below will only accept the input if it is somehow tied to styling (whether it be
33913   * style/class bindings or static style/class attributes).
33914   */
33915
33916
33917  registerBoundInput(input) {
33918    // [attr.style] or [attr.class] are skipped in the code below,
33919    // they should not be treated as styling-based bindings since
33920    // they are intended to be written directly to the attr and
33921    // will therefore skip all style/class resolution that is present
33922    // with style="", [style]="" and [style.prop]="", class="",
33923    // [class.prop]="". [class]="" assignments
33924    let binding = null;
33925    let name = input.name;
33926
33927    switch (input.type) {
33928      case 0
33929      /* BindingType.Property */
33930      :
33931        binding = this.registerInputBasedOnName(name, input.value, input.sourceSpan);
33932        break;
33933
33934      case 3
33935      /* BindingType.Style */
33936      :
33937        binding = this.registerStyleInput(name, false, input.value, input.sourceSpan, input.unit);
33938        break;
33939
33940      case 2
33941      /* BindingType.Class */
33942      :
33943        binding = this.registerClassInput(name, false, input.value, input.sourceSpan);
33944        break;
33945    }
33946
33947    return binding ? true : false;
33948  }
33949
33950  registerInputBasedOnName(name, expression, sourceSpan) {
33951    let binding = null;
33952    const prefix = name.substring(0, 6);
33953    const isStyle = name === 'style' || prefix === 'style.' || prefix === 'style!';
33954    const isClass = !isStyle && (name === 'class' || prefix === 'class.' || prefix === 'class!');
33955
33956    if (isStyle || isClass) {
33957      const isMapBased = name.charAt(5) !== '.'; // style.prop or class.prop makes this a no
33958
33959      const property = name.slice(isMapBased ? 5 : 6); // the dot explains why there's a +1
33960
33961      if (isStyle) {
33962        binding = this.registerStyleInput(property, isMapBased, expression, sourceSpan);
33963      } else {
33964        binding = this.registerClassInput(property, isMapBased, expression, sourceSpan);
33965      }
33966    }
33967
33968    return binding;
33969  }
33970
33971  registerStyleInput(name, isMapBased, value, sourceSpan, suffix) {
33972    if (isEmptyExpression(value)) {
33973      return null;
33974    } // CSS custom properties are case-sensitive so we shouldn't normalize them.
33975    // See: https://www.w3.org/TR/css-variables-1/#defining-variables
33976
33977
33978    if (!isCssCustomProperty(name)) {
33979      name = hyphenate(name);
33980    }
33981
33982    const {
33983      property,
33984      hasOverrideFlag,
33985      suffix: bindingSuffix
33986    } = parseProperty(name);
33987    suffix = typeof suffix === 'string' && suffix.length !== 0 ? suffix : bindingSuffix;
33988    const entry = {
33989      name: property,
33990      suffix: suffix,
33991      value,
33992      sourceSpan,
33993      hasOverrideFlag
33994    };
33995
33996    if (isMapBased) {
33997      this._styleMapInput = entry;
33998    } else {
33999      (this._singleStyleInputs = this._singleStyleInputs || []).push(entry);
34000      registerIntoMap(this._stylesIndex, property);
34001    }
34002
34003    this._lastStylingInput = entry;
34004    this._firstStylingInput = this._firstStylingInput || entry;
34005
34006    this._checkForPipes(value);
34007
34008    this.hasBindings = true;
34009    return entry;
34010  }
34011
34012  registerClassInput(name, isMapBased, value, sourceSpan) {
34013    if (isEmptyExpression(value)) {
34014      return null;
34015    }
34016
34017    const {
34018      property,
34019      hasOverrideFlag
34020    } = parseProperty(name);
34021    const entry = {
34022      name: property,
34023      value,
34024      sourceSpan,
34025      hasOverrideFlag,
34026      suffix: null
34027    };
34028
34029    if (isMapBased) {
34030      this._classMapInput = entry;
34031    } else {
34032      (this._singleClassInputs = this._singleClassInputs || []).push(entry);
34033      registerIntoMap(this._classesIndex, property);
34034    }
34035
34036    this._lastStylingInput = entry;
34037    this._firstStylingInput = this._firstStylingInput || entry;
34038
34039    this._checkForPipes(value);
34040
34041    this.hasBindings = true;
34042    return entry;
34043  }
34044
34045  _checkForPipes(value) {
34046    if (value instanceof ASTWithSource && value.ast instanceof BindingPipe) {
34047      this.hasBindingsWithPipes = true;
34048    }
34049  }
34050  /**
34051   * Registers the element's static style string value to the builder.
34052   *
34053   * @param value the style string (e.g. `width:100px; height:200px;`)
34054   */
34055
34056
34057  registerStyleAttr(value) {
34058    this._initialStyleValues = parse(value);
34059    this._hasInitialValues = true;
34060  }
34061  /**
34062   * Registers the element's static class string value to the builder.
34063   *
34064   * @param value the className string (e.g. `disabled gold zoom`)
34065   */
34066
34067
34068  registerClassAttr(value) {
34069    this._initialClassValues = value.trim().split(/\s+/g);
34070    this._hasInitialValues = true;
34071  }
34072  /**
34073   * Appends all styling-related expressions to the provided attrs array.
34074   *
34075   * @param attrs an existing array where each of the styling expressions
34076   * will be inserted into.
34077   */
34078
34079
34080  populateInitialStylingAttrs(attrs) {
34081    // [CLASS_MARKER, 'foo', 'bar', 'baz' ...]
34082    if (this._initialClassValues.length) {
34083      attrs.push(literal(1
34084      /* AttributeMarker.Classes */
34085      ));
34086
34087      for (let i = 0; i < this._initialClassValues.length; i++) {
34088        attrs.push(literal(this._initialClassValues[i]));
34089      }
34090    } // [STYLE_MARKER, 'width', '200px', 'height', '100px', ...]
34091
34092
34093    if (this._initialStyleValues.length) {
34094      attrs.push(literal(2
34095      /* AttributeMarker.Styles */
34096      ));
34097
34098      for (let i = 0; i < this._initialStyleValues.length; i += 2) {
34099        attrs.push(literal(this._initialStyleValues[i]), literal(this._initialStyleValues[i + 1])
34099);
34100      }
34101    }
34102  }
34103  /**
34104   * Builds an instruction with all the expressions and parameters for `elementHostAttrs`.
34105   *
34106   * The instruction generation code below is used for producing the AOT statement code which is
34107   * responsible for registering initial styles (within a directive hostBindings' creation block),
34108   * as well as any of the provided attribute values, to the directive host element.
34109   */
34110
34111
34112  assignHostAttrs(attrs, definitionMap) {
34113    if (this._directiveExpr && (attrs.length || this._hasInitialValues)) {
34114      this.populateInitialStylingAttrs(attrs);
34115      definitionMap.set('hostAttrs', literalArr(attrs));
34116    }
34117  }
34118  /**
34119   * Builds an instruction with all the expressions and parameters for `classMap`.
34120   *
34121   * The instruction data will contain all expressions for `classMap` to function
34122   * which includes the `[class]` expression params.
34123   */
34124
34125
34126  buildClassMapInstruction(valueConverter) {
34127    if (this._classMapInput) {
34128      return this._buildMapBasedInstruction(valueConverter, true, this._classMapInput);
34129    }
34130
34131    return null;
34132  }
34133  /**
34134   * Builds an instruction with all the expressions and parameters for `styleMap`.
34135   *
34136   * The instruction data will contain all expressions for `styleMap` to function
34137   * which includes the `[style]` expression params.
34138   */
34139
34140
34141  buildStyleMapInstruction(valueConverter) {
34142    if (this._styleMapInput) {
34143      return this._buildMapBasedInstruction(valueConverter, false, this._styleMapInput);
34144    }
34145
34146    return null;
34147  }
34148
34149  _buildMapBasedInstruction(valueConverter, isClassBased, stylingInput) {
34150    // each styling binding value is stored in the LView
34151    // map-based bindings allocate two slots: one for the
34152    // previous binding value and another for the previous
34153    // className or style attribute value.
34154    let totalBindingSlotsRequired = MIN_STYLING_BINDING_SLOTS_REQUIRED; // these values must be outside of the update block so that they can
34155    // be evaluated (the AST visit call) during creation time so that any
34156    // pipes can be picked up in time before the template is built
34157
34158    const mapValue = stylingInput.value.visit(valueConverter);
34159    let reference;
34160
34161    if (mapValue instanceof Interpolation) {
34162      totalBindingSlotsRequired += mapValue.expressions.length;
34163      reference = isClassBased ? getClassMapInterpolationExpression(mapValue) : getStyleMapInterpolationExpression(mapValue);
34164    } else {
34165      reference = isClassBased ? Identifiers.classMap : Identifiers.styleMap;
34166    }
34167
34168    return {
34169      reference,
34170      calls: [{
34171        supportsInterpolation: true,
34172        sourceSpan: stylingInput.sourceSpan,
34173        allocateBindingSlots: totalBindingSlotsRequired,
34174        params: convertFn => {
34175          const convertResult = convertFn(mapValue);
34176          const params = Array.isArray(convertResult) ? convertResult : [convertResult];
34177          return params;
34178        }
34179      }]
34180    };
34181  }
34182
34183  _buildSingleInputs(reference, inputs, valueConverter, getInterpolationExpressionFn, isClassBased) {
34184    const instructions = [];
34185    inputs.forEach(input => {
34186      const previousInstruction = instructions[instructions.length - 1];
34187      const value = input.value.visit(valueConverter);
34188      let referenceForCall = reference; // each styling binding value is stored in the LView
34189      // but there are two values stored for each binding:
34190      //   1) the value itself
34191      //   2) an intermediate value (concatenation of style up to this point).
34192      //      We need to store the intermediate value so that we don't allocate
34193      //      the strings on each CD.
34194
34195      let totalBindingSlotsRequired = MIN_STYLING_BINDING_SLOTS_REQUIRED;
34196
34197      if (value instanceof Interpolation) {
34198        totalBindingSlotsRequired += value.expressions.length;
34199
34200        if (getInterpolationExpressionFn) {
34201          referenceForCall = getInterpolationExpressionFn(value);
34202        }
34203      }
34204
34205      const call = {
34206        sourceSpan: input.sourceSpan,
34207        allocateBindingSlots: totalBindingSlotsRequired,
34208        supportsInterpolation: !!getInterpolationExpressionFn,
34209        params: convertFn => {
34210          // params =>
34210 stylingProp(propName, value, suffix)
34211          const params = [];
34212          params.push(literal(input.name));
34213          const convertResult = convertFn(value);
34214
34215          if (Array.isArray(convertResult)) {
34216            params.push(...convertResult);
34217          } else {
34218            params.push(convertResult);
34219          } // [style.prop] bindings may use suffix values (e.g. px, em, etc...), therefore,
34220          // if that is detected then we need to pass that in as an optional param.
34221
34222
34223          if (!isClassBased && input.suffix !== null) {
34224            params.push(literal(input.suffix));
34225          }
34226
34227          return params;
34228        }
34229      }; // If we ended up generating a call to the same instruction as the previous styling property
34230      // we can chain the calls together safely to save some bytes, otherwise we have to generate
34231      // a separate instruction call. This is primarily a concern with interpolation instructions
34232      // where we may start off with one `reference`, but end up using another based on the
34233      // number of interpolations.
34234
34235      if (previousInstruction && previousInstruction.reference === referenceForCall) {
34236        previousInstruction.calls.push(call);
34237      } else {
34238        instructions.push({
34239          reference: referenceForCall,
34240          calls: [call]
34241        });
34242      }
34243    });
34244    return instructions;
34245  }
34246
34247  _buildClassInputs(valueConverter) {
34248    if (this._singleClassInputs) {
34249      return this._buildSingleInputs(Identifiers.classProp, this._singleClassInputs, valueConverter, null, true);
34250    }
34251
34252    return [];
34253  }
34254
34255  _buildStyleInputs(valueConverter) {
34256    if (this._singleStyleInputs) {
34257      return this._buildSingleInputs(Identifiers.styleProp, this._singleStyleInputs, valueConverter, getStylePropInterpolationExpression, false);
34258    }
34259
34260    return [];
34261  }
34262  /**
34263   * Constructs all instructions which contain the expressions that will be placed
34264   * into the update block of a template function or a directive hostBindings function.
34265   */
34266
34267
34268  buildUpdateLevelInstructions(valueConverter) {
34269    const instructions = [];
34270
34271    if (this.hasBindings) {
34272      const styleMapInstruction = this.buildStyleMapInstruction(valueConverter);
34273
34274      if (styleMapInstruction) {
34275        instructions.push(styleMapInstruction);
34276      }
34277
34278      const classMapInstruction = this.buildClassMapInstruction(valueConverter);
34279
34280      if (classMapInstruction) {
34281        instructions.push(classMapInstruction);
34282      }
34283
34284      instructions.push(...this._buildStyleInputs(valueConverter));
34285      instructions.push(...this._buildClassInputs(valueConverter));
34286    }
34287
34288    return instructions;
34289  }
34290
34291}
34292
34293function registerIntoMap(map, key) {
34294  if (!map.has(key)) {
34295    map.set(key, map.size);
34296  }
34297}
34298
34299function parseProperty(name) {
34300  let hasOverrideFlag = false;
34301  const overrideIndex = name.indexOf(IMPORTANT_FLAG);
34302
34303  if (overrideIndex !== -1) {
34304    name = overrideIndex > 0 ? name.substring(0, overrideIndex) : '';
34305    hasOverrideFlag = true;
34306  }
34307
34308  let suffix = null;
34309  let property = name;
34310  const unitIndex = name.lastIndexOf('.');
34311
34312  if (unitIndex > 0) {
34313    suffix = name.slice(unitIndex + 1);
34314    property = name.substring(0, unitIndex);
34315  }
34316
34317  return {
34318    property,
34319    suffix,
34320    hasOverrideFlag
34321  };
34322}
34323/**
34324 * Gets the instruction to generate for an interpolated class map.
34325 * @param interpolation An Interpolation AST
34326 */
34327
34328
34329function getClassMapInterpolationExpression(interpolation) {
34330  switch (getInterpolationArgsLength(interpolation)) {
34331    case 1:
34332      return Identifiers.classMap;
34333
34334    case 3:
34335      return Identifiers.classMapInterpolate1;
34336
34337    case 5:
34338      return Identifiers.classMapInterpolate2;
34339
34340    case 7:
34341      return Identifiers.classMapInterpolate3;
34342
34343    case 9:
34344      return Identifiers.classMapInterpolate4;
34345
34346    case 11:
34347      return Identifiers.classMapInterpolate5;
34348
34349    case 13:
34350      return Identifiers.classMapInterpolate6;
34351
34352    case 15:
34353      return Identifiers.classMapInterpolate7;
34354
34355    case 17:
34356      return Identifiers.classMapInterpolate8;
34357
34358    default:
34359      return Identifiers.classMapInterpolateV;
34360  }
34361}
34362/**
34363 * Gets the instruction to generate for an interpolated style map.
34364 * @param interpolation An Interpolation AST
34365 */
34366
34367
34368function getStyleMapInterpolationExpression(interpolation) {
34369  switch (getInterpolationArgsLength(interpolation)) {
34370    case 1:
34371      return Identifiers.styleMap;
34372
34373    case 3:
34374      return Identifiers.styleMapInterpolate1;
34375
34376    case 5:
34377      return Identifiers.styleMapInterpolate2;
34378
34379    case 7:
34380      return Identifiers.styleMapInterpolate3;
34381
34382    case 9:
34383      return Identifiers.styleMapInterpolate4;
34384
34385    case 11:
34386      return Identifiers.styleMapInterpolate5;
34387
34388    case 13:
34389      return Identifiers.styleMapInterpolate6;
34390
34391    case 15:
34392      return Identifiers.styleMapInterpolate7;
34393
34394    case 17:
34395      return Identifiers.styleMapInterpolate8;
34396
34397    default:
34398      return Identifiers.styleMapInterpolateV;
34399  }
34400}
34401/**
34402 * Gets the instruction to generate for an interpolated style prop.
34403 * @param interpolation An Interpolation AST
34404 */
34405
34406
34407function getStylePropInterpolationExpression(interpolation) {
34408  switch (getInterpolationArgsLength(interpolation)) {
34409    case 1:
34410      return Identifiers.styleProp;
34411
34412    case 3:
34413      return Identifiers.stylePropInterpolate1;
34414
34415    case 5:
34416      return Identifiers.stylePropInterpolate2;
34417
34418    case 7:
34419      return Identifiers.stylePropInterpolate3;
34420
34421    case 9:
34422      return Identifiers.stylePropInterpolate4;
34423
34424    case 11:
34425      return Identifiers.stylePropInterpolate5;
34426
34427    case 13:
34428      return Identifiers.stylePropInterpolate6;
34429
34430    case 15:
34431      return Identifiers.stylePropInterpolate7;
34432
34433    case 17:
34434      return Identifiers.stylePropInterpolate8;
34435
34436    default:
34437      return Identifiers.stylePropInterpolateV;
34438  }
34439}
34440/**
34441 * Checks whether property name is a custom CSS property.
34442 * See: https://www.w3.org/TR/css-variables-1
34443 */
34444
34445
34446function isCssCustomProperty(name) {
34447  return name.startsWith('--');
34448}
34449
34450function isEmptyExpression(ast) {
34451  if (ast instanceof ASTWithSource) {
34452    ast = ast.ast;
34453  }
34454
34455  return ast instanceof EmptyExpr;
34456}
34457/**
34458 * @license
34459 * Copyright Google LLC All Rights Reserved.
34460 *
34461 * Use of this source code is governed by an MIT-style license that can be
34462 * found in the LICENSE file at https://angular.io/license
34463 */
34464
34465
34466var TokenType;
34467
34468(function (TokenType) {
34469  TokenType[TokenType["Character"] = 0] = "Character";
34470  TokenType[TokenType["Identifier"] = 1] = "Identifier";
34471  TokenType[TokenType["PrivateIdentifier"] = 2] = "PrivateIdentifier";
34472  TokenType[TokenType["Keyword"] = 3] = "Keyword";
34473  TokenType[TokenType["String"] = 4] = "String";
34474  TokenType[TokenType["Operator"] = 5] = "Operator";
34475  TokenType[TokenType["Number"] = 6] = "Number";
34476  TokenType[TokenType["Error"] = 7] = "Error";
34477})(TokenType || (TokenType = {}));
34478
34479const KEYWORDS = ['var', 'let', 'as', 'null', 'undefined', 'true', 'false', 'if', 'else', 'this'];
34480
34481class Lexer {
34482  tokenize(text) {
34483    const scanner = new _Scanner(text);
34484    const tokens = [];
34485    let token = scanner.scanToken();
34486
34487    while (token != null) {
34488      tokens.push(token);
34489      token = scanner.scanToken();
34490    }
34491
34492    return tokens;
34493  }
34494
34495}
34496
34497class Token {
34498  constructor(index, end, type, numValue, strValue) {
34499    this.index = index;
34500    this.end = end;
34501    this.type = type;
34502    this.numValue = numValue;
34503    this.strValue = strValue;
34504  }
34505
34506  isCharacter(code) {
34507    return this.type == TokenType.Character && this.numValue == code;
34508  }
34509
34510  isNumber() {
34511    return this.type == TokenType.Number;
34512  }
34513
34514  isString() {
34515    return this.type == TokenType.String;
34516  }
34517
34518  isOperator(operator) {
34519    return this.type == TokenType.Operator && this.strValue == operator;
34520  }
34521
34522  isIdentifier() {
34523    return this.type == TokenType.Identifier;
34524  }
34525
34526  isPrivateIdentifier() {
34527    return this.type == TokenType.PrivateIdentifier;
34528  }
34529
34530  isKeyword() {
34531    return this.type == TokenType.Keyword;
34532  }
34533
34534  isKeywordLet() {
34535    return this.type == TokenType.Keyword && this.strValue == 'let';
34536  }
34537
34538  isKeywordAs() {
34539    return this.type == TokenType.Keyword && this.strValue == 'as';
34540  }
34541
34542  isKeywordNull() {
34543    return this.type == TokenType.Keyword && this.strValue == 'null';
34544  }
34545
34546  isKeywordUndefined() {
34547    return this.type == TokenType.Keyword && this.strValue == 'undefined';
34548  }
34549
34550  isKeywordTrue() {
34551    return this.type == TokenType.Keyword && this.strValue == 'true';
34552  }
34553
34554  isKeywordFalse() {
34555    return this.type == TokenType.Keyword && this.strValue == 'false';
34556  }
34557
34558  isKeywordThis() {
34559    return this.type == TokenType.Keyword && this.strValue == 'this';
34560  }
34561
34562  isError() {
34563    return this.type == TokenType.Error;
34564  }
34565
34566  toNumber() {
34567    return this.type == TokenType.Number ? this.numValue : -1;
34568  }
34569
34570  toString() {
34571    switch (this.type) {
34572      case TokenType.Character:
34573      case TokenType.Identifier:
34574      case TokenType.Keyword:
34575      case TokenType.Operator:
34576      case TokenType.PrivateIdentifier:
34577      case TokenType.String:
34578      case TokenType.Error:
34579        return this.strValue;
34580
34581      case TokenType.Number:
34582        return this.numValue.toString();
34583
34584      default:
34585        return null;
34586    }
34587  }
34588
34589}
34590
34591function newCharacterToken(index, end, code) {
34592  return new Token(index, end, TokenType.Character, code, String.fromCharCode(code));
34593}
34594
34595function newIdentifierToken(index, end, text) {
34596  return new Token(index, end, TokenType.Identifier, 0, text);
34597}
34598
34599function newPrivateIdentifierToken(index, end, text) {
34600  return new Token(index, end, TokenType.PrivateIdentifier, 0, text);
34601}
34602
34603function newKeywordToken(index, end, text) {
34604  return new Token(index, end, TokenType.Keyword, 0, text);
34605}
34606
34607function newOperatorToken(index, end, text) {
34608  return new Token(index, end, TokenType.Operator, 0, text);
34609}
34610
34611function newStringToken(index, end, text) {
34612  return new Token(index, end, TokenType.String, 0, text);
34613}
34614
34615function newNumberToken(index, end, n) {
34616  return new Token(index, end, TokenType.Number, n, '');
34617}
34618
34619function newErrorToken(index, end, message) {
34620  return new Token(index, end, TokenType.Error, 0, message);
34621}
34622
34623const EOF = new Token(-1, -1, TokenType.Character, 0, '');
34624
34625class _Scanner {
34626  constructor(input) {
34627    this.input = input;
34628    this.peek = 0;
34629    this.index = -1;
34630    this.length = input.length;
34631    this.advance();
34632  }
34633
34634  advance() {
34635    this.peek = ++this.index >= this.length ? $EOF : this.input.charCodeAt(this.index);
34636  }
34637
34638  scanToken() {
34639    const input = this.input,
34640          length = this.length;
34641    let peek = this.peek,
34642        index = this.index; // Skip whitespace.
34643
34644    while (peek <= $SPACE) {
34645      if (++index >= length) {
34646        peek = $EOF;
34647        break;
34648      } else {
34649        peek = input.charCodeAt(index);
34650      }
34651    }
34652
34653    this.peek = peek;
34654    this.index = index;
34655
34656    if (index >= length) {
34657      return null;
34658    } // Handle identifiers and numbers.
34659
34660
34661    if (isIdentifierStart(peek)) return this.scanIdentifier();
34662    if (isDigit(peek)) return this.scanNumber(index);
34663    const start = index;
34664
34665    switch (peek) {
34666      case $PERIOD:
34667        this.advance();
34668        return isDigit(this.peek) ? this.scanNumber(start) : newCharacterToken(start, this.index, $PERIOD);
34669
34670      case $LPAREN:
34671      case $RPAREN:
34672      case $LBRACE:
34673      case $RBRACE:
34674      case $LBRACKET:
34675      case $RBRACKET:
34676      case $COMMA:
34677      case $COLON:
34678      case $SEMICOLON:
34679        return this.scanCharacter(start, peek);
34680
34681      case $SQ:
34682      case $DQ:
34683        return this.scanString();
34684
34685      case $HASH:
34686        return this.scanPrivateIdentifier();
34687
34688      case $PLUS:
34689      case $MINUS:
34690      case $STAR:
34691      case $SLASH:
34692      case $PERCENT:
34693      case $CARET:
34694        return this.scanOperator(start, String.fromCharCode(peek));
34695
34696      case $QUESTION:
34697        return this.scanQuestion(start);
34698
34699      case $LT:
34700      case $GT:
34701        return this.scanComplexOperator(start, String.fromCharCode(peek), $EQ, '=');
34702
34703      case $BANG:
34704      case $EQ:
34705        return this.scanComplexOperator(start, String.fromCharCode(peek), $EQ, '=', $EQ, '=');
34706
34707      case $AMPERSAND:
34708        return this.scanComplexOperator(start, '&', $AMPERSAND, '&');
34709
34710      case $BAR:
34711        return this.scanComplexOperator(start, '|', $BAR, '|');
34712
34713      case $NBSP:
34714        while (isWhitespace(this.peek)) this.advance();
34715
34716        return this.scanToken();
34717    }
34718
34719    this.advance();
34720    return this.error(`Unexpected character [${String.fromCharCode(peek)}]`, 0);
34721  }
34722
34723  scanCharacter(start, code) {
34724    this.advance();
34725    return newCharacterToken(start, this.index, code);
34726  }
34727
34728  scanOperator(start, str) {
34729    this.advance();
34730    return newOperatorToken(start, this.index, str);
34731  }
34732  /**
34733   * Tokenize a 2/3 char long operator
34734   *
34735   * @param start start index in the expression
34736   * @param one first symbol (always part of the operator)
34737   * @param twoCode code point for the second symbol
34738   * @param two second symbol (part of the operator when the second code point matches)
34739   * @param threeCode code point for the third symbol
34740   * @param three third symbol (part of the operator when provided and matches source expression)
34741   */
34742
34743
34744  scanComplexOperator(start, one, twoCode, two, threeCode, three) {
34745    this.advance();
34746    let str = one;
34747
34748    if (this.peek == twoCode) {
34749      this.advance();
34750      str += two;
34751    }
34752
34753    if (threeCode != null && this.peek == threeCode) {
34754      this.advance();
34755      str += three;
34756    }
34757
34758    return newOperatorToken(start, this.index, str);
34759  }
34760
34761  scanIdentifier() {
34762    const start = this.index;
34763    this.advance();
34764
34765    while (isIdentifierPart(this.peek)) this.advance();
34766
34767    const str = this.input.substring(start, this.index);
34768    return KEYWORDS.indexOf(str) > -1 ? newKeywordToken(start, this.index, str) : newIdentifierToken(start, this.index, str);
34769  }
34770  /** Scans an ECMAScript private identifier. */
34771
34772
34773  scanPrivateIdentifier() {
34774    const start = this.index;
34775    this.advance();
34776
34777    if (!isIdentifierStart(this.peek)) {
34778      return this.error('Invalid character [#]', -1);
34779    }
34780
34781    while (isIdentifierPart(this.peek)) this.advance();
34782
34783    const identifierName = this.input.substring(start, this.index);
34784    return newPrivateIdentifierToken(start, this.index, identifierName);
34785  }
34786
34787  scanNumber(start) {
34788    let simple = this.index === start;
34789    let hasSeparators = false;
34790    this.advance(); // Skip initial digit.
34791
34792    while (true) {
34793      if (isDigit(this.peek)) {// Do nothing.
34794      } else if (this.peek === $_) {
34795        // Separators are only valid when they're surrounded by digits. E.g. `1_0_1` is
34796        // valid while `_101` and `101_` are not. The separator can't be next to the decimal
34797        // point or another separator either. Note that it's unlikely that we'll hit a case where
34798        // the underscore is at the start, because that's a valid identifier and it will be picked
34799        // up earlier in the parsing. We validate for it anyway just in case.
34800        if (!isDigit(this.input.charCodeAt(this.index - 1)) || !isDigit(this.input.charCodeAt(this.index + 1))) {
34801          return this.error('Invalid numeric separator', 0);
34802        }
34803
34804        hasSeparators = true;
34805      } else if (this.peek === $PERIOD) {
34806        simple = false;
34807      } else if (isExponentStart(this.peek)) {
34808        this.advance();
34809        if (isExponentSign(this.peek)) this.advance();
34810        if (!isDigit(this.peek)) return this.error('Invalid exponent', -1);
34811        simple = false;
34812      } else {
34813        break;
34814      }
34815
34816      this.advance();
34817    }
34818
34819    let str = this.input.substring(start, this.index);
34820
34821    if (hasSeparators) {
34822      str = str.replace(/_/g, '');
34823    }
34824
34825    const value = simple ? parseIntAutoRadix(str) : parseFloat(str);
34826    return newNumberToken(start, this.index, value);
34827  }
34828
34829  scanString() {
34830    const start = this.index;
34831    const quote = this.peek;
34832    this.advance(); // Skip initial quote.
34833
34834    let buffer = '';
34835    let marker = this.index;
34836    const input = this.input;
34837
34838    while (this.peek != quote) {
34839      if (this.peek == $BACKSLASH) {
34840        buffer += input.substring(marker, this.index);
34841        this.advance();
34842        let unescapedCode; // Workaround for TS2.1-introduced type strictness
34843
34844        this.peek = this.peek;
34845
34846        if (this.peek == $u) {
34847          // 4 character hex code for unicode character.
34848          const hex = input.substring(this.index + 1, this.index + 5);
34849
34850          if (/^[0-9a-f]+$/i.test(hex)) {
34851            unescapedCode = parseInt(hex, 16);
34852          } else {
34853            return this.error(`Invalid unicode escape [\\u${hex}]`, 0);
34854          }
34855
34856          for (let i = 0; i < 5; i++) {
34857            this.advance();
34858          }
34859        } else {
34860          unescapedCode = unescape(this.peek);
34861          this.advance();
34862        }
34863
34864        buffer += String.fromCharCode(unescapedCode);
34865        marker = this.index;
34866      } else if (this.peek == $EOF) {
34867        return this.error('Unterminated quote', 0);
34868      } else {
34869        this.advance();
34870      }
34871    }
34872
34873    const last = input.substring(marker, this.index);
34874    this.advance(); // Skip terminating quote.
34875
34876    return newStringToken(start, this.index, buffer + last);
34877  }
34878
34879  scanQuestion(start) {
34880    this.advance();
34881    let str = '?'; // Either `a ?? b` or 'a?.b'.
34882
34883    if (this.peek === $QUESTION || this.peek === $PERIOD) {
34884      str += this.peek === $PERIOD ? '.' : '?';
34885      this.advance();
34886    }
34887
34888    return newOperatorToken(start, this.index, str);
34889  }
34890
34891  error(message, offset) {
34892    const position = this.index + offset;
34893    return newErrorToken(position, this.index, `Lexer Error: ${message} at column ${position} in expression [${this.input}]`);
34894  }
34895
34896}
34897
34898function isIdentifierStart(code) {
34899  return $a <= code && code <= $z || $A <= code && code <= $Z || code == $_ || code == $$;
34900}
34901
34902function isIdentifier(input) {
34903  if (input.length == 0) return false;
34904  const scanner = new _Scanner(input);
34905  if (!isIdentifierStart(scanner.peek)) return false;
34906  scanner.advance();
34907
34908  while (scanner.peek !== $EOF) {
34909    if (!isIdentifierPart(scanner.peek)) return false;
34910    scanner.advance();
34911  }
34912
34913  return true;
34914}
34915
34916function isIdentifierPart(code) {
34917  return isAsciiLetter(code) || isDigit(code) || code == $_ || code == $$;
34918}
34919
34920function isExponentStart(code) {
34921  return code == $e || code == $E;
34922}
34923
34924function isExponentSign(code) {
34925  return code == $MINUS || code == $PLUS;
34926}
34927
34928function unescape(code) {
34929  switch (code) {
34930    case $n:
34931      return $LF;
34932
34933    case $f:
34934      return $FF;
34935
34936    case $r:
34937      return $CR;
34938
34939    case $t:
34940      return $TAB;
34941
34942    case $v:
34943      return $VTAB;
34944
34945    default:
34946      return code;
34947  }
34948}
34949
34950function parseIntAutoRadix(text) {
34951  const result = parseInt(text);
34952
34953  if (isNaN(result)) {
34954    throw new Error('Invalid integer literal when parsing ' + text);
34955  }
34956
34957  return result;
34958}
34959/**
34960 * @license
34961 * Copyright Google LLC All Rights Reserved.
34962 *
34963 * Use of this source code is governed by an MIT-style license that can be
34964 * found in the LICENSE file at https://angular.io/license
34965 */
34966
34967
34968class SplitInterpolation {
34969  constructor(strings, expressions, offsets) {
34970    this.strings = strings;
34971    this.expressions = expressions;
34972    this.offsets = offsets;
34973  }
34974
34975}
34976
34977class TemplateBindingParseResult {
34978  constructor(templateBindings, warnings, errors) {
34979    this.templateBindings = templateBindings;
34980    this.warnings = warnings;
34981    this.errors = errors;
34982  }
34983
34984}
34985
34986class Parser$1 {
34987  constructor(_lexer) {
34988    this._lexer = _lexer;
34989    this.errors = [];
34990  }
34991
34992  parseAction(input, isAssignmentEvent, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
34993    this._checkNoInterpolation(input, location, interpolationConfig);
34994
34995    const sourceToLex = this._stripComments(input);
34996
34997    const tokens = this._lexer.tokenize(sourceToLex);
34998
34999    let flags = 1
35000    /* ParseFlags.Action */
35001    ;
35002
35003    if (isAssignmentEvent) {
35004      flags |= 2
35005      /* ParseFlags.AssignmentEvent */
35006      ;
35007    }
35008
35009    const ast = new _ParseAST(input, location, absoluteOffset, tokens, flags, this.errors, 0).parseChain();
35010    return new ASTWithSource(ast, input, location, absoluteOffset, this.errors);
35011  }
35012
35013  parseBinding(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
35014    const ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig);
35015
35016    return new ASTWithSource(ast, input, location, absoluteOffset, this.errors);
35017  }
35018
35019  checkSimpleExpression(ast) {
35020    const checker = new SimpleExpressionChecker();
35021    ast.visit(checker);
35022    return checker.errors;
35023  }
35024
35025  parseSimpleBinding(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
35026    const ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig);
35027
35028    const errors = this.checkSimpleExpression(ast);
35029
35030    if (errors.length > 0) {
35031      this._reportError(`Host binding expression cannot contain ${errors.join(' ')}`, input, location);
35032    }
35033
35034    return new ASTWithSource(ast, input, location, absoluteOffset, this.errors);
35035  }
35036
35037  _reportError(message, input, errLocation, ctxLocation) {
35038    this.errors.push(new ParserError(message, input, errLocation, ctxLocation));
35039  }
35040
35041  _parseBindingAst(input, location, absoluteOffset, interpolationConfig) {
35042    this._checkNoInterpolation(input, location, interpolationConfig);
35043
35044    const sourceToLex = this._stripComments(input);
35045
35046    const tokens = this._lexer.tokenize(sourceToLex);
35047
35048    return new _ParseAST(input, location, absoluteOffset, tokens, 0
35049    /* ParseFlags.None */
35050    , this.errors, 0).parseChain();
35051  }
35052  /**
35053   * Parse microsyntax template expression and return a list of bindings or
35054   * parsing errors in case the given expression is invalid.
35055   *
35056   * For example,
35057   * ```
35058   *   <div *ngFor="let item of items">
35059   *         ^      ^ absoluteValueOffset for `templateValue`
35060   *         absoluteKeyOffset for `templateKey`
35061   * ```
35062   * contains three bindings:
35063   * 1. ngFor -> null
35064   * 2. item -> NgForOfContext.$implicit
35065   * 3. ngForOf -> items
35066   *
35067   * This is apparent from the de-sugared template:
35068   * ```
35069   *   <ng-template ngFor let-item [ngForOf]="items">
35070   * ```
35071   *
35072   * @param templateKey name of directive, without the * prefix. For example: ngIf, ngFor
35073   * @param templateValue RHS of the microsyntax attribute
35074   * @param templateUrl template filename if it's external, component filename if it's inline
35075   * @param absoluteKeyOffset start of the `templateKey`
35076   * @param absoluteValueOffset start of the `templateValue`
35077   */
35078
35079
35080  parseTemplateBindings(templateKey, templateValue, templateUrl, absoluteKeyOffset, absoluteValueOffset) {
35081    const tokens = this._lexer.tokenize(templateValue);
35082
35083    const parser = new _ParseAST(templateValue, templateUrl, absoluteValueOffset, tokens, 0
35084    /* ParseFlags.None */
35085    , this.errors, 0
35086    /* relative offset */
35087    );
35088    return parser.parseTemplateBindings({
35089      source: templateKey,
35090      span: new AbsoluteSourceSpan(absoluteKeyOffset, absoluteKeyOffset + templateKey.length)
35091    });
35092  }
35093
35094  parseInterpolation(input, location, absoluteOffset, interpolatedTokens, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
35095    const {
35096      strings,
35097      expressions,
35098      offsets
35099    } = this.splitInterpolation(input, location, interpolatedTokens, interpolationConfig);
35100    if (expressions.length === 0) return null;
35101    const expressionNodes = [];
35102
35103    for (let i = 0; i < expressions.length; ++i) {
35104      const expressionText = expressions[i].text;
35105
35106      const sourceToLex = this._stripComments(expressionText);
35107
35108      const tokens = this._lexer.tokenize(sourceToLex);
35109
35110      const ast = new _ParseAST(input, location, absoluteOffset, tokens, 0
35111      /* ParseFlags.None */
35112      , this.errors, offsets[i]).parseChain();
35113      expressionNodes.push(ast);
35114    }
35115
35116    return this.createInterpolationAst(strings.map(s => s.text), expressionNodes, input, location, absoluteOffset);
35117  }
35118  /**
35119   * Similar to `parseInterpolation`, but treats the provided string as a single expression
35120   * element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`).
35121   * This is used for parsing the switch expression in ICUs.
35122   */
35123
35124
35125  parseInterpolationExpression(expression, location, absoluteOffset) {
35126    const sourceToLex = this._stripComments(expression);
35127
35128    const tokens = this._lexer.tokenize(sourceToLex);
35129
35130    const ast = new _ParseAST(expression, location, absoluteOffset, tokens, 0
35131    /* ParseFlags.None */
35132    , this.errors, 0).parseChain();
35133    const strings = ['', '']; // The prefix and suffix strings are both empty
35134
35135    return this.createInterpolationAst(strings, [ast], expression, location, absoluteOffset);
35136  }
35137
35138  createInterpolationAst(strings, expressions, input, location, absoluteOffset) {
35139    const span = new ParseSpan(0, input.length);
35140    const interpolation = new Interpolation(span, span.toAbsolute(absoluteOffset), strings, expressions);
35141    return new ASTWithSource(interpolation, input, location, absoluteOffset, this.errors);
35142  }
35143  /**
35144   * Splits a string of text into "raw" text segments and expressions present in interpolations in
35145   * the string.
35146   * Returns `null` if there are no interpolations, otherwise a
35147   * `SplitInterpolation` with splits that look like
35148   *   <raw text> <expression> <raw text> ... <raw text> <expression> <raw text>
35149   */
35150
35151
35152  splitInterpolation(input, location, interpolatedTokens, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
35153    const strings = [];
35154    const expressions = [];
35155    const offsets = [];
35156    const inputToTemplateIndexMap = interpolatedTokens ? getIndexMapForOriginalTemplate(interpolatedTokens) : null;
35157    let i = 0;
35158    let atInterpolation = false;
35159    let extendLastString = false;
35160    let {
35161      start: interpStart,
35162      end: interpEnd
35163    } = interpolationConfig;
35164
35165    while (i < input.length) {
35166      if (!atInterpolation) {
35167        // parse until starting {{
35168        const start = i;
35169        i = input.indexOf(interpStart, i);
35170
35171        if (i === -1) {
35172          i = input.length;
35173        }
35174
35175        const text = input.substring(start, i);
35176        strings.push({
35177          text,
35178          start,
35179          end: i
35180        });
35181        atInterpolation = true;
35182      } else {
35183        // parse from starting {{ to ending }} while ignoring content inside quotes.
35184        const fullStart = i;
35185        const exprStart = fullStart + interpStart.length;
35186
35187        const exprEnd = this._getInterpolationEndIndex(input, interpEnd, exprStart);
35188
35189        if (exprEnd === -1) {
35190          // Could not find the end of the interpolation; do not parse an expression.
35191          // Instead we should extend the content on the last raw string.
35192          atInterpolation = false;
35193          extendLastString = true;
35194          break;
35195        }
35196
35197        const fullEnd = exprEnd + interpEnd.length;
35198        const text = input.substring(exprStart, exprEnd);
35199
35200        if (text.trim().length === 0) {
35201          this._reportError('Blank expressions are not allowed in interpolated strings', input, `at column ${i} in`, location);
35202        }
35203
35204        expressions.push({
35205          text,
35206          start: fullStart,
35207          end: fullEnd
35208        });
35209        const startInOriginalTemplate = inputToTemplateIndexMap?.get(fullStart) ?? fullStart;
35210        const offset = startInOriginalTemplate + interpStart.length;
35211        offsets.push(offset);
35212        i = fullEnd;
35213        atInterpolation = false;
35214      }
35215    }
35216
35217    if (!atInterpolation) {
35218      // If we are now at a text section, add the remaining content as a raw string.
35219      if (extendLastString) {
35220        const piece = strings[strings.length - 1];
35221        piece.text += input.substring(i);
35222        piece.end = input.length;
35223      } else {
35224        strings.push({
35225          text: input.substring(i),
35226          start: i,
35227          end: input.length
35228        });
35229      }
35230    }
35231
35232    return new SplitInterpolation(strings, expressions, offsets);
35233  }
35234
35235  wrapLiteralPrimitive(input, location, absoluteOffset) {
35236    const span = new ParseSpan(0, input == null ? 0 : input.length);
35237    return new ASTWithSource(new LiteralPrimitive(span, span.toAbsolute(absoluteOffset), input), input, location, absoluteOffset, this.errors);
35238  }
35239
35240  _stripComments(input) {
35241    const i = this._commentStart(input);
35242
35243    return i != null ? input.substring(0, i) : input;
35244  }
35245
35246  _commentStart(input) {
35247    let outerQuote = null;
35248
35249    for (let i = 0; i < input.length - 1; i++) {
35250      const char = input.charCodeAt(i);
35251      const nextChar = input.charCodeAt(i + 1);
35252      if (char === $SLASH && nextChar == $SLASH && outerQuote == null) return i;
35253
35254      if (outerQuote === char) {
35255        outerQuote = null;
35256      } else if (outerQuote == null && isQuote(char)) {
35257        outerQuote = char;
35258      }
35259    }
35260
35261    return null;
35262  }
35263
35264  _checkNoInterpolation(input, location, {
35265    start,
35266    end
35267  }) {
35268    let startIndex = -1;
35269    let endIndex = -1;
35270
35271    for (const charIndex of this._forEachUnquotedChar(input, 0)) {
35272      if (startIndex === -1) {
35273        if (input.startsWith(start)) {
35274          startIndex = charIndex;
35275        }
35276      } else {
35277        endIndex = this._getInterpolationEndIndex(input, end, charIndex);
35278
35279        if (endIndex > -1) {
35280          break;
35281        }
35282      }
35283    }
35284
35285    if (startIndex > -1 && endIndex > -1) {
35286      this._reportError(`Got interpolation (${start}${end}) where expression was expected`, input, `at column ${startIndex} in`, location);
35287    }
35288  }
35289  /**
35290   * Finds the index of the end of an interpolation expression
35291   * while ignoring comments and quoted content.
35292   */
35293
35294
35295  _getInterpolationEndIndex(input, expressionEnd, start) {
35296    for (const charIndex of this._forEachUnquotedChar(input, start)) {
35297      if (input.startsWith(expressionEnd, charIndex)) {
35298        return charIndex;
35299      } // Nothing else in the expression matters after we've
35300      // hit a comment so look directly for the end token.
35301
35302
35303      if (input.startsWith('//', charIndex)) {
35304        return input.indexOf(expressionEnd, charIndex);
35305      }
35306    }
35307
35308    return -1;
35309  }
35310  /**
35311   * Generator used to iterate over the character indexes of a string that are outside of quotes.
35312   * @param input String to loop through.
35313   * @param start Index within the string at which to start.
35314   */
35315
35316
35317  *_forEachUnquotedChar(input, start) {
35318    let currentQuote = null;
35319    let escapeCount = 0;
35320
35321    for (let i = start; i < input.length; i++) {
35322      const char = input[i]; // Skip the characters inside quotes. Note that we only care about the outer-most
35323      // quotes matching up and we need to account for escape characters.
35324
35325      if (isQuote(input.charCodeAt(i)) && (currentQuote === null || currentQuote === char) && escapeCount % 2 === 0) {
35326        currentQuote = currentQuote === null ? char : null;
35327      } else if (currentQuote === null) {
35328        yield i;
35329      }
35330
35331      escapeCount = char === '\\' ? escapeCount + 1 : 0;
35332    }
35333  }
35334
35335}
35336/** Describes a stateful context an expression parser is in. */
35337
35338
35339var ParseContextFlags;
35340
35341(function (ParseContextFlags) {
35342  ParseContextFlags[ParseContextFlags["None"] = 0] = "None";
35343  /**
35344   * A Writable context is one in which a value may be written to an lvalue.
35345   * For example, after we see a property access, we may expect a write to the
35346   * property via the "=" operator.
35347   *   prop
35348   *        ^ possible "=" after
35349   */
35350
35351  ParseContextFlags[ParseContextFlags["Writable"] = 1] = "Writable";
35352})(ParseContextFlags || (ParseContextFlags = {}));
35353
35354class _ParseAST {
35355  constructor(input, location, absoluteOffset, tokens, parseFlags, errors, offset) {
35356    this.input = input;
35357    this.location = location;
35358    this.absoluteOffset = absoluteOffset;
35359    this.tokens = tokens;
35360    this.parseFlags = parseFlags;
35361    this.errors = errors;
35362    this.offset = offset;
35363    this.rparensExpected = 0;
35364    this.rbracketsExpected = 0;
35365    this.rbracesExpected = 0;
35366    this.context = ParseContextFlags.None; // Cache of expression start and input indeces to the absolute source span they map to, used to
35367    // prevent creating superfluous source spans in `sourceSpan`.
35368    // A serial of the expression start and input index is used for mapping because both are stateful
35369    // and may change for subsequent expressions visited by the parser.
35370
35371    this.sourceSpanCache = new Map();
35372    this.index = 0;
35373  }
35374
35375  peek(offset) {
35376    const i = this.index + offset;
35377    return i < this.tokens.length ? this.tokens[i] : EOF;
35378  }
35379
35380  get next() {
35381    return this.peek(0);
35382  }
35383  /** Whether all the parser input has been processed. */
35384
35385
35386  get atEOF() {
35387    return this.index >= this.tokens.length;
35388  }
35389  /**
35390   * Index of the next token to be processed, or the end of the last token if all have been
35391   * processed.
35392   */
35393
35394
35395  get inputIndex() {
35396    return this.atEOF ? this.currentEndIndex : this.next.index + this.offset;
35397  }
35398  /**
35399   * End index of the last processed token, or the start of the first token if none have been
35400   * processed.
35401   */
35402
35403
35404  get currentEndIndex() {
35405    if (this.index > 0) {
35406      const curToken = this.peek(-1);
35407      return curToken.end + this.offset;
35408    } // No tokens have been processed yet; return the next token's start or the length of the input
35409    // if there is no token.
35410
35411
35412    if (this.tokens.length === 0) {
35413      return this.input.length + this.offset;
35414    }
35415
35416    return this.next.index + this.offset;
35417  }
35418  /**
35419   * Returns the absolute offset of the start of the current token.
35420   */
35421
35422
35423  get currentAbsoluteOffset() {
35424    return this.absoluteOffset + this.inputIndex;
35425  }
35426  /**
35427   * Retrieve a `ParseSpan` from `start` to the current position (or to `artificialEndIndex` if
35428   * provided).
35429   *
35430   * @param start Position from which the `ParseSpan` will start.
35431   * @param artificialEndIndex Optional ending index to be used if provided (and if greater than the
35432   *     natural ending index)
35433   */
35434
35435
35436  span(start, artificialEndIndex) {
35437    let endIndex = this.currentEndIndex;
35438
35439    if (artificialEndIndex !== undefined && artificialEndIndex > this.currentEndIndex) {
35440      endIndex = artificialEndIndex;
35441    } // In some unusual parsing scenarios (like when certain tokens are missing and an `EmptyExpr` is
35442    // being created), the current token may already be advanced beyond the `currentEndIndex`. This
35443    // appears to be a deep-seated parser bug.
35444    //
35445    // As a workaround for now, swap the start and end indices to ensure a valid `ParseSpan`.
35446    // TODO(alxhub): fix the bug upstream in the parser state, and remove this workaround.
35447
35448
35449    if (start > endIndex) {
35450      const tmp = endIndex;
35451      endIndex = start;
35452      start = tmp;
35453    }
35454
35455    return new ParseSpan(start, endIndex);
35456  }
35457
35458  sourceSpan(start, artificialEndIndex) {
35459    const serial = `${start}@${this.inputIndex}:${artificialEndIndex}`;
35460
35461    if (!this.sourceSpanCache.has(serial)) {
35462      this.sourceSpanCache.set(serial, this.span(start, artificialEndIndex).toAbsolute(this.absoluteOffset));
35463    }
35464
35465    return this.sourceSpanCache.get(serial);
35466  }
35467
35468  advance() {
35469    this.index++;
35470  }
35471  /**
35472   * Executes a callback in the provided context.
35473   */
35474
35475
35476  withContext(context, cb) {
35477    this.context |= context;
35478    const ret = cb();
35479    this.context ^= context;
35480    return ret;
35481  }
35482
35483  consumeOptionalCharacter(code) {
35484    if (this.next.isCharacter(code)) {
35485      this.advance();
35486      return true;
35487    } else {
35488      return false;
35489    }
35490  }
35491
35492  peekKeywordLet() {
35493    return this.next.isKeywordLet();
35494  }
35495
35496  peekKeywordAs() {
35497    return this.next.isKeywordAs();
35498  }
35499  /**
35500   * Consumes an expected character, otherwise emits an error about the missing expected character
35501   * and skips over the token stream until reaching a recoverable point.
35502   *
35503   * See `this.error` and `this.skip` for more details.
35504   */
35505
35506
35507  expectCharacter(code) {
35508    if (this.consumeOptionalCharacter(code)) return;
35509    this.error(`Missing expected ${String.fromCharCode(code)}`);
35510  }
35511
35512  consumeOptionalOperator(op) {
35513    if (this.next.isOperator(op)) {
35514      this.advance();
35515      return true;
35516    } else {
35517      return false;
35518    }
35519  }
35520
35521  expectOperator(operator) {
35522    if (this.consumeOptionalOperator(operator)) return;
35523    this.error(`Missing expected operator ${operator}`);
35524  }
35525
35526  prettyPrintToken(tok) {
35527    return tok === EOF ? 'end of input' : `token ${tok}`;
35528  }
35529
35530  expectIdentifierOrKeyword() {
35531    const n = this.next;
35532
35533    if (!n.isIdentifier() && !n.isKeyword()) {
35534      if (n.isPrivateIdentifier()) {
35535        this._reportErrorForPrivateIdentifier(n, 'expected identifier or keyword');
35536      } else {
35537        this.error(`Unexpected ${this.prettyPrintToken(n)}, expected identifier or keyword`);
35538      }
35539
35540      return null;
35541    }
35542
35543    this.advance();
35544    return n.toString();
35545  }
35546
35547  expectIdentifierOrKeywordOrString() {
35548    const n = this.next;
35549
35550    if (!n.isIdentifier() && !n.isKeyword() && !n.isString()) {
35551      if (n.isPrivateIdentifier()) {
35552        this._reportErrorForPrivateIdentifier(n, 'expected identifier, keyword or string');
35553      } else {
35554        this.error(`Unexpected ${this.prettyPrintToken(n)}, expected identifier, keyword, or string`);
35555      }
35556
35557      return '';
35558    }
35559
35560    this.advance();
35561    return n.toString();
35562  }
35563
35564  parseChain() {
35565    const exprs = [];
35566    const start = this.inputIndex;
35567
35568    while (this.index < this.tokens.length) {
35569      const expr = this.parsePipe();
35570      exprs.push(expr);
35571
35572      if (this.consumeOptionalCharacter($SEMICOLON)) {
35573        if (!(this.parseFlags & 1
35574        /* ParseFlags.Action */
35575        )) {
35576          this.error('Binding expression cannot contain chained expression');
35577        }
35578
35579        while (this.consumeOptionalCharacter($SEMICOLON)) {} // read all semicolons
35580
35581      } else if (this.index < this.tokens.length) {
35582        const errorIndex = this.index;
35583        this.error(`Unexpected token '${this.next}'`); // The `error` call above will skip ahead to the next recovery point in an attempt to
35584        // recover part of the expression, but that might be the token we started from which will
35585        // lead to an infinite loop. If that's the case, break the loop assuming that we can't
35586        // parse further.
35587
35588        if (this.index === errorIndex) {
35589          break;
35590        }
35591      }
35592    }
35593
35594    if (exprs.length === 0) {
35595      // We have no expressions so create an empty expression that spans the entire input length
35596      const artificialStart = this.offset;
35597      const artificialEnd = this.offset + this.input.length;
35598      return new EmptyExpr(this.span(artificialStart, artificialEnd), this.sourceSpan(artificialStart, artificialEnd));
35599    }
35600
35601    if (exprs.length == 1) return exprs[0];
35602    return new Chain(this.span(start), this.sourceSpan(start), exprs);
35603  }
35604
35605  parsePipe() {
35606    const start = this.inputIndex;
35607    let result = this.parseExpression();
35608
35609    if (this.consumeOptionalOperator('|')) {
35610      if (this.parseFlags & 1
35611      /* ParseFlags.Action */
35612      ) {
35613        this.error('Cannot have a pipe in an action expression');
35614      }
35615
35616      do {
35617        const nameStart = this.inputIndex;
35618        let nameId = this.expectIdentifierOrKeyword();
35619        let nameSpan;
35620        let fullSpanEnd = undefined;
35621
35622        if (nameId !== null) {
35623          nameSpan = this.sourceSpan(nameStart);
35624        } else {
35625          // No valid identifier was found, so we'll assume an empty pipe name ('').
35626          nameId = ''; // However, there may have been whitespace present between the pipe character and the next
35627          // token in the sequence (or the end of input). We want to track this whitespace so that
35628          // the `BindingPipe` we produce covers not just the pipe character, but any trailing
35629          // whitespace beyond it. Another way of thinking about this is that the zero-length name
35630          // is assumed to be at the end of any whitespace beyond the pipe character.
35631          //
35632          // Therefore, we push the end of the `ParseSpan` for this pipe all the way up to the
35633          // beginning of the next token, or until the end of input if the next token is EOF.
35634
35635          fullSpanEnd = this.next.index !== -1 ? this.next.index : this.input.length + this.offset; // The `nameSpan` for an empty pipe name is zero-length at the end of any whitespace
35636          // beyond the pipe character.
35637
35638          nameSpan = new ParseSpan(fullSpanEnd, fullSpanEnd).toAbsolute(this.absoluteOffset);
35639        }
35640
35641        const args = [];
35642
35643        while (this.consumeOptionalCharacter($COLON)) {
35644          args.push(this.parseExpression()); // If there are additional expressions beyond the name, then the artificial end for the
35645          // name is no longer relevant.
35646        }
35647
35648        result = new BindingPipe(this.span(start), this.sourceSpan(start, fullSpanEnd), result, nameId, args, nameSpan);
35649      } while (this.consumeOptionalOperator('|'));
35650    }
35651
35652    return result;
35653  }
35654
35655  parseExpression() {
35656    return this.parseConditional();
35657  }
35658
35659  parseConditional() {
35660    const start = this.inputIndex;
35661    const result = this.parseLogicalOr();
35662
35663    if (this.consumeOptionalOperator('?')) {
35664      const yes = this.parsePipe();
35665      let no;
35666
35667      if (!this.consumeOptionalCharacter($COLON)) {
35668        const end = this.inputIndex;
35669        const expression = this.input.substring(start, end);
35670        this.error(`Conditional expression ${expression} requires all 3 expressions`);
35671        no = new EmptyExpr(this.span(start), this.sourceSpan(start));
35672      } else {
35673        no = this.parsePipe();
35674      }
35675
35676      return new Conditional(this.span(start), this.sourceSpan(start), result, yes, no);
35677    } else {
35678      return result;
35679    }
35680  }
35681
35682  parseLogicalOr() {
35683    // '||'
35684    const start = this.inputIndex;
35685    let result = this.parseLogicalAnd();
35686
35687    while (this.consumeOptionalOperator('||')) {
35688      const right = this.parseLogicalAnd();
35689      result = new Binary(this.span(start), this.sourceSpan(start), '||', result, right);
35690    }
35691
35692    return result;
35693  }
35694
35695  parseLogicalAnd() {
35696    // '&&'
35697    const start = this.inputIndex;
35698    let result = this.parseNullishCoalescing();
35699
35700    while (this.consumeOptionalOperator('&&')) {
35701      const right = this.parseNullishCoalescing();
35702      result = new Binary(this.span(start), this.sourceSpan(start), '&&', result, right);
35703    }
35704
35705    return result;
35706  }
35707
35708  parseNullishCoalescing() {
35709    // '??'
35710    const start = this.inputIndex;
35711    let result = this.parseEquality();
35712
35713    while (this.consumeOptionalOperator('??')) {
35714      const right = this.parseEquality();
35715      result = new Binary(this.span(start), this.sourceSpan(start), '??', result, right);
35716    }
35717
35718    return result;
35719  }
35720
35721  parseEquality() {
35722    // '==','!=','===','!=='
35723    const start = this.inputIndex;
35724    let result = this.parseRelational();
35725
35726    while (this.next.type == TokenType.Operator) {
35727      const operator = this.next.strValue;
35728
35729      switch (operator) {
35730        case '==':
35731        case '===':
35732        case '!=':
35733        case '!==':
35734          this.advance();
35735          const right = this.parseRelational();
35736          result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
35737          continue;
35738      }
35739
35740      break;
35741    }
35742
35743    return result;
35744  }
35745
35746  parseRelational() {
35747    // '<', '>', '<=', '>='
35748    const start = this.inputIndex;
35749    let result = this.parseAdditive();
35750
35751    while (this.next.type == TokenType.Operator) {
35752      const operator = this.next.strValue;
35753
35754      switch (operator) {
35755        case '<':
35756        case '>':
35757        case '<=':
35758        case '>=':
35759          this.advance();
35760          const right = this.parseAdditive();
35761          result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
35762          continue;
35763      }
35764
35765      break;
35766    }
35767
35768    return result;
35769  }
35770
35771  parseAdditive() {
35772    // '+', '-'
35773    const start = this.inputIndex;
35774    let result = this.parseMultiplicative();
35775
35776    while (this.next.type == TokenType.Operator) {
35777      const operator = this.next.strValue;
35778
35779      switch (operator) {
35780        case '+':
35781        case '-':
35782          this.advance();
35783          let right = this.parseMultiplicative();
35784          result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
35785          continue;
35786      }
35787
35788      break;
35789    }
35790
35791    return result;
35792  }
35793
35794  parseMultiplicative() {
35795    // '*', '%', '/'
35796    const start = this.inputIndex;
35797    let result = this.parsePrefix();
35798
35799    while (this.next.type == TokenType.Operator) {
35800      const operator = this.next.strValue;
35801
35802      switch (operator) {
35803        case '*':
35804        case '%':
35805        case '/':
35806          this.advance();
35807          let right = this.parsePrefix();
35808          result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
35809          continue;
35810      }
35811
35812      break;
35813    }
35814
35815    return result;
35816  }
35817
35818  parsePrefix() {
35819    if (this.next.type == TokenType.Operator) {
35820      const start = this.inputIndex;
35821      const operator = this.next.strValue;
35822      let result;
35823
35824      switch (operator) {
35825        case '+':
35826          this.advance();
35827          result = this.parsePrefix();
35828          return Unary.createPlus(this.span(start), this.sourceSpan(start), result);
35829
35830        case '-':
35831          this.advance();
35832          result = this.parsePrefix();
35833          return Unary.createMinus(this.span(start), this.sourceSpan(start), result);
35834
35835        case '!':
35836          this.advance();
35837          result = this.parsePrefix();
35838          return new PrefixNot(this.span(start), this.sourceSpan(start), result);
35839      }
35840    }
35841
35842    return this.parseCallChain();
35843  }
35844
35845  parseCallChain() {
35846    const start = this.inputIndex;
35847    let result = this.parsePrimary();
35848
35849    while (true) {
35850      if (this.consumeOptionalCharacter($PERIOD)) {
35851        result = this.parseAccessMember(result, start, false);
35852      } else if (this.consumeOptionalOperator('?.')) {
35853        if (this.consumeOptionalCharacter($LPAREN)) {
35854          result = this.parseCall(result, start, true);
35855        } else {
35856          result = this.consumeOptionalCharacter($LBRACKET) ? this.parseKeyedReadOrWrite(result, start, true) : this.parseAccessMember(result, start, true);
35857        }
35858      } else if (this.consumeOptionalCharacter($LBRACKET)) {
35859        result = this.parseKeyedReadOrWrite(result, start, false);
35860      } else if (this.consumeOptionalCharacter($LPAREN)) {
35861        result = this.parseCall(result, start, false);
35862      } else if (this.consumeOptionalOperator('!')) {
35863        result = new NonNullAssert(this.span(start), this.sourceSpan(start), result);
35864      } else {
35865        return result;
35866      }
35867    }
35868  }
35869
35870  parsePrimary() {
35871    const start = this.inputIndex;
35872
35873    if (this.consumeOptionalCharacter($LPAREN)) {
35874      this.rparensExpected++;
35875      const result = this.parsePipe();
35876      this.rparensExpected--;
35877      this.expectCharacter($RPAREN);
35878      return result;
35879    } else if (this.next.isKeywordNull()) {
35880      this.advance();
35881      return new LiteralPrimitive(this.span(start), this.sourceSpan(start), null);
35882    } else if (this.next.isKeywordUndefined()) {
35883      this.advance();
35884      return new LiteralPrimitive(this.span(start), this.sourceSpan(start), void 0);
35885    } else if (this.next.isKeywordTrue()) {
35886      this.advance();
35887      return new LiteralPrimitive(this.span(start), this.sourceSpan(start), true);
35888    } else if (this.next.isKeywordFalse()) {
35889      this.advance();
35890      return new LiteralPrimitive(this.span(start), this.sourceSpan(start), false);
35891    } else if (this.next.isKeywordThis()) {
35892      this.advance();
35893      return new ThisReceiver(this.span(start), this.sourceSpan(start));
35894    } else if (this.consumeOptionalCharacter($LBRACKET)) {
35895      this.rbracketsExpected++;
35896      const elements = this.parseExpressionList($RBRACKET);
35897      this.rbracketsExpected--;
35898      this.expectCharacter($RBRACKET);
35899      return new LiteralArray(this.span(start), this.sourceSpan(start), elements);
35900    } else if (this.next.isCharacter($LBRACE)) {
35901      return this.parseLiteralMap();
35902    } else if (this.next.isIdentifier()) {
35903      return this.parseAccessMember(new ImplicitReceiver(this.span(start), this.sourceSpan(start)), start, false);
35904    } else if (this.next.isNumber()) {
35905      const value = this.next.toNumber();
35906      this.advance();
35907      return new LiteralPrimitive(this.span(start), this.sourceSpan(start), value);
35908    } else if (this.next.isString()) {
35909      const literalValue = this.next.toString();
35910      this.advance();
35911      return new LiteralPrimitive(this.span(start), this.sourceSpan(start), literalValue);
35912    } else if (this.next.isPrivateIdentifier()) {
35913      this._reportErrorForPrivateIdentifier(this.next, null);
35914
35915      return new EmptyExpr(this.span(start), this.sourceSpan(start));
35916    } else if (this.index >= this.tokens.length) {
35917      this.error(`Unexpected end of expression: ${this.input}`);
35918      return new EmptyExpr(this.span(start), this.sourceSpan(start));
35919    } else {
35920      this.error(`Unexpected token ${this.next}`);
35921      return new EmptyExpr(this.span(start), this.sourceSpan(start));
35922    }
35923  }
35924
35925  parseExpressionList(terminator) {
35926    const result = [];
35927
35928    do {
35929      if (!this.next.isCharacter(terminator)) {
35930        result.push(this.parsePipe());
35931      } else {
35932        break;
35933      }
35934    } while (this.consumeOptionalCharacter($COMMA));
35935
35936    return result;
35937  }
35938
35939  parseLiteralMap() {
35940    const keys = [];
35941    const values = [];
35942    const start = this.inputIndex;
35943    this.expectCharacter($LBRACE);
35944
35945    if (!this.consumeOptionalCharacter($RBRACE)) {
35946      this.rbracesExpected++;
35947
35948      do {
35949        const keyStart = this.inputIndex;
35950        const quoted = this.next.isString();
35951        const key = this.expectIdentifierOrKeywordOrString();
35952        keys.push({
35953          key,
35954          quoted
35955        }); // Properties with quoted keys can't use the shorthand syntax.
35956
35957        if (quoted) {
35958          this.expectCharacter($COLON);
35959          values.push(this.parsePipe());
35960        } else if (this.consumeOptionalCharacter($COLON)) {
35961          values.push(this.parsePipe());
35962        } else {
35963          const span = this.span(keyStart);
35964          const sourceSpan = this.sourceSpan(keyStart);
35965          values.push(new PropertyRead(span, sourceSpan, sourceSpan, new ImplicitReceiver(span, sourceSpan), key));
35966        }
35967      } while (this.consumeOptionalCharacter($COMMA));
35968
35969      this.rbracesExpected--;
35970      this.expectCharacter($RBRACE);
35971    }
35972
35973    return new LiteralMap(this.span(start), this.sourceSpan(start), keys, values);
35974  }
35975
35976  parseAccessMember(readReceiver, start, isSafe) {
35977    const nameStart = this.inputIndex;
35978    const id = this.withContext(ParseContextFlags.Writable, () => {
35979      const id = this.expectIdentifierOrKeyword() ?? '';
35980
35981      if (id.length === 0) {
35982        this.error(`Expected identifier for property access`, readReceiver.span.end);
35983      }
35984
35985      return id;
35986    });
35987    const nameSpan = this.sourceSpan(nameStart);
35988    let receiver;
35989
35990    if (isSafe) {
35991      if (this.consumeOptionalAssignment()) {
35992        this.error('The \'?.\' operator cannot be used in the assignment');
35993        receiver = new EmptyExpr(this.span(start), this.sourceSpan(start));
35994      } else {
35995        receiver = new SafePropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
35996      }
35997    } else {
35998      if (this.consumeOptionalAssignment()) {
35999        if (!(this.parseFlags & 1
36000        /* ParseFlags.Action */
36001        )) {
36002          this.error('Bindings cannot contain assignments');
36003          return new EmptyExpr(this.span(start), this.sourceSpan(start));
36004        }
36005
36006        const value = this.parseConditional();
36007        receiver = new PropertyWrite(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id, value);
36008      } else {
36009        receiver = new PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
36010      }
36011    }
36012
36013    return receiver;
36014  }
36015
36016  parseCall(receiver, start, isSafe) {
36017    const argumentStart = this.inputIndex;
36018    this.rparensExpected++;
36019    const args = this.parseCallArguments();
36020    const argumentSpan = this.span(argumentStart, this.inputIndex).toAbsolute(this.absoluteOffset);
36021    this.expectCharacter($RPAREN);
36022    this.rparensExpected--;
36023    const span = this.span(start);
36024    const sourceSpan = this.sourceSpan(start);
36025    return isSafe ? new SafeCall(span, sourceSpan, receiver, args, argumentSpan) : new Call(span, sourceSpan, receiver, args, argumentSpan);
36026  }
36027
36028  consumeOptionalAssignment() {
36029    // When parsing assignment events (originating from two-way-binding aka banana-in-a-box syntax),
36030    // it is valid for the primary expression to be terminated by the non-null operator. This
36031    // primary expression is substituted as LHS of the assignment operator to achieve
36032    // two-way-binding, such that the LHS could be the non-null operator. The grammar doesn't
36033    // naturally allow for this syntax, so assignment events are parsed specially.
36034    if (this.parseFlags & 2
36035    /* ParseFlags.AssignmentEvent */
36036    && this.next.isOperator('!') && this.peek(1).isOperator('=')) {
36037      // First skip over the ! operator.
36038      this.advance(); // Then skip over the = operator, to fully consume the optional assignment operator.
36039
36040      this.advance();
36041      return true;
36042    }
36043
36044    return this.consumeOptionalOperator('=');
36045  }
36046
36047  parseCallArguments() {
36048    if (this.next.isCharacter($RPAREN)) return [];
36049    const positionals = [];
36050
36051    do {
36052      positionals.push(this.parsePipe());
36053    } while (this.consumeOptionalCharacter($COMMA));
36054
36055    return positionals;
36056  }
36057  /**
36058   * Parses an identifier, a keyword, a string with an optional `-` in between,
36059   * and returns the string along with its absolute source span.
36060   */
36061
36062
36063  expectTemplateBindingKey() {
36064    let result = '';
36065    let operatorFound = false;
36066    const start = this.currentAbsoluteOffset;
36067
36068    do {
36069      result += this.expectIdentifierOrKeywordOrString();
36070      operatorFound = this.consumeOptionalOperator('-');
36071
36072      if (operatorFound) {
36073        result += '-';
36074      }
36075    } while (operatorFound);
36076
36077    return {
36078      source: result,
36079      span: new AbsoluteSourceSpan(start, start + result.length)
36080    };
36081  }
36082  /**
36083   * Parse microsyntax template expression and return a list of bindings or
36084   * parsing errors in case the given expression is invalid.
36085   *
36086   * For example,
36087   * ```
36088   *   <div *ngFor="let item of items; index as i; trackBy: func">
36089   * ```
36090   * contains five bindings:
36091   * 1. ngFor -> null
36092   * 2. item -> NgForOfContext.$implicit
36093   * 3. ngForOf -> items
36094   * 4. i -> NgForOfContext.index
36095   * 5. ngForTrackBy -> func
36096   *
36097   * For a full description of the microsyntax grammar, see
36098   * https://gist.github.com/mhevery/d3530294cff2e4a1b3fe15ff75d08855
36099   *
36100   * @param templateKey name of the microsyntax directive, like ngIf, ngFor,
36101   * without the *, along with its absolute span.
36102   */
36103
36104
36105  parseTemplateBindings(templateKey) {
36106    const bindings = []; // The first binding is for the template key itself
36107    // In *ngFor="let item of items", key = "ngFor", value = null
36108    // In *ngIf="cond | pipe", key = "ngIf", value = "cond | pipe"
36109
36110    bindings.push(...this.parseDirectiveKeywordBindings(templateKey));
36111
36112    while (this.index < this.tokens.length) {
36113      // If it starts with 'let', then this must be variable declaration
36114      const letBinding = this.parseLetBinding();
36115
36116      if (letBinding) {
36117        bindings.push(letBinding);
36118      } else {
36119        // Two possible cases here, either `value "as" key` or
36120        // "directive-keyword expression". We don't know which case, but both
36121        // "value" and "directive-keyword" are template binding key, so consume
36122        // the key first.
36123        const key = this.expectTemplateBindingKey(); // Peek at the next token, if it is "as" then this must be variable
36124        // declaration.
36125
36126        const binding = this.parseAsBinding(key);
36127
36128        if (binding) {
36129          bindings.push(binding);
36130        } else {
36131          // Otherwise the key must be a directive keyword, like "of". Transform
36132          // the key to actual key. Eg. of -> ngForOf, trackBy -> ngForTrackBy
36133          key.source = templateKey.source + key.source.charAt(0).toUpperCase() + key.source.substring(1);
36134          bindings.push(...this.parseDirectiveKeywordBindings(key));
36135        }
36136      }
36137
36138      this.consumeStatementTerminator();
36139    }
36140
36141    return new TemplateBindingParseResult(bindings, []
36142    /* warnings */
36143    , this.errors);
36144  }
36145
36146  parseKeyedReadOrWrite(receiver, start, isSafe) {
36147    return this.withContext(ParseContextFlags.Writable, () => {
36148      this.rbracketsExpected++;
36149      const key = this.parsePipe();
36150
36151      if (key instanceof EmptyExpr) {
36152        this.error(`Key access cannot be empty`);
36153      }
36154
36155      this.rbracketsExpected--;
36156      this.expectCharacter($RBRACKET);
36157
36158      if (this.consumeOptionalOperator('=')) {
36159        if (isSafe) {
36160          this.error('The \'?.\' operator cannot be used in the assignment');
36161        } else {
36162          const value = this.parseConditional();
36163          return new KeyedWrite(this.span(start), this.sourceSpan(start), receiver, key, value);
36164        }
36165      } else {
36166        return isSafe ? new SafeKeyedRead(this.span(start), this.sourceSpan(start), receiver, key) : new KeyedRead(this.span(start), this.sourceSpan(start), receiver, key);
36167      }
36168
36169      return new EmptyExpr(this.span(start), this.sourceSpan(start));
36170    });
36171  }
36172  /**
36173   * Parse a directive keyword, followed by a mandatory expression.
36174   * For example, "of items", "trackBy: func".
36175   * The bindings are: ngForOf -> items, ngForTrackBy -> func
36176   * There could be an optional "as" binding that follows the expression.
36177   * For example,
36178   * ```
36179   *   *ngFor="let item of items | slice:0:1 as collection".
36180   *                    ^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
36181   *               keyword    bound target   optional 'as' binding
36182   * ```
36183   *
36184   * @param key binding key, for example, ngFor, ngIf, ngForOf, along with its
36185   * absolute span.
36186   */
36187
36188
36189  parseDirectiveKeywordBindings(key) {
36190    const bindings = [];
36191    this.consumeOptionalCharacter($COLON); // trackBy: trackByFunction
36192
36193    const value = this.getDirectiveBoundTarget();
36194    let spanEnd = this.currentAbsoluteOffset; // The binding could optionally be followed by "as". For example,
36195    // *ngIf="cond | pipe as x". In this case, the key in the "as" binding
36196    // is "x" and the value is the template key itself ("ngIf"). Note that the
36197    // 'key' in the current context now becomes the "value" in the next binding.
36198
36199    const asBinding = this.parseAsBinding(key);
36200
36201    if (!asBinding) {
36202      this.consumeStatementTerminator();
36203      spanEnd = this.currentAbsoluteOffset;
36204    }
36205
36206    const sourceSpan = new AbsoluteSourceSpan(key.span.start, spanEnd);
36207    bindings.push(new ExpressionBinding(sourceSpan, key, value));
36208
36209    if (asBinding) {
36210      bindings.push(asBinding);
36211    }
36212
36213    return bindings;
36214  }
36215  /**
36216   * Return the expression AST for the bound target of a directive keyword
36217   * binding. For example,
36218   * ```
36219   *   *ngIf="condition | pipe"
36220   *          ^^^^^^^^^^^^^^^^ bound target for "ngIf"
36221   *   *ngFor="let item of items"
36222   *                       ^^^^^ bound target for "ngForOf"
36223   * ```
36224   */
36225
36226
36227  getDirectiveBoundTarget() {
36228    if (this.next === EOF || this.peekKeywordAs() || this.peekKeywordLet()) {
36229      return null;
36230    }
36231
36232    const ast = this.parsePipe(); // example: "condition | async"
36233
36234    const {
36235      start,
36236      end
36237    } = ast.span;
36238    const value = this.input.substring(start, end);
36239    return new ASTWithSource(ast, value, this.location, this.absoluteOffset + start, this.errors);
36240  }
36241  /**
36242   * Return the binding for a variable declared using `as`. Note that the order
36243   * of the key-value pair in this declaration is reversed. For example,
36244   * ```
36245   *   *ngFor="let item of items; index as i"
36246   *                              ^^^^^    ^
36247   *                              value    key
36248   * ```
36249   *
36250   * @param value name of the value in the declaration, "ngIf" in the example
36251   * above, along with its absolute span.
36252   */
36253
36254
36255  parseAsBinding(value) {
36256    if (!this.peekKeywordAs()) {
36257      return null;
36258    }
36259
36260    this.advance(); // consume the 'as' keyword
36261
36262    const key = this.expectTemplateBindingKey();
36263    this.consumeStatementTerminator();
36264    const sourceSpan = new AbsoluteSourceSpan(value.span.start, this.currentAbsoluteOffset);
36265    return new VariableBinding(sourceSpan, key, value);
36266  }
36267  /**
36268   * Return the binding for a variable declared using `let`. For example,
36269   * ```
36270   *   *ngFor="let item of items; let i=index;"
36271   *           ^^^^^^^^           ^^^^^^^^^^^
36272   * ```
36273   * In the first binding, `item` is bound to `NgForOfContext.$implicit`.
36274   * In the second binding, `i` is bound to `NgForOfContext.index`.
36275   */
36276
36277
36278  parseLetBinding() {
36279    if (!this.peekKeywordLet()) {
36280      return null;
36281    }
36282
36283    const spanStart = this.currentAbsoluteOffset;
36284    this.advance(); // consume the 'let' keyword
36285
36286    const key = this.expectTemplateBindingKey();
36287    let value = null;
36288
36289    if (this.consumeOptionalOperator('=')) {
36290      value = this.expectTemplateBindingKey();
36291    }
36292
36293    this.consumeStatementTerminator();
36294    const sourceSpan = new AbsoluteSourceSpan(spanStart, this.currentAbsoluteOffset);
36295    return new VariableBinding(sourceSpan, key, value);
36296  }
36297  /**
36298   * Consume the optional statement terminator: semicolon or comma.
36299   */
36300
36301
36302  consumeStatementTerminator() {
36303    this.consumeOptionalCharacter($SEMICOLON) || this.consumeOptionalCharacter($COMMA);
36304  }
36305  /**
36306   * Records an error and skips over the token stream until reaching a recoverable point. See
36307   * `this.skip` for more details on token skipping.
36308   */
36309
36310
36311  error(message, index = null) {
36312    this.errors.push(new ParserError(message, this.input, this.locationText(index), this.location));
36313    this.skip();
36314  }
36315
36316  locationText(index = null) {
36317    if (index == null) index = this.index;
36318    return index < this.tokens.length ? `at column ${this.tokens[index].index + 1} in` : `at the end of the expression`;
36319  }
36320  /**
36321   * Records an error for an unexpected private identifier being discovered.
36322   * @param token Token representing a private identifier.
36323   * @param extraMessage Optional additional message being appended to the error.
36324   */
36325
36326
36327  _reportErrorForPrivateIdentifier(token, extraMessage) {
36328    let errorMessage = `Private identifiers are not supported. Unexpected private identifier: ${token}`;
36329
36330    if (extraMessage !== null) {
36331      errorMessage += `, ${extraMessage}`;
36332    }
36333
36334    this.error(errorMessage);
36335  }
36336  /**
36337   * Error recovery should skip tokens until it encounters a recovery point.
36338   *
36339   * The following are treated as unconditional recovery points:
36340   *   - end of input
36341   *   - ';' (parseChain() is always the root production, and it expects a ';')
36342   *   - '|' (since pipes may be chained and each pipe expression may be treated independently)
36343   *
36344   * The following are conditional recovery points:
36345   *   - ')', '}', ']' if one of calling productions is expecting one of these symbols
36346   *     - This allows skip() to recover from errors such as '(a.) + 1' allowing more of the AST to
36347   *       be retained (it doesn't skip any tokens as the ')' is retained because of the '(' begins
36348   *       an '(' <expr> ')' production).
36349   *       The recovery points of grouping symbols must be conditional as they must be skipped if
36350   *       none of the calling productions are not expecting the closing token else we will never
36351   *       make progress in the case of an extraneous group closing symbol (such as a stray ')').
36352   *       That is, we skip a closing symbol if we are not in a grouping production.
36353   *   - '=' in a `Writable` context
36354   *     - In this context, we are able to recover after seeing the `=` operator, which
36355   *       signals the presence of an independent rvalue expression following the `=` operator.
36356   *
36357   * If a production expects one of these token it increments the corresponding nesting count,
36358   * and then decrements it just prior to checking if the token is in the input.
36359   */
36360
36361
36362  skip() {
36363    let n = this.next;
36364
36365    while (this.index < this.tokens.length && !n.isCharacter($SEMICOLON) && !n.isOperator('|') && (this.rparensExpected <= 0 || !n.isCharacter($RPAREN)) && (this.rbracesExpected <= 0 || !n.isCharacter($RBRACE)) && (this.rbracketsExpected <= 0 || !n.isCharacter($RBRACKET)) && (!(this.context & ParseContextFlags.Writable) || !n.isOperator('='))) {
36366      if (this.next.isError()) {
36367        this.errors.push(new ParserError(this.next.toString(), this.input, this.locationText(), this.location));
36368      }
36369
36370      this.advance();
36371      n = this.next;
36372    }
36373  }
36374
36375}
36376
36377class SimpleExpressionChecker extends RecursiveAstVisitor {
36378  constructor() {
36379    super(...arguments);
36380    this.errors = [];
36381  }
36382
36383  visitPipe() {
36384    this.errors.push('pipes');
36385  }
36386
36387}
36388/**
36389 * Computes the real offset in the original template for indexes in an interpolation.
36390 *
36391 * Because templates can have encoded HTML entities and the input passed to the parser at this stage
36392 * of the compiler is the _decoded_ value, we need to compute the real offset using the original
36393 * encoded values in the interpolated tokens. Note that this is only a special case handling for
36394 * `MlParserTokenType.ENCODED_ENTITY` token types. All other interpolated tokens are expected to
36395 * have parts which exactly match the input string for parsing the interpolation.
36396 *
36397 * @param interpolatedTokens The tokens for the interpolated value.
36398 *
36399 * @returns A map of index locations in the decoded template to indexes in the original template
36400 */
36401
36402
36403function getIndexMapForOriginalTemplate(interpolatedTokens) {
36404  let offsetMap = new Map();
36405  let consumedInOriginalTemplate = 0;
36406  let consumedInInput = 0;
36407  let tokenIndex = 0;
36408
36409  while (tokenIndex < interpolatedTokens.length) {
36410    const currentToken = interpolatedTokens[tokenIndex];
36411
36412    if (currentToken.type === 9
36413    /* MlParserTokenType.ENCODED_ENTITY */
36414    ) {
36415      const [decoded, encoded] = currentToken.parts;
36416      consumedInOriginalTemplate += encoded.length;
36417      consumedInInput += decoded.length;
36418    } else {
36419      const lengthOfParts = currentToken.parts.reduce((sum, current) => sum + current.length, 0);
36420      consumedInInput += lengthOfParts;
36421      consumedInOriginalTemplate += lengthOfParts;
36422    }
36423
36424    offsetMap.set(consumedInInput, consumedInOriginalTemplate);
36425    tokenIndex++;
36426  }
36427
36428  return offsetMap;
36429}
36430/**
36431 * @license
36432 * Copyright Google LLC All Rights Reserved.
36433 *
36434 * Use of this source code is governed by an MIT-style license that can be
36435 * found in the LICENSE file at https://angular.io/license
36436 */
36437
36438
36439class NodeWithI18n {
36440  constructor(sourceSpan, i18n) {
36441    this.sourceSpan = sourceSpan;
36442    this.i18n = i18n;
36443  }
36444
36445}
36446
36447class Text extends NodeWithI18n {
36448  constructor(value, sourceSpan, tokens, i18n) {
36449    super(sourceSpan, i18n);
36450    this.value = value;
36451    this.tokens = tokens;
36452  }
36453
36454  visit(visitor, context) {
36455    return visitor.visitText(this, context);
36456  }
36457
36458}
36459
36460class Expansion extends NodeWithI18n {
36461  constructor(switchValue, type, cases, sourceSpan, switchValueSourceSpan, i18n) {
36462    super(sourceSpan, i18n);
36463    this.switchValue = switchValue;
36464    this.type = type;
36465    this.cases = cases;
36466    this.switchValueSourceSpan = switchValueSourceSpan;
36467  }
36468
36469  visit(visitor, context) {
36470    return visitor.visitExpansion(this, context);
36471  }
36472
36473}
36474
36475class ExpansionCase {
36476  constructor(value, expression, sourceSpan, valueSourceSpan, expSourceSpan) {
36477    this.value = value;
36478    this.expression = expression;
36479    this.sourceSpan = sourceSpan;
36480    this.valueSourceSpan = valueSourceSpan;
36481    this.expSourceSpan = expSourceSpan;
36482  }
36483
36484  visit(visitor, context) {
36485    return visitor.visitExpansionCase(this, context);
36486  }
36487
36488}
36489
36490class Attribute extends NodeWithI18n {
36491  constructor(name, value, sourceSpan, keySpan, valueSpan, valueTokens, i18n) {
36492    super(sourceSpan, i18n);
36493    this.name = name;
36494    this.value = value;
36495    this.keySpan = keySpan;
36496    this.valueSpan = valueSpan;
36497    this.valueTokens = valueTokens;
36498  }
36499
36500  visit(visitor, context) {
36501    return visitor.visitAttribute(this, context);
36502  }
36503
36504}
36505
36506class Element extends NodeWithI18n {
36507  constructor(name, attrs, children, sourceSpan, startSourceSpan, endSourceSpan = null, i18n) {
36508    super(sourceSpan, i18n);
36509    this.name = name;
36510    this.attrs = attrs;
36511    this.children = children;
36512    this.startSourceSpan = startSourceSpan;
36513    this.endSourceSpan = endSourceSpan;
36514  }
36515
36516  visit(visitor, context) {
36517    return visitor.visitElement(this, context);
36518  }
36519
36520}
36521
36522class Comment {
36523  constructor(value, sourceSpan) {
36524    this.value = value;
36525    this.sourceSpan = sourceSpan;
36526  }
36527
36528  visit(visitor, context) {
36529    return visitor.visitComment(this, context);
36530  }
36531
36532}
36533
36534function visitAll(visitor, nodes, context = null) {
36535  const result = [];
36536  const visit = visitor.visit ? ast => visitor.visit(ast, context) || ast.visit(visitor, context) : ast => ast.visit(visitor, context);
36537  nodes.forEach(ast => {
36538    const astResult = visit(ast);
36539
36540    if (astResult) {
36541      result.push(astResult);
36542    }
36543  });
36544  return result;
36545}
36546
36547class RecursiveVisitor {
36548  constructor() {}
36549
36550  visitElement(ast, context) {
36551    this.visitChildren(context, visit => {
36552      visit(ast.attrs);
36553      visit(ast.children);
36554    });
36555  }
36556
36557  visitAttribute(ast, context) {}
36558
36559  visitText(ast, context) {}
36560
36561  visitComment(ast, context) {}
36562
36563  visitExpansion(ast, context) {
36564    return this.visitChildren(context, visit => {
36565      visit(ast.cases);
36566    });
36567  }
36568
36569  visitExpansionCase(ast, context) {}
36570
36571  visitChildren(context, cb) {
36572    let results = [];
36573    let t = this;
36574
36575    function visit(children) {
36576      if (children) results.push(visitAll(t, children, context));
36577    }
36578
36579    cb(visit);
36580    return Array.prototype.concat.apply([], results);
36581  }
36582
36583}
36584/**
36585 * @license
36586 * Copyright Google LLC All Rights Reserved.
36587 *
36588 * Use of this source code is governed by an MIT-style license that can be
36589 * found in the LICENSE file at https://angular.io/license
36590 */
36591// Mapping between all HTML entity names and their unicode representation.
36592// Generated from https://html.spec.whatwg.org/multipage/entities.json by stripping
36593// the `&` and `;` from the keys and removing the duplicates.
36594// see https://www.w3.org/TR/html51/syntax.html#named-character-references
36595
36596
36597const NAMED_ENTITIES = {
36598  'AElig': '\u00C6',
36599  'AMP': '\u0026',
36600  'amp': '\u0026',
36601  'Aacute': '\u00C1',
36602  'Abreve': '\u0102',
36603  'Acirc': '\u00C2',
36604  'Acy': '\u0410',
36605  'Afr': '\uD835\uDD04',
36606  'Agrave': '\u00C0',
36607  'Alpha': '\u0391',
36608  'Amacr': '\u0100',
36609  'And': '\u2A53',
36610  'Aogon': '\u0104',
36611  'Aopf': '\uD835\uDD38',
36612  'ApplyFunction': '\u2061',
36613  'af': '\u2061',
36614  'Aring': '\u00C5',
36615  'angst': '\u00C5',
36616  'Ascr': '\uD835\uDC9C',
36617  'Assign': '\u2254',
36618  'colone': '\u2254',
36619  'coloneq': '\u2254',
36620  'Atilde': '\u00C3',
36621  'Auml': '\u00C4',
36622  'Backslash': '\u2216',
36623  'setminus': '\u2216',
36624  'setmn': '\u2216',
36625  'smallsetminus': '\u2216',
36626  'ssetmn': '\u2216',
36627  'Barv': '\u2AE7',
36628  'Barwed': '\u2306',
36629  'doublebarwedge': '\u2306',
36630  'Bcy': '\u0411',
36631  'Because': '\u2235',
36632  'becaus': '\u2235',
36633  'because': '\u2235',
36634  'Bernoullis': '\u212C',
36635  'Bscr': '\u212C',
36636  'bernou': '\u212C',
36637  'Beta': '\u0392',
36638  'Bfr': '\uD835\uDD05',
36639  'Bopf': '\uD835\uDD39',
36640  'Breve': '\u02D8',
36641  'breve': '\u02D8',
36642  'Bumpeq': '\u224E',
36643  'HumpDownHump': '\u224E',
36644  'bump': '\u224E',
36645  'CHcy': '\u0427',
36646  'COPY': '\u00A9',
36647  'copy': '\u00A9',
36648  'Cacute': '\u0106',
36649  'Cap': '\u22D2',
36650  'CapitalDifferentialD': '\u2145',
36651  'DD': '\u2145',
36652  'Cayleys': '\u212D',
36653  'Cfr': '\u212D',
36654  'Ccaron': '\u010C',
36655  'Ccedil': '\u00C7',
36656  'Ccirc': '\u0108',
36657  'Cconint': '\u2230',
36658  'Cdot': '\u010A',
36659  'Cedilla': '\u00B8',
36660  'cedil': '\u00B8',
36661  'CenterDot': '\u00B7',
36662  'centerdot': '\u00B7',
36663  'middot': '\u00B7',
36664  'Chi': '\u03A7',
36665  'CircleDot': '\u2299',
36666  'odot': '\u2299',
36667  'CircleMinus': '\u2296',
36668  'ominus': '\u2296',
36669  'CirclePlus': '\u2295',
36670  'oplus': '\u2295',
36671  'CircleTimes': '\u2297',
36672  'otimes': '\u2297',
36673  'ClockwiseContourIntegral': '\u2232',
36674  'cwconint': '\u2232',
36675  'CloseCurlyDoubleQuote': '\u201D',
36676  'rdquo': '\u201D',
36677  'rdquor': '\u201D',
36678  'CloseCurlyQuote': '\u2019',
36679  'rsquo': '\u2019',
36680  'rsquor': '\u2019',
36681  'Colon': '\u2237',
36682  'Proportion': '\u2237',
36683  'Colone': '\u2A74',
36684  'Congruent': '\u2261',
36685  'equiv': '\u2261',
36686  'Conint': '\u222F',
36687  'DoubleContourIntegral': '\u222F',
36688  'ContourIntegral': '\u222E',
36689  'conint': '\u222E',
36690  'oint': '\u222E',
36691  'Copf': '\u2102',
36692  'complexes': '\u2102',
36693  'Coproduct': '\u2210',
36694  'coprod': '\u2210',
36695  'CounterClockwiseContourIntegral': '\u2233',
36696  'awconint': '\u2233',
36697  'Cross': '\u2A2F',
36698  'Cscr': '\uD835\uDC9E',
36699  'Cup': '\u22D3',
36700  'CupCap': '\u224D',
36701  'asympeq': '\u224D',
36702  'DDotrahd': '\u2911',
36703  'DJcy': '\u0402',
36704  'DScy': '\u0405',
36705  'DZcy': '\u040F',
36706  'Dagger': '\u2021',
36707  'ddagger': '\u2021',
36708  'Darr': '\u21A1',
36709  'Dashv': '\u2AE4',
36710  'DoubleLeftTee': '\u2AE4',
36711  'Dcaron': '\u010E',
36712  'Dcy': '\u0414',
36713  'Del': '\u2207',
36714  'nabla': '\u2207',
36715  'Delta': '\u0394',
36716  'Dfr': '\uD835\uDD07',
36717  'DiacriticalAcute': '\u00B4',
36718  'acute': '\u00B4',
36719  'DiacriticalDot': '\u02D9',
36720  'dot': '\u02D9',
36721  'DiacriticalDoubleAcute': '\u02DD',
36722  'dblac': '\u02DD',
36723  'DiacriticalGrave': '\u0060',
36724  'grave': '\u0060',
36725  'DiacriticalTilde': '\u02DC',
36726  'tilde': '\u02DC',
36727  'Diamond': '\u22C4',
36728  'diam': '\u22C4',
36729  'diamond': '\u22C4',
36730  'DifferentialD': '\u2146',
36731  'dd': '\u2146',
36732  'Dopf': '\uD835\uDD3B',
36733  'Dot': '\u00A8',
36734  'DoubleDot': '\u00A8',
36735  'die': '\u00A8',
36736  'uml': '\u00A8',
36737  'DotDot': '\u20DC',
36738  'DotEqual': '\u2250',
36739  'doteq': '\u2250',
36740  'esdot': '\u2250',
36741  'DoubleDownArrow': '\u21D3',
36742  'Downarrow': '\u21D3',
36743  'dArr': '\u21D3',
36744  'DoubleLeftArrow': '\u21D0',
36745  'Leftarrow': '\u21D0',
36746  'lArr': '\u21D0',
36747  'DoubleLeftRightArrow': '\u21D4',
36748  'Leftrightarrow': '\u21D4',
36749  'hArr': '\u21D4',
36750  'iff': '\u21D4',
36751  'DoubleLongLeftArrow': '\u27F8',
36752  'Longleftarrow': '\u27F8',
36753  'xlArr': '\u27F8',
36754  'DoubleLongLeftRightArrow': '\u27FA',
36755  'Longleftrightarrow': '\u27FA',
36756  'xhArr': '\u27FA',
36757  'DoubleLongRightArrow': '\u27F9',
36758  'Longrightarrow': '\u27F9',
36759  'xrArr': '\u27F9',
36760  'DoubleRightArrow': '\u21D2',
36761  'Implies': '\u21D2',
36762  'Rightarrow': '\u21D2',
36763  'rArr': '\u21D2',
36764  'DoubleRightTee': '\u22A8',
36765  'vDash': '\u22A8',
36766  'DoubleUpArrow': '\u21D1',
36767  'Uparrow': '\u21D1',
36768  'uArr': '\u21D1',
36769  'DoubleUpDownArrow': '\u21D5',
36770  'Updownarrow': '\u21D5',
36771  'vArr': '\u21D5',
36772  'DoubleVerticalBar': '\u2225',
36773  'par': '\u2225',
36774  'parallel': '\u2225',
36775  'shortparallel': '\u2225',
36776  'spar': '\u2225',
36777  'DownArrow': '\u2193',
36778  'ShortDownArrow': '\u2193',
36779  'darr': '\u2193',
36780  'downarrow': '\u2193',
36781  'DownArrowBar': '\u2913',
36782  'DownArrowUpArrow': '\u21F5',
36783  'duarr': '\u21F5',
36784  'DownBreve': '\u0311',
36785  'DownLeftRightVector': '\u2950',
36786  'DownLeftTeeVector': '\u295E',
36787  'DownLeftVector': '\u21BD',
36788  'leftharpoondown': '\u21BD',
36789  'lhard': '\u21BD',
36790  'DownLeftVectorBar': '\u2956',
36791  'DownRightTeeVector': '\u295F',
36792  'DownRightVector': '\u21C1',
36793  'rhard': '\u21C1',
36794  'rightharpoondown': '\u21C1',
36795  'DownRightVectorBar': '\u2957',
36796  'DownTee': '\u22A4',
36797  'top': '\u22A4',
36798  'DownTeeArrow': '\u21A7',
36799  'mapstodown': '\u21A7',
36800  'Dscr': '\uD835\uDC9F',
36801  'Dstrok': '\u0110',
36802  'ENG': '\u014A',
36803  'ETH': '\u00D0',
36804  'Eacute': '\u00C9',
36805  'Ecaron': '\u011A',
36806  'Ecirc': '\u00CA',
36807  'Ecy': '\u042D',
36808  'Edot': '\u0116',
36809  'Efr': '\uD835\uDD08',
36810  'Egrave': '\u00C8',
36811  'Element': '\u2208',
36812  'in': '\u2208',
36813  'isin': '\u2208',
36814  'isinv': '\u2208',
36815  'Emacr': '\u0112',
36816  'EmptySmallSquare': '\u25FB',
36817  'EmptyVerySmallSquare': '\u25AB',
36818  'Eogon': '\u0118',
36819  'Eopf': '\uD835\uDD3C',
36820  'Epsilon': '\u0395',
36821  'Equal': '\u2A75',
36822  'EqualTilde': '\u2242',
36823  'eqsim': '\u2242',
36824  'esim': '\u2242',
36825  'Equilibrium': '\u21CC',
36826  'rightleftharpoons': '\u21CC',
36827  'rlhar': '\u21CC',
36828  'Escr': '\u2130',
36829  'expectation': '\u2130',
36830  'Esim': '\u2A73',
36831  'Eta': '\u0397',
36832  'Euml': '\u00CB',
36833  'Exists': '\u2203',
36834  'exist': '\u2203',
36835  'ExponentialE': '\u2147',
36836  'ee': '\u2147',
36837  'exponentiale': '\u2147',
36838  'Fcy': '\u0424',
36839  'Ffr': '\uD835\uDD09',
36840  'FilledSmallSquare': '\u25FC',
36841  'FilledVerySmallSquare': '\u25AA',
36842  'blacksquare': '\u25AA',
36843  'squarf': '\u25AA',
36844  'squf': '\u25AA',
36845  'Fopf': '\uD835\uDD3D',
36846  'ForAll': '\u2200',
36847  'forall': '\u2200',
36848  'Fouriertrf': '\u2131',
36849  'Fscr': '\u2131',
36850  'GJcy': '\u0403',
36851  'GT': '\u003E',
36852  'gt': '\u003E',
36853  'Gamma': '\u0393',
36854  'Gammad': '\u03DC',
36855  'Gbreve': '\u011E',
36856  'Gcedil': '\u0122',
36857  'Gcirc': '\u011C',
36858  'Gcy': '\u0413',
36859  'Gdot': '\u0120',
36860  'Gfr': '\uD835\uDD0A',
36861  'Gg': '\u22D9',
36862  'ggg': '\u22D9',
36863  'Gopf': '\uD835\uDD3E',
36864  'GreaterEqual': '\u2265',
36865  'ge': '\u2265',
36866  'geq': '\u2265',
36867  'GreaterEqualLess': '\u22DB',
36868  'gel': '\u22DB',
36869  'gtreqless': '\u22DB',
36870  'GreaterFullEqual': '\u2267',
36871  'gE': '\u2267',
36872  'geqq': '\u2267',
36873  'GreaterGreater': '\u2AA2',
36874  'GreaterLess': '\u2277',
36875  'gl': '\u2277',
36876  'gtrless': '\u2277',
36877  'GreaterSlantEqual': '\u2A7E',
36878  'geqslant': '\u2A7E',
36879  'ges': '\u2A7E',
36880  'GreaterTilde': '\u2273',
36881  'gsim': '\u2273',
36882  'gtrsim': '\u2273',
36883  'Gscr': '\uD835\uDCA2',
36884  'Gt': '\u226B',
36885  'NestedGreaterGreater': '\u226B',
36886  'gg': '\u226B',
36887  'HARDcy': '\u042A',
36888  'Hacek': '\u02C7',
36889  'caron': '\u02C7',
36890  'Hat': '\u005E',
36891  'Hcirc': '\u0124',
36892  'Hfr': '\u210C',
36893  'Poincareplane': '\u210C',
36894  'HilbertSpace': '\u210B',
36895  'Hscr': '\u210B',
36896  'hamilt': '\u210B',
36897  'Hopf': '\u210D',
36898  'quaternions': '\u210D',
36899  'HorizontalLine': '\u2500',
36900  'boxh': '\u2500',
36901  'Hstrok': '\u0126',
36902  'HumpEqual': '\u224F',
36903  'bumpe': '\u224F',
36904  'bumpeq': '\u224F',
36905  'IEcy': '\u0415',
36906  'IJlig': '\u0132',
36907  'IOcy': '\u0401',
36908  'Iacute': '\u00CD',
36909  'Icirc': '\u00CE',
36910  'Icy': '\u0418',
36911  'Idot': '\u0130',
36912  'Ifr': '\u2111',
36913  'Im': '\u2111',
36914  'image': '\u2111',
36915  'imagpart': '\u2111',
36916  'Igrave': '\u00CC',
36917  'Imacr': '\u012A',
36918  'ImaginaryI': '\u2148',
36919  'ii': '\u2148',
36920  'Int': '\u222C',
36921  'Integral': '\u222B',
36922  'int': '\u222B',
36923  'Intersection': '\u22C2',
36924  'bigcap': '\u22C2',
36925  'xcap': '\u22C2',
36926  'InvisibleComma': '\u2063',
36927  'ic': '\u2063',
36928  'InvisibleTimes': '\u2062',
36929  'it': '\u2062',
36930  'Iogon': '\u012E',
36931  'Iopf': '\uD835\uDD40',
36932  'Iota': '\u0399',
36933  'Iscr': '\u2110',
36934  'imagline': '\u2110',
36935  'Itilde': '\u0128',
36936  'Iukcy': '\u0406',
36937  'Iuml': '\u00CF',
36938  'Jcirc': '\u0134',
36939  'Jcy': '\u0419',
36940  'Jfr': '\uD835\uDD0D',
36941  'Jopf': '\uD835\uDD41',
36942  'Jscr': '\uD835\uDCA5',
36943  'Jsercy': '\u0408',
36944  'Jukcy': '\u0404',
36945  'KHcy': '\u0425',
36946  'KJcy': '\u040C',
36947  'Kappa': '\u039A',
36948  'Kcedil': '\u0136',
36949  'Kcy': '\u041A',
36950  'Kfr': '\uD835\uDD0E',
36951  'Kopf': '\uD835\uDD42',
36952  'Kscr': '\uD835\uDCA6',
36953  'LJcy': '\u0409',
36954  'LT': '\u003C',
36955  'lt': '\u003C',
36956  'Lacute': '\u0139',
36957  'Lambda': '\u039B',
36958  'Lang': '\u27EA',
36959  'Laplacetrf': '\u2112',
36960  'Lscr': '\u2112',
36961  'lagran': '\u2112',
36962  'Larr': '\u219E',
36963  'twoheadleftarrow': '\u219E',
36964  'Lcaron': '\u013D',
36965  'Lcedil': '\u013B',
36966  'Lcy': '\u041B',
36967  'LeftAngleBracket': '\u27E8',
36968  'lang': '\u27E8',
36969  'langle': '\u27E8',
36970  'LeftArrow': '\u2190',
36971  'ShortLeftArrow': '\u2190',
36972  'larr': '\u2190',
36973  'leftarrow': '\u2190',
36974  'slarr': '\u2190',
36975  'LeftArrowBar': '\u21E4',
36976  'larrb': '\u21E4',
36977  'LeftArrowRightArrow': '\u21C6',
36978  'leftrightarrows': '\u21C6',
36979  'lrarr': '\u21C6',
36980  'LeftCeiling': '\u2308',
36981  'lceil': '\u2308',
36982  'LeftDoubleBracket': '\u27E6',
36983  'lobrk': '\u27E6',
36984  'LeftDownTeeVector': '\u2961',
36985  'LeftDownVector': '\u21C3',
36986  'dharl': '\u21C3',
36987  'downharpoonleft': '\u21C3',
36988  'LeftDownVectorBar': '\u2959',
36989  'LeftFloor': '\u230A',
36990  'lfloor': '\u230A',
36991  'LeftRightArrow': '\u2194',
36992  'harr': '\u2194',
36993  'leftrightarrow': '\u2194',
36994  'LeftRightVector': '\u294E',
36995  'LeftTee': '\u22A3',
36996  'dashv': '\u22A3',
36997  'LeftTeeArrow': '\u21A4',
36998  'mapstoleft': '\u21A4',
36999  'LeftTeeVector': '\u295A',
37000  'LeftTriangle': '\u22B2',
37001  'vartriangleleft': '\u22B2',
37002  'vltri': '\u22B2',
37003  'LeftTriangleBar': '\u29CF',
37004  'LeftTriangleEqual': '\u22B4',
37005  'ltrie': '\u22B4',
37006  'trianglelefteq': '\u22B4',
37007  'LeftUpDownVector': '\u2951',
37008  'LeftUpTeeVector': '\u2960',
37009  'LeftUpVector': '\u21BF',
37010  'uharl': '\u21BF',
37011  'upharpoonleft': '\u21BF',
37012  'LeftUpVectorBar': '\u2958',
37013  'LeftVector': '\u21BC',
37014  'leftharpoonup': '\u21BC',
37015  'lharu': '\u21BC',
37016  'LeftVectorBar': '\u2952',
37017  'LessEqualGreater': '\u22DA',
37018  'leg': '\u22DA',
37019  'lesseqgtr': '\u22DA',
37020  'LessFullEqual': '\u2266',
37021  'lE': '\u2266',
37022  'leqq': '\u2266',
37023  'LessGreater': '\u2276',
37024  'lessgtr': '\u2276',
37025  'lg': '\u2276',
37026  'LessLess': '\u2AA1',
37027  'LessSlantEqual': '\u2A7D',
37028  'leqslant': '\u2A7D',
37029  'les': '\u2A7D',
37030  'LessTilde': '\u2272',
37031  'lesssim': '\u2272',
37032  'lsim': '\u2272',
37033  'Lfr': '\uD835\uDD0F',
37034  'Ll': '\u22D8',
37035  'Lleftarrow': '\u21DA',
37036  'lAarr': '\u21DA',
37037  'Lmidot': '\u013F',
37038  'LongLeftArrow': '\u27F5',
37039  'longleftarrow': '\u27F5',
37040  'xlarr': '\u27F5',
37041  'LongLeftRightArrow': '\u27F7',
37042  'longleftrightarrow': '\u27F7',
37043  'xharr': '\u27F7',
37044  'LongRightArrow': '\u27F6',
37045  'longrightarrow': '\u27F6',
37046  'xrarr': '\u27F6',
37047  'Lopf': '\uD835\uDD43',
37048  'LowerLeftArrow': '\u2199',
37049  'swarr': '\u2199',
37050  'swarrow': '\u2199',
37051  'LowerRightArrow': '\u2198',
37052  'searr': '\u2198',
37053  'searrow': '\u2198',
37054  'Lsh': '\u21B0',
37055  'lsh': '\u21B0',
37056  'Lstrok': '\u0141',
37057  'Lt': '\u226A',
37058  'NestedLessLess': '\u226A',
37059  'll': '\u226A',
37060  'Map': '\u2905',
37061  'Mcy': '\u041C',
37062  'MediumSpace': '\u205F',
37063  'Mellintrf': '\u2133',
37064  'Mscr': '\u2133',
37065  'phmmat': '\u2133',
37066  'Mfr': '\uD835\uDD10',
37067  'MinusPlus': '\u2213',
37068  'mnplus': '\u2213',
37069  'mp': '\u2213',
37070  'Mopf': '\uD835\uDD44',
37071  'Mu': '\u039C',
37072  'NJcy': '\u040A',
37073  'Nacute': '\u0143',
37074  'Ncaron': '\u0147',
37075  'Ncedil': '\u0145',
37076  'Ncy': '\u041D',
37077  'NegativeMediumSpace': '\u200B',
37078  'NegativeThickSpace': '\u200B',
37079  'NegativeThinSpace': '\u200B',
37080  'NegativeVeryThinSpace': '\u200B',
37081  'ZeroWidthSpace': '\u200B',
37082  'NewLine': '\u000A',
37083  'Nfr': '\uD835\uDD11',
37084  'NoBreak': '\u2060',
37085  'NonBreakingSpace': '\u00A0',
37086  'nbsp': '\u00A0',
37087  'Nopf': '\u2115',
37088  'naturals': '\u2115',
37089  'Not': '\u2AEC',
37090  'NotCongruent': '\u2262',
37091  'nequiv': '\u2262',
37092  'NotCupCap': '\u226D',
37093  'NotDoubleVerticalBar': '\u2226',
37094  'npar': '\u2226',
37095  'nparallel': '\u2226',
37096  'nshortparallel': '\u2226',
37097  'nspar': '\u2226',
37098  'NotElement': '\u2209',
37099  'notin': '\u2209',
37100  'notinva': '\u2209',
37101  'NotEqual': '\u2260',
37102  'ne': '\u2260',
37103  'NotEqualTilde': '\u2242\u0338',
37104  'nesim': '\u2242\u0338',
37105  'NotExists': '\u2204',
37106  'nexist': '\u2204',
37107  'nexists': '\u2204',
37108  'NotGreater': '\u226F',
37109  'ngt': '\u226F',
37110  'ngtr': '\u226F',
37111  'NotGreaterEqual': '\u2271',
37112  'nge': '\u2271',
37113  'ngeq': '\u2271',
37114  'NotGreaterFullEqual': '\u2267\u0338',
37115  'ngE': '\u2267\u0338',
37116  'ngeqq': '\u2267\u0338',
37117  'NotGreaterGreater': '\u226B\u0338',
37118  'nGtv': '\u226B\u0338',
37119  'NotGreaterLess': '\u2279',
37120  'ntgl': '\u2279',
37121  'NotGreaterSlantEqual': '\u2A7E\u0338',
37122  'ngeqslant': '\u2A7E\u0338',
37123  'nges': '\u2A7E\u0338',
37124  'NotGreaterTilde': '\u2275',
37125  'ngsim': '\u2275',
37126  'NotHumpDownHump': '\u224E\u0338',
37127  'nbump': '\u224E\u0338',
37128  'NotHumpEqual': '\u224F\u0338',
37129  'nbumpe': '\u224F\u0338',
37130  'NotLeftTriangle': '\u22EA',
37131  'nltri': '\u22EA',
37132  'ntriangleleft': '\u22EA',
37133  'NotLeftTriangleBar': '\u29CF\u0338',
37134  'NotLeftTriangleEqual': '\u22EC',
37135  'nltrie': '\u22EC',
37136  'ntrianglelefteq': '\u22EC',
37137  'NotLess': '\u226E',
37138  'nless': '\u226E',
37139  'nlt': '\u226E',
37140  'NotLessEqual': '\u2270',
37141  'nle': '\u2270',
37142  'nleq': '\u2270',
37143  'NotLessGreater': '\u2278',
37144  'ntlg': '\u2278',
37145  'NotLessLess': '\u226A\u0338',
37146  'nLtv': '\u226A\u0338',
37147  'NotLessSlantEqual': '\u2A7D\u0338',
37148  'nleqslant': '\u2A7D\u0338',
37149  'nles': '\u2A7D\u0338',
37150  'NotLessTilde': '\u2274',
37151  'nlsim': '\u2274',
37152  'NotNestedGreaterGreater': '\u2AA2\u0338',
37153  'NotNestedLessLess': '\u2AA1\u0338',
37154  'NotPrecedes': '\u2280',
37155  'npr': '\u2280',
37156  'nprec': '\u2280',
37157  'NotPrecedesEqual': '\u2AAF\u0338',
37158  'npre': '\u2AAF\u0338',
37159  'npreceq': '\u2AAF\u0338',
37160  'NotPrecedesSlantEqual': '\u22E0',
37161  'nprcue': '\u22E0',
37162  'NotReverseElement': '\u220C',
37163  'notni': '\u220C',
37164  'notniva': '\u220C',
37165  'NotRightTriangle': '\u22EB',
37166  'nrtri': '\u22EB',
37167  'ntriangleright': '\u22EB',
37168  'NotRightTriangleBar': '\u29D0\u0338',
37169  'NotRightTriangleEqual': '\u22ED',
37170  'nrtrie': '\u22ED',
37171  'ntrianglerighteq': '\u22ED',
37172  'NotSquareSubset': '\u228F\u0338',
37173  'NotSquareSubsetEqual': '\u22E2',
37174  'nsqsube': '\u22E2',
37175  'NotSquareSuperset': '\u2290\u0338',
37176  'NotSquareSupersetEqual': '\u22E3',
37177  'nsqsupe': '\u22E3',
37178  'NotSubset': '\u2282\u20D2',
37179  'nsubset': '\u2282\u20D2',
37180  'vnsub': '\u2282\u20D2',
37181  'NotSubsetEqual': '\u2288',
37182  'nsube': '\u2288',
37183  'nsubseteq': '\u2288',
37184  'NotSucceeds': '\u2281',
37185  'nsc': '\u2281',
37186  'nsucc': '\u2281',
37187  'NotSucceedsEqual': '\u2AB0\u0338',
37188  'nsce': '\u2AB0\u0338',
37189  'nsucceq': '\u2AB0\u0338',
37190  'NotSucceedsSlantEqual': '\u22E1',
37191  'nsccue': '\u22E1',
37192  'NotSucceedsTilde': '\u227F\u0338',
37193  'NotSuperset': '\u2283\u20D2',
37194  'nsupset': '\u2283\u20D2',
37195  'vnsup': '\u2283\u20D2',
37196  'NotSupersetEqual': '\u2289',
37197  'nsupe': '\u2289',
37198  'nsupseteq': '\u2289',
37199  'NotTilde': '\u2241',
37200  'nsim': '\u2241',
37201  'NotTildeEqual': '\u2244',
37202  'nsime': '\u2244',
37203  'nsimeq': '\u2244',
37204  'NotTildeFullEqual': '\u2247',
37205  'ncong': '\u2247',
37206  'NotTildeTilde': '\u2249',
37207  'nap': '\u2249',
37208  'napprox': '\u2249',
37209  'NotVerticalBar': '\u2224',
37210  'nmid': '\u2224',
37211  'nshortmid': '\u2224',
37212  'nsmid': '\u2224',
37213  'Nscr': '\uD835\uDCA9',
37214  'Ntilde': '\u00D1',
37215  'Nu': '\u039D',
37216  'OElig': '\u0152',
37217  'Oacute': '\u00D3',
37218  'Ocirc': '\u00D4',
37219  'Ocy': '\u041E',
37220  'Odblac': '\u0150',
37221  'Ofr': '\uD835\uDD12',
37222  'Ograve': '\u00D2',
37223  'Omacr': '\u014C',
37224  'Omega': '\u03A9',
37225  'ohm': '\u03A9',
37226  'Omicron': '\u039F',
37227  'Oopf': '\uD835\uDD46',
37228  'OpenCurlyDoubleQuote': '\u201C',
37229  'ldquo': '\u201C',
37230  'OpenCurlyQuote': '\u2018',
37231  'lsquo': '\u2018',
37232  'Or': '\u2A54',
37233  'Oscr': '\uD835\uDCAA',
37234  'Oslash': '\u00D8',
37235  'Otilde': '\u00D5',
37236  'Otimes': '\u2A37',
37237  'Ouml': '\u00D6',
37238  'OverBar': '\u203E',
37239  'oline': '\u203E',
37240  'OverBrace': '\u23DE',
37241  'OverBracket': '\u23B4',
37242  'tbrk': '\u23B4',
37243  'OverParenthesis': '\u23DC',
37244  'PartialD': '\u2202',
37245  'part': '\u2202',
37246  'Pcy': '\u041F',
37247  'Pfr': '\uD835\uDD13',
37248  'Phi': '\u03A6',
37249  'Pi': '\u03A0',
37250  'PlusMinus': '\u00B1',
37251  'plusmn': '\u00B1',
37252  'pm': '\u00B1',
37253  'Popf': '\u2119',
37254  'primes': '\u2119',
37255  'Pr': '\u2ABB',
37256  'Precedes': '\u227A',
37257  'pr': '\u227A',
37258  'prec': '\u227A',
37259  'PrecedesEqual': '\u2AAF',
37260  'pre': '\u2AAF',
37261  'preceq': '\u2AAF',
37262  'PrecedesSlantEqual': '\u227C',
37263  'prcue': '\u227C',
37264  'preccurlyeq': '\u227C',
37265  'PrecedesTilde': '\u227E',
37266  'precsim': '\u227E',
37267  'prsim': '\u227E',
37268  'Prime': '\u2033',
37269  'Product': '\u220F',
37270  'prod': '\u220F',
37271  'Proportional': '\u221D',
37272  'prop': '\u221D',
37273  'propto': '\u221D',
37274  'varpropto': '\u221D',
37275  'vprop': '\u221D',
37276  'Pscr': '\uD835\uDCAB',
37277  'Psi': '\u03A8',
37278  'QUOT': '\u0022',
37279  'quot': '\u0022',
37280  'Qfr': '\uD835\uDD14',
37281  'Qopf': '\u211A',
37282  'rationals': '\u211A',
37283  'Qscr': '\uD835\uDCAC',
37284  'RBarr': '\u2910',
37285  'drbkarow': '\u2910',
37286  'REG': '\u00AE',
37287  'circledR': '\u00AE',
37288  'reg': '\u00AE',
37289  'Racute': '\u0154',
37290  'Rang': '\u27EB',
37291  'Rarr': '\u21A0',
37292  'twoheadrightarrow': '\u21A0',
37293  'Rarrtl': '\u2916',
37294  'Rcaron': '\u0158',
37295  'Rcedil': '\u0156',
37296  'Rcy': '\u0420',
37297  'Re': '\u211C',
37298  'Rfr': '\u211C',
37299  'real': '\u211C',
37300  'realpart': '\u211C',
37301  'ReverseElement': '\u220B',
37302  'SuchThat': '\u220B',
37303  'ni': '\u220B',
37304  'niv': '\u220B',
37305  'ReverseEquilibrium': '\u21CB',
37306  'leftrightharpoons': '\u21CB',
37307  'lrhar': '\u21CB',
37308  'ReverseUpEquilibrium': '\u296F',
37309  'duhar': '\u296F',
37310  'Rho': '\u03A1',
37311  'RightAngleBracket': '\u27E9',
37312  'rang': '\u27E9',
37313  'rangle': '\u27E9',
37314  'RightArrow': '\u2192',
37315  'ShortRightArrow': '\u2192',
37316  'rarr': '\u2192',
37317  'rightarrow': '\u2192',
37318  'srarr': '\u2192',
37319  'RightArrowBar': '\u21E5',
37320  'rarrb': '\u21E5',
37321  'RightArrowLeftArrow': '\u21C4',
37322  'rightleftarrows': '\u21C4',
37323  'rlarr': '\u21C4',
37324  'RightCeiling': '\u2309',
37325  'rceil': '\u2309',
37326  'RightDoubleBracket': '\u27E7',
37327  'robrk': '\u27E7',
37328  'RightDownTeeVector': '\u295D',
37329  'RightDownVector': '\u21C2',
37330  'dharr': '\u21C2',
37331  'downharpoonright': '\u21C2',
37332  'RightDownVectorBar': '\u2955',
37333  'RightFloor': '\u230B',
37334  'rfloor': '\u230B',
37335  'RightTee': '\u22A2',
37336  'vdash': '\u22A2',
37337  'RightTeeArrow': '\u21A6',
37338  'map': '\u21A6',
37339  'mapsto': '\u21A6',
37340  'RightTeeVector': '\u295B',
37341  'RightTriangle': '\u22B3',
37342  'vartriangleright': '\u22B3',
37343  'vrtri': '\u22B3',
37344  'RightTriangleBar': '\u29D0',
37345  'RightTriangleEqual': '\u22B5',
37346  'rtrie': '\u22B5',
37347  'trianglerighteq': '\u22B5',
37348  'RightUpDownVector': '\u294F',
37349  'RightUpTeeVector': '\u295C',
37350  'RightUpVector': '\u21BE',
37351  'uharr': '\u21BE',
37352  'upharpoonright': '\u21BE',
37353  'RightUpVectorBar': '\u2954',
37354  'RightVector': '\u21C0',
37355  'rharu': '\u21C0',
37356  'rightharpoonup': '\u21C0',
37357  'RightVectorBar': '\u2953',
37358  'Ropf': '\u211D',
37359  'reals': '\u211D',
37360  'RoundImplies': '\u2970',
37361  'Rrightarrow': '\u21DB',
37362  'rAarr': '\u21DB',
37363  'Rscr': '\u211B',
37364  'realine': '\u211B',
37365  'Rsh': '\u21B1',
37366  'rsh': '\u21B1',
37367  'RuleDelayed': '\u29F4',
37368  'SHCHcy': '\u0429',
37369  'SHcy': '\u0428',
37370  'SOFTcy': '\u042C',
37371  'Sacute': '\u015A',
37372  'Sc': '\u2ABC',
37373  'Scaron': '\u0160',
37374  'Scedil': '\u015E',
37375  'Scirc': '\u015C',
37376  'Scy': '\u0421',
37377  'Sfr': '\uD835\uDD16',
37378  'ShortUpArrow': '\u2191',
37379  'UpArrow': '\u2191',
37380  'uarr': '\u2191',
37381  'uparrow': '\u2191',
37382  'Sigma': '\u03A3',
37383  'SmallCircle': '\u2218',
37384  'compfn': '\u2218',
37385  'Sopf': '\uD835\uDD4A',
37386  'Sqrt': '\u221A',
37387  'radic': '\u221A',
37388  'Square': '\u25A1',
37389  'squ': '\u25A1',
37390  'square': '\u25A1',
37391  'SquareIntersection': '\u2293',
37392  'sqcap': '\u2293',
37393  'SquareSubset': '\u228F',
37394  'sqsub': '\u228F',
37395  'sqsubset': '\u228F',
37396  'SquareSubsetEqual': '\u2291',
37397  'sqsube': '\u2291',
37398  'sqsubseteq': '\u2291',
37399  'SquareSuperset': '\u2290',
37400  'sqsup': '\u2290',
37401  'sqsupset': '\u2290',
37402  'SquareSupersetEqual': '\u2292',
37403  'sqsupe': '\u2292',
37404  'sqsupseteq': '\u2292',
37405  'SquareUnion': '\u2294',
37406  'sqcup': '\u2294',
37407  'Sscr': '\uD835\uDCAE',
37408  'Star': '\u22C6',
37409  'sstarf': '\u22C6',
37410  'Sub': '\u22D0',
37411  'Subset': '\u22D0',
37412  'SubsetEqual': '\u2286',
37413  'sube': '\u2286',
37414  'subseteq': '\u2286',
37415  'Succeeds': '\u227B',
37416  'sc': '\u227B',
37417  'succ': '\u227B',
37418  'SucceedsEqual': '\u2AB0',
37419  'sce': '\u2AB0',
37420  'succeq': '\u2AB0',
37421  'SucceedsSlantEqual': '\u227D',
37422  'sccue': '\u227D',
37423  'succcurlyeq': '\u227D',
37424  'SucceedsTilde': '\u227F',
37425  'scsim': '\u227F',
37426  'succsim': '\u227F',
37427  'Sum': '\u2211',
37428  'sum': '\u2211',
37429  'Sup': '\u22D1',
37430  'Supset': '\u22D1',
37431  'Superset': '\u2283',
37432  'sup': '\u2283',
37433  'supset': '\u2283',
37434  'SupersetEqual': '\u2287',
37435  'supe': '\u2287',
37436  'supseteq': '\u2287',
37437  'THORN': '\u00DE',
37438  'TRADE': '\u2122',
37439  'trade': '\u2122',
37440  'TSHcy': '\u040B',
37441  'TScy': '\u0426',
37442  'Tab': '\u0009',
37443  'Tau': '\u03A4',
37444  'Tcaron': '\u0164',
37445  'Tcedil': '\u0162',
37446  'Tcy': '\u0422',
37447  'Tfr': '\uD835\uDD17',
37448  'Therefore': '\u2234',
37449  'there4': '\u2234',
37450  'therefore': '\u2234',
37451  'Theta': '\u0398',
37452  'ThickSpace': '\u205F\u200A',
37453  'ThinSpace': '\u2009',
37454  'thinsp': '\u2009',
37455  'Tilde': '\u223C',
37456  'sim': '\u223C',
37457  'thicksim': '\u223C',
37458  'thksim': '\u223C',
37459  'TildeEqual': '\u2243',
37460  'sime': '\u2243',
37461  'simeq': '\u2243',
37462  'TildeFullEqual': '\u2245',
37463  'cong': '\u2245',
37464  'TildeTilde': '\u2248',
37465  'ap': '\u2248',
37466  'approx': '\u2248',
37467  'asymp': '\u2248',
37468  'thickapprox': '\u2248',
37469  'thkap': '\u2248',
37470  'Topf': '\uD835\uDD4B',
37471  'TripleDot': '\u20DB',
37472  'tdot': '\u20DB',
37473  'Tscr': '\uD835\uDCAF',
37474  'Tstrok': '\u0166',
37475  'Uacute': '\u00DA',
37476  'Uarr': '\u219F',
37477  'Uarrocir': '\u2949',
37478  'Ubrcy': '\u040E',
37479  'Ubreve': '\u016C',
37480  'Ucirc': '\u00DB',
37481  'Ucy': '\u0423',
37482  'Udblac': '\u0170',
37483  'Ufr': '\uD835\uDD18',
37484  'Ugrave': '\u00D9',
37485  'Umacr': '\u016A',
37486  'UnderBar': '\u005F',
37487  'lowbar': '\u005F',
37488  'UnderBrace': '\u23DF',
37489  'UnderBracket': '\u23B5',
37490  'bbrk': '\u23B5',
37491  'UnderParenthesis': '\u23DD',
37492  'Union': '\u22C3',
37493  'bigcup': '\u22C3',
37494  'xcup': '\u22C3',
37495  'UnionPlus': '\u228E',
37496  'uplus': '\u228E',
37497  'Uogon': '\u0172',
37498  'Uopf': '\uD835\uDD4C',
37499  'UpArrowBar': '\u2912',
37500  'UpArrowDownArrow': '\u21C5',
37501  'udarr': '\u21C5',
37502  'UpDownArrow': '\u2195',
37503  'updownarrow': '\u2195',
37504  'varr': '\u2195',
37505  'UpEquilibrium': '\u296E',
37506  'udhar': '\u296E',
37507  'UpTee': '\u22A5',
37508  'bot': '\u22A5',
37509  'bottom': '\u22A5',
37510  'perp': '\u22A5',
37511  'UpTeeArrow': '\u21A5',
37512  'mapstoup': '\u21A5',
37513  'UpperLeftArrow': '\u2196',
37514  'nwarr': '\u2196',
37515  'nwarrow': '\u2196',
37516  'UpperRightArrow': '\u2197',
37517  'nearr': '\u2197',
37518  'nearrow': '\u2197',
37519  'Upsi': '\u03D2',
37520  'upsih': '\u03D2',
37521  'Upsilon': '\u03A5',
37522  'Uring': '\u016E',
37523  'Uscr': '\uD835\uDCB0',
37524  'Utilde': '\u0168',
37525  'Uuml': '\u00DC',
37526  'VDash': '\u22AB',
37527  'Vbar': '\u2AEB',
37528  'Vcy': '\u0412',
37529  'Vdash': '\u22A9',
37530  'Vdashl': '\u2AE6',
37531  'Vee': '\u22C1',
37532  'bigvee': '\u22C1',
37533  'xvee': '\u22C1',
37534  'Verbar': '\u2016',
37535  'Vert': '\u2016',
37536  'VerticalBar': '\u2223',
37537  'mid': '\u2223',
37538  'shortmid': '\u2223',
37539  'smid': '\u2223',
37540  'VerticalLine': '\u007C',
37541  'verbar': '\u007C',
37542  'vert': '\u007C',
37543  'VerticalSeparator': '\u2758',
37544  'VerticalTilde': '\u2240',
37545  'wr': '\u2240',
37546  'wreath': '\u2240',
37547  'VeryThinSpace': '\u200A',
37548  'hairsp': '\u200A',
37549  'Vfr': '\uD835\uDD19',
37550  'Vopf': '\uD835\uDD4D',
37551  'Vscr': '\uD835\uDCB1',
37552  'Vvdash': '\u22AA',
37553  'Wcirc': '\u0174',
37554  'Wedge': '\u22C0',
37555  'bigwedge': '\u22C0',
37556  'xwedge': '\u22C0',
37557  'Wfr': '\uD835\uDD1A',
37558  'Wopf': '\uD835\uDD4E',
37559  'Wscr': '\uD835\uDCB2',
37560  'Xfr': '\uD835\uDD1B',
37561  'Xi': '\u039E',
37562  'Xopf': '\uD835\uDD4F',
37563  'Xscr': '\uD835\uDCB3',
37564  'YAcy': '\u042F',
37565  'YIcy': '\u0407',
37566  'YUcy': '\u042E',
37567  'Yacute': '\u00DD',
37568  'Ycirc': '\u0176',
37569  'Ycy': '\u042B',
37570  'Yfr': '\uD835\uDD1C',
37571  'Yopf': '\uD835\uDD50',
37572  'Yscr': '\uD835\uDCB4',
37573  'Yuml': '\u0178',
37574  'ZHcy': '\u0416',
37575  'Zacute': '\u0179',
37576  'Zcaron': '\u017D',
37577  'Zcy': '\u0417',
37578  'Zdot': '\u017B',
37579  'Zeta': '\u0396',
37580  'Zfr': '\u2128',
37581  'zeetrf': '\u2128',
37582  'Zopf': '\u2124',
37583  'integers': '\u2124',
37584  'Zscr': '\uD835\uDCB5',
37585  'aacute': '\u00E1',
37586  'abreve': '\u0103',
37587  'ac': '\u223E',
37588  'mstpos': '\u223E',
37589  'acE': '\u223E\u0333',
37590  'acd': '\u223F',
37591  'acirc': '\u00E2',
37592  'acy': '\u0430',
37593  'aelig': '\u00E6',
37594  'afr': '\uD835\uDD1E',
37595  'agrave': '\u00E0',
37596  'alefsym': '\u2135',
37597  'aleph': '\u2135',
37598  'alpha': '\u03B1',
37599  'amacr': '\u0101',
37600  'amalg': '\u2A3F',
37601  'and': '\u2227',
37602  'wedge': '\u2227',
37603  'andand': '\u2A55',
37604  'andd': '\u2A5C',
37605  'andslope': '\u2A58',
37606  'andv': '\u2A5A',
37607  'ang': '\u2220',
37608  'angle': '\u2220',
37609  'ange': '\u29A4',
37610  'angmsd': '\u2221',
37611  'measuredangle': '\u2221',
37612  'angmsdaa': '\u29A8',
37613  'angmsdab': '\u29A9',
37614  'angmsdac': '\u29AA',
37615  'angmsdad': '\u29AB',
37616  'angmsdae': '\u29AC',
37617  'angmsdaf': '\u29AD',
37618  'angmsdag': '\u29AE',
37619  'angmsdah': '\u29AF',
37620  'angrt': '\u221F',
37621  'angrtvb': '\u22BE',
37622  'angrtvbd': '\u299D',
37623  'angsph': '\u2222',
37624  'angzarr': '\u237C',
37625  'aogon': '\u0105',
37626  'aopf': '\uD835\uDD52',
37627  'apE': '\u2A70',
37628  'apacir': '\u2A6F',
37629  'ape': '\u224A',
37630  'approxeq': '\u224A',
37631  'apid': '\u224B',
37632  'apos': '\u0027',
37633  'aring': '\u00E5',
37634  'ascr': '\uD835\uDCB6',
37635  'ast': '\u002A',
37636  'midast': '\u002A',
37637  'atilde': '\u00E3',
37638  'auml': '\u00E4',
37639  'awint': '\u2A11',
37640  'bNot': '\u2AED',
37641  'backcong': '\u224C',
37642  'bcong': '\u224C',
37643  'backepsilon': '\u03F6',
37644  'bepsi': '\u03F6',
37645  'backprime': '\u2035',
37646  'bprime': '\u2035',
37647  'backsim': '\u223D',
37648  'bsim': '\u223D',
37649  'backsimeq': '\u22CD',
37650  'bsime': '\u22CD',
37651  'barvee': '\u22BD',
37652  'barwed': '\u2305',
37653  'barwedge': '\u2305',
37654  'bbrktbrk': '\u23B6',
37655  'bcy': '\u0431',
37656  'bdquo': '\u201E',
37657  'ldquor': '\u201E',
37658  'bemptyv': '\u29B0',
37659  'beta': '\u03B2',
37660  'beth': '\u2136',
37661  'between': '\u226C',
37662  'twixt': '\u226C',
37663  'bfr': '\uD835\uDD1F',
37664  'bigcirc': '\u25EF',
37665  'xcirc': '\u25EF',
37666  'bigodot': '\u2A00',
37667  'xodot': '\u2A00',
37668  'bigoplus': '\u2A01',
37669  'xoplus': '\u2A01',
37670  'bigotimes': '\u2A02',
37671  'xotime': '\u2A02',
37672  'bigsqcup': '\u2A06',
37673  'xsqcup': '\u2A06',
37674  'bigstar': '\u2605',
37675  'starf': '\u2605',
37676  'bigtriangledown': '\u25BD',
37677  'xdtri': '\u25BD',
37678  'bigtriangleup': '\u25B3',
37679  'xutri': '\u25B3',
37680  'biguplus': '\u2A04',
37681  'xuplus': '\u2A04',
37682  'bkarow': '\u290D',
37683  'rbarr': '\u290D',
37684  'blacklozenge': '\u29EB',
37685  'lozf': '\u29EB',
37686  'blacktriangle': '\u25B4',
37687  'utrif': '\u25B4',
37688  'blacktriangledown': '\u25BE',
37689  'dtrif': '\u25BE',
37690  'blacktriangleleft': '\u25C2',
37691  'ltrif': '\u25C2',
37692  'blacktriangleright': '\u25B8',
37693  'rtrif': '\u25B8',
37694  'blank': '\u2423',
37695  'blk12': '\u2592',
37696  'blk14': '\u2591',
37697  'blk34': '\u2593',
37698  'block': '\u2588',
37699  'bne': '\u003D\u20E5',
37700  'bnequiv': '\u2261\u20E5',
37701  'bnot': '\u2310',
37702  'bopf': '\uD835\uDD53',
37703  'bowtie': '\u22C8',
37704  'boxDL': '\u2557',
37705  'boxDR': '\u2554',
37706  'boxDl': '\u2556',
37707  'boxDr': '\u2553',
37708  'boxH': '\u2550',
37709  'boxHD': '\u2566',
37710  'boxHU': '\u2569',
37711  'boxHd': '\u2564',
37712  'boxHu': '\u2567',
37713  'boxUL': '\u255D',
37714  'boxUR': '\u255A',
37715  'boxUl': '\u255C',
37716  'boxUr': '\u2559',
37717  'boxV': '\u2551',
37718  'boxVH': '\u256C',
37719  'boxVL': '\u2563',
37720  'boxVR': '\u2560',
37721  'boxVh': '\u256B',
37722  'boxVl': '\u2562',
37723  'boxVr': '\u255F',
37724  'boxbox': '\u29C9',
37725  'boxdL': '\u2555',
37726  'boxdR': '\u2552',
37727  'boxdl': '\u2510',
37728  'boxdr': '\u250C',
37729  'boxhD': '\u2565',
37730  'boxhU': '\u2568',
37731  'boxhd': '\u252C',
37732  'boxhu': '\u2534',
37733  'boxminus': '\u229F',
37734  'minusb': '\u229F',
37735  'boxplus': '\u229E',
37736  'plusb': '\u229E',
37737  'boxtimes': '\u22A0',
37738  'timesb': '\u22A0',
37739  'boxuL': '\u255B',
37740  'boxuR': '\u2558',
37741  'boxul': '\u2518',
37742  'boxur': '\u2514',
37743  'boxv': '\u2502',
37744  'boxvH': '\u256A',
37745  'boxvL': '\u2561',
37746  'boxvR': '\u255E',
37747  'boxvh': '\u253C',
37748  'boxvl': '\u2524',
37749  'boxvr': '\u251C',
37750  'brvbar': '\u00A6',
37751  'bscr': '\uD835\uDCB7',
37752  'bsemi': '\u204F',
37753  'bsol': '\u005C',
37754  'bsolb': '\u29C5',
37755  'bsolhsub': '\u27C8',
37756  'bull': '\u2022',
37757  'bullet': '\u2022',
37758  'bumpE': '\u2AAE',
37759  'cacute': '\u0107',
37760  'cap': '\u2229',
37761  'capand': '\u2A44',
37762  'capbrcup': '\u2A49',
37763  'capcap': '\u2A4B',
37764  'capcup': '\u2A47',
37765  'capdot': '\u2A40',
37766  'caps': '\u2229\uFE00',
37767  'caret': '\u2041',
37768  'ccaps': '\u2A4D',
37769  'ccaron': '\u010D',
37770  'ccedil': '\u00E7',
37771  'ccirc': '\u0109',
37772  'ccups': '\u2A4C',
37773  'ccupssm': '\u2A50',
37774  'cdot': '\u010B',
37775  'cemptyv': '\u29B2',
37776  'cent': '\u00A2',
37777  'cfr': '\uD835\uDD20',
37778  'chcy': '\u0447',
37779  'check': '\u2713',
37780  'checkmark': '\u2713',
37781  'chi': '\u03C7',
37782  'cir': '\u25CB',
37783  'cirE': '\u29C3',
37784  'circ': '\u02C6',
37785  'circeq': '\u2257',
37786  'cire': '\u2257',
37787  'circlearrowleft': '\u21BA',
37788  'olarr': '\u21BA',
37789  'circlearrowright': '\u21BB',
37790  'orarr': '\u21BB',
37791  'circledS': '\u24C8',
37792  'oS': '\u24C8',
37793  'circledast': '\u229B',
37794  'oast': '\u229B',
37795  'circledcirc': '\u229A',
37796  'ocir': '\u229A',
37797  'circleddash': '\u229D',
37798  'odash': '\u229D',
37799  'cirfnint': '\u2A10',
37800  'cirmid': '\u2AEF',
37801  'cirscir': '\u29C2',
37802  'clubs': '\u2663',
37803  'clubsuit': '\u2663',
37804  'colon': '\u003A',
37805  'comma': '\u002C',
37806  'commat': '\u0040',
37807  'comp': '\u2201',
37808  'complement': '\u2201',
37809  'congdot': '\u2A6D',
37810  'copf': '\uD835\uDD54',
37811  'copysr': '\u2117',
37812  'crarr': '\u21B5',
37813  'cross': '\u2717',
37814  'cscr': '\uD835\uDCB8',
37815  'csub': '\u2ACF',
37816  'csube': '\u2AD1',
37817  'csup': '\u2AD0',
37818  'csupe': '\u2AD2',
37819  'ctdot': '\u22EF',
37820  'cudarrl': '\u2938',
37821  'cudarrr': '\u2935',
37822  'cuepr': '\u22DE',
37823  'curlyeqprec': '\u22DE',
37824  'cuesc': '\u22DF',
37825  'curlyeqsucc': '\u22DF',
37826  'cularr': '\u21B6',
37827  'curvearrowleft': '\u21B6',
37828  'cularrp': '\u293D',
37829  'cup': '\u222A',
37830  'cupbrcap': '\u2A48',
37831  'cupcap': '\u2A46',
37832  'cupcup': '\u2A4A',
37833  'cupdot': '\u228D',
37834  'cupor': '\u2A45',
37835  'cups': '\u222A\uFE00',
37836  'curarr': '\u21B7',
37837  'curvearrowright': '\u21B7',
37838  'curarrm': '\u293C',
37839  'curlyvee': '\u22CE',
37840  'cuvee': '\u22CE',
37841  'curlywedge': '\u22CF',
37842  'cuwed': '\u22CF',
37843  'curren': '\u00A4',
37844  'cwint': '\u2231',
37845  'cylcty': '\u232D',
37846  'dHar': '\u2965',
37847  'dagger': '\u2020',
37848  'daleth': '\u2138',
37849  'dash': '\u2010',
37850  'hyphen': '\u2010',
37851  'dbkarow': '\u290F',
37852  'rBarr': '\u290F',
37853  'dcaron': '\u010F',
37854  'dcy': '\u0434',
37855  'ddarr': '\u21CA',
37856  'downdownarrows': '\u21CA',
37857  'ddotseq': '\u2A77',
37858  'eDDot': '\u2A77',
37859  'deg': '\u00B0',
37860  'delta': '\u03B4',
37861  'demptyv': '\u29B1',
37862  'dfisht': '\u297F',
37863  'dfr': '\uD835\uDD21',
37864  'diamondsuit': '\u2666',
37865  'diams': '\u2666',
37866  'digamma': '\u03DD',
37867  'gammad': '\u03DD',
37868  'disin': '\u22F2',
37869  'div': '\u00F7',
37870  'divide': '\u00F7',
37871  'divideontimes': '\u22C7',
37872  'divonx': '\u22C7',
37873  'djcy': '\u0452',
37874  'dlcorn': '\u231E',
37875  'llcorner': '\u231E',
37876  'dlcrop': '\u230D',
37877  'dollar': '\u0024',
37878  'dopf': '\uD835\uDD55',
37879  'doteqdot': '\u2251',
37880  'eDot': '\u2251',
37881  'dotminus': '\u2238',
37882  'minusd': '\u2238',
37883  'dotplus': '\u2214',
37884  'plusdo': '\u2214',
37885  'dotsquare': '\u22A1',
37886  'sdotb': '\u22A1',
37887  'drcorn': '\u231F',
37888  'lrcorner': '\u231F',
37889  'drcrop': '\u230C',
37890  'dscr': '\uD835\uDCB9',
37891  'dscy': '\u0455',
37892  'dsol': '\u29F6',
37893  'dstrok': '\u0111',
37894  'dtdot': '\u22F1',
37895  'dtri': '\u25BF',
37896  'triangledown': '\u25BF',
37897  'dwangle': '\u29A6',
37898  'dzcy': '\u045F',
37899  'dzigrarr': '\u27FF',
37900  'eacute': '\u00E9',
37901  'easter': '\u2A6E',
37902  'ecaron': '\u011B',
37903  'ecir': '\u2256',
37904  'eqcirc': '\u2256',
37905  'ecirc': '\u00EA',
37906  'ecolon': '\u2255',
37907  'eqcolon': '\u2255',
37908  'ecy': '\u044D',
37909  'edot': '\u0117',
37910  'efDot': '\u2252',
37911  'fallingdotseq': '\u2252',
37912  'efr': '\uD835\uDD22',
37913  'eg': '\u2A9A',
37914  'egrave': '\u00E8',
37915  'egs': '\u2A96',
37916  'eqslantgtr': '\u2A96',
37917  'egsdot': '\u2A98',
37918  'el': '\u2A99',
37919  'elinters': '\u23E7',
37920  'ell': '\u2113',
37921  'els': '\u2A95',
37922  'eqslantless': '\u2A95',
37923  'elsdot': '\u2A97',
37924  'emacr': '\u0113',
37925  'empty': '\u2205',
37926  'emptyset': '\u2205',
37927  'emptyv': '\u2205',
37928  'varnothing': '\u2205',
37929  'emsp13': '\u2004',
37930  'emsp14': '\u2005',
37931  'emsp': '\u2003',
37932  'eng': '\u014B',
37933  'ensp': '\u2002',
37934  'eogon': '\u0119',
37935  'eopf': '\uD835\uDD56',
37936  'epar': '\u22D5',
37937  'eparsl': '\u29E3',
37938  'eplus': '\u2A71',
37939  'epsi': '\u03B5',
37940  'epsilon': '\u03B5',
37941  'epsiv': '\u03F5',
37942  'straightepsilon': '\u03F5',
37943  'varepsilon': '\u03F5',
37944  'equals': '\u003D',
37945  'equest': '\u225F',
37946  'questeq': '\u225F',
37947  'equivDD': '\u2A78',
37948  'eqvparsl': '\u29E5',
37949  'erDot': '\u2253',
37950  'risingdotseq': '\u2253',
37951  'erarr': '\u2971',
37952  'escr': '\u212F',
37953  'eta': '\u03B7',
37954  'eth': '\u00F0',
37955  'euml': '\u00EB',
37956  'euro': '\u20AC',
37957  'excl': '\u0021',
37958  'fcy': '\u0444',
37959  'female': '\u2640',
37960  'ffilig': '\uFB03',
37961  'fflig': '\uFB00',
37962  'ffllig': '\uFB04',
37963  'ffr': '\uD835\uDD23',
37964  'filig': '\uFB01',
37965  'fjlig': '\u0066\u006A',
37966  'flat': '\u266D',
37967  'fllig': '\uFB02',
37968  'fltns': '\u25B1',
37969  'fnof': '\u0192',
37970  'fopf': '\uD835\uDD57',
37971  'fork': '\u22D4',
37972  'pitchfork': '\u22D4',
37973  'forkv': '\u2AD9',
37974  'fpartint': '\u2A0D',
37975  'frac12': '\u00BD',
37976  'half': '\u00BD',
37977  'frac13': '\u2153',
37978  'frac14': '\u00BC',
37979  'frac15': '\u2155',
37980  'frac16': '\u2159',
37981  'frac18': '\u215B',
37982  'frac23': '\u2154',
37983  'frac25': '\u2156',
37984  'frac34': '\u00BE',
37985  'frac35': '\u2157',
37986  'frac38': '\u215C',
37987  'frac45': '\u2158',
37988  'frac56': '\u215A',
37989  'frac58': '\u215D',
37990  'frac78': '\u215E',
37991  'frasl': '\u2044',
37992  'frown': '\u2322',
37993  'sfrown': '\u2322',
37994  'fscr': '\uD835\uDCBB',
37995  'gEl': '\u2A8C',
37996  'gtreqqless': '\u2A8C',
37997  'gacute': '\u01F5',
37998  'gamma': '\u03B3',
37999  'gap': '\u2A86',
38000  'gtrapprox': '\u2A86',
38001  'gbreve': '\u011F',
38002  'gcirc': '\u011D',
38003  'gcy': '\u0433',
38004  'gdot': '\u0121',
38005  'gescc': '\u2AA9',
38006  'gesdot': '\u2A80',
38007  'gesdoto': '\u2A82',
38008  'gesdotol': '\u2A84',
38009  'gesl': '\u22DB\uFE00',
38010  'gesles': '\u2A94',
38011  'gfr': '\uD835\uDD24',
38012  'gimel': '\u2137',
38013  'gjcy': '\u0453',
38014  'glE': '\u2A92',
38015  'gla': '\u2AA5',
38016  'glj': '\u2AA4',
38017  'gnE': '\u2269',
38018  'gneqq': '\u2269',
38019  'gnap': '\u2A8A',
38020  'gnapprox': '\u2A8A',
38021  'gne': '\u2A88',
38022  'gneq': '\u2A88',
38023  'gnsim': '\u22E7',
38024  'gopf': '\uD835\uDD58',
38025  'gscr': '\u210A',
38026  'gsime': '\u2A8E',
38027  'gsiml': '\u2A90',
38028  'gtcc': '\u2AA7',
38029  'gtcir': '\u2A7A',
38030  'gtdot': '\u22D7',
38031  'gtrdot': '\u22D7',
38032  'gtlPar': '\u2995',
38033  'gtquest': '\u2A7C',
38034  'gtrarr': '\u2978',
38035  'gvertneqq': '\u2269\uFE00',
38036  'gvnE': '\u2269\uFE00',
38037  'hardcy': '\u044A',
38038  'harrcir': '\u2948',
38039  'harrw': '\u21AD',
38040  'leftrightsquigarrow': '\u21AD',
38041  'hbar': '\u210F',
38042  'hslash': '\u210F',
38043  'planck': '\u210F',
38044  'plankv': '\u210F',
38045  'hcirc': '\u0125',
38046  'hearts': '\u2665',
38047  'heartsuit': '\u2665',
38048  'hellip': '\u2026',
38049  'mldr': '\u2026',
38050  'hercon': '\u22B9',
38051  'hfr': '\uD835\uDD25',
38052  'hksearow': '\u2925',
38053  'searhk': '\u2925',
38054  'hkswarow': '\u2926',
38055  'swarhk': '\u2926',
38056  'hoarr': '\u21FF',
38057  'homtht': '\u223B',
38058  'hookleftarrow': '\u21A9',
38059  'larrhk': '\u21A9',
38060  'hookrightarrow': '\u21AA',
38061  'rarrhk': '\u21AA',
38062  'hopf': '\uD835\uDD59',
38063  'horbar': '\u2015',
38064  'hscr': '\uD835\uDCBD',
38065  'hstrok': '\u0127',
38066  'hybull': '\u2043',
38067  'iacute': '\u00ED',
38068  'icirc': '\u00EE',
38069  'icy': '\u0438',
38070  'iecy': '\u0435',
38071  'iexcl': '\u00A1',
38072  'ifr': '\uD835\uDD26',
38073  'igrave': '\u00EC',
38074  'iiiint': '\u2A0C',
38075  'qint': '\u2A0C',
38076  'iiint': '\u222D',
38077  'tint': '\u222D',
38078  'iinfin': '\u29DC',
38079  'iiota': '\u2129',
38080  'ijlig': '\u0133',
38081  'imacr': '\u012B',
38082  'imath': '\u0131',
38083  'inodot': '\u0131',
38084  'imof': '\u22B7',
38085  'imped': '\u01B5',
38086  'incare': '\u2105',
38087  'infin': '\u221E',
38088  'infintie': '\u29DD',
38089  'intcal': '\u22BA',
38090  'intercal': '\u22BA',
38091  'intlarhk': '\u2A17',
38092  'intprod': '\u2A3C',
38093  'iprod': '\u2A3C',
38094  'iocy': '\u0451',
38095  'iogon': '\u012F',
38096  'iopf': '\uD835\uDD5A',
38097  'iota': '\u03B9',
38098  'iquest': '\u00BF',
38099  'iscr': '\uD835\uDCBE',
38100  'isinE': '\u22F9',
38101  'isindot': '\u22F5',
38102  'isins': '\u22F4',
38103  'isinsv': '\u22F3',
38104  'itilde': '\u0129',
38105  'iukcy': '\u0456',
38106  'iuml': '\u00EF',
38107  'jcirc': '\u0135',
38108  'jcy': '\u0439',
38109  'jfr': '\uD835\uDD27',
38110  'jmath': '\u0237',
38111  'jopf': '\uD835\uDD5B',
38112  'jscr': '\uD835\uDCBF',
38113  'jsercy': '\u0458',
38114  'jukcy': '\u0454',
38115  'kappa': '\u03BA',
38116  'kappav': '\u03F0',
38117  'varkappa': '\u03F0',
38118  'kcedil': '\u0137',
38119  'kcy': '\u043A',
38120  'kfr': '\uD835\uDD28',
38121  'kgreen': '\u0138',
38122  'khcy': '\u0445',
38123  'kjcy': '\u045C',
38124  'kopf': '\uD835\uDD5C',
38125  'kscr': '\uD835\uDCC0',
38126  'lAtail': '\u291B',
38127  'lBarr': '\u290E',
38128  'lEg': '\u2A8B',
38129  'lesseqqgtr': '\u2A8B',
38130  'lHar': '\u2962',
38131  'lacute': '\u013A',
38132  'laemptyv': '\u29B4',
38133  'lambda': '\u03BB',
38134  'langd': '\u2991',
38135  'lap': '\u2A85',
38136  'lessapprox': '\u2A85',
38137  'laquo': '\u00AB',
38138  'larrbfs': '\u291F',
38139  'larrfs': '\u291D',
38140  'larrlp': '\u21AB',
38141  'looparrowleft': '\u21AB',
38142  'larrpl': '\u2939',
38143  'larrsim': '\u2973',
38144  'larrtl': '\u21A2',
38145  'leftarrowtail': '\u21A2',
38146  'lat': '\u2AAB',
38147  'latail': '\u2919',
38148  'late': '\u2AAD',
38149  'lates': '\u2AAD\uFE00',
38150  'lbarr': '\u290C',
38151  'lbbrk': '\u2772',
38152  'lbrace': '\u007B',
38153  'lcub': '\u007B',
38154  'lbrack': '\u005B',
38155  'lsqb': '\u005B',
38156  'lbrke': '\u298B',
38157  'lbrksld': '\u298F',
38158  'lbrkslu': '\u298D',
38159  'lcaron': '\u013E',
38160  'lcedil': '\u013C',
38161  'lcy': '\u043B',
38162  'ldca': '\u2936',
38163  'ldrdhar': '\u2967',
38164  'ldrushar': '\u294B',
38165  'ldsh': '\u21B2',
38166  'le': '\u2264',
38167  'leq': '\u2264',
38168  'leftleftarrows': '\u21C7',
38169  'llarr': '\u21C7',
38170  'leftthreetimes': '\u22CB',
38171  'lthree': '\u22CB',
38172  'lescc': '\u2AA8',
38173  'lesdot': '\u2A7F',
38174  'lesdoto': '\u2A81',
38175  'lesdotor': '\u2A83',
38176  'lesg': '\u22DA\uFE00',
38177  'lesges': '\u2A93',
38178  'lessdot': '\u22D6',
38179  'ltdot': '\u22D6',
38180  'lfisht': '\u297C',
38181  'lfr': '\uD835\uDD29',
38182  'lgE': '\u2A91',
38183  'lharul': '\u296A',
38184  'lhblk': '\u2584',
38185  'ljcy': '\u0459',
38186  'llhard': '\u296B',
38187  'lltri': '\u25FA',
38188  'lmidot': '\u0140',
38189  'lmoust': '\u23B0',
38190  'lmoustache': '\u23B0',
38191  'lnE': '\u2268',
38192  'lneqq': '\u2268',
38193  'lnap': '\u2A89',
38194  'lnapprox': '\u2A89',
38195  'lne': '\u2A87',
38196  'lneq': '\u2A87',
38197  'lnsim': '\u22E6',
38198  'loang': '\u27EC',
38199  'loarr': '\u21FD',
38200  'longmapsto': '\u27FC',
38201  'xmap': '\u27FC',
38202  'looparrowright': '\u21AC',
38203  'rarrlp': '\u21AC',
38204  'lopar': '\u2985',
38205  'lopf': '\uD835\uDD5D',
38206  'loplus': '\u2A2D',
38207  'lotimes': '\u2A34',
38208  'lowast': '\u2217',
38209  'loz': '\u25CA',
38210  'lozenge': '\u25CA',
38211  'lpar': '\u0028',
38212  'lparlt': '\u2993',
38213  'lrhard': '\u296D',
38214  'lrm': '\u200E',
38215  'lrtri': '\u22BF',
38216  'lsaquo': '\u2039',
38217  'lscr': '\uD835\uDCC1',
38218  'lsime': '\u2A8D',
38219  'lsimg': '\u2A8F',
38220  'lsquor': '\u201A',
38221  'sbquo': '\u201A',
38222  'lstrok': '\u0142',
38223  'ltcc': '\u2AA6',
38224  'ltcir': '\u2A79',
38225  'ltimes': '\u22C9',
38226  'ltlarr': '\u2976',
38227  'ltquest': '\u2A7B',
38228  'ltrPar': '\u2996',
38229  'ltri': '\u25C3',
38230  'triangleleft': '\u25C3',
38231  'lurdshar': '\u294A',
38232  'luruhar': '\u2966',
38233  'lvertneqq': '\u2268\uFE00',
38234  'lvnE': '\u2268\uFE00',
38235  'mDDot': '\u223A',
38236  'macr': '\u00AF',
38237  'strns': '\u00AF',
38238  'male': '\u2642',
38239  'malt': '\u2720',
38240  'maltese': '\u2720',
38241  'marker': '\u25AE',
38242  'mcomma': '\u2A29',
38243  'mcy': '\u043C',
38244  'mdash': '\u2014',
38245  'mfr': '\uD835\uDD2A',
38246  'mho': '\u2127',
38247  'micro': '\u00B5',
38248  'midcir': '\u2AF0',
38249  'minus': '\u2212',
38250  'minusdu': '\u2A2A',
38251  'mlcp': '\u2ADB',
38252  'models': '\u22A7',
38253  'mopf': '\uD835\uDD5E',
38254  'mscr': '\uD835\uDCC2',
38255  'mu': '\u03BC',
38256  'multimap': '\u22B8',
38257  'mumap': '\u22B8',
38258  'nGg': '\u22D9\u0338',
38259  'nGt': '\u226B\u20D2',
38260  'nLeftarrow': '\u21CD',
38261  'nlArr': '\u21CD',
38262  'nLeftrightarrow': '\u21CE',
38263  'nhArr': '\u21CE',
38264  'nLl': '\u22D8\u0338',
38265  'nLt': '\u226A\u20D2',
38266  'nRightarrow': '\u21CF',
38267  'nrArr': '\u21CF',
38268  'nVDash': '\u22AF',
38269  'nVdash': '\u22AE',
38270  'nacute': '\u0144',
38271  'nang': '\u2220\u20D2',
38272  'napE': '\u2A70\u0338',
38273  'napid': '\u224B\u0338',
38274  'napos': '\u0149',
38275  'natur': '\u266E',
38276  'natural': '\u266E',
38277  'ncap': '\u2A43',
38278  'ncaron': '\u0148',
38279  'ncedil': '\u0146',
38280  'ncongdot': '\u2A6D\u0338',
38281  'ncup': '\u2A42',
38282  'ncy': '\u043D',
38283  'ndash': '\u2013',
38284  'neArr': '\u21D7',
38285  'nearhk': '\u2924',
38286  'nedot': '\u2250\u0338',
38287  'nesear': '\u2928',
38288  'toea': '\u2928',
38289  'nfr': '\uD835\uDD2B',
38290  'nharr': '\u21AE',
38291  'nleftrightarrow': '\u21AE',
38292  'nhpar': '\u2AF2',
38293  'nis': '\u22FC',
38294  'nisd': '\u22FA',
38295  'njcy': '\u045A',
38296  'nlE': '\u2266\u0338',
38297  'nleqq': '\u2266\u0338',
38298  'nlarr': '\u219A',
38299  'nleftarrow': '\u219A',
38300  'nldr': '\u2025',
38301  'nopf': '\uD835\uDD5F',
38302  'not': '\u00AC',
38303  'notinE': '\u22F9\u0338',
38304  'notindot': '\u22F5\u0338',
38305  'notinvb': '\u22F7',
38306  'notinvc': '\u22F6',
38307  'notnivb': '\u22FE',
38308  'notnivc': '\u22FD',
38309  'nparsl': '\u2AFD\u20E5',
38310  'npart': '\u2202\u0338',
38311  'npolint': '\u2A14',
38312  'nrarr': '\u219B',
38313  'nrightarrow': '\u219B',
38314  'nrarrc': '\u2933\u0338',
38315  'nrarrw': '\u219D\u0338',
38316  'nscr': '\uD835\uDCC3',
38317  'nsub': '\u2284',
38318  'nsubE': '\u2AC5\u0338',
38319  'nsubseteqq': '\u2AC5\u0338',
38320  'nsup': '\u2285',
38321  'nsupE': '\u2AC6\u0338',
38322  'nsupseteqq': '\u2AC6\u0338',
38323  'ntilde': '\u00F1',
38324  'nu': '\u03BD',
38325  'num': '\u0023',
38326  'numero': '\u2116',
38327  'numsp': '\u2007',
38328  'nvDash': '\u22AD',
38329  'nvHarr': '\u2904',
38330  'nvap': '\u224D\u20D2',
38331  'nvdash': '\u22AC',
38332  'nvge': '\u2265\u20D2',
38333  'nvgt': '\u003E\u20D2',
38334  'nvinfin': '\u29DE',
38335  'nvlArr': '\u2902',
38336  'nvle': '\u2264\u20D2',
38337  'nvlt': '\u003C\u20D2',
38338  'nvltrie': '\u22B4\u20D2',
38339  'nvrArr': '\u2903',
38340  'nvrtrie': '\u22B5\u20D2',
38341  'nvsim': '\u223C\u20D2',
38342  'nwArr': '\u21D6',
38343  'nwarhk': '\u2923',
38344  'nwnear': '\u2927',
38345  'oacute': '\u00F3',
38346  'ocirc': '\u00F4',
38347  'ocy': '\u043E',
38348  'odblac': '\u0151',
38349  'odiv': '\u2A38',
38350  'odsold': '\u29BC',
38351  'oelig': '\u0153',
38352  'ofcir': '\u29BF',
38353  'ofr': '\uD835\uDD2C',
38354  'ogon': '\u02DB',
38355  'ograve': '\u00F2',
38356  'ogt': '\u29C1',
38357  'ohbar': '\u29B5',
38358  'olcir': '\u29BE',
38359  'olcross': '\u29BB',
38360  'olt': '\u29C0',
38361  'omacr': '\u014D',
38362  'omega': '\u03C9',
38363  'omicron': '\u03BF',
38364  'omid': '\u29B6',
38365  'oopf': '\uD835\uDD60',
38366  'opar': '\u29B7',
38367  'operp': '\u29B9',
38368  'or': '\u2228',
38369  'vee': '\u2228',
38370  'ord': '\u2A5D',
38371  'order': '\u2134',
38372  'orderof': '\u2134',
38373  'oscr': '\u2134',
38374  'ordf': '\u00AA',
38375  'ordm': '\u00BA',
38376  'origof': '\u22B6',
38377  'oror': '\u2A56',
38378  'orslope': '\u2A57',
38379  'orv': '\u2A5B',
38380  'oslash': '\u00F8',
38381  'osol': '\u2298',
38382  'otilde': '\u00F5',
38383  'otimesas': '\u2A36',
38384  'ouml': '\u00F6',
38385  'ovbar': '\u233D',
38386  'para': '\u00B6',
38387  'parsim': '\u2AF3',
38388  'parsl': '\u2AFD',
38389  'pcy': '\u043F',
38390  'percnt': '\u0025',
38391  'period': '\u002E',
38392  'permil': '\u2030',
38393  'pertenk': '\u2031',
38394  'pfr': '\uD835\uDD2D',
38395  'phi': '\u03C6',
38396  'phiv': '\u03D5',
38397  'straightphi': '\u03D5',
38398  'varphi': '\u03D5',
38399  'phone': '\u260E',
38400  'pi': '\u03C0',
38401  'piv': '\u03D6',
38402  'varpi': '\u03D6',
38403  'planckh': '\u210E',
38404  'plus': '\u002B',
38405  'plusacir': '\u2A23',
38406  'pluscir': '\u2A22',
38407  'plusdu': '\u2A25',
38408  'pluse': '\u2A72',
38409  'plussim': '\u2A26',
38410  'plustwo': '\u2A27',
38411  'pointint': '\u2A15',
38412  'popf': '\uD835\uDD61',
38413  'pound': '\u00A3',
38414  'prE': '\u2AB3',
38415  'prap': '\u2AB7',
38416  'precapprox': '\u2AB7',
38417  'precnapprox': '\u2AB9',
38418  'prnap': '\u2AB9',
38419  'precneqq': '\u2AB5',
38420  'prnE': '\u2AB5',
38421  'precnsim': '\u22E8',
38422  'prnsim': '\u22E8',
38423  'prime': '\u2032',
38424  'profalar': '\u232E',
38425  'profline': '\u2312',
38426  'profsurf': '\u2313',
38427  'prurel': '\u22B0',
38428  'pscr': '\uD835\uDCC5',
38429  'psi': '\u03C8',
38430  'puncsp': '\u2008',
38431  'qfr': '\uD835\uDD2E',
38432  'qopf': '\uD835\uDD62',
38433  'qprime': '\u2057',
38434  'qscr': '\uD835\uDCC6',
38435  'quatint': '\u2A16',
38436  'quest': '\u003F',
38437  'rAtail': '\u291C',
38438  'rHar': '\u2964',
38439  'race': '\u223D\u0331',
38440  'racute': '\u0155',
38441  'raemptyv': '\u29B3',
38442  'rangd': '\u2992',
38443  'range': '\u29A5',
38444  'raquo': '\u00BB',
38445  'rarrap': '\u2975',
38446  'rarrbfs': '\u2920',
38447  'rarrc': '\u2933',
38448  'rarrfs': '\u291E',
38449  'rarrpl': '\u2945',
38450  'rarrsim': '\u2974',
38451  'rarrtl': '\u21A3',
38452  'rightarrowtail': '\u21A3',
38453  'rarrw': '\u219D',
38454  'rightsquigarrow': '\u219D',
38455  'ratail': '\u291A',
38456  'ratio': '\u2236',
38457  'rbbrk': '\u2773',
38458  'rbrace': '\u007D',
38459  'rcub': '\u007D',
38460  'rbrack': '\u005D',
38461  'rsqb': '\u005D',
38462  'rbrke': '\u298C',
38463  'rbrksld': '\u298E',
38464  'rbrkslu': '\u2990',
38465  'rcaron': '\u0159',
38466  'rcedil': '\u0157',
38467  'rcy': '\u0440',
38468  'rdca': '\u2937',
38469  'rdldhar': '\u2969',
38470  'rdsh': '\u21B3',
38471  'rect': '\u25AD',
38472  'rfisht': '\u297D',
38473  'rfr': '\uD835\uDD2F',
38474  'rharul': '\u296C',
38475  'rho': '\u03C1',
38476  'rhov': '\u03F1',
38477  'varrho': '\u03F1',
38478  'rightrightarrows': '\u21C9',
38479  'rrarr': '\u21C9',
38480  'rightthreetimes': '\u22CC',
38481  'rthree': '\u22CC',
38482  'ring': '\u02DA',
38483  'rlm': '\u200F',
38484  'rmoust': '\u23B1',
38485  'rmoustache': '\u23B1',
38486  'rnmid': '\u2AEE',
38487  'roang': '\u27ED',
38488  'roarr': '\u21FE',
38489  'ropar': '\u2986',
38490  'ropf': '\uD835\uDD63',
38491  'roplus': '\u2A2E',
38492  'rotimes': '\u2A35',
38493  'rpar': '\u0029',
38494  'rpargt': '\u2994',
38495  'rppolint': '\u2A12',
38496  'rsaquo': '\u203A',
38497  'rscr': '\uD835\uDCC7',
38498  'rtimes': '\u22CA',
38499  'rtri': '\u25B9',
38500  'triangleright': '\u25B9',
38501  'rtriltri': '\u29CE',
38502  'ruluhar': '\u2968',
38503  'rx': '\u211E',
38504  'sacute': '\u015B',
38505  'scE': '\u2AB4',
38506  'scap': '\u2AB8',
38507  'succapprox': '\u2AB8',
38508  'scaron': '\u0161',
38509  'scedil': '\u015F',
38510  'scirc': '\u015D',
38511  'scnE': '\u2AB6',
38512  'succneqq': '\u2AB6',
38513  'scnap': '\u2ABA',
38514  'succnapprox': '\u2ABA',
38515  'scnsim': '\u22E9',
38516  'succnsim': '\u22E9',
38517  'scpolint': '\u2A13',
38518  'scy': '\u0441',
38519  'sdot': '\u22C5',
38520  'sdote': '\u2A66',
38521  'seArr': '\u21D8',
38522  'sect': '\u00A7',
38523  'semi': '\u003B',
38524  'seswar': '\u2929',
38525  'tosa': '\u2929',
38526  'sext': '\u2736',
38527  'sfr': '\uD835\uDD30',
38528  'sharp': '\u266F',
38529  'shchcy': '\u0449',
38530  'shcy': '\u0448',
38531  'shy': '\u00AD',
38532  'sigma': '\u03C3',
38533  'sigmaf': '\u03C2',
38534  'sigmav': '\u03C2',
38535  'varsigma': '\u03C2',
38536  'simdot': '\u2A6A',
38537  'simg': '\u2A9E',
38538  'simgE': '\u2AA0',
38539  'siml': '\u2A9D',
38540  'simlE': '\u2A9F',
38541  'simne': '\u2246',
38542  'simplus': '\u2A24',
38543  'simrarr': '\u2972',
38544  'smashp': '\u2A33',
38545  'smeparsl': '\u29E4',
38546  'smile': '\u2323',
38547  'ssmile': '\u2323',
38548  'smt': '\u2AAA',
38549  'smte': '\u2AAC',
38550  'smtes': '\u2AAC\uFE00',
38551  'softcy': '\u044C',
38552  'sol': '\u002F',
38553  'solb': '\u29C4',
38554  'solbar': '\u233F',
38555  'sopf': '\uD835\uDD64',
38556  'spades': '\u2660',
38557  'spadesuit': '\u2660',
38558  'sqcaps': '\u2293\uFE00',
38559  'sqcups': '\u2294\uFE00',
38560  'sscr': '\uD835\uDCC8',
38561  'star': '\u2606',
38562  'sub': '\u2282',
38563  'subset': '\u2282',
38564  'subE': '\u2AC5',
38565  'subseteqq': '\u2AC5',
38566  'subdot': '\u2ABD',
38567  'subedot': '\u2AC3',
38568  'submult': '\u2AC1',
38569  'subnE': '\u2ACB',
38570  'subsetneqq': '\u2ACB',
38571  'subne': '\u228A',
38572  'subsetneq': '\u228A',
38573  'subplus': '\u2ABF',
38574  'subrarr': '\u2979',
38575  'subsim': '\u2AC7',
38576  'subsub': '\u2AD5',
38577  'subsup': '\u2AD3',
38578  'sung': '\u266A',
38579  'sup1': '\u00B9',
38580  'sup2': '\u00B2',
38581  'sup3': '\u00B3',
38582  'supE': '\u2AC6',
38583  'supseteqq': '\u2AC6',
38584  'supdot': '\u2ABE',
38585  'supdsub': '\u2AD8',
38586  'supedot': '\u2AC4',
38587  'suphsol': '\u27C9',
38588  'suphsub': '\u2AD7',
38589  'suplarr': '\u297B',
38590  'supmult': '\u2AC2',
38591  'supnE': '\u2ACC',
38592  'supsetneqq': '\u2ACC',
38593  'supne': '\u228B',
38594  'supsetneq': '\u228B',
38595  'supplus': '\u2AC0',
38596  'supsim': '\u2AC8',
38597  'supsub': '\u2AD4',
38598  'supsup': '\u2AD6',
38599  'swArr': '\u21D9',
38600  'swnwar': '\u292A',
38601  'szlig': '\u00DF',
38602  'target': '\u2316',
38603  'tau': '\u03C4',
38604  'tcaron': '\u0165',
38605  'tcedil': '\u0163',
38606  'tcy': '\u0442',
38607  'telrec': '\u2315',
38608  'tfr': '\uD835\uDD31',
38609  'theta': '\u03B8',
38610  'thetasym': '\u03D1',
38611  'thetav': '\u03D1',
38612  'vartheta': '\u03D1',
38613  'thorn': '\u00FE',
38614  'times': '\u00D7',
38615  'timesbar': '\u2A31',
38616  'timesd': '\u2A30',
38617  'topbot': '\u2336',
38618  'topcir': '\u2AF1',
38619  'topf': '\uD835\uDD65',
38620  'topfork': '\u2ADA',
38621  'tprime': '\u2034',
38622  'triangle': '\u25B5',
38623  'utri': '\u25B5',
38624  'triangleq': '\u225C',
38625  'trie': '\u225C',
38626  'tridot': '\u25EC',
38627  'triminus': '\u2A3A',
38628  'triplus': '\u2A39',
38629  'trisb': '\u29CD',
38630  'tritime': '\u2A3B',
38631  'trpezium': '\u23E2',
38632  'tscr': '\uD835\uDCC9',
38633  'tscy': '\u0446',
38634  'tshcy': '\u045B',
38635  'tstrok': '\u0167',
38636  'uHar': '\u2963',
38637  'uacute': '\u00FA',
38638  'ubrcy': '\u045E',
38639  'ubreve': '\u016D',
38640  'ucirc': '\u00FB',
38641  'ucy': '\u0443',
38642  'udblac': '\u0171',
38643  'ufisht': '\u297E',
38644  'ufr': '\uD835\uDD32',
38645  'ugrave': '\u00F9',
38646  'uhblk': '\u2580',
38647  'ulcorn': '\u231C',
38648  'ulcorner': '\u231C',
38649  'ulcrop': '\u230F',
38650  'ultri': '\u25F8',
38651  'umacr': '\u016B',
38652  'uogon': '\u0173',
38653  'uopf': '\uD835\uDD66',
38654  'upsi': '\u03C5',
38655  'upsilon': '\u03C5',
38656  'upuparrows': '\u21C8',
38657  'uuarr': '\u21C8',
38658  'urcorn': '\u231D',
38659  'urcorner': '\u231D',
38660  'urcrop': '\u230E',
38661  'uring': '\u016F',
38662  'urtri': '\u25F9',
38663  'uscr': '\uD835\uDCCA',
38664  'utdot': '\u22F0',
38665  'utilde': '\u0169',
38666  'uuml': '\u00FC',
38667  'uwangle': '\u29A7',
38668  'vBar': '\u2AE8',
38669  'vBarv': '\u2AE9',
38670  'vangrt': '\u299C',
38671  'varsubsetneq': '\u228A\uFE00',
38672  'vsubne': '\u228A\uFE00',
38673  'varsubsetneqq': '\u2ACB\uFE00',
38674  'vsubnE': '\u2ACB\uFE00',
38675  'varsupsetneq': '\u228B\uFE00',
38676  'vsupne': '\u228B\uFE00',
38677  'varsupsetneqq': '\u2ACC\uFE00',
38678  'vsupnE': '\u2ACC\uFE00',
38679  'vcy': '\u0432',
38680  'veebar': '\u22BB',
38681  'veeeq': '\u225A',
38682  'vellip': '\u22EE',
38683  'vfr': '\uD835\uDD33',
38684  'vopf': '\uD835\uDD67',
38685  'vscr': '\uD835\uDCCB',
38686  'vzigzag': '\u299A',
38687  'wcirc': '\u0175',
38688  'wedbar': '\u2A5F',
38689  'wedgeq': '\u2259',
38690  'weierp': '\u2118',
38691  'wp': '\u2118',
38692  'wfr': '\uD835\uDD34',
38693  'wopf': '\uD835\uDD68',
38694  'wscr': '\uD835\uDCCC',
38695  'xfr': '\uD835\uDD35',
38696  'xi': '\u03BE',
38697  'xnis': '\u22FB',
38698  'xopf': '\uD835\uDD69',
38699  'xscr': '\uD835\uDCCD',
38700  'yacute': '\u00FD',
38701  'yacy': '\u044F',
38702  'ycirc': '\u0177',
38703  'ycy': '\u044B',
38704  'yen': '\u00A5',
38705  'yfr': '\uD835\uDD36',
38706  'yicy': '\u0457',
38707  'yopf': '\uD835\uDD6A',
38708  'yscr': '\uD835\uDCCE',
38709  'yucy': '\u044E',
38710  'yuml': '\u00FF',
38711  'zacute': '\u017A',
38712  'zcaron': '\u017E',
38713  'zcy': '\u0437',
38714  'zdot': '\u017C',
38715  'zeta': '\u03B6',
38716  'zfr': '\uD835\uDD37',
38717  'zhcy': '\u0436',
38718  'zigrarr': '\u21DD',
38719  'zopf': '\uD835\uDD6B',
38720  'zscr': '\uD835\uDCCF',
38721  'zwj': '\u200D',
38722  'zwnj': '\u200C'
38723}; // The &ngsp; pseudo-entity is denoting a space. see:
38724// https://github.com/dart-lang/angular/blob/0bb611387d29d65b5af7f9d2515ab571fd3fbee4/_tests/test/compiler/preserve_whitespace_test.dart
38725
38726const NGSP_UNICODE = '\uE500';
38727NAMED_ENTITIES['ngsp'] = NGSP_UNICODE;
38728/**
38729 * @license
38730 * Copyright Google LLC All Rights Reserved.
38731 *
38732 * Use of this source code is governed by an MIT-style license that can be
38733 * found in the LICENSE file at https://angular.io/license
38734 */
38735
38736class TokenError extends ParseError {
38737  constructor(errorMsg, tokenType, span) {
38738    super(span, errorMsg);
38739    this.tokenType = tokenType;
38740  }
38741
38742}
38743
38744class TokenizeResult {
38745  constructor(tokens, errors, nonNormalizedIcuExpressions) {
38746    this.tokens = tokens;
38747    this.errors = errors;
38748    this.nonNormalizedIcuExpressions = nonNormalizedIcuExpressions;
38749  }
38750
38751}
38752
38753function tokenize(source, url, getTagDefinition, options = {}) {
38754  const tokenizer = new _Tokenizer(new ParseSourceFile(source, url), getTagDefinition, options);
38755  tokenizer.tokenize();
38756  return new TokenizeResult(mergeTextTokens(tokenizer.tokens), tokenizer.errors, tokenizer.nonNormalizedIcuExpressions);
38757}
38758
38759const _CR_OR_CRLF_REGEXP = /\r\n?/g;
38760
38761function _unexpectedCharacterErrorMsg(charCode) {
38762  const char = charCode === $EOF ? 'EOF' : String.fromCharCode(charCode);
38763  return `Unexpected character "${char}"`;
38764}
38765
38766function _unknownEntityErrorMsg(entitySrc) {
38767  return `Unknown entity "${entitySrc}" - use the "&#<decimal>;" or  "&#x<hex>;" syntax`;
38768}
38769
38770function _unparsableEntityErrorMsg(type, entityStr) {
38771  return `Unable to parse entity "${entityStr}" - ${type} character reference entities must end with ";"`;
38772}
38773
38774var CharacterReferenceType;
38775
38776(function (CharacterReferenceType) {
38777  CharacterReferenceType["HEX"] = "hexadecimal";
38778  CharacterReferenceType["DEC"] = "decimal";
38779})(CharacterReferenceType || (CharacterReferenceType = {}));
38780
38781class _ControlFlowError {
38782  constructor(error) {
38783    this.error = error;
38784  }
38785
38786} // See https://www.w3.org/TR/html51/syntax.html#writing-html-documents
38787
38788
38789class _Tokenizer {
38790  /**
38791   * @param _file The html source file being tokenized.
38792   * @param _getTagDefinition A function that will retrieve a tag definition for a given tag name.
38793   * @param options Configuration of the tokenization.
38794   */
38795  constructor(_file, _getTagDefinition, options) {
38796    this._getTagDefinition = _getTagDefinition;
38797    this._currentTokenStart = null;
38798    this._currentTokenType = null;
38799    this._expansionCaseStack = [];
38800    this._inInterpolation = false;
38801    this.tokens = [];
38802    this.errors = [];
38803    this.nonNormalizedIcuExpressions = [];
38804    this._tokenizeIcu = options.tokenizeExpansionForms || false;
38805    this._interpolationConfig = options.interpolationConfig || DEFAULT_INTERPOLATION_CONFIG;
38806    this._leadingTriviaCodePoints = options.leadingTriviaChars && options.leadingTriviaChars.map(c => c.codePointAt(0) || 0);
38807    const range = options.range || {
38808      endPos: _file.content.length,
38809      startPos: 0,
38810      startLine: 0,
38811      startCol: 0
38812    };
38813    this._cursor = options.escapedString ? new EscapedCharacterCursor(_file, range) : new PlainCharacterCursor(_file, range);
38814    this._preserveLineEndings = options.preserveLineEndings || false;
38815    this._escapedString = options.escapedString || false;
38816    this._i18nNormalizeLineEndingsInICUs = options.i18nNormalizeLineEndingsInICUs || false;
38817
38818    try {
38819      this._cursor.init();
38820    } catch (e) {
38821      this.handleError(e);
38822    }
38823  }
38824
38825  _processCarriageReturns(content) {
38826    if (this._preserveLineEndings) {
38827      return content;
38828    } // https://www.w3.org/TR/html51/syntax.html#preprocessing-the-input-stream
38829    // In order to keep the original position in the source, we can not
38830    // pre-process it.
38831    // Instead CRs are processed right before instantiating the tokens.
38832
38833
38834    return content.replace(_CR_OR_CRLF_REGEXP, '\n');
38835  }
38836
38837  tokenize() {
38838    while (this._cursor.peek() !== $EOF) {
38839      const start = this._cursor.clone();
38840
38841      try {
38842        if (this._attemptCharCode($LT)) {
38843          if (this._attemptCharCode($BANG)) {
38844            if (this._attemptCharCode($LBRACKET)) {
38845              this._consumeCdata(start);
38846            } else if (this._attemptCharCode($MINUS)) {
38847              this._consumeComment(start);
38848            } else {
38849              this._consumeDocType(start);
38850            }
38851          } else if (this._attemptCharCode($SLASH)) {
38852            this._consumeTagClose(start);
38853          } else {
38854            this._consumeTagOpen(start);
38855          }
38856        } else if (!(this._tokenizeIcu && this._tokenizeExpansionForm())) {
38857          // In (possibly interpolated) text the end of the text is given by `isTextEnd()`, while
38858          // the premature end of an interpolation is given by the start of a new HTML element.
38859          this._consumeWithInterpolation(5
38860          /* TokenType.TEXT */
38861          , 8
38862          /* TokenType.INTERPOLATION */
38863          , () => this._isTextEnd(), () => this._isTagStart());
38864        }
38865      } catch (e) {
38866        this.handleError(e);
38867      }
38868    }
38869
38870    this._beginToken(24
38871    /* TokenType.EOF */
38872    );
38873
38874    this._endToken([]);
38875  }
38876  /**
38877   * @returns whether an ICU token has been created
38878   * @internal
38879   */
38880
38881
38882  _tokenizeExpansionForm() {
38883    if (this.isExpansionFormStart()) {
38884      this._consumeExpansionFormStart();
38885
38886      return true;
38887    }
38888
38889    if (isExpansionCaseStart(this._cursor.peek()) && this._isInExpansionForm()) {
38890      this._consumeExpansionCaseStart();
38891
38892      return true;
38893    }
38894
38895    if (this._cursor.peek() === $RBRACE) {
38896      if (this._isInExpansionCase()) {
38897        this._consumeExpansionCaseEnd();
38898
38899        return true;
38900      }
38901
38902      if (this._isInExpansionForm()) {
38903        this._consumeExpansionFormEnd();
38904
38905        return true;
38906      }
38907    }
38908
38909    return false;
38910  }
38911
38912  _beginToken(type, start = this._cursor.clone()) {
38913    this._currentTokenStart = start;
38914    this._currentTokenType = type;
38915  }
38916
38917  _endToken(parts, end) {
38918    if (this._currentTokenStart === null) {
38919      throw new TokenError('Programming error - attempted to end a token when there was no start to the token', this._currentTokenType, this._cursor.getSpan(end));
38920    }
38921
38922    if (this._currentTokenType === null) {
38923      throw new TokenError('Programming error - attempted to end a token which has no token type', null, this._cursor.getSpan(this._currentTokenStart));
38924    }
38925
38926    const token = {
38927      type: this._currentTokenType,
38928      parts,
38929      sourceSpan: (end ?? this._cursor).getSpan(this._currentTokenStart, this._leadingTriviaCodePoints)
38930    };
38931    this.tokens.push(token);
38932    this._currentTokenStart = null;
38933    this._currentTokenType = null;
38934    return token;
38935  }
38936
38937  _createError(msg, span) {
38938    if (this._isInExpansionForm()) {
38939      msg += ` (Do you have an unescaped "{" in your template? Use "{{ '{' }}") to escape it.)`;
38940    }
38941
38942    const error = new TokenError(msg, this._currentTokenType, span);
38943    this._currentTokenStart = null;
38944    this._currentTokenType = null;
38945    return new _ControlFlowError(error);
38946  }
38947
38948  handleError(e) {
38949    if (e instanceof CursorError) {
38950      e = this._createError(e.msg, this._cursor.getSpan(e.cursor));
38951    }
38952
38953    if (e instanceof _ControlFlowError) {
38954      this.errors.push(e.error);
38955    } else {
38956      throw e;
38957    }
38958  }
38959
38960  _attemptCharCode(charCode) {
38961    if (this._cursor.peek() === charCode) {
38962      this._cursor.advance();
38963
38964      return true;
38965    }
38966
38967    return false;
38968  }
38969
38970  _attemptCharCodeCaseInsensitive(charCode) {
38971    if (compareCharCodeCaseInsensitive(this._cursor.peek(), charCode)) {
38972      this._cursor.advance();
38973
38974      return true;
38975    }
38976
38977    return false;
38978  }
38979
38980  _requireCharCode(charCode) {
38981    const location = this._cursor.clone();
38982
38983    if (!this._attemptCharCode(charCode)) {
38984      throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(location));
38985    }
38986  }
38987
38988  _attemptStr(chars) {
38989    const len = chars.length;
38990
38991    if (this._cursor.charsLeft() < len) {
38992      return false;
38993    }
38994
38995    const initialPosition = this._cursor.clone();
38996
38997    for (let i = 0; i < len; i++) {
38998      if (!this._attemptCharCode(chars.charCodeAt(i))) {
38999        // If attempting to parse the string fails, we want to reset the parser
39000        // to where it was before the attempt
39001        this._cursor = initialPosition;
39002        return false;
39003      }
39004    }
39005
39006    return true;
39007  }
39008
39009  _attemptStrCaseInsensitive(chars) {
39010    for (let i = 0; i < chars.length; i++) {
39011      if (!this._attemptCharCodeCaseInsensitive(chars.charCodeAt(i))) {
39012        return false;
39013      }
39014    }
39015
39016    return true;
39017  }
39018
39019  _requireStr(chars) {
39020    const location = this._cursor.clone();
39021
39022    if (!this._attemptStr(chars)) {
39023      throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(location));
39024    }
39025  }
39026
39027  _attemptCharCodeUntilFn(predicate) {
39028    while (!predicate(this._cursor.peek())) {
39029      this._cursor.advance();
39030    }
39031  }
39032
39033  _requireCharCodeUntilFn(predicate, len) {
39034    const start = this._cursor.clone();
39035
39036    this._attemptCharCodeUntilFn(predicate);
39037
39038    if (this._cursor.diff(start) < len) {
39039      throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(start));
39040    }
39041  }
39042
39043  _attemptUntilChar(char) {
39044    while (this._cursor.peek() !== char) {
39045      this._cursor.advance();
39046    }
39047  }
39048
39049  _readChar() {
39050    // Don't rely upon reading directly from `_input` as the actual char value
39051    // may have been generated from an escape sequence.
39052    const char = String.fromCodePoint(this._cursor.peek());
39053
39054    this._cursor.advance();
39055
39056    return char;
39057  }
39058
39059  _consumeEntity(textTokenType) {
39060    this._beginToken(9
39061    /* TokenType.ENCODED_ENTITY */
39062    );
39063
39064    const start = this._cursor.clone();
39065
39066    this._cursor.advance();
39067
39068    if (this._attemptCharCode($HASH)) {
39069      const isHex = this._attemptCharCode($x) || this._attemptCharCode($X);
39070
39071      const codeStart = this._cursor.clone();
39072
39073      this._attemptCharCodeUntilFn(isDigitEntityEnd);
39074
39075      if (this._cursor.peek() != $SEMICOLON) {
39076        // Advance cursor to include the peeked character in the string provided to the error
39077        // message.
39078        this._cursor.advance();
39079
39080        const entityType = isHex ? CharacterReferenceType.HEX : CharacterReferenceType.DEC;
39081        throw this._createError(_unparsableEntityErrorMsg(entityType, this._cursor.getChars(start)), this._cursor.getSpan());
39082      }
39083
39084      const strNum = this._cursor.getChars(codeStart);
39085
39086      this._cursor.advance();
39087
39088      try {
39089        const charCode = parseInt(strNum, isHex ? 16 : 10);
39090
39091        this._endToken([String.fromCharCode(charCode), this._cursor.getChars(start)]);
39092      } catch {
39093        throw this._createError(_unknownEntityErrorMsg(this._cursor.getChars(start)), this._cursor.getSpan());
39094      }
39095    } else {
39096      const nameStart = this._cursor.clone();
39097
39098      this._attemptCharCodeUntilFn(isNamedEntityEnd);
39099
39100      if (this._cursor.peek() != $SEMICOLON) {
39101        // No semicolon was found so abort the encoded entity token that was in progress, and treat
39102        // this as a text token
39103        this._beginToken(textTokenType, start);
39104
39105        this._cursor = nameStart;
39106
39107        this._endToken(['&']);
39108      } else {
39109        const name = this._cursor.getChars(nameStart);
39110
39111        this._cursor.advance();
39112
39113        const char = NAMED_ENTITIES[name];
39114
39115        if (!char) {
39116          throw this._createError(_unknownEntityErrorMsg(name), this._cursor.getSpan(start));
39117        }
39118
39119        this._endToken([char, `&${name};`]);
39120      }
39121    }
39122  }
39123
39124  _consumeRawText(consumeEntities, endMarkerPredicate) {
39125    this._beginToken(consumeEntities ? 6
39126    /* TokenType.ESCAPABLE_RAW_TEXT */
39127    : 7
39128    /* TokenType.RAW_TEXT */
39129    );
39130
39131    const parts = [];
39132
39133    while (true) {
39134      const tagCloseStart = this._cursor.clone();
39135
39136      const foundEndMarker = endMarkerPredicate();
39137      this._cursor = tagCloseStart;
39138
39139      if (foundEndMarker) {
39140        break;
39141      }
39142
39143      if (consumeEntities && this._cursor.peek() === $AMPERSAND) {
39144        this._endToken([this._processCarriageReturns(parts.join(''))]);
39145
39146        parts.length = 0;
39147
39148        this._consumeEntity(6
39149        /* TokenType.ESCAPABLE_RAW_TEXT */
39150        );
39151
39152        this._beginToken(6
39153        /* TokenType.ESCAPABLE_RAW_TEXT */
39154        );
39155      } else {
39156        parts.push(this._readChar());
39157      }
39158    }
39159
39160    this._endToken([this._processCarriageReturns(parts.join(''))]);
39161  }
39162
39163  _consumeComment(start) {
39164    this._beginToken(10
39165    /* TokenType.COMMENT_START */
39166    , start);
39167
39168    this._requireCharCode($MINUS);
39169
39170    this._endToken([]);
39171
39172    this._consumeRawText(false, () => this._attemptStr('-->'));
39173
39174    this._beginToken(11
39175    /* TokenType.COMMENT_END */
39176    );
39177
39178    this._requireStr('-->');
39179
39180    this._endToken([]);
39181  }
39182
39183  _consumeCdata(start) {
39184    this._beginToken(12
39185    /* TokenType.CDATA_START */
39186    , start);
39187
39188    this._requireStr('CDATA[');
39189
39190    this._endToken([]);
39191
39192    this._consumeRawText(false, () => this._attemptStr(']]>'));
39193
39194    this._beginToken(13
39195    /* TokenType.CDATA_END */
39196    );
39197
39198    this._requireStr(']]>');
39199
39200    this._endToken([]);
39201  }
39202
39203  _consumeDocType(start) {
39204    this._beginToken(18
39205    /* TokenType.DOC_TYPE */
39206    , start);
39207
39208    const contentStart = this._cursor.clone();
39209
39210    this._attemptUntilChar($GT);
39211
39212    const content = this._cursor.getChars(contentStart);
39213
39214    this._cursor.advance();
39215
39216    this._endToken([content]);
39217  }
39218
39219  _consumePrefixAndName() {
39220    const nameOrPrefixStart = this._cursor.clone();
39221
39222    let prefix = '';
39223
39224    while (this._cursor.peek() !== $COLON && !isPrefixEnd(this._cursor.peek())) {
39225      this._cursor.advance();
39226    }
39227
39228    let nameStart;
39229
39230    if (this._cursor.peek() === $COLON) {
39231      prefix = this._cursor.getChars(nameOrPrefixStart);
39232
39233      this._cursor.advance();
39234
39235      nameStart = this._cursor.clone();
39236    } else {
39237      nameStart = nameOrPrefixStart;
39238    }
39239
39240    this._requireCharCodeUntilFn(isNameEnd, prefix === '' ? 0 : 1);
39241
39242    const name = this._cursor.getChars(nameStart);
39243
39244    return [prefix, name];
39245  }
39246
39247  _consumeTagOpen(start) {
39248    let tagName;
39249    let prefix;
39250    let openTagToken;
39251
39252    try {
39253      if (!isAsciiLetter(this._cursor.peek())) {
39254        throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(start));
39255      }
39256
39257      openTagToken = this._consumeTagOpenStart(start);
39258      prefix = openTagToken.parts[0];
39259      tagName = openTagToken.parts[1];
39260
39261      this._attemptCharCodeUntilFn(isNotWhitespace);
39262
39263      while (this._cursor.peek() !== $SLASH && this._cursor.peek() !== $GT && this._cursor.peek() !== $LT && this._cursor.peek() !== $EOF) {
39264        this._consumeAttributeName();
39265
39266        this._attemptCharCodeUntilFn(isNotWhitespace);
39267
39268        if (this._attemptCharCode($EQ)) {
39269          this._attemptCharCodeUntilFn(isNotWhitespace);
39270
39271          this._consumeAttributeValue();
39272        }
39273
39274        this._attemptCharCodeUntilFn(isNotWhitespace);
39275      }
39276
39277      this._consumeTagOpenEnd();
39278    } catch (e) {
39279      if (e instanceof _ControlFlowError) {
39280        if (openTagToken) {
39281          // We errored before we could close the opening tag, so it is incomplete.
39282          openTagToken.type = 4
39283          /* TokenType.INCOMPLETE_TAG_OPEN */
39284          ;
39285        } else {
39286          // When the start tag is invalid, assume we want a "<" as text.
39287          // Back to back text tokens are merged at the end.
39288          this._beginToken(5
39289          /* TokenType.TEXT */
39290          , start);
39291
39292          this._endToken(['<']);
39293        }
39294
39295        return;
39296      }
39297
39298      throw e;
39299    }
39300
39301    const contentTokenType = this._getTagDefinition(tagName).getContentType(prefix);
39302
39303    if (contentTokenType === TagContentType.RAW_TEXT) {
39304      this._consumeRawTextWithTagClose(prefix, tagName, false);
39305    } else if (contentTokenType === TagContentType.ESCAPABLE_RAW_TEXT) {
39306      this._consumeRawTextWithTagClose(prefix, tagName, true);
39307    }
39308  }
39309
39310  _consumeRawTextWithTagClose(prefix, tagName, consumeEntities) {
39311    this._consumeRawText(consumeEntities, () => {
39312      if (!this._attemptCharCode($LT)) return false;
39313      if (!this._attemptCharCode($SLASH)) return false;
39314
39315      this._attemptCharCodeUntilFn(isNotWhitespace);
39316
39317      if (!this._attemptStrCaseInsensitive(tagName)) return false;
39318
39319      this._attemptCharCodeUntilFn(isNotWhitespace);
39320
39321      return this._attemptCharCode($GT);
39322    });
39323
39324    this._beginToken(3
39325    /* TokenType.TAG_CLOSE */
39326    );
39327
39328    this._requireCharCodeUntilFn(code => code === $GT, 3);
39329
39330    this._cursor.advance(); // Consume the `>`
39331
39332
39333    this._endToken([prefix, tagName]);
39334  }
39335
39336  _consumeTagOpenStart(start) {
39337    this._beginToken(0
39338    /* TokenType.TAG_OPEN_START */
39339    , start);
39340
39341    const parts = this._consumePrefixAndName();
39342
39343    return this._endToken(parts);
39344  }
39345
39346  _consumeAttributeName() {
39347    const attrNameStart = this._cursor.peek();
39348
39349    if (attrNameStart === $SQ || attrNameStart === $DQ) {
39350      throw this._createError(_unexpectedCharacterErrorMsg(attrNameStart), this._cursor.getSpan());
39351    }
39352
39353    this._beginToken(14
39354    /* TokenType.ATTR_NAME */
39355    );
39356
39357    const prefixAndName = this._consumePrefixAndName();
39358
39359    this._endToken(prefixAndName);
39360  }
39361
39362  _consumeAttributeValue() {
39363    let value;
39364
39365    if (this._cursor.peek() === $SQ || this._cursor.peek() === $DQ) {
39366      const quoteChar = this._cursor.peek();
39367
39368      this._consumeQuote(quoteChar); // In an attribute then end of the attribute value and the premature end to an interpolation
39369      // are both triggered by the `quoteChar`.
39370
39371
39372      const endPredicate = () => this._cursor.peek() === quoteChar;
39373
39374      this._consumeWithInterpolation(16
39375      /* TokenType.ATTR_VALUE_TEXT */
39376      , 17
39377      /* TokenType.ATTR_VALUE_INTERPOLATION */
39378      , endPredicate, endPredicate);
39379
39380      this._consumeQuote(quoteChar);
39381    } else {
39382      const endPredicate = () => isNameEnd(this._cursor.peek());
39383
39384      this._consumeWithInterpolation(16
39385      /* TokenType.ATTR_VALUE_TEXT */
39386      , 17
39387      /* TokenType.ATTR_VALUE_INTERPOLATION */
39388      , endPredicate, endPredicate);
39389    }
39390  }
39391
39392  _consumeQuote(quoteChar) {
39393    this._beginToken(15
39394    /* TokenType.ATTR_QUOTE */
39395    );
39396
39397    this._requireCharCode(quoteChar);
39398
39399    this._endToken([String.fromCodePoint(quoteChar)]);
39400  }
39401
39402  _consumeTagOpenEnd() {
39403    const tokenType = this._attemptCharCode($SLASH) ? 2
39404    /* TokenType.TAG_OPEN_END_VOID */
39405    : 1
39406    /* TokenType.TAG_OPEN_END */
39407    ;
39408
39409    this._beginToken(tokenType);
39410
39411    this._requireCharCode($GT);
39412
39413    this._endToken([]);
39414  }
39415
39416  _consumeTagClose(start) {
39417    this._beginToken(3
39418    /* TokenType.TAG_CLOSE */
39419    , start);
39420
39421    this._attemptCharCodeUntilFn(isNotWhitespace);
39422
39423    const prefixAndName = this._consumePrefixAndName();
39424
39425    this._attemptCharCodeUntilFn(isNotWhitespace);
39426
39427    this._requireCharCode($GT);
39428
39429    this._endToken(prefixAndName);
39430  }
39431
39432  _consumeExpansionFormStart() {
39433    this._beginToken(19
39434    /* TokenType.EXPANSION_FORM_START */
39435    );
39436
39437    this._requireCharCode($LBRACE);
39438
39439    this._endToken([]);
39440
39441    this._expansionCaseStack.push(19
39442    /* TokenType.EXPANSION_FORM_START */
39443    );
39444
39445    this._beginToken(7
39446    /* TokenType.RAW_TEXT */
39447    );
39448
39449    const condition = this._readUntil($COMMA);
39450
39451    const normalizedCondition = this._processCarriageReturns(condition);
39452
39453    if (this._i18nNormalizeLineEndingsInICUs) {
39454      // We explicitly want to normalize line endings for this text.
39455      this._endToken([normalizedCondition]);
39456    } else {
39457      // We are not normalizing line endings.
39458      const conditionToken = this._endToken([condition]);
39459
39460      if (normalizedCondition !== condition) {
39461        this.nonNormalizedIcuExpressions.push(conditionToken);
39462      }
39463    }
39464
39465    this._requireCharCode($COMMA);
39466
39467    this._attemptCharCodeUntilFn(isNotWhitespace);
39468
39469    this._beginToken(7
39470    /* TokenType.RAW_TEXT */
39471    );
39472
39473    const type = this._readUntil($COMMA);
39474
39475    this._endToken([type]);
39476
39477    this._requireCharCode($COMMA);
39478
39479    this._attemptCharCodeUntilFn(isNotWhitespace);
39480  }
39481
39482  _consumeExpansionCaseStart() {
39483    this._beginToken(20
39484    /* TokenType.EXPANSION_CASE_VALUE */
39485    );
39486
39487    const value = this._readUntil($LBRACE).trim();
39488
39489    this._endToken([value]);
39490
39491    this._attemptCharCodeUntilFn(isNotWhitespace);
39492
39493    this._beginToken(21
39494    /* TokenType.EXPANSION_CASE_EXP_START */
39495    );
39496
39497    this._requireCharCode($LBRACE);
39498
39499    this._endToken([]);
39500
39501    this._attemptCharCodeUntilFn(isNotWhitespace);
39502
39503    this._expansionCaseStack.push(21
39504    /* TokenType.EXPANSION_CASE_EXP_START */
39505    );
39506  }
39507
39508  _consumeExpansionCaseEnd() {
39509    this._beginToken(22
39510    /* TokenType.EXPANSION_CASE_EXP_END */
39511    );
39512
39513    this._requireCharCode($RBRACE);
39514
39515    this._endToken([]);
39516
39517    this._attemptCharCodeUntilFn(isNotWhitespace);
39518
39519    this._expansionCaseStack.pop();
39520  }
39521
39522  _consumeExpansionFormEnd() {
39523    this._beginToken(23
39524    /* TokenType.EXPANSION_FORM_END */
39525    );
39526
39527    this._requireCharCode($RBRACE);
39528
39529    this._endToken([]);
39530
39531    this._expansionCaseStack.pop();
39532  }
39533  /**
39534   * Consume a string that may contain interpolation expressions.
39535   *
39536   * The first token consumed will be of `tokenType` and then there will be alternating
39537   * `interpolationTokenType` and `tokenType` tokens until the `endPredicate()` returns true.
39538   *
39539   * If an interpolation token ends prematurely it will have no end marker in its `parts` array.
39540   *
39541   * @param textTokenType the kind of tokens to interleave around interpolation tokens.
39542   * @param interpolationTokenType the kind of tokens that contain interpolation.
39543   * @param endPredicate a function that should return true when we should stop consuming.
39544   * @param endInterpolation a function that should return true if there is a premature end to an
39545   *     interpolation expression - i.e. before we get to the normal interpolation closing marker.
39546   */
39547
39548
39549  _consumeWithInterpolation(textTokenType, interpolationTokenType, endPredicate, endInterpolation) {
39550    this._beginToken(textTokenType);
39551
39552    const parts = [];
39553
39554    while (!endPredicate()) {
39555      const current = this._cursor.clone();
39556
39557      if (this._interpolationConfig && this._attemptStr(this._interpolationConfig.start)) {
39558        this._endToken([this._processCarriageReturns(parts.join(''))], current);
39559
39560        parts.length = 0;
39561
39562        this._consumeInterpolation(interpolationTokenType, current, endInterpolation);
39563
39564        this._beginToken(textTokenType);
39565      } else if (this._cursor.peek() === $AMPERSAND) {
39566        this._endToken([this._processCarriageReturns(parts.join(''))]);
39567
39568        parts.length = 0;
39569
39570        this._consumeEntity(textTokenType);
39571
39572        this._beginToken(textTokenType);
39573      } else {
39574        parts.push(this._readChar());
39575      }
39576    } // It is possible that an interpolation was started but not ended inside this text token.
39577    // Make sure that we reset the state of the lexer correctly.
39578
39579
39580    this._inInterpolation = false;
39581
39582    this._endToken([this._processCarriageReturns(parts.join(''))]);
39583  }
39584  /**
39585   * Consume a block of text that has been interpreted as an Angular interpolation.
39586   *
39587   * @param interpolationTokenType the type of the interpolation token to generate.
39588   * @param interpolationStart a cursor that points to the start of this interpolation.
39589   * @param prematureEndPredicate a function that should return true if the next characters indicate
39590   *     an end to the interpolation before its normal closing marker.
39591   */
39592
39593
39594  _consumeInterpolation(interpolationTokenType, interpolationStart, prematureEndPredicate) {
39595    const parts = [];
39596
39597    this._beginToken(interpolationTokenType, interpolationStart);
39598
39599    parts.push(this._interpolationConfig.start); // Find the end of the interpolation, ignoring content inside quotes.
39600
39601    const expressionStart = this._cursor.clone();
39602
39603    let inQuote = null;
39604    let inComment = false;
39605
39606    while (this._cursor.peek() !== $EOF && (prematureEndPredicate === null || !prematureEndPredicate())) {
39607      const current = this._cursor.clone();
39608
39609      if (this._isTagStart()) {
39610        // We are starting what looks like an HTML element in the middle of this interpolation.
39611        // Reset the cursor to before the `<` character and end the interpolation token.
39612        // (This is actually wrong but here for backward compatibility).
39613        this._cursor = current;
39614        parts.push(this._getProcessedChars(expressionStart, current));
39615
39616        this._endToken(parts);
39617
39618        return;
39619      }
39620
39621      if (inQuote === null) {
39622        if (this._attemptStr(this._interpolationConfig.end)) {
39623          // We are not in a string, and we hit the end interpolation marker
39624          parts.push(this._getProcessedChars(expressionStart, current));
39625          parts.push(this._interpolationConfig.end);
39626
39627          this._endToken(parts);
39628
39629          return;
39630        } else if (this._attemptStr('//')) {
39631          // Once we are in a comment we ignore any quotes
39632          inComment = true;
39633        }
39634      }
39635
39636      const char = this._cursor.peek();
39637
39638      this._cursor.advance();
39639
39640      if (char === $BACKSLASH) {
39641        // Skip the next character because it was escaped.
39642        this._cursor.advance();
39643      } else if (char === inQuote) {
39644        // Exiting the current quoted string
39645        inQuote = null;
39646      } else if (!inComment && inQuote === null && isQuote(char)) {
39647        // Entering a new quoted string
39648        inQuote = char;
39649      }
39650    } // We hit EOF without finding a closing interpolation marker
39651
39652
39653    parts.push(this._getProcessedChars(expressionStart, this._cursor));
39654
39655    this._endToken(parts);
39656  }
39657
39658  _getProcessedChars(start, end) {
39659    return this._processCarriageReturns(end.getChars(start));
39660  }
39661
39662  _isTextEnd() {
39663    if (this._isTagStart() || this._cursor.peek() === $EOF) {
39664      return true;
39665    }
39666
39667    if (this._tokenizeIcu && !this._inInterpolation) {
39668      if (this.isExpansionFormStart()) {
39669        // start of an expansion form
39670        return true;
39671      }
39672
39673      if (this._cursor.peek() === $RBRACE && this._isInExpansionCase()) {
39674        // end of and expansion case
39675        return true;
39676      }
39677    }
39678
39679    return false;
39680  }
39681  /**
39682   * Returns true if the current cursor is pointing to the start of a tag
39683   * (opening/closing/comments/cdata/etc).
39684   */
39685
39686
39687  _isTagStart() {
39688    if (this._cursor.peek() === $LT) {
39689      // We assume that `<` followed by whitespace is not the start of an HTML element.
39690      const tmp = this._cursor.clone();
39691
39692      tmp.advance(); // If the next character is alphabetic, ! nor / then it is a tag start
39693
39694      const code = tmp.peek();
39695
39696      if ($a <= code && code <= $z || $A <= code && code <= $Z || code === $SLASH || code === $BANG) {
39697        return true;
39698      }
39699    }
39700
39701    return false;
39702  }
39703
39704  _readUntil(char) {
39705    const start = this._cursor.clone();
39706
39707    this._attemptUntilChar(char);
39708
39709    return this._cursor.getChars(start);
39710  }
39711
39712  _isInExpansionCase() {
39713    return this._expansionCaseStack.length > 0 && this._expansionCaseStack[this._expansionCaseStack.length - 1] === 21
39714    /* TokenType.EXPANSION_CASE_EXP_START */
39715    ;
39716  }
39717
39718  _isInExpansionForm() {
39719    return this._expansionCaseStack.length > 0 && this._expansionCaseStack[this._expansionCaseStack.length - 1] === 19
39720    /* TokenType.EXPANSION_FORM_START */
39721    ;
39722  }
39723
39724  isExpansionFormStart() {
39725    if (this._cursor.peek() !== $LBRACE) {
39726      return false;
39727    }
39728
39729    if (this._interpolationConfig) {
39730      const start = this._cursor.clone();
39731
39732      const isInterpolation = this._attemptStr(this._interpolationConfig.start);
39733
39734      this._cursor = start;
39735      return !isInterpolation;
39736    }
39737
39738    return true;
39739  }
39740
39741}
39742
39743function isNotWhitespace(code) {
39744  return !isWhitespace(code) || code === $EOF;
39745}
39746
39747function isNameEnd(code) {
39748  return isWhitespace(code) || code === $GT || code === $LT || code === $SLASH || code === $SQ || code === $DQ || code === $EQ || code === $EOF;
39749}
39750
39751function isPrefixEnd(code) {
39752  return (code < $a || $z < code) && (code < $A || $Z < code) && (code < $0 || code > $9);
39753}
39754
39755function isDigitEntityEnd(code) {
39756  return code === $SEMICOLON || code === $EOF || !isAsciiHexDigit(code);
39757}
39758
39759function isNamedEntityEnd(code) {
39760  return code === $SEMICOLON || code === $EOF || !isAsciiLetter(code);
39761}
39762
39763function isExpansionCaseStart(peek) {
39764  return peek !== $RBRACE;
39765}
39766
39767function compareCharCodeCaseInsensitive(code1, code2) {
39768  return toUpperCaseCharCode(code1) === toUpperCaseCharCode(code2);
39769}
39770
39771function toUpperCaseCharCode(code) {
39772  return code >= $a && code <= $z ? code - $a + $A : code;
39773}
39774
39775function mergeTextTokens(srcTokens) {
39776  const dstTokens = [];
39777  let lastDstToken = undefined;
39778
39779  for (let i = 0; i < srcTokens.length; i++) {
39780    const token = srcTokens[i];
39781
39782    if (lastDstToken && lastDstToken.type === 5
39783    /* TokenType.TEXT */
39784    && token.type === 5
39785    /* TokenType.TEXT */
39786    || lastDstToken && lastDstToken.type === 16
39787    /* TokenType.ATTR_VALUE_TEXT */
39788    && token.type === 16
39789    /* TokenType.ATTR_VALUE_TEXT */
39790    ) {
39791      lastDstToken.parts[0] += token.parts[0];
39792      lastDstToken.sourceSpan.end = token.sourceSpan.end;
39793    } else {
39794      lastDstToken = token;
39795      dstTokens.push(lastDstToken);
39796    }
39797  }
39798
39799  return dstTokens;
39800}
39801
39802class PlainCharacterCursor {
39803  constructor(fileOrCursor, range) {
39804    if (fileOrCursor instanceof PlainCharacterCursor) {
39805      this.file = fileOrCursor.file;
39806      this.input = fileOrCursor.input;
39807      this.end = fileOrCursor.end;
39808      const state = fileOrCursor.state; // Note: avoid using `{...fileOrCursor.state}` here as that has a severe performance penalty.
39809      // In ES5 bundles the object spread operator is translated into the `__assign` helper, which
39810      // is not optimized by VMs as efficiently as a raw object literal. Since this constructor is
39811      // called in tight loops, this difference matters.
39812
39813      this.state = {
39814        peek: state.peek,
39815        offset: state.offset,
39816        line: state.line,
39817        column: state.column
39818      };
39819    } else {
39820      if (!range) {
39821        throw new Error('Programming error: the range argument must be provided with a file argument.');
39822      }
39823
39824      this.file = fileOrCursor;
39825      this.input = fileOrCursor.content;
39826      this.end = range.endPos;
39827      this.state = {
39828        peek: -1,
39829        offset: range.startPos,
39830        line: range.startLine,
39831        column: range.startCol
39832      };
39833    }
39834  }
39835
39836  clone() {
39837    return new PlainCharacterCursor(this);
39838  }
39839
39840  peek() {
39841    return this.state.peek;
39842  }
39843
39844  charsLeft() {
39845    return this.end - this.state.offset;
39846  }
39847
39848  diff(other) {
39849    return this.state.offset - other.state.offset;
39850  }
39851
39852  advance() {
39853    this.advanceState(this.state);
39854  }
39855
39856  init() {
39857    this.updatePeek(this.state);
39858  }
39859
39860  getSpan(start, leadingTriviaCodePoints) {
39861    start = start || this;
39862    let fullStart = start;
39863
39864    if (leadingTriviaCodePoints) {
39865      while (this.diff(start) > 0 && leadingTriviaCodePoints.indexOf(start.peek()) !== -1) {
39866        if (fullStart === start) {
39867          start = start.clone();
39868        }
39869
39870        start.advance();
39871      }
39872    }
39873
39874    const startLocation = this.locationFromCursor(start);
39875    const endLocation = this.locationFromCursor(this);
39876    const fullStartLocation = fullStart !== start ? this.locationFromCursor(fullStart) : startLocation;
39877    return new ParseSourceSpan(startLocation, endLocation, fullStartLocation);
39878  }
39879
39880  getChars(start) {
39881    return this.input.substring(start.state.offset, this.state.offset);
39882  }
39883
39884  charAt(pos) {
39885    return this.input.charCodeAt(pos);
39886  }
39887
39888  advanceState(state) {
39889    if (state.offset >= this.end) {
39890      this.state = state;
39891      throw new CursorError('Unexpected character "EOF"', this);
39892    }
39893
39894    const currentChar = this.charAt(state.offset);
39895
39896    if (currentChar === $LF) {
39897      state.line++;
39898      state.column = 0;
39899    } else if (!isNewLine(currentChar)) {
39900      state.column++;
39901    }
39902
39903    state.offset++;
39904    this.updatePeek(state);
39905  }
39906
39907  updatePeek(state) {
39908    state.peek = state.offset >= this.end ? $EOF : this.charAt(state.offset);
39909  }
39910
39911  locationFromCursor(cursor) {
39912    return new ParseLocation(cursor.file, cursor.state.offset, cursor.state.line, cursor.state.column);
39913  }
39914
39915}
39916
39917class EscapedCharacterCursor extends PlainCharacterCursor {
39918  constructor(fileOrCursor, range) {
39919    if (fileOrCursor instanceof EscapedCharacterCursor) {
39920      super(fileOrCursor);
39921      this.internalState = { ...fileOrCursor.internalState
39922      };
39923    } else {
39924      super(fileOrCursor, range);
39925      this.internalState = this.state;
39926    }
39927  }
39928
39929  advance() {
39930    this.state = this.internalState;
39931    super.advance();
39932    this.processEscapeSequence();
39933  }
39934
39935  init() {
39936    super.init();
39937    this.processEscapeSequence();
39938  }
39939
39940  clone() {
39941    return new EscapedCharacterCursor(this);
39942  }
39943
39944  getChars(start) {
39945    const cursor = start.clone();
39946    let chars = '';
39947
39948    while (cursor.internalState.offset < this.internalState.offset) {
39949      chars += String.fromCodePoint(cursor.peek());
39950      cursor.advance();
39951    }
39952
39953    return chars;
39954  }
39955  /**
39956   * Process the escape sequence that starts at the current position in the text.
39957   *
39958   * This method is called to ensure that `peek` has the unescaped value of escape sequences.
39959   */
39960
39961
39962  processEscapeSequence() {
39963    const peek = () => this.internalState.peek;
39964
39965    if (peek() === $BACKSLASH) {
39966      // We have hit an escape sequence so we need the internal state to become independent
39967      // of the external state.
39968      this.internalState = { ...this.state
39969      }; // Move past the backslash
39970
39971      this.advanceState(this.internalState); // First check for standard control char sequences
39972
39973      if (peek() === $n) {
39974        this.state.peek = $LF;
39975      } else if (peek() === $r) {
39976        this.state.peek = $CR;
39977      } else if (peek() === $v) {
39978        this.state.peek = $VTAB;
39979      } else if (peek() === $t) {
39980        this.state.peek = $TAB;
39981      } else if (peek() === $b) {
39982        this.state.peek = $BSPACE;
39983      } else if (peek() === $f) {
39984        this.state.peek = $FF;
39985      } // Now consider more complex sequences
39986      else if (peek() === $u) {
39987        // Unicode code-point sequence
39988        this.advanceState(this.internalState); // advance past the `u` char
39989
39990        if (peek() === $LBRACE) {
39991          // Variable length Unicode, e.g. `\x{123}`
39992          this.advanceState(this.internalState); // advance past the `{` char
39993          // Advance past the variable number of hex digits until we hit a `}` char
39994
39995          const digitStart = this.clone();
39996          let length = 0;
39997
39998          while (peek() !== $RBRACE) {
39999            this.advanceState(this.internalState);
40000            length++;
40001          }
40002
40003          this.state.peek = this.decodeHexDigits(digitStart, length);
40004        } else {
40005          // Fixed length Unicode, e.g. `\u1234`
40006          const digitStart = this.clone();
40007          this.advanceState(this.internalState);
40008          this.advanceState(this.internalState);
40009          this.advanceState(this.internalState);
40010          this.state.peek = this.decodeHexDigits(digitStart, 4);
40011        }
40012      } else if (peek() === $x) {
40013        // Hex char code, e.g. `\x2F`
40014        this.advanceState(this.internalState); // advance past the `x` char
40015
40016        const digitStart = this.clone();
40017        this.advanceState(this.internalState);
40018        this.state.peek = this.decodeHexDigits(digitStart, 2);
40019      } else if (isOctalDigit(peek())) {
40020        // Octal char code, e.g. `\012`,
40021        let octal = '';
40022        let length = 0;
40023        let previous = this.clone();
40024
40025        while (isOctalDigit(peek()) && length < 3) {
40026          previous = this.clone();
40027          octal += String.fromCodePoint(peek());
40028          this.advanceState(this.internalState);
40029          length++;
40030        }
40031
40032        this.state.peek = parseInt(octal, 8); // Backup one char
40033
40034        this.internalState = previous.internalState;
40035      } else if (isNewLine(this.internalState.peek)) {
40036        // Line continuation `\` followed by a new line
40037        this.advanceState(this.internalState); // advance over the newline
40038
40039        this.state = this.internalState;
40040      } else {
40041        // If none of the `if` blocks were executed then we just have an escaped normal character.
40042        // In that case we just, effectively, skip the backslash from the character.
40043        this.state.peek = this.internalState.peek;
40044      }
40045    }
40046  }
40047
40048  decodeHexDigits(start, length) {
40049    const hex = this.input.slice(start.internalState.offset, start.internalState.offset + length);
40050    const charCode = parseInt(hex, 16);
40051
40052    if (!isNaN(charCode)) {
40053      return charCode;
40054    } else {
40055      start.state = start.internalState;
40056      throw new CursorError('Invalid hexadecimal escape sequence', start);
40057    }
40058  }
40059
40060}
40061
40062class CursorError {
40063  constructor(msg, cursor) {
40064    this.msg = msg;
40065    this.cursor = cursor;
40066  }
40067
40068}
40069/**
40070 * @license
40071 * Copyright Google LLC All Rights Reserved.
40072 *
40073 * Use of this source code is governed by an MIT-style license that can be
40074 * found in the LICENSE file at https://angular.io/license
40075 */
40076
40077
40078class TreeError extends ParseError {
40079  constructor(elementName, span, msg) {
40080    super(span, msg);
40081    this.elementName = elementName;
40082  }
40083
40084  static create(elementName, span, msg) {
40085    return new TreeError(elementName, span, msg);
40086  }
40087
40088}
40089
40090class ParseTreeResult {
40091  constructor(rootNodes, errors) {
40092    this.rootNodes = rootNodes;
40093    this.errors = errors;
40094  }
40095
40096}
40097
40098class Parser {
40099  constructor(getTagDefinition) {
40100    this.getTagDefinition = getTagDefinition;
40101  }
40102
40103  parse(source, url, options) {
40104    const tokenizeResult = tokenize(source, url, this.getTagDefinition, options);
40105    const parser = new _TreeBuilder(tokenizeResult.tokens, this.getTagDefinition);
40106    parser.build();
40107    return new ParseTreeResult(parser.rootNodes, tokenizeResult.errors.concat(parser.errors));
40108  }
40109
40110}
40111
40112class _TreeBuilder {
40113  constructor(tokens, getTagDefinition) {
40114    this.tokens = tokens;
40115    this.getTagDefinition = getTagDefinition;
40116    this._index = -1;
40117    this._elementStack = [];
40118    this.rootNodes = [];
40119    this.errors = [];
40120
40121    this._advance();
40122  }
40123
40124  build() {
40125    while (this._peek.type !== 24
40126    /* TokenType.EOF */
40127    ) {
40128      if (this._peek.type === 0
40129      /* TokenType.TAG_OPEN_START */
40130      || this._peek.type === 4
40131      /* TokenType.INCOMPLETE_TAG_OPEN */
40132      ) {
40133        this._consumeStartTag(this._advance());
40134      } else if (this._peek.type === 3
40135      /* TokenType.TAG_CLOSE */
40136      ) {
40137        this._consumeEndTag(this._advance());
40138      } else if (this._peek.type === 12
40139      /* TokenType.CDATA_START */
40140      ) {
40141        this._closeVoidElement();
40142
40143        this._consumeCdata(this._advance());
40144      } else if (this._peek.type === 10
40145      /* TokenType.COMMENT_START */
40146      ) {
40147        this._closeVoidElement();
40148
40149        this._consumeComment(this._advance());
40150      } else if (this._peek.type === 5
40151      /* TokenType.TEXT */
40152      || this._peek.type === 7
40153      /* TokenType.RAW_TEXT */
40154      || this._peek.type === 6
40155      /* TokenType.ESCAPABLE_RAW_TEXT */
40156      ) {
40157        this._closeVoidElement();
40158
40159        this._consumeText(this._advance());
40160      } else if (this._peek.type === 19
40161      /* TokenType.EXPANSION_FORM_START */
40162      ) {
40163        this._consumeExpansion(this._advance());
40164      } else {
40165        // Skip all other tokens...
40166        this._advance();
40167      }
40168    }
40169  }
40170
40171  _advance() {
40172    const prev = this._peek;
40173
40174    if (this._index < this.tokens.length - 1) {
40175      // Note: there is always an EOF token at the end
40176      this._index++;
40177    }
40178
40179    this._peek = this.tokens[this._index];
40180    return prev;
40181  }
40182
40183  _advanceIf(type) {
40184    if (this._peek.type === type) {
40185      return this._advance();
40186    }
40187
40188    return null;
40189  }
40190
40191  _consumeCdata(_startToken) {
40192    this._consumeText(this._advance());
40193
40194    this._advanceIf(13
40195    /* TokenType.CDATA_END */
40196    );
40197  }
40198
40199  _consumeComment(token) {
40200    const text = this._advanceIf(7
40201    /* TokenType.RAW_TEXT */
40202    );
40203
40204    this._advanceIf(11
40205    /* TokenType.COMMENT_END */
40206    );
40207
40208    const value = text != null ? text.parts[0].trim() : null;
40209
40210    this._addToParent(new Comment(value, token.sourceSpan));
40211  }
40212
40213  _consumeExpansion(token) {
40214    const switchValue = this._advance();
40215
40216    const type = this._advance();
40217
40218    const cases = []; // read =
40219
40220    while (this._peek.type === 20
40221    /* TokenType.EXPANSION_CASE_VALUE */
40222    ) {
40223      const expCase = this._parseExpansionCase();
40224
40225      if (!expCase) return; // error
40226
40227      cases.push(expCase);
40228    } // read the final }
40229
40230
40231    if (this._peek.type !== 23
40232    /* TokenType.EXPANSION_FORM_END */
40233    ) {
40234      this.errors.push(TreeError.create(null, this._peek.sourceSpan, `Invalid ICU message. Missing '}'.`));
40235      return;
40236    }
40237
40238    const sourceSpan = new ParseSourceSpan(token.sourceSpan.start, this._peek.sourceSpan.end, token.sourceSpan.fullStart);
40239
40240    this._addToParent(new Expansion(switchValue.parts[0], type.parts[0], cases, sourceSpan, switchValue.sourceSpan));
40241
40242    this._advance();
40243  }
40244
40245  _parseExpansionCase() {
40246    const value = this._advance(); // read {
40247
40248
40249    if (this._peek.type !== 21
40250    /* TokenType.EXPANSION_CASE_EXP_START */
40251    ) {
40252      this.errors.push(TreeError.create(null, this._peek.sourceSpan, `Invalid ICU message. Missing '{'.`));
40253      return null;
40254    } // read until }
40255
40256
40257    const start = this._advance();
40258
40259    const exp = this._collectExpansionExpTokens(start);
40260
40261    if (!exp) return null;
40262
40263    const end = this._advance();
40264
40265    exp.push({
40266      type: 24
40267      /* TokenType.EOF */
40268      ,
40269      parts: [],
40270      sourceSpan: end.sourceSpan
40271    }); // parse everything in between { and }
40272
40273    const expansionCaseParser = new _TreeBuilder(exp, this.getTagDefinition);
40274    expansionCaseParser.build();
40275
40276    if (expansionCaseParser.errors.length > 0) {
40277      this.errors = this.errors.concat(expansionCaseParser.errors);
40278      return null;
40279    }
40280
40281    const sourceSpan = new ParseSourceSpan(value.sourceSpan.start, end.sourceSpan.end, value.sourceSpan.fullStart);
40282    const expSourceSpan = new ParseSourceSpan(start.sourceSpan.start, end.sourceSpan.end, start.sourceSpan.fullStart);
40283    return new ExpansionCase(value.parts[0], expansionCaseParser.rootNodes, sourceSpan, value.sourceSpan, expSourceSpan);
40284  }
40285
40286  _collectExpansionExpTokens(start) {
40287    const exp = [];
40288    const expansionFormStack = [21
40289    /* TokenType.EXPANSION_CASE_EXP_START */
40290    ];
40291
40292    while (true) {
40293      if (this._peek.type === 19
40294      /* TokenType.EXPANSION_FORM_START */
40295      || this._peek.type === 21
40296      /* TokenType.EXPANSION_CASE_EXP_START */
40297      ) {
40298        expansionFormStack.push(this._peek.type);
40299      }
40300
40301      if (this._peek.type === 22
40302      /* TokenType.EXPANSION_CASE_EXP_END */
40303      ) {
40304        if (lastOnStack(expansionFormStack, 21
40305        /* TokenType.EXPANSION_CASE_EXP_START */
40306        )) {
40307          expansionFormStack.pop();
40308          if (expansionFormStack.length === 0) return exp;
40309        } else {
40310          this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
40311          return null;
40312        }
40313      }
40314
40315      if (this._peek.type === 23
40316      /* TokenType.EXPANSION_FORM_END */
40317      ) {
40318        if (lastOnStack(expansionFormStack, 19
40319        /* TokenType.EXPANSION_FORM_START */
40320        )) {
40321          expansionFormStack.pop();
40322        } else {
40323          this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
40324          return null;
40325        }
40326      }
40327
40328      if (this._peek.type === 24
40329      /* TokenType.EOF */
40330      ) {
40331        this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
40332        return null;
40333      }
40334
40335      exp.push(this._advance());
40336    }
40337  }
40338
40339  _consumeText(token) {
40340    const tokens = [token];
40341    const startSpan = token.sourceSpan;
40342    let text = token.parts[0];
40343
40344    if (text.length > 0 && text[0] === '\n') {
40345      const parent = this._getParentElement();
40346
40347      if (parent != null && parent.children.length === 0 && this.getTagDefinition(parent.name).ignoreFirstLf) {
40348        text = text.substring(1);
40349        tokens[0] = {
40350          type: token.type,
40351          sourceSpan: token.sourceSpan,
40352          parts: [text]
40353        };
40354      }
40355    }
40356
40357    while (this._peek.type === 8
40358    /* TokenType.INTERPOLATION */
40359    || this._peek.type === 5
40360    /* TokenType.TEXT */
40361    || this._peek.type === 9
40362    /* TokenType.ENCODED_ENTITY */
40363    ) {
40364      token = this._advance();
40365      tokens.push(token);
40366
40367      if (token.type === 8
40368      /* TokenType.INTERPOLATION */
40369      ) {
40370        // For backward compatibility we decode HTML entities that appear in interpolation
40371        // expressions. This is arguably a bug, but it could be a considerable breaking change to
40372        // fix it. It should be addressed in a larger project to refactor the entire parser/lexer
40373        // chain after View Engine has been removed.
40374        text += token.parts.join('').replace(/&([^;]+);/g, decodeEntity);
40375      } else if (token.type === 9
40376      /* TokenType.ENCODED_ENTITY */
40377      ) {
40378        text += token.parts[0];
40379      } else {
40380        text += token.parts.join('');
40381      }
40382    }
40383
40384    if (text.length > 0) {
40385      const endSpan = token.sourceSpan;
40386
40387      this._addToParent(new Text(text, new ParseSourceSpan(start
40387Span.start, endSpan.end, startSpan.fullStart, startSpan.details), tokens));
40388    }
40389  }
40390
40391  _closeVoidElement() {
40392    const el = this._getParentElement();
40393
40394    if (el && this.getTagDefinition(el.name).isVoid) {
40395      this._elementStack.pop();
40396    }
40397  }
40398
40399  _consumeStartTag(startTagToken) {
40400    const [prefix, name] = startTagToken.parts;
40401    const attrs = [];
40402
40403    while (this._peek.type === 14
40404    /* TokenType.ATTR_NAME */
40405    ) {
40406      attrs.push(this._consumeAttr(this._advance()));
40407    }
40408
40409    const fullName = this._getElementFullName(prefix, name, this._getParentElement());
40410
40411    let selfClosing = false; // Note: There could have been a tokenizer error
40412    // so that we don't get a token for the end tag...
40413
40414    if (this._peek.type === 2
40415    /* TokenType.TAG_OPEN_END_VOID */
40416    ) {
40417      this._advance();
40418
40419      selfClosing = true;
40420      const tagDef = this.getTagDefinition(fullName);
40421
40422      if (!(tagDef.canSelfClose || getNsPrefix(fullName) !== null || tagDef.isVoid)) {
40423        this.errors.push(TreeError.create(fullName, startTagToken.sourceSpan, `Only void and foreign elements can be self closed "${startTagToken.parts[1]}"`));
40424      }
40425    } else if (this._peek.type === 1
40426    /* TokenType.TAG_OPEN_END */
40427    ) {
40428      this._advance();
40429
40430      selfClosing = false;
40431    }
40432
40433    const end = this._peek.sourceSpan.fullStart;
40434    const span = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart); // Create a separate `startSpan` because `span` will be modified when there is an `end` span.
40435
40436    const startSpan = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
40437    const el = new Element(fullName, attrs, [], span, startSpan, undefined);
40438
40439    this._pushElement(el);
40440
40441    if (selfClosing) {
40442      // Elements that are self-closed have their `endSourceSpan` set to the full span, as the
40443      // element start tag also represents the end tag.
40444      this._popElement(fullName, span);
40445    } else if (startTagToken.type === 4
40446    /* TokenType.INCOMPLETE_TAG_OPEN */
40447    ) {
40448      // We already know the opening tag is not complete, so it is unlikely it has a corresponding
40449      // close tag. Let's optimistically parse it as a full element and emit an error.
40450      this._popElement(fullName, null);
40451
40452      this.errors.push(TreeError.create(fullName, span, `Opening tag "${fullName}" not terminated.`));
40453    }
40454  }
40455
40456  _pushElement(el) {
40457    const parentEl = this._getParentElement();
40458
40459    if (parentEl && this.getTagDefinition(parentEl.name).isClosedByChild(el.name)) {
40460      this._elementStack.pop();
40461    }
40462
40463    this._addToParent(el);
40464
40465    this._elementStack.push(el);
40466  }
40467
40468  _consumeEndTag(endTagToken) {
40469    const fullName = this._getElementFullName(endTagToken.parts[0], endTagToken.parts[1], this._getParentElement());
40470
40471    if (this.getTagDefinition(fullName).isVoid) {
40472      this.errors.push(TreeError.create(fullName, endTagToken.sourceSpan, `Void elements do not have end tags "${endTagToken.parts[1]}"`));
40473    } else if (!this._popElement(fullName, endTagToken.sourceSpan)) {
40474      const errMsg = `Unexpected closing tag "${fullName}". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags`;
40475      this.errors.push(TreeError.create(fullName, endTagToken.sourceSpan, errMsg));
40476    }
40477  }
40478  /**
40479   * Closes the nearest element with the tag name `fullName` in the parse tree.
40480   * `endSourceSpan` is the span of the closing tag, or null if the element does
40481   * not have a closing tag (for example, this happens when an incomplete
40482   * opening tag is recovered).
40483   */
40484
40485
40486  _popElement(fullName, endSourceSpan) {
40487    let unexpectedCloseTagDetected = false;
40488
40489    for (let stackIndex = this._elementStack.length - 1; stackIndex >= 0; stackIndex--) {
40490      const el = this._elementStack[stackIndex];
40491
40492      if (el.name === fullName) {
40493        // Record the parse span with the element that is being closed. Any elements that are
40494        // removed from the element stack at this point are closed implicitly, so they won't get
40495        // an end source span (as there is no explicit closing element).
40496        el.endSourceSpan = endSourceSpan;
40497        el.sourceSpan.end = endSourceSpan !== null ? endSourceSpan.end : el.sourceSpan.end;
40498
40499        this._elementStack.splice(stackIndex, this._elementStack.length - stackIndex);
40500
40501        return !unexpectedCloseTagDetected;
40502      }
40503
40504      if (!this.getTagDefinition(el.name).closedByParent) {
40505        // Note that we encountered an unexpected close tag but continue processing the element
40506        // stack so we can assign an `endSourceSpan` if there is a corresponding start tag for this
40507        // end tag in the stack.
40508        unexpectedCloseTagDetected = true;
40509      }
40510    }
40511
40512    return false;
40513  }
40514
40515  _consumeAttr(attrName) {
40516    const fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]);
40517    let attrEnd = attrName.sourceSpan.end; // Consume any quote
40518
40519    if (this._peek.type === 15
40520    /* TokenType.ATTR_QUOTE */
40521    ) {
40522      this._advance();
40523    } // Consume the attribute value
40524
40525
40526    let value = '';
40527    const valueTokens = [];
40528    let valueStartSpan = undefined;
40529    let valueEnd = undefined; // NOTE: We need to use a new variable `nextTokenType` here to hide the actual type of
40530    // `_peek.type` from TS. Otherwise TS will narrow the type of `_peek.type` preventing it from
40531    // being able to consider `ATTR_VALUE_INTERPOLATION` as an option. This is because TS is not
40532    // able to see that `_advance()` will actually mutate `_peek`.
40533
40534    const nextTokenType = this._peek.type;
40535
40536    if (nextTokenType === 16
40537    /* TokenType.ATTR_VALUE_TEXT */
40538    ) {
40539      valueStartSpan = this._peek.sourceSpan;
40540      valueEnd = this._peek.sourceSpan.end;
40541
40542      while (this._peek.type === 16
40543      /* TokenType.ATTR_VALUE_TEXT */
40544      || this._peek.type === 17
40545      /* TokenType.ATTR_VALUE_INTERPOLATION */
40546      || this._peek.type === 9
40547      /* TokenType.ENCODED_ENTITY */
40548      ) {
40549        const valueToken = this._advance();
40550
40551        valueTokens.push(valueToken);
40552
40553        if (valueToken.type === 17
40554        /* TokenType.ATTR_VALUE_INTERPOLATION */
40555        ) {
40556          // For backward compatibility we decode HTML entities that appear in interpolation
40557          // expressions. This is arguably a bug, but it could be a considerable breaking change to
40558          // fix it. It should be addressed in a larger project to refactor the entire parser/lexer
40559          // chain after View Engine has been removed.
40560          value += valueToken.parts.join('').replace(/&([^;]+);/g, decodeEntity);
40561        } else if (valueToken.type === 9
40562        /* TokenType.ENCODED_ENTITY */
40563        ) {
40564          value += valueToken.parts[0];
40565        } else {
40566          value += valueToken.parts.join('');
40567        }
40568
40569        valueEnd = attrEnd = valueToken.sourceSpan.end;
40570      }
40571    } // Consume any quote
40572
40573
40574    if (this._peek.type === 15
40575    /* TokenType.ATTR_QUOTE */
40576    ) {
40577      const quoteToken = this._advance();
40578
40579      attrEnd = quoteToken.sourceSpan.end;
40580    }
40581
40582    const valueSpan = valueStartSpan && valueEnd && new ParseSourceSpan(valueStartSpan.start, valueEnd, valueStartSpan.fullStart);
40583    return new Attribute(fullName, value, new ParseSourceSpan(attrName.sourceSpan.start, attrEnd, attrName.sourceSpan.fullStart), attrName.sourceSpan, valueSpan, valueTokens.length > 0 ? valueTokens : undefined, undefined);
40584  }
40585
40586  _getParentElement() {
40587    return this._elementStack.length > 0 ? this._elementStack[this._elementStack.length - 1] : null;
40588  }
40589
40590  _addToParent(node) {
40591    const parent = this._getParentElement();
40592
40593    if (parent != null) {
40594      parent.children.push(node);
40595    } else {
40596      this.rootNodes.push(node);
40597    }
40598  }
40599
40600  _getElementFullName(prefix, localName, parentElement) {
40601    if (prefix === '') {
40602      prefix = this.getTagDefinition(localName).implicitNamespacePrefix || '';
40603
40604      if (prefix === '' && parentElement != null) {
40605        const parentTagName = splitNsName(parentElement.name)[1];
40606        const parentTagDefinition = this.getTagDefinition(parentTagName);
40607
40608        if (!parentTagDefinition.preventNamespaceInheritance) {
40609          prefix = getNsPrefix(parentElement.name);
40610        }
40611      }
40612    }
40613
40614    return mergeNsAndName(prefix, localName);
40615  }
40616
40617}
40618
40619function lastOnStack(stack, element) {
40620  return stack.length > 0 && stack[stack.length - 1] === element;
40621}
40622/**
40623 * Decode the `entity` string, which we believe is the contents of an HTML entity.
40624 *
40625 * If the string is not actually a valid/known entity then just return the original `match` string.
40626 */
40627
40628
40629function decodeEntity(match, entity) {
40630  if (NAMED_ENTITIES[entity] !== undefined) {
40631    return NAMED_ENTITIES[entity] || match;
40632  }
40633
40634  if (/^#x[a-f0-9]+$/i.test(entity)) {
40635    return String.fromCodePoint(parseInt(entity.slice(2), 16));
40636  }
40637
40638  if (/^#\d+$/.test(entity)) {
40639    return String.fromCodePoint(parseInt(entity.slice(1), 10));
40640  }
40641
40642  return match;
40643}
40644/**
40645 * @license
40646 * Copyright Google LLC All Rights Reserved.
40647 *
40648 * Use of this source code is governed by an MIT-style license that can be
40649 * found in the LICENSE file at https://angular.io/license
40650 */
40651
40652
40653class HtmlParser extends Parser {
40654  constructor() {
40655    super(getHtmlTagDefinition);
40656  }
40657
40658  parse(source, url, options) {
40659    return super.parse(source, url, options);
40660  }
40661
40662}
40663/**
40664 * @license
40665 * Copyright Google LLC All Rights Reserved.
40666 *
40667 * Use of this source code is governed by an MIT-style license that can be
40668 * found in the LICENSE file at https://angular.io/license
40669 */
40670
40671
40672const PRESERVE_WS_ATTR_NAME = 'ngPreserveWhitespaces';
40673const SKIP_WS_TRIM_TAGS = new Set(['pre', 'template', 'textarea', 'script', 'style']); // Equivalent to \s with \u00a0 (non-breaking space) excluded.
40674// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
40675
40676const WS_CHARS = ' \f\n\r\t\v\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff';
40677const NO_WS_REGEXP = new RegExp(`[^${WS_CHARS}]`);
40678const WS_REPLACE_REGEXP = new RegExp(`[${WS_CHARS}]{2,}`, 'g');
40679
40680function hasPreserveWhitespacesAttr(attrs) {
40681  return attrs.some(attr => attr.name === PRESERVE_WS_ATTR_NAME);
40682}
40683/**
40684 * Angular Dart introduced &ngsp; as a placeholder for non-removable space, see:
40685 * https://github.com/dart-lang/angular/blob/0bb611387d29d65b5af7f9d2515ab571fd3fbee4/_tests/test/compiler/preserve_whitespace_test.dart#L25-L32
40686 * In Angular Dart &ngsp; is converted to the 0xE500 PUA (Private Use Areas) unicode character
40687 * and later on replaced by a space. We are re-implementing the same idea here.
40688 */
40689
40690
40691function replaceNgsp(value) {
40692  // lexer is replacing the &ngsp; pseudo-entity with NGSP_UNICODE
40693  return value.replace(new RegExp(NGSP_UNICODE, 'g'), ' ');
40694}
40695/**
40696 * This visitor can walk HTML parse tree and remove / trim text nodes using the following rules:
40697 * - consider spaces, tabs and new lines as whitespace characters;
40698 * - drop text nodes consisting of whitespace characters only;
40699 * - for all other text nodes replace consecutive whitespace characters with one space;
40700 * - convert &ngsp; pseudo-entity to a single space;
40701 *
40702 * Removal and trimming of whitespaces have positive performance impact (less code to generate
40703 * while compiling templates, faster view creation). At the same time it can be "destructive"
40704 * in some cases (whitespaces can influence layout). Because of the potential of breaking layout
40705 * this visitor is not activated by default in Angular 5 and people need to explicitly opt-in for
40706 * whitespace removal. The default option for whitespace removal will be revisited in Angular 6
40707 * and might be changed to "on" by default.
40708 */
40709
40710
40711class WhitespaceVisitor {
40712  visitElement(element, context) {
40713    if (SKIP_WS_TRIM_TAGS.has(element.name) || hasPreserveWhitespacesAttr(element.attrs)) {
40714      // don't descent into elements where we need to preserve whitespaces
40715      // but still visit all attributes to eliminate one used as a market to preserve WS
40716      return new Element(element.name, visitAll(this, element.attrs), element.children, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
40717    }
40718
40719    return new Element(element.name, element.attrs, visitAllWithSiblings(this, element.children), element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
40720  }
40721
40722  visitAttribute(attribute, context) {
40723    return attribute.name !== PRESERVE_WS_ATTR_NAME ? attribute : null;
40724  }
40725
40726  visitText(text, context) {
40727    const isNotBlank = text.value.match(NO_WS_REGEXP);
40728    const hasExpansionSibling = context && (context.prev instanceof Expansion || context.next instanceof Expansion);
40729
40730    if (isNotBlank || hasExpansionSibling) {
40731      // Process the whitespace in the tokens of this Text node
40732      const tokens = text.tokens.map(token => token.type === 5
40733      /* TokenType.TEXT */
40734      ? createWhitespaceProcessedTextToken(token) : token); // Process the whitespace of the value of this Text node
40735
40736      const value = processWhitespace(text.value);
40737      return new Text(value, text.sourceSpan, tokens, text.i18n);
40738    }
40739
40740    return null;
40741  }
40742
40743  visitComment(comment, context) {
40744    return comment;
40745  }
40746
40747  visitExpansion(expansion, context) {
40748    return expansion;
40749  }
40750
40751  visitExpansionCase(expansionCase, context) {
40752    return expansionCase;
40753  }
40754
40755}
40756
40757function createWhitespaceProcessedTextToken({
40758  type,
40759  parts,
40760  sourceSpan
40761}) {
40762  return {
40763    type,
40764    parts: [processWhitespace(parts[0])],
40765    sourceSpan
40766  };
40767}
40768
40769function processWhitespace(text) {
40770  return replaceNgsp(text).replace(WS_REPLACE_REGEXP, ' ');
40771}
40772
40773function removeWhitespaces(htmlAstWithErrors) {
40774  return new ParseTreeResult(visitAll(new WhitespaceVisitor(), htmlAstWithErrors.rootNodes), htmlAstWithErrors.errors);
40775}
40776
40777function visitAllWithSiblings(visitor, nodes) {
40778  const result = [];
40779  nodes.forEach((ast, i) => {
40780    const context = {
40781      prev: nodes[i - 1],
40782      next: nodes[i + 1]
40783    };
40784    const astResult = ast.visit(visitor, context);
40785
40786    if (astResult) {
40787      result.push(astResult);
40788    }
40789  });
40790  return result;
40791}
40792/**
40793 * @license
40794 * Copyright Google LLC All Rights Reserved.
40795 *
40796 * Use of this source code is governed by an MIT-style license that can be
40797 * found in the LICENSE file at https://angular.io/license
40798 */
40799
40800
40801function mapEntry(key, value) {
40802  return {
40803    key,
40804    value,
40805    quoted: false
40806  };
40807}
40808
40809function mapLiteral(obj, quoted = false) {
40810  return literalMap(Object.keys(obj).map(key => ({
40811    key,
40812    quoted,
40813    value: obj[key]
40814  })));
40815}
40816/**
40817 * @license
40818 * Copyright Google LLC All Rights Reserved.
40819 *
40820 * Use of this source code is governed by an MIT-style license that can be
40821 * found in the LICENSE file at https://angular.io/license
40822 */
40823// =================================================================================================
40824// =================================================================================================
40825// =========== S T O P   -  S T O P   -  S T O P   -  S T O P   -  S T O P   -  S T O P  ===========
40826// =================================================================================================
40827// =================================================================================================
40828//
40829//        DO NOT EDIT THIS LIST OF SECURITY SENSITIVE PROPERTIES WITHOUT A SECURITY REVIEW!
40830//                               Reach out to mprobst for details.
40831//
40832// =================================================================================================
40833
40834/** Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'. */
40835
40836
40837let _SECURITY_SCHEMA;
40838
40839function SECURITY_SCHEMA() {
40840  if (!_SECURITY_SCHEMA) {
40841    _SECURITY_SCHEMA = {}; // Case is insignificant below, all element and attribute names are lower-cased for lookup.
40842
40843    registerContext(SecurityContext.HTML, ['iframe|srcdoc', '*|innerHTML', '*|outerHTML']);
40844    registerContext(SecurityContext.STYLE, ['*|style']); // NB: no SCRIPT contexts here, they are never allowed due to the parser stripping them.
40845
40846    registerContext(SecurityContext.URL, ['*|formAction', 'area|href', 'area|ping', 'audio|src', 'a|href', 'a|ping', 'blockquote|cite', 'body|background', 'del|cite', 'form|action', 'img|src', 'input|src', 'ins|cite', 'q|cite', 'source|src', 'track|src', 'video|poster', 'video|src']);
40847    registerContext(SecurityContext.RESOURCE_URL, ['applet|code', 'applet|codebase', 'base|href', 'embed|src', 'frame|src', 'head|profile', 'html|manifest', 'iframe|src', 'link|href', 'media|src', 'object|codebase', 'object|data', 'script|src']);
40848  }
40849
40850  return _SECURITY_SCHEMA;
40851}
40852
40853function registerContext(ctx, specs) {
40854  for (const spec of specs) _SECURITY_SCHEMA[spec.toLowerCase()] = ctx;
40855}
40856/**
40857 * @license
40858 * Copyright Google LLC All Rights Reserved.
40859 *
40860 * Use of this source code is governed by an MIT-style license that can be
40861 * found in the LICENSE file at https://angular.io/license
40862 */
40863
40864
40865class ElementSchemaRegistry {}
40866/**
40867 * @license
40868 * Copyright Google LLC All Rights Reserved.
40869 *
40870 * Use of this source code is governed by an MIT-style license that can be
40871 * found in the LICENSE file at https://angular.io/license
40872 */
40873
40874
40875const EVENT = 'event';
40876const BOOLEAN = 'boolean';
40877const NUMBER = 'number';
40878const STRING = 'string';
40879const OBJECT = 'object';
40880/**
40881 * This array represents the DOM schema. It encodes inheritance, properties, and events.
40882 *
40883 * ## Overview
40884 *
40885 * Each line represents one kind of element. The `element_inheritance` and properties are joined
40886 * using `element_inheritance|properties` syntax.
40887 *
40888 * ## Element Inheritance
40889 *
40890 * The `element_inheritance` can be further subdivided as `element1,element2,...^parentElement`.
40891 * Here the individual elements are separated by `,` (commas). Every element in the list
40892 * has identical properties.
40893 *
40894 * An `element` may inherit additional properties from `parentElement` If no `^parentElement` is
40895 * specified then `""` (blank) element is assumed.
40896 *
40897 * NOTE: The blank element inherits from root `[Element]` element, the super element of all
40898 * elements.
40899 *
40900 * NOTE an element prefix such as `:svg:` has no special meaning to the schema.
40901 *
40902 * ## Properties
40903 *
40904 * Each element has a set of properties separated by `,` (commas). Each property can be prefixed
40905 * by a special character designating its type:
40906 *
40907 * - (no prefix): property is a string.
40908 * - `*`: property represents an event.
40909 * - `!`: property is a boolean.
40910 * - `#`: property is a number.
40911 * - `%`: property is an object.
40912 *
40913 * ## Query
40914 *
40915 * The class creates an internal squas representation which allows to easily answer the query of
40916 * if a given property exist on a given element.
40917 *
40918 * NOTE: We don't yet support querying for types or events.
40919 * NOTE: This schema is auto extracted from `schema_extractor.ts` located in the test folder,
40920 *       see dom_element_schema_registry_spec.ts
40921 */
40922// =================================================================================================
40923// =================================================================================================
40924// =========== S T O P   -  S T O P   -  S T O P   -  S T O P   -  S T O P   -  S T O P  ===========
40925// =================================================================================================
40926// =================================================================================================
40927//
40928//                       DO NOT EDIT THIS DOM SCHEMA WITHOUT A SECURITY REVIEW!
40929//
40930// Newly added properties must be security reviewed and assigned an appropriate SecurityContext in
40931// dom_security_schema.ts. Reach out to mprobst & rjamet for details.
40932//
40933// =================================================================================================
40934
40935const SCHEMA = ['[Element]|textContent,%classList,className,id,innerHTML,*beforecopy,*beforecut,*beforepaste,*copy,*cut,*paste,*search,*selectstart,*webkitfullscreenchange,*webkitfullscreenerror,*w
40935heel,outerHTML,#scrollLeft,#scrollTop,slot' +
40936/* added manually to avoid breaking changes */
40937',*message,*mozfullscreenchange,*mozfullscreenerror,*mozpointerlockchange,*mozpointerlockerror,*webglcontextcreationerror,*webglcontextlost,*webglcontextrestored', '[HTMLElement]^[Element]|accessKey,contentEditable,dir,!draggable,!hidden,innerText,lang,*abort,*auxclick,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*cuechange,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*seeked,*seeking,*select,*show,*stalled,*submit,*suspend,*timeupdate,*toggle,*volumechange,*waiting,outerText,!spellcheck,%style,#tabIndex,title,!translate', 'abbr,address,article,aside,b,bdi,bdo,cite,code,dd,dfn,dt,em,figcaption,figure,footer,header,i,kbd,main,mark,nav,noscript,rb,rp,rt,rtc,ruby,s,samp,section,small,strong,sub,sup,u,var,wbr^[HTMLElement]|accessKey,contentEditable,dir,!draggable,!hidden,innerText,lang,*abort,*auxclick,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*cuechange,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*seeked,*seeking,*select,*show,*stalled,*submit,*suspend,*timeupdate,*toggle,*volumechange,*waiting,outerText,!spellcheck,%style,#tabIndex,title,!translate', 'media^[HTMLElement]|!autoplay,!controls,%controlsList,%crossOrigin,#currentTime,!defaultMuted,#defaultPlaybackRate,!disableRemotePlayback,!loop,!muted,*encrypted,*waitingforkey,#playbackRate,preload,src,%srcObject,#volume', ':svg:^[HTMLElement]|*abort,*auxclick,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*cuechange,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*seeked,*seeking,*select,*show,*stalled,*submit,*suspend,*timeupdate,*toggle,*volumechange,*waiting,%style,#tabIndex', ':svg:graphics^:svg:|', ':svg:animation^:svg:|*begin,*end,*repeat', ':svg:geometry^:svg:|', ':svg:componentTransferFunction^:svg:|', ':svg:gradient^:svg:|', ':svg:textContent^:svg:graphics|', ':svg:textPositioning^:svg:textContent|', 'a^[HTMLElement]|charset,coords,download,hash,host,hostname,href,hreflang,name,password,pathname,ping,port,protocol,referrerPolicy,rel,rev,search,shape,target,text,type,username', 'area^[HTMLElement]|alt,coords,download,hash,host,hostname,href,!noHref,password,pathname,ping,port,protocol,referrerPolicy,rel,search,shape,target,username', 'audio^media|', 'br^[HTMLElement]|clear', 'base^[HTMLElement]|href,target', 'body^[HTMLElement]|aLink,background,bgColor,link,*beforeunload,*blur,*error,*focus,*hashchange,*languagechange,*load,*message,*offline,*online,*pagehide,*pageshow,*popstate,*rejectionhandled,*resize,*scroll,*storage,*unhandledrejection,*unload,text,vLink', 'button^[HTMLElement]|!autofocus,!disabled,formAction,formEnctype,formMethod,!formNoValidate,formTarget,name,type,value', 'canvas^[HTMLElement]|#height,#width', 'content^[HTMLElement]|select', 'dl^[HTMLElement]|!compact', 'datalist^[HTMLElement]|', 'details^[HTMLElement]|!open', 'dialog^[HTMLElement]|!open,returnValue', 'dir^[HTMLElement]|!compact', 'div^[HTMLElement]|align', 'embed^[HTMLElement]|align,height,name,src,type,width', 'fieldset^[HTMLElement]|!disabled,name', 'font^[HTMLElement]|color,face,size', 'form^[HTMLElement]|acceptCharset,action,autocomplete,encoding,enctype,method,name,!noValidate,target', 'frame^[HTMLElement]|frameBorder,longDesc,marginHeight,marginWidth,name,!noResize,scrolling,src', 'frameset^[HTMLElement]|cols,*beforeunload,*blur,*error,*focus,*hashchange,*languagechange,*load,*message,*offline,*online,*pagehide,*pageshow,*popstate,*rejectionhandled,*resize,*scroll,*storage,*unhandledrejection,*unload,rows', 'hr^[HTMLElement]|align,color,!noShade,size,width', 'head^[HTMLElement]|', 'h1,h2,h3,h4,h5,h6^[HTMLElement]|align', 'html^[HTMLElement]|version', 'iframe^[HTMLElement]|align,!allowFullscreen,frameBorder,height,longDesc,marginHeight,marginWidth,name,referrerPolicy,%sandbox,scrolling,src,srcdoc,width', 'img^[HTMLElement]|align,alt,border,%crossOrigin,#height,#hspace,!isMap,longDesc,lowsrc,name,referrerPolicy,sizes,src,srcset,useMap,#vspace,#width', 'input^[HTMLElement]|accept,align,alt,autocapitalize,autocomplete,!autofocus,!checked,!defaultChecked,defaultValue,dirName,!disabled,%files,formAction,formEnctype,formMethod,!formNoValidate,formTarget,#height,!incremental,!indeterminate,max,#maxLength,min,#minLength,!multiple,name,pattern,placeholder,!readOnly,!required,selectionDirection,#selectionEnd,#selectionStart,#size,src,step,type,useMap,value,%valueAsDate,#valueAsNumber,#width', 'li^[HTMLElement]|type,#value', 'label^[HTMLElement]|htmlFor', 'legend^[HTMLElement]|align', 'link^[HTMLElement]|as,charset,%crossOrigin,!disabled,href,hreflang,integrity,media,referrerPolicy,rel,%relList,rev,%sizes,target,type', 'map^[HTMLElement]|name', 'marquee^[HTMLElement]|behavior,bgColor,direction,height,#hspace,#loop,#scrollAmount,#scrollDelay,!trueSpeed,#vspace,width', 'menu^[HTMLElement]|!compact', 'meta^[HTMLElement]|content,httpEquiv,name,scheme', 'meter^[HTMLElement]|#high,#low,#max,#min,#optimum,#value', 'ins,del^[HTMLElement]|cite,dateTime', 'ol^[HTMLElement]|!compact,!reversed,#start,type', 'object^[HTMLElement]|align,archive,border,code,codeBase,codeType,data,!declare,height,#hspace,name,standby,type,useMap,#vspace,width', 'optgroup^[HTMLElement]|!disabled,label', 'option^[HTMLElement]|!defaultSelected,!disabled,label,!selected,text,value', 'output^[HTMLElement]|defaultValue,%htmlFor,name,value', 'p^[HTMLElement]|align', 'param^[HTMLElement]|name,type,value,valueType', 'picture^[HTMLElement]|', 'pre^[HTMLElement]|#width', 'progress^[HTMLElement]|#max,#value', 'q,blockquote,cite^[HTMLElement]|', 'script^[HTMLElement]|!async,charset,%crossOrigin,!defer,event,htmlFor,integrity,src,text,type', 'select^[HTMLElement]|autocomplete,!autofocus,!disabled,#length,!multiple,name,!required,#selectedIndex,#size,value', 'shadow^[HTMLElement]|', 'slot^[HTMLElement]|name', 'source^[HTMLElement]|media,sizes,src,srcset,type', 'span^[HTMLElement]|', 'style^[HTMLElement]|!disabled,media,type', 'caption^[HTMLElement]|align', 'th,td^[HTMLElement]|abbr,align,axis,bgColor,ch,chOff,#colSpan,headers,height,!noWrap,#rowSpan,scope,vAlign,width', 'col,colgroup^[HTMLElement]|align,ch,chOff,#span,vAlign,width', 'table^[HTMLElement]|align,bgColor,border,%caption,cellPadding,cellSpacing,frame,rules,summary,%tFoot,%tHead,width', 'tr^[HTMLElement]|align,bgColor,ch,chOff,vAlign', 'tfoot,thead,tbody^[HTMLElement]|align,ch,chOff,vAlign', 'template^[HTMLElement]|', 'textarea^[HTMLElement]|autocapitalize,autocomplete,!autofocus,#cols,defaultValue,dirName,!disabled,#maxLength,#minLength,name,placeholder,!readOnly,!required,#rows,selectionDirection,#selectionEnd,#selectionStart,value,wrap', 'title^[HTMLElement]|text', 'track^[HTMLElement]|!default,kind,label,src,srclang', 'ul^[HTMLElement]|!compact,type', 'unknown^[HTMLElement]|', 'video^media|#height,poster,#width', ':svg:a^:svg:graphics|', ':svg:animate^:svg:animation|', ':svg:animateMotion^:svg:animation|', ':svg:animateTransform^:svg:animation|', ':svg:circle^:svg:geometry|', ':svg:clipPath^:svg:graphics|', ':svg:defs^:svg:graphics|', ':svg:desc^:svg:|', ':svg:discard^:svg:|', ':svg:ellipse^:svg:geometry|', ':svg:feBlend^:svg:|', ':svg:feColorMatrix^:svg:|', ':svg:feComponentTransfer^:svg:|', ':svg:feComposite^:svg:|', ':svg:feConvolveMatrix^:svg:|', ':svg:feDiffuseLighting^:svg:|', ':svg:feDisplacementMap^:svg:|', ':svg:feDistantLight^:svg:|', ':svg:feDropShadow^:svg:|', ':svg:feFlood^:svg:|', ':svg:feFuncA^:svg:componentTransferFunction|', ':svg:feFuncB^:svg:componentTransferFunction|', ':svg:feFuncG^:svg:componentTransferFunction|', ':svg:feFuncR^:svg:componentTransferFunction|', ':svg:feGaussianBlur^:svg:|', ':svg:feImage^:svg:|', ':svg:feMerge^:svg:|', ':svg:feMergeNode^:svg:|', ':svg:feMorphology^:svg:|', ':svg:feOffset^:svg:|', ':svg:fePointLight^:svg:|', ':svg:feSpecularLighting^:svg:|', ':svg:feSpotLight^:svg:|', ':svg:feTile^:svg:|', ':svg:feTurbulence^:svg:|', ':svg:filter^:svg:|', ':svg:foreignObject^:svg:graphics|', ':svg:g^:svg:graphics|', ':svg:image^:svg:graphics|', ':svg:line^:svg:geometry|', ':svg:linearGradient^:svg:gradient|', ':svg:mpath^:svg:|', ':svg:marker^:svg:|', ':svg:mask^:svg:|', ':svg:metadata^:svg:|', ':svg:path^:svg:geometry|', ':svg:pattern^:svg:|', ':svg:polygon^:svg:geometry|', ':svg:polyline^:svg:geometry|', ':svg:radialGradient^:svg:gradient|', ':svg:rect^:svg:geometry|', ':svg:svg^:svg:graphics|#currentScale,#zoomAndPan', ':svg:script^:svg:|type', ':svg:set^:svg:animation|', ':svg:stop^:svg:|', ':svg:style^:svg:|!disabled,media,title,type', ':svg:switch^:svg:graphics|', ':svg:symbol^:svg:|', ':svg:tspan^:svg:textPositioning|', ':svg:text^:svg:textPositioning|', ':svg:textPath^:svg:textContent|', ':svg:title^:svg:|', ':svg:use^:svg:graphics|', ':svg:view^:svg:|#zoomAndPan', 'data^[HTMLElement]|value', 'keygen^[HTMLElement]|!autofocus,challenge,!disabled,form,keytype,name', 'menuitem^[HTMLElement]|type,label,icon,!disabled,!checked,radiogroup,!default', 'summary^[HTMLElement]|', 'time^[HTMLElement]|dateTime', ':svg:cursor^:svg:|'];
40938
40939const _ATTR_TO_PROP = new Map(Object.entries({
40940  'class': 'className',
40941  'for': 'htmlFor',
40942  'formaction': 'formAction',
40943  'innerHtml': 'innerHTML',
40944  'readonly': 'readOnly',
40945  'tabindex': 'tabIndex'
40946})); // Invert _ATTR_TO_PROP.
40947
40948
40949const _PROP_TO_ATTR = Array.from(_ATTR_TO_PROP).reduce((inverted, [propertyName, attributeName]) => {
40950  inverted.set(propertyName, attributeName);
40951  return inverted;
40952}, new Map());
40953
40954class DomElementSchemaRegistry extends ElementSchemaRegistry {
40955  constructor() {
40956    super();
40957    this._schema = new Map(); // We don't allow binding to events for security reasons. Allowing event bindings would almost
40958    // certainly introduce bad XSS vulnerabilities. Instead, we store events in a separate schema.
40959
40960    this._eventSchema = new Map();
40961    SCHEMA.forEach(encodedType => {
40962      const type = new Map();
40963      const events = new Set();
40964      const [strType, strProperties] = encodedType.split('|');
40965      const properties = strProperties.split(',');
40966      const [typeNames, superName] = strType.split('^');
40967      typeNames.split(',').forEach(tag => {
40968        this._schema.set(tag.toLowerCase(), type);
40969
40970        this._eventSchema.set(tag.toLowerCase(), events);
40971      });
40972
40973      const superType = superName && this._schema.get(superName.toLowerCase());
40974
40975      if (superType) {
40976        for (const [prop, value] of superType) {
40977          type.set(prop, value);
40978        }
40979
40980        for (const superEvent of this._eventSchema.get(superName.toLowerCase())) {
40981          events.add(superEvent);
40982        }
40983      }
40984
40985      properties.forEach(property => {
40986        if (property.length > 0) {
40987          switch (property[0]) {
40988            case '*':
40989              events.add(property.substring(1));
40990              break;
40991
40992            case '!':
40993              type.set(property.substring(1), BOOLEAN);
40994              break;
40995
40996            case '#':
40997              type.set(property.substring(1), NUMBER);
40998              break;
40999
41000            case '%':
41001              type.set(property.substring(1), OBJECT);
41002              break;
41003
41004            default:
41005              type.set(property, STRING);
41006          }
41007        }
41008      });
41009    });
41010  }
41011
41012  hasProperty(tagName, propName, schemaMetas) {
41013    if (schemaMetas.some(schema => schema.name === NO_ERRORS_SCHEMA.name)) {
41014      return true;
41015    }
41016
41017    if (tagName.indexOf('-') > -1) {
41018      if (isNgContainer(tagName) || isNgContent(tagName)) {
41019        return false;
41020      }
41021
41022      if (schemaMetas.some(schema => schema.name === CUSTOM_ELEMENTS_SCHEMA.name)) {
41023        // Can't tell now as we don't know which properties a custom element will get
41024        // once it is instantiated
41025        return true;
41026      }
41027    }
41028
41029    const elementProperties = this._schema.get(tagName.toLowerCase()) || this._schema.get('unknown');
41030
41031    return elementProperties.has(propName);
41032  }
41033
41034  hasElement(tagName, schemaMetas) {
41035    if (schemaMetas.some(schema => schema.name === NO_ERRORS_SCHEMA.name)) {
41036      return true;
41037    }
41038
41039    if (tagName.indexOf('-') > -1) {
41040      if (isNgContainer(tagName) || isNgContent(tagName)) {
41041        return true;
41042      }
41043
41044      if (schemaMetas.some(schema => schema.name === CUSTOM_ELEMENTS_SCHEMA.name)) {
41045        // Allow any custom elements
41046        return true;
41047      }
41048    }
41049
41050    return this._schema.has(tagName.toLowerCase());
41051  }
41052  /**
41053   * securityContext returns the security context for the given property on the given DOM tag.
41054   *
41055   * Tag and property name are statically known and cannot change at runtime, i.e. it is not
41056   * possible to bind a value into a changing attribute or tag name.
41057   *
41058   * The filtering is based on a list of allowed tags|attributes. All attributes in the schema
41059   * above are assumed to have the 'NONE' security context, i.e. that they are safe inert
41060   * string values. Only specific well known attack vectors are assigned their appropriate context.
41061   */
41062
41063
41064  securityContext(tagName, propName, isAttribute) {
41065    if (isAttribute) {
41066      // NB: For security purposes, use the mapped property name, not the attribute name.
41067      propName = this.getMappedPropName(propName);
41068    } // Make sure comparisons are case insensitive, so that case differences between attribute and
41069    // property names do not have a security impact.
41070
41071
41072    tagName = tagName.toLowerCase();
41073    propName = propName.toLowerCase();
41074    let ctx = SECURITY_SCHEMA()[tagName + '|' + propName];
41075
41076    if (ctx) {
41077      return ctx;
41078    }
41079
41080    ctx = SECURITY_SCHEMA()['*|' + propName];
41081    return ctx ? ctx : SecurityContext.NONE;
41082  }
41083
41084  getMappedPropName(propName) {
41085    return _ATTR_TO_PROP.get(propName) ?? propName;
41086  }
41087
41088  getDefaultComponentElementName() {
41089    return 'ng-component';
41090  }
41091
41092  validateProperty(name) {
41093    if (name.toLowerCase().startsWith('on')) {
41094      const msg = `Binding to event property '${name}' is disallowed for security reasons, ` + `please use (${name.slice(2)})=...` + `\nIf '${name}' is a directive input, make sure the directive is imported by the` + ` current module.`;
41095      return {
41096        error: true,
41097        msg: msg
41098      };
41099    } else {
41100      return {
41101        error: false
41102      };
41103    }
41104  }
41105
41106  validateAttribute(name) {
41107    if (name.toLowerCase().startsWith('on')) {
41108      const msg = `Binding to event attribute '${name}' is disallowed for security reasons, ` + `please use (${name.slice(2)})=...`;
41109      return {
41110        error: true,
41111        msg: msg
41112      };
41113    } else {
41114      return {
41115        error: false
41116      };
41117    }
41118  }
41119
41120  allKnownElementNames() {
41121    return Array.from(this._schema.keys());
41122  }
41123
41124  allKnownAttributesOfElement(tagName) {
41125    const elementProperties = this._schema.get(tagName.toLowerCase()) || this._schema.get('unknown'); // Convert properties to attributes.
41126
41127
41128    return Array.from(elementProperties.keys()).map(prop => _PROP_TO_ATTR.get(prop) ?? prop);
41129  }
41130
41131  allKnownEventsOfElement(tagName) {
41132    return Array.from(this._eventSchema.get(tagName.toLowerCase()) ?? []);
41133  }
41134
41135  normalizeAnimationStyleProperty(propName) {
41136    return dashCaseToCamelCase(propName);
41137  }
41138
41139  normalizeAnimationStyleValue(camelCaseProp, userProvidedProp, val) {
41140    let unit = '';
41141    const strVal = val.toString().trim();
41142    let errorMsg = null;
41143
41144    if (_isPixelDimensionStyle(camelCaseProp) && val !== 0 && val !== '0') {
41145      if (typeof val === 'number') {
41146        unit = 'px';
41147      } else {
41148        const valAndSuffixMatch = val.match(/^[+-]?[\d\.]+([a-z]*)$/);
41149
41150        if (valAndSuffixMatch && valAndSuffixMatch[1].length == 0) {
41151          errorMsg = `Please provide a CSS unit value for ${userProvidedProp}:${val}`;
41152        }
41153      }
41154    }
41155
41156    return {
41157      error: errorMsg,
41158      value: strVal + unit
41159    };
41160  }
41161
41162}
41163
41164function _isPixelDimensionStyle(prop) {
41165  switch (prop) {
41166    case 'width':
41167    case 'height':
41168    case 'minWidth':
41169    case 'minHeight':
41170    case 'maxWidth':
41171    case 'maxHeight':
41172    case 'left':
41173    case 'top':
41174    case 'bottom':
41175    case 'right':
41176    case 'fontSize':
41177    case 'outlineWidth':
41178    case 'outlineOffset':
41179    case 'paddingTop':
41180    case 'paddingLeft':
41181    case 'paddingBottom':
41182    case 'paddingRight':
41183    case 'marginTop':
41184    case 'marginLeft':
41185    case 'marginBottom':
41186    case 'marginRight':
41187    case 'borderRadius':
41188    case 'borderWidth':
41189    case 'borderTopWidth':
41190    case 'borderLeftWidth':
41191    case 'borderRightWidth':
41192    case 'borderBottomWidth':
41193    case 'textIndent':
41194      return true;
41195
41196    default:
41197      return false;
41198  }
41199}
41200/**
41201 * @license
41202 * Copyright Google LLC All Rights Reserved.
41203 *
41204 * Use of this source code is governed by an MIT-style license that can be
41205 * found in the LICENSE file at https://angular.io/license
41206 */
41207
41208/**
41209 * Set of tagName|propertyName corresponding to Trusted Types sinks. Properties applying to all
41210 * tags use '*'.
41211 *
41212 * Extracted from, and should be kept in sync with
41213 * https://w3c.github.io/webappsec-trusted-types/dist/spec/#integrations
41214 */
41215
41216
41217const TRUSTED_TYPES_SINKS = new Set([// NOTE: All strings in this set *must* be lowercase!
41218// TrustedHTML
41219'iframe|srcdoc', '*|innerhtml', '*|outerhtml', // NB: no TrustedScript here, as the corresponding tags are stripped by the compiler.
41220// TrustedScriptURL
41221'embed|src', 'object|codebase', 'object|data']);
41222/**
41223 * isTrustedTypesSink returns true if the given property on the given DOM tag is a Trusted Types
41224 * sink. In that case, use `ElementSchemaRegistry.securityContext` to determine which particular
41225 * Trusted Type is required for values passed to the sink:
41226 * - SecurityContext.HTML corresponds to TrustedHTML
41227 * - SecurityContext.RESOURCE_URL corresponds to TrustedScriptURL
41228 */
41229
41230function isTrustedTypesSink(tagName, propName) {
41231  // Make sure comparisons are case insensitive, so that case differences between attribute and
41232  // property names do not have a security impact.
41233  tagName = tagName.toLowerCase();
41234  propName = propName.toLowerCase();
41235  return TRUSTED_TYPES_SINKS.has(tagName + '|' + propName) || TRUSTED_TYPES_SINKS.has('*|' + propName);
41236}
41237/**
41238 * @license
41239 * Copyright Google LLC All Rights Reserved.
41240 *
41241 * Use of this source code is governed by an MIT-style license that can be
41242 * found in the LICENSE file at https://angular.io/license
41243 */
41244
41245
41246const PROPERTY_PARTS_SEPARATOR = '.';
41247const ATTRIBUTE_PREFIX = 'attr';
41248const CLASS_PREFIX = 'class';
41249const STYLE_PREFIX = 'style';
41250const TEMPLATE_ATTR_PREFIX$1 = '*';
41251const ANIMATE_PROP_PREFIX = 'animate-';
41252/**
41253 * Parses bindings in templates and in the directive host area.
41254 */
41255
41256class BindingParser {
41257  constructor(_exprParser, _interpolationConfig, _schemaRegistry, errors) {
41258    this._exprParser = _exprParser;
41259    this._interpolationConfig = _interpolationConfig;
41260    this._schemaRegistry = _schemaRegistry;
41261    this.errors = errors;
41262  }
41263
41264  get interpolationConfig() {
41265    return this._interpolationConfig;
41266  }
41267
41268  createBoundHostProperties(properties, sourceSpan) {
41269    const boundProps = [];
41270
41271    for (const propName of Object.keys(properties)) {
41272      const expression = properties[propName];
41273
41274      if (typeof expression === 'string') {
41275        this.parsePropertyBinding(propName, expression, true, sourceSpan, sourceSpan.start.offset, undefined, [], // Use the `sourceSpan` for  `keySpan`. This isn't really accurate, but neither is the
41276        // sourceSpan, as it represents the sourceSpan of the host itself rather than the
41277        // source of the host binding (which doesn't exist in the template). Regardless,
41278        // neither of these values are used in Ivy but are only here to satisfy the function
41279        // signature. This should likely be refactored in the future so that `sourceSpan`
41280        // isn't being used inaccurately.
41281        boundProps, sourceSpan);
41282      } else {
41283        this._reportError(`Value of the host property binding "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`, sourceSpan);
41284      }
41285    }
41286
41287    return boundProps;
41288  }
41289
41290  createDirectiveHostEventAsts(hostListeners, sourceSpan) {
41291    const targetEvents = [];
41292
41293    for (const propName of Object.keys(hostListeners)) {
41294      const expression = hostListeners[propName];
41295
41296      if (typeof expression === 'string') {
41297        // Use the `sourceSpan` for  `keySpan` and `handlerSpan`. This isn't really accurate, but
41298        // neither is the `sourceSpan`, as it represents the `sourceSpan` of the host itself
41299        // rather than the source of the host binding (which doesn't exist in the template).
41300        // Regardless, neither of these values are used in Ivy but are only here to satisfy the
41301        // function signature. This should likely be refactored 
41301in the future so that `sourceSpan`
41302        // isn't being used inaccurately.
41303        this.parseEvent(propName, expression,
41304        /* isAssignmentEvent */
41305        false, sourceSpan, sourceSpan, [], targetEvents, sourceSpan);
41306      } else {
41307        this._reportError(`Value of the host listener "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`, sourceSpan);
41308      }
41309    }
41310
41311    return targetEvents;
41312  }
41313
41314  parseInterpolation(value, sourceSpan, interpolatedTokens) {
41315    const sourceInfo = sourceSpan.start.toString();
41316    const absoluteOffset = sourceSpan.fullStart.offset;
41317
41318    try {
41319      const ast = this._exprParser.parseInterpolation(value, sourceInfo, absoluteOffset, interpolatedTokens, this._interpolationConfig);
41320
41321      if (ast) this._reportExpressionParserErrors(ast.errors, sourceSpan);
41322      return ast;
41323    } catch (e) {
41324      this._reportError(`${e}`, sourceSpan);
41325
41326      return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
41327    }
41328  }
41329  /**
41330   * Similar to `parseInterpolation`, but treats the provided string as a single expression
41331   * element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`).
41332   * This is used for parsing the switch expression in ICUs.
41333   */
41334
41335
41336  parseInterpolationExpression(expression, sourceSpan) {
41337    const sourceInfo = sourceSpan.start.toString();
41338    const absoluteOffset = sourceSpan.start.offset;
41339
41340    try {
41341      const ast = this._exprParser.parseInterpolationExpression(expression, sourceInfo, absoluteOffset);
41342
41343      if (ast) this._reportExpressionParserErrors(ast.errors, sourceSpan);
41344      return ast;
41345    } catch (e) {
41346      this._reportError(`${e}`, sourceSpan);
41347
41348      return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
41349    }
41350  }
41351  /**
41352   * Parses the bindings in a microsyntax expression, and converts them to
41353   * `ParsedProperty` or `ParsedVariable`.
41354   *
41355   * @param tplKey template binding name
41356   * @param tplValue template binding value
41357   * @param sourceSpan span of template binding relative to entire the template
41358   * @param absoluteValueOffset start of the tplValue relative to the entire template
41359   * @param targetMatchableAttrs potential attributes to match in the template
41360   * @param targetProps target property bindings in the template
41361   * @param targetVars target variables in the template
41362   */
41363
41364
41365  parseInlineTemplateBinding(tplKey, tplValue, sourceSpan, absoluteValueOffset, targetMatchableAttrs, targetProps, targetVars, isIvyAst) {
41366    const absoluteKeyOffset = sourceSpan.start.offset + TEMPLATE_ATTR_PREFIX$1.length;
41367
41368    const bindings = this._parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset);
41369
41370    for (const binding of bindings) {
41371      // sourceSpan is for the entire HTML attribute. bindingSpan is for a particular
41372      // binding within the microsyntax expression so it's more narrow than sourceSpan.
41373      const bindingSpan = moveParseSourceSpan(sourceSpan, binding.sourceSpan);
41374      const key = binding.key.source;
41375      const keySpan = moveParseSourceSpan(sourceSpan, binding.key.span);
41376
41377      if (binding instanceof VariableBinding) {
41378        const value = binding.value ? binding.value.source : '$implicit';
41379        const valueSpan = binding.value ? moveParseSourceSpan(sourceSpan, binding.value.span) : undefined;
41380        targetVars.push(new ParsedVariable(key, value, bindingSpan, keySpan, valueSpan));
41381      } else if (binding.value) {
41382        const srcSpan = isIvyAst ? bindingSpan : sourceSpan;
41383        const valueSpan = moveParseSourceSpan(sourceSpan, binding.value.ast.sourceSpan);
41384
41385        this._parsePropertyAst(key, binding.value, srcSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
41386      } else {
41387        targetMatchableAttrs.push([key, ''
41388        /* value */
41389        ]); // Since this is a literal attribute with no RHS, source span should be
41390        // just the key span.
41391
41392        this.parseLiteralAttr(key, null
41393        /* value */
41394        , keySpan, absoluteValueOffset, undefined
41395        /* valueSpan */
41396        , targetMatchableAttrs, targetProps, keySpan);
41397      }
41398    }
41399  }
41400  /**
41401   * Parses the bindings in a microsyntax expression, e.g.
41402   * ```
41403   *    <tag *tplKey="let value1 = prop; let value2 = localVar">
41404   * ```
41405   *
41406   * @param tplKey template binding name
41407   * @param tplValue template binding value
41408   * @param sourceSpan span of template binding relative to entire the template
41409   * @param absoluteKeyOffset start of the `tplKey`
41410   * @param absoluteValueOffset start of the `tplValue`
41411   */
41412
41413
41414  _parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset) {
41415    const sourceInfo = sourceSpan.start.toString();
41416
41417    try {
41418      const bindingsResult = this._exprParser.parseTemplateBindings(tplKey, tplValue, sourceInfo, absoluteKeyOffset, absoluteValueOffset);
41419
41420      this._reportExpressionParserErrors(bindingsResult.errors, sourceSpan);
41421
41422      bindingsResult.warnings.forEach(warning => {
41423        this._reportError(warning, sourceSpan, ParseErrorLevel.WARNING);
41424      });
41425      return bindingsResult.templateBindings;
41426    } catch (e) {
41427      this._reportError(`${e}`, sourceSpan);
41428
41429      return [];
41430    }
41431  }
41432
41433  parseLiteralAttr(name, value, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs, targetProps, keySpan) {
41434    if (isAnimationLabel(name)) {
41435      name = name.substring(1);
41436
41437      if (keySpan !== undefined) {
41438        keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
41439      }
41440
41441      if (value) {
41442        this._reportError(`Assigning animation triggers via @prop="exp" attributes with an expression is invalid.` + ` Use property bindings (e.g. [@prop]="exp") or use an attribute without a value (e.g. @prop) instead.`, sourceSpan, ParseErrorLevel.ERROR);
41443      }
41444
41445      this._parseAnimation(name, value, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
41446    } else {
41447      targetProps.push(new ParsedProperty(name, this._exprParser.wrapLiteralPrimitive(value, '', absoluteOffset), ParsedPropertyType.LITERAL_ATTR, sourceSpan, keySpan, valueSpan));
41448    }
41449  }
41450
41451  parsePropertyBinding(name, expression, isHost, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs, targetProps, keySpan) {
41452    if (name.length === 0) {
41453      this._reportError(`Property name is missing in binding`, sourceSpan);
41454    }
41455
41456    let isAnimationProp = false;
41457
41458    if (name.startsWith(ANIMATE_PROP_PREFIX)) {
41459      isAnimationProp = true;
41460      name = name.substring(ANIMATE_PROP_PREFIX.length);
41461
41462      if (keySpan !== undefined) {
41463        keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + ANIMATE_PROP_PREFIX.length, keySpan.end.offset));
41464      }
41465    } else if (isAnimationLabel(name)) {
41466      isAnimationProp = true;
41467      name = name.substring(1);
41468
41469      if (keySpan !== undefined) {
41470        keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
41471      }
41472    }
41473
41474    if (isAnimationProp) {
41475      this._parseAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
41476    } else {
41477      this._parsePropertyAst(name, this._parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
41478    }
41479  }
41480
41481  parsePropertyInterpolation(name, value, sourceSpan, valueSpan, targetMatchableAttrs, targetProps, keySpan, interpolatedTokens) {
41482    const expr = this.parseInterpolation(value, valueSpan || sourceSpan, interpolatedTokens);
41483
41484    if (expr) {
41485      this._parsePropertyAst(name, expr, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
41486
41487      return true;
41488    }
41489
41490    return false;
41491  }
41492
41493  _parsePropertyAst(name, ast, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
41494    targetMatchableAttrs.push([name, ast.source]);
41495    targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.DEFAULT, sourceSpan, keySpan, valueSpan));
41496  }
41497
41498  _parseAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
41499    if (name.length === 0) {
41500      this._reportError('Animation trigger is missing', sourceSpan);
41501    } // This will occur when a @trigger is not paired with an expression.
41502    // For animations it is valid to not have an expression since */void
41503    // states will be applied by angular when the element is attached/detached
41504
41505
41506    const ast = this._parseBinding(expression || 'undefined', false, valueSpan || sourceSpan, absoluteOffset);
41507
41508    targetMatchableAttrs.push([name, ast.source]);
41509    targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.ANIMATION, sourceSpan, keySpan, valueSpan));
41510  }
41511
41512  _parseBinding(value, isHostBinding, sourceSpan, absoluteOffset) {
41513    const sourceInfo = (sourceSpan && sourceSpan.start || '(unknown)').toString();
41514
41515    try {
41516      const ast = isHostBinding ? this._exprParser.parseSimpleBinding(value, sourceInfo, absoluteOffset, this._interpolationConfig) : this._exprParser.parseBinding(value, sourceInfo, absoluteOffset, this._interpolationConfig);
41517      if (ast) this._reportExpressionParserErrors(ast.errors, sourceSpan);
41518      return ast;
41519    } catch (e) {
41520      this._reportError(`${e}`, sourceSpan);
41521
41522      return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
41523    }
41524  }
41525
41526  createBoundElementProperty(elementSelector, boundProp, skipValidation = false, mapPropertyName = true) {
41527    if (boundProp.isAnimation) {
41528      return new BoundElementProperty(boundProp.name, 4
41529      /* BindingType.Animation */
41530      , SecurityContext.NONE, boundProp.expression, null, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
41531    }
41532
41533    let unit = null;
41534    let bindingType = undefined;
41535    let boundPropertyName = null;
41536    const parts = boundProp.name.split(PROPERTY_PARTS_SEPARATOR);
41537    let securityContexts = undefined; // Check for special cases (prefix style, attr, class)
41538
41539    if (parts.length > 1) {
41540      if (parts[0] == ATTRIBUTE_PREFIX) {
41541        boundPropertyName = parts.slice(1).join(PROPERTY_PARTS_SEPARATOR);
41542
41543        if (!skipValidation) {
41544          this._validatePropertyOrAttributeName(boundPropertyName, boundProp.sourceSpan, true);
41545        }
41546
41547        securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, boundPropertyName, true);
41548        const nsSeparatorIdx = boundPropertyName.indexOf(':');
41549
41550        if (nsSeparatorIdx > -1) {
41551          const ns = boundPropertyName.substring(0, nsSeparatorIdx);
41552          const name = boundPropertyName.substring(nsSeparatorIdx + 1);
41553          boundPropertyName = mergeNsAndName(ns, name);
41554        }
41555
41556        bindingType = 1
41557        /* BindingType.Attribute */
41558        ;
41559      } else if (parts[0] == CLASS_PREFIX) {
41560        boundPropertyName = parts[1];
41561        bindingType = 2
41562        /* BindingType.Class */
41563        ;
41564        securityContexts = [SecurityContext.NONE];
41565      } else if (parts[0] == STYLE_PREFIX) {
41566        unit = parts.length > 2 ? parts[2] : null;
41567        boundPropertyName = parts[1];
41568        bindingType = 3
41569        /* BindingType.Style */
41570        ;
41571        securityContexts = [SecurityContext.STYLE];
41572      }
41573    } // If not a special case, use the full property name
41574
41575
41576    if (boundPropertyName === null) {
41577      const mappedPropName = this._schemaRegistry.getMappedPropName(boundProp.name);
41578
41579      boundPropertyName = mapPropertyName ? mappedPropName : boundProp.name;
41580      securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, mappedPropName, false);
41581      bindingType = 0
41582      /* BindingType.Property */
41583      ;
41584
41585      if (!skipValidation) {
41586        this._validatePropertyOrAttributeName(mappedPropName, boundProp.sourceSpan, false);
41587      }
41588    }
41589
41590    return new BoundElementProperty(boundPropertyName, bindingType, securityContexts[0], boundProp.expression, unit, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
41591  } // TODO: keySpan should be required but was made optional to avoid changing VE parser.
41592
41593
41594  parseEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
41595    if (name.length === 0) {
41596      this._reportError(`Event name is missing in binding`, sourceSpan);
41597    }
41598
41599    if (isAnimationLabel(name)) {
41600      name = name.slice(1);
41601
41602      if (keySpan !== undefined) {
41603        keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
41604      }
41605
41606      this._parseAnimationEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetEvents, keySpan);
41607    } else {
41608      this._parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan);
41609    }
41610  }
41611
41612  calcPossibleSecurityContexts(selector, propName, isAttribute) {
41613    const prop = this._schemaRegistry.getMappedPropName(propName);
41614
41615    return calcPossibleSecurityContexts(this._schemaRegistry, selector, prop, isAttribute);
41616  }
41617
41618  _parseAnimationEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetEvents, keySpan) {
41619    const matches = splitAtPeriod(name, [name, '']);
41620    const eventName = matches[0];
41621    const phase = matches[1].toLowerCase();
41622
41623    const ast = this._parseAction(expression, isAssignmentEvent, handlerSpan);
41624
41625    targetEvents.push(new ParsedEvent(eventName, phase, 1
41626    /* ParsedEventType.Animation */
41627    , ast, sourceSpan, handlerSpan, keySpan));
41628
41629    if (eventName.length === 0) {
41630      this._reportError(`Animation event name is missing in binding`, sourceSpan);
41631    }
41632
41633    if (phase) {
41634      if (phase !== 'start' && phase !== 'done') {
41635        this._reportError(`The provided animation output phase value "${phase}" for "@${eventName}" is not supported (use start or done)`, sourceSpan);
41636      }
41637    } else {
41638      this._reportError(`The animation trigger output event (@${eventName}) is missing its phase value name (start or done are currently supported)`, sourceSpan);
41639    }
41640  }
41641
41642  _parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
41643    // long format: 'target: eventName'
41644    const [target, eventName] = splitAtColon(name, [null, name]);
41645
41646    const ast = this._parseAction(expression, isAssignmentEvent, handlerSpan);
41647
41648    targetMatchableAttrs.push([name, ast.source]);
41649    targetEvents.push(new ParsedEvent(eventName, target, 0
41650    /* ParsedEventType.Regular */
41651    , ast, sourceSpan, handlerSpan, keySpan)); // Don't detect directives for event names for now,
41652    // so don't add the event name to the matchableAttrs
41653  }
41654
41655  _parseAction(value, isAssignmentEvent, sourceSpan) {
41656    const sourceInfo = (sourceSpan && sourceSpan.start || '(unknown').toString();
41657    const absoluteOffset = sourceSpan && sourceSpan.start ? sourceSpan.start.offset : 0;
41658
41659    try {
41660      const ast = this._exprParser.parseAction(value, isAssignmentEvent, sourceInfo, absoluteOffset, this._interpolationConfig);
41661
41662      if (ast) {
41663        this._reportExpressionParserErrors(ast.errors, sourceSpan);
41664      }
41665
41666      if (!ast || ast.ast instanceof EmptyExpr) {
41667        this._reportError(`Empty expressions are not allowed`, sourceSpan);
41668
41669        return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
41670      }
41671
41672      return ast;
41673    } catch (e) {
41674      this._reportError(`${e}`, sourceSpan);
41675
41676      return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
41677    }
41678  }
41679
41680  _reportError(message, sourceSpan, level = ParseErrorLevel.ERROR) {
41681    this.errors.push(new ParseError(sourceSpan, message, level));
41682  }
41683
41684  _reportExpressionParserErrors(errors, sourceSpan) {
41685    for (const error of errors) {
41686      this._reportError(error.message, sourceSpan);
41687    }
41688  }
41689  /**
41690   * @param propName the name of the property / attribute
41691   * @param sourceSpan
41692   * @param isAttr true when binding to an attribute
41693   */
41694
41695
41696  _validatePropertyOrAttributeName(propName, sourceSpan, isAttr) {
41697    const report = isAttr ? this._schemaRegistry.validateAttribute(propName) : this._schemaRegistry.validateProperty(propName);
41698
41699    if (report.error) {
41700      this._reportError(report.msg, sourceSpan, ParseErrorLevel.ERROR);
41701    }
41702  }
41703
41704}
41705
41706class PipeCollector extends RecursiveAstVisitor {
41707  constructor() {
41708    super(...arguments);
41709    this.pipes = new Map();
41710  }
41711
41712  visitPipe(ast, context) {
41713    this.pipes.set(ast.name, ast);
41714    ast.exp.visit(this);
41715    this.visitAll(ast.args, context);
41716    return null;
41717  }
41718
41719}
41720
41721function isAnimationLabel(name) {
41722  return name[0] == '@';
41723}
41724
41725function calcPossibleSecurityContexts(registry, selector, propName, isAttribute) {
41726  const ctxs = [];
41727  CssSelector.parse(selector).forEach(selector => {
41728    const elementNames = selector.element ? [selector.element] : registry.allKnownElementNames();
41729    const notElementNames = new Set(selector.notSelectors.filter(selector => selector.isElementSelector()).map(selector => selector.element));
41730    const possibleElementNames = elementNames.filter(elementName => !notElementNames.has(elementName));
41731    ctxs.push(...possibleElementNames.map(elementName => registry.securityContext(elementName, propName, isAttribute)));
41732  });
41733  return ctxs.length === 0 ? [SecurityContext.NONE] : Array.from(new Set(ctxs)).sort();
41734}
41735/**
41736 * Compute a new ParseSourceSpan based off an original `sourceSpan` by using
41737 * absolute offsets from the specified `absoluteSpan`.
41738 *
41739 * @param sourceSpan original source span
41740 * @param absoluteSpan absolute source span to move to
41741 */
41742
41743
41744function moveParseSourceSpan(sourceSpan, absoluteSpan) {
41745  // The difference of two absolute offsets provide the relative offset
41746  const startDiff = absoluteSpan.start - sourceSpan.start.offset;
41747  const endDiff = absoluteSpan.end - sourceSpan.end.offset;
41748  return new ParseSourceSpan(sourceSpan.start.moveBy(startDiff), sourceSpan.end.moveBy(endDiff), sourceSpan.fullStart.moveBy(startDiff), sourceSpan.details);
41749}
41750/**
41751 * @license
41752 * Copyright Google LLC All Rights Reserved.
41753 *
41754 * Use of this source code is governed by an MIT-style license that can be
41755 * found in the LICENSE file at https://angular.io/license
41756 */
41757// Some of the code comes from WebComponents.JS
41758// https://github.com/webcomponents/webcomponentsjs/blob/master/src/HTMLImports/path.js
41759
41760
41761function isStyleUrlResolvable(url) {
41762  if (url == null || url.length === 0 || url[0] == '/') return false;
41763  const schemeMatch = url.match(URL_WITH_SCHEMA_REGEXP);
41764  return schemeMatch === null || schemeMatch[1] == 'package' || schemeMatch[1] == 'asset';
41765}
41766
41767const URL_WITH_SCHEMA_REGEXP = /^([^:/?#]+):/;
41768/**
41769 * @license
41770 * Copyright Google LLC All Rights Reserved.
41771 *
41772 * Use of this source code is governed by an MIT-style license that can be
41773 * found in the LICENSE file at https://angular.io/license
41774 */
41775
41776const NG_CONTENT_SELECT_ATTR$1 = 'select';
41777const LINK_ELEMENT = 'link';
41778const LINK_STYLE_REL_ATTR = 'rel';
41779const LINK_STYLE_HREF_ATTR = 'href';
41780const LINK_STYLE_REL_VALUE = 'stylesheet';
41781const STYLE_ELEMENT = 'style';
41782const SCRIPT_ELEMENT = 'script';
41783const NG_NON_BINDABLE_ATTR = 'ngNonBindable';
41784const NG_PROJECT_AS = 'ngProjectAs';
41785
41786function preparseElement(ast) {
41787  let selectAttr = null;
41788  let hrefAttr = null;
41789  let relAttr = null;
41790  let nonBindable = false;
41791  let projectAs = '';
41792  ast.attrs.forEach(attr => {
41793    const lcAttrName = attr.name.toLowerCase();
41794
41795    if (lcAttrName == NG_CONTENT_SELECT_ATTR$1) {
41796      selectAttr = attr.value;
41797    } else if (lcAttrName == LINK_STYLE_HREF_ATTR) {
41798      hrefAttr = attr.value;
41799    } else if (lcAttrName == LINK_STYLE_REL_ATTR) {
41800      relAttr = attr.value;
41801    } else if (attr.name == NG_NON_BINDABLE_ATTR) {
41802      nonBindable = true;
41803    } else if (attr.name == NG_PROJECT_AS) {
41804      if (attr.value.length > 0) {
41805        projectAs = attr.value;
41806      }
41807    }
41808  });
41809  selectAttr = normalizeNgContentSelect(selectAttr);
41810  const nodeName = ast.name.toLowerCase();
41811  let type = PreparsedElementType.OTHER;
41812
41813  if (isNgContent(nodeName)) {
41814    type = PreparsedElementType.NG_CONTENT;
41815  } else if (nodeName == STYLE_ELEMENT) {
41816    type = PreparsedElementType.STYLE;
41817  } else if (nodeName == SCRIPT_ELEMENT) {
41818    type = PreparsedElementType.SCRIPT;
41819  } else if (nodeName == LINK_ELEMENT && relAttr == LINK_STYLE_REL_VALUE) {
41820    type = PreparsedElementType.STYLESHEET;
41821  }
41822
41823  return new PreparsedElement(type, selectAttr, hrefAttr, nonBindable, projectAs);
41824}
41825
41826var PreparsedElementType;
41827
41828(function (PreparsedElementType) {
41829  PreparsedElementType[PreparsedElementType["NG_CONTENT"] = 0] = "NG_CONTENT";
41830  PreparsedElementType[PreparsedElementType["STYLE"] = 1] = "STYLE";
41831  PreparsedElementType[PreparsedElementType["STYLESHEET"] = 2] = "STYLESHEET";
41832  PreparsedElementType[PreparsedElementType["SCRIPT"] = 3] = "SCRIPT";
41833  PreparsedElementType[PreparsedElementType["OTHER"] = 4] = "OTHER";
41834})(PreparsedElementType || (PreparsedElementType = {}));
41835
41836class PreparsedElement {
41837  constructor(type, selectAttr, hrefAttr, nonBindable, projectAs) {
41838    this.type = type;
41839    this.selectAttr = selectAttr;
41840    this.hrefAttr = hrefAttr;
41841    this.nonBindable = nonBindable;
41842    this.projectAs = projectAs;
41843  }
41844
41845}
41846
41847function normalizeNgContentSelect(selectAttr) {
41848  if (selectAttr === null || selectAttr.length === 0) {
41849    return '*';
41850  }
41851
41852  return selectAttr;
41853}
41854/**
41855 * @license
41856 * Copyright Google LLC All Rights Reserved.
41857 *
41858 * Use of this source code is governed by an MIT-style license that can be
41859 * found in the LICENSE file at https://angular.io/license
41860 */
41861
41862
41863const BIND_NAME_REGEXP = /^(?:(bind-)|(let-)|(ref-|#)|(on-)|(bindon-)|(@))(.*)$/; // Group 1 = "bind-"
41864
41865const KW_BIND_IDX = 1; // Group 2 = "let-"
41866
41867const KW_LET_IDX = 2; // Group 3 = "ref-/#"
41868
41869const KW_REF_IDX = 3; // Group 4 = "on-"
41870
41871const KW_ON_IDX = 4; // Group 5 = "bindon-"
41872
41873const KW_BINDON_IDX = 5; // Group 6 = "@"
41874
41875const KW_AT_IDX = 6; // Group 7 = the identifier after "bind-", "let-", "ref-/#", "on-", "bindon-" or "@"
41876
41877const IDENT_KW_IDX = 7;
41878const BINDING_DELIMS = {
41879  BANANA_BOX: {
41880    start: '[(',
41881    end: ')]'
41882  },
41883  PROPERTY: {
41884    start: '[',
41885    end: ']'
41886  },
41887  EVENT: {
41888    start: '(',
41889    end: ')'
41890  }
41891};
41892const TEMPLATE_ATTR_PREFIX = '*';
41893
41894function htmlAstToRender3Ast(htmlNodes, bindingParser, options) {
41895  const transformer = new HtmlAstToIvyAst(bindingParser, options);
41896  const ivyNodes = visitAll(transformer, htmlNodes); // Errors might originate in either the binding parser or the html to ivy transformer
41897
41898  const allErrors = bindingParser.errors.concat(transformer.errors);
41899  const result = {
41900    nodes: ivyNodes,
41901    errors: allErrors,
41902    styleUrls: transformer.styleUrls,
41903    styles: transformer.styles,
41904    ngContentSelectors: transformer.ngContentSelectors
41905  };
41906
41907  if (options.collectCommentNodes) {
41908    result.commentNodes = transformer.commentNodes;
41909  }
41910
41911  return result;
41912}
41913
41914class HtmlAstToIvyAst {
41915  constructor(bindingParser, options) {
41916    this.bindingParser = bindingParser;
41917    this.options = options;
41918    this.errors = [];
41919    this.styles = [];
41920    this.styleUrls = [];
41921    this.ngContentSelectors = []; // This array will be populated if `Render3ParseOptions['collectCommentNodes']` is true
41922
41923    this.commentNodes = [];
41924    this.inI18nBlock = false;
41925  } // HTML visitor
41926
41927
41928  visitElement(element) {
41929    const isI18nRootElement = isI18nRootNode(element.i18n);
41930
41931    if (isI18nRootElement) {
41932      if (this.inI18nBlock) {
41933        this.reportError('Cannot mark an element as translatable inside of a translatable section. Please remove the nested i18n marker.', element.sourceSpan);
41934      }
41935
41936      this.inI18nBlock = true;
41937    }
41938
41939    const preparsedElement = preparseElement(element);
41940
41941    if (preparsedElement.type === PreparsedElementType.SCRIPT) {
41942      return null;
41943    } else if (preparsedElement.type === PreparsedElementType.STYLE) {
41944      const contents = textContents(element);
41945
41946      if (contents !== null) {
41947        this.styles.push(contents);
41948      }
41949
41950      return null;
41951    } else if (preparsedElement.type === PreparsedElementType.STYLESHEET && isStyleUrlResolvable(preparsedElement.hrefAttr)) {
41952      this.styleUrls.push(preparsedElement.hrefAttr);
41953      return null;
41954    } // Whether the element is a `<ng-template>`
41955
41956
41957    const isTemplateElement = isNgTemplate(element.name);
41958    const parsedProperties = [];
41959    const boundEvents = [];
41960    const variables = [];
41961    const references = [];
41962    const attributes = [];
41963    const i18nAttrsMeta = {};
41964    const templateParsedProperties = [];
41965    const templateVariables = []; // Whether the element has any *-attribute
41966
41967    let elementHasInlineTemplate = false;
41968
41969    for (const attribute of element.attrs) {
41970      let hasBinding = false;
41971      const normalizedName = normalizeAttributeName(attribute.name); // `*attr` defines template bindings
41972
41973      let isTemplateBinding = false;
41974
41975      if (attribute.i18n) {
41976        i18nAttrsMeta[attribute.name] = attribute.i18n;
41977      }
41978
41979      if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX)) {
41980        // *-attributes
41981        if (elementHasInlineTemplate) {
41982          this.reportError(`Can't have multiple template bindings on one element. Use only one attribute prefixed with *`, attribute.sourceSpan);
41983        }
41984
41985        isTemplateBinding = true;
41986        elementHasInlineTemplate = true;
41987        const templateValue = attribute.value;
41988        const templateKey = normalizedName.substring(TEMPLATE_ATTR_PREFIX.length);
41989        const parsedVariables = [];
41990        const absoluteValueOffset = attribute.valueSpan ? attribute.valueSpan.start.offset : // If there is no value span the attribute does not have a value, like `attr` in
41991        //`<div attr></div>`. In this case, point to one character beyond the last character of
41992        // the attribute name.
41993        attribute.sourceSpan.start.offset + attribute.name.length;
41994        this.bindingParser.parseInlineTemplateBinding(templateKey, templateValue, attribute.sourceSpan, absoluteValueOffset, [], templateParsedProperties, parsedVariables, true
41995        /* isIvyAst */
41996        );
41997        templateVariables.push(...parsedVariables.map(v => new Variable(v.name, v.value, v.sourceSpan, v.keySpan, v.valueSpan)));
41998      } else {
41999        // Check for variables, events, property bindings, interpolation
42000        hasBinding = this.parseAttribute(isTemplateElement, attribute, [], parsedProperties, boundEvents, variables, references);
42001      }
42002
42003      if (!hasBinding && !isTemplateBinding) {
42004        // don't include the bindings as attributes as well in the AST
42005        attributes.push(this.visitAttribute(attribute));
42006      }
42007    }
42008
42009    const children = visitAll(preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children);
42010    let parsedElement;
42011
42012    if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
42013      // `<ng-content>`
42014      if (element.children && !element.children.every(node => isEmptyTextNode(node) || isCommentNode(node))) {
42015        this.reportError(`<ng-content> element cannot have content.`, element.sourceSpan);
42016      }
42017
42018      const selector = preparsedElement.selectAttr;
42019      const attrs = element.attrs.map(attr => this.visitAttribute(attr));
42020      parsedElement = new Content(selector, attrs, element.sourceSpan, element.i18n);
42021      this.ngContentSelectors.push(selector);
42022    } else if (isTemplateElement) {
42023      // `<ng-template>`
42024      const attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta);
42025      parsedElement = new Template(element.name, attributes, attrs.bound, boundEvents, [
42026        /* no template attributes */
42027      ], children, references, variables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
42028    } else {
42029      const attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta);
42030      parsedElement = new Element$1(element.name, attributes, attrs.bound, boundEvents, children, references, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
42031    }
42032
42033    if (elementHasInlineTemplate) {
42034      // If this node is an inline-template (e.g. has *ngFor) then we need to create a template
42035      // node that contains this node.
42036      // Moreover, if the node is an element, then we need to hoist its attributes to the template
42037      // node for matching against content projection selectors.
42038      const attrs = this.extractAttributes('ng-template', templateParsedProperties, i18nAttrsMeta);
42039      const templateAttrs = [];
42040      attrs.literal.forEach(attr => templateAttrs.push(attr));
42041      attrs.bound.forEach(attr => templateAttrs.push(attr));
42042      const hoistedAttrs = parsedElement instanceof Element$1 ? {
42043        attributes: parsedElement.attributes,
42044        inputs: parsedElement.inputs,
42045        outputs: parsedElement.outputs
42046      } : {
42047        attributes: [],
42048        inputs: [],
42049        outputs: []
42050      }; // For <ng-template>s with structural directives on them, avoid passing i18n information to
42051      // the wrapping template to prevent unnecessary i18n instructions from being generated. The
42052      // necessary i18n meta information will be extracted from child elements.
42053
42054      const i18n = isTemplateElement && isI18nRootElement ? undefined : element.i18n;
42055      const name = parsedElement instanceof Template ? null : parsedElement.name;
42056      parsedElement = new Template(name, hoistedAttrs.attributes, hoistedAttrs.inputs, hoistedAttrs.outputs, templateAttrs, [parsedElement], [
42057        /* no references */
42058      ], templateVariables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, i18n);
42059    }
42060
42061    if (isI18nRootElement) {
42062      this.inI18nBlock = false;
42063    }
42064
42065    return parsedElement;
42066  }
42067
42068  visitAttribute(attribute) {
42069    return new TextAttribute(attribute.name, attribute.value, attribute.sourceSpan, attribute.keySpan, attribute.valueSpan, attribute.i18n);
42070  }
42071
42072  visitText(text) {
42073    return this._visitTextWithInterpolation(text.value, text.sourceSpan, text.tokens, text.i18n);
42074  }
42075
42076  visitExpansion(expansion) {
42077    if (!expansion.i18n) {
42078      // do not generate Icu in case it was created
42079      // outside of i18n block in a template
42080      return null;
42081    }
42082
42083    if (!isI18nRootNode(expansion.i18n)) {
42084      throw new Error(`Invalid type "${expansion.i18n.constructor}" for "i18n" property of ${expansion.sourceSpan.toString()}. Expected a "Message"`);
42085    }
42086
42087    const message = expansion.i18n;
42088    const vars = {};
42089    const placeholders = {}; // extract VARs from ICUs - we process them separately while
42090    // assembling resulting message via goog.getMsg function, since
42091    // we need to pass them to top-level goog.getMsg call
42092
42093    Object.keys(message.placeholders).forEach(key => {
42094      const value = message.placeholders[key];
42095
42096      if (key.startsWith(I18N_ICU_VAR_PREFIX)) {
42097        // Currently when the `plural` or `select` keywords in an ICU contain trailing spaces (e.g.
42098        // `{count, select , ...}`), these spaces are also included into the key names in ICU vars
42099        // (e.g. "VAR_SELECT "). These trailing spaces are not desirable, since they will later be
42100        // converted into `_` symbols while normalizing placeholder names, which might lead to
42101        // mismatches at runtime (i.e. placeholder will not be replaced with the correct value).
42102        const formattedKey = key.trim();
42103        const ast = this.bindingParser.parseInterpolationExpression(value.text, value.sourceSpan);
42104        vars[formattedKey] = new BoundText(ast, value.sourceSpan);
42105      } else {
42106        placeholders[key] = this._visitTextWithInterpolation(value.text, value.sourceSpan, null);
42107      }
42108    });
42109    return new Icu$1(vars, placeholders, expansion.sourceSpan, message);
42110  }
42111
42112  visitExpansionCase(expansionCase) {
42113    return null;
42114  }
42115
42116  visitComment(comment) {
42117    if (this.options.collectCommentNodes) {
42118      this.commentNodes.push(new Comment$1(comment.value || '', comment.sourceSpan));
42119    }
42120
42121    return null;
42122  } // convert view engine `ParsedProperty` to a format suitable for IVY
42123
42124
42125  extractAttributes(elementName, properties, i18nPropsMeta) {
42126    const bound = [];
42127    const literal = [];
42128    properties.forEach(prop => {
42129      const i18n = i18nPropsMeta[prop.name];
42130
42131      if (prop.isLiteral) {
42132        literal.push(new TextAttribute(prop.name, prop.expression.source || '', prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n));
42133      } else {
42134        // Note that validation is skipped and property mapping is disabled
42135        // due to the fact that we need to make sure a given prop is not an
42136        // input of a directive and directive matching happens at runtime.
42137        const bep = this.bindingParser.createBoundElementProperty(elementName, prop,
42138        /* skipValidation */
42139        true,
42140        /* mapPropertyName */
42141        false);
42142        bound.push(BoundAttribute.fromBoundElementProperty(bep, i18n));
42143      }
42144    });
42145    return {
42146      bound,
42147      literal
42148    };
42149  }
42150
42151  parseAttribute(isTemplateElement, attribute, matchableAttributes, parsedProperties, boundEvents, variables, references) {
42152    const name = normalizeAttributeName(attribute.name);
42153    const value = attribute.value;
42154    const srcSpan = attribute.sourceSpan;
42155    const absoluteOffset = attribute.valueSpan ? attribute.valueSpan.start.offset : srcSpan.start.offset;
42156
42157    function createKeySpan(srcSpan, prefix, identifier) {
42158      // We need to adjust the start location for the keySpan to account for the removed 'data-'
42159      // prefix from `normalizeAttributeName`.
42160      const normalizationAdjustment = attribute.name.length - name.length;
42161      const keySpanStart = srcSpan.start.moveBy(prefix.length + normalizationAdjustment);
42162      const keySpanEnd = keySpanStart.moveBy(identifier.length);
42163      return new ParseSourceSpan(keySpanStart, keySpanEnd, keySpanStart, identifier);
42164    }
42165
42166    const bindParts = name.match(BIND_NAME_REGEXP);
42167
42168    if (bindParts) {
42169      if (bindParts[KW_BIND_IDX] != null) {
42170        const identifier = bindParts[IDENT_KW_IDX];
42171        const keySpan = createKeySpan(srcSpan, bindParts[KW_BIND_IDX], identifier);
42172        this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
42173      } else if (bindParts[KW_LET_IDX]) {
42174        if (isTemplateElement) {
42175          const identifier = bindParts[IDENT_KW_IDX];
42176          const keySpan = createKeySpan(srcSpan, bindParts[KW_LET_IDX], identifier);
42177          this.parseVariable(identifier, value, srcSpan, keySpan, attribute.valueSpan, variables);
42178        } else {
42179          this.reportError(`"let-" is only supported on ng-template elements.`, srcSpan);
42180        }
42181      } else if (bindParts[KW_REF_IDX]) {
42182        const identifier = bindParts[IDENT_KW_IDX];
42183        const keySpan = createKeySpan(srcSpan, bindParts[KW_REF_IDX], identifier);
42184        this.parseReference(identifier, value, srcSpan, keySpan, attribute.valueSpan, references);
42185      } else if (bindParts[KW_ON_IDX]) {
42186        const events = [];
42187        const identifier = bindParts[IDENT_KW_IDX];
42188        const keySpan = createKeySpan(srcSpan, bindParts[KW_ON_IDX], identifier);
42189        this.bindingParser.parseEvent(identifier, value,
42190        /* isAssignmentEvent */
42191        false, srcSpan, attribute.valueSpan || srcSpan, matchableAttributes, events, keySpan);
42192        addEvents(events, boundEvents);
42193      } else if (bindParts[KW_BINDON_IDX]) {
42194        const identifier = bindParts[IDENT_KW_IDX];
42195        const keySpan = createKeySpan(srcSpan, bindParts[KW_BINDON_IDX], identifier);
42196        this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
42197        this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan);
42198      } else if (bindParts[KW_AT_IDX]) {
42199        const keySpan = createKeySpan(srcSpan, '', name);
42200        this.bindingParser.parseLiteralAttr(name, value, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
42201      }
42202
42203      return true;
42204    } // We didn't see a kw-prefixed property binding, but we have not yet checked
42205    // for the []/()/[()] syntax.
42206
42207
42208    let delims = null;
42209
42210    if (name.startsWith(BINDING_DELIMS.BANANA_BOX.start)) {
42211      delims = BINDING_DELIMS.BANANA_BOX;
42212    } else if (name.startsWith(BINDING_DELIMS.PROPERTY.start)) {
42213      delims = BINDING_DELIMS.PROPERTY;
42214    } else if (name.startsWith(BINDING_DELIMS.EVENT.start)) {
42215      delims = BINDING_DELIMS.EVENT;
42216    }
42217
42218    if (delims !== null && // NOTE: older versions of the parser would match a start/end delimited
42219    // binding iff the property name was terminated by the ending delimiter
42220    // and the identifier in the binding was non-empty.
42221    // TODO(ayazhafiz): update this to handle malformed bindings.
42222    name.endsWith(delims.end) && name.length > delims.start.length + delims.end.length) {
42223      const identifier = name.substring(delims.start.length, name.length - delims.end.length);
42224      const keySpan = createKeySpan(srcSpan, delims.start, identifier);
42225
42226      if (delims.start === BINDING_DELIMS.BANANA_BOX.start) {
42227        this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
42228        this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan);
42229      } else if (delims.start === BINDING_DELIMS.PROPERTY.start) {
42230        this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
42231      } else {
42232        const events = [];
42233        this.bindingParser.parseEvent(identifier, value,
42234        /* isAssignmentEvent */
42235        false, srcSpan, attribute.valueSpan || srcSpan, matchableAttributes, events, keySpan);
42236        addEvents(events, boundEvents);
42237      }
42238
42239      return true;
42240    } // No explicit binding found.
42241
42242
42243    const keySpan = createKeySpan(srcSpan, ''
42244    /* prefix */
42245    , name);
42246    const hasBinding = this.bindingParser.parsePropertyInterpolation(name, value, srcSpan, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan, attribute.valueTokens ?? null);
42247    return hasBinding;
42248  }
42249
42250  _visitTextWithInterpolation(value, sourceSpan, interpolatedTokens, i18n) {
42251    const valueNoNgsp = replaceNgsp(value);
42252    const expr = this.bindingParser.parseInterpolation(valueNoNgsp, sourceSpan, interpolatedTokens);
42253    return expr ? new BoundText(expr, sourceSpan, i18n) : new Text$3(valueNoNgsp, sourceSpan);
42254  }
42255
42256  parseVariable(identifier, value, sourceSpan, keySpan, valueSpan, variables) {
42257    if (identifier.indexOf('-') > -1) {
42258      this.reportError(`"-" is not allowed in variable names`, sourceSpan);
42259    } else if (identifier.length === 0) {
42260      this.reportError(`Variable does not have a name`, sourceSpan);
42261    }
42262
42263    variables.push(new Variable(identifier, value, sourceSpan, keySpan, valueSpan));
42264  }
42265
42266  parseReference(identifier, value, sourceSpan, keySpan, valueSpan, references) {
42267    if (identifier.indexOf('-') > -1) {
42268      this.reportError(`"-" is not allowed in reference names`, sourceSpan);
42269    } else if (identifier.length === 0) {
42270      this.reportError(`Reference does not have a name`, sourceSpan);
42271    } else if (references.some(reference => reference.name === identifier)) {
42272      this.reportError(`Reference "#${identifier}" is defined more than once`, sourceSpan);
42273    }
42274
42275    references.push(new Reference(identifier, value, sourceSpan, keySpan, valueSpan));
42276  }
42277
42278  parseAssignmentEvent(name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan) {
42279    const events = [];
42280    this.bindingParser.parseEvent(`${name}Change`, `${expression} =$event`,
42281    /* isAssignmentEvent */
42282    true, sourceSpan, valueSpan || sourceSpan, targetMatchableAttrs, events, keySpan);
42283    addEvents(events, boundEvents);
42284  }
42285
42286  reportError(message, sourceSpan, level = ParseErrorLevel.ERROR) {
42287    this.errors.push(new ParseError(sourceSpan, message, level));
42288  }
42289
42290}
42291
42292class NonBindableVisitor {
42293  visitElement(ast) {
42294    const preparsedElement = preparseElement(ast);
42295
42296    if (preparsedElement.type === PreparsedElementType.SCRIPT || preparsedElement.type === PreparsedElementType.STYLE || preparsedElement.type === PreparsedElementType.STYLESHEET) {
42297      // Skipping <script> for security reasons
42298      // Skipping <style> and stylesheets as we already processed them
42299      // in the StyleCompiler
42300      return null;
42301    }
42302
42303    const children = visitAll(this, ast.children, null);
42304    return new Element$1(ast.name, visitAll(this, ast.attrs),
42305    /* inputs */
42306    [],
42307    /* outputs */
42308    [], children,
42309    /* references */
42310    [], ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
42311  }
42312
42313  visitComment(comment) {
42314    return null;
42315  }
42316
42317  visitAttribute(attribute) {
42318    return new TextAttribute(attribute.name, attribute.value, attribute.sourceSpan, attribute.keySpan, attribute.valueSpan, attribute.i18n);
42319  }
42320
42321  visitText(text) {
42322    return new Text$3(text.value, text.sourceSpan);
42323  }
42324
42325  visitExpansion(expansion) {
42326    return null;
42327  }
42328
42329  visitExpansionCase(expansionCase) {
42330    return null;
42331  }
42332
42333}
42334
42335const NON_BINDABLE_VISITOR = new NonBindableVisitor();
42336
42337function normalizeAttributeName(attrName) {
42338  return /^data-/i.test(attrName) ? attrName.substring(5) : attrName;
42339}
42340
42341function addEvents(events, boundEvents) {
42342  boundEvents.push(...events.map(e => BoundEvent.fromParsedEvent(e)));
42343}
42344
42345function isEmptyTextNode(node) {
42346  return node instanceof Text && node.value.trim().length == 0;
42347}
42348
42349function isCommentNode(node) {
42350  return node instanceof Comment;
42351}
42352
42353function textContents(node) {
42354  if (node.children.length !== 1 || !(node.children[0] instanceof Text)) {
42355    return null;
42356  } else {
42357    return node.children[0].value;
42358  }
42359}
42360/**
42361 * @license
42362 * Copyright Google LLC All Rights Reserved.
42363 *
42364 * Use of this source code is governed by an MIT-style license that can be
42365 * found in the LICENSE file at https://angular.io/license
42366 */
42367
42368
42369var TagType;
42370
42371(function (TagType) {
42372  TagType[TagType["ELEMENT"] = 0] = "ELEMENT";
42373  TagType[TagType["TEMPLATE"] = 1] = "TEMPLATE";
42374})(TagType || (TagType = {}));
42375/**
42376 * Generates an object that is used as a shared state between parent and all child contexts.
42377 */
42378
42379
42380function setupRegistry() {
42381  return {
42382    getUniqueId: getSeqNumberGenerator(),
42383    icus: new Map()
42384  };
42385}
42386/**
42387 * I18nContext is a helper class which keeps track of all i18n-related as
42387pects
42388 * (accumulates placeholders, bindings, etc) between i18nStart and i18nEnd instructions.
42389 *
42390 * When we enter a nested template, the top-level context is being passed down
42391 * to the nested component, which uses this context to generate a child instance
42392 * of I18nContext class (to handle nested template) and at the end, reconciles it back
42393 * with the parent context.
42394 *
42395 * @param index Instruction index of i18nStart, which initiates this context
42396 * @param ref Reference to a translation const that represents the content if thus context
42397 * @param level Nesting level defined for child contexts
42398 * @param templateIndex Instruction index of a template which this context belongs to
42399 * @param meta Meta information (id, meaning, description, etc) associated with this context
42400 */
42401
42402
42403class I18nContext {
42404  constructor(index, ref, level = 0, templateIndex = null, meta, registry) {
42405    this.index = index;
42406    this.ref = ref;
42407    this.level = level;
42408    this.templateIndex = templateIndex;
42409    this.meta = meta;
42410    this.registry = registry;
42411    this.bindings = new Set();
42412    this.placeholders = new Map();
42413    this.isEmitted = false;
42414    this._unresolvedCtxCount = 0;
42415    this._registry = registry || setupRegistry();
42416    this.id = this._registry.getUniqueId();
42417  }
42418
42419  appendTag(type, node, index, closed) {
42420    if (node.isVoid && closed) {
42421      return; // ignore "close" for void tags
42422    }
42423
42424    const ph = node.isVoid || !closed ? node.startName : node.closeName;
42425    const content = {
42426      type,
42427      index,
42428      ctx: this.id,
42429      isVoid: node.isVoid,
42430      closed
42431    };
42432    updatePlaceholderMap(this.placeholders, ph, content);
42433  }
42434
42435  get icus() {
42436    return this._registry.icus;
42437  }
42438
42439  get isRoot() {
42440    return this.level === 0;
42441  }
42442
42443  get isResolved() {
42444    return this._unresolvedCtxCount === 0;
42445  }
42446
42447  getSerializedPlaceholders() {
42448    const result = new Map();
42449    this.placeholders.forEach((values, key) => result.set(key, values.map(serializePlaceholderValue)));
42450    return result;
42451  } // public API to accumulate i18n-related content
42452
42453
42454  appendBinding(binding) {
42455    this.bindings.add(binding);
42456  }
42457
42458  appendIcu(name, ref) {
42459    updatePlaceholderMap(this._registry.icus, name, ref);
42460  }
42461
42462  appendBoundText(node) {
42463    const phs = assembleBoundTextPlaceholders(node, this.bindings.size, this.id);
42464    phs.forEach((values, key) => updatePlaceholderMap(this.placeholders, key, ...values));
42465  }
42466
42467  appendTemplate(node, index) {
42468    // add open and close tags at the same time,
42469    // since we process nested templates separately
42470    this.appendTag(TagType.TEMPLATE, node, index, false);
42471    this.appendTag(TagType.TEMPLATE, node, index, true);
42472    this._unresolvedCtxCount++;
42473  }
42474
42475  appendElement(node, index, closed) {
42476    this.appendTag(TagType.ELEMENT, node, index, closed);
42477  }
42478
42479  appendProjection(node, index) {
42480    // Add open and close tags at the same time, since `<ng-content>` has no content,
42481    // so when we come across `<ng-content>` we can register both open and close tags.
42482    // Note: runtime i18n logic doesn't distinguish `<ng-content>` tag placeholders and
42483    // regular element tag placeholders, so we generate element placeholders for both types.
42484    this.appendTag(TagType.ELEMENT, node, index, false);
42485    this.appendTag(TagType.ELEMENT, node, index, true);
42486  }
42487  /**
42488   * Generates an instance of a child context based on the root one,
42489   * when we enter a nested template within I18n section.
42490   *
42491   * @param index Instruction index of corresponding i18nStart, which initiates this context
42492   * @param templateIndex Instruction index of a template which this context belongs to
42493   * @param meta Meta information (id, meaning, description, etc) associated with this context
42494   *
42495   * @returns I18nContext instance
42496   */
42497
42498
42499  forkChildContext(index, templateIndex, meta) {
42500    return new I18nContext(index, this.ref, this.level + 1, templateIndex, meta, this._registry);
42501  }
42502  /**
42503   * Reconciles child context into parent one once the end of the i18n block is reached (i18nEnd).
42504   *
42505   * @param context Child I18nContext instance to be reconciled with parent context.
42506   */
42507
42508
42509  reconcileChildContext(context) {
42510    // set the right context id for open and close
42511    // template tags, so we can use it as sub-block ids
42512    ['start', 'close'].forEach(op => {
42513      const key = context.meta[`${op}Name`];
42514      const phs = this.placeholders.get(key) || [];
42515      const tag = phs.find(findTemplateFn(this.id, context.templateIndex));
42516
42517      if (tag) {
42518        tag.ctx = context.id;
42519      }
42520    }); // reconcile placeholders
42521
42522    const childPhs = context.placeholders;
42523    childPhs.forEach((values, key) => {
42524      const phs = this.placeholders.get(key);
42525
42526      if (!phs) {
42527        this.placeholders.set(key, values);
42528        return;
42529      } // try to find matching template...
42530
42531
42532      const tmplIdx = phs.findIndex(findTemplateFn(context.id, context.templateIndex));
42533
42534      if (tmplIdx >= 0) {
42535        // ... if found - replace it with nested template content
42536        const isCloseTag = key.startsWith('CLOSE');
42537        const isTemplateTag = key.endsWith('NG-TEMPLATE');
42538
42539        if (isTemplateTag) {
42540          // current template's content is placed before or after
42541          // parent template tag, depending on the open/close attribute
42542          phs.splice(tmplIdx + (isCloseTag ? 0 : 1), 0, ...values);
42543        } else {
42544          const idx = isCloseTag ? values.length - 1 : 0;
42545          values[idx].tmpl = phs[tmplIdx];
42546          phs.splice(tmplIdx, 1, ...values);
42547        }
42548      } else {
42549        // ... otherwise just append content to placeholder value
42550        phs.push(...values);
42551      }
42552
42553      this.placeholders.set(key, phs);
42554    });
42555    this._unresolvedCtxCount--;
42556  }
42557
42558} //
42559// Helper methods
42560//
42561
42562
42563function wrap(symbol, index, contextId, closed) {
42564  const state = closed ? '/' : '';
42565  return wrapI18nPlaceholder(`${state}${symbol}${index}`, contextId);
42566}
42567
42568function wrapTag(symbol, {
42569  index,
42570  ctx,
42571  isVoid
42572}, closed) {
42573  return isVoid ? wrap(symbol, index, ctx) + wrap(symbol, index, ctx, true) : wrap(symbol, index, ctx, closed);
42574}
42575
42576function findTemplateFn(ctx, templateIndex) {
42577  return token => typeof token === 'object' && token.type === TagType.TEMPLATE && token.index === templateIndex && token.ctx === ctx;
42578}
42579
42580function serializePlaceholderValue(value) {
42581  const element = (data, closed) => wrapTag('#', data, closed);
42582
42583  const template = (data, closed) => wrapTag('*', data, closed);
42584
42585  const projection = (data, closed) => wrapTag('!', data, closed);
42586
42587  switch (value.type) {
42588    case TagType.ELEMENT:
42589      // close element tag
42590      if (value.closed) {
42591        return element(value, true) + (value.tmpl ? template(value.tmpl, true) : '');
42592      } // open element tag that also initiates a template
42593
42594
42595      if (value.tmpl) {
42596        return template(value.tmpl) + element(value) + (value.isVoid ? template(value.tmpl, true) : '');
42597      }
42598
42599      return element(value);
42600
42601    case TagType.TEMPLATE:
42602      return template(value, value.closed);
42603
42604    default:
42605      return value;
42606  }
42607}
42608/**
42609 * @license
42610 * Copyright Google LLC All Rights Reserved.
42611 *
42612 * Use of this source code is governed by an MIT-style license that can be
42613 * found in the LICENSE file at https://angular.io/license
42614 */
42615
42616
42617class IcuSerializerVisitor {
42618  visitText(text) {
42619    return text.value;
42620  }
42621
42622  visitContainer(container) {
42623    return container.children.map(child => child.visit(this)).join('');
42624  }
42625
42626  visitIcu(icu) {
42627    const strCases = Object.keys(icu.cases).map(k => `${k} {${icu.cases[k].visit(this)}}`);
42628    const result = `{${icu.expressionPlaceholder}, ${icu.type}, ${strCases.join(' ')}}`;
42629    return result;
42630  }
42631
42632  visitTagPlaceholder(ph) {
42633    return ph.isVoid ? this.formatPh(ph.startName) : `${this.formatPh(ph.startName)}${ph.children.map(child => child.visit(this)).join('')}${this.formatPh(ph.closeName)}`;
42634  }
42635
42636  visitPlaceholder(ph) {
42637    return this.formatPh(ph.name);
42638  }
42639
42640  visitIcuPlaceholder(ph, context) {
42641    return this.formatPh(ph.name);
42642  }
42643
42644  formatPh(value) {
42645    return `{${formatI18nPlaceholderName(value,
42646    /* useCamelCase */
42647    false)}}`;
42648  }
42649
42650}
42651
42652const serializer = new IcuSerializerVisitor();
42653
42654function serializeIcuNode(icu) {
42655  return icu.visit(serializer);
42656}
42657/**
42658 * @license
42659 * Copyright Google LLC All Rights Reserved.
42660 *
42661 * Use of this source code is governed by an MIT-style license that can be
42662 * found in the LICENSE file at https://angular.io/license
42663 */
42664
42665
42666const TAG_TO_PLACEHOLDER_NAMES = {
42667  'A': 'LINK',
42668  'B': 'BOLD_TEXT',
42669  'BR': 'LINE_BREAK',
42670  'EM': 'EMPHASISED_TEXT',
42671  'H1': 'HEADING_LEVEL1',
42672  'H2': 'HEADING_LEVEL2',
42673  'H3': 'HEADING_LEVEL3',
42674  'H4': 'HEADING_LEVEL4',
42675  'H5': 'HEADING_LEVEL5',
42676  'H6': 'HEADING_LEVEL6',
42677  'HR': 'HORIZONTAL_RULE',
42678  'I': 'ITALIC_TEXT',
42679  'LI': 'LIST_ITEM',
42680  'LINK': 'MEDIA_LINK',
42681  'OL': 'ORDERED_LIST',
42682  'P': 'PARAGRAPH',
42683  'Q': 'QUOTATION',
42684  'S': 'STRIKETHROUGH_TEXT',
42685  'SMALL': 'SMALL_TEXT',
42686  'SUB': 'SUBSTRIPT',
42687  'SUP': 'SUPERSCRIPT',
42688  'TBODY': 'TABLE_BODY',
42689  'TD': 'TABLE_CELL',
42690  'TFOOT': 'TABLE_FOOTER',
42691  'TH': 'TABLE_HEADER_CELL',
42692  'THEAD': 'TABLE_HEADER',
42693  'TR': 'TABLE_ROW',
42694  'TT': 'MONOSPACED_TEXT',
42695  'U': 'UNDERLINED_TEXT',
42696  'UL': 'UNORDERED_LIST'
42697};
42698/**
42699 * Creates unique names for placeholder with different content.
42700 *
42701 * Returns the same placeholder name when the content is identical.
42702 */
42703
42704class PlaceholderRegistry {
42705  constructor() {
42706    // Count the occurrence of the base name top generate a unique name
42707    this._placeHolderNameCounts = {}; // Maps signature to placeholder names
42708
42709    this._signatureToName = {};
42710  }
42711
42712  getStartTagPlaceholderName(tag, attrs, isVoid) {
42713    const signature = this._hashTag(tag, attrs, isVoid);
42714
42715    if (this._signatureToName[signature]) {
42716      return this._signatureToName[signature];
42717    }
42718
42719    const upperTag = tag.toUpperCase();
42720    const baseName = TAG_TO_PLACEHOLDER_NAMES[upperTag] || `TAG_${upperTag}`;
42721
42722    const name = this._generateUniqueName(isVoid ? baseName : `START_${baseName}`);
42723
42724    this._signatureToName[signature] = name;
42725    return name;
42726  }
42727
42728  getCloseTagPlaceholderName(tag) {
42729    const signature = this._hashClosingTag(tag);
42730
42731    if (this._signatureToName[signature]) {
42732      return this._signatureToName[signature];
42733    }
42734
42735    const upperTag = tag.toUpperCase();
42736    const baseName = TAG_TO_PLACEHOLDER_NAMES[upperTag] || `TAG_${upperTag}`;
42737
42738    const name = this._generateUniqueName(`CLOSE_${baseName}`);
42739
42740    this._signatureToName[signature] = name;
42741    return name;
42742  }
42743
42744  getPlaceholderName(name, content) {
42745    const upperName = name.toUpperCase();
42746    const signature = `PH: ${upperName}=${content}`;
42747
42748    if (this._signatureToName[signature]) {
42749      return this._signatureToName[signature];
42750    }
42751
42752    const uniqueName = this._generateUniqueName(upperName);
42753
42754    this._signatureToName[signature] = uniqueName;
42755    return uniqueName;
42756  }
42757
42758  getUniquePlaceholder(name) {
42759    return this._generateUniqueName(name.toUpperCase());
42760  } // Generate a hash for a tag - does not take attribute order into account
42761
42762
42763  _hashTag(tag, attrs, isVoid) {
42764    const start = `<${tag}`;
42765    const strAttrs = Object.keys(attrs).sort().map(name => ` ${name}=${attrs[name]}`).join('');
42766    const end = isVoid ? '/>' : `></${tag}>`;
42767    return start + strAttrs + end;
42768  }
42769
42770  _hashClosingTag(tag) {
42771    return this._hashTag(`/${tag}`, {}, false);
42772  }
42773
42774  _generateUniqueName(base) {
42775    const seen = this._placeHolderNameCounts.hasOwnProperty(base);
42776
42777    if (!seen) {
42778      this._placeHolderNameCounts[base] = 1;
42779      return base;
42780    }
42781
42782    const id = this._placeHolderNameCounts[base];
42783    this._placeHolderNameCounts[base] = id + 1;
42784    return `${base}_${id}`;
42785  }
42786
42787}
42788/**
42789 * @license
42790 * Copyright Google LLC All Rights Reserved.
42791 *
42792 * Use of this source code is governed by an MIT-style license that can be
42793 * found in the LICENSE file at https://angular.io/license
42794 */
42795
42796
42797const _expParser = new Parser$1(new Lexer());
42798/**
42799 * Returns a function converting html nodes to an i18n Message given an interpolationConfig
42800 */
42801
42802
42803function createI18nMessageFactory(interpolationConfig) {
42804  const visitor = new _I18nVisitor(_expParser, interpolationConfig);
42805  return (nodes, meaning, description, customId, visitNodeFn) => visitor.toI18nMessage(nodes, meaning, description, customId, visitNodeFn);
42806}
42807
42808function noopVisitNodeFn(_html, i18n) {
42809  return i18n;
42810}
42811
42812class _I18nVisitor {
42813  constructor(_expressionParser, _interpolationConfig) {
42814    this._expressionParser = _expressionParser;
42815    this._interpolationConfig = _interpolationConfig;
42816  }
42817
42818  toI18nMessage(nodes, meaning = '', description = '', customId = '', visitNodeFn) {
42819    const context = {
42820      isIcu: nodes.length == 1 && nodes[0] instanceof Expansion,
42821      icuDepth: 0,
42822      placeholderRegistry: new PlaceholderRegistry(),
42823      placeholderToContent: {},
42824      placeholderToMessage: {},
42825      visitNodeFn: visitNodeFn || noopVisitNodeFn
42826    };
42827    const i18nodes = visitAll(this, nodes, context);
42828    return new Message(i18nodes, context.placeholderToContent, context.placeholderToMessage, meaning, description, customId);
42829  }
42830
42831  visitElement(el, context) {
42832    const children = visitAll(this, el.children, context);
42833    const attrs = {};
42834    el.attrs.forEach(attr => {
42835      // Do not visit the attributes, translatable ones are top-level ASTs
42836      attrs[attr.name] = attr.value;
42837    });
42838    const isVoid = getHtmlTagDefinition(el.name).isVoid;
42839    const startPhName = context.placeholderRegistry.getStartTagPlaceholderName(el.name, attrs, isVoid);
42840    context.placeholderToContent[startPhName] = {
42841      text: el.startSourceSpan.toString(),
42842      sourceSpan: el.startSourceSpan
42843    };
42844    let closePhName = '';
42845
42846    if (!isVoid) {
42847      closePhName = context.placeholderRegistry.getCloseTagPlaceholderName(el.name);
42848      context.placeholderToContent[closePhName] = {
42849        text: `</${el.name}>`,
42850        sourceSpan: el.endSourceSpan ?? el.sourceSpan
42851      };
42852    }
42853
42854    const node = new TagPlaceholder(el.name, attrs, startPhName, closePhName, children, isVoid, el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
42855    return context.visitNodeFn(el, node);
42856  }
42857
42858  visitAttribute(attribute, context) {
42859    const node = attribute.valueTokens === undefined || attribute.valueTokens.length === 1 ? new Text$2(attribute.value, attribute.valueSpan || attribute.sourceSpan) : this._visitTextWithInterpolation(attribute.valueTokens, attribute.valueSpan || attribute.sourceSpan, context, attribute.i18n);
42860    return context.visitNodeFn(attribute, node);
42861  }
42862
42863  visitText(text, context) {
42864    const node = text.tokens.length === 1 ? new Text$2(text.value, text.sourceSpan) : this._visitTextWithInterpolation(text.tokens, text.sourceSpan, context, text.i18n);
42865    return context.visitNodeFn(text, node);
42866  }
42867
42868  visitComment(comment, context) {
42869    return null;
42870  }
42871
42872  visitExpansion(icu, context) {
42873    context.icuDepth++;
42874    const i18nIcuCases = {};
42875    const i18nIcu = new Icu(icu.switchValue, icu.type, i18nIcuCases, icu.sourceSpan);
42876    icu.cases.forEach(caze => {
42877      i18nIcuCases[caze.value] = new Container(caze.expression.map(node => node.visit(this, context)), caze.expSourceSpan);
42878    });
42879    context.icuDepth--;
42880
42881    if (context.isIcu || context.icuDepth > 0) {
42882      // Returns an ICU node when:
42883      // - the message (vs a part of the message) is an ICU message, or
42884      // - the ICU message is nested.
42885      const expPh = context.placeholderRegistry.getUniquePlaceholder(`VAR_${icu.type}`);
42886      i18nIcu.expressionPlaceholder = expPh;
42887      context.placeholderToContent[expPh] = {
42888        text: icu.switchValue,
42889        sourceSpan: icu.switchValueSourceSpan
42890      };
42891      return context.visitNodeFn(icu, i18nIcu);
42892    } // Else returns a placeholder
42893    // ICU placeholders should not be replaced with their original content but with the their
42894    // translations.
42895    // TODO(vicb): add a html.Node -> i18n.Message cache to avoid having to re-create the msg
42896
42897
42898    const phName = context.placeholderRegistry.getPlaceholderName('ICU', icu.sourceSpan.toString());
42899    context.placeholderToMessage[phName] = this.toI18nMessage([icu], '', '', '', undefined);
42900    const node = new IcuPlaceholder(i18nIcu, phName, icu.sourceSpan);
42901    return context.visitNodeFn(icu, node);
42902  }
42903
42904  visitExpansionCase(_icuCase, _context) {
42905    throw new Error('Unreachable code');
42906  }
42907  /**
42908   * Convert, text and interpolated tokens up into text and placeholder pieces.
42909   *
42910   * @param tokens The text and interpolated tokens.
42911   * @param sourceSpan The span of the whole of the `text` string.
42912   * @param context The current context of the visitor, used to compute and store placeholders.
42913   * @param previousI18n Any i18n metadata associated with this `text` from a previous pass.
42914   */
42915
42916
42917  _visitTextWithInterpolation(tokens, sourceSpan, context, previousI18n) {
42918    // Return a sequence of `Text` and `Placeholder` nodes grouped in a `Container`.
42919    const nodes = []; // We will only create a container if there are actually interpolations,
42920    // so this flag tracks that.
42921
42922    let hasInterpolation = false;
42923
42924    for (const token of tokens) {
42925      switch (token.type) {
42926        case 8
42927        /* TokenType.INTERPOLATION */
42928        :
42929        case 17
42930        /* TokenType.ATTR_VALUE_INTERPOLATION */
42931        :
42932          hasInterpolation = true;
42933          const expression = token.parts[1];
42934          const baseName = extractPlaceholderName(expression) || 'INTERPOLATION';
42935          const phName = context.placeholderRegistry.getPlaceholderName(baseName, expression);
42936          context.placeholderToContent[phName] = {
42937            text: token.parts.join(''),
42938            sourceSpan: token.sourceSpan
42939          };
42940          nodes.push(new Placeholder(expression, phName, token.sourceSpan));
42941          break;
42942
42943        default:
42944          if (token.parts[0].length > 0) {
42945            // This token is text or an encoded entity.
42946            // If it is following on from a previous text node then merge it into that node
42947            // Otherwise, if it is following an interpolation, then add a new node.
42948            const previous = nodes[nodes.length - 1];
42949
42950            if (previous instanceof Text$2) {
42951              previous.value += token.parts[0];
42952              previous.sourceSpan = new ParseSourceSpan(previous.sourceSpan.start, token.sourceSpan.end, previous.sourceSpan.fullStart, previous.sourceSpan.details);
42953            } else {
42954              nodes.push(new Text$2(token.parts[0], token.sourceSpan));
42955            }
42956          }
42957
42958          break;
42959      }
42960    }
42961
42962    if (hasInterpolation) {
42963      // Whitespace removal may have invalidated the interpolation source-spans.
42964      reusePreviousSourceSpans(nodes, previousI18n);
42965      return new Container(nodes, sourceSpan);
42966    } else {
42967      return nodes[0];
42968    }
42969  }
42970
42971}
42972/**
42973 * Re-use the source-spans from `previousI18n` metadata for the `nodes`.
42974 *
42975 * Whitespace removal can invalidate the source-spans of interpolation nodes, so we
42976 * reuse the source-span stored from a previous pass before the whitespace was removed.
42977 *
42978 * @param nodes The `Text` and `Placeholder` nodes to be processed.
42979 * @param previousI18n Any i18n metadata for these `nodes` stored from a previous pass.
42980 */
42981
42982
42983function reusePreviousSourceSpans(nodes, previousI18n) {
42984  if (previousI18n instanceof Message) {
42985    // The `previousI18n` is an i18n `Message`, so we are processing an `Attribute` with i18n
42986    // metadata. The `Message` should consist only of a single `Container` that contains the
42987    // parts (`Text` and `Placeholder`) to process.
42988    assertSingleContainerMessage(previousI18n);
42989    previousI18n = previousI18n.nodes[0];
42990  }
42991
42992  if (previousI18n instanceof Container) {
42993    // The `previousI18n` is a `Container`, which means that this is a second i18n extraction pass
42994    // after whitespace has been removed from the AST nodes.
42995    assertEquivalentNodes(previousI18n.children, nodes); // Reuse the source-spans from the first pass.
42996
42997    for (let i = 0; i < nodes.length; i++) {
42998      nodes[i].sourceSpan = previousI18n.children[i].sourceSpan;
42999    }
43000  }
43001}
43002/**
43003 * Asserts that the `message` contains exactly one `Container` node.
43004 */
43005
43006
43007function assertSingleContainerMessage(message) {
43008  const nodes = message.nodes;
43009
43010  if (nodes.length !== 1 || !(nodes[0] instanceof Container)) {
43011    throw new Error('Unexpected previous i18n message - expected it to consist of only a single `Container` node.');
43012  }
43013}
43014/**
43015 * Asserts that the `previousNodes` and `node` collections have the same number of elements and
43016 * corresponding elements have the same node type.
43017 */
43018
43019
43020function assertEquivalentNodes(previousNodes, nodes) {
43021  if (previousNodes.length !== nodes.length) {
43022    throw new Error('The number of i18n message children changed between first and second pass.');
43023  }
43024
43025  if (previousNodes.some((node, i) => nodes[i].constructor !== node.constructor)) {
43026    throw new Error('The types of the i18n message children changed between first and second pass.');
43027  }
43028}
43029
43030const _CUSTOM_PH_EXP = /\/\/[\s\S]*i18n[\s\S]*\([\s\S]*ph[\s\S]*=[\s\S]*("|')([\s\S]*?)\1[\s\S]*\)/g;
43031
43032function extractPlaceholderName(input) {
43033  return input.split(_CUSTOM_PH_EXP)[2];
43034}
43035/**
43036 * @license
43037 * Copyright Google LLC All Rights Reserved.
43038 *
43039 * Use of this source code is governed by an MIT-style license that can be
43040 * found in the LICENSE file at https://angular.io/license
43041 */
43042
43043/**
43044 * An i18n error.
43045 */
43046
43047
43048class I18nError extends ParseError {
43049  constructor(span, msg) {
43050    super(span, msg);
43051  }
43052
43053}
43054/**
43055 * @license
43056 * Copyright Google LLC All Rights Reserved.
43057 *
43058 * Use of this source code is governed by an MIT-style license that can be
43059 * found in the LICENSE file at https://angular.io/license
43060 */
43061
43062
43063const setI18nRefs = (htmlNode, i18nNode) => {
43064  if (htmlNode instanceof NodeWithI18n) {
43065    if (i18nNode instanceof IcuPlaceholder && htmlNode.i18n instanceof Message) {
43066      // This html node represents an ICU but this is a second processing pass, and the legacy id
43067      // was computed in the previous pass and stored in the `i18n` property as a message.
43068      // We are about to wipe out that property so capture the previous message to be reused when
43069      // generating the message for this ICU later. See `_generateI18nMessage()`.
43070      i18nNode.previousMessage = htmlNode.i18n;
43071    }
43072
43073    htmlNode.i18n = i18nNode;
43074  }
43075
43076  return i18nNode;
43077};
43078/**
43079 * This visitor walks over HTML parse tree and converts information stored in
43080 * i18n-related attributes ("i18n" and "i18n-*") into i18n meta object that is
43081 * stored with other element's and attribute's information.
43082 */
43083
43084
43085class I18nMetaVisitor {
43086  constructor(interpolationConfig = DEFAULT_INTERPOLATION_CONFIG, keepI18nAttrs = false, enableI18nLegacyMessageIdFormat = false) {
43087    this.interpolationConfig = interpolationConfig;
43088    this.keepI18nAttrs = keepI18nAttrs;
43089    this.enableI18nLegacyMessageIdFormat = enableI18nLegacyMessageIdFormat; // whether visited nodes contain i18n information
43090
43091    this.hasI18nMeta = false;
43092    this._errors = []; // i18n message generation factory
43093
43094    this._createI18nMessage = createI18nMessageFactory(this.interpolationConfig);
43095  }
43096
43097  _generateI18nMessage(nodes, meta = '', visitNodeFn) {
43098    const {
43099      meaning,
43100      description,
43101      customId
43102    } = this._parseMetadata(meta);
43103
43104    const message = this._createI18nMessage(nodes, meaning, description, customId, visitNodeFn);
43105
43106    this._setMessageId(message, meta);
43107
43108    this._setLegacyIds(message, meta);
43109
43110    return message;
43111  }
43112
43113  visitAllWithErrors(nodes) {
43114    const result = nodes.map(node => node.visit(this, null));
43115    return new ParseTreeResult(result, this._errors);
43116  }
43117
43118  visitElement(element) {
43119    let message = undefined;
43120
43121    if (hasI18nAttrs(element)) {
43122      this.hasI18nMeta = true;
43123      const attrs = [];
43124      const attrsMeta = {};
43125
43126      for (const attr of element.attrs) {
43127        if (attr.name === I18N_ATTR) {
43128          // root 'i18n' node attribute
43129          const i18n = element.i18n || attr.value;
43130          message = this._generateI18nMessage(element.children, i18n, setI18nRefs);
43131
43132          if (message.nodes.length === 0) {
43133            // Ignore the message if it is empty.
43134            message = undefined;
43135          } // Store the message on the element
43136
43137
43138          element.i18n = message;
43139        } else if (attr.name.startsWith(I18N_ATTR_PREFIX)) {
43140          // 'i18n-*' attributes
43141          const name = attr.name.slice(I18N_ATTR_PREFIX.length);
43142
43143          if (isTrustedTypesSink(element.name, name)) {
43144            this._reportError(attr, `Translating attribute '${name}' is disallowed for security reasons.`);
43145          } else {
43146            attrsMeta[name] = attr.value;
43147          }
43148        } else {
43149          // non-i18n attributes
43150          attrs.push(attr);
43151        }
43152      } // set i18n meta for attributes
43153
43154
43155      if (Object.keys(attrsMeta).length) {
43156        for (const attr of attrs) {
43157          const meta = attrsMeta[attr.name]; // do not create translation for empty attributes
43158
43159          if (meta !== undefined && attr.value) {
43160            attr.i18n = this._generateI18nMessage([attr], attr.i18n || meta);
43161          }
43162        }
43163      }
43164
43165      if (!this.keepI18nAttrs) {
43166        // update element's attributes,
43167        // keeping only non-i18n related ones
43168        element.attrs = attrs;
43169      }
43170    }
43171
43172    visitAll(this, element.children, message);
43173    return element;
43174  }
43175
43176  visitExpansion(expansion, currentMessage) {
43177    let message;
43178    const meta = expansion.i18n;
43179    this.hasI18nMeta = true;
43180
43181    if (meta instanceof IcuPlaceholder) {
43182      // set ICU placeholder name (e.g. "ICU_1"),
43183      // generated while processing root element contents,
43184      // so we can reference it when we output translation
43185      const name = meta.name;
43186      message = this._generateI18nMessage([expansion], meta);
43187      const icu = icuFromI18nMessage(message);
43188      icu.name = name;
43189
43190      if (currentMessage !== null) {
43191        // Also update the placeholderToMessage map with this new message
43192        currentMessage.placeholderToMessage[name] = message;
43193      }
43194    } else {
43195      // ICU is a top level message, try to use metadata from container element if provided via
43196      // `context` argument. Note: context may not be available for standalone ICUs (without
43197      // wrapping element), so fallback to ICU metadata in this case.
43198      message = this._generateI18nMessage([expansion], currentMessage || meta);
43199    }
43200
43201    expansion.i18n = message;
43202    return expansion;
43203  }
43204
43205  visitText(text) {
43206    return text;
43207  }
43208
43209  visitAttribute(attribute) {
43210    return attribute;
43211  }
43212
43213  visitComment(comment) {
43214    return comment;
43215  }
43216
43217  visitExpansionCase(expansionCase) {
43218    return expansionCase;
43219  }
43220  /**
43221   * Parse the general form `meta` passed into extract the explicit metadata needed to create a
43222   * `Message`.
43223   *
43224   * There are three possibilities for the `meta` variable
43225   * 1) a string from an `i18n` template attribute: parse it to extract the metadata values.
43226   * 2) a `Message` from a previous processing pass: reuse the metadata values in the message.
43227   * 4) other: ignore this and just process the message metadata as normal
43228   *
43229   * @param meta the bucket that holds information about the message
43230   * @returns the parsed metadata.
43231   */
43232
43233
43234  _parseMetadata(meta) {
43235    return typeof meta === 'string' ? parseI18nMeta(meta) : meta instanceof Message ? meta : {};
43236  }
43237  /**
43238   * Generate (or restore) message id if not specified already.
43239   */
43240
43241
43242  _setMessageId(message, meta) {
43243    if (!message.id) {
43244      message.id = meta instanceof Message && meta.id || decimalDigest(message);
43245    }
43246  }
43247  /**
43248   * Update the `message` with a `legacyId` if necessary.
43249   *
43250   * @param message the message whose legacy id should be set
43251   * @param meta information about the message being processed
43252   */
43253
43254
43255  _setLegacyIds(message, meta) {
43256    if (this.enableI18nLegacyMessageIdFormat) {
43257      message.legacyIds = [computeDigest(message), computeDecimalDigest(message)];
43258    } else if (typeof meta !== 'string') {
43259      // This occurs if we are doing the 2nd pass after whitespace removal (see `parseTemplate()` in
43260      // `packages/compiler/src/render3/view/template.ts`).
43261      // In that case we want to reuse the legacy message generated in the 1st pass (see
43262      // `setI18nRefs()`).
43263      const previousMessage = meta instanceof Message ? meta : meta instanceof IcuPlaceholder ? meta.previousMessage : undefined;
43264      message.legacyIds = previousMessage ? previousMessage.legacyIds : [];
43265    }
43266  }
43267
43268  _reportError(node, msg) {
43269    this._errors.push(new I18nError(node.sourceSpan, msg));
43270  }
43271
43272}
43273/** I18n separators for metadata **/
43274
43275
43276const I18N_MEANING_SEPARATOR = '|';
43277const I18N_ID_SEPARATOR = '@@';
43278/**
43279 * Parses i18n metas like:
43280 *  - "@@id",
43281 *  - "description[@@id]",
43282 *  - "meaning|description[@@id]"
43283 * and returns an object with parsed output.
43284 *
43285 * @param meta String that represents i18n meta
43286 * @returns Object with id, meaning and description fields
43287 */
43288
43289function parseI18nMeta(meta = '') {
43290  let customId;
43291  let meaning;
43292  let description;
43293  meta = meta.trim();
43294
43295  if (meta) {
43296    const idIndex = meta.indexOf(I18N_ID_SEPARATOR);
43297    const descIndex = meta.indexOf(I18N_MEANING_SEPARATOR);
43298    let meaningAndDesc;
43299    [meaningAndDesc, customId] = idIndex > -1 ? [meta.slice(0, idIndex), meta.slice(idIndex + 2)] : [meta, ''];
43300    [meaning, description] = descIndex > -1 ? [meaningAndDesc.slice(0, descIndex), meaningAndDesc.slice(descIndex + 1)] : ['', meaningAndDesc];
43301  }
43302
43303  return {
43304    customId,
43305    meaning,
43306    description
43307  };
43308} // Converts i18n meta information for a message (id, description, meaning)
43309// to a JsDoc statement formatted as expected by the Closure compiler.
43310
43311
43312function i18nMetaToJSDoc(meta) {
43313  const tags = [];
43314
43315  if (meta.description) {
43316    tags.push({
43317      tagName: "desc"
43318      /* o.JSDocTagName.Desc */
43319      ,
43320      text: meta.description
43321    });
43322  } else {
43323    // Suppress the JSCompiler warning that a `@desc` was not given for this message.
43324    tags.push({
43325      tagName: "suppress"
43326      /* o.JSDocTagName.Suppress */
43327      ,
43328      text: '{msgDescriptions}'
43329    });
43330  }
43331
43332  if (meta.meaning) {
43333    tags.push({
43334      tagName: "meaning"
43335      /* o.JSDocTagName.Meaning */
43336      ,
43337      text: meta.meaning
43338    });
43339  }
43340
43341  return jsDocComment(tags);
43342}
43343/** Closure uses `goog.getMsg(message)` to lookup translations */
43344
43345
43346const GOOG_GET_MSG = 'goog.getMsg';
43347/**
43348 * Generates a `goog.getMsg()` statement and reassignment. The template:
43349 *
43350 * ```html
43351 * <div i18n>Sent from {{ sender }} to <span class="receiver">{{ receiver }}</span></div>
43352 * ```
43353 *
43354 * Generates:
43355 *
43356 * ```typescript
43357 * const MSG_FOO = goog.getMsg(
43358 *   // Message template.
43359 *   'Sent from {$interpolation} to {$startTagSpan}{$interpolation_1}{$closeTagSpan}.',
43360 *   // Placeholder values, set to magic strings which get replaced by the Angular runtime.
43361 *   {
43362 *     'interpolation': '\uFFFD0\uFFFD',
43363 *     'startTagSpan': '\uFFFD1\uFFFD',
43364 *     'interpolation_1': '\uFFFD2\uFFFD',
43365 *     'closeTagSpan': '\uFFFD3\uFFFD',
43366 *   },
43367 *   // Options bag.
43368 *   {
43369 *     // Maps each placeholder to the original Angular source code which generates it's value.
43370 *     original_code: {
43371 *       'interpolation': '{{ sender }}',
43372 *       'startTagSpan': '<span class="receiver">',
43373 *       'interpolation_1': '{{ receiver }}',
43374 *       'closeTagSpan': '</span>',
43375 *     },
43376 *   },
43377 * );
43378 * const I18N_0 = MSG_FOO;
43379 * ```
43380 */
43381
43382function createGoogleGetMsgStatements(variable$1, message, closureVar, placeholderValues) {
43383  const messageString = serializeI18nMessageForGetMsg(message);
43384  const args = [literal(messageString)];
43385
43386  if (Object.keys(placeholderValues).length) {
43387    // Message template parameters containing the magic strings replaced by the Angular runtime with
43388    // real data, e.g. `{'interpolation': '\uFFFD0\uFFFD'}`.
43389    args.push(mapLiteral(formatI18nPlaceholderNamesInMap(placeholderValues, true
43390    /* useCamelCase */
43391    ), true
43392    /* quoted */
43393    )); // Message options object, which contains original source code for placeholders (as they are
43394    // present in a template, e.g.
43395    // `{original_code: {'interpolation': '{{ name }}', 'startTagSpan': '<span>'}}`.
43396
43397    args.push(mapLiteral({
43398      original_code: literalMap(Object.keys(placeholderValues).map(param => ({
43399        key: formatI18nPlaceholderName(param),
43400        quoted: true,
43401        value: message.placeholders[param] ? // Get source span for typical placeholder if it exists.
43402        literal(message.placeholders[param].sourceSpan.toString()) : // Otherwise must be an ICU expression, get it's source span.
43403        literal(message.placeholderToMessage[param].nodes.map(node => node.sourceSpan.toString()).join(''))
43404      })))
43405    }));
43406  } // /**
43407  //  * @desc description of message
43408  //  * @meaning meaning of message
43409  //  */
43410  // const MSG_... = goog.getMsg(..);
43411  // I18N_X = MSG_...;
43412
43413
43414  const googGetMsgStmt = closureVar.set(variable(GOOG_GET_MSG).callFn(args)).toConstDecl();
43415  googGetMsgStmt.addLeadingComment(i18nMetaToJSDoc(message));
43416  const i18nAssignmentStmt = new ExpressionStatement(variable$1.set(closureVar));
43417  return [googGetMsgStmt, i18nAssignmentStmt];
43418}
43419/**
43420 * This visitor walks over i18n tree and generates its string representation, including ICUs and
43421 * placeholders in `{$placeholder}` (for plain messages) or `{PLACEHOLDER}` (inside ICUs) format.
43422 */
43423
43424
43425class GetMsgSerializerVisitor {
43426  formatPh(value) {
43427    return `{$${formatI18nPlaceholderName(value)}}`;
43428  }
43429
43430  visitText(text) {
43431    return text.value;
43432  }
43433
43434  visitContainer(container) {
43435    return container.children.map(child => child.visit(this)).join('');
43436  }
43437
43438  visitIcu(icu) {
43439    return serializeIcuNode(icu);
43440  }
43441
43442  visitTagPlaceholder(ph) {
43443    return ph.isVoid ? this.formatPh(ph.startName) : `${this.formatPh(ph.startName)}${ph.children.map(child => child.visit(this)).join('')}${this.formatPh(ph.closeName)}`;
43444  }
43445
43446  visitPlaceholder(ph) {
43447    return this.formatPh(ph.name);
43448  }
43449
43450  visitIcuPlaceholder(ph, context) {
43451    return this.formatPh(ph.name);
43452  }
43453
43454}
43455
43456const serializerVisitor = new GetMsgSerializerVisitor();
43457
43458function serializeI18nMessageForGetMsg(message) {
43459  return message.nodes.map(node => node.visit(serializerVisitor, null)).join('');
43460}
43461
43462function createLocalizeStatements(variable, message, params) {
43463  const {
43464    messageParts,
43465    placeHolders
43466  } = serializeI18nMessageForLocalize(message);
43467  const sourceSpan = getSourceSpan(message);
43468  const expressions = placeHolders.map(ph => params[ph.text]);
43469  const localizedString$1 = localizedString(message, messageParts, placeHolders, expressions, sourceSpan);
43470  const variableInitialization = variable.set(localizedString$1);
43471  return [new ExpressionStatement(variableInitialization)];
43472}
43473/**
43474 * This visitor walks over an i18n tree, capturing literal strings and placeholders.
43475 *
43476 * The result can be used for generating the `$localize` tagged template literals.
43477 */
43478
43479
43480class LocalizeSerializerVisitor {
43481  constructor(placeholderToMessage, pieces) {
43482    this.placeholderToMessage = placeholderToMessage;
43483    this.pieces = pieces;
43484  }
43485
43486  visitText(text) {
43487    if (this.pieces[this.pieces.length - 1] instanceof LiteralPiece) {
43488      // Two literal pieces in a row means that there was some comment node in-between.
43489      this.pieces[this.pieces.length - 1].text += text.value;
43490    } else {
43491      const sourceSpan = new ParseSourceSpan(text.sourceSpan.fullStart, text.sourceSpan.end, text.sourceSpan.fullStart, text.sourceSpan.details);
43492      this.pieces.push(new LiteralPiece(text.value, sourceSpan));
43493    }
43494  }
43495
43496  visitContainer(container) {
43497    container.children.forEach(child => child.visit(this));
43498  }
43499
43500  visitIcu(icu) {
43501    this.pieces.push(new LiteralPiece(serializeIcuNode(icu), icu.sourceSpan));
43502  }
43503
43504  visitTagPlaceholder(ph) {
43505    this.pieces.push(this.createPlaceholderPiece(ph.startName, ph.startSourceSpan ?? ph.sourceSpan));
43506
43507    if (!ph.isVoid) {
43508      ph.children.forEach(child => child.visit(this));
43509      this.pieces.push(this.createPlaceholderPiece(ph.closeName, ph.endSourceSpan ?? ph.sourceSpan));
43510    }
43511  }
43512
43513  visitPlaceholder(ph) {
43514    this.pieces.push(this.createPlaceholderPiece(ph.name, ph.sourceSpan));
43515  }
43516
43517  visitIcuPlaceholder(ph) {
43518    this.pieces.push(this.createPlaceholderPiece(ph.name, ph.sourceSpan, this.placeholderToMessage[ph.name]));
43519  }
43520
43521  createPlaceholderPiece(name, sourceSpan, associatedMessage) {
43522    return new PlaceholderPiece(formatI18nPlaceholderName(name,
43523    /* useCamelCase */
43524    false), sourceSpan, associatedMessage);
43525  }
43526
43527}
43528/**
43529 * Serialize an i18n message into two arrays: messageParts and placeholders.
43530 *
43531 * These arrays will be used to generate `$localize` tagged template literals.
43532 *
43533 * @param message The message to be serialized.
43534 * @returns an object containing the messageParts and placeholders.
43535 */
43536
43537
43538function serializeI18nMessageForLocalize(message) {
43539  const pieces = [];
43540  const serializerVisitor = new LocalizeSerializerVisitor(message.placeholderToMessage, pieces);
43541  message.nodes.forEach(node => node.visit(serializerVisitor));
43542  return processMessagePieces(pieces);
43543}
43544
43545function getSourceSpan(message) {
43546  const startNode = message.nodes[0];
43547  const endNode = message.nodes[message.nodes.length - 1];
43548  return new ParseSourceSpan(startNode.sourceSpan.fullStart, endNode.sourceSpan.end, startNode.sourceSpan.fullStart, startNode.sourceSpan.details);
43549}
43550/**
43551 * Convert the list of serialized MessagePieces into two arrays.
43552 *
43553 * One contains the literal string pieces and the other the placeholders that will be replaced by
43554 * expressions when rendering `$localize` tagged template literals.
43555 *
43556 * @param pieces The pieces to process.
43557 * @returns an object containing the messageParts and placeholders.
43558 */
43559
43560
43561function processMessagePieces(pieces) {
43562  const messageParts = [];
43563  const placeHolders = [];
43564
43565  if (pieces[0] instanceof PlaceholderPiece) {
43566    // The first piece was a placeholder so we need to add an initial empty message part.
43567    messageParts.push(createEmptyMessagePart(pieces[0].sourceSpan.start));
43568  }
43569
43570  for (let i = 0; i < pieces.length; i++) {
43571    const part = pieces[i];
43572
43573    if (part instanceof LiteralPiece) {
43574      messageParts.push(part);
43575    } else {
43576      placeHolders.push(part);
43577
43578      if (pieces[i - 1] instanceof PlaceholderPiece) {
43579        // There were two placeholders in a row, so we need to add an empty message part.
43580        messageParts.push(createEmptyMessagePart(pieces[i - 1].sourceSpan.end));
43581      }
43582    }
43583  }
43584
43585  if (pieces[pieces.length - 1] instanceof PlaceholderPiece) {
43586    // The last piece was a placeholder so we need to add a final empty message part.
43587    messageParts.push(createEmptyMessagePart(pieces[pieces.length - 1].sourceSpan.end));
43588  }
43589
43590  return {
43591    messageParts,
43592    placeHolders
43593  };
43594}
43595
43596function createEmptyMessagePart(location) {
43597  return new LiteralPiece('', new ParseSourceSpan(location, location));
43598}
43599/**
43600 * @license
43601 * Copyright Google LLC All Rights Reserved.
43602 *
43603 * Use of this source code is governed by an MIT-style license that can be
43604 * found in the LICENSE file at https://angular.io/license
43605 */
43606// Selector attribute name of `<ng-content>`
43607
43608
43609const NG_CONTENT_SELECT_ATTR = 'select'; // Attribute name of `ngProjectAs`.
43610
43611const NG_PROJECT_AS_ATTR_NAME = 'ngProjectAs'; // Global symbols available only inside event bindings.
43612
43613const EVENT_BINDING_SCOPE_GLOBALS = new Set(['$event']); // List of supported global targets for event listeners
43614
43615const GLOBAL_TARGET_RESOLVERS = new Map([['window', Identifiers.resolveWindow], ['document', Identifiers.resolveDocument], ['body', Identifiers.resolveBody]]);
43616const LEADING_TRIVIA_CHARS = [' ', '\n', '\r', '\t']; //  if (rf & flags) { .. }
43617
43618function renderFlagCheckIfStmt(flags, statements) {
43619  return ifStmt(variable(RENDER_FLAGS).bitwiseAnd(literal(flags), null, false), statements);
43620}
43621
43622function prepareEventListenerParameters(eventAst, handlerName = null, scope = null) {
43623  const {
43624    type,
43625    name,
43626    target,
43627    phase,
43628    handler
43629  } = eventAst;
43630
43631  if (target && !GLOBAL_TARGET_RESOLVERS.has(target)) {
43632    throw new Error(`Unexpected global target '${target}' defined for '${name}' event.
43633        Supported list of global targets: ${Array.from(GLOBAL_TARGET_RESOLVERS.keys())}.`);
43634  }
43635
43636  const eventArgumentName = '$event';
43637  const implicitReceiverAccesses = new Set();
43638  const implicitReceiverExpr = scope === null || scope.bindingLevel === 0 ? variable(CONTEXT_NAME) : scope.getOrCreateSharedContextVar(0);
43639  const bindingStatements = convertActionBinding(scope, implicitReceiverExpr, handler, 'b', eventAst.handlerSpan, implicitReceiverAccesses, EVENT_BINDING_SCOPE_GLOBALS);
43640  const statements = [];
43641  const variableDeclarations = scope?.variableDeclarations();
43642  const restoreViewStatement = scope?.restoreViewStatement();
43643
43644  if (variableDeclarations) {
43645    // `variableDeclarations` needs to run first, because
43646    // `restoreViewStatement` depends on the result.
43647    statements.push(...variableDeclarations);
43648  }
43649
43650  statements.push(...bindingStatements);
43651
43652  if (restoreViewStatement) {
43653    statements.unshift(restoreViewStatement); // If there's a `restoreView` call, we need to reset the view at the end of the listener
43654    // in order to avoid a leak. If there's a `return` statement already, we wrap it in the
43655    // call, e.g. `return resetView(ctx.foo())`. Otherwise we add the call as the last statement.
43656
43657    const lastStatement = statements[statements.length - 1];
43658
43659    if (lastStatement instanceof ReturnStatement) {
43660      statements[statements.length - 1] = new ReturnStatement(invokeInstruction(lastStatement.value.sourceSpan, Identifiers.resetView, [lastStatement.value]));
43661    } else {
43662      statements.push(new ExpressionStatement(invokeInstruction(null, Identifiers.resetView, [])));
43663    }
43664  }
43665
43666  const eventName = type === 1
43667  /* ParsedEventType.Animation */
43668  ? prepareSyntheticListenerName(name, phase) : name;
43669  const fnName = handlerName && sanitizeIdentifier(handlerName);
43670  const fnArgs = [];
43671
43672  if (implicitReceiverAccesses.has(eventArgumentName)) {
43673    fnArgs.push(new FnParam(eventArgumentName, DYNAMIC_TYPE));
43674  }
43675
43676  const handlerFn = fn(fnArgs, statements, INFERRED_TYPE, null, fnName);
43677  const params = [literal(eventName), handlerFn];
43678
43679  if (target) {
43680    params.push(literal(false), // `useCapture` flag, defaults to `false`
43681    importExpr(GLOBAL_TARGET_RESOLVERS.get(target)));
43682  }
43683
43684  return params;
43685}
43686
43687function createComponentDefConsts() {
43688  return {
43689    prepareStatements: [],
43690    constExpressions: [],
43691    i18nVarRefsCache: new Map()
43692  };
43693}
43694
43695class TemplateDefinitionBuilder {
43696  constructor(constantPool, parentBindingScope, level = 0, contextName, i18nContext, templateIndex, templateName, _namespace, relativeContextFilePath, i18nUseExternalIds, _constants = createComponentDefConsts()) {
43697    this.constantPool = constantPool;
43698    this.level = level;
43699    this.contextName = contextName;
43700    this.i18nContext = i18nContext;
43701    this.templateIndex = templateIndex;
43702    this.templateName = templateName;
43703    this._namespace = _namespace;
43704    this.i18nUseExternalIds = i18nUseExternalIds;
43705    this._constants = _constants;
43706    this._dataIndex = 0;
43707    this._bindingContext = 0;
43708    this._prefixCode = [];
43709    /**
43710     * List of callbacks to generate creation mode instructions. We store them here as we process
43711     * the template so bindings in listeners are resolved only once all nodes have been visited.
43712     * This ensures all local refs and context variables are available for matching.
43713     */
43714
43715    this._creationCodeFns = [];
43716    /**
43717     * List of callbacks to generate update mode instructions. We store them here as we process
43718     * the template so bindings are resolved only once all nodes have been visited. This ensures
43719     * all local refs and context variables are available for matching.
43720     */
43721
43722    this._updateCodeFns = [];
43723    /** Index of the currently-selected node. */
43724
43725    this._currentIndex = 0;
43726    /** Temporary variable declarations generated from visiting pipes, literals, etc. */
43727
43728    this._tempVariables = [];
43729    /**
43730     * List of callbacks to build nested templates. Nested templates must not be visited until
43731     * after the parent template has finished visiting all of its nodes. This ensures that all
43732     * local ref bindings in nested templates are able to find local ref values if the refs
43733     * are defined after the template declaration.
43734     */
43735
43736    this._nestedTemplateFns = []; // i18n context local to this template
43737
43738    this.i18n = null; // Number of slots to reserve for pureFunctions
43739
43740    this._pureFunctionSlots = 0; // Number of binding slots
43741
43742    this._bindingSlots = 0; // Projection slots found in the template. Projection slots can distribute projected
43743    // nodes based on a selector, or can just use the wildcard selector to match
43744    // all nodes which aren't matching any selector.
43745
43746    this._ngContentReservedSlots = []; // Number of non-default selectors found in all parent templates of this template. We need to
43747    // track it to properly adjust projection slot index in the `projection` instruction.
43748
43749    this._ngContentSelectorsOffset = 0; // Expression that should be used as implicit receiver when convert
43749ing template
43750    // expressions to output AST.
43751
43752    this._implicitReceiverExpr = null; // These should be handled in the template or element directly.
43753
43754    this.visitReference = invalid;
43755    this.visitVariable = invalid;
43756    this.visitTextAttribute = invalid;
43757    this.visitBoundAttribute = invalid;
43758    this.visitBoundEvent = invalid;
43759    this._bindingScope = parentBindingScope.nestedScope(level); // Turn the relative context file path into an identifier by replacing non-alphanumeric
43760    // characters with underscores.
43761
43762    this.fileBasedI18nSuffix = relativeContextFilePath.replace(/[^A-Za-z0-9]/g, '_') + '_';
43763    this._valueConverter = new ValueConverter(constantPool, () => this.allocateDataSlot(), numSlots => this.allocatePureFunctionSlots(numSlots), (name, localName, slot, value) => {
43764      this._bindingScope.set(this.level, localName, value);
43765
43766      this.creationInstruction(null, Identifiers.pipe, [literal(slot), literal(name)]);
43767    });
43768  }
43769
43770  buildTemplateFunction(nodes, variables, ngContentSelectorsOffset = 0, i18n) {
43771    this._ngContentSelectorsOffset = ngContentSelectorsOffset;
43772
43773    if (this._namespace !== Identifiers.namespaceHTML) {
43774      this.creationInstruction(null, this._namespace);
43775    } // Create variable bindings
43776
43777
43778    variables.forEach(v => this.registerContextVariables(v)); // Initiate i18n context in case:
43779    // - this template has parent i18n context
43780    // - or the template has i18n meta associated with it,
43781    //   but it's not initiated by the Element (e.g. <ng-template i18n>)
43782
43783    const initI18nContext = this.i18nContext || isI18nRootNode(i18n) && !isSingleI18nIcu(i18n) && !(isSingleElementTemplate(nodes) && nodes[0].i18n === i18n);
43784    const selfClosingI18nInstruction = hasTextChildrenOnly(nodes);
43785
43786    if (initI18nContext) {
43787      this.i18nStart(null, i18n, selfClosingI18nInstruction);
43788    } // This is the initial pass through the nodes of this template. In this pass, we
43789    // queue all creation mode and update mode instructions for generation in the second
43790    // pass. It's necessary to separate the passes to ensure local refs are defined before
43791    // resolving bindings. We also count bindings in this pass as we walk bound expressions.
43792
43793
43794    visitAll$1(this, nodes); // Add total binding count to pure function count so pure function instructions are
43795    // generated with the correct slot offset when update instructions are processed.
43796
43797    this._pureFunctionSlots += this._bindingSlots; // Pipes are walked in the first pass (to enqueue `pipe()` creation instructions and
43798    // `pipeBind` update instructions), so we have to update the slot offsets manually
43799    // to account for bindings.
43800
43801    this._valueConverter.updatePipeSlotOffsets(this._bindingSlots); // Nested templates must be processed before creation instructions so template()
43802    // instructions can be generated with the correct internal const count.
43803
43804
43805    this._nestedTemplateFns.forEach(buildTemplateFn => buildTemplateFn()); // Output the `projectionDef` instruction when some `<ng-content>` tags are present.
43806    // The `projectionDef` instruction is only emitted for the component template and
43807    // is skipped for nested templates (<ng-template> tags).
43808
43809
43810    if (this.level === 0 && this._ngContentReservedSlots.length) {
43811      const parameters = []; // By default the `projectionDef` instructions creates one slot for the wildcard
43812      // selector if no parameters are passed. Therefore we only want to allocate a new
43813      // array for the projection slots if the default projection slot is not sufficient.
43814
43815      if (this._ngContentReservedSlots.length > 1 || this._ngContentReservedSlots[0] !== '*') {
43816        const r3ReservedSlots = this._ngContentReservedSlots.map(s => s !== '*' ? parseSelectorToR3Selector(s) : s);
43817
43818        parameters.push(this.constantPool.getConstLiteral(asLiteral(r3ReservedSlots), true));
43819      } // Since we accumulate ngContent selectors while processing template elements,
43820      // we *prepend* `projectionDef` to creation instructions block, to put it before
43821      // any `projection` instructions
43822
43823
43824      this.creationInstruction(null, Identifiers.projectionDef, parameters,
43825      /* prepend */
43826      true);
43827    }
43828
43829    if (initI18nContext) {
43830      this.i18nEnd(null, selfClosingI18nInstruction);
43831    } // Generate all the creation mode instructions (e.g. resolve bindings in listeners)
43832
43833
43834    const creationStatements = getInstructionStatements(this._creationCodeFns); // Generate all the update mode instructions (e.g. resolve property or text bindings)
43835
43836    const updateStatements = getInstructionStatements(this._updateCodeFns); //  Variable declaration must occur after binding resolution so we can generate context
43837    //  instructions that build on each other.
43838    // e.g. const b = nextContext().$implicit(); const b = nextContext();
43839
43840    const creationVariables = this._bindingScope.viewSnapshotStatements();
43841
43842    const updateVariables = this._bindingScope.variableDeclarations().concat(this._tempVariables);
43843
43844    const creationBlock = creationStatements.length > 0 ? [renderFlagCheckIfStmt(1
43845    /* core.RenderFlags.Create */
43846    , creationVariables.concat(creationStatements))] : [];
43847    const updateBlock = updateStatements.length > 0 ? [renderFlagCheckIfStmt(2
43848    /* core.RenderFlags.Update */
43849    , updateVariables.concat(updateStatements))] : [];
43850    return fn( // i.e. (rf: RenderFlags, ctx: any)
43851    [new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null)], [// Temporary variable declarations for query refresh (i.e. let _t: any;)
43852    ...this._prefixCode, // Creating mode (i.e. if (rf & RenderFlags.
43852Create) { ... })
43853    ...creationBlock, // Binding and refresh mode (i.e. if (rf & RenderFlags.Update) {...})
43854    ...updateBlock], INFERRED_TYPE, null, this.templateName);
43855  } // LocalResolver
43856
43857
43858  getLocal(name) {
43859    return this._bindingScope.get(name);
43860  } // LocalResolver
43861
43862
43863  notifyImplicitReceiverUse() {
43864    this._bindingScope.notifyImplicitReceiverUse();
43865  } // LocalResolver
43866
43867
43868  maybeRestoreView() {
43869    this._bindingScope.maybeRestoreView();
43870  }
43871
43872  i18nTranslate(message, params = {}, ref, transformFn) {
43873    const _ref = ref || this.i18nGenerateMainBlockVar(); // Closure Compiler requires const names to start with `MSG_` but disallows any other const to
43874    // start with `MSG_`. We define a variable starting with `MSG_` just for the `goog.getMsg` call
43875
43876
43877    const closureVar = this.i18nGenerateClosureVar(message.id);
43878    const statements = getTranslationDeclStmts(message, _ref, closureVar, params, transformFn);
43879
43880    this._constants.prepareStatements.push(...statements);
43881
43882    return _ref;
43883  }
43884
43885  registerContextVariables(variable$1) {
43886    const scopedName = this._bindingScope.freshReferenceName();
43887
43888    const retrievalLevel = this.level;
43889    const lhs = variable(variable$1.name + scopedName);
43890
43891    this._bindingScope.set(retrievalLevel, variable$1.name, lhs, 1
43892    /* DeclarationPriority.CONTEXT */
43893    , (scope, relativeLevel) => {
43894      let rhs;
43895
43896      if (scope.bindingLevel === retrievalLevel) {
43897        if (scope.isListenerScope() && scope.hasRestoreViewVariable()) {
43898          // e.g. restoredCtx.
43899          // We have to get the context from a view reference, if one is available, because
43900          // the context that was passed in during creation may not be correct anymore.
43901          // For more information see: https://github.com/angular/angular/pull/40360.
43902          rhs = variable(RESTORED_VIEW_CONTEXT_NAME);
43903          scope.notifyRestoredViewContextUse();
43904        } else {
43905          // e.g. ctx
43906          rhs = variable(CONTEXT_NAME);
43907        }
43908      } else {
43909        const sharedCtxVar = scope.getSharedContextName(retrievalLevel); // e.g. ctx_r0   OR  x(2);
43910
43911        rhs = sharedCtxVar ? sharedCtxVar : generateNextContextExpr(relativeLevel);
43912      } // e.g. const $item$ = x(2).$implicit;
43913
43914
43915      return [lhs.set(rhs.prop(variable$1.value || IMPLICIT_REFERENCE)).toConstDecl()];
43916    });
43917  }
43918
43919  i18nAppendBindings(expressions) {
43920    if (expressions.length > 0) {
43921      expressions.forEach(expression => this.i18n.appendBinding(expression));
43922    }
43923  }
43924
43925  i18nBindProps(props) {
43926    const bound = {};
43927    Object.keys(props).forEach(key => {
43928      const prop = props[key];
43929
43930      if (prop instanceof Text$3) {
43931        bound[key] = literal(prop.value);
43932      } else {
43933        const value = prop.value.visit(this._valueConverter);
43934        this.allocateBindingSlots(value);
43935
43936        if (value instanceof Interpolation) {
43937          const {
43938            strings,
43939            expressions
43940          } = value;
43941          const {
43942            id,
43943            bindings
43944          } = this.i18n;
43945          const label = assembleI18nBoundString(strings, bindings.size, id);
43946          this.i18nAppendBindings(expressions);
43947          bound[key] = literal(label);
43948        }
43949      }
43950    });
43951    return bound;
43952  } // Generates top level vars for i18n blocks (i.e. `i18n_N`).
43953
43954
43955  i18nGenerateMainBlockVar() {
43956    return variable(this.constantPool.uniqueName(TRANSLATION_VAR_PREFIX));
43957  } // Generates vars with Closure-specific names for i18n blocks (i.e. `MSG_XXX`).
43958
43959
43960  i18nGenerateClosureVar(messageId) {
43961    let name;
43962    const suffix = this.fileBasedI18nSuffix.toUpperCase();
43963
43964    if (this.i18nUseExternalIds) {
43965      const prefix = getTranslationConstPrefix(`EXTERNAL_`);
43966      const uniqueSuffix = this.constantPool.uniqueName(suffix);
43967      name = `${prefix}${sanitizeIdentifier(messageId)}$$${uniqueSuffix}`;
43968    } else {
43969      const prefix = getTranslationConstPrefix(suffix);
43970      name = this.constantPool.uniqueName(prefix);
43971    }
43972
43973    return variable(name);
43974  }
43975
43976  i18nUpdateRef(context) {
43977    const {
43978      icus,
43979      meta,
43980      isRoot,
43981      isResolved,
43982      isEmitted
43983    } = context;
43984
43985    if (isRoot && isResolved && !isEmitted && !isSingleI18nIcu(meta)) {
43986      context.isEmitted = true;
43987      const placeholders = context.getSerializedPlaceholders();
43988      let icuMapping = {};
43989      let params = placeholders.size ? placeholdersToParams(placeholders) : {};
43990
43991      if (icus.size) {
43992        icus.forEach((refs, key) => {
43993          if (refs.length === 1) {
43994            // if we have one ICU defined for a given
43995            // placeholder - just output its reference
43996            params[key] = refs[0];
43997          } else {
43998            // ... otherwise we need to activate post-processing
43999            // to replace ICU placeholders with proper values
44000            const placeholder = wrapI18nPlaceholder(`${I18N_ICU_MAPPING_PREFIX}${key}`);
44001            params[key] = literal(placeholder);
44002            icuMapping[key] = literalArr(refs);
44003          }
44004        });
44005      } // translation requires post processing in 2 cases:
44006      // - if we have placeholders with multiple values (ex. `START_DIV`: [�#1�, �#2�, ...])
44007      // - if we have multiple ICUs that refer to the same placeholder name
44008
44009
44010      const needsPostprocessing = Array.from(placeholders.values()).some(value => value.length > 1) || Object.keys(icuMapping).length;
44011      let transformFn;
44012
44013      if (needsPostprocessing) {
44014        transformFn = raw => {
44015          const args = [raw];
44016
44017          if (Object.keys(icuMapping).length) {
44018            args.push(mapLiteral(icuMapping, true));
44019          }
44020
44021          return invokeInstruction(null, Identifiers.i18nPostprocess, args);
44022        };
44023      }
44024
44025      this.i18nTranslate(meta, params, context.ref, transformFn);
44026    }
44027  }
44028
44029  i18nStart(span = null, meta, selfClosing) {
44030    const index = this.allocateDataSlot();
44031    this.i18n = this.i18nContext ? this.i18nContext.forkChildContext(index, this.templateIndex, meta) : new I18nContext(index, this.i18nGenerateMainBlockVar(), 0, this.templateIndex, meta); // generate i18nStart instruction
44032
44033    const {
44034      id,
44035      ref
44036    } = this.i18n;
44037    const params = [literal(index), this.addToConsts(ref)];
44038
44039    if (id > 0) {
44040      // do not push 3rd argument (sub-block id)
44041      // into i18nStart call for top level i18n context
44042      params.push(literal(id));
44043    }
44044
44045    this.creationInstruction(span, selfClosing ? Identifiers.i18n : Identifiers.i18nStart, params);
44046  }
44047
44048  i18nEnd(span = null, selfClosing) {
44049    if (!this.i18n) {
44050      throw new Error('i18nEnd is executed with no i18n context present');
44051    }
44052
44053    if (this.i18nContext) {
44054      this.i18nContext.reconcileChildContext(this.i18n);
44055      this.i18nUpdateRef(this.i18nContext);
44056    } else {
44057      this.i18nUpdateRef(this.i18n);
44058    } // setup accumulated bindings
44059
44060
44061    const {
44062      index,
44063      bindings
44064    } = this.i18n;
44065
44066    if (bindings.size) {
44067      for (const binding of bindings) {
44068        // for i18n block, advance to the most recent element index (by taking the current number of
44069        // elements and subtracting one) before invoking `i18nExp` instructions, to make sure the
44070        // necessary lifecycle hooks of components/directives are properly flushed.
44071        this.updateInstructionWithAdvance(this.getConstCount() - 1, span, Identifiers.i18nExp, () => this.convertPropertyBinding(binding));
44072      }
44073
44074      this.updateInstruction(span, Identifiers.i18nApply, [literal(index)]);
44075    }
44076
44077    if (!selfClosing) {
44078      this.creationInstruction(span, Identifiers.i18nEnd);
44079    }
44080
44081    this.i18n = null; // reset local i18n context
44082  }
44083
44084  i18nAttributesInstruction(nodeIndex, attrs, sourceSpan) {
44085    let hasBindings = false;
44086    const i18nAttrArgs = [];
44087    attrs.forEach(attr => {
44088      const message = attr.i18n;
44089      const converted = attr.value.visit(this._valueConverter);
44090      this.allocateBindingSlots(converted);
44091
44092      if (converted instanceof Interpolation) {
44093        const placeholders = assembleBoundTextPlaceholders(message);
44094        const params = placeholdersToParams(placeholders);
44095        i18nAttrArgs.push(literal(attr.name), this.i18nTranslate(message, params));
44096        converted.expressions.forEach(expression => {
44097          hasBindings = true;
44098          this.updateInstructionWithAdvance(nodeIndex, sourceSpan, Identifiers.i18nExp, () => this.convertPropertyBinding(expression));
44099        });
44100      }
44101    });
44102
44103    if (i18nAttrArgs.length > 0) {
44104      const index = literal(this.allocateDataSlot());
44105      const constIndex = this.addToConsts(literalArr(i18nAttrArgs));
44106      this.creationInstruction(sourceSpan, Identifiers.i18nAttributes, [index, constIndex]);
44107
44108      if (hasBindings) {
44109        this.updateInstruction(sourceSpan, Identifiers.i18nApply, [index]);
44110      }
44111    }
44112  }
44113
44114  getNamespaceInstruction(namespaceKey) {
44115    switch (namespaceKey) {
44116      case 'math':
44117        return Identifiers.namespaceMathML;
44118
44119      case 'svg':
44120        return Identifiers.namespaceSVG;
44121
44122      default:
44123        return Identifiers.namespaceHTML;
44124    }
44125  }
44126
44127  addNamespaceInstruction(nsInstruction, element) {
44128    this._namespace = nsInstruction;
44129    this.creationInstruction(element.startSourceSpan, nsInstruction);
44130  }
44131  /**
44132   * Adds an update instruction for an interpolated property or attribute, such as
44133   * `prop="{{value}}"` or `attr.title="{{value}}"`
44134   */
44135
44136
44137  interpolatedUpdateInstruction(instruction, elementIndex, attrName, input, value, params) {
44138    this.updateInstructionWithAdvance(elementIndex, input.sourceSpan, instruction, () => [literal(attrName), ...this.getUpdateInstructionArguments(value), ...params]);
44139  }
44140
44141  visitContent(ngContent) {
44142    const slot = this.allocateDataSlot();
44143    const projectionSlotIdx = this._ngContentSelectorsOffset + this._ngContentReservedSlots.length;
44144    const parameters = [literal(slot)];
44145
44146    this._ngContentReservedSlots.push(ngContent.selector);
44147
44148    const nonContentSelectAttributes = ngContent.attributes.filter(attr => attr.name.toLowerCase() !== NG_CONTENT_SELECT_ATTR);
44149    const attributes = this.getAttributeExpressions(ngContent.name, nonContentSelectAttributes, [], []);
44150
44151    if (attributes.length > 0) {
44152      parameters.push(literal(projectionSlotIdx), literalArr(attributes));
44153    } else if (projectionSlotIdx !== 0) {
44154      parameters.push(literal(projectionSlotIdx));
44155    }
44156
44157    this.creationInstruction(ngContent.sourceSpan, Identifiers.projection, parameters);
44158
44159    if (this.i18n) {
44160      this.i18n.appendProjection(ngContent.i18n, slot);
44161    }
44162  }
44163
44164  visitElement(element) {
44165    const elementIndex = this.allocateDataSlot();
44166    const stylingBuilder = new StylingBuilder(null);
44167    let isNonBindableMode = false;
44168    const isI18nRootElement = isI18nRootNode(element.i18n) && !isSingleI18nIcu(element.i18n);
44169    const outputAttrs = [];
44170    const [namespaceKey, elementName] = splitNsName(element.name);
44171    const isNgContainer$1 = isNgContainer(element.name); // Handle styling, i18n, ngNonBindable attributes
44172
44173    for (const attr of element.attributes) {
44174      const {
44175        name,
44176        value
44177      } = attr;
44178
44179      if (name === NON_BINDABLE_ATTR) {
44180        isNonBindableMode = true;
44181      } else if (name === 'style') {
44182        stylingBuilder.registerStyleAttr(value);
44183      } else if (name === 'class') {
44184        stylingBuilder.registerClassAttr(value);
44185      } else {
44186        outputAttrs.push(attr);
44187      }
44188    } // Regular element or ng-container creation mode
44189
44190
44191    const parameters = [literal(elementIndex)];
44192
44193    if (!isNgContainer$1) {
44194      parameters.push(literal(elementName));
44195    } // Add the attributes
44196
44197
44198    const allOtherInputs = [];
44199    const boundI18nAttrs = [];
44200    element.inputs.forEach(input => {
44201      const stylingInputWasSet = stylingBuilder.registerBoundInput(input);
44202
44203      if (!stylingInputWasSet) {
44204        if (input.type === 0
44205        /* BindingType.Property */
44206        && input.i18n) {
44207          boundI18nAttrs.push(input);
44208        } else {
44209          allOtherInputs.push(input);
44210        }
44211      }
44212    }); // add attributes for directive and projection matching purposes
44213
44214    const attributes = this.getAttributeExpressions(element.name, outputAttrs, allOtherInputs, element.outputs, stylingBuilder, [], boundI18nAttrs);
44215    parameters.push(this.addAttrsToConsts(attributes)); // local refs (ex.: <div #foo #bar="baz">)
44216
44217    const refs = this.prepareRefsArray(element.references);
44218    parameters.push(this.addToConsts(refs));
44219    const wasInNamespace = this._namespace;
44220    const currentNamespace = this.getNamespaceInstruction(namespaceKey); // If the namespace is changing now, include an instruction to change it
44221    // during element creation.
44222
44223    if (currentNamespace !== wasInNamespace) {
44224      this.addNamespaceInstruction(currentNamespace, element);
44225    }
44226
44227    if (this.i18n) {
44228      this.i18n.appendElement(element.i18n, elementIndex);
44229    } // Note that we do not append text node instructions and ICUs inside i18n section,
44230    // so we exclude them while calculating whether current element has children
44231
44232
44233    const hasChildren = !isI18nRootElement && this.i18n ? !hasTextChildrenOnly(element.children) : element.children.length > 0;
44234    const createSelfClosingInstruction = !stylingBuilder.hasBindingsWithPipes && element.outputs.length === 0 && boundI18nAttrs.length === 0 && !hasChildren;
44235    const createSelfClosingI18nInstruction = !createSelfClosingInstruction && hasTextChildrenOnly(element.children);
44236
44237    if (createSelfClosingInstruction) {
44238      this.creationInstruction(element.sourceSpan, isNgContainer$1 ? Identifiers.elementContainer : Identifiers.element, trimTrailingNulls(parameters));
44239    } else {
44240      this.creationInstruction(element.startSourceSpan, isNgContainer$1 ? Identifiers.elementContainerStart : Identifiers.elementStart, trimTrailingNulls(parameters));
44241
44242      if (isNonBindableMode) {
44243        this.creationInstruction(element.startSourceSpan, Identifiers.disableBindings);
44244      }
44245
44246      if (boundI18nAttrs.length > 0) {
44247        this.i18nAttributesInstruction(elementIndex, boundI18nAttrs, element.startSourceSpan ?? element.sourceSpan);
44248      } // Generate Listeners (outputs)
44249
44250
44251      if (element.outputs.length > 0) {
44252        for (const outputAst of element.outputs) {
44253          this.creationInstruction(outputAst.sourceSpan, Identifiers.listener, this.prepareListenerParameter(element.name, outputAst, elementIndex));
44254        }
44255      } // Note: it's important to keep i18n/i18nStart instructions after i18nAttributes and
44256      // listeners, to make sure i18nAttributes instruction targets current element at runtime.
44257
44258
44259      if (isI18nRootElement) {
44260        this.i18nStart(element.startSourceSpan, element.i18n, createSelfClosingI18nInstruction);
44261      }
44262    } // the code here will collect all update-level styling instructions and add them to the
44263    // update block of the template function AOT code. Instructions like `styleProp`,
44264    // `styleMap`, `classMap`, `classProp`
44265    // are all generated and assigned in the code below.
44266
44267
44268    const stylingInstructions = stylingBuilder.buildUpdateLevelInstructions(this._valueConverter);
44269    const limit = stylingInstructions.length - 1;
44270
44271    for (let i = 0; i <= limit; i++) {
44272      const instruction = stylingInstructions[i];
44273      this._bindingSlots += this.processStylingUpdateInstruction(elementIndex, instruction);
44274    } // the reason why `undefined` is used is because the renderer understands this as a
44275    // special value to symbolize that there is no RHS to this binding
44276    // TODO (matsko): revisit this once FW-959 is approached
44277
44278
44279    const emptyValueBindInstruction = literal(undefined);
44280    const propertyBindings = [];
44281    const attributeBindings = []; // Generate element input bindings
44282
44283    allOtherInputs.forEach(input => {
44284      const inputType = input.type;
44285
44286      if (inputType === 4
44287      /* BindingType.Animation */
44288      ) {
44289        const value = input.value.visit(this._valueConverter); // animation bindings can be presented in the following formats:
44290        // 1. [@binding]="fooExp"
44291        // 2. [@binding]="{value:fooExp, params:{...}}"
44292        // 3. [@binding]
44293        // 4. @binding
44294        // All formats will be valid for when a synthetic binding is created.
44295        // The reasoning for this is because the renderer should get each
44296        // synthetic binding value in the order of the array that they are
44297        // defined in...
44298
44299        const hasValue = value instanceof LiteralPrimitive ? !!value.value : true;
44300        this.allocateBindingSlots(value);
44301        propertyBindings.push({
44302          span: input.sourceSpan,
44303          paramsOrFn: getBindingFunctionParams(() => hasValue ? this.convertPropertyBinding(value) : emptyValueBindInstruction, prepareSyntheticPropertyName(input.name))
44304        });
44305      } else {
44306        // we must skip attributes with associated i18n context, since these attributes are handled
44307        // separately and corresponding `i18nExp` and `i18nApply` instructions will be generated
44308        if (input.i18n) return;
44309        const value = input.value.visit(this._valueConverter);
44310
44311        if (value !== undefined) {
44312          const params = [];
44313          const [attrNamespace, attrName] = splitNsName(input.name);
44314          const isAttributeBinding = inputType === 1
44315          /* BindingType.Attribute */
44316          ;
44317          const sanitizationRef = resolveSanitizationFn(input.securityContext, isAttributeBinding);
44318          if (sanitizationRef) params.push(sanitizationRef);
44319
44320          if (attrNamespace) {
44321            const namespaceLiteral = literal(attrNamespace);
44322
44323            if (sanitizationRef) {
44324              params.push(namespaceLiteral);
44325            } else {
44326              // If there wasn't a sanitization ref, we need to add
44327              // an extra param so that we can pass in the namespace.
44328              params.push(literal(null), namespaceLiteral);
44329            }
44330          }
44331
44332          this.allocateBindingSlots(value);
44333
44334          if (inputType === 0
44335          /* BindingType.Property */
44336          ) {
44337            if (value instanceof Interpolation) {
44338              // prop="{{value}}" and friends
44339              this.interpolatedUpdateInstruction(getPropertyInterpolationExpression(value), elementIndex, attrName, input, value, params);
44340            } else {
44341              // [prop]="value"
44342              // Collect all the properties so that we can chain into a single function at the end.
44343              propertyBindings.push({
44344                span: input.sourceSpan,
44345                paramsOrFn: getBindingFunctionParams(() => this.convertPropertyBinding(value), attrName, params)
44346              });
44347            }
44348          } else if (inputType === 1
44349          /* BindingType.Attribute */
44350          ) {
44351            if (value instanceof Interpolation && getInterpolationArgsLength(value) > 1) {
44352              // attr.name="text{{value}}" and friends
44353              this.interpolatedUpdateInstruction(getAttributeInterpolationExpression(value), elementIndex, attrName, input, value, params);
44354            } else {
44355              const boundValue = value instanceof Interpolation ? value.expressions[0] : value; // [attr.name]="value" or attr.name="{{value}}"
44356              // Collect the attribute bindings so that they can be chained at the end.
44357
44358              attributeBindings.push({
44359                span: input.sourceSpan,
44360                paramsOrFn: getBindingFunctionParams(() => this.convertPropertyBinding(boundValue), attrName, params)
44361              });
44362            }
44363          } else {
44364            // class prop
44365            this.updateInstructionWithAdvance(elementIndex, input.sourceSpan, Identifiers.classProp, () => {
44366              return [literal(elementIndex), literal(attrName), this.convertPropertyBinding(value), ...params];
44367            });
44368          }
44369        }
44370      }
44371    });
44372
44373    for (const propertyBinding of propertyBindings) {
44374      this.updateInstructionWithAdvance(elementIndex, propertyBinding.span, Identifiers.property, propertyBinding.paramsOrFn);
44375    }
44376
44377    for (const attributeBinding of attributeBindings) {
44378      this.updateInstructionWithAdvance(elementIndex, attributeBinding.span, Identifiers.attribute, attributeBinding.paramsOrFn);
44379    } // Traverse element child nodes
44380
44381
44382    visitAll$1(this, element.children);
44383
44384    if (!isI18nRootElement && this.i18n) {
44385      this.i18n.appendElement(element.i18n, elementIndex, true);
44386    }
44387
44388    if (!createSelfClosingInstruction) {
44389      // Finish element construction mode.
44390      const span = element.endSourceSpan ?? element.sourceSpan;
44391
44392      if (isI18nRootElement) {
44393        this.i18nEnd(span, createSelfClosingI18nInstruction);
44394      }
44395
44396      if (isNonBindableMode) {
44397        this.creationInstruction(span, Identifiers.enableBindings);
44398      }
44399
44400      this.creationInstruction(span, isNgContainer$1 ? Identifiers.elementContainerEnd : Identifiers.elementEnd);
44401    }
44402  }
44403
44404  visitTemplate(template) {
44405    const NG_TEMPLATE_TAG_NAME = 'ng-template';
44406    const templateIndex = this.allocateDataSlot();
44407
44408    if (this.i18n) {
44409      this.i18n.appendTemplate(template.i18n, templateIndex);
44410    }
44411
44412    const tagNameWithoutNamespace = template.tagName ? splitNsName(template.tagName)[1] : template.tagName;
44413    const contextName = `${this.contextName}${template.tagName ? '_' + sanitizeIdentifier(template.tagName) : ''}_${templateIndex}`;
44414    const templateName = `${contextName}_Template`;
44415    const parameters = [literal(templateIndex), variable(templateName), // We don't care about the tag's namespace here, because we infer
44416    // it based on the parent nodes inside the template instruction.
44417    literal(tagNameWithoutNamespace)]; // prepare attributes parameter (including attributes used for directive matching)
44418
44419    const attrsExprs = this.getAttributeExpressions(NG_TEMPLATE_TAG_NAME, template.attributes, template.inputs, template.outputs, undefined
44420    /* styles */
44421    , template.templateAttrs);
44422    parameters.push(this.addAttrsToConsts(attrsExprs)); // local refs (ex.: <ng-template #foo>)
44423
44424    if (template.references && template.references.length) {
44425      const refs = this.prepareRefsArray(template.references);
44426      parameters.push(this.addToConsts(refs));
44427      parameters.push(importExpr(Identifiers.templateRefExtractor));
44428    } // Create the template function
44429
44430
44431    const templateVisitor = new TemplateDefinitionBuilder(this.constantPool, this._bindingScope, this.level + 1, contextName, this.i18n, templateIndex, templateName, this._namespace, this.fileBasedI18nSuffix, this.i18nUseExternalIds, this._constants); // Nested templates must not be visited until after their parent templates have completed
44432    // processing, so they are queued here until after the initial pass. Otherwise, we wouldn't
44433    // be able to support bindings in nested templates to local refs that occur after the
44434    // template definition. e.g. <div *ngIf="showing">{{ foo }}</div>  <div #foo></div>
44435
44436    this._nestedTemplateFns.push(() => {
44437      const templateFunctionExpr = templateVisitor.buildTemplateFunction(template.children, template.variables, this._ngContentReservedSlots.length + this._ngContentSelectorsOffset, template.i18n);
44438      this.constantPool.statements.push(templateFunctionExpr.toDeclStmt(templateName));
44439
44440      if (templateVisitor._ngContentReservedSlots.length) {
44441        this._ngContentReservedSlots.push(...templateVisitor._ngContentReservedSlots);
44442      }
44443    }); // e.g. template(1, MyComp_Template_1)
44444
44445
44446    this.creationInstruction(template.sourceSpan, Identifiers.templateCreate, () => {
44447      parameters.splice(2, 0, literal(templateVisitor.getConstCount()), literal(templateVisitor.getVarCount()));
44448      return trimTrailingNulls(parameters);
44449    }); // handle property bindings e.g. ɵɵproperty('ngForOf', ctx.items), et al;
44450
44451    this.templatePropertyBindings(templateIndex, template.templateAttrs); // Only add normal input/output binding instructions on explicit <ng-template> elements.
44452
44453    if (tagNameWithoutNamespace === NG_TEMPLATE_TAG_NAME) {
44454      const [i18nInputs, inputs] = partitionArray(template.inputs, hasI18nMeta); // Add i18n attributes that may act as inputs to directives. If such attributes are present,
44455      // generate `i18nAttributes` instruction. Note: we generate it only for explicit <ng-template>
44456      // elements, in case of inline templates, corresponding instructions will be generated in the
44457      // nested template function.
44458
44459      if (i18nInputs.length > 0) {
44460        this.i18nAttributesInstruction(templateIndex, i18nInputs, template.startSourceSpan ?? template.sourceSpan);
44461      } // Add the input bindings
44462
44463
44464      if (inputs.length > 0) {
44465        this.templatePropertyBindings(templateIndex, inputs);
44466      } // Generate listeners for directive output
44467
44468
44469      for (const outputAst of template.outputs) {
44470        this.creationInstruction(outputAst.sourceSpan, Identifiers.listener, this.prepareListenerParameter('ng_template', outputAst, templateIndex));
44471      }
44472    }
44473  }
44474
44475  visitBoundText(text) {
44476    if (this.i18n) {
44477      const value = text.value.visit(this._valueConverter);
44478      this.allocateBindingSlots(value);
44479
44480      if (value instanceof Interpolation) {
44481        this.i18n.appendBoundText(text.i18n);
44482        this.i18nAppendBindings(value.expressions);
44483      }
44484
44485      return;
44486    }
44487
44488    const nodeIndex = this.allocateDataSlot();
44489    this.creationInstruction(text.sourceSpan, Identifiers.text, [literal(nodeIndex)]);
44490    const value = text.value.visit(this._valueConverter);
44491    this.allocateBindingSlots(value);
44492
44493    if (value instanceof Interpolation) {
44494      this.updateInstructionWithAdvance(nodeIndex, text.sourceSpan, getTextInterpolationExpression(value), () => this.getUpdateInstructionArguments(value));
44495    } else {
44496      error('Text nodes should be interpolated and never bound directly.');
44497    }
44498  }
44499
44500  visitText(text) {
44501    // when a text element is located within a translatable
44502    // block, we exclude this text element from instructions set,
44503    // since it will be captured in i18n content and processed at runtime
44504    if (!this.i18n) {
44505      this.creationInstruction(text.sourceSpan, Identifiers.text, [literal(this.allocateDataSlot()), literal(text.value)]);
44506    }
44507  }
44508
44509  visitIcu(icu) {
44510    let initWasInvoked = false; // if an ICU was created outside of i18n block, we still treat
44511    // it as a translatable entity and invoke i18nStart and i18nEnd
44512    // to generate i18n context and the necessary instructions
44513
44514    if (!this.i18n) {
44515      initWasInvoked = true;
44516      this.i18nStart(null, icu.i18n, true);
44517    }
44518
44519    const i18n = this.i18n;
44520    const vars = this.i18nBindProps(icu.vars);
44521    const placeholders = this.i18nBindProps(icu.placeholders); // output ICU directly and keep ICU reference in context
44522
44523    const message = icu.i18n; // we always need post-processing function for ICUs, to make sure that:
44524    // - all placeholders in a form of {PLACEHOLDER} are replaced with actual values (note:
44525    // `goog.getMsg` does not process ICUs and uses the `{PLACEHOLDER}` format for placeholders
44526    // inside ICUs)
44527    // - all ICU vars (such as `VAR_SELECT` or `VAR_PLURAL`) are replaced with correct values
44528
44529    const transformFn = raw => {
44530      const params = { ...vars,
44531        ...placeholders
44532      };
44533      const formatted = formatI18nPlaceholderNamesInMap(params,
44534      /* useCamelCase */
44535      false);
44536      return invokeInstruction(null, Identifiers.i18nPostprocess, [raw, mapLiteral(formatted, true)]);
44537    }; // in case the whole i18n message is a single ICU - we do not need to
44538    // create a separate top-level translation, we can use the root ref instead
44539    // and make this ICU a top-level translation
44540    // note: ICU placeholders are replaced with actual values in `i18nPostprocess` function
44541    // separately, so we do not pass placeholders into `i18nTranslate` function.
44542
44543
44544    if (isSingleI18nIcu(i18n.meta)) {
44545      this.i18nTranslate(message,
44546      /* placeholders */
44547      {}, i18n.ref, transformFn);
44548    } else {
44549      // output ICU directly and keep ICU reference in context
44550      const ref = this.i18nTranslate(message,
44551      /* placeholders */
44552      {},
44553      /* ref */
44554      undefined, transformFn);
44555      i18n.appendIcu(icuFromI18nMessage(message).name, ref);
44556    }
44557
44558    if (initWasInvoked) {
44559      this.i18nEnd(null, true);
44560    }
44561
44562    return null;
44563  }
44564
44565  allocateDataSlot() {
44566    return this._dataIndex++;
44567  }
44568
44569  getConstCount() {
44570    return this._dataIndex;
44571  }
44572
44573  getVarCount() {
44574    return this._pureFunctionSlots;
44575  }
44576
44577  getConsts() {
44578    return this._constants;
44579  }
44580
44581  getNgContentSelectors() {
44582    return this._ngContentReservedSlots.length ? this.constantPool.getConstLiteral(asLiteral(this._ngContentReservedSlots), true) : null;
44583  }
44584
44585  bindingContext() {
44586    return `${this._bindingContext++}`;
44587  }
44588
44589  templatePropertyBindings(templateIndex, attrs) {
44590    const propertyBindings = [];
44591
44592    for (const input of attrs) {
44593      if (!(input instanceof BoundAttribute)) {
44594        continue;
44595      }
44596
44597      const value = input.value.visit(this._valueConverter);
44598
44599      if (value === undefined) {
44600        continue;
44601      }
44602
44603      this.allocateBindingSlots(value);
44604
44605      if (value instanceof Interpolation) {
44606        // Params typically contain attribute namespace and value sanitizer, which is applicable
44607        // for regular HTML elements, but not applicable for <ng-template> (since props act as
44608        // inputs to directives), so keep params array empty.
44609        const params = []; // prop="{{value}}" case
44610
44611        this.interpolatedUpdateInstruction(getPropertyInterpolationExpression(value), templateIndex, input.name, input, value, params);
44612      } else {
44613        // [prop]="value" case
44614        propertyBindings.push({
44615          span: input.sourceSpan,
44616          paramsOrFn: getBindingFunctionParams(() => this.convertPropertyBinding(value), input.name)
44617        });
44618      }
44619    }
44620
44621    for (const propertyBinding of propertyBindings) {
44622      this.updateInstructionWithAdvance(templateIndex, propertyBinding.span, Identifiers.property, propertyBinding.paramsOrFn);
44623    }
44624  } // Bindings must only be resolved after all local refs have been visited, so all
44625  // instructions are queued in callbacks that execute once the initial pass has completed.
44626  // Otherwise, we wouldn't be able to support local refs that are defined after their
44627  // bindings. e.g. {{ foo }} <div #foo></div>
44628
44629
44630  instructionFn(fns, span, reference, paramsOrFn, prepend = false) {
44631    fns[prepend ? 'unshift' : 'push']({
44632      span,
44633      reference,
44634      paramsOrFn
44635    });
44636  }
44637
44638  processStylingUpdateInstruction(elementIndex, instruction) {
44639    let allocateBindingSlots = 0;
44640
44641    if (instruction) {
44642      for (const call of instruction.calls) {
44643        allocateBindingSlots += call.allocateBindingSlots;
44644        this.updateInstructionWithAdvance(elementIndex, call.sourceSpan, instruction.reference, () => call.params(value =>
44644 call.supportsInterpolation && value instanceof Interpolation ? this.getUpdateInstructionArguments(value) : this.convertPropertyBinding(value)));
44645      }
44646    }
44647
44648    return allocateBindingSlots;
44649  }
44650
44651  creationInstruction(span, reference, paramsOrFn, prepend) {
44652    this.instructionFn(this._creationCodeFns, span, reference, paramsOrFn || [], prepend);
44653  }
44654
44655  updateInstructionWithAdvance(nodeIndex, span, reference, paramsOrFn) {
44656    this.addAdvanceInstructionIfNecessary(nodeIndex, span);
44657    this.updateInstruction(span, reference, paramsOrFn);
44658  }
44659
44660  updateInstruction(span, reference, paramsOrFn) {
44661    this.instructionFn(this._updateCodeFns, span, reference, paramsOrFn || []);
44662  }
44663
44664  addAdvanceInstructionIfNecessary(nodeIndex, span) {
44665    if (nodeIndex !== this._currentIndex) {
44666      const delta = nodeIndex - this._currentIndex;
44667
44668      if (delta < 1) {
44669        throw new Error('advance instruction can only go forwards');
44670      }
44671
44672      this.instructionFn(this._updateCodeFns, span, Identifiers.advance, [literal(delta)]);
44673      this._currentIndex = nodeIndex;
44674    }
44675  }
44676
44677  allocatePureFunctionSlots(numSlots) {
44678    const originalSlots = this._pureFunctionSlots;
44679    this._pureFunctionSlots += numSlots;
44680    return originalSlots;
44681  }
44682
44683  allocateBindingSlots(value) {
44684    this._bindingSlots += value instanceof Interpolation ? value.expressions.length : 1;
44685  }
44686  /**
44687   * Gets an expression that refers to the implicit receiver. The implicit
44688   * receiver is always the root level context.
44689   */
44690
44691
44692  getImplicitReceiverExpr() {
44693    if (this._implicitReceiverExpr) {
44694      return this._implicitReceiverExpr;
44695    }
44696
44697    return this._implicitReceiverExpr = this.level === 0 ? variable(CONTEXT_NAME) : this._bindingScope.getOrCreateSharedContextVar(0);
44698  }
44699
44700  convertPropertyBinding(value) {
44701    const convertedPropertyBinding = convertPropertyBinding(this, this.getImplicitReceiverExpr(), value, this.bindingContext());
44702    const valExpr = convertedPropertyBinding.currValExpr;
44703
44704    this._tempVariables.push(...convertedPropertyBinding.stmts);
44705
44706    return valExpr;
44707  }
44708  /**
44709   * Gets a list of argument expressions to pass to an update instruction expression. Also updates
44710   * the temp variables state with temp variables that were identified as needing to be created
44711   * while visiting the arguments.
44712   * @param value The original expression we will be resolving an arguments list from.
44713   */
44714
44715
44716  getUpdateInstructionArguments(value) {
44717    const {
44718      args,
44719      stmts
44720    } = convertUpdateArguments(this, this.getImplicitReceiverExpr(), value, this.bindingContext());
44721
44722    this._tempVariables.push(...stmts);
44723
44724    return args;
44725  }
44726  /**
44727   * Prepares all attribute expression values for the `TAttributes` array.
44728   *
44729   * The purpose of this function is to properly construct an attributes array that
44730   * is passed into the `elementStart` (or just `element`) functions. Because there
44731   * are many different types of attributes, the array needs to be constructed in a
44732   * special way so that `elementStart` can properly evaluate them.
44733   *
44734   * The format looks like this:
44735   *
44736   * ```
44737   * attrs = [prop, value, prop2, value2,
44738   *   PROJECT_AS, selector,
44739   *   CLASSES, class1, class2,
44740   *   STYLES, style1, value1, style2, value2,
44741   *   BINDINGS, name1, name2, name3,
44742   *   TEMPLATE, name4, name5, name6,
44743   *   I18N, name7, name8, ...]
44744   * ```
44745   *
44746   * Note that this function will fully ignore all synthetic (@foo) attribute values
44747   * because those values are intended to always be generated as property instructions.
44748   */
44749
44750
44751  getAttributeExpressions(elementName, renderAttributes, inputs, outputs, styles, templateAttrs = [], boundI18nAttrs = []) {
44752    const alreadySeen = new Set();
44753    const attrExprs = [];
44754    let ngProjectAsAttr;
44755
44756    for (const attr of renderAttributes) {
44757      if (attr.name === NG_PROJECT_AS_ATTR_NAME) {
44758        ngProjectAsAttr = attr;
44759      } // Note that static i18n attributes aren't in the i18n array,
44760      // because they're treated in the same way as regular attributes.
44761
44762
44763      if (attr.i18n) {
44764        // When i18n attributes are present on elements with structural directives
44765        // (e.g. `<div *ngIf title="Hello" i18n-title>`), we want to avoid generating
44766        // duplicate i18n translation blocks for `ɵɵtemplate` and `ɵɵelement` instruction
44767        // attributes. So we do a cache lookup to see if suitable i18n translation block
44768        // already exists.
44769        const {
44770          i18nVarRefsCache
44771        } = this._constants;
44772        let i18nVarRef;
44773
44774        if (i18nVarRefsCache.has(attr.i18n)) {
44775          i18nVarRef = i18nVarRefsCache.get(attr.i18n);
44776        } else {
44777          i18nVarRef = this.i18nTranslate(attr.i18n);
44778          i18nVarRefsCache.set(attr.i18n, i18nVarRef);
44779        }
44780
44781        attrExprs.push(literal(attr.name), i18nVarRef);
44782      } else {
44783        attrExprs.push(...getAttributeNameLiterals(attr.name), trustedConstAttribute(elementName, attr));
44784      }
44785    } // Keep ngProjectAs next to the other name, value pairs so we can verify that we match
44786    // ngProjectAs marker in the attribute name slot.
44787
44788
44789    if (ngProjectAsAttr) {
44790      attrExprs.push(...getNgProjectAsLiteral(ngProjectAsAttr));
44791    }
44792
44793    function addAttrExpr(key, value) {
44794      if (typeof key === 'string') {
44795        if (!alreadySeen.has(key)) {
44796          attrExprs.push(...getAttributeNameLiterals(key));
44797          value !== undefined && attrExprs.push(value);
44798          alreadySeen.add(key);
44799        }
44800      } else {
44801        attrExprs.push(literal(key));
44802      }
44803    } // it's important that this occurs before BINDINGS and TEMPLATE because once `elementStart`
44804    // comes across the BINDINGS or TEMPLATE markers then it will continue reading each value as
44805    // as single property value cell by cell.
44806
44807
44808    if (styles) {
44809      styles.populateInitialStylingAttrs(attrExprs);
44810    }
44811
44812    if (inputs.length || outputs.length) {
44813      const attrsLengthBeforeInputs = attrExprs.length;
44814
44815      for (let i = 0; i < inputs.length; i++) {
44816        const input = inputs[i]; // We don't want the animation and attribute bindings in the
44817        // attributes array since they aren't used for directive matching.
44818
44819        if (input.type !== 4
44820        /* BindingType.Animation */
44821        && input.type !== 1
44822        /* BindingType.Attribute */
44823        ) {
44824          addAttrExpr(input.name);
44825        }
44826      }
44827
44828      for (let i = 0; i < outputs.length; i++) {
44829        const output = outputs[i];
44830
44831        if (output.type !== 1
44832        /* ParsedEventType.Animation */
44833        ) {
44834          addAttrExpr(output.name);
44835        }
44836      } // this is a cheap way of adding the marker only after all the input/output
44837      // values have been filtered (by not including the animation ones) and added
44838      // to the expressions. The marker is important because it tells the runtime
44839      // code that this is where attributes without values start...
44840
44841
44842      if (attrExprs.length !== attrsLengthBeforeInputs) {
44843        attrExprs.splice(attrsLengthBeforeInputs, 0, literal(3
44844        /* core.AttributeMarker.Bindings */
44845        ));
44846      }
44847    }
44848
44849    if (templateAttrs.length) {
44850      attrExprs.push(literal(4
44851      /* core.AttributeMarker.Template */
44852      ));
44853      templateAttrs.forEach(attr => addAttrExpr(attr.name));
44854    }
44855
44856    if (boundI18nAttrs.length) {
44857      attrExprs.push(literal(6
44858      /* core.AttributeMarker.I18n */
44859      ));
44860      boundI18nAttrs.forEach(attr => addAttrExpr(attr.name));
44861    }
44862
44863    return attrExprs;
44864  }
44865
44866  addToConsts(expression) {
44867    if (isNull(expression)) {
44868      return TYPED_NULL_EXPR;
44869    }
44870
44871    const consts = this._constants.constExpressions; // Try to reuse a literal that's already in the array, if possible.
44872
44873    for (let i = 0; i < consts.length; i++) {
44874      if (consts[i].isEquivalent(expression)) {
44875        return literal(i);
44876      }
44877    }
44878
44879    return literal(consts.push(expression) - 1);
44880  }
44881
44882  addAttrsToConsts(attrs) {
44883    return attrs.length > 0 ? this.addToConsts(literalArr(attrs)) : TYPED_NULL_EXPR;
44884  }
44885
44886  prepareRefsArray(references) {
44887    if (!references || references.length === 0) {
44888      return TYPED_NULL_EXPR;
44889    }
44890
44891    const refsParam = flatten(references.map(reference => {
44892      const slot = this.allocateDataSlot(); // Generate the update temporary.
44893
44894      const variableName = this._bindingScope.freshReferenceName();
44895
44896      const retrievalLevel = this.level;
44897      const lhs = variable(variableName);
44898
44899      this._bindingScope.set(retrievalLevel, reference.name, lhs, 0
44900      /* DeclarationPriority.DEFAULT */
44901      , (scope, relativeLevel) => {
44902        // e.g. nextContext(2);
44903        const nextContextStmt = relativeLevel > 0 ? [generateNextContextExpr(relativeLevel).toStmt()] : []; // e.g. const $foo$ = reference(1);
44904
44905        const refExpr = lhs.set(importExpr(Identifiers.reference).callFn([literal(slot)]));
44906        return nextContextStmt.concat(refExpr.toConstDecl());
44907      }, true);
44908
44909      return [reference.name, reference.value];
44910    }));
44911    return asLiteral(refsParam);
44912  }
44913
44914  prepareListenerParameter(tagName, outputAst, index) {
44915    return () => {
44916      const eventName = outputAst.name;
44917      const bindingFnName = outputAst.type === 1
44918      /* ParsedEventType.Animation */
44919      ? // synthetic @listener.foo values are treated the exact same as are standard listeners
44920      prepareSyntheticListenerFunctionName(eventName, outputAst.phase) : sanitizeIdentifier(eventName);
44921      const handlerName = `${this.templateName}_${tagName}_${bindingFnName}_${index}_listener`;
44922
44923      const scope = this._bindingScope.nestedScope(this._bindingScope.bindingLevel, EVENT_BINDING_SCOPE_GLOBALS);
44924
44925      return prepareEventListenerParameters(outputAst, handlerName, scope);
44926    };
44927  }
44928
44929}
44930
44931class ValueConverter extends AstMemoryEfficientTransformer {
44932  constructor(constantPool, allocateSlot, allocatePureFunctionSlots, definePipe) {
44933    super();
44934    this.constantPool = constantPool;
44935    this.allocateSlot = allocateSlot;
44936    this.allocatePureFunctionSlots = allocatePureFunctionSlots;
44937    this.definePipe = definePipe;
44938    this._pipeBindExprs = [];
44939  } // AstMemoryEfficientTransformer
44940
44941
44942  visitPipe(pipe, context) {
44943    // Allocate a slot to create the pipe
44944    const slot = this.allocateSlot();
44945    const slotPseudoLocal = `PIPE:${slot}`; // Allocate one slot for the result plus one slot per pipe argument
44946
44947    const pureFunctionSlot = this.allocatePureFunctionSlots(2 + pipe.args.length);
44948    const target = new PropertyRead(pipe.span, pipe.sourceSpan, pipe.nameSpan, new ImplicitReceiver(pipe.span, pipe.sourceSpan), slotPseudoLocal);
44949    const {
44950      identifier,
44951      isVarLength
44952    } = pipeBindingCallInfo(pipe.args);
44953    this.definePipe(pipe.name, slotPseudoLocal, slot, importExpr(identifier));
44954    const args = [pipe.exp, ...pipe.args];
44955    const convertedArgs = isVarLength ? this.visitAll([new LiteralArray(pipe.span, pipe.sourceSpan, args)]) : this.visitAll(args);
44956    const pipeBindExpr = new Call(pipe.span, pipe.sourceSpan, target, [new LiteralPrimitive(pipe.span, pipe.sourceSpan, slot), new LiteralPrimitive(pipe.span, pipe.sourceSpan, pureFunctionSlot), ...convertedArgs], null);
44957
44958    this._pipeBindExprs.push(pipeBindExpr);
44959
44960    return pipeBindExpr;
44961  }
44962
44963  updatePipeSlotOffsets(bindingSlots) {
44964    this._pipeBindExprs.forEach(pipe => {
44965      // update the slot offset arg (index 1) to account for binding slots
44966      const slotOffset = pipe.args[1];
44967      slotOffset.value += bindingSlots;
44968    });
44969  }
44970
44971  visitLiteralArray(array, context) {
44972    return new BuiltinFunctionCall(array.span, array.sourceSpan, this.visitAll(array.expressions), values => {
44973      // If the literal has calculated (non-literal) elements transform it into
44974      // calls to literal factories that compose the literal and will cache intermediate
44975      // values.
44976      const literal = literalArr(values);
44977      return getLiteralFactory(this.constantPool, literal, this.allocatePureFunctionSlots);
44978    });
44979  }
44980
44981  visitLiteralMap(map, context) {
44982    return new BuiltinFunctionCall(map.span, map.sourceSpan, this.visitAll(map.values), values => {
44983      // If the literal has calculated (non-literal) elements  transform it into
44984      // calls to literal factories that compose the literal and will cache intermediate
44985      // values.
44986      const literal = literalMap(values.map((value, index) => ({
44987        key: map.keys[index].key,
44988        value,
44989        quoted: map.keys[index].quoted
44990      })));
44991      return getLiteralFactory(this.constantPool, literal, this.allocatePureFunctionSlots);
44992    });
44993  }
44994
44995} // Pipes always have at least one parameter, the value they operate on
44996
44997
44998const pipeBindingIdentifiers = [Identifiers.pipeBind1, Identifiers.pipeBind2, Identifiers.pipeBind3, Identifiers.pipeBind4];
44999
45000function pipeBindingCallInfo(args) {
45001  const identifier = pipeBindingIdentifiers[args.length];
45002  return {
45003    identifier: identifier || Identifiers.pipeBindV,
45004    isVarLength: !identifier
45005  };
45006}
45007
45008const pureFunctionIdentifiers = [Identifiers.pureFunction0, Identifiers.pureFunction1, Identifiers.pureFunction2, Identifiers.pureFunction3, Identifiers.pureFunction4, Identifiers.pureFunction5, Identifiers.pureFunction6, Identifiers.pureFunction7, Identifiers.pureFunction8];
45009
45010function pureFunctionCallInfo(args) {
45011  const identifier = pureFunctionIdentifiers[args.length];
45012  return {
45013    identifier: identifier || Identifiers.pureFunctionV,
45014    isVarLength: !identifier
45015  };
45016} // e.g. x(2);
45017
45018
45019function generateNextContextExpr(relativeLevelDiff) {
45020  return importExpr(Identifiers.nextContext).callFn(relativeLevelDiff > 1 ? [literal(relativeLevelDiff)] : []);
45021}
45022
45023function getLiteralFactory(constantPool, literal$1, allocateSlots) {
45024  const {
45025    literalFactory,
45026    literalFactoryArguments
45027  } = constantPool.getLiteralFactory(literal$1); // Allocate 1 slot for the result plus 1 per argument
45028
45029  const startSlot = allocateSlots(1 + literalFactoryArguments.length);
45030  const {
45031    identifier,
45032    isVarLength
45033  } = pureFunctionCallInfo(literalFactoryArguments); // Literal factories are pure functions that only need to be re-invoked when the parameters
45034  // change.
45035
45036  const args = [literal(startSlot), literalFactory];
45037
45038  if (isVarLength) {
45039    args.push(literalArr(literalFactoryArguments));
45040  } else {
45041    args.push(...literalFactoryArguments);
45042  }
45043
45044  return importExpr(identifier).callFn(args);
45045}
45046/**
45047 * Gets an array of literals that can be added to an expression
45048 * to represent the name and namespace of an attribute. E.g.
45049 * `:xlink:href` turns into `[AttributeMarker.NamespaceURI, 'xlink', 'href']`.
45050 *
45051 * @param name Name of the attribute, including the namespace.
45052 */
45053
45054
45055function getAttributeNameLiterals(name) {
45056  const [attributeNamespace, attributeName] = splitNsName(name);
45057  const nameLiteral = literal(attributeName);
45058
45059  if (attributeNamespace) {
45060    return [literal(0
45061    /* core.AttributeMarker.NamespaceURI */
45062    ), literal(attributeNamespace), nameLiteral];
45063  }
45064
45065  return [nameLiteral];
45066}
45067/** The prefix used to get a shared context in BindingScope's map. */
45068
45069
45070const SHARED_CONTEXT_KEY = '$$shared_ctx$$';
45071
45072class BindingScope {
45073  constructor(bindingLevel = 0, parent = null, globals) {
45074    this.bindingLevel = bindingLevel;
45075    this.parent = parent;
45076    this.globals = globals;
45077    /** Keeps a map from local variables to their BindingData. */
45078
45079    this.map = new Map();
45080    this.referenceNameIndex = 0;
45081    this.restoreViewVariable = null;
45082    this.usesRestoredViewContext = false;
45083
45084    if (globals !== undefined) {
45085      for (const name of globals) {
45086        this.set(0, name, variable(name));
45087      }
45088    }
45089  }
45090
45091  static createRootScope() {
45092    return new BindingScope();
45093  }
45094
45095  get(name) {
45096    let current = this;
45097
45098    while (current) {
45099      let value = current.map.get(name);
45100
45101      if (value != null) {
45102        if (current !== this) {
45103          // make a local copy and reset the `declare` state
45104          value = {
45105            retrievalLevel: value.retrievalLevel,
45106            lhs: value.lhs,
45107            declareLocalCallback: value.declareLocalCallback,
45108            declare: false,
45109            priority: value.priority
45110          }; // Cache the value locally.
45111
45112          this.map.set(name, value); // Possibly generate a shared context var
45113
45114          this.maybeGenerateSharedContextVar(value);
45115          this.maybeRestoreView();
45116        }
45117
45118        if (value.declareLocalCallback && !value.declare) {
45119          value.declare = true;
45120        }
45121
45122        return value.lhs;
45123      }
45124
45125      current = current.parent;
45126    } // If we get to this point, we are looking for a property on the top level component
45127    // - If level === 0, we are on the top and don't need to re-declare `ctx`.
45128    // - If level > 0, we are in an embedded view. We need to retrieve the name of the
45129    // local var we used to store the component context, e.g. const $comp$ = x();
45130
45131
45132    return this.bindingLevel === 0 ? null : this.getComponentProperty(name);
45133  }
45134  /**
45135   * Create a local variable for later reference.
45136   *
45137   * @param retrievalLevel The level from which this value can be retrieved
45138   * @param name Name of the variable.
45139   * @param lhs AST representing the left hand side of the `let lhs = rhs;`.
45140   * @param priority The sorting priority of this var
45141   * @param declareLocalCallback The callback to invoke when declaring this local var
45142   * @param localRef Whether or not this is a local ref
45143   */
45144
45145
45146  set(retrievalLevel, name, lhs, priority = 0
45147  /* DeclarationPriority.DEFAULT */
45148  , declareLocalCallback, localRef) {
45149    if (this.map.has(name)) {
45150      if (localRef) {
45151        // Do not throw an error if it's a local ref and do not update existing value,
45152        // so the first defined ref is always returned.
45153        return this;
45154      }
45155
45156      error(`The name ${name} is already defined in scope to be ${this.map.get(name)}`);
45157    }
45158
45159    this.map.set(name, {
45160      retrievalLevel: retrievalLevel,
45161      lhs: lhs,
45162      declare: false,
45163      declareLocalCallback: declareLocalCallback,
45164      priority: priority
45165    });
45166    return this;
45167  } // Implemented as part of LocalResolver.
45168
45169
45170  getLocal(name) {
45171    return this.get(name);
45172  } // Implemented as part of LocalResolver.
45173
45174
45175  notifyImplicitReceiverUse() {
45176    if (this.bindingLevel !== 0) {
45177      // Since the implicit receiver is accessed in an embedded view, we need to
45178      // ensure that we declare a shared context variable for the current template
45179      // in the update variables.
45180      this.map.get(SHARED_CONTEXT_KEY + 0).declare = true;
45181    }
45182  }
45183
45184  nestedScope(level, globals) {
45185    const newScope = new BindingScope(level, this, globals);
45186    if (level > 0) newScope.generateSharedContextVar(0);
45187    return newScope;
45188  }
45189  /**
45190   * Gets or creates a shared context variable and returns its expression. Note that
45191   * this does not mean that the shared variable will be declared. Variables in the
45192   * binding scope will be only declared if they are used.
45193   */
45194
45195
45196  getOrCreateSharedContextVar(retrievalLevel) {
45197    const bindingKey = SHARED_CONTEXT_KEY + retrievalLevel;
45198
45199    if (!this.map.has(bindingKey)) {
45200      this.generateSharedContextVar(retrievalLevel);
45201    } // Shared context variables are always generated as "ReadVarExpr".
45202
45203
45204    return this.map.get(bindingKey).lhs;
45205  }
45206
45207  getSharedContextName(retrievalLevel) {
45208    const sharedCtxObj = this.map.get(SHARED_CONTEXT_KEY + retrievalLevel); // Shared context variables are always generated as "ReadVarExpr".
45209
45210    return sharedCtxObj && sharedCtxObj.declare ? sharedCtxObj.lhs : null;
45211  }
45212
45213  maybeGenerateSharedContextVar(value) {
45214    if (value.priority === 1
45215    /* DeclarationPriority.CONTEXT */
45216    && value.retrievalLevel < this.bindingLevel) {
45217      const sharedCtxObj = this.map.get(SHARED_CONTEXT_KEY + value.retrievalLevel);
45218
45219      if (sharedCtxObj) {
45220        sharedCtxObj.declare = true;
45221      } else {
45222        this.generateSharedContextVar(value.retrievalLevel);
45223      }
45224    }
45225  }
45226
45227  generateSharedContextVar(retrievalLevel) {
45228    const lhs = variable(CONTEXT_NAME + this.freshReferenceName());
45229    this.map.set(SHARED_CONTEXT_KEY + retrievalLevel, {
45230      retrievalLevel: retrievalLevel,
45231      lhs: lhs,
45232      declareLocalCallback: (scope, relativeLevel) => {
45233        // const ctx_r0 = nextContext(2);
45234        return [lhs.set(generateNextContextExpr(relativeLevel)).toConstDecl()];
45235      },
45236      declare: false,
45237      priority: 2
45238      /* DeclarationPriority.SHARED_CONTEXT */
45239
45240    });
45241  }
45242
45243  getComponentProperty(name) {
45244    const componentValue = this.map.get(SHARED_CONTEXT_KEY + 0);
45245    componentValue.declare = true;
45246    this.maybeRestoreView();
45247    return componentValue.lhs.prop(name);
45248  }
45249
45250  maybeRestoreView() {
45251    // View restoration is required for listener instructions inside embedded views, because
45252    // they only run in creation mode and they can have references to the context object.
45253    // If the context object changes in update mode, the reference will be incorrect, because
45254    // it was established during creation.
45255    if (this.isListenerScope()) {
45256      if (!this.parent.restoreViewVariable) {
45257        // parent saves variable to generate a shared `const $s$ = getCurrentView();` instruction
45258        this.parent.restoreViewVariable = variable(this.parent.freshReferenceName());
45259      }
45260
45261      this.restoreViewVariable = this.parent.restoreViewVariable;
45262    }
45263  }
45264
45265  restoreViewStatement() {
45266    if (this.restoreViewVariable) {
45267      const restoreCall = invokeInstruction(null, Identifiers.restoreView, [this.restoreViewVariable]); // Either `const restoredCtx = restoreView($state$);` or `restoreView($state$);`
45268      // depending on whether it is being used.
45269
45270      return this.usesRestoredViewContext ? variable(RESTORED_VIEW_CONTEXT_NAME).set(restoreCall).toConstDecl() : restoreCall.toStmt();
45271    }
45272
45273    return null;
45274  }
45275
45276  viewSnapshotStatements() {
45277    // const $state$ = getCurrentView();
45278    return this.restoreViewVariable ? [this.restoreViewVariable.set(invokeInstruction(null, Identifiers.getCurrentView, [])).toConstDecl()] : [];
45279  }
45280
45281  isListenerScope() {
45282    return this.parent && this.parent.bindingLevel === this.bindingLevel;
45283  }
45284
45285  variableDeclarations() {
45286    let currentContextLevel = 0;
45287    return Array.from(this.map.values()).filter(value => value.declare).sort((a, b) => b.retrievalLevel - a.retrievalLevel || b.priority - a.priority).reduce((stmts, value) => {
45288      const levelDiff = this.bindingLevel - value.retrievalLevel;
45289      const currStmts = value.declareLocalCallback(this, levelDiff - currentContextLevel);
45290      currentContextLevel = levelDiff;
45291      return stmts.concat(currStmts);
45292    }, []);
45293  }
45294
45295  freshReferenceName() {
45296    let current = this; // Find the top scope as it maintains the global reference count
45297
45298    while (current.parent) current = current.parent;
45299
45300    const ref = `${REFERENCE_PREFIX}${current.referenceNameIndex++}`;
45301    return ref;
45302  }
45303
45304  hasRestoreViewVariable() {
45305    return !!this.restoreViewVariable;
45306  }
45307
45308  notifyRestoredViewContextUse() {
45309    this.usesRestoredViewContext = true;
45310  }
45311
45312}
45313/**
45314 * Creates a `CssSelector` given a tag name and a map of attributes
45315 */
45316
45317
45318function createCssSelector(elementName, attributes) {
45319  const cssSelector = new CssSelector();
45320  const elementNameNoNs = splitNsName(elementName)[1];
45321  cssSelector.setElement(elementNameNoNs);
45322  Object.getOwnPropertyNames(attributes).forEach(name => {
45323    const nameNoNs = splitNsName(name)[1];
45324    const value = attributes[name];
45325    cssSelector.addAttribute(nameNoNs, value);
45326
45327    if (name.toLowerCase() === 'class') {
45328      const classes = value.trim().split(/\s+/);
45329      classes.forEach(className => cssSelector.addClassName(className));
45330    }
45331  });
45332  return cssSelector;
45333}
45334/**
45335 * Creates an array of expressions out of an `ngProjectAs` attributes
45336 * which can be added to the instruction parameters.
45337 */
45338
45339
45340function getNgProjectAsLiteral(attribute) {
45341  // Parse the attribute value into a CssSelectorList. Note that we only take the
45342  // first selector, because we don't support multiple selectors in ngProjectAs.
45343  const parsedR3Selector = parseSelectorToR3Selector(attribute.value)[0];
45344  return [literal(5
45345  /* core.AttributeMarker.ProjectAs */
45346  ), asLiteral(parsedR3Selector)];
45347}
45348/**
45349 * Gets the instruction to generate for an interpolated property
45350 * @param interpolation An Interpolation AST
45351 */
45352
45353
45354function getPropertyInterpolationExpression(interpolation) {
45355  switch (getInterpolationArgsLength(interpolation)) {
45356    case 1:
45357      return Identifiers.propertyInterpolate;
45358
45359    case 3:
45360      return Identifiers.propertyInterpolate1;
45361
45362    case 5:
45363      return Identifiers.propertyInterpolate2;
45364
45365    case 7:
45366      return Identifiers.propertyInterpolate3;
45367
45368    case 9:
45369      return Identifiers.propertyInterpolate4;
45370
45371    case 11:
45372      return Identifiers.propertyInterpolate5;
45373
45374    case 13:
45375      return Identifiers.propertyInterpolate6;
45376
45377    case 15:
45378      return Identifiers.propertyInterpolate7;
45379
45380    case 17:
45381      return Identifiers.propertyInterpolate8;
45382
45383    default:
45384      return Identifiers.propertyInterpolateV;
45385  }
45386}
45387/**
45388 * Gets the instruction to generate for an interpolated attribute
45389 * @param interpolation An Interpolation AST
45390 */
45391
45392
45393function getAttributeInterpolationExpression(interpolation) {
45394  switch (getInterpolationArgsLength(interpolation)) {
45395    case 3:
45396      return Identifiers.attributeInterpolate1;
45397
45398    case 5:
45399      return Identifiers.attributeInterpolate2;
45400
45401    case 7:
45402      return Identifiers.attributeInterpolate3;
45403
45404    case 9:
45405      return Identifiers.attributeInterpolate4;
45406
45407    case 11:
45408      return Identifiers.attributeInterpolate5;
45409
45410    case 13:
45411      return Identifiers.attributeInterpolate6;
45412
45413    case 15:
45414      return Identifiers.attributeInterpolate7;
45415
45416    case 17:
45417      return Identifiers.attributeInterpolate8;
45418
45419    default:
45420      return Identifiers.attributeInterpolateV;
45421  }
45422}
45423/**
45424 * Gets the instruction to generate for interpolated text.
45425 * @param interpolation An Interpolation AST
45426 */
45427
45428
45429function getTextInterpolationExpression(interpolation) {
45430  switch (getInterpolationArgsLength(interpolation)) {
45431    case 1:
45432      return Identifiers.textInterpolate;
45433
45434    case 3:
45435      return Identifiers.textInterpolate1;
45436
45437    case 5:
45438      return Identifiers.textInterpolate2;
45439
45440    case 7:
45441      return Identifiers.textInterpolate3;
45442
45443    case 9:
45444      return Identifiers.textInterpolate4;
45445
45446    case 11:
45447      return Identifiers.textInterpolate5;
45448
45449    case 13:
45450      return Identifiers.textInterpolate6;
45451
45452    case 15:
45453      return Identifiers.textInterpolate7;
45454
45455    case 17:
45456      return Identifiers.textInterpolate8;
45457
45458    default:
45459      return Identifiers.textInterpolateV;
45460  }
45461}
45462/**
45463 * Parse a template into render3 `Node`s and additional metadata, with no other dependencies.
45464 *
45465 * @param template text of the template to parse
45466 * @param templateUrl URL to use for source mapping of the parsed template
45467 * @param options options to modify how the template is parsed
45468 */
45469
45470
45471function parseTemplate(template, templateUrl, options = {}) {
45472  const {
45473    interpolationConfig,
45474    preserveWhitespaces,
45475    enableI18nLegacyMessageIdFormat
45476  } = options;
45477  const bindingParser = makeBindingParser(interpolationConfig);
45478  const htmlParser = new HtmlParser();
45479  const parseResult = htmlParser.parse(template, templateUrl, {
45480    leadingTriviaChars: LEADING_TRIVIA_CHARS,
45481    ...options,
45482    tokenizeExpansionForms: true
45483  });
45484
45485  if (!options.alwaysAttemptHtmlToR3AstConversion && parseResult.errors && parseResult.errors.length > 0) {
45486    const parsedTemplate = {
45487      interpolationConfig,
45488      preserveWhitespaces,
45489      errors: parseResult.errors,
45490      nodes: [],
45491      styleUrls: [],
45492      styles: [],
45493      ngContentSelectors: []
45494    };
45495
45496    if (options.collectCommentNodes) {
45497      parsedTemplate.commentNodes = [];
45498    }
45499
45500    return parsedTemplate;
45501  }
45502
45503  let rootNodes = parseResult.rootNodes; // process i18n meta information (scan attributes, generate ids)
45504  // before we run whitespace removal process, because existing i18n
45505  // extraction process (ng extract-i18n) relies on a raw content to generate
45506  // message ids
45507
45508  const i18nMetaVisitor = new I18nMetaVisitor(interpolationConfig,
45509  /* keepI18nAttrs */
45510  !preserveWhitespaces, enableI18nLegacyMessageIdFormat);
45511  const i18nMetaResult = i18nMetaVisitor.visitAllWithErrors(rootNodes);
45512
45513  if (!options.alwaysAttemptHtmlToR3AstConversion && i18nMetaResult.errors && i18nMetaResult.errors.length > 0) {
45514    const parsedTemplate = {
45515      interpolationConfig,
45516      preserveWhitespaces,
45517      errors: i18nMetaResult.errors,
45518      nodes: [],
45519      styleUrls: [],
45520      styles: [],
45521      ngContentSelectors: []
45522    };
45523
45524    if (options.collectCommentNodes) {
45525      parsedTemplate.commentNodes = [];
45526    }
45527
45528    return parsedTemplate;
45529  }
45530
45531  rootNodes = i18nMetaResult.rootNodes;
45532
45533  if (!preserveWhitespaces) {
45534    rootNodes = visitAll(new WhitespaceVisitor(), rootNodes); // run i18n meta visitor again in case whitespaces are removed (because that might affect
45535    // generated i18n message content) and first pass indicated that i18n content is present in a
45536    // template. During this pass i18n IDs generated at the first pass will be preserved, so we can
45537    // mimic existing extraction process (ng extract-i18n)
45538
45539    if (i18nMetaVisitor.hasI18nMeta) {
45540      rootNodes = visitAll(new I18nMetaVisitor(interpolationConfig,
45541      /* keepI18nAttrs */
45542      false), rootNodes);
45543    }
45544  }
45545
45546  const {
45547    nodes,
45548    errors,
45549    styleUrls,
45550    styles,
45551    ngContentSelectors,
45552    commentNodes
45553  } = htmlAstToRender3Ast(rootNodes, bindingParser, {
45554    collectCommentNodes: !!options.collectCommentNodes
45555  });
45556  errors.push(...parseResult.errors, ...i18nMetaResult.errors);
45557  const parsedTemplate = {
45558    interpolationConfig,
45559    preserveWhitespaces,
45560    errors: errors.length > 0 ? errors : null,
45561    nodes,
45562    styleUrls,
45563    styles,
45564    ngContentSelectors
45565  };
45566
45567  if (options.collectCommentNodes) {
45568    parsedTemplate.commentNodes = commentNodes;
45569  }
45570
45571  return parsedTemplate;
45572}
45573
45574const elementRegistry = new DomElementSchemaRegistry();
45575/**
45576 * Construct a `BindingParser` with a default configuration.
45577 */
45578
45579function makeBindingParser(interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
45580  return new BindingParser(new Parser$1(new Lexer()), interpolationConfig, elementRegistry, []);
45581}
45582
45583function resolveSanitizationFn(context, isAttribute) {
45584  switch (context) {
45585    case SecurityContext.HTML:
45586      return importExpr(Identifiers.sanitizeHtml);
45587
45588    case SecurityContext.SCRIPT:
45589      return importExpr(Identifiers.sanitizeScript);
45590
45591    case SecurityContext.STYLE:
45592      // the compiler does not fill in an instruction for [style.prop?] binding
45593      // values because the style algorithm knows internally what props are subject
45594      // to sanitization (only [attr.style] values are explicitly sanitized)
45595      return isAttribute ? importExpr(Identifiers.sanitizeStyle) : null;
45596
45597    case SecurityContext.URL:
45598      return importExpr(Identifiers.sanitizeUrl);
45599
45600    case SecurityContext.RESOURCE_URL:
45601      return importExpr(Identifiers.sanitizeResourceUrl);
45602
45603    default:
45604      return null;
45605  }
45606}
45607
45608function trustedConstAttribute(tagName, attr) {
45609  const value = asLiteral(attr.value);
45610
45611  if (isTrustedTypesSink(tagName, attr.name)) {
45612    switch (elementRegistry.securityContext(tagName, attr.name,
45613    /* isAttribute */
45614    true)) {
45615      case SecurityContext.HTML:
45616        return taggedTemplate(importExpr(Identifiers.trustConstantHtml), new TemplateLiteral([new TemplateLiteralElement(attr.value)], []), undefined, attr.valueSpan);
45617      // NB: no SecurityContext.SCRIPT here, as the corresponding tags are stripped by the compiler.
45618
45619      case SecurityContext.RESOURCE_URL:
45620        return taggedTemplate(importExpr(Identifiers.trustConstantResourceUrl), new TemplateLiteral([new TemplateLiteralElement(attr.value)], []), undefined, attr.valueSpan);
45621
45622      default:
45623        return value;
45624    }
45625  } else {
45626    return value;
45627  }
45628}
45629
45630function isSingleElementTemplate(children) {
45631  return children.length === 1 && children[0] instanceof Element$1;
45632}
45633
45634function isTextNode(node) {
45635  return node instanceof Text$3 || node instanceof BoundText || node instanceof Icu$1;
45636}
45637
45638function hasTextChildrenOnly(children) {
45639  return children.every(isTextNode);
45640}
45641
45642function getBindingFunctionParams(deferredParams, name, eagerParams) {
45643  return () => {
45644    const value = deferredParams();
45645    const fnParams = Array.isArray(value) ? value : [value];
45646
45647    if (eagerParams) {
45648      fnParams.push(...eagerParams);
45649    }
45650
45651    if (name) {
45652      // We want the property name to always be the first function parameter.
45653      fnParams.unshift(literal(name));
45654    }
45655
45656    return fnParams;
45657  };
45658}
45659/** Name of the global variable that is used to determine if we use Closure translations or not */
45660
45661
45662const NG_I18N_CLOSURE_MODE = 'ngI18nClosureMode';
45663/**
45664 * Generate statements that define a given translation message.
45665 *
45666 * ```
45667 * var I18N_1;
45668 * if (typeof ngI18nClosureMode !== undefined && ngI18nClosureMode) {
45669 *     var MSG_EXTERNAL_XXX = goog.getMsg(
45670 *          "Some message with {$interpolation}!",
45671 *          { "interpolation": "\uFFFD0\uFFFD" }
45672 *     );
45673 *     I18N_1 = MSG_EXTERNAL_XXX;
45674 * }
45675 * else {
45676 *     I18N_1 = $localize`Some message with ${'\uFFFD0\uFFFD'}!`;
45677 * }
45678 * ```
45679 *
45680 * @param message The original i18n AST message node
45681 * @param variable The variable that will be assigned the translation, e.g. `I18N_1`.
45682 * @param closureVar The variable for Closure `goog.getMsg` calls, e.g. `MSG_EXTERNAL_XXX`.
45683 * @param params Object mapping placeholder names to their values (e.g.
45684 * `{ "interpolation": "\uFFFD0\uFFFD" }`).
45685 * @param transformFn Optional transformation function that will be applied to the translation (e.g.
45686 * post-processing).
45687 * @returns An array of statements that defined a given translation.
45688 */
45689
45690function getTranslationDeclStmts(message, variable, closureVar, params = {}, transformFn) {
45691  const statements = [declareI18nVariable(variable), ifStmt(createClosureModeGuard(), createGoogleGetMsgStatements(variable, message, closureVar, params), createLocalizeStatements(variable, message, formatI18nPlaceholderNamesInMap(params,
45692  /* useCamelCase */
45693  false)))];
45694
45695  if (transformFn) {
45696    statements.push(new ExpressionStatement(variable.set(transformFn(variable))));
45697  }
45698
45699  return statements;
45700}
45701/**
45702 * Create the expression that will be used to guard the closure mode block
45703 * It is equivalent to:
45704 *
45705 * ```
45706 * typeof ngI18nClosureMode !== undefined && ngI18nClosureMode
45707 * ```
45708 */
45709
45710
45711function createClosureModeGuard() {
45712  return typeofExpr(variable(NG_I18N_CLOSURE_MODE)).notIdentical(literal('undefined', STRING_TYPE)).and(variable(NG_I18N_CLOSURE_MODE));
45713}
45714
45715function flatten(list) {
45716  return list.reduce((flat, item) => {
45717    const flatItem = Array.isArray(item) ? flatten(item) : item;
45718    return flat.concat(flatItem);
45719  }, []);
45720}
45721/**
45722 * @license
45723 * Copyright Google LLC All Rights Reserved.
45724 *
45725 * Use of this source code is governed by an MIT-style license that can be
45726 * found in the LICENSE file at https://angular.io/license
45727 */
45728// This regex matches any binding names that contain the "attr." prefix, e.g. "attr.required"
45729// If there is a match, the first matching group will contain the attribute name to bind.
45730
45731
45732const ATTR_REGEX = /attr\.([^\]]+)/;
45733const COMPONENT_VARIABLE = '%COMP%';
45734const HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;
45735const CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;
45736
45737function baseDirectiveFields(meta, constantPool, bindingParser) {
45738  const definitionMap = new DefinitionMap();
45739  const selectors = parseSelectorToR3Selector(meta.selector); // e.g. `type: MyDirective`
45740
45741  definitionMap.set('type', meta.internalType); // e.g. `selectors: [['', 'someDir', '']]`
45742
45743  if (selectors.length > 0) {
45744    definitionMap.set('selectors', asLiteral(selectors));
45745  }
45746
45747  if (meta.queries.length > 0) {
45748    // e.g. `contentQueries: (rf, ctx, dirIndex) => { ... }
45749    definitionMap.set('contentQueries', createContentQueriesFunction(meta.queries, constantPool, meta.name));
45750  }
45751
45752  if (meta.viewQueries.length) {
45753    definitionMap.set('viewQuery', createViewQueriesFunction(meta.viewQueries, constantPool, meta.name));
45754  } // e.g. `hostBindings: (rf, ctx) => { ... }
45755
45756
45757  definitionMap.set('hostBindings', createHostBindingsFunction(meta.host, meta.typeSourceSpan, bindingParser, constantPool, meta.selector || '', meta.name, definitionMap)); // e.g 'inputs: {a: 'a'}`
45758
45759  definitionMap.set('inputs', conditionallyCreateMapObjectLiteral(meta.inputs, true)); // e.g 'outputs: {a: 'a'}`
45760
45761  definitionMap.set('outputs', conditionallyCreateMapObjectLiteral(meta.outputs));
45762
45763  if (meta.exportAs !== null) {
45764    definitionMap.set('exportAs', literalArr(meta.exportAs.map(e => literal(e))));
45765  }
45766
45767  if (meta.isStandalone) {
45768    definitionMap.set('standalone', literal(true));
45769  }
45770
45771  return definitionMap;
45772}
45773/**
45774 * Add features to the definition map.
45775 */
45776
45777
45778function addFeatures(definitionMap, meta) {
45779  // e.g. `features: [NgOnChangesFeature]`
45780  const features = [];
45781  const providers = meta.providers;
45782  const viewProviders = meta.viewProviders;
45783
45784  if (providers || viewProviders) {
45785    const args = [providers || new LiteralArrayExpr([])];
45786
45787    if (viewProviders) {
45788      args.push(viewProviders);
45789    }
45790
45791    features.push(importExpr(Identifiers.ProvidersFeature).callFn(args));
45792  }
45793
45794  if (meta.usesInheritance) {
45795    features.push(importExpr(Identifiers.InheritDefinitionFeature));
45796  }
45797
45798  if (meta.fullInheritance) {
45799    features.push(importExpr(Identifiers.CopyDefinitionFeature));
45800  }
45801
45802  if (meta.lifecycle.usesOnChanges) {
45803    features.push(importExpr(Identifiers.NgOnChangesFeature));
45804  } // TODO: better way of differentiating component vs directive metadata.
45805
45806
45807  if (meta.hasOwnProperty('template') && meta.isStandalone) {
45808    features.push(importExpr(Identifiers.StandaloneFeature));
45809  }
45810
45811  if (features.length) {
45812    definitionMap.set('features', literalArr(features));
45813  }
45814}
45815/**
45816 * Compile a directive for the render3 runtime as defined by the `R3DirectiveMetadata`.
45817 */
45818
45819
45820function compileDirectiveFromMetadata(meta, constantPool, bindingParser) {
45821  const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
45822  addFeatures(definitionMap, meta);
45823  const expression = importExpr(Identifiers.defineDirective).callFn([definitionMap.toLiteralMap()], undefined, true);
45824  const type = createDirectiveType(meta);
45825  return {
45826    expression,
45827    type,
45828    statements: []
45829  };
45830}
45831/**
45832 * Compile a component for the render3 runtime as defined by the `R3ComponentMetadata`.
45833 */
45834
45835
45836function compileComponentFromMetadata(meta, constantPool, bindingParser) {
45837  const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
45838  addFeatures(definitionMap, meta);
45839  const selector = meta.selector && CssSelector.parse(meta.selector);
45840  const firstSelector = selector && selector[0]; // e.g. `attr: ["class", ".my.app"]`
45841  // This is optional an only included if the first selector of a component specifies attributes.
45842
45843  if (firstSelector) {
45844    const selectorAttributes = firstSelector.getAttrs();
45845
45846    if (selectorAttributes.length) {
45847      definitionMap.set('attrs', constantPool.getConstLiteral(literalArr(selectorAttributes.map(value => value != null ? literal(value) : literal(undefined))),
45848      /* forceShared */
45849      true));
45850    }
45851  } // e.g. `template: function MyComponent_Template(_ctx, _cm) {...}`
45852
45853
45854  const templateTypeName = meta.name;
45855  const templateName = templateTypeName ? `${templateTypeName}_Template` : null;
45856  const changeDetection = meta.changeDetection;
45857  const template = meta.template;
45858  const templateBuilder = new TemplateDefinitionBuilder(constantPool, BindingScope.createRootScope(), 0, templateTypeName, null, null, templateName, Identifiers.namespaceHTML, meta.relativeContextFilePath, meta.i18nUseExternalIds);
45859  const templateFunctionExpression = templateBuilder.buildTemplateFunction(template.nodes, []); // We need to provide this so that dynamically generated components know what
45860  // projected content blocks to pass through to the component when it is instantiated.
45861
45862  const ngContentSelectors = templateBuilder.getNgContentSelectors();
45863
45864  if (ngContentSelectors) {
45865    definitionMap.set('ngContentSelectors', ngContentSelectors);
45866  } // e.g. `decls: 2`
45867
45868
45869  definitionMap.set('decls', literal(templateBuilder.getConstCount())); // e.g. `vars: 2`
45870
45871  definitionMap.set('vars', literal(templateBuilder.getVarCount())); // Generate `consts` section of ComponentDef:
45872  // - either as an array:
45873  //   `consts: [['one', 'two'], ['three', 'four']]`
45874  // - or as a factory function in case additional statements are present (to support i18n):
45875  //   `consts: function() { var i18n_0; if (ngI18nClosureMode) {...} else {...} return [i18n_0]; }`
45876
45877  const {
45878    constExpressions,
45879    prepareStatements
45880  } = templateBuilder.getConsts();
45881
45882  if (constExpressions.length > 0) {
45883    let constsExpr = literalArr(constExpressions); // Prepare statements are present - turn `consts` into a function.
45884
45885    if (prepareStatements.length > 0) {
45886      constsExpr = fn([], [...prepareStatements, new ReturnStatement(constsExpr)]);
45887    }
45888
45889    definitionMap.set('consts', constsExpr);
45890  }
45891
45892  definitionMap.set('template', templateFunctionExpression);
45893
45894  if (meta.declarations.length > 0) {
45895    definitionMap.set('dependencies', compileDeclarationList(literalArr(meta.declarations.map(decl => decl.type)), meta.declarationListEmitMode));
45896  }
45897
45898  if (meta.encapsulation === null) {
45899    meta.encapsulation = ViewEncapsulation.Emulated;
45900  } // e.g. `styles: [str1, str2]`
45901
45902
45903  if (meta.styles && meta.styles.length) {
45904    const styleValues = meta.encapsulation == ViewEncapsulation.Emulated ? compileStyles(meta.styles, CONTENT_ATTR, HOST_ATTR) : meta.styles;
45905    const styleNodes = styleValues.reduce((result, style) => {
45906      if (style.trim().length > 0) {
45907        result.push(constantPool.getConstLiteral(literal(style)));
45908      }
45909
45910      return result;
45911    }, []);
45912
45913    if (styleNodes.length > 0) {
45914      definitionMap.set('styles', literalArr(styleNodes));
45915    }
45916  } else if (meta.encapsulation === ViewEncapsulation.Emulated) {
45917    // If there is no style, don't generate css selectors on elements
45918    meta.encapsulation = ViewEncapsulation.None;
45919  } // Only set view encapsulation if it's not the default value
45920
45921
45922  if (meta.encapsulation !== ViewEncapsulation.Emulated) {
45923    definitionMap.set('encapsulation', literal(meta.encapsulation));
45924  } // e.g. `animation: [trigger('123', [])]`
45925
45926
45927  if (meta.animations !== null) {
45928    definitionMap.set('data', literalMap([{
45929      key: 'animation',
45930      value: meta.animations,
45931      quoted: false
45932    }]));
45933  } // Only set the change detection flag if it's defined and it's not the default.
45934
45935
45936  if (changeDetection != null && changeDetection !== ChangeDetectionStrategy.Default) {
45937    definitionMap.set('changeDetection', literal(changeDetection));
45938  }
45939
45940  const expression = importExpr(Identifiers.defineComponent).callFn([definitionMap.toLiteralMap()], undefined, true);
45941  const type = createComponentType(meta);
45942  return {
45943    expression,
45944    type,
45945    statements: []
45946  };
45947}
45948/**
45949 * Creates the type specification from the component meta. This type is inserted into .d.ts files
45950 * to be consumed by upstream compilations.
45951 */
45952
45953
45954function createComponentType(meta) {
45955  const typeParams = createBaseDirectiveTypeParams(meta);
45956  typeParams.push(stringArrayAsType(meta.template.ngContentSelectors));
45957  typeParams.push(expressionType(literal(meta.isStandalone)));
45958  return expressionType(importExpr(Identifiers.ComponentDeclaration, typeParams));
45959}
45960/**
45961 * Compiles the array literal of declarations into an expression according to the provided emit
45962 * mode.
45963 */
45964
45965
45966function compileDeclarationList(list, mode) {
45967  switch (mode) {
45968    case 0
45969    /* DeclarationListEmitMode.Direct */
45970    :
45971      // directives: [MyDir],
45972      return list;
45973
45974    case 1
45975    /* DeclarationListEmitMode.Closure */
45976    :
45977      // directives: function () { return [MyDir]; }
45978      return fn([], [new ReturnStatement(list)]);
45979
45980    case 2
45981    /* DeclarationListEmitMode.ClosureResolved */
45982    :
45983      // directives: function () { return [MyDir].map(ng.resolveForwardRef); }
45984      const resolvedList = list.prop('map').callFn([importExpr(Identifiers.resolveForwardRef)]);
45985      return fn([], [new ReturnStatement(resolvedList)]);
45986  }
45987}
45988
45989function prepareQueryParams(query, constantPool) {
45990  const parameters = [getQueryPredicate(query, constantPool), literal(toQueryFlags(query))];
45991
45992  if (query.read) {
45993    parameters.push(query.read);
45994  }
45995
45996  return parameters;
45997}
45998/**
45999 * Translates query flags into `TQueryFlags` type in packages/core/src/render3/interfaces/query.ts
46000 * @param query
46001 */
46002
46003
46004function toQueryFlags(query) {
46005  return (query.descendants ? 1
46006  /* QueryFlags.descendants */
46007  : 0
46008  /* QueryFlags.none */
46009  ) | (query.static ? 2
46010  /* QueryFlags.isStatic */
46011  : 0
46012  /* QueryFlags.none */
46013  ) | (query.emitDistinctChangesOnly ? 4
46014  /* QueryFlags.emitDistinctChangesOnly */
46015  : 0
46016  /* QueryFlags.none */
46017  );
46018}
46019
46020function convertAttributesToExpressions(attributes) {
46021  const values = [];
46022
46023  for (let key of Object.getOwnPropertyNames(attributes)) {
46024    const value = attributes[key];
46025    values.push(literal(key), value);
46026  }
46027
46028  return values;
46029} // Define and update any content queries
46030
46031
46032function createContentQueriesFunction(queries, constantPool, name) {
46033  const createStatements = [];
46034  const updateStatements = [];
46035  const tempAllocator = temporaryAllocator(updateStatements, TEMPORARY_NAME);
46036
46037  for (const query of queries) {
46038    // creation, e.g. r3.contentQuery(dirIndex, somePredicate, true, null);
46039    createStatements.push(importExpr(Identifiers.contentQuery).callFn([variable('dirIndex'), ...prepareQueryParams(query, constantPool)]).toStmt()); // update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp));
46040
46041    const temporary = tempAllocator();
46042    const getQueryList = importExpr(Identifiers.loadQuery).callFn([]);
46043    const refresh = importExpr(Identifiers.queryRefresh).callFn([temporary.set(getQueryList)]);
46044    const updateDirective = variable(CONTEXT_NAME).prop(query.propertyName).set(query.first ? temporary.prop('first') : temporary);
46045    updateStatements.push(refresh.and(updateDirective).toStmt());
46046  }
46047
46048  const contentQueriesFnName = name ? `${name}_ContentQueries` : null;
46049  return fn([new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null), new FnParam('dirIndex', null)], [renderFlagCheckIfStmt(1
46050  /* core.RenderFlags.Create */
46051  , createStatements), renderFlagCheckIfStmt(2
46052  /* core.RenderFlags.Update */
46053  , updateStatements)], INFERRED_TYPE, null, contentQueriesFnName);
46054}
46055
46056function stringAsType(str) {
46057  return expressionType(literal(str));
46058}
46059
46060function stringMapAsType(map) {
46061  const mapValues = Object.keys(map).map(key => {
46062    const value = Array.isArray(map[key]) ? map[key][0] : map[key];
46063    return {
46064      key,
46065      value: literal(value),
46066      quoted: true
46067    };
46068  });
46069  return expressionType(literalMap(mapValues));
46070}
46071
46072function stringArrayAsType(arr) {
46073  return arr.length > 0 ? expressionType(literalArr(arr.map(value => literal(value)))) : NONE_TYPE;
46074}
46075
46076function createBaseDirectiveTypeParams(meta) {
46077  // On the type side, remove newlines from the selector as it will need to fit into a TypeScript
46078  // string literal, which must be on one line.
46079  const selectorForType = meta.selector !== null ? meta.selector.replace(/\n/g, '') : null;
46080  return [typeWithParameters(meta.type.type, meta.typeArgumentCount), selectorForType !== null ? stringAsType(selectorForType) : NONE_TYPE, meta.exportAs !== null ? stringArrayAsType(meta.exportAs) : NONE_TYPE, stringMapAsType(meta.inputs), stringMapAsType(meta.outputs), stringArrayAsType(meta.queries.map(q => q.propertyName))];
46081}
46082/**
46083 * Creates the type specification from the directive meta. This type is inserted into .d.ts files
46084 * to be consumed by upstream compilations.
46085 */
46086
46087
46088function createDirectiveType(meta) {
46089  const typeParams = createBaseDirectiveTypeParams(meta); // Directives have no NgContentSelectors slot, but instead express a `never` type
46090  // so that future fields align.
46091
46092  typeParams.push(NONE_TYPE);
46093  typeParams.push(expressionType(literal(meta.isStandalone)));
46094  return expressionType(importExpr(Identifiers.DirectiveDeclaration, typeParams));
46095} // Define and update any view queries
46096
46097
46098function createViewQueriesFunction(viewQueries, constantPool, name) {
46099  const createStatements = [];
46100  const updateStatements = [];
46101  const tempAllocator = temporaryAllocator(updateStatements, TEMPORARY_NAME);
46102  viewQueries.forEach(query => {
46103    // creation, e.g. r3.viewQuery(somePredicate, true);
46104    const queryDefinition = importExpr(Identifiers.viewQuery).callFn(prepareQueryParams(query, constantPool));
46105    createStatements.push(queryDefinition.toStmt()); // update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp));
46106
46107    const temporary = tempAllocator();
46108    const getQueryList = importExpr(Identifiers.loadQuery).callFn([]);
46109    const refresh = importExpr(Identifiers.queryRefresh).callFn([temporary.set(getQueryList)]);
46110    const updateDirective = variable(CONTEXT_NAME).prop(query.propertyName).set(query.first ? temporary.prop('first') : temporary);
46111    updateStatements.push(refresh.and(updateDirective).toStmt());
46112  });
46113  const viewQueryFnName = name ? `${name}_Query` : null;
46114  return fn([new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null)], [renderFlagCheckIfStmt(1
46115  /* core.RenderFlags.Create */
46116  , createStatements), renderFlagCheckIfStmt(2
46117  /* core.RenderFlags.Update */
46118  , updateStatements)], INFERRED_TYPE, null, viewQueryFnName);
46119} // Return a host binding function or null if one is not necessary.
46120
46121
46122function createHostBindingsFunction(hostBindingsMetadata, typeSourceSpan, bindingParser, constantPool, selector, name, definitionMap) {
46123  const bindingContext = variable(CONTEXT_NAME);
46124  const styleBuilder = new StylingBuilder(bindingContext);
46125  const {
46126    styleAttr,
46127    classAttr
46128  } = hostBindingsMetadata.specialAttributes;
46129
46130  if (styleAttr !== undefined) {
46131    styleBuilder.registerStyleAttr(styleAttr);
46132  }
46133
46134  if (classAttr !== undefined) {
46135    styleBuilder.registerClassAttr(classAttr);
46136  }
46137
46138  const createInstructions = [];
46139  const updateInstructions = [];
46140  const updateVariables = [];
46141  const hostBindingSourceSpan = typeSourceSpan; // Calculate host event bindings
46142
46143  const eventBindings = bindingParser.createDirectiveHostEventAsts(hostBindingsMetadata.listeners, hostBindingSourceSpan);
46144
46145  if (eventBindings && eventBindings.length) {
46146    createInstructions.push(...createHostListeners(eventBindings, name));
46147  } // Calculate the host property bindings
46148
46149
46150  const bindings = bindingParser.createBoundHostProperties(hostBindingsMetadata.properties, hostBindingSourceSpan);
46151  const allOtherBindings = []; // We need to calculate the total amount of binding slots required by
46152  // all the instructions together before any value conversions happen.
46153  // Value conversions may require additional slots for interpolation and
46154  // bindings with pipes. These calculates happen after this block.
46155
46156  let totalHostVarsCount = 0;
46157  bindings && bindings.forEach(binding => {
46158    const stylingInputWasSet = styleBuilder.registerInputBasedOnName(binding.name, binding.expression, hostBindingSourceSpan);
46159
46160    if (stylingInputWasSet) {
46161      totalHostVarsCount += MIN_STYLING_BINDING_SLOTS_REQUIRED;
46162    } else {
46163      allOtherBindings.push(binding);
46164      totalHostVarsCount++;
46165    }
46166  });
46167  let valueConverter;
46168
46169  const getValueConverter = () => {
46170    if (!valueConverter) {
46171      const hostVarsCountFn = numSlots => {
46172        const originalVarsCount = totalHostVarsCount;
46173        totalHostVarsCount += numSlots;
46174        return originalVarsCount;
46175      };
46176
46177      valueConverter = new ValueConverter(constantPool, () => error('Unexpected node'), // new nodes are illegal here
46178      hostVarsCountFn, () => error('Unexpected pipe')); // pipes are illegal here
46179    }
46180
46181    return valueConverter;
46182  };
46183
46184  const propertyBindings = [];
46185  const attributeBindings = [];
46186  const syntheticHostBindings = [];
46187
46188  for (const binding of allOtherBindings) {
46189    // resolve literal arrays and literal objects
46190    const value = binding.expression.visit(getValueConverter());
46191    const bindingExpr = bindingFn(bindingContext, value);
46192    const {
46193      bindingName,
46194      instruction,
46195      isAttribute
46196    } = getBindingNameAndInstruction(binding);
46197    const securityContexts = bindingParser.calcPossibleSecurityContexts(selector, bindingName, isAttribute).filter(context => context !== SecurityContext.NONE);
46198    let sanitizerFn = null;
46199
46200    if (securityContexts.length) {
46201      if (securityContexts.length === 2 && securityContexts.indexOf(SecurityContext.URL) > -1 && securityContexts.indexOf(SecurityContext.RESOURCE_URL) > -1) {
46202        // Special case for some URL attributes (such as "src" and "href") that may be a part
46203        // of different security contexts. In this case we use special sanitization function and
46204        // select the actual sanitizer at runtime based on a tag name that is provided while
46205        // invoking sanitization function.
46206        sanitizerFn = importExpr(Identifiers.sanitizeUrlOrResourceUrl);
46207      } else {
46208        sanitizerFn = resolveSanitizationFn(securityContexts[0], isAttribute);
46209      }
46210    }
46211
46212    const instructionParams = [literal(bindingName), bindingExpr.currValExpr];
46213
46214    if (sanitizerFn) {
46215      instructionParams.push(sanitizerFn);
46216    }
46217
46218    updateVariables.push(...bindingExpr.stmts);
46219
46220    if (instruction === Identifiers.hostProperty) {
46221      propertyBindings.push(instructionParams);
46222    } else if (instruction === Identifiers.attribute) {
46223      attributeBindings.push(instructionParams);
46224    } else if (instruction === Identifiers.syntheticHostProperty) {
46225      syntheticHostBindings.push(instructionParams);
46226    } else {
46227      updateInstructions.push({
46228        reference: instruction,
46229        paramsOrFn: instructionParams,
46230        span: null
46231      });
46232    }
46233  }
46234
46235  for (const bindingParams of propertyBindings) {
46236    updateInstructions.push({
46237      reference: Identifiers.hostProperty,
46238      paramsOrFn: bindingParams,
46239      span: null
46240    });
46241  }
46242
46243  for (const bindingParams of attributeBindings) {
46244    updateInstructions.push({
46245      reference: Identifiers.attribute,
46246      paramsOrFn: bindingParams,
46247      span: null
46248    });
46249  }
46250
46251  for (const bindingParams of syntheticHostBindings) {
46252    updateInstructions.push({
46253      reference: Identifiers.syntheticHostProperty,
46254      paramsOrFn: bindingParams,
46255      span: null
46256    });
46257  } // since we're dealing with directives/components and both have hostBinding
46258  // functions, we need to generate a special hostAttrs instruction that deals
46259  // with both the assignment of styling as well as static attributes to the host
46260  // element. The instruction below will instruct all initial styling (styling
46261  // that is inside of a host binding within a directive/component) to be attached
46262  // to the host element alongside any of the provided host attributes that were
46263  // collected earlier.
46264
46265
46266  const hostAttrs = convertAttributesToExpressions(hostBindingsMetadata.attributes);
46267  styleBuilder.assignHostAttrs(hostAttrs, definitionMap);
46268
46269  if (styleBuilder.hasBindings) {
46270    // finally each binding that was registered in the statement above will need to be added to
46271    // the update block of a component/directive templateFn/hostBindingsFn so that the bindings
46272    // are evaluated and updated for the element.
46273    styleBuilder.buildUpdateLevelInstructions(getValueConverter()).forEac
46273h(instruction => {
46274      for (const call of instruction.calls) {
46275        // we subtract a value of `1` here because the binding slot was already allocated
46276        // at the top of this method when all the input bindings were counted.
46277        totalHostVarsCount += Math.max(call.allocateBindingSlots - MIN_STYLING_BINDING_SLOTS_REQUIRED, 0);
46278        updateInstructions.push({
46279          reference: instruction.reference,
46280          paramsOrFn: convertStylingCall(call, bindingContext, bindingFn),
46281          span: null
46282        });
46283      }
46284    });
46285  }
46286
46287  if (totalHostVarsCount) {
46288    definitionMap.set('hostVars', literal(totalHostVarsCount));
46289  }
46290
46291  if (createInstructions.length > 0 || updateInstructions.length > 0) {
46292    const hostBindingsFnName = name ? `${name}_HostBindings` : null;
46293    const statements = [];
46294
46295    if (createInstructions.length > 0) {
46296      statements.push(renderFlagCheckIfStmt(1
46297      /* core.RenderFlags.Create */
46298      , getInstructionStatements(createInstructions)));
46299    }
46300
46301    if (updateInstructions.length > 0) {
46302      statements.push(renderFlagCheckIfStmt(2
46303      /* core.RenderFlags.Update */
46304      , updateVariables.concat(getInstructionStatements(updateInstructions))));
46305    }
46306
46307    return fn([new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null)], statements, INFERRED_TYPE, null, hostBindingsFnName);
46308  }
46309
46310  return null;
46311}
46312
46313function bindingFn(implicit, value) {
46314  return convertPropertyBinding(null, implicit, value, 'b');
46315}
46316
46317function convertStylingCall(call, bindingContext, bindingFn) {
46318  return call.params(value => bindingFn(bindingContext, value).currValExpr);
46319}
46320
46321function getBindingNameAndInstruction(binding) {
46322  let bindingName = binding.name;
46323  let instruction; // Check to see if this is an attr binding or a property binding
46324
46325  const attrMatches = bindingName.match(ATTR_REGEX);
46326
46327  if (attrMatches) {
46328    bindingName = attrMatches[1];
46329    instruction = Identifiers.attribute;
46330  } else {
46331    if (binding.isAnimation) {
46332      bindingName = prepareSyntheticPropertyName(bindingName); // host bindings that have a synthetic property (e.g. @foo) should always be rendered
46333      // in the context of the component and not the parent. Therefore there is a special
46334      // compatibility instruction available for this purpose.
46335
46336      instruction = Identifiers.syntheticHostProperty;
46337    } else {
46338      instruction = Identifiers.hostProperty;
46339    }
46340  }
46341
46342  return {
46343    bindingName,
46344    instruction,
46345    isAttribute: !!attrMatches
46346  };
46347}
46348
46349function createHostListeners(eventBindings, name) {
46350  const listenerParams = [];
46351  const syntheticListenerParams = [];
46352  const instructions = [];
46353
46354  for (const binding of eventBindings) {
46355    let bindingName = binding.name && sanitizeIdentifier(binding.name);
46356    const bindingFnName = binding.type === 1
46357    /* ParsedEventType.Animation */
46358    ? prepareSyntheticListenerFunctionName(bindingName, binding.targetOrPhase) : bindingName;
46359    const handlerName = name && bindingName ? `${name}_${bindingFnName}_HostBindingHandler` : null;
46360    const params = prepareEventListenerParameters(BoundEvent.fromParsedEvent(binding), handlerName);
46361
46362    if (binding.type == 1
46363    /* ParsedEventType.Animation */
46364    ) {
46365      syntheticListenerParams.push(params);
46366    } else {
46367      listenerParams.push(params);
46368    }
46369  }
46370
46371  for (const params of syntheticListenerParams) {
46372    instructions.push({
46373      reference: Identifiers.syntheticHostListener,
46374      paramsOrFn: params,
46375      span: null
46376    });
46377  }
46378
46379  for (const params of listenerParams) {
46380    instructions.push({
46381      reference: Identifiers.listener,
46382      paramsOrFn: params,
46383      span: null
46384    });
46385  }
46386
46387  return instructions;
46388}
46389
46390const HOST_REG_EXP = /^(?:\[([^\]]+)\])|(?:\(([^\)]+)\))$/;
46391
46392function parseHostBindings(host) {
46393  const attributes = {};
46394  const listeners = {};
46395  const properties = {};
46396  const specialAttributes = {};
46397
46398  for (const key of Object.keys(host)) {
46399    const value = host[key];
46400    const matches = key.match(HOST_REG_EXP);
46401
46402    if (matches === null) {
46403      switch (key) {
46404        case 'class':
46405          if (typeof value !== 'string') {
46406            // TODO(alxhub): make this a diagnostic.
46407            throw new Error(`Class binding must be string`);
46408          }
46409
46410          specialAttributes.classAttr = value;
46411          break;
46412
46413        case 'style':
46414          if (typeof value !== 'string') {
46415            // TODO(alxhub): make this a diagnostic.
46416            throw new Error(`Style binding must be string`);
46417          }
46418
46419          specialAttributes.styleAttr = value;
46420          break;
46421
46422        default:
46423          if (typeof value === 'string') {
46424            attributes[key] = literal(value);
46425          } else {
46426            attributes[key] = value;
46427          }
46428
46429      }
46430    } else if (matches[1
46431    /* HostBindingGroup.Binding */
46432    ] != null) {
46433      if (typeof value !== 'string') {
46434        // TODO(alxhub): make this a diagnostic.
46435        throw new Error(`Property binding must be string`);
46436      } // synthetic properties (the ones that have a `@` as a prefix)
46437      // are still treated the same as regular properties. Therefore
46438      // there is no point in storing them in a separate map.
46439
46440
46441      properties[matches[1
46442      /* HostBindingGroup.Binding */
46443      ]] = value;
46444    } else if (matches[2
46445    /* HostBindingGroup.Event */
46446    ] != null) {
46447      if (typeof value !== 'string') {
46448        // TODO(alxhub): make this a diagnostic.
46449        throw new Error(`Event binding must be string`);
46450      }
46451
46452      listeners[matches[2
46453      /* HostBindingGroup.Event */
46454      ]] = value;
46455    }
46456  }
46457
46458  return {
46459    attributes,
46460    listeners,
46461    properties,
46462    specialAttributes
46463  };
46464}
46465/**
46466 * Verifies host bindings and returns the list of errors (if any). Empty array indicates that a
46467 * given set of host bindings has no errors.
46468 *
46469 * @param bindings set of host bindings to verify.
46470 * @param sourceSpan source span where host bindings were defined.
46471 * @returns array of errors associated with a given set of host bindings.
46472 */
46473
46474
46475function verifyHostBindings(bindings, sourceSpan) {
46476  // TODO: abstract out host bindings verification logic and use it instead of
46477  // creating events and properties ASTs to detect errors (FW-996)
46478  const bindingParser = makeBindingParser();
46479  bindingParser.createDirectiveHostEventAsts(bindings.listeners, sourceSpan);
46480  bindingParser.createBoundHostProperties(bindings.properties, sourceSpan);
46481  return bindingParser.errors;
46482}
46483
46484function compileStyles(styles, selector, hostSelector) {
46485  const shadowCss = new ShadowCss();
46486  return styles.map(style => {
46487    return shadowCss.shimCssText(style, selector, hostSelector);
46488  });
46489}
46490/**
46491 * @license
46492 * Copyright Google LLC All Rights Reserved.
46493 *
46494 * Use of this source code is governed by an MIT-style license that can be
46495 * found in the LICENSE file at https://angular.io/license
46496 */
46497
46498/**
46499 * An interface for retrieving documents by URL that the compiler uses to
46500 * load templates.
46501 *
46502 * This is an abstract class, rather than an interface, so that it can be used
46503 * as injection token.
46504 */
46505
46506
46507class ResourceLoader {}
46508/**
46509 * @license
46510 * Copyright Google LLC All Rights Reserved.
46511 *
46512 * Use of this source code is governed by an MIT-style license that can be
46513 * found in the LICENSE file at https://angular.io/license
46514 */
46515
46516
46517class CompilerFacadeImpl {
46518  constructor(jitEvaluator = new JitEvaluator()) {
46519    this.jitEvaluator = jitEvaluator;
46520    this.FactoryTarget = FactoryTarget$1;
46521    this.ResourceLoader = ResourceLoader;
46522    this.elementSchemaRegistry = new DomElementSchemaRegistry();
46523  }
46524
46525  compilePipe(angularCoreEnv, sourceMapUrl, facade) {
46526    const metadata = {
46527      name: facade.name,
46528      type: wrapReference(facade.type),
46529      internalType: new WrappedNodeExpr(facade.type),
46530      typeArgumentCount: 0,
46531      deps: null,
46532      pipeName: facade.pipeName,
46533      pure: facade.pure,
46534      isStandalone: facade.isStandalone
46535    };
46536    const res = compilePipeFromMetadata(metadata);
46537    return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []);
46538  }
46539
46540  compilePipeDeclaration(angularCoreEnv, sourceMapUrl, declaration) {
46541    const meta = convertDeclarePipeFacadeToMetadata(declaration);
46542    const res = compilePipeFromMetadata(meta);
46543    return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []);
46544  }
46545
46546  compileInjectable(angularCoreEnv, sourceMapUrl, facade) {
46547    const {
46548      expression,
46549      statements
46550    } = compileInjectable({
46551      name: facade.name,
46552      type: wrapReference(facade.type),
46553      internalType: new WrappedNodeExpr(facade.type),
46554      typeArgumentCount: facade.typeArgumentCount,
46555      providedIn: computeProvidedIn(facade.providedIn),
46556      useClass: convertToProviderExpression(facade, 'useClass'),
46557      useFactory: wrapExpression(facade, 'useFactory'),
46558      useValue: convertToProviderExpression(facade, 'useValue'),
46559      useExisting: convertToProviderExpression(facade, 'useExisting'),
46560      deps: facade.deps?.map(convertR3DependencyMetadata)
46561    },
46562    /* resolveForwardRefs */
46563    true);
46564    return this.jitExpression(expression, angularCoreEnv, sourceMapUrl, statements);
46565  }
46566
46567  compileInjectableDeclaration(angularCoreEnv, sourceMapUrl, facade) {
46568    const {
46569      expression,
46570      statements
46571    } = compileInjectable({
46572      name: facade.type.name,
46573      type: wrapReference(facade.type),
46574      internalType: new WrappedNodeExpr(facade.type),
46575      typeArgumentCount: 0,
46576      providedIn: computeProvidedIn(facade.providedIn),
46577      useClass: convertToProviderExpression(facade, 'useClass'),
46578      useFactory: wrapExpression(facade, 'useFactory'),
46579      useValue: convertToProviderExpression(facade, 'useValue'),
46580      useExisting: convertToProviderExpression(facade, 'useExisting'),
46581      deps: facade.deps?.map(convertR3DeclareDependencyMetadata)
46582    },
46583    /* resolveForwardRefs */
46584    true);
46585    return this.jitExpression(expression, angularCoreEnv, sourceMapUrl, statements);
46586  }
46587
46588  compileInjector(angularCoreEnv, sourceMapUrl, facade) {
46589    const meta = {
46590      name: facade.name,
46591      type: wrapReference(facade.type),
46592      internalType: new WrappedNodeExpr(facade.type),
46593      providers: facade.providers && facade.providers.length > 0 ? new WrappedNodeExpr(facade.providers) : null,
46594      imports: facade.imports.map(i => new WrappedNodeExpr(i))
46595    };
46596    const res = compileInjector(meta);
46597    return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []);
46598  }
46599
46600  compileInjectorDeclaration(angularCoreEnv, sourceMapUrl, declaration) {
46601    const meta = convertDeclareInjectorFacadeToMetadata(declaration);
46602    const res = compileInjector(meta);
46603    return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []);
46604  }
46605
46606  compileNgModule(angularCoreEnv, sourceMapUrl, facade) {
46607    const meta = {
46608      type: wrapReference(facade.type),
46609      internalType: new WrappedNodeExpr(facade.type),
46610      adjacentType: new WrappedNodeExpr(facade.type),
46611      bootstrap: facade.bootstrap.map(wrapReference),
46612      declarations: facade.declarations.map(wrapReference),
46613      publicDeclarationTypes: null,
46614      imports: facade.imports.map(wrapReference),
46615      includeImportTypes: true,
46616      exports: facade.exports.map(wrapReference),
46617      selectorScopeMode: R3SelectorScopeMode.Inline,
46618      containsForwardDecls: false,
46619      schemas: facade.schemas ? facade.schemas.map(wrapReference) : null,
46620      id: facade.id ? new WrappedNodeExpr(facade.id) : null
46621    };
46622    const res = compileNgModule(meta);
46623    return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []);
46624  }
46625
46626  compileNgModuleDeclaration(angularCoreEnv, sourceMapUrl, declaration) {
46627    const expression = compileNgModuleDeclarationExpression(declaration);
46628    return this.jitExpression(expression, angularCoreEnv, sourceMapUrl, []);
46629  }
46630
46631  compileDirective(angularCoreEnv, sourceMapUrl, facade) {
46632    const meta = convertDirectiveFacadeToMetadata(facade);
46633    return this.compileDirectiveFromMeta(angularCoreEnv, sourceMapUrl, meta);
46634  }
46635
46636  compileDirectiveDeclaration(angularCoreEnv, sourceMapUrl, declaration) {
46637    const typeSourceSpan = this.createParseSourceSpan('Directive', declaration.type.name, sourceMapUrl);
46638    const meta = convertDeclareDirectiveFacadeToMetadata(declaration, typeSourceSpan);
46639    return this.compileDirectiveFromMeta(angularCoreEnv, sourceMapUrl, meta);
46640  }
46641
46642  compileDirectiveFromMeta(angularCoreEnv, sourceMapUrl, meta) {
46643    const constantPool = new ConstantPool();
46644    const bindingParser = makeBindingParser();
46645    const res = compileDirectiveFromMetadata(meta, constantPool, bindingParser);
46646    return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, constantPool.statements);
46647  }
46648
46649  compileComponent(angularCoreEnv, sourceMapUrl, facade) {
46650    // Parse the template and check for errors.
46651    const {
46652      template,
46653      interpolation
46654    } = parseJitTemplate(facade.template, facade.name, sourceMapUrl, facade.preserveWhitespace
46654s, facade.interpolation); // Compile the component metadata, including template, into an expression.
46655
46656    const meta = { ...facade,
46657      ...convertDirectiveFacadeToMetadata(facade),
46658      selector: facade.selector || this.elementSchemaRegistry.getDefaultComponentElementName(),
46659      template,
46660      declarations: facade.declarations.map(convertDeclarationFacadeToMetadata),
46661      declarationListEmitMode: 0
46662      /* DeclarationListEmitMode.Direct */
46663      ,
46664      styles: [...facade.styles, ...template.styles],
46665      encapsulation: facade.encapsulation,
46666      interpolation,
46667      changeDetection: facade.changeDetection,
46668      animations: facade.animations != null ? new WrappedNodeExpr(facade.animations) : null,
46669      viewProviders: facade.viewProviders != null ? new WrappedNodeExpr(facade.viewProviders) : null,
46670      relativeContextFilePath: '',
46671      i18nUseExternalIds: true
46672    };
46673    const jitExpressionSourceMap = `ng:///${facade.name}.js`;
46674    return this.compileComponentFromMeta(angularCoreEnv, jitExpressionSourceMap, meta);
46675  }
46676
46677  compileComponentDeclaration(angularCoreEnv, sourceMapUrl, declaration) {
46678    const typeSourceSpan = this.createParseSourceSpan('Component', declaration.type.name, sourceMapUrl);
46679    const meta = convertDeclareComponentFacadeToMetadata(declaration, typeSourceSpan, sourceMapUrl);
46680    return this.compileComponentFromMeta(angularCoreEnv, sourceMapUrl, meta);
46681  }
46682
46683  compileComponentFromMeta(angularCoreEnv, sourceMapUrl, meta) {
46684    const constantPool = new ConstantPool();
46685    const bindingParser = makeBindingParser(meta.interpolation);
46686    const res = compileComponentFromMetadata(meta, constantPool, bindingParser);
46687    return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, constantPool.statements);
46688  }
46689
46690  compileFactory(angularCoreEnv, sourceMapUrl, meta) {
46691    const factoryRes = compileFactoryFunction({
46692      name: meta.name,
46693      type: wrapReference(meta.type),
46694      internalType: new WrappedNodeExpr(meta.type),
46695      typeArgumentCount: meta.typeArgumentCount,
46696      deps: convertR3DependencyMetadataArray(meta.deps),
46697      target: meta.target
46698    });
46699    return this.jitExpression(factoryRes.expression, angularCoreEnv, sourceMapUrl, factoryRes.statements);
46700  }
46701
46702  compileFactoryDeclaration(angularCoreEnv, sourceMapUrl, meta) {
46703    const factoryRes = compileFactoryFunction({
46704      name: meta.type.name,
46705      type: wrapReference(meta.type),
46706      internalType: new WrappedNodeExpr(meta.type),
46707      typeArgumentCount: 0,
46708      deps: Array.isArray(meta.deps) ? meta.deps.map(convertR3DeclareDependencyMetadata) : meta.deps,
46709      target: meta.target
46710    });
46711    return this.jitExpression(factoryRes.expression, angularCoreEnv, sourceMapUrl, factoryRes.statements);
46712  }
46713
46714  createParseSourceSpan(kind, typeName, sourceUrl) {
46715    return r3JitTypeSourceSpan(kind, typeName, sourceUrl);
46716  }
46717  /**
46718   * JIT compiles an expression and returns the result of executing that expression.
46719   *
46720   * @param def the definition which will be compiled and executed to get the value to patch
46721   * @param context an object map of @angular/core symbol names to symbols which will be available
46722   * in the context of the compiled expression
46723   * @param sourceUrl a URL to use for the source map of the compiled expression
46724   * @param preStatements a collection of statements that should be evaluated before the expression.
46725   */
46726
46727
46728  jitExpression(def, context, sourceUrl, preStatements) {
46729    // The ConstantPool may contain Statements which declare variables used in the final expression.
46730    // Therefore, its statements need to precede the actual JIT operation. The final statement is a
46731    // declaration of $def which is set to the expression being compiled.
46732    const statements = [...preStatements, new DeclareVarStmt('$def', def, undefined, StmtModifier.Exported)];
46733    const res = this.jitEvaluator.evaluateStatements(sourceUrl, statements, new R3JitReflector(context),
46734    /* enableSourceMaps */
46735    true);
46736    return res['$def'];
46737  }
46738
46739}
46740
46741function convertToR3QueryMetadata(facade) {
46742  return { ...facade,
46743    predicate: convertQueryPredicate(facade.predicate),
46744    read: facade.read ? new WrappedNodeExpr(facade.read) : null,
46745    static: facade.static,
46746    emitDistinctChangesOnly: facade.emitDistinctChangesOnly
46747  };
46748}
46749
46750function convertQueryDeclarationToMetadata(declaration) {
46751  return {
46752    propertyName: declaration.propertyName,
46753    first: declaration.first ?? false,
46754    predicate: convertQueryPredicate(declaration.predicate),
46755    descendants: declaration.descendants ?? false,
46756    read: declaration.read ? new WrappedNodeExpr(declaration.read) : null,
46757    static: declaration.static ?? false,
46758    emitDistinctChangesOnly: declaration.emitDistinctChangesOnly ?? true
46759  };
46760}
46761
46762function convertQueryPredicate(predicate) {
46763  return Array.isArray(predicate) ? // The predicate is an array of str
46763ings so pass it through.
46764  predicate : // The predicate is a type - assume that we will need to unwrap any `forwardRef()` calls.
46765  createMayBeForwardRefExpression(new WrappedNodeExpr(predicate), 1
46766  /* ForwardRefHandling.Wrapped */
46767  );
46768}
46769
46770function convertDirectiveFacadeToMetadata(facade) {
46771  const inputsFromMetadata = parseInputOutputs(facade.inputs || []);
46772  const outputsFromMetadata = parseInputOutputs(facade.outputs || []);
46773  const propMetadata = facade.propMetadata;
46774  const inputsFromType = {};
46775  const outputsFromType = {};
46776
46777  for (const field in propMetadata) {
46778    if (propMetadata.hasOwnProperty(field)) {
46779      propMetadata[field].forEach(ann => {
46780        if (isInput(ann)) {
46781          inputsFromType[field] = ann.bindingPropertyName ? [ann.bindingPropertyName, field] : field;
46782        } else if (isOutput(ann)) {
46783          outputsFromType[field] = ann.bindingPropertyName || field;
46784        }
46785      });
46786    }
46787  }
46788
46789  return { ...facade,
46790    typeArgumentCount: 0,
46791    typeSourceSpan: facade.typeSourceSpan,
46792    type: wrapReference(facade.type),
46793    internalType: new WrappedNodeExpr(facade.type),
46794    deps: null,
46795    host: extractHostBindings(facade.propMetadata, facade.typeSourceSpan, facade.host),
46796    inputs: { ...inputsFromMetadata,
46797      ...inputsFromType
46798    },
46799    outputs: { ...outputsFromMetadata,
46800      ...outputsFromType
46801    },
46802    queries: facade.queries.map(convertToR3QueryMetadata),
46803    providers: facade.providers != null ? new WrappedNodeExpr(facade.providers) : null,
46804    viewQueries: facade.viewQueries.map(convertToR3QueryMetadata),
46805    fullInheritance: false
46806  };
46807}
46808
46809function convertDeclareDirectiveFacadeToMetadata(declaration, typeSourceSpan) {
46810  return {
46811    name: declaration.type.name,
46812    type: wrapReference(declaration.type),
46813    typeSourceSpan,
46814    internalType: new WrappedNodeExpr(declaration.type),
46815    selector: declaration.selector ?? null,
46816    inputs: declaration.inputs ?? {},
46817    outputs: declaration.outputs ?? {},
46818    host: convertHostDeclarationToMetadata(declaration.host),
46819    queries: (declaration.queries ?? []).map(convertQueryDeclarationToMetadata),
46820    viewQueries: (declaration.viewQueries ?? []).map(convertQueryDeclarationToMetadata),
46821    providers: declaration.providers !== undefined ? new WrappedNodeExpr(declaration.providers) : null,
46822    exportAs: declaration.exportAs ?? null,
46823    usesInheritance: declaration.usesInheritance ?? false,
46824    lifecycle: {
46825      usesOnChanges: declaration.usesOnChanges ?? false
46826    },
46827    deps: null,
46828    typeArgumentCount: 0,
46829    fullInheritance: false,
46830    isStandalone: declaration.isStandalone ?? false
46831  };
46832}
46833
46834function convertHostDeclarationToMetadata(host = {}) {
46835  return {
46836    attributes: convertOpaqueValuesToExpressions(host.attributes ?? {}),
46837    listeners: host.listeners ?? {},
46838    properties: host.properties ?? {},
46839    specialAttributes: {
46840      classAttr: host.classAttribute,
46841      styleAttr: host.styleAttribute
46842    }
46843  };
46844}
46845
46846function convertOpaqueValuesToExpressions(obj) {
46847  const result = {};
46848
46849  for (const key of Object.keys(obj)) {
46850    result[key] = new WrappedNodeExpr(obj[key]);
46851  }
46852
46853  return result;
46854}
46855
46856function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMapUrl) {
46857  const {
46858    template,
46859    interpolation
46860  } = parseJitTemplate(decl.template, decl.type.name, sourceMapUrl, decl.preserveWhitespaces ?? false, decl.interpolation);
46861  const declarations = [];
46862
46863  if (decl.dependencies) {
46864    for (const innerDep of decl.dependencies) {
46865      switch (innerDep.kind) {
46866        case 'directive':
46867        case 'component':
46868          declarations.push(convertDirectiveDeclarationToMetadata(innerDep));
46869          break;
46870
46871        case 'pipe':
46872          declarations.push(convertPipeDeclarationToMetadata(innerDep));
46873          break;
46874      }
46875    }
46876  } else if (decl.components || decl.directives || decl.pipes) {
46877    // Existing declarations on NPM may not be using the new `dependencies` merged field, and may
46878    // have separate fields for dependencies instead. Unify them for JIT compilation.
46879    decl.components && declarations.push(...decl.components.map(dir => convertDirectiveDeclarationToMetadata(dir,
46880    /* isComponent */
46881    true)));
46882    decl.directives && declarations.push(...decl.directives.map(dir => convertDirectiveDeclarationToMetadata(dir)));
46883    decl.pipes && declarations.push(...convertPipeMapToMetadata(decl.pipes));
46884  }
46885
46886  return { ...convertDeclareDirectiveFacadeToMetadata(decl, typeSourceSpan),
46887    template,
46888    styles: decl.styles ?? [],
46889    declarations,
46890    viewProviders: decl.viewProviders !== undefined ? new WrappedNodeExpr(decl.viewProviders) : null,
46891    animations: decl.animations !== undefined ? new WrappedNodeExpr(decl.animations) : null,
46892    changeDetection: decl.changeDetection ?? ChangeDetectionStrategy.Default,
46893    encapsulation: decl.encapsulation ?? ViewEncapsulation.Emulated,
46894    interpolation,
46895    declarationListEmitMode: 2
46896    /* DeclarationListEmitMode.ClosureResolved */
46897    ,
46898    relativeContextFilePath: '',
46899    i18nUseExternalIds: true
46900  };
46901}
46902
46903function convertDeclarationFacadeToMetadata(declaration) {
46904  return { ...declaration,
46905    type: new WrappedNodeExpr(declaration.type)
46906  };
46907}
46908
46909function convertDirectiveDeclarationToMetadata(declaration, isComponent = null) {
46910  return {
46911    kind: R3TemplateDependencyKind.Directive,
46912    isComponent: isComponent || declaration.kind === 'component',
46913    selector: declaration.selector,
46914    type: new WrappedNodeExpr(declaration.type),
46915    inputs: declaration.inputs ?? [],
46916    outputs: declaration.outputs ?? [],
46917    exportAs: declaration.exportAs ?? null
46918  };
46919}
46920
46921function convertPipeMapToMetadata(pipes) {
46922  if (!pipes) {
46923    return [];
46924  }
46925
46926  return Object.keys(pipes).map(name => {
46927    return {
46928      kind: R3TemplateDependencyKind.Pipe,
46929      name,
46930      type: new WrappedNodeExpr(pipes[name])
46931    };
46932  });
46933}
46934
46935function convertPipeDeclarationToMetadata(pipe) {
46936  return {
46937    kind: R3TemplateDependencyKind.Pipe,
46938    name: pipe.name,
46939    type: new WrappedNodeExpr(pipe.type)
46940  };
46941}
46942
46943function parseJitTemplate(template, typeName, sourceMapUrl, preserveWhitespace
46943s, interpolation) {
46944  const interpolationConfig = interpolation ? InterpolationConfig.fromArray(interpolation) : DEFAULT_INTERPOLATION_CONFIG; // Parse the template and check for errors.
46945
46946  const parsed = parseTemplate(template, sourceMapUrl, {
46947    preserveWhitespaces,
46948    interpolationConfig
46949  });
46950
46951  if (parsed.errors !== null) {
46952    const errors = parsed.errors.map(err => err.toString()).join(', ');
46953    throw new Error(`Errors during JIT compilation of template for ${typeName}: ${errors}`);
46954  }
46955
46956  return {
46957    template: parsed,
46958    interpolation: interpolationConfig
46959  };
46960}
46961/**
46962 * Convert the expression, if present to an `R3ProviderExpression`.
46963 *
46964 * In JIT mode we do not want the compiler to wrap the expression in a `forwardRef()` call because,
46965 * if it is referencing a type that has not yet been defined, it will have already been wrapped in
46966 * a `forwardRef()` - either by the application developer or during partial-compilation. Thus we can
46967 * use `ForwardRefHandling.None`.
46968 */
46969
46970
46971function convertToProviderExpression(obj, property) {
46972  if (obj.hasOwnProperty(property)) {
46973    return createMayBeForwardRefExpression(new WrappedNodeExpr(obj[property]), 0
46974    /* ForwardRefHandling.None */
46975    );
46976  } else {
46977    return undefined;
46978  }
46979}
46980
46981function wrapExpression(obj, property) {
46982  if (obj.hasOwnProperty(property)) {
46983    return new WrappedNodeExpr(obj[property]);
46984  } else {
46985    return undefined;
46986  }
46987}
46988
46989function computeProvidedIn(providedIn) {
46990  const expression = typeof providedIn === 'function' ? new WrappedNodeExpr(providedIn) : new LiteralExpr(providedIn ?? null); // See `convertToProviderExpression()` for why this uses `ForwardRefHandling.None`.
46991
46992  return createMayBeForwardRefExpression(expression, 0
46993  /* ForwardRefHandling.None */
46994  );
46995}
46996
46997function convertR3DependencyMetadataArray(facades) {
46998  return facades == null ? null : facades.map(convertR3DependencyMetadata);
46999}
47000
47001function convertR3DependencyMetadata(facade) {
47002  const isAttributeDep = facade.attribute != null; // both `null` and `undefined`
47003
47004  const rawToken = facade.token === null ? null : new WrappedNodeExpr(facade.token); // In JIT mode, if the dep is an `@Attribute()` then we use the attribute name given in
47005  // `attribute` rather than the `token`.
47006
47007  const token = isAttributeDep ? new WrappedNodeExpr(facade.attribute) : rawToken;
47008  return createR3DependencyMetadata(token, isAttributeDep, facade.host, facade.optional, facade.self, facade.skipSelf);
47009}
47010
47011function convertR3DeclareDependencyMetadata(facade) {
47012  const isAttributeDep = facade.attribute ?? false;
47013  const token = facade.token === null ? null : new WrappedNodeExpr(facade.token);
47014  return createR3DependencyMetadata(token, isAttributeDep, facade.host ?? false, facade.optional ?? false, facade.self ?? false, facade.skipSelf ?? false);
47015}
47016
47017function createR3DependencyMetadata(token, isAttributeDep, host, optional, self, skipSelf) {
47018  // If the dep is an `@Attribute()` the `attributeNameType` ought to be the `unknown` type.
47019  // But types are not available at runtime so we just use a literal `"<unknown>"` string as a dummy
47020  // marker.
47021  const attributeNameType = isAttributeDep ? literal('unknown') : null;
47022  return {
47023    token,
47024    attributeNameType,
47025    host,
47026    optional,
47027    self,
47028    skipSelf
47029  };
47030}
47031
47032function extractHostBindings(propMetadata, sourceSpan, host) {
47033  // First parse the declarations from the metadata.
47034  const bindings = parseHostBindings(host || {}); // After that check host bindings for errors
47035
47036  const errors = verifyHostBindings(bindings, sourceSpan);
47037
47038  if (errors.length) {
47039    throw new Error(errors.map(error => error.msg).join('\n'));
47040  } // Next, loop over the properties of the object, looking for @HostBinding and @HostListener.
47041
47042
47043  for (const field in propMetadata) {
47044    if (propMetadata.hasOwnProperty(field)) {
47045      propMetadata[field].forEach(ann => {
47046        if (isHostBinding(ann)) {
47047          // Since this is a decorator, we know that the value is a class member. Always access it
47048          // through `this` so that further down the line it can't be confused for a literal value
47049          // (e.g. if there's a property called `true`).
47050          bindings.properties[ann.hostPropertyName || field] = getSafePropertyAccessString('this', field);
47051        } else if (isHostListener(ann)) {
47052          bindings.listeners[ann.eventName || field] = `${field}(${(ann.args || []).join(',')})`;
47053        }
47054      });
47055    }
47056  }
47057
47058  return bindings;
47059}
47060
47061function isHostBinding(value) {
47062  return value.ngMetadataName === 'HostBinding';
47063}
47064
47065function isHostListener(value) {
47066  return value.ngMetadataName === 'HostListener';
47067}
47068
47069function isInput(value) {
47070  return value.ngMetadataName === 'Input';
47071}
47072
47073function isOutput(value) {
47074  return value.ngMetadataName === 'Output';
47075}
47076
47077function parseInputOutputs(values) {
47078  return values.reduce((results, value) => {
47079    const [field, property] = value.split(':', 2).map(str => str.trim());
47080    results[field] = property || field;
47081    return results;
47082  }, {});
47083}
47084
47085function convertDeclarePipeFacadeToMetadata(declaration) {
47086  return {
47087    name: declaration.type.name,
47088    type: wrapReference(declaration.type),
47089    internalType: new WrappedNodeExpr(declaration.type),
47090    typeArgumentCount: 0,
47091    pipeName: declaration.name,
47092    deps: null,
47093    pure: declaration.pure ?? true,
47094    isStandalone: declaration.isStandalone ?? false
47095  };
47096}
47097
47098function convertDeclareInjectorFacadeToMetadata(declaration) {
47099  return {
47100    name: declaration.type.name,
47101    type: wrapReference(declaration.type),
47102    internalType: new WrappedNodeExpr(declaration.type),
47103    providers: declaration.providers !== undefined && declaration.providers.length > 0 ? new WrappedNodeExpr(declaration.providers) : null,
47104    imports: declaration.imports !== undefined ? declaration.imports.map(i => new WrappedNodeExpr(i)) : []
47105  };
47106}
47107
47108function publishFacade(global) {
47109  const ng = global.ng || (global.ng = {});
47110  ng.ɵcompilerFacade = new CompilerFacadeImpl();
47111}
47112/**
47113 * @license
47114 * Copyright Google LLC All Rights Reserved.
47115 *
47116 * Use of this source code is governed by an MIT-style license that can be
47117 * found in the LICENSE file at https://angular.io/license
47118 */
47119
47120
47121const VERSION = new Version('14.2.10');
47122/**
47123 * @license
47124 * Copyright Google LLC All Rights Reserved.
47125 *
47126 * Use of this source code is governed by an MIT-style license that can be
47127 * found in the LICENSE file at https://angular.io/license
47128 */
47129
47130class CompilerConfig {
47131  constructor({
47132    defaultEncapsulation = ViewEncapsulation.Emulated,
47133    useJit = true,
47134    jitDevMode = false,
47135    missingTranslation = null,
47136    preserveWhitespaces,
47137    strictInjectionParameters
47138  } = {}) {
47139    this.defaultEncapsulation = defaultEncapsulation;
47140    this.useJit = !!useJit;
47141    this.jitDevMode = !!jitDevMode;
47142    this.missingTranslation = missingTranslation;
47143    this.preserveWhitespaces = preserveWhitespacesDefault(noUndefined(preserveWhitespaces));
47144    this.strictInjectionParameters = strictInjectionParameters === true;
47145  }
47146
47147}
47148
47149function preserveWhitespacesDefault(preserveWhitespacesOption, defaultSetting = false) {
47150  return preserveWhitespacesOption === null ? defaultSetting : preserveWhitespacesOption;
47151}
47152/**
47153 * @license
47154 * Copyright Google LLC All Rights Reserved.
47155 *
47156 * Use of this source code is governed by an MIT-style license that can be
47157 * found in the LICENSE file at https://angular.io/license
47158 */
47159
47160
47161const _I18N_ATTR = 'i18n';
47162const _I18N_ATTR_PREFIX = 'i18n-';
47163const _I18N_COMMENT_PREFIX_REGEXP = /^i18n:?/;
47164const MEANING_SEPARATOR = '|';
47165const ID_SEPARATOR = '@@';
47166let i18nCommentsWarned = false;
47167/**
47168 * Extract translatable messages from an html AST
47169 */
47170
47171function extractMessages(nodes, interpolationConfig, implicitTags, implicitAttrs) {
47172  const visitor = new _Visitor(implicitTags, implicitAttrs);
47173  return visitor.extract(nodes, interpolationConfig);
47174}
47175
47176function mergeTranslations(nodes, translations, interpolationConfig, implicitTags, implicitAttrs) {
47177  const visitor = new _Visitor(implicitTags, implicitAttrs);
47178  return visitor.merge(nodes, translations, interpolationConfig);
47179}
47180
47181class ExtractionResult {
47182  constructor(messages, errors) {
47183    this.messages = messages;
47184    this.errors = errors;
47185  }
47186
47187}
47188
47189var _VisitorMode;
47190
47191(function (_VisitorMode) {
47192  _VisitorMode[_VisitorMode["Extract"] = 0] = "Extract";
47193  _VisitorMode[_VisitorMode["Merge"] = 1] = "Merge";
47194})(_VisitorMode || (_VisitorMode = {}));
47195/**
47196 * This Visitor is used:
47197 * 1. to extract all the translatable strings from an html AST (see `extract()`),
47198 * 2. to replace the translatable strings with the actual translations (see `merge()`)
47199 *
47200 * @internal
47201 */
47202
47203
47204class _Visitor {
47205  constructor(_implicitTags, _implicitAttrs) {
47206    this._implicitTags = _implicitTags;
47207    this._implicitAttrs = _implicitAttrs;
47208  }
47209  /**
47210   * Extracts the messages from the tree
47211   */
47212
47213
47214  extract(nodes, interpolationConfig) {
47215    this._init(_VisitorMode.Extract, interpolationConfig);
47216
47217    nodes.forEach(node => node.visit(this, null));
47218
47219    if (this._inI18nBlock) {
47220      this._reportError(nodes[nodes.length - 1], 'Unclosed block');
47221    }
47222
47223    return new ExtractionResult(this._messages, this._errors);
47224  }
47225  /**
47226   * Returns a tree where all translatable nodes are translated
47227   */
47228
47229
47230  merge(nodes, translations, interpolationConfig) {
47231    this._init(_VisitorMode.Merge, interpolationConfig);
47232
47233    this._translations = translations; // Construct a single fake root element
47234
47235    const wrapper = new Element('wrapper', [], nodes, undefined, undefined, undefined);
47236    const translatedNode = wrapper.visit(this, null);
47237
47238    if (this._inI18nBlock) {
47239      this._reportError(nodes[nodes.length - 1], 'Unclosed block');
47240    }
47241
47242    return new ParseTreeResult(translatedNode.children, this._errors);
47243  }
47244
47245  visitExpansionCase(icuCase, context) {
47246    // Parse cases for translatable html attributes
47247    const expression = visitAll(this, icuCase.expression, context);
47248
47249    if (this._mode === _VisitorMode.Merge) {
47250      return new ExpansionCase(icuCase.value, expression, icuCase.sourceSpan, icuCase.valueSourceSpan, icuCase.expSourceSpan);
47251    }
47252  }
47253
47254  visitExpansion(icu, context) {
47255    this._mayBeAddBlockChildren(icu);
47256
47257    const wasInIcu = this._inIcu;
47258
47259    if (!this._inIcu) {
47260      // nested ICU messages should not be extracted but top-level translated as a whole
47261      if (this._isInTranslatableSection) {
47262        this._addMessage([icu]);
47263      }
47264
47265      this._inIcu = true;
47266    }
47267
47268    const cases = visitAll(this, icu.cases, context);
47269
47270    if (this._mode === _VisitorMode.Merge) {
47271      icu = new Expansion(icu.switchValue, icu.type, cases, icu.sourceSpan, icu.switchValueSourceSpan);
47272    }
47273
47274    this._inIcu = wasInIcu;
47275    return icu;
47276  }
47277
47278  visitComment(comment, context) {
47279    const isOpening = _isOpeningComment(comment);
47280
47281    if (isOpening && this._isInTranslatableSection) {
47282      this._reportError(comment, 'Could not start a block inside a translatable section');
47283
47284      return;
47285    }
47286
47287    const isClosing = _isClosingComment(comment);
47288
47289    if (isClosing && !this._inI18nBlock) {
47290      this._reportError(comment, 'Trying to close an unopened block');
47291
47292      return;
47293    }
47294
47295    if (!this._inI18nNode && !this._inIcu) {
47296      if (!this._inI18nBlock) {
47297        if (isOpening) {
47298          // deprecated from v5 you should use <ng-container i18n> instead of i18n comments
47299          if (!i18nCommentsWarned && console && console.warn) {
47300            i18nCommentsWarned = true;
47301            const details = comment.sourceSpan.details ? `, ${comment.sourceSpan.details}` : ''; // TODO(ocombe): use a log service once there is a public one available
47302
47303            console.warn(`I18n comments are deprecated, use an <ng-container> element instead (${comment.sourceSpan.start}${details})`);
47304          }
47305
47306          this._inI18nBlock = true;
47307          this._blockStartDepth = this._depth;
47308          this._blockChildren = [];
47309          this._blockMeaningAndDesc = comment.value.replace(_I18N_COMMENT_PREFIX_REGEXP, '').trim();
47310
47311          this._openTranslatableSection(comment);
47312        }
47313      } else {
47314        if (isClosing) {
47315          if (this._depth == this._blockStartDepth) {
47316            this._closeTranslatableSection(comment, this._blockChildren);
47317
47318            this._inI18nBlock = false;
47319
47320            const message = this._addMessage(this._blockChildren, this._blockMeaningAndDesc); // merge attributes in sections
47321
47322
47323            const nodes = this._translateMessage(comment, message);
47324
47325            return visitAll(this, nodes);
47326          } else {
47327            this._reportError(comment, 'I18N blocks should not cross element boundaries');
47328
47329            return;
47330          }
47331        }
47332      }
47333    }
47334  }
47335
47336  visitText(text, context) {
47337    if (this._isInTranslatableSection) {
47338      this._mayBeAddBlockChildren(text);
47339    }
47340
47341    return text;
47342  }
47343
47344  visitElement(el, context) {
47345    this._mayBeAddBlockChildren(el);
47346
47347    this._depth++;
47348    const wasInI18nNode = this._inI18nNode;
47349    const wasInImplicitNode = this._inImplicitNode;
47350    let childNodes = [];
47351    let translatedChildNodes = undefined; // Extract:
47352    // - top level nodes with the (implicit) "i18n" attribute if not already in a section
47353    // - ICU messages
47354
47355    const i18nAttr = _getI18nAttr(el);
47356
47357    const i18nMeta = i18nAttr ? i18nAttr.value : '';
47358    const isImplicit = this._implicitTags.some(tag => el.name === tag) && !this._inIcu && !this._isInTranslatableSection;
47359    const isTopLevelImplicit = !wasInImplicitNode && isImplicit;
47360    this._inImplicitNode = wasInImplicitNode || isImplicit;
47361
47362    if (!this._isInTranslatableSection && !this._inIcu) {
47363      if (i18nAttr || isTopLevelImplicit) {
47364        this._inI18nNode = true;
47365
47366        const message = this._addMessage(el.children, i18nMeta);
47367
47368        translatedChildNodes = this._translateMessage(el, message);
47369      }
47370
47371      if (this._mode == _VisitorMode.Extract) {
47372        const isTranslatable = i18nAttr || isTopLevelImplicit;
47373        if (isTranslatable) this._openTranslatableSection(el);
47374        visitAll(this, el.children);
47375        if (isTranslatable) this._closeTranslatableSection(el, el.children);
47376      }
47377    } else {
47378      if (i18nAttr || isTopLevelImplicit) {
47379        this._reportError(el, 'Could not mark an element as translatable inside a translatable section');
47380      }
47381
47382      if (this._mode == _VisitorMode.Extract) {
47383        // Descend into child nodes for extraction
47384        visitAll(this, el.children);
47385      }
47386    }
47387
47388    if (this._mode === _VisitorMode.Merge) {
47389      const visitNodes = translatedChildNodes || el.children;
47390      visitNodes.forEach(child => {
47391        const visited = child.visit(this, context);
47392
47393        if (visited && !this._isInTranslatableSection) {
47394          // Do not add the children from translatable sections (= i18n blocks here)
47395          // They will be added later in this loop when the block closes (i.e. on `<!-- /i18n -->`)
47396          childNodes = childNodes.concat(visited);
47397        }
47398      });
47399    }
47400
47401    this._visitAttributesOf(el);
47402
47403    this._depth--;
47404    this._inI18nNode = wasInI18nNode;
47405    this._inImplicitNode = wasInImplicitNode;
47406
47407    if (this._mode === _VisitorMode.Merge) {
47408      const translatedAttrs = this._translateAttributes(el);
47409
47410      return new Element(el.name, translatedAttrs, childNodes, el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
47411    }
47412
47413    return null;
47414  }
47415
47416  visitAttribute(attribute, context) {
47417    throw new Error('unreachable code');
47418  }
47419
47420  _init(mode, interpolationConfig) {
47421    this._mode = mode;
47422    this._inI18nBlock = false;
47423    this._inI18nNode = false;
47424    this._depth = 0;
47425    this._inIcu = false;
47426    this._msgCountAtSectionStart = undefined;
47427    this._errors = [];
47428    this._messages = [];
47429    this._inImplicitNode = false;
47430    this._createI18nMessage = createI18nMessageFactory(interpolationConfig);
47431  } // looks for translatable attributes
47432
47433
47434  _visitAttributesOf(el) {
47435    const explicitAttrNameToValue = {};
47436    const implicitAttrNames = this._implicitAttrs[el.name] || [];
47437    el.attrs.filter(attr => attr.name.startsWith(_I18N_ATTR_PREFIX)).forEach(attr => explicitAttrNameToValue[attr.name.slice(_I18N_ATTR_PREFIX.length)] = attr.value);
47438    el.attrs.forEach(attr => {
47439      if (attr.name in explicitAttrNameToValue) {
47440        this._addMessage([attr], explicitAttrNameToValue[attr.name]);
47441      } else if (implicitAttrNames.some(name => attr.name === name)) {
47442        this._addMessage([attr]);
47443      }
47444    });
47445  } // add a translatable message
47446
47447
47448  _addMessage(ast, msgMeta) {
47449    if (ast.length == 0 || ast.length == 1 && ast[0] instanceof Attribute && !ast[0].value) {
47450      // Do not create empty messages
47451      return null;
47452    }
47453
47454    const {
47455      meaning,
47456      description,
47457      id
47458    } = _parseMessageMeta(msgMeta);
47459
47460    const message = this._createI18nMessage(ast, meaning, description, id);
47461
47462    this._messages.push(message);
47463
47464    return message;
47465  } // Translates the given message given the `TranslationBundle`
47466  // This is used for translating elements / blocks - see `_translateAttributes` for attributes
47467  // no-op when called in extraction mode (returns [])
47468
47469
47470  _translateMessage(el, message) {
47471    if (message && this._mode === _VisitorMode.Merge) {
47472      const nodes = this._translations.get(message);
47473
47474      if (nodes) {
47475        return nodes;
47476      }
47477
47478      this._reportError(el, `Translation unavailable for message id="${this._translations.digest(message)}"`);
47479    }
47480
47481    return [];
47482  } // translate the attributes of an element and remove i18n specific attributes
47483
47484
47485  _translateAttributes(el) {
47486    const attributes = el.attrs;
47487    const i18nParsedMessageMeta = {};
47488    attributes.forEach(attr => {
47489      if (attr.name.startsWith(_I18N_ATTR_PREFIX)) {
47490        i18nParsedMessageMeta[attr.name.slice(_I18N_ATTR_PREFIX.length)] = _parseMessageMeta(attr.value);
47491      }
47492    });
47493    const translatedAttributes = [];
47494    attributes.forEach(attr => {
47495      if (attr.name === _I18N_ATTR || attr.name.startsWith(_I18N_ATTR_PREFIX)) {
47496        // strip i18n specific attributes
47497        return;
47498      }
47499
47500      if (attr.value && attr.value != '' && i18nParsedMessageMeta.hasOwnProperty(attr.name)) {
47501        const {
47502          meaning,
47503          description,
47504          id
47505        } = i18nParsedMessageMeta[attr.name];
47506
47507        const message = this._createI18nMessage([attr], meaning, description, id);
47508
47509        const nodes = this._translations.get(message);
47510
47511        if (nodes) {
47512          if (nodes.length == 0) {
47513            translatedAttributes.push(new Attribute(attr.name, '', attr.sourceSpan, undefined
47514            /* keySpan */
47515            , undefined
47516            /* valueSpan */
47517            , undefined
47518            /* valueTokens */
47519            , undefined
47520            /* i18n */
47521            ));
47522          } else if (nodes[0] instanceof Text) {
47523            const value = nodes[0].value;
47524            translatedAttributes.push(new Attribute(attr.name, value, attr.sourceSpan, undefined
47525            /* keySpan */
47526            , undefined
47527            /* valueSpan */
47528            , undefined
47529            /* valueTokens */
47530            , undefined
47531            /* i18n */
47532            ));
47533          } else {
47534            this._reportError(el, `Unexpected translation for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`);
47535          }
47536        } else {
47537          this._reportError(el, `Translation unavailable for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`);
47538        }
47539      } else {
47540        translatedAttributes.push(attr);
47541      }
47542    });
47543    return translatedAttributes;
47544  }
47545  /**
47546   * Add the node as a child of the block when:
47547   * - we are in a block,
47548   * - we are not inside a ICU message (those are handled separately),
47549   * - the node is a "direct child" of the block
47550   */
47551
47552
47553  _mayBeAddBlockChildren(node) {
47554    if (this._inI18nBlock && !this._inIcu && this._depth == this._blockStartDepth) {
47555      this._blockChildren.push(node);
47556    }
47557  }
47558  /**
47559   * Marks the start of a section, see `_closeTranslatableSection`
47560   */
47561
47562
47563  _openTranslatableSection(node) {
47564    if (this._isInTranslatableSection) {
47565      this._reportError(node, 'Unexpected section start');
47566    } else {
47567      this._msgCountAtSectionStart = this._messages.length;
47568    }
47569  }
47570  /**
47571   * A translatable section could be:
47572   * - the content of translatable element,
47573   * - nodes between `<!-- i18n -->` and `<!-- /i18n -->` comments
47574   */
47575
47576
47577  get _isInTranslatableSection() {
47578    return this._msgCountAtSectionStart !== void 0;
47579  }
47580  /**
47581   * Terminates a section.
47582   *
47583   * If a section has only one significant children (comments not significant) then we should not
47584   * keep the message from this children:
47585   *
47586   * `<p i18n="meaning|description">{ICU message}</p>` would produce two messages:
47587   * - one for the <p> content with meaning and description,
47588   * - another one for the ICU message.
47589   *
47590   * In this case the last message is discarded as it contains less information (the AST is
47591   * otherwise identical).
47592   *
47593   * Note that we should still keep messages extracted from attributes inside the section (ie in the
47594   * ICU message here)
47595   */
47596
47597
47598  _closeTranslatableSection(node, directChildren) {
47599    if (!this._isInTranslatableSection) {
47600      this._reportError(node, 'Unexpected section end');
47601
47602      return;
47603    }
47604
47605    const startIndex = this._msgCountAtSectionStart;
47606    const significantChildren = directChildren.reduce((count, node) => count + (node instanceof Comment ? 0 : 1), 0);
47607
47608    if (significantChildren == 1) {
47609      for (let i = this._messages.length - 1; i >= startIndex; i--) {
47610        const ast = this._messages[i].nodes;
47611
47612        if (!(ast.length == 1 && ast[0] instanceof Text$2)) {
47613          this._messages.splice(i, 1);
47614
47615          break;
47616        }
47617      }
47618    }
47619
47620    this._msgCountAtSectionStart = undefined;
47621  }
47622
47623  _reportError(node, msg) {
47624    this._errors.push(new I18nError(node.sourceSpan, msg));
47625  }
47626
47627}
47628
47629function _isOpeningComment(n) {
47630  return !!(n instanceof Comment && n.value && n.value.startsWith('i18n'));
47631}
47632
47633function _isClosingComment(n) {
47634  return !!(n instanceof Comment && n.value && n.value === '/i18n');
47635}
47636
47637function _getI18nAttr(p) {
47638  return p.attrs.find(attr => attr.name === _I18N_ATTR) || null;
47639}
47640
47641function _parseMessageMeta(i18n) {
47642  if (!i18n) return {
47643    meaning: '',
47644    description: '',
47645    id: ''
47646  };
47647  const idIndex = i18n.indexOf(ID_SEPARATOR);
47648  const descIndex = i18n.indexOf(MEANING_SEPARATOR);
47649  const [meaningAndDesc, id] = idIndex > -1 ? [i18n.slice(0, idIndex), i18n.slice(idIndex + 2)] : [i18n, ''];
47650  const [meaning, description] = descIndex > -1 ? [meaningAndDesc.slice(0, descIndex), meaningAndDesc.slice(descIndex + 1)] : ['', meaningAndDesc];
47651  return {
47652    meaning,
47653    description,
47654    id: id.trim()
47655  };
47656}
47657/**
47658 * @license
47659 * Copyright Google LLC All Rights Reserved.
47660 *
47661 * Use of this source code is governed by an MIT-style license that can be
47662 * found in the LICENSE file at https://angular.io/license
47663 */
47664
47665
47666class XmlTagDefinition {
47667  constructor() {
47668    this.closedByParent = false;
47669    this.isVoid = false;
47670    this.ignoreFirstLf = false;
47671    this.canSelfClose = true;
47672    this.preventNamespaceInheritance = false;
47673  }
47674
47675  requireExtraParent(currentParent) {
47676    return false;
47677  }
47678
47679  isClosedByChild(name) {
47680    return false;
47681  }
47682
47683  getContentType() {
47684    return TagContentType.PARSABLE_DATA;
47685  }
47686
47687}
47688
47689const _TAG_DEFINITION = new XmlTagDefinition();
47690
47691function getXmlTagDefinition(tagName) {
47692  return _TAG_DEFINITION;
47693}
47694/**
47695 * @license
47696 * Copyright Google LLC All Rights Reserved.
47697 *
47698 * Use of this source code is governed by an MIT-style license that can be
47699 * found in the LICENSE file at https://angular.io/license
47700 */
47701
47702
47703class XmlParser extends Parser {
47704  constructor() {
47705    super(getXmlTagDefinition);
47706  }
47707
47708  parse(source, url, options) {
47709    return super.parse(source, url, options);
47710  }
47711
47712}
47713/**
47714 * @license
47715 * Copyright Google LLC All Rights Reserved.
47716 *
47717 * Use of this source code is governed by an MIT-style license that can be
47718 * found in the LICENSE file at https://angular.io/license
47719 */
47720
47721
47722const _VERSION$1 = '1.2';
47723const _XMLNS$1 = 'urn:oasis:names:tc:xliff:document:1.2'; // TODO(vicb): make this a param (s/_/-/)
47724
47725const _DEFAULT_SOURCE_LANG$1 = 'en';
47726const _PLACEHOLDER_TAG$2 = 'x';
47727const _MARKER_TAG$1 = 'mrk';
47728const _FILE_TAG = 'file';
47729const _SOURCE_TAG$1 = 'source';
47730const _SEGMENT_SOURCE_TAG = 'seg-source';
47731const _ALT_TRANS_TAG = 'alt-trans';
47732const _TARGET_TAG$1 = 'target';
47733const _UNIT_TAG$1 = 'trans-unit';
47734const _CONTEXT_GROUP_TAG = 'context-group';
47735const _CONTEXT_TAG = 'context'; // https://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html
47736// https://docs.oasis-open.org/xliff/v1.2/xliff-profile-html/xliff-profile-html-1.2.html
47737
47738class Xliff extends Serializer {
47739  write(messages, locale) {
47740    const visitor = new _WriteVisitor$1();
47741    const transUnits = [];
47742    messages.forEach(message => {
47743      let contextTags = [];
47744      message.sources.forEach(source => {
47745        let contextGroupTag = new Tag(_CONTEXT_GROUP_TAG, {
47746          purpose: 'location'
47747        });
47748        contextGroupTag.children.push(new CR(10), new Tag(_CONTEXT_TAG, {
47749          'context-type': 'sourcefile'
47750        }, [new Text$1(source.filePath)]), new CR(10), new Tag(_CONTEXT_TAG, {
47751          'context-type': 'linenumber'
47752        }, [new Text$1(`${source.startLine}`)]), new CR(8));
47753        contextTags.push(new CR(8), contextGroupTag);
47754      });
47755      const transUnit = new Tag(_UNIT_TAG$1, {
47756        id: message.id,
47757        datatype: 'html'
47758      });
47759      transUnit.children.push(new CR(8), new Tag(_SOURCE_TAG$1, {}, visitor.serialize(message.nodes)), ...contextTags);
47760
47761      if (message.description) {
47762        transUnit.children.push(new CR(8), new Tag('note', {
47763          priority: '1',
47764          from: 'description'
47765        }, [new Text$1(message.description)]));
47766      }
47767
47768      if (message.meaning) {
47769        transUnit.children.push(new CR(8), new Tag('note', {
47770          priority: '1',
47771          from: 'meaning'
47772        }, [new Text$1(message.meaning)]));
47773      }
47774
47775      transUnit.children.push(new CR(6));
47776      transUnits.push(new CR(6), transUnit);
47777    });
47778    const body = new Tag('body', {}, [...transUnits, new CR(4)]);
47779    const file = new Tag('file', {
47780      'source-language': locale || _DEFAULT_SOURCE_LANG$1,
47781      datatype: 'plaintext',
47782      original: 'ng2.template'
47783    }, [new CR(4), body, new CR(2)]);
47784    const xliff = new Tag('xliff', {
47785      version: _VERSION$1,
47786      xmlns: _XMLNS$1
47787    }, [new CR(2), file, new CR()]);
47788    return serialize([new Declaration({
47789      version: '1.0',
47790      encoding: 'UTF-8'
47791    }), new CR(), xliff, new CR()]);
47792  }
47793
47794  load(content, url) {
47795    // xliff to xml nodes
47796    const xliffParser = new XliffParser();
47797    const {
47798      locale,
47799      msgIdToHtml,
47800      errors
47801    } = xliffParser.parse(content, url); // xml nodes to i18n nodes
47802
47803    const i18nNodesByMsgId = {};
47804    const converter = new XmlToI18n$2();
47805    Object.keys(msgIdToHtml).forEach(msgId => {
47806      const {
47807        i18nNodes,
47808        errors: e
47809      } = converter.convert(msgIdToHtml[msgId], url);
47810      errors.push(...e);
47811      i18nNodesByMsgId[msgId] = i18nNodes;
47812    });
47813
47814    if (errors.length) {
47815      throw new Error(`xliff parse errors:\n${errors.join('\n')}`);
47816    }
47817
47818    return {
47819      locale: locale,
47820      i18nNodesByMsgId
47821    };
47822  }
47823
47824  digest(message) {
47825    return digest$1(message);
47826  }
47827
47828}
47829
47830class _WriteVisitor$1 {
47831  visitText(text, context) {
47832    return [new Text$1(text.value)];
47833  }
47834
47835  visitContainer(container, context) {
47836    const nodes = [];
47837    container.children.forEach(node => nodes.push(...node.visit(this)));
47838    return nodes;
47839  }
47840
47841  visitIcu(icu, context) {
47842    const nodes = [new Text$1(`{${icu.expressionPlaceholder}, ${icu.type}, `)];
47843    Object.keys(icu.cases).forEach(c => {
47844      nodes.push(new Text$1(`${c} {`), ...icu.cases[c].visit(this), new Text$1(`} `));
47845    });
47846    nodes.push(new Text$1(`}`));
47847    return nodes;
47848  }
47849
47850  visitTagPlaceholder(ph, context) {
47851    const ctype = getCtypeForTag(ph.tag);
47852
47853    if (ph.isVoid) {
47854      // void tags have no children nor closing tags
47855      return [new Tag(_PLACEHOLDER_TAG$2, {
47856        id: ph.startName,
47857        ctype,
47858        'equiv-text': `<${ph.tag}/>`
47859      })];
47860    }
47861
47862    const startTagPh = new Tag(_PLACEHOLDER_TAG$2, {
47863      id: ph.startName,
47864      ctype,
47865      'equiv-text': `<${ph.tag}>`
47866    });
47867    const closeTagPh = new Tag(_PLACEHOLDER_TAG$2, {
47868      id: ph.closeName,
47869      ctype,
47870      'equiv-text': `</${ph.tag}>`
47871    });
47872    return [startTagPh, ...this.serialize(ph.children), closeTagPh];
47873  }
47874
47875  visitPlaceholder(ph, context) {
47876    return [new Tag(_PLACEHOLDER_TAG$2, {
47877      id: ph.name,
47878      'equiv-text': `{{${ph.value}}}`
47879    })];
47880  }
47881
47882  visitIcuPlaceholder(ph, context) {
47883    const equivText = `{${ph.value.expression}, ${ph.value.type}, ${Object.keys(ph.value.cases).map(value => value + ' {...}').join(' ')}}`;
47884    return [new Tag(_PLACEHOLDER_TAG$2, {
47885      id: ph.name,
47886      'equiv-text': equivText
47887    })];
47888  }
47889
47890  serialize(nodes) {
47891    return [].concat(...nodes.map(node => node.visit(this)));
47892  }
47893
47894} // TODO(vicb): add error management (structure)
47895// Extract messages as xml nodes from the xliff file
47896
47897
47898class XliffParser {
47899  constructor() {
47900    this._locale = null;
47901  }
47902
47903  parse(xliff, url) {
47904    this._unitMlString = null;
47905    this._msgIdToHtml = {};
47906    const xml = new XmlParser().parse(xliff, url);
47907    this._errors = xml.errors;
47908    visitAll(this, xml.rootNodes, null);
47909    return {
47910      msgIdToHtml: this._msgIdToHtml,
47911      errors: this._errors,
47912      locale: this._locale
47913    };
47914  }
47915
47916  visitElement(element, context) {
47917    switch (element.name) {
47918      case _UNIT_TAG$1:
47919        this._unitMlString = null;
47920        const idAttr = element.attrs.find(attr => attr.name === 'id');
47921
47922        if (!idAttr) {
47923          this._addError(element, `<${_UNIT_TAG$1}> misses the "id" attribute`);
47924        } else {
47925          const id = idAttr.value;
47926
47927          if (this._msgIdToHtml.hasOwnProperty(id)) {
47928            this._addError(element, `Duplicated translations for msg ${id}`);
47929          } else {
47930            visitAll(this, element.children, null);
47931
47932            if (typeof this._unitMlString === 'string') {
47933              this._msgIdToHtml[id] = this._unitMlString;
47934            } else {
47935              this._addError(element, `Message ${id} misses a translation`);
47936            }
47937          }
47938        }
47939
47940        break;
47941      // ignore those tags
47942
47943      case _SOURCE_TAG$1:
47944      case _SEGMENT_SOURCE_TAG:
47945      case _ALT_TRANS_TAG:
47946        break;
47947
47948      case _TARGET_TAG$1:
47949        const innerTextStart = element.startSourceSpan.end.offset;
47950        const innerTextEnd = element.endSourceSpan.start.offset;
47951        const content = element.startSourceSpan.start.file.content;
47952        const innerText = content.slice(innerTextStart, innerTextEnd);
47953        this._unitMlString = innerText;
47954        break;
47955
47956      case _FILE_TAG:
47957        const localeAttr = element.attrs.find(attr => attr.name === 'target-language');
47958
47959        if (localeAttr) {
47960          this._locale = localeAttr.value;
47961        }
47962
47963        visitAll(this, element.children, null);
47964        break;
47965
47966      default:
47967        // TODO(vicb): assert file structure, xliff version
47968        // For now only recurse on unhandled nodes
47969        visitAll(this, element.children, null);
47970    }
47971  }
47972
47973  visitAttribute(attribute, context) {}
47974
47975  visitText(text, context) {}
47976
47977  visitComment(comment, context) {}
47978
47979  visitExpansion(expansion, context) {}
47980
47981  visitExpansionCase(expansionCase, context) {}
47982
47983  _addError(node, message) {
47984    this._errors.push(new I18nError(node.sourceSpan, message));
47985  }
47986
47987} // Convert ml nodes (xliff syntax) to i18n nodes
47988
47989
47990class XmlToI18n$2 {
47991  convert(message, url) {
47992    const xmlIcu = new XmlParser().parse(message, url, {
47993      tokenizeExpansionForms: true
47994    });
47995    this._errors = xmlIcu.errors;
47996    const i18nNodes = this._errors.length > 0 || xmlIcu.rootNodes.length == 0 ? [] : [].concat(...visitAll(this, xmlIcu.rootNodes));
47997    return {
47998      i18nNodes: i18nNodes,
47999      errors: this._errors
48000    };
48001  }
48002
48003  visitText(text, context) {
48004    return new Text$2(text.value, text.sourceSpan);
48005  }
48006
48007  visitElement(el, context) {
48008    if (el.name === _PLACEHOLDER_TAG$2) {
48009      const nameAttr = el.attrs.find(attr => attr.name === 'id');
48010
48011      if (nameAttr) {
48012        return new Placeholder('', nameAttr.value, el.sourceSpan);
48013      }
48014
48015      this._addError(el, `<${_PLACEHOLDER_TAG$2}> misses the "id" attribute`);
48016
48017      return null;
48018    }
48019
48020    if (el.name === _MARKER_TAG$1) {
48021      return [].concat(...visitAll(this, el.children));
48022    }
48023
48024    this._addError(el, `Unexpected tag`);
48025
48026    return null;
48027  }
48028
48029  visitExpansion(icu, context) {
48030    const caseMap = {};
48031    visitAll(this, icu.cases).forEach(c => {
48032      caseMap[c.value] = new Container(c.nodes, icu.sourceSpan);
48033    });
48034    return new Icu(icu.switchValue, icu.type, caseMap, icu.sourceSpan);
48035  }
48036
48037  visitExpansionCase(icuCase, context) {
48038    return {
48039      value: icuCase.value,
48040      nodes: visitAll(this, icuCase.expression)
48041    };
48042  }
48043
48044  visitComment(comment, context) {}
48045
48046  visitAttribute(attribute, context) {}
48047
48048  _addError(node, message) {
48049    this._errors.push(new I18nError(node.sourceSpan, message));
48050  }
48051
48052}
48053
48054function getCtypeForTag(tag) {
48055  switch (tag.toLowerCase()) {
48056    case 'br':
48057      return 'lb';
48058
48059    case 'img':
48060      return 'image';
48061
48062    default:
48063      return `x-${tag}`;
48064  }
48065}
48066/**
48067 * @license
48068 * Copyright Google LLC All Rights Reserved.
48069 *
48070 * Use of this source code is governed by an MIT-style license that can be
48071 * found in the LICENSE file at https://angular.io/license
48072 */
48073
48074
48075const _VERSION = '2.0';
48076const _XMLNS = 'urn:oasis:names:tc:xliff:document:2.0'; // TODO(vicb): make this a param (s/_/-/)
48077
48078const _DEFAULT_SOURCE_LANG = 'en';
48079const _PLACEHOLDER_TAG$1 = 'ph';
48080const _PLACEHOLDER_SPANNING_TAG = 'pc';
48081const _MARKER_TAG = 'mrk';
48082const _XLIFF_TAG = 'xliff';
48083const _SOURCE_TAG = 'source';
48084const _TARGET_TAG = 'target';
48085const _UNIT_TAG = 'unit'; // https://docs.oasis-open.org/xliff/xliff-core/v2.0/os/xliff-core-v2.0-os.html
48086
48087class Xliff2 extends Serializer {
48088  write(messages, locale) {
48089    const visitor = new _WriteVisitor();
48090    const units = [];
48091    messages.forEach(message => {
48092      const unit = new Tag(_UNIT_TAG, {
48093        id: message.id
48094      });
48095      const notes = new Tag('notes');
48096
48097      if (message.description || message.meaning) {
48098        if (message.description) {
48099          notes.children.push(new CR(8), new Tag('note', {
48100            category: 'description'
48101          }, [new Text$1(message.description)]));
48102        }
48103
48104        if (message.meaning) {
48105          notes.children.push(new CR(8), new Tag('note', {
48106            category: 'meaning'
48107          }, [new Text$1(message.meaning)]));
48108        }
48109      }
48110
48111      message.sources.forEach(source => {
48112        notes.children.push(new CR(8), new Tag('note', {
48113          category: 'location'
48114        }, [new Text$1(`${source.filePath}:${source.startLine}${source.endLine !== source.startLine ? ',' + source.endLine : ''}`)]));
48115      });
48116      notes.children.push(new CR(6));
48117      unit.children.push(new CR(6), notes);
48118      const segment = new Tag('segment');
48119      segment.children.push(new CR(8), new Tag(_SOURCE_TAG, {}, visitor.serialize(message.nodes)), new CR(6));
48120      unit.children.push(new CR(6), segment, new CR(4));
48121      units.push(new CR(4), unit);
48122    });
48123    const file = new Tag('file', {
48124      'original': 'ng.template',
48125      id: 'ngi18n'
48126    }, [...units, new CR(2)]);
48127    const xliff = new Tag(_XLIFF_TAG, {
48128      version: _VERSION,
48129      xmlns: _XMLNS,
48130      srcLang: locale || _DEFAULT_SOURCE_LANG
48131    }, [new CR(2), file, new CR()]);
48132    return serialize([new Declaration({
48133      version: '1.0',
48134      encoding: 'UTF-8'
48135    }), new CR(), xliff, new CR()]);
48136  }
48137
48138  load(content, url) {
48139    // xliff to xml nodes
48140    const xliff2Parser = new Xliff2Parser();
48141    const {
48142      locale,
48143      msgIdToHtml,
48144      errors
48145    } = xliff2Parser.parse(content, url); // xml nodes to i18n nodes
48146
48147    const i18nNodesByMsgId = {};
48148    const converter = new XmlToI18n$1();
48149    Object.keys(msgIdToHtml).forEach(msgId => {
48150      const {
48151        i18nNodes,
48152        errors: e
48153      } = converter.convert(msgIdToHtml[msgId], url);
48154      errors.push(...e);
48155      i18nNodesByMsgId[msgId] = i18nNodes;
48156    });
48157
48158    if (errors.length) {
48159      throw new Error(`xliff2 parse errors:\n${errors.join('\n')}`);
48160    }
48161
48162    return {
48163      locale: locale,
48164      i18nNodesByMsgId
48165    };
48166  }
48167
48168  digest(message) {
48169    return decimalDigest(message);
48170  }
48171
48172}
48173
48174class _WriteVisitor {
48175  visitText(text, context) {
48176    return [new Text$1(text.value)];
48177  }
48178
48179  visitContainer(container, context) {
48180    const nodes = [];
48181    container.children.forEach(node => nodes.push(...node.visit(this)));
48182    return nodes;
48183  }
48184
48185  visitIcu(icu, context) {
48186    const nodes = [new Text$1(`{${icu.expressionPlaceholder}, ${icu.type}, `)];
48187    Object.keys(icu.cases).forEach(c => {
48188      nodes.push(new Text$1(`${c} {`), ...icu.cases[c].visit(this), new Text$1(`} `));
48189    });
48190    nodes.push(new Text$1(`}`));
48191    return nodes;
48192  }
48193
48194  visitTagPlaceholder(ph, context) {
48195    const type = getTypeForTag(ph.tag);
48196
48197    if (ph.isVoid) {
48198      const tagPh = new Tag(_PLACEHOLDER_TAG$1, {
48199        id: (this._nextPlaceholderId++).toString(),
48200        equiv: ph.startName,
48201        type: type,
48202        disp: `<${ph.tag}/>`
48203      });
48204      return [tagPh];
48205    }
48206
48207    const tagPc = new Tag(_PLACEHOLDER_SPANNING_TAG, {
48208      id: (this._nextPlaceholderId++).toString(),
48209      equivStart: ph.startName,
48210      equivEnd: ph.closeName,
48211      type: type,
48212      dispStart: `<${ph.tag}>`,
48213      dispEnd: `</${ph.tag}>`
48214    });
48215    const nodes = [].concat(...ph.children.map(node => node.visit(this)));
48216
48217    if (nodes.length) {
48218      nodes.forEach(node => tagPc.children.push(node));
48219    } else {
48220      tagPc.children.push(new Text$1(''));
48221    }
48222
48223    return [tagPc];
48224  }
48225
48226  visitPlaceholder(ph, context) {
48227    const idStr = (this._nextPlaceholderId++).toString();
48228    return [new Tag(_PLACEHOLDER_TAG$1, {
48229      id: idStr,
48230      equiv: ph.name,
48231      disp: `{{${ph.value}}}`
48232    })];
48233  }
48234
48235  visitIcuPlaceholder(ph, context) {
48236    const cases = Object.keys(ph.value.cases).map(value => value + ' {...}').join(' ');
48237    const idStr = (this._nextPlaceholderId++).toString();
48238    return [new Tag(_PLACEHOLDER_TAG$1, {
48239      id: idStr,
48240      equiv: ph.name,
48241      disp: `{${ph.value.expression}, ${ph.value.type}, ${cases}}`
48242    })];
48243  }
48244
48245  serialize(nodes) {
48246    this._nextPlaceholderId = 0;
48247    return [].concat(...nodes.map(node => node.visit(this)));
48248  }
48249
48250} // Extract messages as xml nodes from the xliff file
48251
48252
48253class Xliff2Parser {
48254  constructor() {
48255    this._locale = null;
48256  }
48257
48258  parse(xliff, url) {
48259    this._unitMlString = null;
48260    this._msgIdToHtml = {};
48261    const xml = new XmlParser().parse(xliff, url);
48262    this._errors = xml.errors;
48263    visitAll(this, xml.rootNodes, null);
48264    return {
48265      msgIdToHtml: this._msgIdToHtml,
48266      errors: this._errors,
48267      locale: this._locale
48268    };
48269  }
48270
48271  visitElement(element, context) {
48272    switch (element.name) {
48273      case _UNIT_TAG:
48274        this._unitMlString = null;
48275        const idAttr = element.attrs.find(attr => attr.name === 'id');
48276
48277        if (!idAttr) {
48278          this._addError(element, `<${_UNIT_TAG}> misses the "id" attribute`);
48279        } else {
48280          const id = idAttr.value;
48281
48282          if (this._msgIdToHtml.hasOwnProperty(id)) {
48283            this._addError(element, `Duplicated translations for msg ${id}`);
48284          } else {
48285            visitAll(this, element.children, null);
48286
48287            if (typeof this._unitMlString === 'string') {
48288              this._msgIdToHtml[id] = this._unitMlString;
48289            } else {
48290              this._addError(element, `Message ${id} misses a translation`);
48291            }
48292          }
48293        }
48294
48295        break;
48296
48297      case _SOURCE_TAG:
48298        // ignore source message
48299        break;
48300
48301      case _TARGET_TAG:
48302        const innerTextStart = element.startSourceSpan.end.offset;
48303        const innerTextEnd = element.endSourceSpan.start.offset;
48304        const content = element.startSourceSpan.start.file.content;
48305        const innerText = content.slice(innerTextStart, innerTextEnd);
48306        this._unitMlString = innerText;
48307        break;
48308
48309      case _XLIFF_TAG:
48310        const localeAttr = element.attrs.find(attr => attr.name === 'trgLang');
48311
48312        if (localeAttr) {
48313          this._locale = localeAttr.value;
48314        }
48315
48316        const versionAttr = element.attrs.find(attr => attr.name === 'version');
48317
48318        if (versionAttr) {
48319          const version = versionAttr.value;
48320
48321          if (version !== '2.0') {
48322            this._addError(element, `The XLIFF file version ${version} is not compatible with XLIFF 2.0 serializer`);
48323          } else {
48324            visitAll(this, element.children, null);
48325          }
48326        }
48327
48328        break;
48329
48330      default:
48331        visitAll(this, element.children, null);
48332    }
48333  }
48334
48335  visitAttribute(attribute, context) {}
48336
48337  visitText(text, context) {}
48338
48339  visitComment(comment, context) {}
48340
48341  visitExpansion(expansion, context) {}
48342
48343  visitExpansionCase(expansionCase, context) {}
48344
48345  _addError(node, message) {
48346    this._errors.push(new I18nError(node.sourceSpan, message));
48347  }
48348
48349} // Convert ml nodes (xliff syntax) to i18n nodes
48350
48351
48352class XmlToI18n$1 {
48353  convert(message, url) {
48354    const xmlIcu = new XmlParser().parse(message, url, {
48355      tokenizeExpansionForms: true
48356    });
48357    this._errors = xmlIcu.errors;
48358    const i18nNodes = this._errors.length > 0 || xmlIcu.rootNodes.length == 0 ? [] : [].concat(...visitAll(this, xmlIcu.rootNodes));
48359    return {
48360      i18nNodes,
48361      errors: this._errors
48362    };
48363  }
48364
48365  visitText(text, context) {
48366    return new Text$2(text.value, text.sourceSpan);
48367  }
48368
48369  visitElement(el, context) {
48370    switch (el.name) {
48371      case _PLACEHOLDER_TAG$1:
48372        const nameAttr = el.attrs.find(attr => attr.name === 'equiv');
48373
48374        if (nameAttr) {
48375          return [new Placeholder('', nameAttr.value, el.sourceSpan)];
48376        }
48377
48378        this._addError(el, `<${_PLACEHOLDER_TAG$1}> misses the "equiv" attribute`);
48379
48380        break;
48381
48382      case _PLACEHOLDER_SPANNING_TAG:
48383        const startAttr = el.attrs.find(attr => attr.name === 'equivStart');
48384        const endAttr = el.attrs.find(attr => attr.name === 'equivEnd');
48385
48386        if (!startAttr) {
48387          this._addError(el, `<${_PLACEHOLDER_TAG$1}> misses the "equivStart" attribute`);
48388        } else if (!endAttr) {
48389          this._addError(el, `<${_PLACEHOLDER_TAG$1}> misses the "equivEnd" attribute`);
48390        } else {
48391          const startId = startAttr.value;
48392          const endId = endAttr.value;
48393          const nodes = [];
48394          return nodes.concat(new Placeholder('', startId, el.sourceSpan), ...el.children.map(node =>
48394 node.visit(this, null)), new Placeholder('', endId, el.sourceSpan));
48395        }
48396
48397        break;
48398
48399      case _MARKER_TAG:
48400        return [].concat(...visitAll(this, el.children));
48401
48402      default:
48403        this._addError(el, `Unexpected tag`);
48404
48405    }
48406
48407    return null;
48408  }
48409
48410  visitExpansion(icu, context) {
48411    const caseMap = {};
48412    visitAll(this, icu.cases).forEach(c => {
48413      caseMap[c.value] = new Container(c.nodes, icu.sourceSpan);
48414    });
48415    return new Icu(icu.switchValue, icu.type, caseMap, icu.sourceSpan);
48416  }
48417
48418  visitExpansionCase(icuCase, context) {
48419    return {
48420      value: icuCase.value,
48421      nodes: [].concat(...visitAll(this, icuCase.expression))
48422    };
48423  }
48424
48425  visitComment(comment, context) {}
48426
48427  visitAttribute(attribute, context) {}
48428
48429  _addError(node, message) {
48430    this._errors.push(new I18nError(node.sourceSpan, message));
48431  }
48432
48433}
48434
48435function getTypeForTag(tag) {
48436  switch (tag.toLowerCase()) {
48437    case 'br':
48438    case 'b':
48439    case 'i':
48440    case 'u':
48441      return 'fmt';
48442
48443    case 'img':
48444      return 'image';
48445
48446    case 'a':
48447      return 'link';
48448
48449    default:
48450      return 'other';
48451  }
48452}
48453/**
48454 * @license
48455 * Copyright Google LLC All Rights Reserved.
48456 *
48457 * Use of this source code is governed by an MIT-style license that can be
48458 * found in the LICENSE file at https://angular.io/license
48459 */
48460
48461
48462const _TRANSLATIONS_TAG = 'translationbundle';
48463const _TRANSLATION_TAG = 'translation';
48464const _PLACEHOLDER_TAG = 'ph';
48465
48466class Xtb extends Serializer {
48467  write(messages, locale) {
48468    throw new Error('Unsupported');
48469  }
48470
48471  load(content, url) {
48472    // xtb to xml nodes
48473    const xtbParser = new XtbParser();
48474    const {
48475      locale,
48476      msgIdToHtml,
48477      errors
48478    } = xtbParser.parse(content, url); // xml nodes to i18n nodes
48479
48480    const i18nNodesByMsgId = {};
48481    const converter = new XmlToI18n(); // Because we should be able to load xtb files that rely on features not supported by angular,
48482    // we need to delay the conversion of html to i18n nodes so that non angular messages are not
48483    // converted
48484
48485    Object.keys(msgIdToHtml).forEach(msgId => {
48486      const valueFn = function () {
48487        const {
48488          i18nNodes,
48489          errors
48490        } = converter.convert(msgIdToHtml[msgId], url);
48491
48492        if (errors.length) {
48493          throw new Error(`xtb parse errors:\n${errors.join('\n')}`);
48494        }
48495
48496        return i18nNodes;
48497      };
48498
48499      createLazyProperty(i18nNodesByMsgId, msgId, valueFn);
48500    });
48501
48502    if (errors.length) {
48503      throw new Error(`xtb parse errors:\n${errors.join('\n')}`);
48504    }
48505
48506    return {
48507      locale: locale,
48508      i18nNodesByMsgId
48509    };
48510  }
48511
48512  digest(message) {
48513    return digest(message);
48514  }
48515
48516  createNameMapper(message) {
48517    return new SimplePlaceholderMapper(message, toPublicName);
48518  }
48519
48520}
48521
48522function createLazyProperty(messages, id, valueFn) {
48523  Object.defineProperty(messages, id, {
48524    configurable: true,
48525    enumerable: true,
48526    get: function () {
48527      const value = valueFn();
48528      Object.defineProperty(messages, id, {
48529        enumerable: true,
48530        value
48531      });
48532      return value;
48533    },
48534    set: _ => {
48535      throw new Error('Could not overwrite an XTB translation');
48536    }
48537  });
48538} // Extract messages as xml nodes from the xtb file
48539
48540
48541class XtbParser {
48542  constructor() {
48543    this._locale = null;
48544  }
48545
48546  parse(xtb, url) {
48547    this._bundleDepth = 0;
48548    this._msgIdToHtml = {}; // We can not parse the ICU messages at this point as some messages might not originate
48549    // from Angular that could not be lex'd.
48550
48551    const xml = new XmlParser().parse(xtb, url);
48552    this._errors = xml.errors;
48553    visitAll(this, xml.rootNodes);
48554    return {
48555      msgIdToHtml: this._msgIdToHtml,
48556      errors: this._errors,
48557      locale: this._locale
48558    };
48559  }
48560
48561  visitElement(element, context) {
48562    switch (element.name) {
48563      case _TRANSLATIONS_TAG:
48564        this._bundleDepth++;
48565
48566        if (this._bundleDepth > 1) {
48567          this._addError(element, `<${_TRANSLATIONS_TAG}> elements can not be nested`);
48568        }
48569
48570        const langAttr = element.attrs.find(attr => attr.name === 'lang');
48571
48572        if (langAttr) {
48573          this._locale = langAttr.value;
48574        }
48575
48576        visitAll(this, element.children, null);
48577        this._bundleDepth--;
48578        break;
48579
48580      case _TRANSLATION_TAG:
48581        const idAttr = element.attrs.find(attr => attr.name === 'id');
48582
48583        if (!idAttr) {
48584          this._addError(element, `<${_TRANSLATION_TAG}> misses the "id" attribute`);
48585        } else {
48586          const id = idAttr.value;
48587
48588          if (this._msgIdToHtml.hasOwnProperty(id)) {
48589            this._addError(element, `Duplicated translations for msg ${id}`);
48590          } else {
48591            const innerTextStart = element.startSourceSpan.end.offset;
48592            const innerTextEnd = element.endSourceSpan.start.offset;
48593            const content = element.startSourceSpan.start.file.content;
48594            const innerText = content.slice(innerTextStart, innerTextEnd);
48595            this._msgIdToHtml[id] = innerText;
48596          }
48597        }
48598
48599        break;
48600
48601      default:
48602        this._addError(element, 'Unexpected tag');
48603
48604    }
48605  }
48606
48607  visitAttribute(attribute, context) {}
48608
48609  visitText(text, context) {}
48610
48611  visitComment(comment, context) {}
48612
48613  visitExpansion(expansion, context) {}
48614
48615  visitExpansionCase(expansionCase, context) {}
48616
48617  _addError(node, message) {
48618    this._errors.push(new I18nError(node.sourceSpan, message));
48619  }
48620
48621} // Convert ml nodes (xtb syntax) to i18n nodes
48622
48623
48624class XmlToI18n {
48625  convert(message, url) {
48626    const xmlIcu = new XmlParser().parse(message, url, {
48627      tokenizeExpansionForms: true
48628    });
48629    this._errors = xmlIcu.errors;
48630    const i18nNodes = this._errors.length > 0 || xmlIcu.rootNodes.length == 0 ? [] : visitAll(this, xmlIcu.rootNodes);
48631    return {
48632      i18nNodes,
48633      errors: this._errors
48634    };
48635  }
48636
48637  visitText(text, context) {
48638    return new Text$2(text.value, text.sourceSpan);
48639  }
48640
48641  visitExpansion(icu, context) {
48642    const caseMap = {};
48643    visitAll(this, icu.cases).forEach(c => {
48644      caseMap[c.value] = new Container(c.nodes, icu.sourceSpan);
48645    });
48646    return new Icu(icu.switchValue, icu.type, caseMap, icu.sourceSpan);
48647  }
48648
48649  visitExpansionCase(icuCase, context) {
48650    return {
48651      value: icuCase.value,
48652      nodes: visitAll(this, icuCase.expression)
48653    };
48654  }
48655
48656  visitElement(el, context) {
48657    if (el.name === _PLACEHOLDER_TAG) {
48658      const nameAttr = el.attrs.find(attr => attr.name === 'name');
48659
48660      if (nameAttr) {
48661        return new Placeholder('', nameAttr.value, el.sourceSpan);
48662      }
48663
48664      this._addError(el, `<${_PLACEHOLDER_TAG}> misses the "name" attribute`);
48665    } else {
48666      this._addError(el, `Unexpected tag`);
48667    }
48668
48669    return null;
48670  }
48671
48672  visitComment(comment, context) {}
48673
48674  visitAttribute(attribute, context) {}
48675
48676  _addError(node, message) {
48677    this._errors.push(new I18nError(node.sourceSpan, message));
48678  }
48679
48680}
48681/**
48682 * @license
48683 * Copyright Google LLC All Rights Reserved.
48684 *
48685 * Use of this source code is governed by an MIT-style license that can be
48686 * found in the LICENSE file at https://angular.io/license
48687 */
48688
48689/**
48690 * A container for translated messages
48691 */
48692
48693
48694class TranslationBundle {
48695  constructor(_i18nNodesByMsgId = {}, locale, digest, mapperFactory, missingTranslationStrategy = MissingTranslationStrategy.Warning, console) {
48696    this._i18nNodesByMsgId = _i18nNodesByMsgId;
48697    this.digest = digest;
48698    this.mapperFactory = mapperFactory;
48699    this._i18nToHtml = new I18nToHtmlVisitor(_i18nNodesByMsgId, locale, digest, mapperFactory, missingTranslationStrategy, console);
48700  } // Creates a `TranslationBundle` by parsing the given `content` with the `serializer`.
48701
48702
48703  static load(content, url, serializer, missingTranslationStrategy, console) {
48704    const {
48705      locale,
48706      i18nNodesByMsgId
48707    } = serializer.load(content, url);
48708
48709    const digestFn = m => serializer.digest(m);
48710
48711    const mapperFactory = m => serializer.createNameMapper(m);
48712
48713    return new TranslationBundle(i18nNodesByMsgId, locale, digestFn, mapperFactory, missingTranslationStrategy, console);
48714  } // Returns the translation as HTML nodes from the given source message.
48715
48716
48717  get(srcMsg) {
48718    const html = this._i18nToHtml.convert(srcMsg);
48719
48720    if (html.errors.length) {
48721      throw new Error(html.errors.join('\n'));
48722    }
48723
48724    return html.nodes;
48725  }
48726
48727  has(srcMsg) {
48728    return this.digest(srcMsg) in this._i18nNodesByMsgId;
48729  }
48730
48731}
48732
48733class I18nToHtmlVisitor {
48734  constructor(_i18nNodesByMsgId = {}, _locale, _digest, _mapperFactory, _missingTranslationStrategy, _console) {
48735    this._i18nNodesByMsgId = _i18nNodesByMsgId;
48736    this._locale = _locale;
48737    this._digest = _digest;
48738    this._mapperFactory = _mapperFactory;
48739    this._missingTranslationStrategy = _missingTranslationStrategy;
48740    this._console = _console;
48741    this._contextStack = [];
48742    this._errors = [];
48743  }
48744
48745  convert(srcMsg) {
48746    this._contextStack.length = 0;
48747    this._errors.length = 0; // i18n to text
48748
48749    const text = this._convertToText(srcMsg); // text to html
48750
48751
48752    const url = srcMsg.nodes[0].sourceSpan.start.file.url;
48753    const html = new HtmlParser().parse(text, url, {
48754      tokenizeExpansionForms: true
48755    });
48756    return {
48757      nodes: html.rootNodes,
48758      errors: [...this._errors, ...html.errors]
48759    };
48760  }
48761
48762  visitText(text, context) {
48763    // `convert()` uses an `HtmlParser` to return `html.Node`s
48764    // we should then make sure that any special characters are escaped
48765    return escapeXml(text.value);
48766  }
48767
48768  visitContainer(container, context) {
48769    return container.children.map(n => n.visit(this)).join('');
48770  }
48771
48772  visitIcu(icu, context) {
48773    const cases = Object.keys(icu.cases).map(k => `${k} {${icu.cases[k].visit(this)}}`); // TODO(vicb): Once all format switch to using expression placeholders
48774    // we should throw when the placeholder is not in the source message
48775
48776    const exp = this._srcMsg.placeholders.hasOwnProperty(icu.expression) ? this._srcMsg.placeholders[icu.expression].text : icu.expression;
48777    return `{${exp}, ${icu.type}, ${cases.join(' ')}}`;
48778  }
48779
48780  visitPlaceholder(ph, context) {
48781    const phName = this._mapper(ph.name);
48782
48783    if (this._srcMsg.placeholders.hasOwnProperty(phName)) {
48784      return this._srcMsg.placeholders[phName].text;
48785    }
48786
48787    if (this._srcMsg.placeholderToMessage.hasOwnProperty(phName)) {
48788      return this._convertToText(this._srcMsg.placeholderToMessage[phName]);
48789    }
48790
48791    this._addError(ph, `Unknown placeholder "${ph.name}"`);
48792
48793    return '';
48794  } // Loaded message contains only placeholders (vs tag and icu placeholders).
48795  // However when a translation can not be found, we need to serialize the source message
48796  // which can contain tag placeholders
48797
48798
48799  visitTagPlaceholder(ph, context) {
48800    const tag = `${ph.tag}`;
48801    const attrs = Object.keys(ph.attrs).map(name => `${name}="${ph.attrs[name]}"`).join(' ');
48802
48803    if (ph.isVoid) {
48804      return `<${tag} ${attrs}/>`;
48805    }
48806
48807    const children = ph.children.map(c => c.visit(this)).join('');
48808    return `<${tag} ${attrs}>${children}</${tag}>`;
48809  } // Loaded message contains only placeholders (vs tag and icu placeholders).
48810  // However when a translation can not be found, we need to serialize the source message
48811  // which can contain tag placeholders
48812
48813
48814  visitIcuPlaceholder(ph, context) {
48815    // An ICU placeholder references the source message to be serialized
48816    return this._convertToText(this._srcMsg.placeholderToMessage[ph.name]);
48817  }
48818  /**
48819   * Convert a source message to a translated text string:
48820   * - text nodes are replaced with their translation,
48821   * - placeholders are replaced with their content,
48822   * - ICU nodes are converted to ICU expressions.
48823   */
48824
48825
48826  _convertToText(srcMsg) {
48827    const id = this._digest(srcMsg);
48828
48829    const mapper = this._mapperFactory ? this._mapperFactory(srcMsg) : null;
48830    let nodes;
48831
48832    this._contextStack.push({
48833      msg: this._srcMsg,
48834      mapper: this._mapper
48835    });
48836
48837    this._srcMsg = srcMsg;
48838
48839    if (this._i18nNodesByMsgId.hasOwnProperty(id)) {
48840      // When there is a translation use its nodes as the source
48841      // And create a mapper to convert serialized placeholder names to internal names
48842      nodes = this._i18nNodesByMsgId[id];
48843
48844      this._mapper = name => mapper ? mapper.toInternalName(name) : name;
48845    } else {
48846      // When no translation has been found
48847      // - report an error / a warning / nothing,
48848      // - use the nodes from the original message
48849      // - placeholders are already internal and need no mapper
48850      if (this._missingTranslationStrategy === MissingTranslationStrategy.Error) {
48851        const ctx = this._locale ? ` for locale "${this._locale}"` : '';
48852
48853        this._addError(srcMsg.nodes[0], `Missing translation for message "${id}"${ctx}`);
48854      } else if (this._console && this._missingTranslationStrategy === MissingTranslationStrategy.Warning) {
48855        const ctx = this._locale ? ` for locale "${this._locale}"` : '';
48856
48857        this._console.warn(`Missing translation for message "${id}"${ctx}`);
48858      }
48859
48860      nodes = srcMsg.nodes;
48861
48862      this._mapper = name => name;
48863    }
48864
48865    const text = nodes.map(node => node.visit(this)).join('');
48866
48867    const context = this._contextStack.pop();
48868
48869    this._srcMsg = context.msg;
48870    this._mapper = context.mapper;
48871    return text;
48872  }
48873
48874  _addError(el, msg) {
48875    this._errors.push(new I18nError(el.sourceSpan, msg));
48876  }
48877
48878}
48879/**
48880 * @license
48881 * Copyright Google LLC All Rights Reserved.
48882 *
48883 * Use of this source code is governed by an MIT-style license that can be
48884 * found in the LICENSE file at https://angular.io/license
48885 */
48886
48887
48888class I18NHtmlParser {
48889  constructor(_htmlParser, translations, translationsFormat, missingTranslation = MissingTranslationStrategy.Warning, console) {
48890    this._htmlParser = _htmlParser;
48891
48892    if (translations) {
48893      const serializer = createSerializer(translationsFormat);
48894      this._translationBundle = TranslationBundle.load(translations, 'i18n', serializer, missingTranslation, console);
48895    } else {
48896      this._translationBundle = new TranslationBundle({}, null, digest$1, undefined, missingTranslation, console);
48897    }
48898  }
48899
48900  parse(source, url, options = {}) {
48901    const interpolationConfig = options.interpolationConfig || DEFAULT_INTERPOLATION_CONFIG;
48902
48903    const parseResult = this._htmlParser.parse(source, url, {
48904      interpolationConfig,
48905      ...options
48906    });
48907
48908    if (parseResult.errors.length) {
48909      return new ParseTreeResult(parseResult.rootNodes, parseResult.errors);
48910    }
48911
48912    return mergeTranslations(parseResult.rootNodes, this._translationBundle, interpolationConfig, [], {});
48913  }
48914
48915}
48916
48917function createSerializer(format) {
48918  format = (format || 'xlf').toLowerCase();
48919
48920  switch (format) {
48921    case 'xmb':
48922      return new Xmb();
48923
48924    case 'xtb':
48925      return new Xtb();
48926
48927    case 'xliff2':
48928    case 'xlf2':
48929      return new Xliff2();
48930
48931    case 'xliff':
48932    case 'xlf':
48933    default:
48934      return new Xliff();
48935  }
48936}
48937/**
48938 * @license
48939 * Copyright Google LLC All Rights Reserved.
48940 *
48941 * Use of this source code is governed by an MIT-style license that can be
48942 * found in the LICENSE file at https://angular.io/license
48943 */
48944
48945/**
48946 * A container for message extracted from the templates.
48947 */
48948
48949
48950class MessageBundle {
48951  constructor(_htmlParser, _implicitTags, _implicitAttrs, _locale = null) {
48952    this._htmlParser = _htmlParser;
48953    this._implicitTags = _implicitTags;
48954    this._implicitAttrs = _implicitAttrs;
48955    this._locale = _locale;
48956    this._messages = [];
48957  }
48958
48959  updateFromTemplate(html, url, interpolationConfig) {
48960    const htmlParserResult = this._htmlParser.parse(html, url, {
48961      tokenizeExpansionForms: true,
48962      interpolationConfig
48963    });
48964
48965    if (htmlParserResult.errors.length) {
48966      return htmlParserResult.errors;
48967    }
48968
48969    const i18nParserResult = extractMessages(htmlParserResult.rootNodes, interpolationConfig, this._implicitTags, this._implicitAttrs);
48970
48971    if (i18nParserResult.errors.length) {
48972      return i18nParserResult.errors;
48973    }
48974
48975    this._messages.push(...i18nParserResult.messages);
48976
48977    return [];
48978  } // Return the message in the internal format
48979  // The public (serialized) format might be different, see the `write` method.
48980
48981
48982  getMessages() {
48983    return this._messages;
48984  }
48985
48986  write(serializer, filterSources) {
48987    const messages = {};
48988    const mapperVisitor = new MapPlaceholderNames(); // Deduplicate messages based on their ID
48989
48990    this._messages.forEach(message => {
48991      const id = serializer.digest(message);
48992
48993      if (!messages.hasOwnProperty(id)) {
48994        messages[id] = message;
48995      } else {
48996        messages[id].sources.push(...message.sources);
48997      }
48998    }); // Transform placeholder names using the serializer mapping
48999
49000
49001    const msgList = Object.keys(messages).map(id => {
49002      const mapper = serializer.createNameMapper(messages[id]);
49003      const src = messages[id];
49004      const nodes = mapper ? mapperVisitor.convert(src.nodes, mapper) : src.nodes;
49005      let transformedMessage = new Message(nodes, {}, {}, src.meaning, src.description, id);
49006      transformedMessage.sources = src.sources;
49007
49008      if (filterSources) {
49009        transformedMessage.sources.forEach(source => source.filePath = filterSources(source.filePath));
49010      }
49011
49012      return transformedMessage;
49013    });
49014    return serializer.write(msgList, this._locale);
49015  }
49016
49017} // Transform an i18n AST by renaming the placeholder nodes with the given mapper
49018
49019
49020class MapPlaceholderNames extends CloneVisitor {
49021  convert(nodes, mapper) {
49022    return mapper ? nodes.map(n => n.visit(this, mapper)) : nodes;
49023  }
49024
49025  visitTagPlaceholder(ph, mapper) {
49026    const startName = mapper.toPublicName(ph.startName);
49027    const closeName = ph.closeName ? mapper.toPublicName(ph.closeName) : ph.closeName;
49028    const children = ph.children.map(n => n.visit(this, mapper));
49029    return new TagPlaceholder(ph.tag, ph.attrs, startName, closeName, children, ph.isVoid, ph.sourceSpan, ph.startSourceSpan, ph.endSourceSpan);
49030  }
49031
49032  visitPlaceholder(ph, mapper) {
49033    return new Placeholder(ph.value, mapper.toPublicName(ph.name), ph.sourceSpan);
49034  }
49035
49036  visitIcuPlaceholder(ph, mapper) {
49037    return new IcuPlaceholder(ph.value, mapper.toPublicName(ph.name), ph.sourceSpan);
49038  }
49039
49040}
49041/**
49042 * @license
49043 * Copyright Google LLC All Rights Reserved.
49044 *
49045 * Use of this source code is governed by an MIT-style license that can be
49046 * found in the LICENSE file at https://angular.io/license
49047 */
49048
49049
49050var FactoryTarget;
49051
49052(function (FactoryTarget) {
49053  FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
49054  FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
49055  FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
49056  FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
49057  FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
49058})(FactoryTarget || (FactoryTarget = {}));
49059/**
49060 * @license
49061 * Copyright Google LLC All Rights Reserved.
49062 *
49063 * Use of this source code is governed by an MIT-style license that can be
49064 * found in the LICENSE file at https://angular.io/license
49065 */
49066
49067/**
49068 * @license
49069 * Copyright Google LLC All Rights Reserved.
49070 *
49071 * Use of this source code is governed by an MIT-style license that can be
49072 * found in the LICENSE file at https://angular.io/license
49073 */
49074
49075/**
49076 * Processes `Target`s with a given set of directives and performs a binding operation, which
49077 * returns an object similar to TypeScript's `ts.TypeChecker` that contains knowledge about the
49078 * target.
49079 */
49080
49081
49082class R3TargetBinder {
49083  constructor(directiveMatcher) {
49084    this.directiveMatcher = directiveMatcher;
49085  }
49086  /**
49087   * Perform a binding operation on the given `Target` and return a `BoundTarget` which contains
49088   * metadata about the types referenced in the template.
49089   */
49090
49091
49092  bind(target) {
49093    if (!target.template) {
49094      // TODO(alxhub): handle targets which contain things like HostBindings, etc.
49095      throw new Error('Binding without a template not yet supported');
49096    } // First, parse the template into a `Scope` structure. This operation captures the syntactic
49097    // scopes in the template and makes them available for later use.
49098
49099
49100    const scope = Scope.apply(target.template); // Use the `Scope` to extract the entities present at every level of the template.
49101
49102    const templateEntities = extractTemplateEntities(scope); // Next, perform directive matching on the template using the `DirectiveBinder`. This returns:
49103    //   - directives: Map of nodes (elements & ng-templates) to the directives on them.
49104    //   - bindings: Map of inputs, outputs, and attributes to the directive/element that claims
49105    //     them. TODO(alxhub): handle multiple directives claiming an input/output/etc.
49106    //   - references: Map of #references to their targets.
49107
49108    const {
49109      directives,
49110      bindings,
49111      references
49112    } = DirectiveBinder.apply(target.template, this.directiveMatcher); // Finally, run the TemplateBinder to bind references, variables, and other entities within the
49113    // template. This extracts all the metadata that doesn't depend on directive matching.
49114
49115    const {
49116      expressions,
49117      symbols,
49118      nestingLevel,
49119      usedPipes
49120    } = TemplateBinder.applyWithScope(target.template, scope);
49121    return new R3BoundTarget(target, directives, bindings, references, expressions, symbols, nestingLevel, templateEntities, usedPipes);
49122  }
49123
49124}
49125/**
49126 * Represents a binding scope within a template.
49127 *
49128 * Any variables, references, or other named entities declared within the template will
49129 * be captured and available by name in `namedEntities`. Additionally, child templates will
49130 * be analyzed and have their child `Scope`s available in `childScopes`.
49131 */
49132
49133
49134class Scope {
49135  constructor(parentScope, template) {
49136    this.parentScope = parentScope;
49137    this.template = template;
49138    /**
49139     * Named members of the `Scope`, such as `Reference`s or `Variable`s.
49140     */
49141
49142    this.namedEntities = new Map();
49143    /**
49144     * Child `Scope`s for immediately nested `Template`s.
49145     */
49146
49147    this.childScopes = new Map();
49148  }
49149
49150  static newRootScope() {
49151    return new Scope(null, null);
49152  }
49153  /**
49154   * Process a template (either as a `Template` sub-template with variables, or a plain array of
49155   * template `Node`s) and construct its `Scope`.
49156   */
49157
49158
49159  static apply(template) {
49160    const scope = Scope.newRootScope();
49161    scope.ingest(template);
49162    return scope;
49163  }
49164  /**
49165   * Internal method to process the template and populate the `Scope`.
49166   */
49167
49168
49169  ingest(template) {
49170    if (template instanceof Template) {
49171      // Variables on an <ng-template> are defined in the inner scope.
49172      template.variables.forEach(node => this.visitVariable(node)); // Process the nodes of the template.
49173
49174      template.children.forEach(node => node.visit(this));
49175    } else {
49176      // No overarching `Template` instance, so process the nodes directly.
49177      template.forEach(node => node.visit(this));
49178    }
49179  }
49180
49181  visitElement(element) {
49182    // `Element`s in the template may have `Reference`s which are captured in the scope.
49183    element.references.forEach(node => this.visitReference(node)); // Recurse into the `Element`'s children.
49184
49185    element.children.forEach(node => node.visit(this));
49186  }
49187
49188  visitTemplate(template) {
49189    // References on a <ng-template> are defined in the outer scope, so capture them before
49190    // processing the template's child scope.
49191    template.references.forEach(node => this.visitReference(node)); // Next, create an inner scope and process the template within it.
49192
49193    const scope = new Scope(this, template);
49194    scope.ingest(template);
49195    this.childScopes.set(template, scope);
49196  }
49197
49198  visitVariable(variable) {
49199    // Declare the variable if it's not already.
49200    this.maybeDeclare(variable);
49201  }
49202
49203  visitReference(reference) {
49204    // Declare the variable if it's not already.
49205    this.maybeDeclare(reference);
49206  } // Unused visitors.
49207
49208
49209  visitContent(content) {}
49210
49211  visitBoundAttribute(attr) {}
49212
49213  visitBoundEvent(event) {}
49214
49215  visitBoundText(text) {}
49216
49217  visitText(text) {}
49218
49219  visitTextAttribute(attr) {}
49220
49221  visitIcu(icu) {}
49222
49223  maybeDeclare(thing) {
49224    // Declare something with a name, as long as that name isn't taken.
49225    if (!this.namedEntities.has(thing.name)) {
49226      this.namedEntities.set(thing.name, thing);
49227    }
49228  }
49229  /**
49230   * Look up a variable within this `Scope`.
49231   *
49232   * This can recurse into a parent `Scope` if it's available.
49233   */
49234
49235
49236  lookup(name) {
49237    if (this.namedEntities.has(name)) {
49238      // Found in the local scope.
49239      return this.namedEntities.get(name);
49240    } else if (this.parentScope !== null) {
49241      // Not in the local scope, but there's a parent scope so check there.
49242      return this.parentScope.lookup(name);
49243    } else {
49244      // At the top level and it wasn't found.
49245      return null;
49246    }
49247  }
49248  /**
49249   * Get the child scope for a `Template`.
49250   *
49251   * This should always be defined.
49252   */
49253
49254
49255  getChildScope(template) {
49256    const res = this.childScopes.get(template);
49257
49258    if (res === undefined) {
49259      throw new Error(`Assertion error: child scope for ${template} not found`);
49260    }
49261
49262    return res;
49263  }
49264
49265}
49266/**
49267 * Processes a template and matches directives on nodes (elements and templates).
49268 *
49269 * Usually used via the static `apply()` method.
49270 */
49271
49272
49273class DirectiveBinder {
49274  constructor(matcher, directives, bindings, references) {
49275    this.matcher = matcher;
49276    this.directives = directives;
49277    this.bindings = bindings;
49278    this.references = references;
49279  }
49280  /**
49281   * Process a template (list of `Node`s) and perform directive matching against each node.
49282   *
49283   * @param template the list of template `Node`s to match (recursively).
49284   * @param selectorMatcher a `SelectorMatcher` containing the directives that are in scope for
49285   * this template.
49286   * @returns three maps which contain information about directives in the template: the
49287   * `directives` map which lists directives matched on each node, the `bindings` map which
49288   * indicates which directives claimed which bindings (inputs, outputs, etc), and the `references`
49289   * map which resolves #references (`Reference`s) within the template to the named directive or
49290   * template node.
49291   */
49292
49293
49294  static apply(template, selectorMatcher) {
49295    const directives = new Map();
49296    const bindings = new Map();
49297    const references = new Map();
49298    const matcher = new DirectiveBinder(selectorMatcher, directives, bindings, references);
49299    matcher.ingest(template);
49300    return {
49301      directives,
49302      bindings,
49303      references
49304    };
49305  }
49306
49307  ingest(template) {
49308    template.forEach(node =>
49308 node.visit(this));
49309  }
49310
49311  visitElement(element) {
49312    this.visitElementOrTemplate(element.name, element);
49313  }
49314
49315  visitTemplate(template) {
49316    this.visitElementOrTemplate('ng-template', template);
49317  }
49318
49319  visitElementOrTemplate(elementName, node) {
49320    // First, determine the HTML shape of the node for the purpose of directive matching.
49321    // Do this by building up a `CssSelector` for the node.
49322    const cssSelector = createCssSelector(elementName, getAttrsForDirectiveMatching(node)); // Next, use the `SelectorMatcher` to get the list of directives on the node.
49323
49324    const directives = [];
49325    this.matcher.match(cssSelector, (_, directive) => directives.push(directive));
49326
49327    if (directives.length > 0) {
49328      this.directives.set(node, directives);
49329    } // Resolve any references that are created on this node.
49330
49331
49332    node.references.forEach(ref => {
49333      let dirTarget = null; // If the reference expression is empty, then it matches the "primary" directive on the node
49334      // (if there is one). Otherwise it matches the host node itself (either an element or
49335      // <ng-template> node).
49336
49337      if (ref.value.trim() === '') {
49338        // This could be a reference to a component if there is one.
49339        dirTarget = directives.find(dir => dir.isComponent) || null;
49340      } else {
49341        // This should be a reference to a directive exported via exportAs.
49342        dirTarget = directives.find(dir => dir.exportAs !== null && dir.exportAs.some(value => value === ref.value)) || null; // Check if a matching directive was found.
49343
49344        if (dirTarget === null) {
49345          // No matching directive was found - this reference points to an unknown target. Leave it
49346          // unmapped.
49347          return;
49348        }
49349      }
49350
49351      if (dirTarget !== null) {
49352        // This reference points to a directive.
49353        this.references.set(ref, {
49354          directive: dirTarget,
49355          node
49356        });
49357      } else {
49358        // This reference points to the node itself.
49359        this.references.set(ref, node);
49360      }
49361    });
49362
49363    const setAttributeBinding = (attribute, ioType) => {
49364      const dir = directives.find(dir => dir[ioType].hasBindingPropertyName(attribute.name));
49365      const binding = dir !== undefined ? dir : node;
49366      this.bindings.set(attribute, binding);
49367    }; // Node inputs (bound attributes) and text attributes can be bound to an
49368    // input on a directive.
49369
49370
49371    node.inputs.forEach(input => setAttributeBinding(input, 'inputs'));
49372    node.attributes.forEach(attr => setAttributeBinding(attr, 'inputs'));
49373
49374    if (node instanceof Template) {
49375      node.templateAttrs.forEach(attr => setAttributeBinding(attr, 'inputs'));
49376    } // Node outputs (bound events) can be bound to an output on a directive.
49377
49378
49379    node.outputs.forEach(output => setAttributeBinding(output, 'outputs')); // Recurse into the node's children.
49380
49381    node.children.forEach(child => child.visit(this));
49382  } // Unused visitors.
49383
49384
49385  visitContent(content) {}
49386
49387  visitVariable(variable) {}
49388
49389  visitReference(reference) {}
49390
49391  visitTextAttribute(attribute) {}
49392
49393  visitBoundAttribute(attribute) {}
49394
49395  visitBoundEvent(attribute) {}
49396
49397  visitBoundAttributeOrEvent(node) {}
49398
49399  visitText(text) {}
49400
49401  visitBoundText(text) {}
49402
49403  visitIcu(icu) {}
49404
49405}
49406/**
49407 * Processes a template and extract metadata about expressions and symbols within.
49408 *
49409 * This is a companion to the `DirectiveBinder` that doesn't require knowledge of directives matched
49410 * within the template in order to operate.
49411 *
49412 * Expressions are visited by the superclass `RecursiveAstVisitor`, with custom logic provided
49413 * by overridden methods from that visitor.
49414 */
49415
49416
49417class TemplateBinder extends RecursiveAstVisitor {
49418  constructor(bindings, symbols, usedPipes, nestingLevel, scope, template, level) {
49419    super();
49420    this.bindings = bindings;
49421    this.symbols = symbols;
49422    this.usedPipes = usedPipes;
49423    this.nestingLevel = nestingLevel;
49424    this.scope = scope;
49425    this.template = template;
49426    this.level = level;
49427    this.pipesUsed = []; // Save a bit of processing time by constructing this closure in advance.
49428
49429    this.visitNode = node =>
49429 node.visit(this);
49430  } // This method is defined to reconcile the type of TemplateBinder since both
49431  // RecursiveAstVisitor and Visitor define the visit() method in their
49432  // interfaces.
49433
49434
49435  visit(node, context) {
49436    if (node instanceof AST) {
49437      node.visit(this, context);
49438    } else {
49439      node.visit(this);
49440    }
49441  }
49442  /**
49443   * Process a template and extract metadata about expressions and symbols within.
49444   *
49445   * @param template the nodes of the template to process
49446   * @param scope the `Scope` of the template being processed.
49447   * @returns three maps which contain metadata about the template: `expressions` which interprets
49448   * special `AST` nodes in expressions as pointing to references or variables declared within the
49449   * template, `symbols` which maps those variables and references to the nested `Template` which
49450   * declares them, if any, and `nestingLevel` which associates each `Template` with a integer
49451   * nesting level (how many levels deep within the template structure the `Template` is), starting
49452   * at 1.
49453   */
49454
49455
49456  static applyWithScope(template, scope) {
49457    const expressions = new Map();
49458    const symbols = new Map();
49459    const nestingLevel = new Map();
49460    const usedPipes = new Set(); // The top-level template has nesting level 0.
49461
49462    const binder = new TemplateBinder(expressions, symbols, usedPipes, nestingLevel, scope, template instanceof Template ? template : null, 0);
49463    binder.ingest(template);
49464    return {
49465      expressions,
49466      symbols,
49467      nestingLevel,
49468      usedPipes
49469    };
49470  }
49471
49472  ingest(template) {
49473    if (template instanceof Template) {
49474      // For <ng-template>s, process only variables and child nodes. Inputs, outputs, templateAttrs,
49475      // and references were all processed in the scope of the containing template.
49476      template.variables.forEach(this.visitNode);
49477      template.children.forEach(this.visitNode); // Set the nesting level.
49478
49479      this.nestingLevel.set(template, this.level);
49480    } else {
49481      // Visit each node from the top-level template.
49482      template.forEach(this.visitNode);
49483    }
49484  }
49485
49486  visitElement(element) {
49487    // Visit the inputs, outputs, and children of the element.
49488    element.inputs.forEach(this.visitNode);
49489    element.outputs.forEach(this.visitNode);
49490    element.children.forEach(this.visitNode);
49491  }
49492
49493  visitTemplate(template) {
49494    // First, visit inputs, outputs and template attributes of the template node.
49495    template.inputs.forEach(this.visitNode);
49496    template.outputs.forEach(this.visitNode);
49497    template.templateAttrs.forEach(this.visitNode); // References are also evaluated in the outer context.
49498
49499    template.references.forEach(this.visitNode); // Next, recurse into the template using its scope, and bumping the nesting level up by one.
49500
49501    const childScope = this.scope.getChildScope(template);
49502    const binder = new TemplateBinder(this.bindings, this.symbols, this.usedPipes, this.nestingLevel, childScope, template, this.level + 1);
49503    binder.ingest(template);
49504  }
49505
49506  visitVariable(variable) {
49507    // Register the `Variable` as a symbol in the current `Template`.
49508    if (this.template !== null) {
49509      this.symbols.set(variable, this.template);
49510    }
49511  }
49512
49513  visitReference(reference) {
49514    // Register the `Reference` as a symbol in the current `Template`.
49515    if (this.template !== null) {
49516      this.symbols.set(reference, this.template);
49517    }
49518  } // Unused template visitors
49519
49520
49521  visitText(text) {}
49522
49523  visitContent(content) {}
49524
49525  visitTextAttribute(attribute) {}
49526
49527  visitIcu(icu) {
49528    Object.keys(icu.vars).forEach(key => icu.vars[key].visit(this));
49529    Object.keys(icu.placeholders).forEach(key => icu.placeholders[key].visit(this));
49530  } // The remaining visitors are concerned with processing AST expressions within template bindings
49531
49532
49533  visitBoundAttribute(attribute) {
49534    attribute.value.visit(this);
49535  }
49536
49537  visitBoundEvent(event) {
49538    event.handler.visit(this);
49539  }
49540
49541  visitBoundText(text) {
49542    text.value.visit(this);
49543  }
49544
49545  visitPipe(ast, context) {
49546    this.usedPipes.add(ast.name);
49547    return super.visitPipe(ast, context);
49548  } // These five types of AST expressions can refer to expression roots, which could be variables
49549  // or references in the current scope.
49550
49551
49552  visitPropertyRead(ast, context) {
49553    this.maybeMap(context, ast, ast.name);
49554    return super.visitPropertyRead(ast, context);
49555  }
49556
49557  visitSafePropertyRead(ast, context) {
49558    this.maybeMap(context, ast, ast.name);
49559    return super.visitSafePropertyRead(ast, context);
49560  }
49561
49562  visitPropertyWrite(ast, context) {
49563    this.maybeMap(context, ast, ast.name);
49564    return super.visitPropertyWrite(ast, context);
49565  }
49566
49567  maybeMap(scope, ast, name) {
49568    // If the receiver of the expression isn't the `ImplicitReceiver`, this isn't the root of an
49569    // `AST` expression that maps to a `Variable` or `Reference`.
49570    if (!(ast.receiver instanceof ImplicitReceiver)) {
49571      return;
49572    } // Check whether the name exists in the current scope. If so, map it. Otherwise, the name is
49573    // probably a property on the top-level component context.
49574
49575
49576    let target = this.scope.lookup(name);
49577
49578    if (target !== null) {
49579      this.bindings.set(ast, target);
49580    }
49581  }
49582
49583}
49584/**
49585 * Metadata container for a `Target` that allows queries for specific bits of metadata.
49586 *
49587 * See `BoundTarget` for documentation on the individual methods.
49588 */
49589
49590
49591class R3BoundTarget {
49592  constructor(target, directives, bindings, references, exprTargets, symbols, nestingLevel, templateEntities, usedPipes) {
49593    this.target = target;
49594    this.directives = directives;
49595    this.bindings = bindings;
49596    this.references = references;
49597    this.exprTargets = exprTargets;
49598    this.symbols = symbols;
49599    this.nestingLevel = nestingLevel;
49600    this.templateEntities = templateEntities;
49601    this.usedPipes = usedPipes;
49602  }
49603
49604  getEntitiesInTemplateScope(template) {
49605    return this.templateEntities.get(template) ?? new Set();
49606  }
49607
49608  getDirectivesOfNode(node) {
49609    return this.directives.get(node) || null;
49610  }
49611
49612  getReferenceTarget(ref) {
49613    return this.references.get(ref) || null;
49614  }
49615
49616  getConsumerOfBinding(binding) {
49617    return this.bindings.get(binding) || null;
49618  }
49619
49620  getExpressionTarget(expr) {
49621    return this.exprTargets.get(expr) || null;
49622  }
49623
49624  getTemplateOfSymbol(symbol) {
49625    return this.symbols.get(symbol) || null;
49626  }
49627
49628  getNestingLevel(template) {
49629    return this.nestingLevel.get(template) || 0;
49630  }
49631
49632  getUsedDirectives() {
49633    const set = new Set();
49634    this.directives.forEach(dirs => dirs.forEach(dir => set.add(dir)));
49635    return Array.from(set.values());
49636  }
49637
49638  getUsedPipes() {
49639    return Array.from(this.usedPipes);
49640  }
49641
49642}
49643
49644function extractTemplateEntities(rootScope) {
49645  const entityMap = new Map();
49646
49647  function extractScopeEntities(scope) {
49648    if (entityMap.has(scope.template)) {
49649      return entityMap.get(scope.template);
49650    }
49651
49652    const currentEntities = scope.namedEntities;
49653    let templateEntities;
49654
49655    if (scope.parentScope !== null) {
49656      templateEntities = new Map([...extractScopeEntities(scope.parentScope), ...currentEntities]);
49657    } else {
49658      templateEntities = new Map(currentEntities);
49659    }
49660
49661    entityMap.set(scope.template, templateEntities);
49662    return templateEntities;
49663  }
49664
49665  const scopesToProcess = [rootScope];
49666
49667  while (scopesToProcess.length > 0) {
49668    const scope = scopesToProcess.pop();
49669
49670    for (const childScope of scope.childScopes.values()) {
49671      scopesToProcess.push(childScope);
49672    }
49673
49674    extractScopeEntities(scope);
49675  }
49676
49677  const templateEntities = new Map();
49678
49679  for (const [template, entities] of entityMap) {
49680    templateEntities.set(template, new Set(entities.values()));
49681  }
49682
49683  return templateEntities;
49684}
49685/**
49686 * @license
49687 * Copyright Google LLC All Rights Reserved.
49688 *
49689 * Use of this source code is governed by an MIT-style license that can be
49690 * found in the LICENSE file at https://angular.io/license
49691 */
49692
49693
49694function compileClassMetadata(metadata) {
49695  // Generate an ngDevMode guarded call to setClassMetadata with the class identifier and its
49696  // metadata.
49697  const fnCall = importExpr(Identifiers.setClassMetadata).callFn([metadata.type, metadata.decorators, metadata.ctorParameters ?? literal(null), metadata.propDecorators ?? literal(null)]);
49698  const iife = fn([], [devOnlyGuardedExpression(fnCall).toStmt()]);
49699  return iife.callFn([]);
49700}
49701/**
49702 * @license
49703 * Copyright Google LLC All Rights Reserved.
49704 *
49705 * Use of this source code is governed by an MIT-style license that can be
49706 * found in the LICENSE file at https://angular.io/license
49707 */
49708
49709/**
49710 * Every time we make a breaking change to the declaration interface or partial-linker behavior, we
49711 * must update this constant to prevent old partial-linkers from incorrectly processing the
49712 * declaration.
49713 *
49714 * Do not include any prerelease in these versions as they are ignored.
49715 */
49716
49717
49718const MINIMUM_PARTIAL_LINKER_VERSION$6 = '12.0.0';
49719
49720function compileDeclareClassMetadata(metadata) {
49721  const definitionMap = new DefinitionMap();
49722  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
49723  definitionMap.set('version', literal('14.2.10'));
49724  definitionMap.set('ngImport', importExpr(Identifiers.core));
49725  definitionMap.set('type', metadata.type);
49726  definitionMap.set('decorators', metadata.decorators);
49727  definitionMap.set('ctorParameters', metadata.ctorParameters);
49728  definitionMap.set('propDecorators', metadata.propDecorators);
49729  return importExpr(Identifiers.declareClassMetadata).callFn([definitionMap.toLiteralMap()]);
49730}
49731/**
49732 * @license
49733 * Copyright Google LLC All Rights Reserved.
49734 *
49735 * Use of this source code is governed by an MIT-style license that can be
49736 * found in the LICENSE file at https://angular.io/license
49737 */
49738
49739/**
49740 * Creates an array literal expression from the given array, mapping all values to an expression
49741 * using the provided mapping function. If the array is empty or null, then null is returned.
49742 *
49743 * @param values The array to transfer into literal array expression.
49744 * @param mapper The logic to use for creating an expression for the array's values.
49745 * @returns An array literal expression representing `values`, or null if `values` is empty or
49746 * is itself null.
49747 */
49748
49749
49750function toOptionalLiteralArray(values, mapper) {
49751  if (values === null || values.length === 0) {
49752    return null;
49753  }
49754
49755  return literalArr(values.map(value => mapper(value)));
49756}
49757/**
49758 * Creates an object literal expression from the given object, mapping all values to an expression
49759 * using the provided mapping function. If the object has no keys, then null is returned.
49760 *
49761 * @param object The object to transfer into an object literal expression.
49762 * @param mapper The logic to use for creating an expression for the object's values.
49763 * @returns An object literal expression representing `object`, or null if `object` does not have
49764 * any keys.
49765 */
49766
49767
49768function toOptionalLiteralMap(object, mapper) {
49769  const entries = Object.keys(object).map(key => {
49770    const value = object[key];
49771    return {
49772      key,
49773      value: mapper(value),
49774      quoted: true
49775    };
49776  });
49777
49778  if (entries.length > 0) {
49779    return literalMap(entries);
49780  } else {
49781    return null;
49782  }
49783}
49784
49785function compileDependencies(deps) {
49786  if (deps === 'invalid') {
49787    // The `deps` can be set to the string "invalid"  by the `unwrapConstructorDependencies()`
49788    // function, which tries to convert `ConstructorDeps` into `R3DependencyMetadata[]`.
49789    return literal('invalid');
49790  } else if (deps === null) {
49791    return literal(null);
49792  } else {
49793    return literalArr(deps.map(compileDependency));
49794  }
49795}
49796
49797function compileDependency(dep) {
49798  const depMeta = new DefinitionMap();
49799  depMeta.set('token', dep.token);
49800
49801  if (dep.attributeNameType !== null) {
49802    depMeta.set('attribute', literal(true));
49803  }
49804
49805  if (dep.host) {
49806    depMeta.set('host', literal(true));
49807  }
49808
49809  if (dep.optional) {
49810    depMeta.set('optional', literal(true));
49811  }
49812
49813  if (dep.self) {
49814    depMeta.set('self', literal(true));
49815  }
49816
49817  if (dep.skipSelf) {
49818    depMeta.set('skipSelf', literal(true));
49819  }
49820
49821  return depMeta.toLiteralMap();
49822}
49823/**
49824 * @license
49825 * Copyright Google LLC All Rights Reserved.
49826 *
49827 * Use of this source code is governed by an MIT-style license that can be
49828 * found in the LICENSE file at https://angular.io/license
49829 */
49830
49831/**
49832 * Every time we make a breaking change to the declaration interface or partial-linker behavior, we
49833 * must update this constant to prevent old partial-linkers from incorrectly processing the
49834 * declaration.
49835 *
49836 * Do not include any prerelease in these versions as they are ignored.
49837 */
49838
49839
49840const MINIMUM_PARTIAL_LINKER_VERSION$5 = '14.0.0';
49841/**
49842 * Compile a directive declaration defined by the `R3DirectiveMetadata`.
49843 */
49844
49845function compileDeclareDirectiveFromMetadata(meta) {
49846  const definitionMap = createDirectiveDefinitionMap(meta);
49847  const expression = importExpr(Identifiers.declareDirective).callFn([definitionMap.toLiteralMap()]);
49848  const type = createDirectiveType(meta);
49849  return {
49850    expression,
49851    type,
49852    statements: []
49853  };
49854}
49855/**
49856 * Gathers the declaration fields for a directive into a `DefinitionMap`. This allows for reusing
49857 * this logic for components, as they extend the directive metadata.
49858 */
49859
49860
49861function createDirectiveDefinitionMap(meta) {
49862  const definitionMap = new DefinitionMap();
49863  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
49864  definitionMap.set('version', literal('14.2.10')); // e.g. `type: MyDirective`
49865
49866  definitionMap.set('type', meta.internalType);
49867
49868  if (meta.isStandalone) {
49869    definitionMap.set('isStandalone', literal(meta.isStandalone));
49870  } // e.g. `selector: 'some-dir'`
49871
49872
49873  if (meta.selector !== null) {
49874    definitionMap.set('selector', literal(meta.selector));
49875  }
49876
49877  definitionMap.set('inputs', conditionallyCreateMapObjectLiteral(meta.inputs, true));
49878  definitionMap.set('outputs', conditionallyCreateMapObjectLiteral(meta.outputs));
49879  definitionMap.set('host', compileHostMetadata(meta.host));
49880  definitionMap.set('providers', meta.providers);
49881
49882  if (meta.queries.length > 0) {
49883    definitionMap.set('queries', literalArr(meta.queries.map(compileQuery)));
49884  }
49885
49886  if (meta.viewQueries.length > 0) {
49887    definitionMap.set('viewQueries', literalArr(meta.viewQueries.map(compileQuery)));
49888  }
49889
49890  if (meta.exportAs !== null) {
49891    definitionMap.set('exportAs', asLiteral(meta.exportAs));
49892  }
49893
49894  if (meta.usesInheritance) {
49895    definitionMap.set('usesInheritance', literal(true));
49896  }
49897
49898  if (meta.lifecycle.usesOnChanges) {
49899    definitionMap.set('usesOnChanges', literal(true));
49900  }
49901
49902  definitionMap.set('ngImport', importExpr(Identifiers.core));
49903  return definitionMap;
49904}
49905/**
49906 * Compiles the metadata of a single query into its partial declaration form as declared
49907 * by `R3DeclareQueryMetadata`.
49908 */
49909
49910
49911function compileQuery(query) {
49912  const meta = new DefinitionMap();
49913  meta.set('propertyName', literal(query.propertyName));
49914
49915  if (query.first) {
49916    meta.set('first', literal(true));
49917  }
49918
49919  meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) : convertFromMaybeForwardRefExpression(query.predicate));
49920
49921  if (!query.emitDistinctChangesOnly) {
49922    // `emitDistinctChangesOnly` is special because we expect it to be `true`.
49923    // Therefore we explicitly emit the field, and explicitly place it only when it's `false`.
49924    meta.set('emitDistinctChangesOnly', literal(false));
49925  } else {// The linker will assume that an absent `emitDistinctChangesOnly` flag is by default `true`.
49926  }
49927
49928  if (query.descendants) {
49929    meta.set('descendants', literal(true));
49930  }
49931
49932  meta.set('read', query.read);
49933
49934  if (query.static) {
49935    meta.set('static', literal(true));
49936  }
49937
49938  return meta.toLiteralMap();
49939}
49940/**
49941 * Compiles the host metadata into its partial declaration form as declared
49942 * in `R3DeclareDirectiveMetadata['host']`
49943 */
49944
49945
49946function compileHostMetadata(meta) {
49947  const hostMetadata = new DefinitionMap();
49948  hostMetadata.set('attributes', toOptionalLiteralMap(meta.attributes, expression => expression));
49949  hostMetadata.set('listeners', toOptionalLiteralMap(meta.listeners, literal));
49950  hostMetadata.set('properties', toOptionalLiteralMap(meta.properties, literal));
49951
49952  if (meta.specialAttributes.styleAttr) {
49953    hostMetadata.set('styleAttribute', literal(meta.specialAttributes.styleAttr));
49954  }
49955
49956  if (meta.specialAttributes.classAttr) {
49957    hostMetadata.set('classAttribute', literal(meta.specialAttributes.classAttr));
49958  }
49959
49960  if (hostMetadata.values.length > 0) {
49961    return hostMetadata.toLiteralMap();
49962  } else {
49963    return null;
49964  }
49965}
49966/**
49967 * @license
49968 * Copyright Google LLC All Rights Reserved.
49969 *
49970 * Use of this source code is governed by an MIT-style license that can be
49971 * found in the LICENSE file at https://angular.io/license
49972 */
49973
49974/**
49975 * Compile a component declaration defined by the `R3ComponentMetadata`.
49976 */
49977
49978
49979function compileDeclareComponentFromMetadata(meta, template, additionalTemplateInfo) {
49980  const definitionMap = createComponentDefinitionMap(meta, template, additionalTemplateInfo);
49981  const expression = importExpr(Identifiers.declareComponent).callFn([definitionMap.toLiteralMap()]);
49982  const type = createComponentType(meta);
49983  return {
49984    expression,
49985    type,
49986    statements: []
49987  };
49988}
49989/**
49990 * Gathers the declaration fields for a component into a `DefinitionMap`.
49991 */
49992
49993
49994function createComponentDefinitionMap(meta, template, templateInfo) {
49995  const definitionMap = createDirectiveDefinitionMap(meta);
49996  definitionMap.set('template', getTemplateExpression(template, templateInfo));
49997
49998  if (templateInfo.isInline) {
49999    definitionMap.set('isInline', literal(true));
50000  }
50001
50002  definitionMap.set('styles', toOptionalLiteralArray(meta.styles, literal));
50003  definitionMap.set('dependencies', compileUsedDependenciesMetadata(meta));
50004  definitionMap.set('viewProviders', meta.viewProviders);
50005  definitionMap.set('animations', meta.animations);
50006
50007  if (meta.changeDetection !== undefined) {
50008    definitionMap.set('changeDetection', importExpr(Identifiers.ChangeDetectionStrategy).prop(ChangeDetectionStrategy[meta.changeDetection]));
50009  }
50010
50011  if (meta.encapsulation !== ViewEncapsulation.Emulated) {
50012    definitionMap.set('encapsulation', importExpr(Identifiers.ViewEncapsulation).prop(ViewEncapsulation[meta.encapsulation]));
50013  }
50014
50015  if (meta.interpolation !== DEFAULT_INTERPOLATION_CONFIG) {
50016    definitionMap.set('interpolation', literalArr([literal(meta.interpolation.start), literal(meta.interpolation.end)]));
50017  }
50018
50019  if (template.preserveWhitespaces === true) {
50020    definitionMap.set('preserveWhitespaces', literal(true));
50021  }
50022
50023  return definitionMap;
50024}
50025
50026function getTemplateExpression(template, templateInfo) {
50027  // If the template has been defined using a direct literal, we use that expression directly
50028  // without any modifications. This is ensures proper source mapping from the partially
50029  // compiled code to the source file declaring the template. Note that this does not capture
50030  // template literals referenced indirectly through an identifier.
50031  if (templateInfo.inlineTemplateLiteralExpression !== null) {
50032    return templateInfo.inlineTemplateLiteralExpression;
50033  } // If the template is defined inline but not through a literal, the template has been resolved
50034  // through static interpretation. We create a literal but cannot provide any source span. Note
50035  // that we cannot use the expression defining the template because the linker expects the template
50036  // to be defined as a literal in the declaration.
50037
50038
50039  if (templateInfo.isInline) {
50040    return literal(templateInfo.content, null, null);
50041  } // The template is external so we must synthesize an expression node with
50042  // the appropriate source-span.
50043
50044
50045  const contents = templateInfo.content;
50046  const file = new ParseSourceFile(contents, templateInfo.sourceUrl);
50047  const start = new ParseLocation(file, 0, 0, 0);
50048  const end = computeEndLocation(file, contents);
50049  const span = new ParseSourceSpan(start, end);
50050  return literal(contents, null, span);
50051}
50052
50053function computeEndLocation(file, contents) {
50054  const length = contents.length;
50055  let lineStart = 0;
50056  let lastLineStart = 0;
50057  let line = 0;
50058
50059  do {
50060    lineStart = contents.indexOf('\n', lastLineStart);
50061
50062    if (lineStart !== -1) {
50063      lastLineStart = lineStart + 1;
50064      line++;
50065    }
50066  } while (lineStart !== -1);
50067
50068  return new ParseLocation(file, length, line, length - lastLineStart);
50069}
50070
50071function compileUsedDependenciesMetadata(meta) {
50072  const wrapType = meta.declarationListEmitMode !== 0
50073  /* DeclarationListEmitMode.Direct */
50074  ? generateForwardRef : expr => expr;
50075  return toOptionalLiteralArray(meta.declarations, decl => {
50076    switch (decl.kind) {
50077      case R3TemplateDependencyKind.Directive:
50078        const dirMeta = new DefinitionMap();
50079        dirMeta.set('kind', literal(decl.isComponent ? 'component' : 'directive'));
50080        dirMeta.set('type', wrapType(decl.type));
50081        dirMeta.set('selector', literal(decl.selector));
50082        dirMeta.set('inputs', toOptionalLiteralArray(decl.inputs, literal));
50083        dirMeta.set('outputs', toOptionalLiteralArray(decl.outputs, literal));
50084        dirMeta.set('exportAs', toOptionalLiteralArray(decl.exportAs, literal));
50085        return dirMeta.toLiteralMap();
50086
50087      case R3TemplateDependencyKind.Pipe:
50088        const pipeMeta = new DefinitionMap();
50089        pipeMeta.set('kind', literal('pipe'));
50090        pipeMeta.set('type', wrapType(decl.type));
50091        pipeMeta.set('name', literal(decl.name));
50092        return pipeMeta.toLiteralMap();
50093
50094      case R3TemplateDependencyKind.NgModule:
50095        const ngModuleMeta = new DefinitionMap();
50096        ngModuleMeta.set('kind', literal('ngmodule'));
50097        ngModuleMeta.set('type', wrapType(decl.type));
50098        return ngModuleMeta.toLiteralMap();
50099    }
50100  });
50101}
50102/**
50103 * @license
50104 * Copyright Google LLC All Rights Reserved.
50105 *
50106 * Use of this source code is governed by an MIT-style license that can be
50107 * found in the LICENSE file at https://angular.io/license
50108 */
50109
50110/**
50111 * Every time we make a breaking change to the declaration interface or partial-linker behavior, we
50112 * must update this constant to prevent old partial-linkers from incorrectly processing the
50113 * declaration.
50114 *
50115 * Do not include any prerelease in these versions as they are ignored.
50116 */
50117
50118
50119const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
50120
50121function compileDeclareFactoryFunction(meta) {
50122  const definitionMap = new DefinitionMap();
50123  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
50124  definitionMap.set('version', literal('14.2.10'));
50125  definitionMap.set('ngImport', importExpr(Identifiers.core));
50126  definitionMap.set('type', meta.internalType);
50127  definitionMap.set('deps', compileDependencies(meta.deps));
50128  definitionMap.set('target', importExpr(Identifiers.FactoryTarget).prop(FactoryTarget$1[meta.target]));
50129  return {
50130    expression: importExpr(Identifiers.declareFactory).callFn([definitionMap.toLiteralMap()]),
50131    statements: [],
50132    type: createFactoryType(meta)
50133  };
50134}
50135/**
50136 * @license
50137 * Copyright Google LLC All Rights Reserved.
50138 *
50139 * Use of this source code is governed by an MIT-style license that can be
50140 * found in the LICENSE file at https://angular.io/license
50141 */
50142
50143/**
50144 * Every time we make a breaking change to the declaration interface or partial-linker behavior, we
50145 * must update this constant to prevent old partial-linkers from incorrectly processing the
50146 * declaration.
50147 *
50148 * Do not include any prerelease in these versions as they are ignored.
50149 */
50150
50151
50152const MINIMUM_PARTIAL_LINKER_VERSION$3 = '12.0.0';
50153/**
50154 * Compile a Injectable declaration defined by the `R3InjectableMetadata`.
50155 */
50156
50157function compileDeclareInjectableFromMetadata(meta) {
50158  const definitionMap = createInjectableDefinitionMap(meta);
50159  const expression = importExpr(Identifiers.declareInjectable).callFn([definitionMap.toLiteralMap()]);
50160  const type = createInjectableType(meta);
50161  return {
50162    expression,
50163    type,
50164    statements: []
50165  };
50166}
50167/**
50168 * Gathers the declaration fields for a Injectable into a `DefinitionMap`.
50169 */
50170
50171
50172function createInjectableDefinitionMap(meta) {
50173  const definitionMap = new DefinitionMap();
50174  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
50175  definitionMap.set('version', literal('14.2.10'));
50176  definitionMap.set('ngImport', importExpr(Identifiers.core));
50177  definitionMap.set('type', meta.internalType); // Only generate providedIn property if it has a non-null value
50178
50179  if (meta.providedIn !== undefined) {
50180    const providedIn = convertFromMaybeForwardRefExpression(meta.providedIn);
50181
50182    if (providedIn.value !== null) {
50183      definitionMap.set('providedIn', providedIn);
50184    }
50185  }
50186
50187  if (meta.useClass !== undefined) {
50188    definitionMap.set('useClass', convertFromMaybeForwardRefExpression(meta.useClass));
50189  }
50190
50191  if (meta.useExisting !== undefined) {
50192    definitionMap.set('useExisting', convertFromMaybeForwardRefExpression(meta.useExisting));
50193  }
50194
50195  if (meta.useValue !== undefined) {
50196    definitionMap.set('useValue', convertFromMaybeForwardRefExpression(meta.useValue));
50197  } // Factories do not contain `ForwardRef`s since any types are already wrapped in a function call
50198  // so the types will not be eagerly evaluated. Therefore we do not need to process this expression
50199  // with `convertFromProviderExpression()`.
50200
50201
50202  if (meta.useFactory !== undefined) {
50203    definitionMap.set('useFactory', meta.useFactory);
50204  }
50205
50206  if (meta.deps !== undefined) {
50207    definitionMap.set('deps', literalArr(meta.deps.map(compileDependency)));
50208  }
50209
50210  return definitionMap;
50211}
50212/**
50213 * @license
50214 * Copyright Google LLC All Rights Reserved.
50215 *
50216 * Use of this source code is governed by an MIT-style license that can be
50217 * found in the LICENSE file at https://angular.io/license
50218 */
50219
50220/**
50221 * Every time we make a breaking change to the declaration interface or partial-linker behavior, we
50222 * must update this constant to prevent old partial-linkers from incorrectly processing the
50223 * declaration.
50224 *
50225 * Do not include any prerelease in these versions as they are ignored.
50226 */
50227
50228
50229const MINIMUM_PARTIAL_LINKER_VERSION$2 = '12.0.0';
50230
50231function compileDeclareInjectorFromMetadata(meta) {
50232  const definitionMap = createInjectorDefinitionMap(meta);
50233  const expression = importExpr(Identifiers.declareInjector).callFn([definitionMap.toLiteralMap()]);
50234  const type = createInjectorType(meta);
50235  return {
50236    expression,
50237    type,
50238    statements: []
50239  };
50240}
50241/**
50242 * Gathers the declaration fields for an Injector into a `DefinitionMap`.
50243 */
50244
50245
50246function createInjectorDefinitionMap(meta) {
50247  const definitionMap = new DefinitionMap();
50248  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
50249  definitionMap.set('version', literal('14.2.10'));
50250  definitionMap.set('ngImport', importExpr(Identifiers.core));
50251  definitionMap.set('type', meta.internalType);
50252  definitionMap.set('providers', meta.providers);
50253
50254  if (meta.imports.length > 0) {
50255    definitionMap.set('imports', literalArr(meta.imports));
50256  }
50257
50258  return definitionMap;
50259}
50260/**
50261 * @license
50262 * Copyright Google LLC All Rights Reserved.
50263 *
50264 * Use of this source code is governed by an MIT-style license that can be
50265 * found in the LICENSE file at https://angular.io/license
50266 */
50267
50268/**
50269 * Every time we make a breaking change to the declaration interface or partial-linker behavior, we
50270 * must update this constant to prevent old partial-linkers from incorrectly processing the
50271 * declaration.
50272 *
50273 * Do not include any prerelease in these versions as they are ignored.
50274 */
50275
50276
50277const MINIMUM_PARTIAL_LINKER_VERSION$1 = '14.0.0';
50278
50279function compileDeclareNgModuleFromMetadata(meta) {
50280  const definitionMap = createNgModuleDefinitionMap(meta);
50281  const expression = importExpr(Identifiers.declareNgModule).callFn([definitionMap.toLiteralMap()]);
50282  const type = createNgModuleType(meta);
50283  return {
50284    expression,
50285    type,
50286    statements: []
50287  };
50288}
50289/**
50290 * Gathers the declaration fields for an NgModule into a `DefinitionMap`.
50291 */
50292
50293
50294function createNgModuleDefinitionMap(meta) {
50295  const definitionMap = new DefinitionMap();
50296  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
50297  definitionMap.set('version', literal('14.2.10'));
50298  definitionMap.set('ngImport', importExpr(Identifiers.core));
50299  definitionMap.set('type', meta.internalType); // We only generate the keys in the metadata if the arrays contain values.
50300  // We must wrap the arrays inside a function if any of the values are a forward reference to a
50301  // not-yet-declared class. This is to support JIT execution of the `ɵɵngDeclareNgModule(
50301)` call.
50302  // In the linker these wrappers are stripped and then reapplied for the `ɵɵdefineNgModule()` call.
50303
50304  if (meta.bootstrap.length > 0) {
50305    definitionMap.set('bootstrap', refsToArray(meta.bootstrap, meta.containsForwardDecls));
50306  }
50307
50308  if (meta.declarations.length > 0) {
50309    definitionMap.set('declarations', refsToArray(meta.declarations, meta.containsForwardDecls));
50310  }
50311
50312  if (meta.imports.length > 0) {
50313    definitionMap.set('imports', refsToArray(meta.imports, meta.containsForwardDecls));
50314  }
50315
50316  if (meta.exports.length > 0) {
50317    definitionMap.set('exports', refsToArray(meta.exports, meta.containsForwardDecls));
50318  }
50319
50320  if (meta.schemas !== null && meta.schemas.length > 0) {
50321    definitionMap.set('schemas', literalArr(meta.schemas.map(ref => ref.value)));
50322  }
50323
50324  if (meta.id !== null) {
50325    definitionMap.set('id', meta.id);
50326  }
50327
50328  return definitionMap;
50329}
50330/**
50331 * @license
50332 * Copyright Google LLC All Rights Reserved.
50333 *
50334 * Use of this source code is governed by an MIT-style license that can be
50335 * found in the LICENSE file at https://angular.io/license
50336 */
50337
50338/**
50339 * Every time we make a breaking change to the declaration interface or partial-linker behavior, we
50340 * must update this constant to prevent old partial-linkers from incorrectly processing the
50341 * declaration.
50342 *
50343 * Do not include any prerelease in these versions as they are ignored.
50344 */
50345
50346
50347const MINIMUM_PARTIAL_LINKER_VERSION = '14.0.0';
50348/**
50349 * Compile a Pipe declaration defined by the `R3PipeMetadata`.
50350 */
50351
50352function compileDeclarePipeFromMetadata(meta) {
50353  const definitionMap = createPipeDefinitionMap(meta);
50354  const expression = importExpr(Identifiers.declarePipe).callFn([definitionMap.toLiteralMap()]);
50355  const type = createPipeType(meta);
50356  return {
50357    expression,
50358    type,
50359    statements: []
50360  };
50361}
50362/**
50363 * Gathers the declaration fields for a Pipe into a `DefinitionMap`.
50364 */
50365
50366
50367function createPipeDefinitionMap(meta) {
50368  const definitionMap = new DefinitionMap();
50369  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
50370  definitionMap.set('version', literal('14.2.10'));
50371  definitionMap.set('ngImport', importExpr(Identifiers.core)); // e.g. `type: MyPipe`
50372
50373  definitionMap.set('type', meta.internalType);
50374
50375  if (meta.isStandalone) {
50376    definitionMap.set('isStandalone', literal(meta.isStandalone));
50377  } // e.g. `name: "myPipe"`
50378
50379
50380  definitionMap.set('name', literal(meta.pipeName));
50381
50382  if (meta.pure === false) {
50383    // e.g. `pure: false`
50384    definitionMap.set('pure', literal(meta.pure));
50385  }
50386
50387  return definitionMap;
50388}
50389/**
50390 * @license
50391 * Copyright Google LLC All Rights Reserved.
50392 *
50393 * Use of this source code is governed by an MIT-style license that can be
50394 * found in the LICENSE file at https://angular.io/license
50395 */
50396// This file only reexports content of the `src` folder. Keep it that way.
50397// This function call has a global side effects and publishes the compiler into global namespace for
50398// the late binding of the Compiler to the @angular/core for jit compilation.
50399
50400
50401publishFacade(_global);
50402/**
50403 * @license
50404 * Copyright Google LLC All Rights Reserved.
50405 *
50406 * Use of this source code is governed by an MIT-style license that can be
50407 * found in the LICENSE file at https://angular.io/license
50408 */
50409// This file only reexports content of the `src` folder. Keep it that way.
50410
50411/**
50412 * @license
50413 * Copyright Google LLC All Rights Reserved.
50414 *
50415 * Use of this source code is governed by an MIT-style license that can be
50416 * found in the LICENSE file at https://angular.io/license
50417 */
50418
50419/**
50420 * @license
50421 * Copyright Google LLC All Rights Reserved.
50422 *
50423 * Use of this source code is governed by an MIT-style license that can be
50424 * found in the LICENSE file at https://angular.io/license
50425 */
50426
50427
50428
50429/***/ }),
50430
50431/***/ 2560:
50432/*!******************************************************!*\
50433  !*** ./node_modules/@angular/core/fesm2020/core.mjs ***!
50434  \******************************************************/
50435/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
50436
50437__webpack_require__.r(__webpack_exports__);
50438/* harmony export */ __webpack_require__.d(__webpack_exports__, {
50439/* harmony export */   "ANALYZE_FOR_ENTRY_COMPONENTS": () => (/* binding */ ANALYZE_FOR_ENTRY_COMPONENTS),
50440/* harmony export */   "ANIMATION_MODULE_TYPE": () => (/* binding */ ANIMATION_MODULE_TYPE),
50441/* harmony export */   "APP_BOOTSTRAP_LISTENER": () => (/* binding */ APP_BOOTSTRAP_LISTENER),
50442/* harmony export */   "APP_ID": () => (/* binding */ APP_ID),
50443/* harmony export */   "APP_INITIALIZER": () => (/* binding */ APP_INITIALIZER),
50444/* harmony export */   "ApplicationInitStatus": () => (/* binding */ ApplicationInitStatus),
50445/* harmony export */   "ApplicationModule": () => (/* binding */ ApplicationModule),
50446/* harmony export */   "ApplicationRef": () => (/* binding */ ApplicationRef),
50447/* harmony export */   "Attribute": () => (/* binding */ Attribute),
50448/* harmony export */   "COMPILER_OPTIONS": () => (/* binding */ COMPILER_OPTIONS),
50449/* harmony export */   "CUSTOM_ELEMENTS_SCHEMA": () => (/* binding */ CUSTOM_ELEMENTS_SCHEMA),
50450/* harmony export */   "ChangeDetectionStrategy": () => (/* binding */ ChangeDetectionStrategy),
50451/* harmony export */   "ChangeDetectorRef": () => (/* binding */ ChangeDetectorRef),
50452/* harmony export */   "Compiler": () => (/* binding */ Compiler),
50453/* harmony export */   "CompilerFactory": () => (/* binding */ CompilerFactory),
50454/* harmony export */   "Component": () => (/* binding */ Component),
50455/* harmony export */   "ComponentFactory": () => (/* binding */ ComponentFactory$1),
50456/* harmony export */   "ComponentFactoryResolver": () => (/* binding */ ComponentFactoryResolver$1),
50457/* harmony export */   "ComponentRef": () => (/* binding */ ComponentRef$1),
50458/* harmony export */   "ContentChild": () => (/* binding */ ContentChild),
50459/* harmony export */   "ContentChildren": () => (/* binding */ ContentChildren),
50460/* harmony export */   "DEFAULT_CURRENCY_CODE": () => (/* binding */ DEFAULT_CURRENCY_CODE),
50461/* harmony export */   "DebugElement": () => (/* binding */ DebugElement),
50462/* harmony export */   "DebugEventListener": () => (/* binding */ DebugEventListener),
50463/* harmony export */   "DebugNode": () => (/* binding */ DebugNode),
50464/* harmony export */   "DefaultIterableDiffer": () => (/* binding */ DefaultIterableDiffer),
50465/* harmony export */   "Directive": () => (/* binding */ Directive),
50466/* harmony export */   "ENVIRONMENT_INITIALIZER": () => (/* binding */ ENVIRONMENT_INITIALIZER),
50467/* harmony export */   "ElementRef": () => (/* binding */ ElementRef),
50468/* harmony export */   "EmbeddedViewRef": () => (/* binding */ EmbeddedViewRef),
50469/* harmony export */   "EnvironmentInjector": () => (/* binding */ EnvironmentInjector),
50470/* harmony export */   "ErrorHandler": () => (/* binding */ ErrorHandler),
50471/* harmony export */   "EventEmitter": () => (/* binding */ EventEmitter),
50472/* harmony export */   "Host": () => (/* binding */ Host),
50473/* harmony export */   "HostBinding": () => (/* binding */ HostBinding),
50474/* harmony export */   "HostListener": () => (/* binding */ HostListener),
50475/* harmony export */   "INJECTOR": () => (/* binding */ INJECTOR),
50476/* harmony export */   "Inject": () => (/* binding */ Inject),
50477/* harmony export */   "InjectFlags": () => (/* binding */ InjectFlags),
50478/* harmony export */   "Injectable": () => (/* binding */ Injectable),
50479/* harmony export */   "InjectionToken": () => (/* binding */ InjectionToken),
50480/* harmony export */   "Injector": () => (/* binding */ Injector),
50481/* harmony export */   "Input": () => (/* binding */ Input),
50482/* harmony export */   "IterableDiffers": () => (/* binding */ IterableDiffers),
50483/* harmony export */   "KeyValueDiffers": () => (/* binding */ KeyValueDiffers),
50484/* harmony export */   "LOCALE_ID": () => (/* binding */ LOCALE_ID),
50485/* harmony export */   "MissingTranslationStrategy": () => (/* binding */ MissingTranslationStrategy),
50486/* harmony export */   "ModuleWithComponentFactories": () => (/* binding */ ModuleWithComponentFactories),
50487/* harmony export */   "NO_ERRORS_SCHEMA": () => (/* binding */ NO_ERRORS_SCHEMA),
50488/* harmony export */   "NgModule": () => (/* binding */ NgModule),
50489/* harmony export */   "NgModuleFactory": () => (/* binding */ NgModuleFactory$1),
50490/* harmony export */   "NgModuleRef": () => (/* binding */ NgModuleRef$1),
50491/* harmony export */   "NgProbeToken": () => (/* binding */ NgProbeToken),
50492/* harmony export */   "NgZone": () => (/* binding */ NgZone),
50493/* harmony export */   "Optional": () => (/* binding */ Optional),
50494/* harmony export */   "Output": () => (/* binding */ Output),
50495/* harmony export */   "PACKAGE_ROOT_URL": () => (/* binding */ PACKAGE_ROOT_URL),
50496/* harmony export */   "PLATFORM_ID": () => (/* binding */ PLATFORM_ID),
50497/* harmony export */   "PLATFORM_INITIALIZER": () => (/* binding */ PLATFORM_INITIALIZER),
50498/* harmony export */   "Pipe": () => (/* binding */ Pipe),
50499/* harmony export */   "PlatformRef": () => (/* binding */ PlatformRef),
50500/* harmony export */   "Query": () => (/* binding */ Query),
50501/* harmony export */   "QueryList": () => (/* binding */ QueryList),
50502/* harmony export */   "ReflectiveInjector": () => (/* binding */ ReflectiveInjector),
50503/* harmony export */   "ReflectiveKey": () => (/* binding */ ReflectiveKey),
50504/* harmony export */   "Renderer2": () => (/* binding */ Renderer2),
50505/* harmony export */   "RendererFactory2": () => (/* binding */ RendererFactory2),
50506/* harmony export */   "RendererStyleFlags2": () => (/* binding */ RendererStyleFlags2),
50507/* harmony export */   "ResolvedReflectiveFactory": () => (/* binding */ ResolvedReflectiveFactory),
50508/* harmony export */   "Sanitizer": () => (/* binding */ Sanitizer),
50509/* harmony export */   "SecurityContext": () => (/* binding */ SecurityContext),
50510/* harmony export */   "Self": () => (/* binding */ Self),
50511/* harmony export */   "SimpleChange": () => (/* binding */ SimpleChange),
50512/* harmony export */   "SkipSelf": () => (/* binding */ SkipSelf),
50513/* harmony export */   "TRANSLATIONS": () => (/* binding */ TRANSLATIONS),
50514/* harmony export */   "TRANSLATIONS_FORMAT": () => (/* binding */ TRANSLATIONS_FORMAT),
50515/* harmony export */   "TemplateRef": () => (/* binding */ TemplateRef),
50516/* harmony export */   "Testability": () => (/* binding */ Testability),
50517/* harmony export */   "TestabilityRegistry": () => (/* binding */ TestabilityRegistry),
50518/* harmony export */   "Type": () => (/* binding */ Type),
50519/* harmony export */   "VERSION": () => (/* binding */ VERSION),
50520/* harmony export */   "Version": () => (/* binding */ Version),
50521/* harmony export */   "ViewChild": () => (/* binding */ ViewChild),
50522/* harmony export */   "ViewChildren": () => (/* binding */ ViewChildren),
50523/* harmony export */   "ViewContainerRef": () => (/* binding */ ViewContainerRef),
50524/* harmony export */   "ViewEncapsulation": () => (/* binding */ ViewEncapsulation$1),
50525/* harmony export */   "ViewRef": () => (/* binding */ ViewRef),
50526/* harmony export */   "asNativeElements": () => (/* binding */ asNativeElements),
50527/* harmony export */   "assertPlatform": () => (/* binding */ assertPlatform),
50528/* harmony export */   "createComponent": () => (/* binding */ createComponent),
50529/* harmony export */   "createEnvironmentInjector": () => (/* binding */ createEnvironmentInjector),
50530/* harmony export */   "createNgModule": () => (/* binding */ createNgModule),
50531/* harmony export */   "createNgModuleRef": () => (/* binding */ createNgModuleRef),
50532/* harmony export */   "createPlatform": () => (/* binding */ createPlatform),
50533/* harmony export */   "createPlatformFactory": () => (/* binding */ createPlatformFactory),
50534/* harmony export */   "defineInjectable": () => (/* binding */ defineInjectable),
50535/* harmony export */   "destroyPlatform": () => (/* binding */ destroyPlatform),
50536/* harmony export */   "enableProdMode": () => (/* binding */ enableProdMode),
50537/* harmony export */   "forwardRef": () => (/* binding */ forwardRef),
50538/* harmony export */   "getDebugNode": () => (/* binding */ getDebugNode),
50539/* harmony export */   "getModuleFactory": () => (/* binding */ getModuleFactory),
50540/* harmony export */   "getNgModuleById": () => (/* binding */ getNgModuleById),
50541/* harmony export */   "getPlatform": () => (/* binding */ getPlatform),
50542/* harmony export */   "importProvidersFrom": () => (/* binding */ importProvidersFrom),
50543/* harmony export */   "inject": () => (/* binding */ inject),
50544/* harmony export */   "isDevMode": () => (/* binding */ isDevMode),
50545/* harmony export */   "platformCore": () => (/* binding */ platformCore),
50546/* harmony export */   "reflectComponentType": () => (/* binding */ reflectComponentType),
50547/* harmony export */   "resolveForwardRef": () => (/* binding */ resolveForwardRef),
50548/* harmony export */   "setTestabilityGetter": () => (/* binding */ setTestabilityGetter),
50549/* harmony export */   "ɵALLOW_MULTIPLE_PLATFORMS": () => (/* binding */ ALLOW_MULTIPLE_PLATFORMS),
50550/* harmony export */   "ɵAPP_ID_RANDOM_PROVIDER": () => (/* binding */ APP_ID_RANDOM_PROVIDER),
50551/* harmony export */   "ɵChangeDetectorStatus": () => (/* binding */ ChangeDetectorStatus),
50552/* harmony export */   "ɵComponentFactory": () => (/* binding */ ComponentFactory$1),
50553/* harmony export */   "ɵConsole": () => (/* binding */ Console),
50554/* harmony export */   "ɵDEFAULT_LOCALE_ID": () => (/* binding */ DEFAULT_LOCALE_ID),
50555/* harmony export */   "ɵINJECTOR_SCOPE": () => (/* binding */ INJECTOR_SCOPE),
50556/* harmony export */   "ɵLContext": () => (/* binding */ LContext),
50557/* harmony export */   "ɵLifecycleHooksFeature": () => (/* binding */ LifecycleHooksFeature),
50558/* harmony export */   "ɵLocaleDataIndex": () => (/* binding */ LocaleDataIndex),
50559/* harmony export */   "ɵNG_COMP_DEF": () => (/* binding */ NG_COMP_DEF),
50560/* harmony export */   "ɵNG_DIR_DEF": () => (/* binding */ NG_DIR_DEF),
50561/* harmony export */   "ɵNG_ELEMENT_ID": () => (/* binding */ NG_ELEMENT_ID),
50562/* harmony export */   "ɵNG_INJ_DEF": () => (/* binding */ NG_INJ_DEF),
50563/* harmony export */   "ɵNG_MOD_DEF": () => (/* binding */ NG_MOD_DEF),
50564/* harmony export */   "ɵNG_PIPE_DEF": () => (/* binding */ NG_PIPE_DEF),
50565/* harmony export */   "ɵNG_PROV_DEF": () => (/* binding */ NG_PROV_DEF),
50566/* harmony export */   "ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR": () => (/* binding */ NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR),
50567/* harmony export */   "ɵNO_CHANGE": () => (/* binding */ NO_CHANGE),
50568/* harmony export */   "ɵNgModuleFactory": () => (/* binding */ NgModuleFactory),
50569/* harmony export */   "ɵNoopNgZone": () => (/* binding */ NoopNgZone),
50570/* harmony export */   "ɵReflectionCapabilities": () => (/* binding */ ReflectionCapabilities),
50571/* harmony export */   "ɵRender3ComponentFactory": () => (/* binding */ ComponentFactory),
50572/* harmony export */   "ɵRender3ComponentRef": () => (/* binding */ ComponentRef),
50573/* harmony export */   "ɵRender3NgModuleRef": () => (/* binding */ NgModuleRef),
50574/* harmony export */   "ɵRuntimeError": () => (/* binding */ RuntimeError),
50575/* harmony export */   "ɵTESTABILITY": () => (/* binding */ TESTABILITY),
50576/* harmony export */   "ɵTESTABILITY_GETTER": () => (/* binding */ TESTABILITY_GETTER),
50577/* harmony export */   "ɵViewRef": () => (/* binding */ ViewRef$1),
50578/* harmony export */   "ɵ_sanitizeHtml": () => (/* binding */ _sanitizeHtml),
50579/* harmony export */   "ɵ_sanitizeUrl": () => (/* binding */ _sanitizeUrl),
50580/* harmony export */   "ɵallowSanitizationBypassAndThrow": () => (/* binding */ allowSanitizationBypassAndThrow),
50581/* harmony export */   "ɵbypassSanitizationTrustHtml": () => (/* binding */ bypassSanitizationTrustHtml),
50582/* harmony export */   "ɵbypassSanitizationTrustResourceUrl": () => (/* binding */ bypassSanitizationTrustResourceUrl),
50583/* harmony export */   "ɵbypassSanitizationTrustScript": () => (/* binding */ bypassSanitizationTrustScript),
50584/* harmony export */   "ɵbypassSanitizationTrustStyle": () => (/* binding */ bypassSanitizationTrustStyle),
50585/* harmony export */   "ɵbypassSanitizationTrustUrl": () => (/* binding */ bypassSanitizationTrustUrl),
50586/* harmony export */   "ɵclearResolutionOfComponentResourcesQueue": () => (/* binding */ clearResolutionOfComponentResourcesQueue),
50587/* harmony export */   "ɵcoerceToBoolean": () => (/* binding */ coerceToBoolean),
50588/* harmony export */   "ɵcompileComponent": () => (/* binding */ compileComponent),
50589/* harmony export */   "ɵcompileDirective": () => (/* binding */ compileDirective),
50590/* harmony export */   "ɵcompileNgModule": () => (/* binding */ compileNgModule),
50591/* harmony export */   "ɵcompileNgModuleDefs": () => (/* binding */ compileNgModuleDefs),
50592/* harmony export */   "ɵcompileNgModuleFactory": () => (/* binding */ compileNgModuleFactory),
50593/* harmony export */   "ɵcompilePipe": () => (/* binding */ compilePipe),
50594/* harmony export */   "ɵcreateInjector": () => (/* binding */ createInjector),
50595/* harmony export */   "ɵdefaultIterableDiffers": () => (/* binding */ defaultIterableDiffers),
50596/* harmony export */   "ɵdefaultKeyValueDiffers": () => (/* binding */ defaultKeyValueDiffers),
50597/* harmony export */   "ɵdetectChanges": () => (/* binding */ detectChanges),
50598/* harmony export */   "ɵdevModeEqual": () => (/* binding */ devModeEqual),
50599/* harmony export */   "ɵfindLocaleData": () => (/* binding */ findLocaleData),
50600/* harmony export */   "ɵflushModuleScopingQueueAsMuchAsPossible": () => (/* binding */ flushModuleScopingQueueAsMuchAsPossible),
50601/* harmony export */   "ɵformatRuntimeError": () => (/* binding */ formatRuntimeError),
50602/* harmony export */   "ɵgetDebugNode": () => (/* binding */ getDebugNode),
50603/* harmony export */   "ɵgetDebugNodeR2": () => (/* binding */ getDebugNodeR2),
50604/* harmony export */   "ɵgetDirectives": () => (/* binding */ getDirectives),
50605/* harmony export */   "ɵgetHostElement": () => (/* binding */ getHostElement),
50606/* harmony export */   "ɵgetInjectableDef": () => (/* binding */ getInjectableDef),
50607/* harmony export */   "ɵgetLContext": () => (/* binding */ getLContext),
50608/* harmony export */   "ɵgetLocaleCurrencyCode": () => (/* binding */ getLocaleCurrencyCode),
50609/* harmony export */   "ɵgetLocalePluralCase": () => (/* binding */ getLocalePluralCase),
50610/* harmony export */   "ɵgetSanitizationBypassType": () => (/* binding */ getSanitizationBypassType),
50611/* harmony export */   "ɵgetUnknownElementStrictMode": () => (/* binding */ ɵgetUnknownElementStrictMode),
50612/* harmony export */   "ɵgetUnknownPropertyStrictMode": () => (/* binding */ ɵgetUnknownPropertyStrictMode),
50613/* harmony export */   "ɵglobal": () => (/* binding */ _global),
50614/* harmony export */   "ɵinjectChangeDetectorRef": () => (/* binding */ injectChangeDetectorRef),
50615/* harmony export */   "ɵinternalCreateApplication": () => (/* binding */ internalCreateApplication),
50616/* harmony export */   "ɵisBoundToModule": () => (/* binding */ isBoundToModule),
50617/* harmony export */   "ɵisDefaultChangeDetectionStrategy": () => (/* binding */ isDefaultChangeDetectionStrategy),
50618/* harmony export */   "ɵisInjectable": () => (/* binding */ isInjectable),
50619/* harmony export */   "ɵisListLikeIterable": () => (/* binding */ isListLikeIterable),
50620/* harmony export */   "ɵisObservable": () => (/* binding */ isObservable),
50621/* harmony export */   "ɵisPromise": () => (/* binding */ isPromise),
50622/* harmony export */   "ɵisStandalone": () => (/* binding */ isStandalone),
50623/* harmony export */   "ɵisSubscribable": () => (/* binding */ isSubscribable),
50624/* harmony export */   "ɵivyEnabled": () => (/* binding */ ɵivyEnabled),
50625/* harmony export */   "ɵmakeDecorator": () => (/* binding */ makeDecorator),
50626/* harmony export */   "ɵnoSideEffects": () => (/* binding */ noSideEffects),
50627/* harmony export */   "ɵpatchComponentDefWithScope": () => (/* binding */ patchComponentDefWithScope),
50628/* harmony export */   "ɵpublishDefaultGlobalUtils": () => (/* binding */ publishDefaultGlobalUtils$1),
50629/* harmony export */   "ɵpublishGlobalUtil": () => (/* binding */ publishGlobalUtil),
50630/* harmony export */   "ɵregisterLocaleData": () => (/* binding */ registerLocaleData),
50631/* harmony export */   "ɵresetCompiledComponents": () => (/* binding */ resetCompiledComponents),
50632/* harmony export */   "ɵresetJitOptions": () => (/* binding */ resetJitOptions),
50633/* harmony export */   "ɵresolveComponentResources": () =>
50633 (/* binding */ resolveComponentResources),
50634/* harmony export */   "ɵsetAllowDuplicateNgModuleIdsForTest": () => (/* binding */ setAllowDuplicateNgModuleIdsForTest),
50635/* harmony export */   "ɵsetClassMetadata": () => (/* binding */ setClassMetadata),
50636/* harmony export */   "ɵsetCurrentInjector": () => (/* binding */ setCurrentInjector),
50637/* harmony export */   "ɵsetDocument": () => (/* binding */ setDocument),
50638/* harmony export */   "ɵsetLocaleId": () => (/* binding */ setLocaleId),
50639/* harmony export */   "ɵsetUnknownElementStrictMode": () => (/* binding */ ɵsetUnknownElementStrictMode),
50640/* harmony export */   "ɵsetUnknownPropertyStrictMode": () => (/* binding */ ɵsetUnknownPropertyStrictMode),
50641/* harmony export */   "ɵstore": () => (/* binding */ store),
50642/* harmony export */   "ɵstringify": () => (/* binding */ stringify),
50643/* harmony export */   "ɵtransitiveScopesFor": () => (/* binding */ transitiveScopesFor),
50644/* harmony export */   "ɵunregisterLocaleData": () => (/* binding */ unregisterAllLocaleData),
50645/* harmony export */   "ɵunwrapSafeValue": () => (/* binding */ unwrapSafeValue),
50646/* harmony export */   "ɵɵCopyDefinitionFeature": () => (/* binding */ ɵɵCopyDefinitionFeature),
50647/* harmony export */   "ɵɵFactoryTarget": () => (/* binding */ FactoryTarget),
50648/* harmony export */   "ɵɵInheritDefinitionFeature": () => (/* binding */ ɵɵInheritDefinitionFeature),
50649/* harmony export */   "ɵɵNgOnChangesFeature": () => (/* binding */ ɵɵNgOnChangesFeature),
50650/* harmony export */   "ɵɵProvidersFeature": () => (/* binding */ ɵɵProvidersFeature),
50651/* harmony export */   "ɵɵStandaloneFeature": () => (/* binding */ ɵɵStandaloneFeature),
50652/* harmony export */   "ɵɵadvance": () => (/* binding */ ɵɵadvance),
50653/* harmony export */   "ɵɵattribute": () => (/* binding */ ɵɵattribute),
50654/* harmony export */   "ɵɵattributeInterpolate1": () => (/* binding */ ɵɵattributeInterpolate1),
50655/* harmony export */   "ɵɵattributeInterpolate2": () => (/* binding */ ɵɵattributeInterpolate2),
50656/* harmony export */   "ɵɵattributeInterpolate3": () => (/* binding */ ɵɵattributeInterpolate3),
50657/* harmony export */   "ɵɵattributeInterpolate4": () => (/* binding */ ɵɵattributeInterpolate4),
50658/* harmony export */   "ɵɵattributeInterpolate5": () => (/* binding */ ɵɵattributeInterpolate5),
50659/* harmony export */   "ɵɵattributeInterpolate6": () => (/* binding */ ɵɵattributeInterpolate6),
50660/* harmony export */   "ɵɵattributeInterpolate7": () => (/* binding */ ɵɵattributeInterpolate7),
50661/* harmony export */   "ɵɵattributeInterpolate8": () => (/* binding */ ɵɵattributeInterpolate8),
50662/* harmony export */   "ɵɵattributeInterpolateV": () => (/* binding */ ɵɵattributeInterpolateV),
50663/* harmony export */   "ɵɵclassMap": () => (/* binding */ ɵɵclassMap),
50664/* harmony export */   "ɵɵclassMapInterpolate1": () => (/* binding */ ɵɵclassMapInterpolate1),
50665/* harmony export */   "ɵɵclassMapInterpolate2": () => (/* binding */ ɵɵclassMapInterpolate2),
50666/* harmony export */   "ɵɵclassMapInterpolate3": () => (/* binding */ ɵɵclassMapInterpolate3),
50667/* harmony export */   "ɵɵclassMapInterpolate4": () => (/* binding */ ɵɵclassMapInterpolate4),
50668/* harmony export */   "ɵɵclassMapInterpolate5": () => (/* binding */ ɵɵclassMapInterpolate5),
50669/* harmony export */   "ɵɵclassMapInterpolate6": () => (/* binding */ ɵɵclassMapInterpolate6),
50670/* harmony export */   "ɵɵclassMapInterpolate7": () => (/* binding */ ɵɵclassMapInterpolate7),
50671/* harmony export */   "ɵɵclassMapInterpolate8": () => (/* binding */ ɵɵclassMapInterpolate8),
50672/* harmony export */   "ɵɵclassMapInterpolateV": () => (/* binding */ ɵɵclassMapInterpolateV),
50673/* harmony export */   "ɵɵclassProp": () => (/* binding */ ɵɵclassProp),
50674/* harmony export */   "ɵɵcontentQuery": () => (/* binding */ ɵɵcontentQuery),
50675/* harmony export */   "ɵɵdefineComponent": () => (/* binding */ ɵɵdefineComponent),
50676/* harmony export */   "ɵɵdefineDirective": () => (/* binding */ ɵɵdefineDirective),
50677/* harmony export */   "ɵɵdefineInjectable": () => (/* binding */ ɵɵdefineInjectable),
50678/* harmony export */   "ɵɵdefineInjector": () => (/* binding */ ɵɵdefineInjector),
50679/* harmony export */   "ɵɵdefineNgModule": () => (/* binding */ ɵɵdefineNgModule),
50680/* harmony export */   "ɵɵdefinePipe": () => (/* binding */ ɵɵdefinePipe),
50681/* harmony export */   "ɵɵdirectiveInject": () => (/* binding */ ɵɵdirectiveInject),
50682/* harmony export */   "ɵɵdisableBindings": () => (/* binding */ ɵɵdisableBindings),
50683/* harmony export */   "ɵɵelement": () => (/* binding */ ɵɵelement),
50684/* harmony export */   "ɵɵelementContainer": () => (/* binding */ ɵɵelementContainer),
50685/* harmony export */   "ɵɵelementContainerEnd": () => (/* binding */ ɵɵelementContainerEnd),
50686/* harmony export */   "ɵɵelementContainerStart": () => (/* binding */ ɵɵelementContainerStart),
50687/* harmony export */   "ɵɵelementEnd": () => (/* binding */ ɵɵelementEnd),
50688/* harmony export */   "ɵɵelementStart": () => (/* binding */ ɵɵelementStart),
50689/* harmony export */   "ɵɵenableBindings": () => (/* binding */ ɵɵenableBindings),
50690/* harmony export */   "ɵɵgetCurrentView": () => (/* binding */ ɵɵgetCurrentView),
50691/* harmony export */   "ɵɵgetInheritedFactory": () => (/* binding */ ɵɵgetInheritedFactory),
50692/* harmony export */   "ɵɵhostProperty": () => (/* binding */ ɵɵhostProperty),
50693/* harmony export */   "ɵɵi18n": () => (/* binding */ ɵɵi18n),
50694/* harmony export */   "ɵɵi18nApply": () => (/* binding */ ɵɵi18nApply),
50695/* harmony export */   "ɵɵi18nAttributes": () => (/* binding */ ɵɵi18nAttributes),
50696/* harmony export */   "ɵɵi18nEnd": () => (/* binding */ ɵɵi18nEnd),
50697/* harmony export */   "ɵɵi18nExp": () => (/* binding */ ɵɵi18nExp),
50698/* harmony export */   "ɵɵi18nPostprocess": () => (/* binding */ ɵɵi18nPostprocess),
50699/* harmony export */   "ɵɵi18nStart": () => (/* binding */ ɵɵi18nStart),
50700/* harmony export */   "ɵɵinject": () => (/* binding */ ɵɵinject),
50701/* harmony export */   "ɵɵinjectAttribute": () => (/* binding */ ɵɵinjectAttribute),
50702/* harmony export */   "ɵɵinvalidFactory": () => (/* binding */ ɵɵinvalidFactory),
50703/* harmony export */   "ɵɵinvalidFactoryDep": () => (/* binding */ ɵɵinvalidFactoryDep),
50704/* harmony export */   "ɵɵlistener": () => (/* binding */ ɵɵlistener),
50705/* harmony export */   "ɵɵloadQuery": () => (/* binding */ ɵɵloadQuery),
50706/* harmony export */   "ɵɵnamespaceHTML": () => (/* binding */ ɵɵnamespaceHTML),
50707/* harmony export */   "ɵɵnamespaceMathML": () => (/* binding */ ɵɵnamespaceMathML),
50708/* harmony export */   "ɵɵnamespaceSVG": () => (/* binding */ ɵɵnamespaceSVG),
50709/* harmony export */   "ɵɵnextContext": () => (/* binding */ ɵɵnextContext),
50710/* harmony export */   "ɵɵngDeclareClassMetadata": () => (/* binding */ ɵɵngDeclareClassMetadata),
50711/* harmony export */   "ɵɵngDeclareComponent": () => (/* binding */ ɵɵngDeclareComponent),
50712/* harmony export */   "ɵɵngDeclareDirective": () => (/* binding */ ɵɵngDeclareDirective),
50713/* harmony export */   "ɵɵngDeclareFactory": () => (/* binding */ ɵɵngDeclareFactory),
50714/* harmony export */   "ɵɵngDeclareInjectable": () => (/* binding */ ɵɵngDeclareInjectable),
50715/* harmony export */   "ɵɵngDeclareInjector": () => (/* binding */ ɵɵngDeclareInjector),
50716/* harmony export */   "ɵɵngDeclareNgModule": () => (/* binding */ ɵɵngDeclareNgModule),
50717/* harmony export */   "ɵɵngDeclarePipe": () => (/* binding */ ɵɵngDeclarePipe),
50718/* harmony export */   "ɵɵpipe": () => (/* binding */ ɵɵpipe),
50719/* harmony export */   "ɵɵpipeBind1": () => (/* binding */ ɵɵpipeBind1),
50720/* harmony export */   "ɵɵpipeBind2": () => (/* binding */ ɵɵpipeBind2),
50721/* harmony export */   "ɵɵpipeBind3": () => (/* binding */ ɵɵpipeBind3),
50722/* harmony export */   "ɵɵpipeBind4": () => (/* binding */ ɵɵpipeBind4),
50723/* harmony export */   "ɵɵpipeBindV": () => (/* binding */ ɵɵpipeBindV),
50724/* harmony export */   "ɵɵprojection": () => (/* binding */ ɵɵprojection),
50725/* harmony export */   "ɵɵprojectionDef": () => (/* binding */ ɵɵprojectionDef),
50726/* harmony export */   "ɵɵproperty": () => (/* binding */ ɵɵproperty),
50727/* harmony export */   "ɵɵpropertyInterpolate": () => (/* binding */ ɵɵpropertyInterpolate),
50728/* harmony export */   "ɵɵpropertyInterpolate1": () => (/* binding */ ɵɵpropertyInterpolate1),
50729/* harmony export */   "ɵɵpropertyInterpolate2": () => (/* binding */ ɵɵpropertyInterpolate2),
50730/* harmony export */   "ɵɵpropertyInterpolate3": () => (/* binding */ ɵɵpropertyInterpolate3),
50731/* harmony export */   "ɵɵpropertyInterpolate4": () => (/* binding */ ɵɵpropertyInterpolate4),
50732/* harmony export */   "ɵɵpropertyInterpolate5": () => (/* binding */ ɵɵpropertyInterpolate5),
50733/* harmony export */   "ɵɵpropertyInterpolate6": () => (/* binding */ ɵɵpropertyInterpolate6),
50734/* harmony export */   "ɵɵpropertyInterpolate7": () => (/* binding */ ɵɵpropertyInterpolate7),
50735/* harmony export */   "ɵɵpropertyInterpolate8": () => (/* binding */ ɵɵpropertyInterpolate8),
50736/* harmony export */   "ɵɵpropertyInterpolateV": () => (/* binding */ ɵɵpropertyInterpolateV),
50737/* harmony export */   "ɵɵpureFunction0": () => (/* binding */ ɵɵpureFunction0),
50738/* harmony export */   "ɵɵpureFunction1": () => (/* binding */ ɵɵpureFunction1),
50739/* harmony export */   "ɵɵpureFunction2": () => (/* binding */ ɵɵpureFunction2),
50740/* harmony export */   "ɵɵpureFunction3": () => (/* binding */ ɵɵpureFunction3),
50741/* harmony export */   "ɵɵpureFunction4": () => (/* binding */ ɵɵpureFunction4),
50742/* harmony export */   "ɵɵpureFunction5": () => (/* binding */ ɵɵpureFunction5),
50743/* harmony export */   "ɵɵpureFunction6": () => (/* binding */ ɵɵpureFunction6),
50744/* harmony export */   "ɵɵpureFunction7": () => (/* binding */ ɵɵpureFunction7),
50745/* harmony export */   "ɵɵpureFunction8": () => (/* binding */ ɵɵpureFunction8),
50746/* harmony export */   "ɵɵpureFunctionV": () => (/* binding */ ɵɵpureFunctionV),
50747/* harmony export */   "ɵɵqueryRefresh": () => (/* binding */ ɵɵqueryRefresh),
50748/* harmony export */   "ɵɵreference": () => (/* binding */ ɵɵreference),
50749/* harmony export */   "ɵɵregisterNgModuleType": () => (/* binding */ registerNgModuleType),
50750/* harmony export */   "ɵɵresetView": () => (/* binding */ ɵɵresetView),
50751/* harmony export */   "ɵɵresolveBody": () => (/* binding */ ɵɵresolveBody),
50752/* harmony export */   "ɵɵresolveDocument": () => (/* binding */ ɵɵresolveDocument),
50753/* harmony export */   "ɵɵresolveWindow": () => (/* binding */ ɵɵresolveWindow),
50754/* harmony export */   "ɵɵrestoreView": () => (/* binding */ ɵɵrestoreView),
50755/* harmony export */   "ɵɵsanitizeHtml": () => (/* binding */ ɵɵsanitizeHtml),
50756/* harmony export */   "ɵɵsanitizeResourceUrl": () => (/* binding */ ɵɵsanitizeResourceUrl),
50757/* harmony export */   "ɵɵsanitizeScript": () => (/* binding */ ɵɵsanitizeScript),
50758/* harmony export */   "ɵɵsanitizeStyle": () => (/* binding */ ɵɵsanitizeStyle),
50759/* harmony export */   "ɵɵsanitizeUrl": () => (/* binding */ ɵɵsanitizeUrl),
50760/* harmony export */   "ɵɵsanitizeUrlOrResourceUrl": () => (/* binding */ ɵɵsanitizeUrlOrResourceUrl),
50761/* harmony export */   "ɵɵsetComponentScope": () => (/* binding */ ɵɵsetComponentScope),
50762/* harmony export */   "ɵɵsetNgModuleScope": () => (/* binding */ ɵɵsetNgModuleScope),
50763/* harmony export */   "ɵɵstyleMap": () => (/* binding */ ɵɵstyleMap),
50764/* harmony export */   "ɵɵstyleMapInterpolate1": () => (/* binding */ ɵɵstyleMapInterpolate1),
50765/* harmony export */   "ɵɵstyleMapInterpolate2": () => (/* binding */ ɵɵstyleMapInterpolate2),
50766/* harmony export */   "ɵɵstyleMapInterpolate3": () => (/* binding */ ɵɵstyleMapInterpolate3),
50767/* harmony export */   "ɵɵstyleMapInterpolate4": () => (/* binding */ ɵɵstyleMapInterpolate4),
50768/* harmony export */   "ɵɵstyleMapInterpolate5": () => (/* binding */ ɵɵstyleMapInterpolate5),
50769/* harmony export */   "ɵɵstyleMapInterpolate6": () => (/* binding */ ɵɵstyleMapInterpolate6),
50770/* harmony export */   "ɵɵstyleMapInterpolate7": () => (/* binding */ ɵɵstyleMapInterpolate7),
50771/* harmony export */   "ɵɵstyleMapInterpolate8": () => (/* binding */ ɵɵstyleMapInterpolate8),
50772/* harmony export */   "ɵɵstyleMapInterpolateV": () => (/* binding */ ɵɵstyleMapInterpolateV),
50773/* harmony export */   "ɵɵstyleProp": () => (/* binding */ ɵɵstyleProp),
50774/* harmony export */   "ɵɵstylePropInterpolate1": () => (/* binding */ ɵɵstylePropInterpolate1),
50775/* harmony export */   "ɵɵstylePropInterpolate2": () => (/* binding */ ɵɵstylePropInterpolate2),
50776/* harmony export */   "ɵɵstylePropInterpolate3": () => (/* binding */ ɵɵstylePropInterpolate3),
50777/* harmony export */   "ɵɵstylePropInterpolate4": () => (/* binding */ ɵɵstylePropInterpolate4),
50778/* harmony export */   "ɵɵstylePropInterpolate5": () => (/* binding */ ɵɵstylePropInterpolate5),
50779/* harmony export */   "ɵɵstylePropInterpolate6": () => (/* binding */ ɵɵstylePropInterpolate6),
50780/* harmony export */   "ɵɵstylePropInterpolate7": () => (/* binding */ ɵɵstylePropInterpolate7),
50781/* harmony export */   "ɵɵstylePropInterpolate8": () => (/* binding */ ɵɵstylePropInterpolate8),
50782/* harmony export */   "ɵɵstylePropInterpolateV": () => (/* binding */ ɵɵstylePropInterpolateV),
50783/* harmony export */   "ɵɵsyntheticHostListener": () => (/* binding */ ɵɵsyntheticHostListener),
50784/* harmony export */   "ɵɵsyntheticHostProperty": () => (/* binding */ ɵɵsyntheticHostProperty),
50785/* harmony export */   "ɵɵtemplate": () => (/* binding */ ɵɵtemplate),
50786/* harmony export */   "ɵɵtemplateRefExtractor": () => (/* binding */ ɵɵtemplateRefExtractor),
50787/* harmony export */   "ɵɵtext": () => (/* binding */ ɵɵtext),
50788/* harmony export */   "ɵɵtextInterpolate": () => (/* binding */ ɵɵtextInterpolate),
50789/* harmony export */   "ɵɵtextInterpolate1": () => (/* binding */ ɵɵtextInterpolate1),
50790/* harmony export */   "ɵɵtextInterpolate2": () => (/* binding */ ɵɵtextInterpolate2),
50791/* harmony export */   "ɵɵtextInterpolate3": () => (/* binding */ ɵɵtextInterpolate3),
50792/* harmony export */   "ɵɵtextInterpolate4": () => (/* binding */ ɵɵtextInterpolate4),
50793/* harmony export */   "ɵɵtextInterpolate5": () => (/* binding */ ɵɵtextInterpolate5),
50794/* harmony export */   "ɵɵtextInterpolate6": () => (/* binding */ ɵɵtextInterpolate6),
50795/* harmony export */   "ɵɵtextInterpolate7": () => (/* binding */ ɵɵtextInterpolate7),
50796/* harmony export */   "ɵɵtextInterpolate8": () => (/* binding */ ɵɵtextInterpolate8),
50797/* harmony export */   "ɵɵtextInterpolateV": () => (/* binding */ ɵɵtextInterpolateV),
50798/* harmony export */   "ɵɵtrustConstantHtml": () => (/* binding */ ɵɵtrustConstantHtml),
vendor: 5,395 bytes, lines 50799-50993
50799/* harmony export */   "ɵɵtrustConstantResourceUrl": () => (/* binding */ ɵɵtrustConstantResourceUrl),
50800/* harmony export */   "ɵɵviewQuery": () => (/* binding */ ɵɵviewQuery)
50801/* harmony export */ });
50802/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rxjs */ 2218);
50803/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 2425);
50804/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 2378);
50805/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 8623);
50806/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 4514);
50807/**
50808 * @license Angular v14.2.10
50809 * (c) 2010-2022 Google LLC. https://angular.io/
50810 * License: MIT
50811 */
50812
50813
50814/**
50815 * @license
50816 * Copyright Google LLC All Rights Reserved.
50817 *
50818 * Use of this source code is governed by an MIT-style license that can be
50819 * found in the LICENSE file at https://angular.io/license
50820 */
50821
50822function getClosureSafeProperty(objWithPropertyToExtract) {
50823  for (let key in objWithPropertyToExtract) {
50824    if (objWithPropertyToExtract[key] === getClosureSafeProperty) {
50825      return key;
50826    }
50827  }
50828
50829  throw Error('Could not find renamed property on target object.');
50830}
50831/**
50832 * Sets properties on a target object from a source object, but only if
50833 * the property doesn't already exist on the target object.
50834 * @param target The target to set properties on
50835 * @param source The source of the property keys and values to set
50836 */
50837
50838
50839function fillProperties(target, source) {
50840  for (const key in source) {
50841    if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) {
50842      target[key] = source[key];
50843    }
50844  }
50845}
50846/**
50847 * @license
50848 * Copyright Google LLC All Rights Reserved.
50849 *
50850 * Use of this source code is governed by an MIT-style license that can be
50851 * found in the LICENSE file at https://angular.io/license
50852 */
50853
50854
50855function stringify(token) {
50856  if (typeof token === 'string') {
50857    return token;
50858  }
50859
50860  if (Array.isArray(token)) {
50861    return '[' + token.map(stringify).join(', ') + ']';
50862  }
50863
50864  if (token == null) {
50865    return '' + token;
50866  }
50867
50868  if (token.overriddenName) {
50869    return `${token.overriddenName}`;
50870  }
50871
50872  if (token.name) {
50873    return `${token.name}`;
50874  }
50875
50876  const res = token.toString();
50877
50878  if (res == null) {
50879    return '' + res;
50880  }
50881
50882  const newLineIndex = res.indexOf('\n');
50883  return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
50884}
50885/**
50886 * Concatenates two strings with separator, allocating new strings only when necessary.
50887 *
50888 * @param before before string.
50889 * @param separator separator string.
50890 * @param after after string.
50891 * @returns concatenated string.
50892 */
50893
50894
50895function concatStringsWithSpace(before, after) {
50896  return before == null || before === '' ? after === null ? '' : after : after == null || after === '' ? before : before + ' ' + after;
50897}
50898/**
50899 * @license
50900 * Copyright Google LLC All Rights Reserved.
50901 *
50902 * Use of this source code is governed by an MIT-style license that can be
50903 * found in the LICENSE file at https://angular.io/license
50904 */
50905
50906
50907const __forward_ref__ = getClosureSafeProperty({
50908  __forward_ref__: getClosureSafeProperty
50909});
50910/**
50911 * Allows to refer to references which are not yet defined.
50912 *
50913 * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
50914 * DI is declared, but not yet defined. It is also used when the `token` which we use when creating
50915 * a query is not yet defined.
50916 *
50917 * @usageNotes
50918 * ### Example
50919 * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
50920 * @publicApi
50921 */
50922
50923
50924function forwardRef(forwardRefFn) {
50925  forwardRefFn.__forward_ref__ = forwardRef;
50926
50927  forwardRefFn.toString = function () {
50928    return stringify(this());
50929  };
50930
50931  return forwardRefFn;
50932}
50933/**
50934 * Lazily retrieves the reference value from a forwardRef.
50935 *
50936 * Acts as the identity function when given a non-forward-ref value.
50937 *
50938 * @usageNotes
50939 * ### Example
50940 *
50941 * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
50942 *
50943 * @see `forwardRef`
50944 * @publicApi
50945 */
50946
50947
50948function resolveForwardRef(type) {
50949  return isForwardRef(type) ? type() : type;
50950}
50951/** Checks whether a function is wrapped by a `forwardRef`. */
50952
50953
50954function isForwardRef(fn) {
50955  return typeof fn === 'function' && fn.hasOwnProperty(__forward_ref__) && fn.__forward_ref__ === forwardRef;
50956}
50957/**
50958 * @license
50959 * Copyright Google LLC All Rights Reserved.
50960 *
50961 * Use of this source code is governed by an MIT-style license that can be
50962 * found in the LICENSE file at https://angular.io/license
50963 */
50964
50965/**
50966 * Base URL for the error details page.
50967 *
50968 * Keep the files below in full sync:
50969 *  - packages/compiler-cli/src/ngtsc/diagnostics/src/error_details_base_url.ts
50970 *  - packages/core/src/error_details_base_url.ts
50971 */
50972
50973
50974const ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors';
50975/**
50976 * @license
50977 * Copyright Google LLC All Rights Reserved.
50978 *
50979 * Use of this source code is governed by an MIT-style license that can be
50980 * found in the LICENSE file at https://angular.io/license
50981 */
50982
50983/**
50984 * Class that represents a runtime error.
50985 * Formats and outputs the error message in a consistent way.
50986 *
50987 * Example:
50988 * ```
50989 *  throw new RuntimeError(
50990 *    RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,
50991 *    ngDevMode && 'Injector has already been destroyed.');
50992 * ```
50993 *
50994 * Note: the `message` argument contains a descriptive error message as a string in development
50995 * mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the
50996 * `message` argument becomes `false`, thus we account for it in the typings and the runtime logic.
50997 */
50998
50999class RuntimeError extends Error {
51000  constructor(code, message) {
51001    super(formatRuntimeError(code, message));
51002    this.code = code;
51003  }
51004
51005}
51006/**
51007 * Called to format a runtime error.
51008 * See additional info on the `message` argument type in the `RuntimeError` class description.
51009 */
51010
51011
51012function formatRuntimeError(code, message) {
51013  // Error code might be a negative number, which is a special marker that instructs the logic to
51014  // generate a link to the error details page on angular.io.
51015  const fullCode = `NG0${Math.abs(code)}`;
51016  let errorMessage = `${fullCode}${message ? ': ' + message.trim() : ''}`;
51017
51018  if (ngDevMode && code < 0) {
51019    const addPeriodSeparator = !errorMessage.match(/[.,;!?]$/);
51020    const separator = addPeriodSeparator ? '.' : '';
51021    errorMessage = `${errorMessage}${separator} Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/${fullCode}`;
51022  }
51023
51024  return errorMessage;
51025}
51026/**
51027 * @license
51028 * Copyright Google LLC All Rights Reserved.
51029 *
51030 * Use of this source code is governed by an MIT-style license that can be
51031 * found in the LICENSE file at https://angular.io/license
51032 */
51033
51034/**
51035 * Used for stringify render output in Ivy.
51036 * Important! This function is very performance-sensitive and we should
51037 * be extra careful not to introduce megamorphic reads in it.
51038 * Check `core/test/render3/perf/render_stringify` for benchmarks and alternate implementations.
51039 */
51040
51041
vendor: 6,915 bytes, lines 51042-51248
51042function renderStringify(value) {
51043  if (typeof value === 'string') return value;
51044  if (value == null) return ''; // Use `String` so that it invokes the `toString` method of the value. Note that this
51045  // appears to be faster than calling `value.toString` (see `render_stringify` benchmark).
51046
51047  return String(value);
51048}
51049/**
51050 * Used to stringify a value so that it can be displayed in an error message.
51051 * Important! This function contains a megamorphic read and should only be
51052 * used for error messages.
51053 */
51054
51055
51056function stringifyForError(value) {
51057  if (typeof value === 'function') return value.name || value.toString();
51058
51059  if (typeof value === 'object' && value != null && typeof value.type === 'function') {
51060    return value.type.name || value.type.toString();
51061  }
51062
51063  return renderStringify(value);
51064}
51065/**
51066 * @license
51067 * Copyright Google LLC All Rights Reserved.
51068 *
51069 * Use of this source code is governed by an MIT-style license that can be
51070 * found in the LICENSE file at https://angular.io/license
51071 */
51072
51073/** Called when directives inject each other (creating a circular dependency) */
51074
51075
51076function throwCyclicDependencyError(token, path) {
51077  const depPath = path ? `. Dependency path: ${path.join(' > ')} > ${token}` : '';
51078  throw new RuntimeError(-200
51079  /* RuntimeErrorCode.CYCLIC_DI_DEPENDENCY */
51080  , `Circular dependency in DI detected for ${token}${depPath}`);
51081}
51082
51083function throwMixedMultiProviderError() {
51084  throw new Error(`Cannot mix multi providers and regular providers`);
51085}
51086
51087function throwInvalidProviderError(ngModuleType, providers, provider) {
51088  if (ngModuleType && providers) {
51089    const providerDetail = providers.map(v => v == provider ? '?' + provider + '?' : '...');
51090    throw new Error(`Invalid provider for the NgModule '${stringify(ngModuleType)}' - only instances of Provider and Type are allowed, got: [${providerDetail.join(', ')}]`);
51091  } else if (provider.ɵproviders) {
51092    throw new RuntimeError(207
51093    /* RuntimeErrorCode.PROVIDER_IN_WRONG_CONTEXT */
51094    , `Invalid providers from 'importProvidersFrom' present in a non-environment injector. 'importProvidersFrom' can't be used for component providers.`);
51095  } else {
51096    throw new Error('Invalid provider');
51097  }
51098}
51099/** Throws an error when a token is not found in DI. */
51100
51101
51102function throwProviderNotFoundError(token, injectorName) {
51103  const injectorDetails = injectorName ? ` in ${injectorName}` : '';
51104  throw new RuntimeError(-201
51105  /* RuntimeErrorCode.PROVIDER_NOT_FOUND */
51106  , ngDevMode && `No provider for ${stringifyForError(token)} found${injectorDetails}`);
51107}
51108/**
51109 * @license
51110 * Copyright Google LLC All Rights Reserved.
51111 *
51112 * Use of this source code is governed by an MIT-style license that can be
51113 * found in the LICENSE file at https://angular.io/license
51114 */
51115
51116
51117function assertNumber(actual, msg) {
51118  if (!(typeof actual === 'number')) {
51119    throwError(msg, typeof actual, 'number', '===');
51120  }
51121}
51122
51123function assertNumberInRange(actual, minInclusive, maxInclusive) {
51124  assertNumber(actual, 'Expected a number');
51125  assertLessThanOrEqual(actual, maxInclusive, 'Expected number to be less than or equal to');
51126  assertGreaterThanOrEqual(actual, minInclusive, 'Expected number to be greater than or equal to');
51127}
51128
51129function assertString(actual, msg) {
51130  if (!(typeof actual === 'string')) {
51131    throwError(msg, actual === null ? 'null' : typeof actual, 'string', '===');
51132  }
51133}
51134
51135function assertFunction(actual, msg) {
51136  if (!(typeof actual === 'function')) {
51137    throwError(msg, actual === null ? 'null' : typeof actual, 'function', '===');
51138  }
51139}
51140
51141function assertEqual(actual, expected, msg) {
51142  if (!(actual == expected)) {
51143    throwError(msg, actual, expected, '==');
51144  }
51145}
51146
51147function assertNotEqual(actual, expected, msg) {
51148  if (!(actual != expected)) {
51149    throwError(msg, actual, expected, '!=');
51150  }
51151}
51152
51153function assertSame(actual, expected, msg) {
51154  if (!(actual === expected)) {
51155    throwError(msg, actual, expected, '===');
51156  }
51157}
51158
51159function assertNotSame(actual, expected, msg) {
51160  if (!(actual !== expected)) {
51161    throwError(msg, actual, expected, '!==');
51162  }
51163}
51164
51165function assertLessThan(actual, expected, msg) {
51166  if (!(actual < expected)) {
51167    throwError(msg, actual, expected, '<');
51168  }
51169}
51170
51171function assertLessThanOrEqual(actual, expected, msg) {
51172  if (!(actual <= expected)) {
51173    throwError(msg, actual, expected, '<=');
51174  }
51175}
51176
51177function assertGreaterThan(actual, expected, msg) {
51178  if (!(actual > expected)) {
51179    throwError(msg, actual, expected, '>');
51180  }
51181}
51182
51183function assertGreaterThanOrEqual(actual, expected, msg) {
51184  if (!(actual >= expected)) {
51185    throwError(msg, actual, expected, '>=');
51186  }
51187}
51188
51189function assertNotDefined(actual, msg) {
51190  if (actual != null) {
51191    throwError(msg, actual, null, '==');
51192  }
51193}
51194
51195function assertDefined(actual, msg) {
51196  if (actual == null) {
51197    throwError(msg, actual, null, '!=');
51198  }
51199}
51200
51201function throwError(msg, actual, expected, comparison) {
51202  throw new Error(`ASSERTION ERROR: ${msg}` + (comparison == null ? '' : ` [Expected=> ${expected} ${comparison} ${actual} <=Actual]`));
51203}
51204
51205function assertDomNode(node) {
51206  // If we're in a worker, `Node` will not be defined.
51207  if (!(typeof Node !== 'undefined' && node instanceof Node) && !(typeof node === 'object' && node != null && node.constructor.name === 'WebWorkerRenderNode')) {
51208    throwError(`The provided value must be an instance of a DOM Node but got ${stringify(node)}`);
51209  }
51210}
51211
51212function assertIndexInRange(arr, index) {
51213  assertDefined(arr, 'Array must be defined.');
51214  const maxLen = arr.length;
51215
51216  if (index < 0 || index >= maxLen) {
51217    throwError(`Index expected to be less than ${maxLen} but got ${index}`);
51218  }
51219}
51220
51221function assertOneOf(value, ...validValues) {
51222  if (validValues.indexOf(value) !== -1) return true;
51223  throwError(`Expected value to be one of ${JSON.stringify(validValues)} but was ${JSON.stringify(value)}.`);
51224}
51225/**
51226 * @license
51227 * Copyright Google LLC All Rights Reserved.
51228 *
51229 * Use of this source code is governed by an MIT-style license that can be
51230 * found in the LICENSE file at https://angular.io/license
51231 */
51232
51233/**
51234 * Construct an injectable definition which defines how a token will be constructed by the DI
51235 * system, and in which injectors (if any) it will be available.
51236 *
51237 * This should be assigned to a static `ɵprov` field on a type, which will then be an
51238 * `InjectableType`.
51239 *
51240 * Options:
51241 * * `providedIn` determines which injectors will include the injectable, by either associating it
51242 *   with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
51243 *   provided in the `'root'` injector, which will be the application-level injector in most apps.
51244 * * `factory` gives the zero argument function which will create an instance of the injectable.
51245 *   The factory can call `inject` to access the `Injector` and request injection of dependencies.
51246 *
51247 * @codeGenApi
51248 * @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to 
51248npm.
51249 */
51250
51251
51252function ɵɵdefineInjectable(opts) {
51253  return {
51254    token: opts.token,
51255    providedIn: opts.providedIn || null,
51256    factory: opts.factory,
51257    value: undefined
51258  };
51259}
51260/**
51261 * @deprecated in v8, delete after v10. This API should be used only by generated code, and that
51262 * code should now use ɵɵdefineInjectable instead.
51263 * @publicApi
51264 */
51265
51266
51267const defineInjectable = ɵɵdefineInjectable;
51268/**
51269 * Construct an `InjectorDef` which configures an injector.
51270 *
51271 * This should be assigned to a static injector def (`ɵinj`) field on a type, which will then be an
51272 * `InjectorType`.
51273 *
51274 * Options:
51275 *
51276 * * `providers`: an optional array of providers to add to the injector. Each provider must
51277 *   either have a factory or point to a type which has a `ɵprov` static property (the
51278 *   type must be an `InjectableType`).
51279 * * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s
51280 *   whose providers will also be added to the injector. Locally provided types will override
51281 *   providers from imports.
51282 *
51283 * @codeGenApi
51284 */
51285
51286function ɵɵdefineInjector(options) {
51287  return {
51288    providers: options.providers || [],
51289    imports: options.imports || []
51290  };
51291}
51292/**
51293 * Read the injectable def (`ɵprov`) for `type` in a way which is immune to accidentally reading
51294 * inherited value.
51295 *
51296 * @param type A type which may have its own (non-inherited) `ɵprov`.
51297 */
51298
51299
51300function getInjectableDef(type) {
51301  return getOwnDefinition(type, NG_PROV_DEF) || getOwnDefinition(type, NG_INJECTABLE_DEF);
51302}
51303
51304function isInjectable(type) {
51305  return getInjectableDef(type) !== null;
51306}
51307/**
51308 * Return definition only if it is defined directly on `type` and is not inherited from a base
51309 * class of `type`.
51310 */
51311
51312
51313function getOwnDefinition(type, field) {
51314  return type.hasOwnProperty(field) ? type[field] : null;
51315}
51316/**
51317 * Read the injectable def (`ɵprov`) for `type` or read the `ɵprov` from one of its ancestors.
51318 *
51319 * @param type A type which may have `ɵprov`, via inheritance.
51320 *
51321 * @deprecated Will be removed in a future version of Angular, where an error will occur in the
51322 *     scenario if we find the `ɵprov` on an ancestor only.
51323 */
51324
51325
51326function getInheritedInjectableDef(type) {
51327  const def = type && (type[NG_PROV_DEF] || type[NG_INJECTABLE_DEF]);
51328
51329  if (def) {
51330    const typeName = getTypeName(type); // TODO(FW-1307): Re-add ngDevMode when closure can handle it
51331    // ngDevMode &&
51332
51333    console.warn(`DEPRECATED: DI is instantiating a token "${typeName}" that inherits its @Injectable decorator but does not provide one itself.\n` + `This will become an error in a future version of Angular. Please add @Injectable() to the "${typeName}" class.`);
51334    return def;
51335  } else {
51336    return null;
51337  }
51338}
51339/** Gets the name of a type, accounting for some cross-browser differences. */
51340
51341
51342function getTypeName(type) {
51343  // `Function.prototype.name` behaves differently between IE and other browsers. In most browsers
51344  // it'll always return the name of the function itself, no matter how many other functions it
51345  // inherits from. On IE the function doesn't have its own `name` property, but it takes it from
51346  // the lowest level in the prototype chain. E.g. if we have `class Foo extends Parent` most
51347  // browsers will evaluate `Foo.name` to `Foo` while IE will return `Parent`. We work around
51348  // the issue by converting the function to a string and parsing its name out that way via a regex.
51349  if (type.hasOwnProperty('name')) {
51350    return type.name;
51351  }
51352
51353  const match = ('' + type).match(/^function\s*([^\s(]+)/);
51354  return match === null ? '' : match[1];
51355}
51356/**
51357 * Read the injector def type in a way which is immune to accidentally reading inherited value.
51358 *
51359 * @param type type which may have an injector def (`ɵinj`)
51360 */
51361
51362
51363function getInjectorDef(type) {
51364  return type && (type.hasOwnProperty(NG_INJ_DEF) || type.hasOwnProperty(NG_INJECTOR_DEF)) ? type[NG_INJ_DEF] : null;
51365}
51366
51367const NG_PROV_DEF = getClosureSafeProperty({
51368  ɵprov: getClosureSafeProperty
51369});
51370const NG_INJ_DEF = getClosureSafeProperty({
51371  ɵinj: getClosureSafeProperty
51372}); // We need to keep these around so we can read off old defs if new defs are unavailable
51373
51374const NG_INJECTABLE_DEF = getClosureSafeProperty({
51375  ngInjectableDef: getClosureSafeProperty
51376});
51377const NG_INJECTOR_DEF = getClosureSafeProperty({
51378  ngInjectorDef: getClosureSafeProperty
51379});
51380/**
51381 * @license
51382 * Copyright Google LLC All Rights Reserved.
51383 *
51384 * Use of this source code is governed by an MIT-style license that can be
51385 * found in the LICENSE file at https://angular.io/license
51386 */
51387
51388/**
51389 * Injection flags for DI.
51390 *
51391 * @publicApi
51392 * @deprecated use an options object for `inject` instead.
51393 */
51394
51395var InjectFlags;
51396
51397(function (InjectFlags) {
51398  // TODO(alxhub): make this 'const' (and remove `InternalInjectFlags` enum) when ngc no longer
51399  // writes exports of it into ngfactory files.
51400
51401  /** Check self and check parent injector if needed */
51402  InjectFlags[InjectFlags["Default"] = 0] = "Default";
51403  /**
51404   * Specifies that an injector should retrieve a dependency from any injector until reaching the
51405   * host element of the current component. (Only used with Element Injector)
51406   */
51407
51408  InjectFlags[InjectFlags["Host"] = 1] = "Host";
51409  /** Don't ascend to ancestors of the node requesting injection. */
51410
51411  InjectFlags[InjectFlags["Self"] = 2] = "Self";
51412  /** Skip the node that is requesting injection. */
51413
51414  InjectFlags[InjectFlags["SkipSelf"] = 4] = "SkipSelf";
51415  /** Inject `defaultValue` instead if token not found. */
51416
51417  InjectFlags[InjectFlags["Optional"] = 8] = "Optional";
51418})(InjectFlags || (InjectFlags = {}));
51419/**
51420 * @license
51421 * Copyright Google LLC All Rights Reserved.
51422 *
51423 * Use of this source code is governed by an MIT-style license that can be
51424 * found in the LICENSE file at https://angular.io/license
51425 */
51426
51427/**
51428 * Current implementation of inject.
51429 *
51430 * By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
51431 * to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
51432 * way for two reasons:
51433 *  1. `Injector` should not depend on ivy logic.
51434 *  2. To maintain tree shake-ability we don't want to bring in unnecessary code.
51435 */
51436
51437
51438let _injectImplementation;
51439
51440function getInjectImplementation() {
51441  return _injectImplementation;
51442}
51443/**
51444 * Sets the current inject implementation.
51445 */
51446
51447
51448function setInjectImplementation(impl) {
51449  const previous = _injectImplementation;
51450  _injectImplementation = impl;
51451  return previous;
51452}
51453/**
51454 * Injects `root` tokens in limp mode.
51455 *
51456 * If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
51457 * `"root"`. This is known as the limp mode injection. In such case the value is stored in the
51458 * injectable definition.
51459 */
51460
51461
51462function injectRootLimpMode(token, notFoundValue, flags) {
51463  const injectableDef = getInjectableDef(token);
51464
51465  if (injectableDef && injectableDef.providedIn == 'root') {
51466    return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() : injectableDef.value;
51467  }
51468
51469  if (flags & InjectFlags.Optional) return null;
51470  if (notFoundValue !== undefined) return notFoundValue;
51471  throwProviderNotFoundError(stringify(token), 'Injector');
51472}
51473/**
51474 * Assert that `_injectImplementation` is not `fn`.
51475 *
51476 * This is useful, to prevent infinite recursion.
51477 *
51478 * @param fn Function which it should not equal to
51479 */
51480
51481
51482function assertInjectImplementationNotEqual(fn) {
51483  ngDevMode && assertNotEqual(_injectImplementation, fn, 'Calling ɵɵinject would cause infinite recursion');
51484}
51485/**
51486 * @license
51487 * Copyright Google LLC All Rights Reserved.
51488 *
51489 * Use of this source code is governed by an MIT-style license that can be
51490 * found in the LICENSE file at https://angular.io/license
51491 */
51492
51493/**
51494 * Convince closure compiler that the wrapped function has no side-effects.
51495 *
51496 * Closure compiler always assumes that `toString` has no side-effects. We use this quirk to
51497 * allow us to execute a function but have closure compiler mark the call as no-side-effects.
51498 * It is important that the return value for the `noSideEffects` function be assigned
51499 * to something which is retained otherwise the call to `noSideEffects` will be removed by closure
51500 * compiler.
51501 */
51502
51503
51504function noSideEffects(fn) {
51505  return {
51506    toString: fn
51507  }.toString();
51508}
51509/**
51510 * @license
51511 * Copyright Google LLC All Rights Reserved.
51512 *
51513 * Use of this source code is governed by an MIT-style license that can be
51514 * found in the LICENSE file at https://angular.io/license
51515 */
51516
51517/**
51518 * The strategy that the default change detector uses to detect changes.
51519 * When set, takes effect the next time change detection is triggered.
51520 *
51521 * @see {@link ChangeDetectorRef#usage-notes Change detection usage}
51522 *
51523 * @publicApi
51524 */
51525
51526
51527var ChangeDetectionStrategy;
51528
51529(function (ChangeDetectionStrategy) {
51530  /**
51531   * Use the `CheckOnce` strategy, meaning that automatic change detection is deactivated
51532   * until reactivated by setting the strategy to `Default` (`CheckAlways`).
51533   * Change detection can still be explicitly invoked.
51534   * This strategy applies to all child directives and cannot be overridden.
51535   */
51536  ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
51537  /**
51538   * Use the default `CheckAlways` strategy, in which change detection is automatic until
51539   * explicitly deactivated.
51540   */
51541
51542  ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
51543})(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));
51544/**
51545 * Defines the possible states of the default change detector.
51546 * @see `ChangeDetectorRef`
51547 */
51548
51549
51550var ChangeDetectorStatus;
51551
51552(function (ChangeDetectorStatus) {
51553  /**
51554   * A state in which, after calling `detectChanges()`, the change detector
51555   * state becomes `Checked`, and must be explicitly invoked or reactivated.
51556   */
51557  ChangeDetectorStatus[ChangeDetectorStatus["CheckOnce"] = 0] = "CheckOnce";
51558  /**
51559   * A state in which change detection is skipped until the change detector mode
51560   * becomes `CheckOnce`.
51561   */
51562
51563  ChangeDetectorStatus[ChangeDetectorStatus["Checked"] = 1] = "Checked";
51564  /**
51565   * A state in which change detection continues automatically until explicitly
51566   * deactivated.
51567   */
51568
51569  ChangeDetectorStatus[ChangeDetectorStatus["CheckAlways"] = 2] = "CheckAlways";
51570  /**
51571   * A state in which a change detector sub tree is not a part of the main tree and
51572   * should be skipped.
51573   */
51574
51575  ChangeDetectorStatus[ChangeDetectorStatus["Detached"] = 3] = "Detached";
51576  /**
51577   * Indicates that the change detector encountered an error checking a binding
51578   * or calling a directive lifecycle method and is now in an inconsistent state. Change
51579   * detectors in this state do not detect changes.
51580   */
51581
51582  ChangeDetectorStatus[ChangeDetectorStatus["Errored"] = 4] = "Errored";
51583  /**
51584   * Indicates that the change detector has been destroyed.
51585   */
51586
51587  ChangeDetectorStatus[ChangeDetectorStatus["Destroyed"] = 5] = "Destroyed";
51588})(ChangeDetectorStatus || (ChangeDetectorStatus = {}));
51589/**
51590 * Reports whether a given strategy is currently the default for change detection.
51591 * @param changeDetectionStrategy The strategy to check.
51592 * @returns True if the given strategy is the current default, false otherwise.
51593 * @see `ChangeDetectorStatus`
51594 * @see `ChangeDetectorRef`
51595 */
51596
51597
51598function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
51599  return changeDetectionStrategy == null || changeDetectionStrategy === ChangeDetectionStrategy.Default;
51600}
51601/**
51602 * @license
51603 * Copyright Google LLC All Rights Reserved.
51604 *
51605 * Use of this source code is governed by an MIT-style license that can be
51606 * found in the LICENSE file at https://angular.io/license
51607 */
51608
51609/**
51610 * Defines the CSS styles encapsulation policies for the {@link Component} decorator's
51611 * `encapsulation` option.
51612 *
51613 * See {@link Component#encapsulation encapsulation}.
51614 *
51615 * @usageNotes
51616 * ### Example
51617 *
51618 * {@example core/ts/metadata/encapsulation.ts region='longform'}
51619 *
51620 * @publicApi
51621 */
51622
51623
51624var ViewEncapsulation$1;
51625
51626(function (ViewEncapsulation) {
51627  // TODO: consider making `ViewEncapsulation` a `const enum` instead. See
51628  // https://github.com/angular/angular/issues/44119 for additional information.
51629
51630  /**
51631   * Emulates a native Shadow DOM encapsulation behavior by adding a specific attribute to the
51632   * component's host element and applying the same attribute to all the CSS selectors provided
51633   * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls}.
51634   *
51635   * This is the default option.
51636   */
51637  ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated"; // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
51638
51639  /**
51640   * Doesn't provide any sort of CSS style encapsulation, meaning that all the styles provided
51641   * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls} are applicable
51642   * to any HTML element of the application regardless of their host Component.
51643   */
51644
51645  ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
51646  /**
51647   * Uses the browser's native Shadow DOM API to encapsulate CSS styles, meaning that it creates
51648   * a ShadowRoot for the component's host element which is then used to encapsulate
51649   * all the Component's styling.
51650   */
51651
51652  ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
51653})(ViewEncapsulation$1 || (ViewEncapsulation$1 = {}));
51654/**
51655 * @license
51656 * Copyright Google LLC All Rights Reserved.
51657 *
51658 * Use of this source code is governed by an MIT-style license that can be
51659 * found in the LICENSE file at https://angular.io/license
51660 */
51661// Always use __globalThis if available, which is the spec-defined global variable across all
51662// environments, then fallback to __global first, because in Node tests both __global and
51663// __window may be defined and _global should be __global in that case. Note: Typeof/Instanceof
51664// checks are considered side-effects in Terser. We explicitly mark this as side-effect free:
51665// https://github.com/terser/terser/issues/250.
51666
51667
51668const _global = /* @__PURE__ */(() => typeof globalThis !== 'undefined' && globalThis || typeof global !== 'undefined' && global || typeof window !== 'undefined' && window || typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope && self)();
51669/**
51670 * @license
51671 * Copyright Google LLC All Rights Reserved.
51672 *
51673 * Use of this source code is governed by an MIT-style license that can be
51674 * found in the LICENSE file at https://angular.io/license
51675 */
51676
51677
51678function ngDevModeResetPerfCounters() {
51679  const locationString = typeof location !== 'undefined' ? location.toString() : '';
51680  const newCounters = {
51681    namedConstructors: locationString.indexOf('ngDevMode=namedConstructors') != -1,
51682    firstCreatePass: 0,
51683    tNode: 0,
51684    tView: 0,
51685    rendererCreateTextNode: 0,
51686    rendererSetText: 0,
51687    rendererCreateElement: 0,
51688    rendererAddEventListener: 0,
51689    rendererSetAttribute: 0,
51690    rendererRemoveAttribute: 0,
51691    rendererSetProperty: 0,
51692    rendererSetClassName: 0,
51693    rendererAddClass: 0,
51694    rendererRemoveClass: 0,
51695    rendererSetStyle: 0,
51696    rendererRemoveStyle: 0,
51697    rendererDestroy: 0,
51698    rendererDestroyNode: 0,
51699    rendererMoveNode: 0,
51700    rendererRemoveNode: 0,
51701    rendererAppendChild: 0,
51702    rendererInsertBefore: 0,
51703    rendererCreateComment: 0
51704  }; // Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
51705
51706  const allowNgDevModeTrue = locationString.indexOf('ngDevMode=false') === -1;
51707  _global['ngDevMode'] = allowNgDevModeTrue && newCounters;
51708  return newCounters;
51709}
51710/**
51711 * This function checks to see if the `ngDevMode` has been set. If yes,
51712 * then we honor it, otherwise we default to dev mode with additional checks.
51713 *
51714 * The idea is that unless we are doing production build where we explicitly
51715 * set `ngDevMode == false` we should be helping the developer by providing
51716 * as much early warning and errors as possible.
51717 *
51718 * `ɵɵdefineComponent` is guaranteed to have been called before any component template functions
51719 * (and thus Ivy instructions), so a single initialization there is sufficient to ensure ngDevMode
51720 * is defined for the entire instruction set.
51721 *
51722 * When checking `ngDevMode` on toplevel, always init it before referencing it
51723 * (e.g. `((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode())`), otherwise you can
51724 *  get a `ReferenceError` like in https://github.com/angular/angular/issues/31595.
51725 *
51726 * Details on possible values for `ngDevMode` can be found on its docstring.
51727 *
51728 * NOTE:
51729 * - changes to the `ngDevMode` name must be synced with `compiler-cli/src/tooling.ts`.
51730 */
51731
51732
51733function initNgDevMode() {
51734  // The below checks are to ensure that calling `initNgDevMode` multiple times does not
51735  // reset the counters.
51736  // If the `ngDevMode` is not an object, then it means we have not created the perf counters
51737  // yet.
51738  if (typeof ngDevMode === 'undefined' || ngDevMode) {
51739    if (typeof ngDevMode !== 'object') {
51740      ngDevModeResetPerfCounters();
51741    }
51742
51743    return typeof ngDevMode !== 'undefined' && !!ngDevMode;
51744  }
51745
51746  return false;
51747}
51748/**
51749 * @license
51750 * Copyright Google LLC All Rights Reserved.
51751 *
51752 * Use of this source code is governed by an MIT-style license that can be
51753 * found in the LICENSE file at https://angular.io/license
51754 */
51755
51756/**
51757 * This file contains reuseable "empty" symbols that can be used as default return values
51758 * in different parts of the rendering code. Because the same symbols are returned, this
51759 * allows for identity checks against these values to be consistently used by the framework
51760 * code.
51761 */
51762
51763
51764const EMPTY_OBJ = {};
51765const EMPTY_ARRAY = []; // freezing the values prevents any code from accidentally inserting new values in
51766
51767if ((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode()) {
51768  // These property accesses can be ignored because ngDevMode will be set to false
51769  // when optimizing code and the whole if statement will be dropped.
51770  // tslint:disable-next-line:no-toplevel-property-access
51771  Object.freeze(EMPTY_OBJ); // tslint:disable-next-line:no-toplevel-property-access
51772
51773  Object.freeze(EMPTY_ARRAY);
51774}
51775/**
51776 * @license
51777 * Copyright Google LLC All Rights Reserved.
51778 *
51779 * Use of this source code is governed by an MIT-style license that can be
51780 * found in the LICENSE file at https://angular.io/license
51781 */
51782
51783
51784const NG_COMP_DEF = getClosureSafeProperty({
51785  ɵcmp: getClosureSafeProperty
51786});
51787const NG_DIR_DEF = getClosureSafeProperty({
51788  ɵdir: getClosureSafeProperty
51789});
51790const NG_PIPE_DEF = getClosureSafeProperty({
51791  ɵpipe: getClosureSafeProperty
51792});
51793const NG_MOD_DEF = getClosureSafeProperty({
51794  ɵmod: getClosureSafeProperty
51795});
51796const NG_FACTORY_DEF = getClosureSafeProperty({
51797  ɵfac: getClosureSafeProperty
51798});
51799/**
51800 * If a directive is diPublic, bloomAdd sets a property on the type with this constant as
51801 * the key and the directive's unique ID as the value. This allows us to map directives to their
51802 * bloom filter bit for DI.
51803 */
51804// TODO(misko): This is wrong. The NG_ELEMENT_ID should never be minified.
51805
51806const NG_ELEMENT_ID = getClosureSafeProperty({
51807  __NG_ELEMENT_ID__: getClosureSafeProperty
51808});
51809/**
51810 * @license
51811 * Copyright Google LLC All Rights Reserved.
51812 *
51813 * Use of this source code is governed by an MIT-style license that can be
51814 * found in the LICENSE file at https://angular.io/license
51815 */
51816
51817/** Counter used to generate unique IDs for component definitions. */
51818
51819let componentDefCount = 0;
51820/**
51821 * Create a component definition object.
51822 *
51823 *
51824 * # Example
51825 * ```
51826 * class MyDirective {
51827 *   // Generated by Angular Template Compiler
51828 *   // [Symbol] syntax will not be supported by TypeScript until v2.7
51829 *   static ɵcmp = defineComponent({
51830 *     ...
51831 *   });
51832 * }
51833 * ```
51834 * @codeGenApi
51835 */
51836
51837function ɵɵdefineComponent(componentDefinition) {
51838  return noSideEffects(() => {
51839    // Initialize ngDevMode. This must be the first statement in ɵɵdefineComponent.
51840    // See the `initNgDevMode` docstring for more information.
51841    (typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode();
51842    const type = componentDefinition.type;
51843    const standalone = componentDefinition.standalone === true;
51844    const declaredInputs = {};
51845    const def = {
51846      type: type,
51847      providersResolver: null,
51848      decls: componentDefinition.decls,
51849      vars: componentDefinition.vars,
51850      factory: null,
51851      template: componentDefinition.template || null,
51852      consts: componentDefinition.consts || null,
51853      ngContentSelectors: componentDefinition.ngContentSelectors,
51854      hostBindings: componentDefinition.hostBindings || null,
51855      hostVars: componentDefinition.hostVars || 0,
51856      hostAttrs: componentDefinition.hostAttrs || null,
51857      contentQueries: componentDefinition.contentQueries || null,
51858      declaredInputs: declaredInputs,
51859      inputs: null,
51860      outputs: null,
51861      exportAs: componentDefinition.exportAs || null,
51862      onPush: componentDefinition.changeDetection === ChangeDetectionStrategy.OnPush,
51863      directiveDefs: null,
51864      pipeDefs: null,
51865      standalone,
51866      dependencies: standalone && componentDefinition.dependencies || null,
51867      getStandaloneInjector: null,
51868      selectors: componentDefinition.selectors || EMPTY_ARRAY,
51869      viewQuery: componentDefinition.viewQuery || null,
51870      features: componentDefinition.features || null,
51871      data: componentDefinition.data || {},
51872      encapsulation: componentDefinition.encapsulation || ViewEncapsulation$1.Emulated,
51873      id: `c${componentDefCount++}`,
51874      styles: componentDefinition.styles || EMPTY_ARRAY,
51875      _: null,
51876      setInput: null,
51877      schemas: componentDefinition.schemas || null,
51878      tView: null
51879    };
51880    const dependencies = componentDefinition.dependencies;
51881    const feature = componentDefinition.features;
51882    def.inputs = invertObject(componentDefinition.inputs, declaredInputs), def.outputs = invertObject(componentDefinition.outputs), feature && feature.forEach(fn => fn(def));
51883    def.directiveDefs = dependencies ? () => (typeof dependencies === 'function' ? dependencies() : dependencies).map(extractDirectiveDef).filter(nonNull) : null;
51884    def.pipeDefs = dependencies ? () => (typeof dependencies === 'function' ? dependencies() : dependencies).map(getPipeDef$1).filter(nonNull) : null;
51885    return def;
51886  });
51887}
51888/**
51889 * Generated next to NgModules to monkey-patch directive and pipe references onto a component's
51890 * definition, when generating a direct reference in the component file would otherwise create an
51891 * import cycle.
51892 *
51893 * See [this explanation](https://hackmd.io/Odw80D0pR6yfsOjg_7XCJg?view) for more details.
51894 *
51895 * @codeGenApi
51896 */
51897
51898
51899function ɵɵsetComponentScope(type, directives, pipes) {
51900  const def = type.ɵcmp;
51901
51902  def.directiveDefs = () => (typeof directives === 'function' ? directives() : directives).map(extractDirectiveDef);
51903
51904  def.pipeDefs = () => (typeof pipes === 'function' ? pipes() : pipes).map(getPipeDef$1);
51905}
51906
51907function extractDirectiveDef(type) {
51908  return getComponentDef(type) || getDirectiveDef(type);
51909}
51910
51911function nonNull(value) {
51912  return value !== null;
51913}
51914/**
51915 * @codeGenApi
51916 */
51917
51918
51919function ɵɵdefineNgModule(def) {
51920  return noSideEffects(() => {
51921    const res = {
51922      type: def.type,
51923      bootstrap: def.bootstrap || EMPTY_ARRAY,
51924      declarations: def.declarations || EMPTY_ARRAY,
51925      imports: def.imports || EMPTY_ARRAY,
51926      exports: def.exports || EMPTY_ARRAY,
51927      transitiveCompileScopes: null,
51928      schemas: def.schemas || null,
51929      id: def.id || null
51930    };
51931    return res;
51932  });
51933}
51934/**
51935 * Adds the module metadata that is necessary to compute the module's transitive scope to an
51936 * existing module definition.
51937 *
51938 * Scope metadata of modules is not used in production builds, so calls to this function can be
51939 * marked pure to tree-shake it from the bundle, allowing for all referenced declarations
51940 * to become eligible for tree-shaking as well.
51941 *
51942 * @codeGenApi
51943 */
51944
51945
51946function ɵɵsetNgModuleScope(type, scope) {
51947  return noSideEffects(() => {
51948    const ngModuleDef = getNgModuleDef(type, true);
51949    ngModuleDef.declarations = scope.declarations || EMPTY_ARRAY;
51950    ngModuleDef.imports = scope.imports || EMPTY_ARRAY;
51951    ngModuleDef.exports = scope.exports || EMPTY_ARRAY;
51952  });
51953}
51954/**
51955 * Inverts an inputs or outputs lookup such that the keys, which were the
51956 * minified keys, are part of the values, and the values are parsed so that
51957 * the publicName of the property is the new key
51958 *
51959 * e.g. for
51960 *
51961 * ```
51962 * class Comp {
51963 *   @Input()
51964 *   propName1: string;
51965 *
51966 *   @Input('publicName2')
51967 *   declaredPropName2: number;
51968 * }
51969 * ```
51970 *
51971 * will be serialized as
51972 *
51973 * ```
51974 * {
51975 *   propName1: 'propName1',
51976 *   declaredPropName2: ['publicName2', 'declaredPropName2'],
51977 * }
51978 * ```
51979 *
51980 * which is than translated by the minifier as:
51981 *
51982 * ```
51983 * {
51984 *   minifiedPropName1: 'propName1',
51985 *   minifiedPropName2: ['publicName2', 'declaredPropName2'],
51986 * }
51987 * ```
51988 *
51989 * becomes: (public name => minifiedName)
51990 *
51991 * ```
51992 * {
51993 *  'propName1': 'minifiedPropName1',
51994 *  'publicName2': 'minifiedPropName2',
51995 * }
51996 * ```
51997 *
51998 * Optionally the function can take `secondary` which will result in: (public name => declared name)
51999 *
52000 * ```
52001 * {
52002 *  'propName1': 'propName1',
52003 *  'publicName2': 'declaredPropName2',
52004 * }
52005 * ```
52006 *
52007
52008 */
52009
52010
52011function invertObject(obj, secondary) {
52012  if (obj == null) return EMPTY_OBJ;
52013  const newLookup = {};
52014
52015  for (const minifiedKey in obj) {
52016    if (obj.hasOwnProperty(minifiedKey)) {
52017      let publicName = obj[minifiedKey];
52018      let declaredName = publicName;
52019
52020      if (Array.isArray(publicName)) {
52021        declaredName = publicName[1];
52022        publicName = publicName[0];
52023      }
52024
52025      newLookup[publicName] = minifiedKey;
52026
52027      if (secondary) {
52028        secondary[publicName] = declaredName;
52029      }
52030    }
52031  }
52032
52033  return newLookup;
52034}
52035/**
52036 * Create a directive definition object.
52037 *
52038 * # Example
52039 * ```ts
52040 * class MyDirective {
52041 *   // Generated by Angular Template Compiler
52042 *   // [Symbol] syntax will not be supported by TypeScript until v2.7
52043 *   static ɵdir = ɵɵdefineDirective({
52044 *     ...
52045 *   });
52046 * }
52047 * ```
52048 *
52049 * @codeGenApi
52050 */
52051
52052
52053const ɵɵdefineDirective = ɵɵdefineComponent;
52054/**
52055 * Create a pipe definition object.
52056 *
52057 * # Example
52058 * ```
52059 * class MyPipe implements PipeTransform {
52060 *   // Generated by Angular Template Compiler
52061 *   static ɵpipe = definePipe({
52062 *     ...
52063 *   });
52064 * }
52065 * ```
52066 * @param pipeDef Pipe definition generated by the compiler
52067 *
52068 * @codeGenApi
52069 */
52070
52071function ɵɵdefinePipe(pipeDef) {
52072  return {
52073    type: pipeDef.type,
52074    name: pipeDef.name,
52075    factory: null,
52076    pure: pipeDef.pure !== false,
52077    standalone: pipeDef.standalone === true,
52078    onDestroy: pipeDef.type.prototype.ngOnDestroy || null
52079  };
52080}
52081/**
52082 * The following getter methods retrieve the definition from the type. Currently the retrieval
52083 * honors inheritance, but in the future we may change the rule to require that definitions are
52084 * explicit. This would require some sort of migration strategy.
52085 */
52086
52087
52088function getComponentDef(type) {
52089  return type[NG_COMP_DEF] || null;
52090}
52091
52092function getDirectiveDef(type) {
52093  return type[NG_DIR_DEF] || null;
52094}
52095
52096function getPipeDef$1(type) {
52097  return type[NG_PIPE_DEF] || null;
52098}
52099
52100function isStandalone(type) {
52101  const def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef$1(type);
52102  return def !== null ? def.standalone : false;
52103}
52104
52105function getNgModuleDef(type, throwNotFound) {
52106  const ngModuleDef = type[NG_MOD_DEF] || null;
52107
52108  if (!ngModuleDef && throwNotFound === true) {
52109    throw new Error(`Type ${stringify(type)} does not have 'ɵmod' property.`);
52110  }
52111
52112  return ngModuleDef;
52113}
52114/**
52115 * @license
52116 * Copyright Google LLC All Rights Reserved.
52117 *
52118 * Use of this source code is governed by an MIT-style license that can be
52119 * found in the LICENSE file at https://angular.io/license
52120 */
52121// Below are constants for LView indices to help us look up LView members
52122// without having to remember the specific indices.
52123// Uglify will inline these when minifying so there shouldn't be a cost.
52124
52125
52126const HOST = 0;
52127const TVIEW = 1;
52128const FLAGS = 2;
52129const PARENT = 3;
52130const NEXT = 4;
52131const TRANSPLANTED_VIEWS_TO_REFRESH = 5;
52132const T_HOST = 6;
52133const CLEANUP = 7;
52134const CONTEXT = 8;
52135const INJECTOR$1 = 9;
52136const RENDERER_FACTORY = 10;
52137const RENDERER = 11;
52138const SANITIZER = 12;
52139const CHILD_HEAD = 13;
52140const CHILD_TAIL = 14; // FIXME(misko): Investigate if the three declarations aren't all same thing.
52141
52142const DECLARATION_VIEW = 15;
52143const DECLARATION_COMPONENT_VIEW = 16;
52144const DECLARATION_LCONTAINER = 17;
52145const PREORDER_HOOK_FLAGS = 18;
52146const QUERIES = 19;
52147const ID = 20;
52148const EMBEDDED_VIEW_INJECTOR = 21;
52149/**
52150 * Size of LView's header. Necessary to adjust for it when setting slots.
52151 *
52152 * IMPORTANT: `HEADER_OFFSET` should only be referred to the in the `ɵɵ*` instructions to translate
52153 * instruction index into `LView` index. All other indexes should be in the `LView` index space and
52154 * there should be no need to refer to `HEADER_OFFSET` anywhere else.
52155 */
52156
52157const HEADER_OFFSET = 22;
52158/**
52159 * Converts `TViewType` into human readable text.
52160 * Make sure this matches with `TViewType`
52161 */
52162
52163const TViewTypeAsString = ['Root', 'Component', 'Embedded' // 2
52164]; // Note: This hack is necessary so we don't erroneously get a circular dependency
52165// failure based on types.
52166
52167const unusedValueExportToPlacateAjd$8 = 1;
52168/**
52169 * @license
52170 * Copyright Google LLC All Rights Reserved.
52171 *
52172 * Use of this source code is governed by an MIT-style license that can be
52173 * found in the LICENSE file at https://angular.io/license
52174 */
52175
52176/**
52177 * Special location which allows easy identification of type. If we have an array which was
52178 * retrieved from the `LView` and that array has `true` at `TYPE` location, we know it is
52179 * `LContainer`.
52180 */
52181
52182const TYPE = 1;
52183/**
52184 * Below are constants for LContainer indices to help us look up LContainer members
52185 * without having to remember the specific indices.
52186 * Uglify will inline these when minifying so there shouldn't be a cost.
52187 */
52188
52189/**
52190 * Flag to signify that this `LContainer` may have transplanted views which need to be change
52191 * detected. (see: `LView[DECLARATION_COMPONENT_VIEW])`.
52192 *
52193 * This flag, once set, is never unset for the `LContainer`. This means that when unset we can skip
52194 * a lot of work in `refreshEmbeddedViews`. But when set we still need to verify
52195 * that the `MOVED_VIEWS` are transplanted and on-push.
52196 */
52197
52198const HAS_TRANSPLANTED_VIEWS = 2; // PARENT, NEXT, TRANSPLANTED_VIEWS_TO_REFRESH are indices 3, 4, and 5
52199// As we already have these constants in LView, we don't need to re-create them.
52200// T_HOST is index 6
52201// We already have this constants in LView, we don't need to re-create it.
52202
52203const NATIVE = 7;
52204const VIEW_REFS = 8;
52205const MOVED_VIEWS = 9;
52206/**
52207 * Size of LContainer's header. Represents the index after which all views in the
52208 * container will be inserted. We need to keep a record of current views so we know
52209 * which views are already in the DOM (and don't need to be re-added) and so we can
52210 * remove views from the DOM when they are no longer required.
52211 */
52212
52213const CONTAINER_HEADER_OFFSET = 10; // Note: This hack is necessary so we don't erroneously get a circular dependency
52214// failure based on types.
52215
52216const unusedValueExportToPlacateAjd$7 = 1;
52217/**
52218 * @license
52219 * Copyright Google LLC All Rights Reserved.
52220 *
52221 * Use of this source code is governed by an MIT-style license that can be
52222 * found in the LICENSE file at https://angular.io/license
52223 */
52224
52225/**
52226 * True if `value` is `LView`.
52227 * @param value wrapped value of `RNode`, `LView`, `LContainer`
52228 */
52229
52230function isLView(value) {
52231  return Array.isArray(value) && typeof value[TYPE] === 'object';
52232}
52233/**
52234 * True if `value` is `LContainer`.
52235 * @param value wrapped value of `RNode`, `LView`, `LContainer`
52236 */
52237
52238
52239function isLContainer(value) {
52240  return Array.isArray(value) && value[TYPE] === true;
52241}
52242
52243function isContentQueryHost(tNode) {
52244  return (tNode.flags & 8
52245  /* TNodeFlags.hasContentQuery */
52246  ) !== 0;
52247}
52248
52249function isComponentHost(tNode) {
52250  return (tNode.flags & 2
52251  /* TNodeFlags.isComponentHost */
52252  ) === 2
52253  /* TNodeFlags.isComponentHost */
52254  ;
52255}
52256
52257function isDirectiveHost(tNode) {
52258  return (tNode.flags & 1
52259  /* TNodeFlags.isDirectiveHost */
52260  ) === 1
52261  /* TNodeFlags.isDirectiveHost */
52262  ;
52263}
52264
52265function isComponentDef(def) {
52266  return def.template !== null;
52267}
52268
52269function isRootView(target) {
52270  return (target[FLAGS] & 256
52271  /* LViewFlags.IsRoot */
52272  ) !== 0;
52273}
52274/**
52275 * @license
52276 * Copyright Google LLC All Rights Reserved.
52277 *
52278 * Use of this source code is governed by an MIT-style license that can be
52279 * found in the LICENSE file at https://angular.io/license
52280 */
52281// [Assert functions do not constraint type when they are guarded by a truthy
52282// expression.](https://github.com/microsoft/TypeScript/issues/37295)
52283
52284
52285function assertTNodeForLView(tNode, lView) {
52286  assertTNodeForTView(tNode, lView[TVIEW]);
52287}
52288
52289function assertTNodeForTView(tNode, tView) {
52290  assertTNode(tNode);
52291  tNode.hasOwnProperty('tView_') && assertEqual(tNode.tView_, tView, 'This TNode does not belong to this TView.');
52292}
52293
52294function assertTNode(tNode) {
52295  assertDefined(tNode, 'TNode must be defined');
52296
vendor: 8,301 bytes, lines 52297-52550
52297  if (!(tNode && typeof tNode === 'object' && tNode.hasOwnProperty('directiveStylingLast'))) {
52298    throwError('Not of type TNode, got: ' + tNode);
52299  }
52300}
52301
52302function assertTIcu(tIcu) {
52303  assertDefined(tIcu, 'Expected TIcu to be defined');
52304
52305  if (!(typeof tIcu.currentCaseLViewIndex === 'number')) {
52306    throwError('Object is not of TIcu type.');
52307  }
52308}
52309
52310function assertComponentType(actual, msg = 'Type passed in is not ComponentType, it does not have \'ɵcmp\' property.') {
52311  if (!getComponentDef(actual)) {
52312    throwError(msg);
52313  }
52314}
52315
52316function assertNgModuleType(actual, msg = 'Type passed in is not NgModuleType, it does not have \'ɵmod\' property.') {
52317  if (!getNgModuleDef(actual)) {
52318    throwError(msg);
52319  }
52320}
52321
52322function assertCurrentTNodeIsParent(isParent) {
52323  assertEqual(isParent, true, 'currentTNode should be a parent');
52324}
52325
52326function assertHasParent(tNode) {
52327  assertDefined(tNode, 'currentTNode should exist!');
52328  assertDefined(tNode.parent, 'currentTNode should have a parent');
52329}
52330
52331function assertDataNext(lView, index, arr) {
52332  if (arr == null) arr = lView;
52333  assertEqual(arr.length, index, `index ${index} expected to be at the end of arr (length ${arr.length})`);
52334}
52335
52336function assertLContainer(value) {
52337  assertDefined(value, 'LContainer must be defined');
52338  assertEqual(isLContainer(value), true, 'Expecting LContainer');
52339}
52340
52341function assertLViewOrUndefined(value) {
52342  value && assertEqual(isLView(value), true, 'Expecting LView or undefined or null');
52343}
52344
52345function assertLView(value) {
52346  assertDefined(value, 'LView must be defined');
52347  assertEqual(isLView(value), true, 'Expecting LView');
52348}
52349
52350function assertFirstCreatePass(tView, errMessage) {
52351  assertEqual(tView.firstCreatePass, true, errMessage || 'Should only be called in first create pass.');
52352}
52353
52354function assertFirstUpdatePass(tView, errMessage) {
52355  assertEqual(tView.firstUpdatePass, true, errMessage || 'Should only be called in first update pass.');
52356}
52357/**
52358 * This is a basic sanity check that an object is probably a directive def. DirectiveDef is
52359 * an interface, so we can't do a direct instanceof check.
52360 */
52361
52362
52363function assertDirectiveDef(obj) {
52364  if (obj.type === undefined || obj.selectors == undefined || obj.inputs === undefined) {
52365    throwError(`Expected a DirectiveDef/ComponentDef and this object does not seem to have the expected shape.`);
52366  }
52367}
52368
52369function assertIndexInDeclRange(lView, index) {
52370  const tView = lView[1];
52371  assertBetween(HEADER_OFFSET, tView.bindingStartIndex, index);
52372}
52373
52374function assertIndexInVarsRange(lView, index) {
52375  const tView = lView[1];
52376  assertBetween(tView.bindingStartIndex, tView.expandoStartIndex, index);
52377}
52378
52379function assertIndexInExpandoRange(lView, index) {
52380  const tView = lView[1];
52381  assertBetween(tView.expandoStartIndex, lView.length, index);
52382}
52383
52384function assertBetween(lower, upper, index) {
52385  if (!(lower <= index && index < upper)) {
52386    throwError(`Index out of range (expecting ${lower} <= ${index} < ${upper})`);
52387  }
52388}
52389
52390function assertProjectionSlots(lView, errMessage) {
52391  assertDefined(lView[DECLARATION_COMPONENT_VIEW], 'Component views should exist.');
52392  assertDefined(lView[DECLARATION_COMPONENT_VIEW][T_HOST].projection, errMessage || 'Components with projection nodes (<ng-content>) must have projection slots defined.');
52393}
52394
52395function assertParentView(lView, errMessage) {
52396  assertDefined(lView, errMessage || 'Component views should always have a parent view (component\'s host view)');
52397}
52398/**
52399 * This is a basic sanity check that the `injectorIndex` seems to point to what looks like a
52400 * NodeInjector data structure.
52401 *
52402 * @param lView `LView` which should be checked.
52403 * @param injectorIndex index into the `LView` where the `NodeInjector` is expected.
52404 */
52405
52406
52407function assertNodeInjector(lView, injectorIndex) {
52408  assertIndexInExpandoRange(lView, injectorIndex);
52409  assertIndexInExpandoRange(lView, injectorIndex + 8
52410  /* NodeInjectorOffset.PARENT */
52411  );
52412  assertNumber(lView[injectorIndex + 0], 'injectorIndex should point to a bloom filter');
52413  assertNumber(lView[injectorIndex + 1], 'injectorIndex should point to a bloom filter');
52414  assertNumber(lView[injectorIndex + 2], 'injectorIndex should point to a bloom filter');
52415  assertNumber(lView[injectorIndex + 3], 'injectorIndex should point to a bloom filter');
52416  assertNumber(lView[injectorIndex + 4], 'injectorIndex should point to a bloom filter');
52417  assertNumber(lView[injectorIndex + 5], 'injectorIndex should point to a bloom filter');
52418  assertNumber(lView[injectorIndex + 6], 'injectorIndex should point to a bloom filter');
52419  assertNumber(lView[injectorIndex + 7], 'injectorIndex should point to a bloom filter');
52420  assertNumber(lView[injectorIndex + 8
52421  /* NodeInjectorOffset.PARENT */
52422  ], 'injectorIndex should point to parent injector');
52423}
52424/**
52425 * @license
52426 * Copyright Google LLC All Rights Reserved.
52427 *
52428 * Use of this source code is governed by an MIT-style license that can be
52429 * found in the LICENSE file at https://angular.io/license
52430 */
52431
52432
52433function getFactoryDef(type, throwNotFound) {
52434  const hasFactoryDef = type.hasOwnProperty(NG_FACTORY_DEF);
52435
52436  if (!hasFactoryDef && throwNotFound === true && ngDevMode) {
52437    throw new Error(`Type ${stringify(type)} does not have 'ɵfac' property.`);
52438  }
52439
52440  return hasFactoryDef ? type[NG_FACTORY_DEF] : null;
52441}
52442/**
52443 * @license
52444 * Copyright Google LLC All Rights Reserved.
52445 *
52446 * Use of this source code is governed by an MIT-style license that can be
52447 * found in the LICENSE file at https://angular.io/license
52448 */
52449
52450/**
52451 * Represents a basic change from a previous to a new value for a single
52452 * property on a directive instance. Passed as a value in a
52453 * {@link SimpleChanges} object to the `ngOnChanges` hook.
52454 *
52455 * @see `OnChanges`
52456 *
52457 * @publicApi
52458 */
52459
52460
52461class SimpleChange {
52462  constructor(previousValue, currentValue, firstChange) {
52463    this.previousValue = previousValue;
52464    this.currentValue = currentValue;
52465    this.firstChange = firstChange;
52466  }
52467  /**
52468   * Check whether the new value is the first value assigned.
52469   */
52470
52471
52472  isFirstChange() {
52473    return this.firstChange;
52474  }
52475
52476}
52477/**
52478 * @license
52479 * Copyright Google LLC All Rights Reserved.
52480 *
52481 * Use of this source code is governed by an MIT-style license that can be
52482 * found in the LICENSE file at https://angular.io/license
52483 */
52484
52485/**
52486 * The NgOnChangesFeature decorates a component with support for the ngOnChanges
52487 * lifecycle hook, so it should be included in any component that implements
52488 * that hook.
52489 *
52490 * If the component or directive uses inheritance, the NgOnChangesFeature MUST
52491 * be included as a feature AFTER {@link InheritDefinitionFeature}, otherwise
52492 * inherited properties will not be propagated to the ngOnChanges lifecycle
52493 * hook.
52494 *
52495 * Example usage:
52496 *
52497 * ```
52498 * static ɵcmp = defineComponent({
52499 *   ...
52500 *   inputs: {name: 'publicName'},
52501 *   features: [NgOnChangesFeature]
52502 * });
52503 * ```
52504 *
52505 * @codeGenApi
52506 */
52507
52508
52509function ɵɵNgOnChangesFeature() {
52510  return NgOnChangesFeatureImpl;
52511}
52512
52513function NgOnChangesFeatureImpl(definition) {
52514  if (definition.type.prototype.ngOnChanges) {
52515    definition.setInput = ngOnChangesSetInput;
52516  }
52517
52518  return rememberChangeHistoryAndInvokeOnChangesHook;
52519} // This option ensures that the ngOnChanges lifecycle hook will be inherited
52520// from superclasses (in InheritDefinitionFeature).
52521
52522/** @nocollapse */
52523// tslint:disable-next-line:no-toplevel-property-access
52524
52525
52526ɵɵNgOnChangesFeature.ngInherit = true;
52527/**
52528 * This is a synthetic lifecycle hook which gets inserted into `TView.preOrderHooks` to simulate
52529 * `ngOnChanges`.
52530 *
52531 * The hook reads the `NgSimpleChangesStore` data from the component instance and if changes are
52532 * found it invokes `ngOnChanges` on the component instance.
52533 *
52534 * @param this Component instance. Because this function gets inserted into `TView.preOrderHooks`,
52535 *     it is guaranteed to be called with component instance.
52536 */
52537
52538function rememberChangeHistoryAndInvokeOnChangesHook() {
52539  const simpleChangesStore = getSimpleChangesStore(this);
52540  const current = simpleChangesStore?.current;
52541
52542  if (current) {
52543    const previous = simpleChangesStore.previous;
52544
52545    if (previous === EMPTY_OBJ) {
52546      simpleChangesStore.previous = current;
52547    } else {
52548      // New changes are copied to the previous store, so that we don't lose history for inputs
52549      // which were not changed this time
52550      for (let key in current) {
52551        previous[key] = current[key];
52552      }
52553    }
52554
52555    simpleChangesStore.current = null;
52556    this.ngOnChanges(current);
52557  }
52558}
52559
52560function ngOnChangesSetInput(instance, value, publicName, privateName) {
52561  const simpleChangesStore = getSimpleChangesStore(instance) || setSimpleChangesStore(instance, {
52562    previous: EMPTY_OBJ,
52563    current: null
52564  });
52565  const current = simpleChangesStore.current || (simpleChangesStore.current = {});
52566  const previous = simpleChangesStore.previous;
52567  const declaredName = this.declaredInputs[publicName];
52568  const previousChange = previous[declaredName];
52569  current[declaredName] = new SimpleChange(previousChange && previousChange.currentValue, value, previous === EMPTY_OBJ);
52570  instance[privateName] = value;
52571}
52572
52573const SIMPLE_CHANGES_STORE = '__ngSimpleChanges__';
52574
52575function getSimpleChangesStore(instance) {
52576  return instance[SIMPLE_CHANGES_STORE] || null;
52577}
52578
52579function setSimpleChangesStore(instance, store) {
52580  return instance[SIMPLE_CHANGES_STORE] = store;
52581}
52582/**
52583 * @license
52584 * Copyright Google LLC All Rights Reserved.
52585 *
52586 * Use of this source code is governed by an MIT-style license that can be
52587 * found in the LICENSE file at https://angular.io/license
52588 */
52589
52590
52591let profilerCallback = null;
52592/**
52593 * Sets the callback function which will be invoked before and after performing certain actions at
52594 * runtime (for example, before and after running change detection).
52595 *
52596 * Warning: this function is *INTERNAL* and should not be relied upon in application's code.
52597 * The contract of the function might be changed in any release and/or the function can be removed
52598 * completely.
52599 *
52600 * @param profiler function provided by the caller or null value to disable profiling.
52601 */
52602
52603const setProfiler = profiler => {
52604  profilerCallback = profiler;
52605};
52606/**
52607 * Profiler function which wraps user code executed by the runtime.
52608 *
52609 * @param event ProfilerEvent corresponding to the execution context
52610 * @param instance component instance
52611 * @param hookOrListener lifecycle hook function or output listener. The value depends on the
52612 *  execution context
52613 * @returns
52614 */
52615
52616
52617const profiler = function (event, instance, hookOrListener) {
52618  if (profilerCallback != null
52619  /* both `null` and `undefined` */
52620  ) {
52621    profilerCallback(event, instance, hookOrListener);
52622  }
52623};
52624/**
52625 * @license
52626 * Copyright Google LLC All Rights Reserved.
52627 *
52628 * Use of this source code is governed by an MIT-style license that can be
52629 * found in the LICENSE file at https://angular.io/license
52630 */
52631
52632
52633const SVG_NAMESPACE = 'svg';
52634const SVG_NAMESPACE_URI = 'http://www.w3.org/2000/svg';
52635const MATH_ML_NAMESPACE = 'math';
52636const MATH_ML_NAMESPACE_URI = 'http://www.w3.org/1998/MathML/';
52637
52638function getNamespaceUri(namespace) {
52639  const name = namespace.toLowerCase();
52640  return name === SVG_NAMESPACE ? SVG_NAMESPACE_URI : name === MATH_ML_NAMESPACE ? MATH_ML_NAMESPACE_URI : null;
52641}
52642/**
52643 * @license
52644 * Copyright Google LLC All Rights Reserved.
52645 *
52646 * Use of this source code is governed by an MIT-style license that can be
52647 * found in the LICENSE file at https://angular.io/license
52648 */
52649
52650/**
52651 * For efficiency reasons we often put several different data types (`RNode`, `LView`, `LContainer`)
52652 * in same location in `LView`. This is because we don't want to pre-allocate space for it
52653 * because the storage is sparse. This file contains utilities for dealing with such data types.
52654 *
52655 * How do we know what is stored at a given location in `LView`.
52656 * - `Array.isArray(value) === false` => `RNode` (The normal storage value)
52657 * - `Array.isArray(value) === true` => then the `value[0]` represents the wrapped value.
52658 *   - `typeof value[TYPE] === 'object'` => `LView`
52659 *      - This happens when we have a component at a given location
52660 *   - `typeof value[TYPE] === true` => `LContainer`
52661 *      - This happens when we have `LContainer` binding at a given location.
52662 *
52663 *
52664 * NOTE: it is assumed that `Array.isArray` and `typeof` operations are very efficient.
52665 */
52666
52667/**
52668 * Returns `RNode`.
52669 * @param value wrapped value of `RNode`, `LView`, `LContainer`
52670 */
52671
52672
52673function unwrapRNode(value) {
52674  while (Array.isArray(value)) {
52675    value = value[HOST];
52676  }
52677
52678  return value;
52679}
52680/**
52681 * Returns `LView` or `null` if not found.
52682 * @param value wrapped value of `RNode`, `LView`, `LContainer`
52683 */
52684
52685
52686function unwrapLView(value) {
52687  while (Array.isArray(value)) {
52688    // This check is same as `isLView()` but we don't call at as we don't want to call
52689    // `Array.isArray()` twice and give JITer more work for inlining.
52690    if (typeof value[TYPE] === 'object') return value;
52691    value = value[HOST];
52692  }
52693
52694  return null;
52695}
52696/**
52697 * Returns `LContainer` or `null` if not found.
52698 * @param value wrapped value of `RNode`, `LView`, `LContainer`
52699 */
52700
52701
52702function unwrapLContainer(value) {
52703  while (Array.isArray(value)) {
52704    // This check is same as `isLContainer()` but we don't call at as we don't want to call
52705    // `Array.isArray()` twice and give JITer more work for inlining.
52706    if (value[TYPE] === true) return value;
52707    value = value[HOST];
52708  }
52709
52710  return null;
52711}
52712/**
52713 * Retrieves an element value from the provided `viewData`, by unwrapping
52714 * from any containers, component views, or style contexts.
52715 */
52716
52717
52718function getNativeByIndex(index, lView) {
52719  ngDevMode && assertIndexInRange(lView, index);
52720  ngDevMode && assertGreaterThanOrEqual(index, HEADER_OFFSET, 'Expected to be past HEADER_OFFSET');
52721  return unwrapRNode(lView[index]);
52722}
52723/**
52724 * Retrieve an `RNode` for a given `TNode` and `LView`.
52725 *
52726 * This function guarantees in dev mode to retrieve a non-null `RNode`.
52727 *
52728 * @param tNode
52729 * @param lView
52730 */
52731
52732
52733function getNativeByTNode(tNode, lView) {
52734  ngDevMode && assertTNodeForLView(tNode, lView);
52735  ngDevMode && assertIndexInRange(lView, tNode.index);
52736  const node = unwrapRNode(lView[tNode.index]);
52737  return node;
52738}
52739/**
52740 * Retrieve an `RNode` or `null` for a given `TNode` and `LView`.
52741 *
52742 * Some `TNode`s don't have associated `RNode`s. For example `Projection`
52743 *
52744 * @param tNode
52745 * @param lView
52746 */
52747
52748
52749function getNativeByTNodeOrNull(tNode, lView) {
52750  const index = tNode === null ? -1 : tNode.index;
52751
52752  if (index !== -1) {
52753    ngDevMode && assertTNodeForLView(tNode, lView);
52754    const node = unwrapRNode(lView[index]);
52755    return node;
52756  }
52757
52758  return null;
52759} // fixme(misko): The return Type should be `TNode|null`
52760
52761
52762function getTNode(tView, index) {
52763  ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');
52764  ngDevMode && assertLessThan(index, tView.data.length, 'wrong index for TNode');
52765  const tNode = tView.data[index];
52766  ngDevMode && tNode !== null && assertTNode(tNode);
52767  return tNode;
52768}
52769/** Retrieves a value from any `LView` or `TData`. */
52770
52771
52772function load(view, index) {
52773  ngDevMode && assertIndexInRange(view, index);
52774  return view[index];
52775}
52776
52777function getComponentLViewByIndex(nodeIndex, hostView) {
52778  // Could be an LView or an LContainer. If LContainer, unwrap to find LView.
52779  ngDevMode && assertIndexInRange(hostView, nodeIndex);
52780  const slotValue = hostView[nodeIndex];
52781  const lView = isLView(slotValue) ? slotValue : slotValue[HOST];
52782  return lView;
52783}
52784/** Checks whether a given view is in creation mode */
52785
52786
52787function isCreationMode(view) {
52788  return (view[FLAGS] & 4
52789  /* LViewFlags.CreationMode */
52790  ) === 4
52791  /* LViewFlags.CreationMode */
52792  ;
52793}
52794/**
52795 * Returns a boolean for whether the view is attached to the change detection tree.
52796 *
52797 * Note: This determines whether a view should be checked, not whether it's inserted
52798 * into a container. For that, you'll want `viewAttachedToContainer` below.
52799 */
52800
52801
52802function viewAttachedToChangeDetector(view) {
52803  return (view[FLAGS] & 64
52804  /* LViewFlags.Attached */
52805  ) === 64
52806  /* LViewFlags.Attached */
52807  ;
52808}
52809/** Returns a boolean for whether the view is attached to a container. */
52810
52811
52812function viewAttachedToContainer(view) {
52813  return isLContainer(view[PARENT]);
52814}
52815
52816function getConstant(consts, index) {
52817  if (index === null || index === undefined) return null;
52818  ngDevMode && assertIndexInRange(consts, index);
52819  return consts[index];
52820}
52821/**
52822 * Resets the pre-order hook flags of the view.
52823 * @param lView the LView on which the flags are reset
52824 */
52825
52826
52827function resetPreOrderHookFlags(lView) {
52828  lView[PREORDER_HOOK_FLAGS] = 0;
52829}
52830/**
52831 * Updates the `TRANSPLANTED_VIEWS_TO_REFRESH` counter on the `LContainer` as well as the parents
52832 * whose
52833 *  1. counter goes from 0 to 1, indicating that there is a new child that has a view to refresh
52834 *  or
52835 *  2. counter goes from 1 to 0, indicating there are no more descendant views to refresh
52836 */
52837
52838
52839function updateTransplantedViewCount(lContainer, amount) {
52840  lContainer[TRANSPLANTED_VIEWS_TO_REFRESH] += amount;
52841  let viewOrContainer = lContainer;
52842  let parent = lContainer[PARENT];
52843
52844  while (parent !== null && (amount === 1 && viewOrContainer[TRANSPLANTED_VIEWS_TO_REFRESH] === 1 || amount === -1 && viewOrContainer[TRANSPLANTED_VIEWS_TO_REFRESH] === 0)) {
52845    parent[TRANSPLANTED_VIEWS_TO_REFRESH] += amount;
52846    viewOrContainer = parent;
52847    parent = parent[PARENT];
52848  }
52849}
52850/**
52851 * @license
52852 * Copyright Google LLC All Rights Reserved.
52853 *
52854 * Use of this source code is governed by an MIT-style license that can be
52855 * found in the LICENSE file at https://angular.io/license
52856 */
52857
52858
52859const instructionState = {
52860  lFrame: createLFrame(null),
52861  bindingsEnabled: true
52862};
52863/**
52864 * In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error.
52865 *
52866 * Necessary to support ChangeDetectorRef.checkNoChanges().
52867 *
52868 * The `checkNoChanges` function is invoked only in ngDevMode=true and verifies that no unintended
52869 * changes exist in the change detector or its children.
52870 */
52871
52872let _isInCheckNoChangesMode = false;
52873/**
52874 * Returns true if the instruction state stack is empty.
52875 *
52876 * Intended to be called from tests only (tree shaken otherwise).
52877 */
52878
52879function specOnlyIsInstructionStateEmpty() {
52880  return instructionState.lFrame.parent === null;
52881}
52882
52883function getElementDepthCount() {
52884  return instructionState.lFrame.elementDepthCount;
52885}
52886
52887function increaseElementDepthCount() {
52888  instructionState.lFrame.elementDepthCount++;
52889}
52890
52891function decreaseElementDepthCount() {
52892  instructionState.lFrame.elementDepthCount--;
52893}
52894
52895function getBindingsEnabled() {
52896  return instructionState.bindingsEnabled;
52897}
52898/**
52899 * Enables directive matching on elements.
52900 *
52901 *  * Example:
52902 * ```
52903 * <my-comp my-directive>
52904 *   Should match component / directive.
52905 * </my-comp>
52906 * <div ngNonBindable>
52907 *   <!-- ɵɵdisableBindings() -->
52908 *   <my-comp my-directive>
52909 *     Should not match component / directive because we are in ngNonBindable.
52910 *   </my-comp>
52911 *   <!-- ɵɵenableBindings() -->
52912 * </div>
52913 * ```
52914 *
52915 * @codeGenApi
52916 */
52917
52918
52919function ɵɵenableBindings() {
52920  instructionState.bindingsEnabled = true;
52921}
52922/**
52923 * Disables directive matching on element.
52924 *
52925 *  * Example:
52926 * ```
52927 * <my-comp my-directive>
52928 *   Should match component / directive.
52929 * </my-comp>
52930 * <div ngNonBindable>
52931 *   <!-- ɵɵdisableBindings() -->
52932 *   <my-comp my-directive>
52933 *     Should not match component / directive because we are in ngNonBindable.
52934 *   </my-comp>
52935 *   <!-- ɵɵenableBindings() -->
52936 * </div>
52937 * ```
52938 *
52939 * @codeGenApi
52940 */
52941
52942
52943function ɵɵdisableBindings() {
52944  instructionState.bindingsEnabled = false;
vendor: 6,419 bytes, lines 52945-53175
52945}
52946/**
52947 * Return the current `LView`.
52948 */
52949
52950
52951function getLView() {
52952  return instructionState.lFrame.lView;
52953}
52954/**
52955 * Return the current `TView`.
52956 */
52957
52958
52959function getTView() {
52960  return instructionState.lFrame.tView;
52961}
52962/**
52963 * Restores `contextViewData` to the given OpaqueViewState instance.
52964 *
52965 * Used in conjunction with the getCurrentView() instruction to save a snapshot
52966 * of the current view and restore it when listeners are invoked. This allows
52967 * walking the declaration view tree in listeners to get vars from parent views.
52968 *
52969 * @param viewToRestore The OpaqueViewState instance to restore.
52970 * @returns Context of the restored OpaqueViewState instance.
52971 *
52972 * @codeGenApi
52973 */
52974
52975
52976function ɵɵrestoreView(viewToRestore) {
52977  instructionState.lFrame.contextLView = viewToRestore;
52978  return viewToRestore[CONTEXT];
52979}
52980/**
52981 * Clears the view set in `ɵɵrestoreView` from memory. Returns the passed in
52982 * value so that it can be used as a return value of an instruction.
52983 *
52984 * @codeGenApi
52985 */
52986
52987
52988function ɵɵresetView(value) {
52989  instructionState.lFrame.contextLView = null;
52990  return value;
52991}
52992
52993function getCurrentTNode() {
52994  let currentTNode = getCurrentTNodePlaceholderOk();
52995
52996  while (currentTNode !== null && currentTNode.type === 64
52997  /* TNodeType.Placeholder */
52998  ) {
52999    currentTNode = currentTNode.parent;
53000  }
53001
53002  return currentTNode;
53003}
53004
53005function getCurrentTNodePlaceholderOk() {
53006  return instructionState.lFrame.currentTNode;
53007}
53008
53009function getCurrentParentTNode() {
53010  const lFrame = instructionState.lFrame;
53011  const currentTNode = lFrame.currentTNode;
53012  return lFrame.isParent ? currentTNode : currentTNode.parent;
53013}
53014
53015function setCurrentTNode(tNode, isParent) {
53016  ngDevMode && tNode && assertTNodeForTView(tNode, instructionState.lFrame.tView);
53017  const lFrame = instructionState.lFrame;
53018  lFrame.currentTNode = tNode;
53019  lFrame.isParent = isParent;
53020}
53021
53022function isCurrentTNodeParent() {
53023  return instructionState.lFrame.isParent;
53024}
53025
53026function setCurrentTNodeAsNotParent() {
53027  instructionState.lFrame.isParent = false;
53028}
53029
53030function setCurrentTNodeAsParent() {
53031  instructionState.lFrame.isParent = true;
53032}
53033
53034function getContextLView() {
53035  const contextLView = instructionState.lFrame.contextLView;
53036  ngDevMode && assertDefined(contextLView, 'contextLView must be defined.');
53037  return contextLView;
53038}
53039
53040function isInCheckNoChangesMode() {
53041  !ngDevMode && throwError('Must never be called in production mode');
53042  return _isInCheckNoChangesMode;
53043}
53044
53045function setIsInCheckNoChangesMode(mode) {
53046  !ngDevMode && throwError('Must never be called in production mode');
53047  _isInCheckNoChangesMode = mode;
53048} // top level variables should not be exported for performance reasons (PERF_NOTES.md)
53049
53050
53051function getBindingRoot() {
53052  const lFrame = instructionState.lFrame;
53053  let index = lFrame.bindingRootIndex;
53054
53055  if (index === -1) {
53056    index = lFrame.bindingRootIndex = lFrame.tView.bindingStartIndex;
53057  }
53058
53059  return index;
53060}
53061
53062function getBindingIndex() {
53063  return instructionState.lFrame.bindingIndex;
53064}
53065
53066function setBindingIndex(value) {
53067  return instructionState.lFrame.bindingIndex = value;
53068}
53069
53070function nextBindingIndex() {
53071  return instructionState.lFrame.bindingIndex++;
53072}
53073
53074function incrementBindingIndex(count) {
53075  const lFrame = instructionState.lFrame;
53076  const index = lFrame.bindingIndex;
53077  lFrame.bindingIndex = lFrame.bindingIndex + count;
53078  return index;
53079}
53080
53081function isInI18nBlock() {
53082  return instructionState.lFrame.inI18n;
53083}
53084
53085function setInI18nBlock(isInI18nBlock) {
53086  instructionState.lFrame.inI18n = isInI18nBlock;
53087}
53088/**
53089 * Set a new binding root index so that host template functions can execute.
53090 *
53091 * Bindings inside the host template are 0 index. But because we don't know ahead of time
53092 * how many host bindings we have we can't pre-compute them. For this reason they are all
53093 * 0 index and we just shift the root so that they match next available location in the LView.
53094 *
53095 * @param bindingRootIndex Root index for `hostBindings`
53096 * @param currentDirectiveIndex `TData[currentDirectiveIndex]` will point to the current directive
53097 *        whose `hostBindings` are being processed.
53098 */
53099
53100
53101function setBindingRootForHostBindings(bindingRootIndex, currentDirectiveIndex) {
53102  const lFrame = instructionState.lFrame;
53103  lFrame.bindingIndex = lFrame.bindingRootIndex = bindingRootIndex;
53104  setCurrentDirectiveIndex(currentDirectiveIndex);
53105}
53106/**
53107 * When host binding is executing this points to the directive index.
53108 * `TView.data[getCurrentDirectiveIndex()]` is `DirectiveDef`
53109 * `LView[getCurrentDirectiveIndex()]` is directive instance.
53110 */
53111
53112
53113function getCurrentDirectiveIndex() {
53114  return instructionState.lFrame.currentDirectiveIndex;
53115}
53116/**
53117 * Sets an index of a directive whose `hostBindings` are being processed.
53118 *
53119 * @param currentDirectiveIndex `TData` index where current directive instance can be found.
53120 */
53121
53122
53123function setCurrentDirectiveIndex(currentDirectiveIndex) {
53124  instructionState.lFrame.currentDirectiveIndex = currentDirectiveIndex;
53125}
53126/**
53127 * Retrieve the current `DirectiveDef` which is active when `hostBindings` instruction is being
53128 * executed.
53129 *
53130 * @param tData Current `TData` where the `DirectiveDef` will be looked up at.
53131 */
53132
53133
53134function getCurrentDirectiveDef(tData) {
53135  const currentDirectiveIndex = instructionState.lFrame.currentDirectiveIndex;
53136  return currentDirectiveIndex === -1 ? null : tData[currentDirectiveIndex];
53137}
53138
53139function getCurrentQueryIndex() {
53140  return instructionState.lFrame.currentQueryIndex;
53141}
53142
53143function setCurrentQueryIndex(value) {
53144  instructionState.lFrame.currentQueryIndex = value;
53145}
53146/**
53147 * Returns a `TNode` of the location where the current `LView` is declared at.
53148 *
53149 * @param lView an `LView` that we want to find parent `TNode` for.
53150 */
53151
53152
53153function getDeclarationTNode(lView) {
53154  const tView = lView[TVIEW]; // Return the declaration parent for embedded views
53155
53156  if (tView.type === 2
53157  /* TViewType.Embedded */
53158  ) {
53159    ngDevMode && assertDefined(tView.declTNode, 'Embedded TNodes should have declaration parents.');
53160    return tView.declTNode;
53161  } // Components don't have `TView.declTNode` because each instance of component could be
53162  // inserted in different location, hence `TView.declTNode` is meaningless.
53163  // Falling back to `T_HOST` in case we cross component boundary.
53164
53165
53166  if (tView.type === 1
53167  /* TViewType.Component */
53168  ) {
53169    return lView[T_HOST];
53170  } // Remaining TNode type is `TViewType.Root` which doesn't have a parent TNode.
53171
53172
53173  return null;
53174}
53175/**
53176 * This is a light weight version of the `enterView` which is needed by the DI system.
53177 *
53178 * @param lView `LView` location of the DI context.
53179 * @param tNode `TNode` for DI context
53180 * @param flags DI context flags. if `SkipSelf` flag is set than we walk up the declaration
53181 *     tree from `tNode`  until we find parent declared `TElementNode`.
53182 * @returns `true` if we have successfully entered DI associated with `tNode` (or with declared
53183 *     `TNode` if `flags` has  `SkipSelf`). Failing to enter DI implies that no associated
53184 *     `NodeInjector` can be found and we should instead use `ModuleInjector`.
53185 *     - If `true` than this call must be fallowed by `leaveDI`
53186 *     - If `false` than this call failed and we should NOT call `leaveDI`
53187 */
53188
53189
53190function enterDI(lView, tNode, flags) {
53191  ngDevMode && assertLViewOrUndefined(lView);
53192
53193  if (flags & InjectFlags.SkipSelf) {
53194    ngDevMode && assertTNodeForTView(tNode, lView[TVIEW]);
53195    let parentTNode = tNode;
53196    let parentLView = lView;
53197
53198    while (true) {
53199      ngDevMode && assertDefined(parentTNode, 'Parent TNode should be defined');
53200      parentTNode = parentTNode.parent;
53201
53202      if (parentTNode === null && !(flags & InjectFlags.Host)) {
53203        parentTNode = getDeclarationTNode(parentLView);
53204        if (parentTNode === null) break; // In this case, a parent exists and is definitely an element. So it will definitely
53205        // have an existing lView as the declaration view, which is why we can assume it's defined.
53206
53207        ngDevMode && assertDefined(parentLView, 'Parent LView should be defined');
53208        parentLView = parentLView[DECLARATION_VIEW]; // In Ivy there are Comment nodes that correspond to ngIf and NgFor embedded directives
53209        // We want to skip those and look only at Elements and ElementContainers to ensure
53210        // we're looking at true parent nodes, and not content or other types.
53211
53212        if (parentTNode.type & (2
53213        /* TNodeType.Element */
53214        | 8
53215        /* TNodeType.ElementContainer */
53216        )) {
53217          break;
53218        }
53219      } else {
53220        break;
53221      }
53222    }
53223
53224    if (parentTNode === null) {
53225      // If we failed to find a parent TNode this means that we should use module injector.
53226      return false;
53227    } else {
53228      tNode = parentTNode;
53229      lView = parentLView;
53230    }
53231  }
53232
53233  ngDevMode && assertTNodeForLView(tNode, lView);
53234  const lFrame = instructionState.lFrame = allocLFrame();
53235  lFrame.currentTNode = tNode;
53236  lFrame.lView = lView;
53237  return true;
53238}
53239/**
53240 * Swap the current lView with a new lView.
53241 *
53242 * For performance reasons we store the lView in the top level of the module.
53243 * This way we minimize the number of properties to read. Whenever a new view
53244 * is entered we have to store the lView for later, and when the view is
53245 * exited the state has to be restored
53246 *
53247 * @param newView New lView to become active
53248 * @returns the previously active lView;
53249 */
53250
53251
53252function enterView(newView) {
53253  ngDevMode && assertNotEqual(newView[0], newView[1], '????');
53254  ngDevMode && assertLViewOrUndefined(newView);
53255  const newLFrame = allocLFrame();
53256
53257  if (ngDevMode) {
53258    assertEqual(newLFrame.isParent, true, 'Expected clean LFrame');
53259    assertEqual(newLFrame.lView, null, 'Expected clean LFrame');
53260    assertEqual(newLFrame.tView, null, 'Expected clean LFrame');
53261    assertEqual(newLFrame.selectedIndex, -1, 'Expected clean LFrame');
53262    assertEqual(newLFrame.elementDepthCount, 0, 'Expected clean LFrame');
53263    assertEqual(newLFrame.currentDirectiveIndex, -1, 'Expected clean LFrame');
53264    assertEqual(newLFrame.currentNamespace, null, 'Expected clean LFrame');
53265    assertEqual(newLFrame.bindingRootIndex, -1, 'Expected clean LFrame');
53266    assertEqual(newLFrame.currentQueryIndex, 0, 'Expected clean LFrame');
53267  }
53268
53269  const tView = newView[TVIEW];
53270  instructionState.lFrame = newLFrame;
53271  ngDevMode && tView.firstChild && assertTNodeForTView(tView.firstChild, tView);
53272  newLFrame.currentTNode = tView.firstChild;
53273  newLFrame.lView = newView;
53274  newLFrame.tView = tView;
53275  newLFrame.contextLView = newView;
53276  newLFrame.bindingIndex = tView.bindingStartIndex;
53277  newLFrame.inI18n = false;
vendor: 5,526 bytes, lines 53278-53471
53278}
53279/**
53280 * Allocates next free LFrame. This function tries to reuse the `LFrame`s to lower memory pressure.
53281 */
53282
53283
53284function allocLFrame() {
53285  const currentLFrame = instructionState.lFrame;
53286  const childLFrame = currentLFrame === null ? null : currentLFrame.child;
53287  const newLFrame = childLFrame === null ? createLFrame(currentLFrame) : childLFrame;
53288  return newLFrame;
53289}
53290
53291function createLFrame(parent) {
53292  const lFrame = {
53293    currentTNode: null,
53294    isParent: true,
53295    lView: null,
53296    tView: null,
53297    selectedIndex: -1,
53298    contextLView: null,
53299    elementDepthCount: 0,
53300    currentNamespace: null,
53301    currentDirectiveIndex: -1,
53302    bindingRootIndex: -1,
53303    bindingIndex: -1,
53304    currentQueryIndex: 0,
53305    parent: parent,
53306    child: null,
53307    inI18n: false
53308  };
53309  parent !== null && (parent.child = lFrame); // link the new LFrame for reuse.
53310
53311  return lFrame;
53312}
53313/**
53314 * A lightweight version of leave which is used with DI.
53315 *
53316 * This function only resets `currentTNode` and `LView` as those are the only properties
53317 * used with DI (`enterDI()`).
53318 *
53319 * NOTE: This function is reexported as `leaveDI`. However `leaveDI` has return type of `void` where
53320 * as `leaveViewLight` has `LFrame`. This is so that `leaveViewLight` can be used in `leaveView`.
53321 */
53322
53323
53324function leaveViewLight() {
53325  const oldLFrame = instructionState.lFrame;
53326  instructionState.lFrame = oldLFrame.parent;
53327  oldLFrame.currentTNode = null;
53328  oldLFrame.lView = null;
53329  return oldLFrame;
53330}
53331/**
53332 * This is a lightweight version of the `leaveView` which is needed by the DI system.
53333 *
53334 * NOTE: this function is an alias so that we can change the type of the function to have `void`
53335 * return type.
53336 */
53337
53338
53339const leaveDI = leaveViewLight;
53340/**
53341 * Leave the current `LView`
53342 *
53343 * This pops the `LFrame` with the associated `LView` from the stack.
53344 *
53345 * IMPORTANT: We must zero out the `LFrame` values here otherwise they will be retained. This is
53346 * because for performance reasons we don't release `LFrame` but rather keep it for next use.
53347 */
53348
53349function leaveView() {
53350  const oldLFrame = leaveViewLight();
53351  oldLFrame.isParent = true;
53352  oldLFrame.tView = null;
53353  oldLFrame.selectedIndex = -1;
53354  oldLFrame.contextLView = null;
53355  oldLFrame.elementDepthCount = 0;
53356  oldLFrame.currentDirectiveIndex = -1;
53357  oldLFrame.currentNamespace = null;
53358  oldLFrame.bindingRootIndex = -1;
53359  oldLFrame.bindingIndex = -1;
53360  oldLFrame.currentQueryIndex = 0;
53361}
53362
53363function nextContextImpl(level) {
53364  const contextLView = instructionState.lFrame.contextLView = walkUpViews(level, instructionState.lFrame.contextLView);
53365  return contextLView[CONTEXT];
53366}
53367
53368function walkUpViews(nestingLevel, currentView) {
53369  while (nestingLevel > 0) {
53370    ngDevMode && assertDefined(currentView[DECLARATION_VIEW], 'Declaration view should be defined if nesting level is greater than 0.');
53371    currentView = currentView[DECLARATION_VIEW];
53372    nestingLevel--;
53373  }
53374
53375  return currentView;
53376}
53377/**
53378 * Gets the currently selected element index.
53379 *
53380 * Used with {@link property} instruction (and more in the future) to identify the index in the
53381 * current `LView` to act on.
53382 */
53383
53384
53385function getSelectedIndex() {
53386  return instructionState.lFrame.selectedIndex;
53387}
53388/**
53389 * Sets the most recent index passed to {@link select}
53390 *
53391 * Used with {@link property} instruction (and more in the future) to identify the index in the
53392 * current `LView` to act on.
53393 *
53394 * (Note that if an "exit function" was set earlier (via `setElementExitFn()`) then that will be
53395 * run if and when the provided `index` value is different from the current selected index value.)
53396 */
53397
53398
53399function setSelectedIndex(index) {
53400  ngDevMode && index !== -1 && assertGreaterThanOrEqual(index, HEADER_OFFSET, 'Index must be past HEADER_OFFSET (or -1).');
53401  ngDevMode && assertLessThan(index, instructionState.lFrame.lView.length, 'Can\'t set index passed end of LView');
53402  instructionState.lFrame.selectedIndex = index;
53403}
53404/**
53405 * Gets the `tNode` that represents currently selected element.
53406 */
53407
53408
53409function getSelectedTNode() {
53410  const lFrame = instructionState.lFrame;
53411  return getTNode(lFrame.tView, lFrame.selectedIndex);
53412}
53413/**
53414 * Sets the namespace used to create elements to `'http://www.w3.org/2000/svg'` in global state.
53415 *
53416 * @codeGenApi
53417 */
53418
53419
53420function ɵɵnamespaceSVG() {
53421  instructionState.lFrame.currentNamespace = SVG_NAMESPACE;
53422}
53423/**
53424 * Sets the namespace used to create elements to `'http://www.w3.org/1998/MathML/'` in global state.
53425 *
53426 * @codeGenApi
53427 */
53428
53429
53430function ɵɵnamespaceMathML() {
53431  instructionState.lFrame.currentNamespace = MATH_ML_NAMESPACE;
53432}
53433/**
53434 * Sets the namespace used to create elements to `null`, which forces element creation to use
53435 * `createElement` rather than `createElementNS`.
53436 *
53437 * @codeGenApi
53438 */
53439
53440
53441function ɵɵnamespaceHTML() {
53442  namespaceHTMLInternal();
53443}
53444/**
53445 * Sets the namespace used to create elements to `null`, which forces element creation to use
53446 * `createElement` rather than `createElementNS`.
53447 */
53448
53449
53450function namespaceHTMLInternal() {
53451  instructionState.lFrame.currentNamespace = null;
53452}
53453
53454function getNamespace$1() {
53455  return instructionState.lFrame.currentNamespace;
53456}
53457/**
53458 * @license
53459 * Copyright Google LLC All Rights Reserved.
53460 *
53461 * Use of this source code is governed by an MIT-style license that can be
53462 * found in the LICENSE file at https://angular.io/license
53463 */
53464
53465/**
53466 * Adds all directive lifecycle hooks from the given `DirectiveDef` to the given `TView`.
53467 *
53468 * Must be run *only* on the first template pass.
53469 *
53470 * Sets up the pre-order hooks on the provided `tView`,
53471 * see {@link HookData}
53471 for details about the data structure.
53472 *
53473 * @param directiveIndex The index of the directive in LView
53474 * @param directiveDef The definition containing the hooks to setup in tView
53475 * @param tView The current TView
53476 */
53477
53478
53479function registerPreOrderHooks(directiveIndex, directiveDef, tView) {
53480  ngDevMode && assertFirstCreatePass(tView);
53481  const {
53482    ngOnChanges,
53483    ngOnInit,
53484    ngDoCheck
53485  } = directiveDef.type.prototype;
53486
53487  if (ngOnChanges) {
53488    const wrappedOnChanges = NgOnChangesFeatureImpl(directiveDef);
53489    (tView.preOrderHooks || (tView.preOrderHooks = [])).push(directiveIndex, wrappedOnChanges);
53490    (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(directiveIndex, wrappedOnChanges);
53491  }
53492
53493  if (ngOnInit) {
53494    (tView.preOrderHooks || (tView.preOrderHooks = [])).push(0 - directiveIndex, ngOnInit);
53495  }
53496
53497  if (ngDoCheck) {
53498    (tView.preOrderHooks || (tView.preOrderHooks = [])).push(directiveIndex, ngDoCheck);
53499    (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(directiveIndex, ngDoCheck);
53500  }
53501}
53502/**
53503 *
53504 * Loops through the directives on the provided `tNode` and queues hooks to be
53505 * run that are not initialization hooks.
53506 *
53507 * Should be executed during `elementEnd()` and similar to
53508 * preserve hook execution order. Content, view, and destroy hooks for projected
53509 * components and directives must be called *before* their hosts.
53510 *
53511 * Sets up the content, view, and destroy hooks on the provided `tView`,
53512 * see {@link HookData} for details about the data structure.
53513 *
53514 * NOTE: This does not set up `onChanges`, `onInit` or `doCheck`, those are set up
53515 * separately at `elementStart`.
53516 *
53517 * @param tView The current TView
53518 * @param tNode The TNode whose directives are to be searched for hooks to queue
53519 */
53520
53521
53522function registerPostOrderHooks(tView, tNode) {
53523  ngDevMode && assertFirstCreatePass(tView); // It's necessary to loop through the directives at elementEnd() (rather than processing in
53524  // directiveCreate) so we can preserve the current hook order. Content, view, and destroy
53525  // hooks for projected components and directives must be called *before* their hosts.
53526
53527  for (let i = tNode.directiveStart, end = tNode.directiveEnd; i < end; i++) {
53528    const directiveDef = tView.data[i];
53529    ngDevMode && assertDefined(directiveDef, 'Expecting DirectiveDef');
53530    const lifecycleHooks = directiveDef.type.prototype;
53531    const {
53532      ngAfterContentInit,
53533      ngAfterContentChecked,
53534      ngAfterViewInit,
53535      ngAfterViewChecked,
53536      ngOnDestroy
53537    } = lifecycleHooks;
53538
53539    if (ngAfterContentInit) {
53540      (tView.contentHooks || (tView.contentHooks = [])).push(-i, ngAfterContentInit);
53541    }
53542
53543    if (ngAfterContentChecked) {
53544      (tView.contentHooks || (tView.contentHooks = [])).push(i, ngAfterContentChecked);
53545      (tView.contentCheckHooks || (tView.contentCheckHooks = [])).push(i, ngAfterContentChecked);
53546    }
53547
53548    if (ngAfterViewInit) {
53549      (tView.viewHooks || (tView.viewHooks = [])).push(-i, ngAfterViewInit);
53550    }
53551
53552    if (ngAfterViewChecked) {
53553      (tView.viewHooks || (tView.viewHooks = [])).push(i, ngAfterViewChecked);
53554      (tView.viewCheckHooks || (tView.viewCheckHooks = [])).push(i, ngAfterViewChecked);
53555    }
53556
53557    if (ngOnDestroy != null) {
53558      (tView.destroyHooks || (tView.destroyHooks = [])).push(i, ngOnDestroy);
53559    }
53560  }
53561}
53562/**
53563 * Executing hooks requires complex logic as we need to deal with 2 constraints.
53564 *
53565 * 1. Init hooks (ngOnInit, ngAfterContentInit, ngAfterViewInit) must all be executed once and only
53566 * once, across many change detection cycles. This must be true even if some hooks throw, or if
53567 * some recursively trigger a change detection cycle.
53568 * To solve that, it is required to track the state of the execution of these init hooks.
53569 * This is done by storing and maintaining flags in the view: the {@link InitPhaseState},
53570 * and the index within that phase. They can be seen as a cursor in the following structure:
53571 * [[onInit1, onInit2], [afterContentInit1], [afterViewInit1, afterViewInit2, afterViewInit3]]
53572 * They are are stored as flags in LView[FLAGS].
53573 *
53574 * 2. Pre-order hooks can be executed in batches, because of the select instruction.
53575 * To be able to pause and resume their execution, we also need some state about the hook's array
53576 * that is being processed:
53577 * - the index of the next hook to be executed
53578 * - the number of init hooks already found in the processed part of the  array
53579 * They are are stored as flags in LView[PREORDER_HOOK_FLAGS].
53580 */
53581
53582/**
53583 * Executes pre-order check hooks ( OnChanges, DoChanges) given a view where all the init hooks were
53584 * executed once. This is a light version of executeInitAndCheckPreOrderHooks where we can skip read
53585 * / write of the init-hooks related flags.
53586 * @param lView The LView where hooks are defined
53587 * @param hooks Hooks to be run
53588 * @param nodeIndex 3 cases depending on the value:
53589 * - undefined: all hooks from the array should be executed (post-order case)
53590 * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
53591 * flushing the remaining hooks)
53592 * - number: execute hooks only from the saved index until that node index exclusive (pre-order
53593 * case, when executing select(number))
53594 */
53595
53596
53597function executeCheckHooks(lView, hooks, nodeIndex) {
53598  callHooks(lView, hooks, 3
53599  /* InitPhaseState.InitPhaseCompleted */
53600  , nodeIndex);
53601}
53602/**
53603 * Executes post-order init and check hooks (one of AfterContentInit, AfterContentChecked,
53604 * AfterViewInit, AfterViewChecked) given a view where there are pending init hooks to be executed.
53605 * @param lView The LView where hooks are defined
53606 * @param hooks Hooks to be run
53607 * @param initPhase A phase for which hooks should be run
53608 * @param nodeIndex 3 cases depending on the value:
53609 * - undefined: all hooks from the array should be executed (post-order case)
53610 * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
53611 * flushing the remaining hooks)
53612 * - number: execute hooks only from the saved index until that node index exclusive (pre-order
53613 * case, when executing select(number))
53614 */
53615
53616
53617function executeInitAndCheckHooks(lView, hooks, initPhase, nodeIndex) {
53618  ngDevMode && assertNotEqual(initPhase, 3
53619  /* InitPhaseState.InitPhaseCompleted */
53620  , 'Init pre-order hooks should not be called more than once');
53621
53622  if ((lView[FLAGS] & 3
53623  /* LViewFlags.InitPhaseStateMask */
53624  ) === initPhase) {
53625    callHooks(lView, hooks, initPhase, nodeIndex);
53626  }
53627}
53628
53629function incrementInitPhaseFlags(lView, initPhase) {
53630  ngDevMode && assertNotEqual(initPhase, 3
53631  /* InitPhaseState.InitPhaseCompleted */
53632  , 'Init hooks phase should not be incremented after all init hooks have been run.');
53633  let flags = lView[FLAGS];
53634
53635  if ((flags & 3
53636  /* LViewFlags.InitPhaseStateMask */
53637  ) === initPhase) {
53638    flags &= 2047
53639    /* LViewFlags.IndexWithinInitPhaseReset */
53640    ;
53641    flags += 1
53642    /* LViewFlags.InitPhaseStateIncrementer */
53643    ;
53644    lView[FLAGS] = flags;
53645  }
53646}
53647/**
53648 * Calls lifecycle hooks with their contexts, skipping init hooks if it's not
53649 * the first LView pass
53650 *
53651 * @param currentView The current view
53652 * @param arr The array in which the hooks are found
53653 * @param initPhaseState the current state of the init phase
53654 * @param currentNodeIndex 3 cases depending on the value:
53655 * - undefined: all hooks from the array should be executed (post-order case)
53656 * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
53657 * flushing the remaining hooks)
53658 * - number: execute hooks only from the saved index until that node index exclusive (pre-order
53659 * case, when executing select(number))
53660 */
53661
53662
53663function callHooks(currentView, arr, initPhase, currentNodeIndex) {
53664  ngDevMode && assertEqual(isInCheckNoChangesMode(), false, 'Hooks should never be run when in check no changes mode.');
53665  const startIndex = currentNodeIndex !== undefined ? currentView[PREORDER_HOOK_FLAGS] & 65535
53666  /* PreOrderHookFlags.IndexOfTheNextPreOrderHookMaskMask */
53667  : 0;
53668  const nodeIndexLimit = currentNodeIndex != null ? currentNodeIndex : -1;
53669  const max = arr.length - 1; // Stop the loop at length - 1, because we look for the hook at i + 1
53670
53671  let lastNodeIndexFound = 0;
53672
53673  for (let i = startIndex; i < max; i++) {
53674    const hook = arr[i + 1];
53675
53676    if (typeof hook === 'number') {
53677      lastNodeIndexFound = arr[i];
53678
53679      if (currentNodeIndex != null && lastNodeIndexFound >= currentNodeIndex) {
53680        break;
53681      }
53682    } else {
53683      const isInitHook = arr[i] < 0;
53684      if (isInitHook) currentView[PREORDER_HOOK_FLAGS] += 65536
53685      /* PreOrderHookFlags.NumberOfInitHooksCalledIncrementer */
53686      ;
53687
53688      if (lastNodeIndexFound < nodeIndexLimit || nodeIndexLimit == -1) {
53689        callHook(currentView, initPhase, arr, i);
53690        currentView[PREORDER_HOOK_FLAGS] = (currentView[PREORDER_HOOK_FLAGS] & 4294901760
53691        /* PreOrderHookFlags.NumberOfInitHooksCalledMask */
53692        ) + i + 2;
53693      }
53694
53695      i++;
53696    }
53697  }
53698}
53699/**
53700 * Execute one hook against the current `LView`.
53701 *
53702 * @param currentView The current view
53703 * @param initPhaseState the current state of the init phase
53704 * @param arr The array in which the hooks are found
53705 * @param i The current index within the hook data array
53706 */
53707
53708
53709function callHook(currentView, initPhase, arr, i) {
53710  const isInitHook = arr[i] < 0;
53711  const hook = arr[i + 1];
53712  const directiveIndex = isInitHook ? -arr[i] : arr[i];
53713  const directive = currentView[directiveIndex];
53714
53715  if (isInitHook) {
53716    const indexWithintInitPhase = currentView[FLAGS] >> 11
53717    /* LViewFlags.IndexWithinInitPhaseShift */
53718    ; // The init phase state must be always checked here as it may have been recursively updated.
53719
53720    if (indexWithintInitPhase < currentView[PREORDER_HOOK_FLAGS] >> 16
53721    /* PreOrderHookFlags.NumberOfInitHooksCalledShift */
53722    && (currentView[FLAGS] & 3
53723    /* LViewFlags.InitPhaseStateMask */
53724    ) === initPhase) {
53725      currentView[FLAGS] += 2048
53726      /* LViewFlags.IndexWithinInitPhaseIncrementer */
53727      ;
53728      profiler(4
53729      /* ProfilerEvent.LifecycleHookStart */
53730      , directive, hook);
53731
53732      try {
53733        hook.call(directive);
53734      } finally {
53735        profiler(5
53736        /* ProfilerEvent.LifecycleHookEnd */
53737        , directive, hook);
53738      }
53739    }
53740  } else {
53741    profiler(4
53742    /* ProfilerEvent.LifecycleHookStart */
53743    , directive, hook);
53744
53745    try {
53746      hook.call(directive);
53747    } finally {
53748      profiler(5
53749      /* ProfilerEvent.LifecycleHookEnd */
53750      , directive, hook);
53751    }
53752  }
53753}
53754/**
53755 * @license
53756 * Copyright Google LLC All Rights Reserved.
53757 *
53758 * Use of this source code is governed by an MIT-style license that can be
53759 * found in the LICENSE file at https://angular.io/license
53760 */
53761
53762
53763const NO_PARENT_INJECTOR = -1;
53764/**
53765 * Each injector is saved in 9 contiguous slots in `LView` and 9 contiguous slots in
53766 * `TView.data`. This allows us to store information about the current node's tokens (which
53767 * can be shared in `TView`) as well as the tokens of its ancestor nodes (which cannot be
53768 * shared, so they live in `LView`).
53769 *
53770 * Each of these slots (aside from the last slot) contains a bloom filter. This bloom filter
53771 * determines whether a directive is available on the associated node or not. This prevents us
53772 * from searching the directives array at this level unless it's probable the directive is in it.
53773 *
53774 * See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters.
53775 *
53776 * Because all injectors have been flattened into `LView` and `TViewData`, they cannot typed
53777 * using interfaces as they were previously. The start index of each `LInjector` and `TInjector`
53778 * will differ based on where it is flattened into the main array, so it's not possible to know
53779 * the indices ahead of time and save their types here. The interfaces are still included here
53780 * for documentation purposes.
53781 *
53782 * export interface LInjector extends Array<any> {
53783 *
53784 *    // Cumulative bloom for directive IDs 0-31  (IDs are % BLOOM_SIZE)
53785 *    [0]: number;
53786 *
53787 *    // Cumulative bloom for directive IDs 32-63
53788 *    [1]: number;
53789 *
53790 *    // Cumulative bloom for directive IDs 64-95
53791 *    [2]: number;
53792 *
53793 *    // Cumulative bloom for directive IDs 96-127
53794 *    [3]: number;
53795 *
53796 *    // Cumulative bloom for directive IDs 128-159
53797 *    [4]: number;
53798 *
53799 *    // Cumulative bloom for directive IDs 160 - 191
53800 *    [5]: number;
53801 *
53802 *    // Cumulative bloom for directive IDs 192 - 223
53803 *    [6]: number;
53804 *
53805 *    // Cumulative bloom for directive IDs 224 - 255
53806 *    [7]: number;
53807 *
53808 *    // We need to store a reference to the injector's parent so DI can keep looking up
53809 *    // the injector tree until it finds the dependency it's looking for.
53810 *    [PARENT_INJECTOR]: number;
53811 * }
53812 *
53813 * export interface TInjector extends Array<any> {
53814 *
53815 *    // Shared node bloom for directive IDs 0-31  (IDs are % BLOOM_SIZE)
53816 *    [0]: number;
53817 *
53818 *    // Shared node bloom for directive IDs 32-63
53819 *    [1]: number;
53820 *
53821 *    // Shared node bloom for directive IDs 64-95
53822 *    [2]: number;
53823 *
53824 *    // Shared node bloom for directive IDs 96-127
53825 *    [3]: number;
53826 *
53827 *    // Shared node bloom for directive IDs 128-159
53828 *    [4]: number;
53829 *
53830 *    // Shared node bloom for directive IDs 160 - 191
53831 *    [5]: number;
53832 *
53833 *    // Shared node bloom for directive IDs 192 - 223
53834 *    [6]: number;
53835 *
53836 *    // Shared node bloom for directive IDs 224 - 255
53837 *    [7]: number;
53838 *
53839 *    // Necessary to find directive indices for a particular node.
53840 *    [TNODE]: TElementNode|TElementContainerNode|TContainerNode;
53841 *  }
53842 */
53843
53844/**
53845 * Factory for creating instances of injectors in the NodeInjector.
53846 *
53847 * This factory is complicated by the fact that it can resolve `multi` factories as well.
53848 *
53849 * NOTE: Some of the fields are optional which means that this class has two hidden classes.
53850 * - One without `multi` support (most common)
53851 * - One with `multi` values, (rare).
53852 *
53853 * Since VMs can cache up to 4 inline hidden classes this is OK.
53854 *
53855 * - Single factory: Only `resolving` and `factory` is defined.
53856 * - `providers` factory: `componentProviders` is a number and `index = -1`.
53857 * - `viewProviders` factory: `componentProviders` is a number and `index` points to `providers`.
53858 */
53859
53860class NodeInjectorFactory {
53861  constructor(
53862  /**
53863   * Factory to invoke in order to create a new instance.
53864   */
53865  factory,
53866  /**
53867   * Set to `true` if the token is declared in `viewProviders` (or if it is component).
53868   */
53869  isViewProvider, injectImplementation) {
53870    this.factory = factory;
53871    /**
53872     * Marker set to true during factory invocation to see if we get into recursive loop.
53873     * Recursive loop causes an error to be displayed.
53874     */
53875
53876    this.resolving = false;
53877    ngDevMode && assertDefined(factory, 'Factory not specified');
53878    ngDevMode && assertEqual(typeof factory, 'function', 'Expected factory function.');
53879    this.canSeeViewProviders = isViewProvider;
53880    this.injectImpl = injectImplementation;
53881  }
53882
53883}
53884
53885function isFactory(obj) {
53886  return obj instanceof NodeInjectorFactory;
53887} // Note: This hack is necessary so we don't erroneously get a circular dependency
53888// failure based on types.
53889
53890
53891const unusedValueExportToPlacateAjd$6 = 1;
53892/**
53893 * Converts `TNodeType` into human readable text.
53894 * Make sure this matches with `TNodeType`
53895 */
53896
53897function toTNodeTypeAsString(tNodeType) {
53898  let text = '';
53899  tNodeType & 1
53900  /* TNodeType.Text */
53901  && (text += '|Text');
53902  tNodeType & 2
53903  /* TNodeType.Element */
53904  && (text += '|Element');
53905  tNodeType & 4
53906  /* TNodeType.Container */
53907  && (text += '|Container');
53908  tNodeType & 8
53909  /* TNodeType.ElementContainer */
53910  && (text += '|ElementContainer');
53911  tNodeType & 16
53912  /* TNodeType.Projection */
53913  && (text += '|Projection');
53914  tNodeType & 32
53915  /* TNodeType.Icu */
53916  && (text += '|IcuContainer');
53917  tNodeType & 64
53918  /* TNodeType.Placeholder */
53919  && (text += '|Placeholder');
53920  return text.length > 0 ? text.substring(1) : text;
53921} // Note: This hack is necessary so we don't erroneously get a circular dependency
53922// failure based on types.
53923
53924
53925const unusedValueExportToPlacateAjd$5 = 1;
53926/**
53927 * Returns `true` if the `TNode` has a directive which has `@Input()` for `class` binding.
53928 *
53929 * ```
53930 * <div my-dir [class]="exp"></div>
53931 * ```
53932 * and
53933 * ```
53934 * @Directive({
53935 * })
53936 * class MyDirective {
53937 *   @Input()
53938 *   class: string;
53939 * }
53940 * ```
53941 *
53942 * In the above case it is necessary to write the reconciled styling information into the
53943 * directive's input.
53944 *
53945 * @param tNode
53946 */
53947
53948function hasClassInput(tNode) {
53949  return (tNode.flags & 16
53950  /* TNodeFlags.hasClassInput */
53951  ) !== 0;
53952}
53953/**
53954 * Returns `true` if the `TNode` has a directive which has `@Input()` for `style` binding.
53955 *
53956 * ```
53957 * <div my-dir [style]="exp"></div>
53958 * ```
53959 * and
53960 * ```
53961 * @Directive({
53962 * })
53963 * class MyDirective {
53964 *   @Input()
53965 *   class: string;
53966 * }
53967 * ```
53968 *
53969 * In the above case it is necessary to write the reconciled styling information into the
53970 * directive's input.
53971 *
53972 * @param tNode
53973 */
53974
53975
53976function hasStyleInput(tNode) {
53977  return (tNode.flags & 32
53978  /* TNodeFlags.hasStyleInput */
53979  ) !== 0;
53980}
53981/**
53982 * @license
53983 * Copyright Google LLC All Rights Reserved.
53984 *
53985 * Use of this source code is governed by an MIT-style license that can be
53986 * found in the LICENSE file at https://angular.io/license
53987 */
53988
53989
53990function assertTNodeType(tNode, expectedTypes, message) {
53991  assertDefined(tNode, 'should be called with a TNode');
53992
53993  if ((tNode.type & expectedTypes) === 0) {
53994    throwError(message || `Expected [${toTNodeTypeAsString(expectedTypes)}] but got ${toTNodeTypeAsString(tNode.type)}.`);
53995  }
53996}
53997
53998function assertPureTNodeType(type) {
53999  if (!(type === 2
54000  /* TNodeType.Element */
54001  || //
54002  type === 1
54003  /* TNodeType.Text */
54004  || //
54005  type === 4
54006  /* TNodeType.Container */
54007  || //
54008  type === 8
54009  /* TNodeType.ElementContainer */
54010  || //
54011  type === 32
54012  /* TNodeType.Icu */
54013  || //
54014  type === 16
54015  /* TNodeType.Projection */
54016  || //
54017  type === 64
54018  /* TNodeType.Placeholder */
54019  )) {
54020    throwError(`Expected TNodeType to have only a single type selected, but got ${toTNodeTypeAsString(type)}.`);
54021  }
54022}
54023/**
54024 * Assigns all attribute values to the provided element via the inferred renderer.
54025 *
54026 * This function accepts two forms of attribute entries:
54027 *
54028 * default: (key, value):
54029 *  attrs = [key1, value1, key2, value2]
54030 *
54031 * namespaced: (NAMESPACE_MARKER, uri, name, value)
54032 *  attrs = [NAMESPACE_MARKER, uri, name, value, NAMESPACE_MARKER, uri, name, value]
54033 *
54034 * The `attrs` array can contain a mix of both the default and namespaced entries.
54035 * The "default" values are set without a marker, but if the function comes across
54036 * a marker value then it will attempt to set a namespaced value. If the marker is
54037 * not of a namespaced value then the function will quit and return the index value
54038 * where it stopped during the iteration of the attrs array.
54039 *
54040 * See [AttributeMarker] to understand what the namespace marker value is.
54041 *
vendor: 46,980 bytes, lines 54042-55360
54042 * Note that this instruction does not support assigning style and class values to
54043 * an element. See `elementStart` and `elementHostAttrs` to learn how styling values
54044 * are applied to an element.
54045 * @param renderer The renderer to be used
54046 * @param native The element that the attributes will be assigned to
54047 * @param attrs The attribute array of values that will be assigned to the element
54048 * @returns the index value that was last accessed in the attributes array
54049 */
54050
54051
54052function setUpAttributes(renderer, native, attrs) {
54053  let i = 0;
54054
54055  while (i < attrs.length) {
54056    const value = attrs[i];
54057
54058    if (typeof value === 'number') {
54059      // only namespaces are supported. Other value types (such as style/class
54060      // entries) are not supported in this function.
54061      if (value !== 0
54062      /* AttributeMarker.NamespaceURI */
54063      ) {
54064        break;
54065      } // we just landed on the marker value ... therefore
54066      // we should skip to the next entry
54067
54068
54069      i++;
54070      const namespaceURI = attrs[i++];
54071      const attrName = attrs[i++];
54072      const attrVal = attrs[i++];
54073      ngDevMode && ngDevMode.rendererSetAttribute++;
54074      renderer.setAttribute(native, attrName, attrVal, namespaceURI);
54075    } else {
54076      // attrName is string;
54077      const attrName = value;
54078      const attrVal = attrs[++i]; // Standard attributes
54079
54080      ngDevMode && ngDevMode.rendererSetAttribute++;
54081
54082      if (isAnimationProp(attrName)) {
54083        renderer.setProperty(native, attrName, attrVal);
54084      } else {
54085        renderer.setAttribute(native, attrName, attrVal);
54086      }
54087
54088      i++;
54089    }
54090  } // another piece of code may iterate over the same attributes array. Therefore
54091  // it may be helpful to return the exact spot where the attributes array exited
54092  // whether by running into an unsupported marker or if all the static values were
54093  // iterated over.
54094
54095
54096  return i;
54097}
54098/**
54099 * Test whether the given value is a marker that indicates that the following
54100 * attribute values in a `TAttributes` array are only the names of attributes,
54101 * and not name-value pairs.
54102 * @param marker The attribute marker to test.
54103 * @returns true if the marker is a "name-only" marker (e.g. `Bindings`, `Template` or `I18n`).
54104 */
54105
54106
54107function isNameOnlyAttributeMarker(marker) {
54108  return marker === 3
54109  /* AttributeMarker.Bindings */
54110  || marker === 4
54111  /* AttributeMarker.Template */
54112  || marker === 6
54113  /* AttributeMarker.I18n */
54114  ;
54115}
54116
54117function isAnimationProp(name) {
54118  // Perf note: accessing charCodeAt to check for the first character of a string is faster as
54119  // compared to accessing a character at index 0 (ex. name[0]). The main reason for this is that
54120  // charCodeAt doesn't allocate memory to return a substring.
54121  return name.charCodeAt(0) === 64
54122  /* CharCode.AT_SIGN */
54123  ;
54124}
54125/**
54126 * Merges `src` `TAttributes` into `dst` `TAttributes` removing any duplicates in the process.
54127 *
54128 * This merge function keeps the order of attrs same.
54129 *
54130 * @param dst Location of where the merged `TAttributes` should end up.
54131 * @param src `TAttributes` which should be appended to `dst`
54132 */
54133
54134
54135function mergeHostAttrs(dst, src) {
54136  if (src === null || src.length === 0) {// do nothing
54137  } else if (dst === null || dst.length === 0) {
54138    // We have source, but dst is empty, just make a copy.
54139    dst = src.slice();
54140  } else {
54141    let srcMarker = -1
54142    /* AttributeMarker.ImplicitAttributes */
54143    ;
54144
54145    for (let i = 0; i < src.length; i++) {
54146      const item = src[i];
54147
54148      if (typeof item === 'number') {
54149        srcMarker = item;
54150      } else {
54151        if (srcMarker === 0
54152        /* AttributeMarker.NamespaceURI */
54153        ) {// Case where we need to consume `key1`, `key2`, `value` items.
54154        } else if (srcMarker === -1
54155        /* AttributeMarker.ImplicitAttributes */
54156        || srcMarker === 2
54157        /* AttributeMarker.Styles */
54158        ) {
54159          // Case where we have to consume `key1` and `value` only.
54160          mergeHostAttribute(dst, srcMarker, item, null, src[++i]);
54161        } else {
54162          // Case where we have to consume `key1` only.
54163          mergeHostAttribute(dst, srcMarker, item, null, null);
54164        }
54165      }
54166    }
54167  }
54168
54169  return dst;
54170}
54171/**
54172 * Append `key`/`value` to existing `TAttributes` taking region marker and duplicates into account.
54173 *
54174 * @param dst `TAttributes` to append to.
54175 * @param marker Region where the `key`/`value` should be added.
54176 * @param key1 Key to add to `TAttributes`
54177 * @param key2 Key to add to `TAttributes` (in case of `AttributeMarker.NamespaceURI`)
54178 * @param value Value to add or to overwrite to `TAttributes` Only used if `marker` is not Class.
54179 */
54180
54181
54182function mergeHostAttribute(dst, marker, key1, key2, value) {
54183  let i = 0; // Assume that new markers will be inserted at the end.
54184
54185  let markerInsertPosition = dst.length; // scan until correct type.
54186
54187  if (marker === -1
54188  /* AttributeMarker.ImplicitAttributes */
54189  ) {
54190    markerInsertPosition = -1;
54191  } else {
54192    while (i < dst.length) {
54193      const dstValue = dst[i++];
54194
54195      if (typeof dstValue === 'number') {
54196        if (dstValue === marker) {
54197          markerInsertPosition = -1;
54198          break;
54199        } else if (dstValue > marker) {
54200          // We need to save this as we want the markers to be inserted in specific order.
54201          markerInsertPosition = i - 1;
54202          break;
54203        }
54204      }
54205    }
54206  } // search until you find place of insertion
54207
54208
54209  while (i < dst.length) {
54210    const item = dst[i];
54211
54212    if (typeof item === 'number') {
54213      // since `i` started as the index after the marker, we did not find it if we are at the next
54214      // marker
54215      break;
54216    } else if (item === key1) {
54217      // We already have same token
54218      if (key2 === null) {
54219        if (value !== null) {
54220          dst[i + 1] = value;
54221        }
54222
54223        return;
54224      } else if (key2 === dst[i + 1]) {
54225        dst[i + 2] = value;
54226        return;
54227      }
54228    } // Increment counter.
54229
54230
54231    i++;
54232    if (key2 !== null) i++;
54233    if (value !== null) i++;
54234  } // insert at location.
54235
54236
54237  if (markerInsertPosition !== -1) {
54238    dst.splice(markerInsertPosition, 0, marker);
54239    i = markerInsertPosition + 1;
54240  }
54241
54242  dst.splice(i++, 0, key1);
54243
54244  if (key2 !== null) {
54245    dst.splice(i++, 0, key2);
54246  }
54247
54248  if (value !== null) {
54249    dst.splice(i++, 0, value);
54250  }
54251}
54252/**
54253 * @license
54254 * Copyright Google LLC All Rights Reserved.
54255 *
54256 * Use of this source code is governed by an MIT-style license that can be
54257 * found in the LICENSE file at https://angular.io/license
54258 */
54259/// Parent Injector Utils ///////////////////////////////////////////////////////////////
54260
54261
54262function hasParentInjector(parentLocation) {
54263  return parentLocation !== NO_PARENT_INJECTOR;
54264}
54265
54266function getParentInjectorIndex(parentLocation) {
54267  ngDevMode && assertNumber(parentLocation, 'Number expected');
54268  ngDevMode && assertNotEqual(parentLocation, -1, 'Not a valid state.');
54269  const parentInjectorIndex = parentLocation & 32767
54270  /* RelativeInjectorLocationFlags.InjectorIndexMask */
54271  ;
54272  ngDevMode && assertGreaterThan(parentInjectorIndex, HEADER_OFFSET, 'Parent injector must be pointing past HEADER_OFFSET.');
54273  return parentLocation & 32767
54274  /* RelativeInjectorLocationFlags.InjectorIndexMask */
54275  ;
54276}
54277
54278function getParentInjectorViewOffset(parentLocation) {
54279  return parentLocation >> 16
54280  /* RelativeInjectorLocationFlags.ViewOffsetShift */
54281  ;
54282}
54283/**
54284 * Unwraps a parent injector location number to find the view offset from the current injector,
54285 * then walks up the declaration view tree until the view is found that contains the parent
54286 * injector.
54287 *
54288 * @param location The location of the parent injector, which contains the view offset
54289 * @param startView The LView instance from which to start walking up the view tree
54290 * @returns The LView instance that contains the parent injector
54291 */
54292
54293
54294function getParentInjectorView(location, startView) {
54295  let viewOffset = getParentInjectorViewOffset(location);
54296  let parentView = startView; // For most cases, the parent injector can be found on the host node (e.g. for component
54297  // or container), but we must keep the loop here to support the rarer case of deeply nested
54298  // <ng-template> tags or inline views, where the parent injector might live many views
54299  // above the child injector.
54300
54301  while (viewOffset > 0) {
54302    parentView = parentView[DECLARATION_VIEW];
54303    viewOffset--;
54304  }
54305
54306  return parentView;
54307}
54308/**
54309 * @license
54310 * Copyright Google LLC All Rights Reserved.
54311 *
54312 * Use of this source code is governed by an MIT-style license that can be
54313 * found in the LICENSE file at https://angular.io/license
54314 */
54315
54316/**
54317 * Defines if the call to `inject` should include `viewProviders` in its resolution.
54318 *
54319 * This is set to true when we try to instantiate a component. This value is reset in
54320 * `getNodeInjectable` to a value which matches the declaration location of the token about to be
54321 * instantiated. This is done so that if we are injecting a token which was declared outside of
54322 * `viewProviders` we don't accidentally pull `viewProviders` in.
54323 *
54324 * Example:
54325 *
54326 * ```
54327 * @Injectable()
54328 * class MyService {
54329 *   constructor(public value: String) {}
54330 * }
54331 *
54332 * @Component({
54333 *   providers: [
54334 *     MyService,
54335 *     {provide: String, value: 'providers' }
54336 *   ]
54337 *   viewProviders: [
54338 *     {provide: String, value: 'viewProviders'}
54339 *   ]
54340 * })
54341 * class MyComponent {
54342 *   constructor(myService: MyService, value: String) {
54343 *     // We expect that Component can see into `viewProviders`.
54344 *     expect(value).toEqual('viewProviders');
54345 *     // `MyService` was not declared in `viewProviders` hence it can't see it.
54346 *     expect(myService.value).toEqual('providers');
54347 *   }
54348 * }
54349 *
54350 * ```
54351 */
54352
54353
54354let includeViewProviders = true;
54355
54356function setIncludeViewProviders(v) {
54357  const oldValue = includeViewProviders;
54358  includeViewProviders = v;
54359  return oldValue;
54360}
54361/**
54362 * The number of slots in each bloom filter (used by DI). The larger this number, the fewer
54363 * directives that will share slots, and thus, the fewer false positives when checking for
54364 * the existence of a directive.
54365 */
54366
54367
54368const BLOOM_SIZE = 256;
54369const BLOOM_MASK = BLOOM_SIZE - 1;
54370/**
54371 * The number of bits that is represented by a single bloom bucket. JS bit operations are 32 bits,
54372 * so each bucket represents 32 distinct tokens which accounts for log2(32) = 5 bits of a bloom hash
54373 * number.
54374 */
54375
54376const BLOOM_BUCKET_BITS = 5;
54377/** Counter used to generate unique IDs for directives. */
54378
54379let nextNgElementId = 0;
54380/** Value used when something wasn't found by an injector. */
54381
54382const NOT_FOUND = {};
54383/**
54384 * Registers this directive as present in its node's injector by flipping the directive's
54385 * corresponding bit in the injector's bloom filter.
54386 *
54387 * @param injectorIndex The index of the node injector where this token should be registered
54388 * @param tView The TView for the injector's bloom filters
54389 * @param type The directive token to register
54390 */
54391
54392function bloomAdd(injectorIndex, tView, type) {
54393  ngDevMode && assertEqual(tView.firstCreatePass, true, 'expected firstCreatePass to be true');
54394  let id;
54395
54396  if (typeof type === 'string') {
54397    id = type.charCodeAt(0) || 0;
54398  } else if (type.hasOwnProperty(NG_ELEMENT_ID)) {
54399    id = type[NG_ELEMENT_ID];
54400  } // Set a unique ID on the directive type, so if something tries to inject the directive,
54401  // we can easily retrieve the ID and hash it into the bloom bit that should be checked.
54402
54403
54404  if (id == null) {
54405    id = type[NG_ELEMENT_ID] = nextNgElementId++;
54406  } // We only have BLOOM_SIZE (256) slots in our bloom filter (8 buckets * 32 bits each),
54407  // so all unique IDs must be modulo-ed into a number from 0 - 255 to fit into the filter.
54408
54409
54410  const bloomHash = id & BLOOM_MASK; // Create a mask that targets the specific bit associated with the directive.
54411  // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
54412  // to bit positions 0 - 31 in a 32 bit integer.
54413
54414  const mask = 1 << bloomHash; // Each bloom bucket in `tData` represents `BLOOM_BUCKET_BITS` number of bits of `bloomHash`.
54415  // Any bits in `bloomHash` beyond `BLOOM_BUCKET_BITS` indicate the bucket offset that the mask
54416  // should be written to.
54417
54418  tView.data[injectorIndex + (bloomHash >> BLOOM_BUCKET_BITS)] |= mask;
54419}
54420/**
54421 * Creates (or gets an existing) injector for a given element or container.
54422 *
54423 * @param tNode for which an injector should be retrieved / created.
54424 * @param lView View where the node is stored
54425 * @returns Node injector
54426 */
54427
54428
54429function getOrCreateNodeInjectorForNode(tNode, lView) {
54430  const existingInjectorIndex = getInjectorIndex(tNode, lView);
54431
54432  if (existingInjectorIndex !== -1) {
54433    return existingInjectorIndex;
54434  }
54435
54436  const tView = lView[TVIEW];
54437
54438  if (tView.firstCreatePass) {
54439    tNode.injectorIndex = lView.length;
54440    insertBloom(tView.data, tNode); // foundation for node bloom
54441
54442    insertBloom(lView, null); // foundation for cumulative bloom
54443
54444    insertBloom(tView.blueprint, null);
54445  }
54446
54447  const parentLoc = getParentInjectorLocation(tNode, lView);
54448  const injectorIndex = tNode.injectorIndex; // If a parent injector can't be found, its location is set to -1.
54449  // In that case, we don't need to set up a cumulative bloom
54450
54451  if (hasParentInjector(parentLoc)) {
54452    const parentIndex = getParentInjectorIndex(parentLoc);
54453    const parentLView = getParentInjectorView(parentLoc, lView);
54454    const parentData = parentLView[TVIEW].data; // Creates a cumulative bloom filter that merges the parent's bloom filter
54455    // and its own cumulative bloom (which contains tokens for all ancestors)
54456
54457    for (let i = 0; i < 8
54458    /* NodeInjectorOffset.BLOOM_SIZE */
54459    ; i++) {
54460      lView[injectorIndex + i] = parentLView[parentIndex + i] | parentData[parentIndex + i];
54461    }
54462  }
54463
54464  lView[injectorIndex + 8
54465  /* NodeInjectorOffset.PARENT */
54466  ] = parentLoc;
54467  return injectorIndex;
54468}
54469
54470function insertBloom(arr, footer) {
54471  arr.push(0, 0, 0, 0, 0, 0, 0, 0, footer);
54472}
54473
54474function getInjectorIndex(tNode, lView) {
54475  if (tNode.injectorIndex === -1 || // If the injector index is the same as its parent's injector index, then the index has been
54476  // copied down from the parent node. No injector has been created yet on this node.
54477  tNode.parent && tNode.parent.injectorIndex === tNode.injectorIndex || // After the first template pass, the injector index might exist but the parent values
54478  // might not have been calculated yet for this instance
54479  lView[tNode.injectorIndex + 8
54480  /* NodeInjectorOffset.PARENT */
54481  ] === null) {
54482    return -1;
54483  } else {
54484    ngDevMode && assertIndexInRange(lView, tNode.injectorIndex);
54485    return tNode.injectorIndex;
54486  }
54487}
54488/**
54489 * Finds the index of the parent injector, with a view offset if applicable. Used to set the
54490 * parent injector initially.
54491 *
54492 * @returns Returns a number that is the combination of the number of LViews that we have to go up
54493 * to find the LView containing the parent inject AND the index of the injector within that LView.
54494 */
54495
54496
54497function getParentInjectorLocation(tNode, lView) {
54498  if (tNode.parent && tNode.parent.injectorIndex !== -1) {
54499    // If we have a parent `TNode` and there is an injector associated with it we are done, because
54500    // the parent injector is within the current `LView`.
54501    return tNode.parent.injectorIndex; // ViewOffset is 0
54502  } // When parent injector location is computed it may be outside of the current view. (ie it could
54503  // be pointing to a declared parent location). This variable stores number of declaration parents
54504  // we need to walk up in order to find the parent injector location.
54505
54506
54507  let declarationViewOffset = 0;
54508  let parentTNode = null;
54509  let lViewCursor = lView; // The parent injector is not in the current `LView`. We will have to walk the declared parent
54510  // `LView` hierarchy and look for it. If we walk of the top, that means that there is no parent
54511  // `NodeInjector`.
54512
54513  while (lViewCursor !== null) {
54514    parentTNode = getTNodeFromLView(lViewCursor);
54515
54516    if (parentTNode === null) {
54517      // If we have no parent, than we are done.
54518      return NO_PARENT_INJECTOR;
54519    }
54520
54521    ngDevMode && parentTNode && assertTNodeForLView(parentTNode, lViewCursor[DECLARATION_VIEW]); // Every iteration of the loop requires that we go to the declared parent.
54522
54523    declarationViewOffset++;
54524    lViewCursor = lViewCursor[DECLARATION_VIEW];
54525
54526    if (parentTNode.injectorIndex !== -1) {
54527      // We found a NodeInjector which points to something.
54528      return parentTNode.injectorIndex | declarationViewOffset << 16
54529      /* RelativeInjectorLocationFlags.ViewOffsetShift */
54530      ;
54531    }
54532  }
54533
54534  return NO_PARENT_INJECTOR;
54535}
54536/**
54537 * Makes a type or an injection token public to the DI system by adding it to an
54538 * injector's bloom filter.
54539 *
54540 * @param di The node injector in which a directive will be added
54541 * @param token The type or the injection token to be made public
54542 */
54543
54544
54545function diPublicInInjector(injectorIndex, tView, token) {
54546  bloomAdd(injectorIndex, tView, token);
54547}
54548/**
54549 * Inject static attribute value into directive constructor.
54550 *
54551 * This method is used with `factory` functions which are generated as part of
54552 * `defineDirective` or `defineComponent`. The method retrieves the static value
54553 * of an attribute. (Dynamic attributes are not supported since they are not resolved
54554 *  at the time of injection and can change over time.)
54555 *
54556 * # Example
54557 * Given:
54558 * ```
54559 * @Component(...)
54560 * class MyComponent {
54561 *   constructor(@Attribute('title') title: string) { ... }
54562 * }
54563 * ```
54564 * When instantiated with
54565 * ```
54566 * <my-component title="Hello"></my-component>
54567 * ```
54568 *
54569 * Then factory method generated is:
54570 * ```
54571 * MyComponent.ɵcmp = defineComponent({
54572 *   factory: () => new MyComponent(injectAttribute('title'))
54573 *   ...
54574 * })
54575 * ```
54576 *
54577 * @publicApi
54578 */
54579
54580
54581function injectAttributeImpl(tNode, attrNameToInject) {
54582  ngDevMode && assertTNodeType(tNode, 12
54583  /* TNodeType.AnyContainer */
54584  | 3
54585  /* TNodeType.AnyRNode */
54586  );
54587  ngDevMode && assertDefined(tNode, 'expecting tNode');
54588
54589  if (attrNameToInject === 'class') {
54590    return tNode.classes;
54591  }
54592
54593  if (attrNameToInject === 'style') {
54594    return tNode.styles;
54595  }
54596
54597  const attrs = tNode.attrs;
54598
54599  if (attrs) {
54600    const attrsLength = attrs.length;
54601    let i = 0;
54602
54603    while (i < attrsLength) {
54604      const value = attrs[i]; // If we hit a `Bindings` or `Template` marker then we are done.
54605
54606      if (isNameOnlyAttributeMarker(value)) break; // Skip namespaced attributes
54607
54608      if (value === 0
54609      /* AttributeMarker.NamespaceURI */
54610      ) {
54611        // we skip the next two values
54612        // as namespaced attributes looks like
54613        // [..., AttributeMarker.NamespaceURI, 'http://someuri.com/test', 'test:exist',
54614        // 'existValue', ...]
54615        i = i + 2;
54616      } else if (typeof value === 'number') {
54617        // Skip to the first value of the marked attribute.
54618        i++;
54619
54620        while (i < attrsLength && typeof attrs[i] === 'string') {
54621          i++;
54622        }
54623      } else if (value === attrNameToInject) {
54624        return attrs[i + 1];
54625      } else {
54626        i = i + 2;
54627      }
54628    }
54629  }
54630
54631  return null;
54632}
54633
54634function notFoundValueOrThrow(notFoundValue, token, flags) {
54635  if (flags & InjectFlags.Optional || notFoundValue !== undefined) {
54636    return notFoundValue;
54637  } else {
54638    throwProviderNotFoundError(token, 'NodeInjector');
54639  }
54640}
54641/**
54642 * Returns the value associated to the given token from the ModuleInjector or throws exception
54643 *
54644 * @param lView The `LView` that contains the `tNode`
54645 * @param token The token to look for
54646 * @param flags Injection flags
54647 * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
54648 * @returns the value from the injector or throws an exception
54649 */
54650
54651
54652function lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue) {
54653  if (flags & InjectFlags.Optional && notFoundValue === undefined) {
54654    // This must be set or the NullInjector will throw for optional deps
54655    notFoundValue = null;
54656  }
54657
54658  if ((flags & (InjectFlags.Self | InjectFlags.Host)) === 0) {
54659    const moduleInjector = lView[INJECTOR$1]; // switch to `injectInjectorOnly` implementation for module injector, since module injector
54660    // should not have access to Component/Directive DI scope (that may happen through
54661    // `directiveInject` implementation)
54662
54663    const previousInjectImplementation = setInjectImplementation(undefined);
54664
54665    try {
54666      if (moduleInjector) {
54667        return moduleInjector.get(token, notFoundValue, flags & InjectFlags.Optional);
54668      } else {
54669        return injectRootLimpMode(token, notFoundValue, flags & InjectFlags.Optional);
54670      }
54671    } finally {
54672      setInjectImplementation(previousInjectImplementation);
54673    }
54674  }
54675
54676  return notFoundValueOrThrow(notFoundValue, token, flags);
54677}
54678/**
54679 * Returns the value associated to the given token from the NodeInjectors => ModuleInjector.
54680 *
54681 * Look for the injector providing the token by walking up the node injector tree and then
54682 * the module injector tree.
54683 *
54684 * This function patches `token` with `__NG_ELEMENT_ID__` which contains the id for the bloom
54685 * filter. `-1` is reserved for injecting `Injector` (implemented by `NodeInjector`)
54686 *
54687 * @param tNode The Node where the search for the injector should start
54688 * @param lView The `LView` that contains the `tNode`
54689 * @param token The token to look for
54690 * @param flags Injection flags
54691 * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
54692 * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
54693 */
54694
54695
54696function getOrCreateInjectable(tNode, lView, token, flags = InjectFlags.Default, notFoundValue) {
54697  if (tNode !== null) {
54698    // If the view or any of its ancestors have an embedded
54699    // view injector, we have to look it up there first.
54700    if (lView[FLAGS] & 1024
54701    /* LViewFlags.HasEmbeddedViewInjector */
54702    ) {
54703      const embeddedInjectorValue = lookupTokenUsingEmbeddedInjector(tNode, lView, token, flags, NOT_FOUND);
54704
54705      if (embeddedInjectorValue !== NOT_FOUND) {
54706        return embeddedInjectorValue;
54707      }
54708    } // Otherwise try the node injector.
54709
54710
54711    const value = lookupTokenUsingNodeInjector(tNode, lView, token, flags, NOT_FOUND);
54712
54713    if (value !== NOT_FOUND) {
54714      return value;
54715    }
54716  } // Finally, fall back to the module injector.
54717
54718
54719  return lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue);
54720}
54721/**
54722 * Returns the value associated to the given token from the node injector.
54723 *
54724 * @param tNode The Node where the search for the injector should start
54725 * @param lView The `LView` that contains the `tNode`
54726 * @param token The token to look for
54727 * @param flags Injection flags
54728 * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
54729 * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
54730 */
54731
54732
54733function lookupTokenUsingNodeInjector(tNode, lView, token, flags, notFoundValue) {
54734  const bloomHash = bloomHashBitOrFactory(token); // If the ID stored here is a function, this is a special object like ElementRef or TemplateRef
54735  // so just call the factory function to create it.
54736
54737  if (typeof bloomHash === 'function') {
54738    if (!enterDI(lView, tNode, flags)) {
54739      // Failed to enter DI, try module injector instead. If a token is injected with the @Host
54740      // flag, the module injector is not searched for that token in Ivy.
54741      return flags & InjectFlags.Host ? notFoundValueOrThrow(notFoundValue, token, flags) : lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue);
54742    }
54743
54744    try {
54745      const value = bloomHash(flags);
54746
54747      if (value == null && !(flags & InjectFlags.Optional)) {
54748        throwProviderNotFoundError(token);
54749      } else {
54750        return value;
54751      }
54752    } finally {
54753      leaveDI();
54754    }
54755  } else if (typeof bloomHash === 'number') {
54756    // A reference to the previous injector TView that was found while climbing the element
54757    // injector tree. This is used to know if viewProviders can be accessed on the current
54758    // injector.
54759    let previousTView = null;
54760    let injectorIndex = getInjectorIndex(tNode, lView);
54761    let parentLocation = NO_PARENT_INJECTOR;
54762    let hostTElementNode = flags & InjectFlags.Host ? lView[DECLARATION_COMPONENT_VIEW][T_HOST] : null; // If we should skip this injector, or if there is no injector on this node, start by
54763    // searching the parent injector.
54764
54765    if (injectorIndex === -1 || flags & InjectFlags.SkipSelf) {
54766      parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lView) : lView[injectorIndex + 8
54767      /* NodeInjectorOffset.PARENT */
54768      ];
54769
54770      if (parentLocation === NO_PARENT_INJECTOR || !shouldSearchParent(flags, false)) {
54771        injectorIndex = -1;
54772      } else {
54773        previousTView = lView[TVIEW];
54774        injectorIndex = getParentInjectorIndex(parentLocation);
54775        lView = getParentInjectorView(parentLocation, lView);
54776      }
54777    } // Traverse up the injector tree until we find a potential match or until we know there
54778    // *isn't* a match.
54779
54780
54781    while (injectorIndex !== -1) {
54782      ngDevMode && assertNodeInjector(lView, injectorIndex); // Check the current injector. If it matches, see if it contains token.
54783
54784      const tView = lView[TVIEW];
54785      ngDevMode && assertTNodeForLView(tView.data[injectorIndex + 8
54786      /* NodeInjectorOffset.TNODE */
54787      ], lView);
54788
54789      if (bloomHasToken(bloomHash, injectorIndex, tView.data)) {
54790        // At this point, we have an injector which *may* contain the token, so we step through
54791        // the providers and directives associated with the injector's corresponding node to get
54792        // the instance.
54793        const instance = searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode);
54794
54795        if (instance !== NOT_FOUND) {
54796          return instance;
54797        }
54798      }
54799
54800      parentLocation = lView[injectorIndex + 8
54801      /* NodeInjectorOffset.PARENT */
54802      ];
54803
54804      if (parentLocation !== NO_PARENT_INJECTOR && shouldSearchParent(flags, lView[TVIEW].data[injectorIndex + 8
54805      /* NodeInjectorOffset.TNODE */
54806      ] === hostTElementNode) && bloomHasToken(bloomHash, injectorIndex, lView)) {
54807        // The def wasn't found anywhere on this node, so it was a false positive.
54808        // Traverse up the tree and continue searching.
54809        previousTView = tView;
54810        injectorIndex = getParentInjectorIndex(parentLocation);
54811        lView = getParentInjectorView(parentLocation, lView);
54812      } else {
54813        // If we should not search parent OR If the ancestor bloom filter value does not have the
54814        // bit corresponding to the directive we can give up on traversing up to find the specific
54815        // injector.
54816        injectorIndex = -1;
54817      }
54818    }
54819  }
54820
54821  return notFoundValue;
54822}
54823
54824function searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode) {
54825  const currentTView = lView[TVIEW];
54826  const tNode = currentTView.data[injectorIndex + 8
54827  /* NodeInjectorOffset.TNODE */
54828  ]; // First, we need to determine if view providers can be accessed by the starting element.
54829  // There are two possibilities
54830
54831  const canAccessViewProviders = previousTView == null ? // 1) This is the first invocation `previousTView == null` which means that we are at the
54832  // `TNode` of where injector is starting to look. In such a case the only time we are allowed
54833  // to look into the ViewProviders is if:
54834  // - we are on a component
54835  // - AND the injector set `includeViewProviders` to true (implying that the token can see
54836  // ViewProviders because it is the Component or a Service which itself was declared in
54837  // ViewProviders)
54838  isComponentHost(tNode) && includeViewProviders : // 2) `previousTView != null` which means that we are now walking across the parent nodes.
54839  // In such a case we are only allowed to look into the ViewProviders if:
54840  // - We just crossed from child View to Parent View `previousTView != currentTView`
54841  // - AND the parent TNode is an Element.
54842  // This means that we just came from the Component's View and therefore are allowed to see
54843  // into the ViewProviders.
54844  previousTView != currentTView && (tNode.type & 3
54845  /* TNodeType.AnyRNode */
54846  ) !== 0; // This special case happens when there is a @host on the inject and when we are searching
54847  // on the host element node.
54848
54849  const isHostSpecialCase = flags & InjectFlags.Host && hostTElementNode === tNode;
54850  const injectableIdx = locateDirectiveOrProvider(tNode, currentTView, token, canAccessViewProviders, isHostSpecialCase);
54851
54852  if (injectableIdx !== null) {
54853    return getNodeInjectable(lView, currentTView, injectableIdx, tNode);
54854  } else {
54855    return NOT_FOUND;
54856  }
54857}
54858/**
54859 * Searches for the given token among the node's directives and providers.
54860 *
54861 * @param tNode TNode on which directives are present.
54862 * @param tView The tView we are currently processing
54863 * @param token Provider token or type of a directive to look for.
54864 * @param canAccessViewProviders Whether view providers should be considered.
54865 * @param isHostSpecialCase Whether the host special case applies.
54866 * @returns Index of a found directive or provider, or null when none found.
54867 */
54868
54869
54870function locateDirectiveOrProvider(tNode, tView, token, canAccessViewProviders, isHostSpecialCase) {
54871  const nodeProviderIndexes = tNode.providerIndexes;
54872  const tInjectables = tView.data;
54873  const injectablesStart = nodeProviderIndexes & 1048575
54874  /* TNodeProviderIndexes.ProvidersStartIndexMask */
54875  ;
54876  const directivesStart = tNode.directiveStart;
54877  const directiveEnd = tNode.directiveEnd;
54878  const cptViewProvidersCount = nodeProviderIndexes >> 20
54879  /* TNodeProviderIndexes.CptViewProvidersCountShift */
54880  ;
54881  const startingIndex = canAccessViewProviders ? injectablesStart : injectablesStart + cptViewProvidersCount; // When the host special case applies, only the viewProviders and the component are visible
54882
54883  const endIndex = isHostSpecialCase ? injectablesStart + cptViewProvidersCount : directiveEnd;
54884
54885  for (let i = startingIndex; i < endIndex; i++) {
54886    const providerTokenOrDef = tInjectables[i];
54887
54888    if (i < directivesStart && token === providerTokenOrDef || i >= directivesStart && providerTokenOrDef.type === token) {
54889      return i;
54890    }
54891  }
54892
54893  if (isHostSpecialCase) {
54894    const dirDef = tInjectables[directivesStart];
54895
54896    if (dirDef && isComponentDef(dirDef) && dirDef.type === token) {
54897      return directivesStart;
54898    }
54899  }
54900
54901  return null;
54902}
54903/**
54904 * Retrieve or instantiate the injectable from the `LView` at particular `index`.
54905 *
54906 * This function checks to see if the value has already been instantiated and if so returns the
54907 * cached `injectable`. Otherwise if it detects that the value is still a factory it
54908 * instantiates the `injectable` and caches the value.
54909 */
54910
54911
54912function getNodeInjectable(lView, tView, index, tNode) {
54913  let value = lView[index];
54914  const tData = tView.data;
54915
54916  if (isFactory(value)) {
54917    const factory = value;
54918
54919    if (factory.resolving) {
54920      throwCyclicDependencyError(stringifyForError(tData[index]));
54921    }
54922
54923    const previousIncludeViewProviders = setIncludeViewProviders(factory.canSeeViewProviders);
54924    factory.resolving = true;
54925    const previousInjectImplementation = factory.injectImpl ? setInjectImplementation(factory.injectImpl) : null;
54926    const success = enterDI(lView, tNode, InjectFlags.Default);
54927    ngDevMode && assertEqual(success, true, 'Because flags do not contain \`SkipSelf\' we expect this to always succeed.');
54928
54929    try {
54930      value = lView[index] = factory.factory(undefined, tData, lView, tNode); // This code path is hit for both directives and providers.
54931      // For perf reasons, we want to avoid searching for hooks on providers.
54932      // It does no harm to try (the hooks just won't exist), but the extra
54933      // checks are unnecessary and this is a hot path. So we check to see
54934      // if the index of the dependency is in the directive range for this
54935      // tNode. If it's not, we know it's a provider and skip hook registration.
54936
54937      if (tView.firstCreatePass && index >= tNode.directiveStart) {
54938        ngDevMode && assertDirectiveDef(tData[index]);
54939        registerPreOrderHooks(index, tData[index], tView);
54940      }
54941    } finally {
54942      previousInjectImplementation !== null && setInjectImplementation(previousInjectImplementation);
54943      setIncludeViewProviders(previousIncludeViewProviders);
54944      factory.resolving = false;
54945      leaveDI();
54946    }
54947  }
54948
54949  return value;
54950}
54951/**
54952 * Returns the bit in an injector's bloom filter that should be used to determine whether or not
54953 * the directive might be provided by the injector.
54954 *
54955 * When a directive is public, it is added to the bloom filter and given a unique ID that can be
54956 * retrieved on the Type. When the directive isn't public or the token is not a directive `null`
54957 * is returned as the node injector can not possibly provide that token.
54958 *
54959 * @param token the injection token
54960 * @returns the matching bit to check in the bloom filter or `null` if the token is not known.
54961 *   When the returned value is negative then it represents special values such as `Injector`.
54962 */
54963
54964
54965function bloomHashBitOrFactory(token) {
54966  ngDevMode && assertDefined(token, 'token must be defined');
54967
54968  if (typeof token === 'string') {
54969    return token.charCodeAt(0) || 0;
54970  }
54971
54972  const tokenId = // First check with `hasOwnProperty` so we don't get an inherited ID.
54973  token.hasOwnProperty(NG_ELEMENT_ID) ? token[NG_ELEMENT_ID] : undefined; // Negative token IDs are used for special objects such as `Injector`
54974
54975  if (typeof tokenId === 'number') {
54976    if (tokenId >= 0) {
54977      return tokenId & BLOOM_MASK;
54978    } else {
54979      ngDevMode && assertEqual(tokenId, -1
54980      /* InjectorMarkers.Injector */
54981      , 'Expecting to get Special Injector Id');
54982      return createNodeInjector;
54983    }
54984  } else {
54985    return tokenId;
54986  }
54987}
54988
54989function bloomHasToken(bloomHash, injectorIndex, injectorView) {
54990  // Create a mask that targets the specific bit associated with the directive we're looking for.
54991  // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
54992  // to bit positions 0 - 31 in a 32 bit integer.
54993  const mask = 1 << bloomHash; // Each bloom bucket in `injectorView` represents `BLOOM_BUCKET_BITS` number of bits of
54994  // `bloomHash`. Any bits in `bloomHash` beyond `BLOOM_BUCKET_BITS` indicate the bucket offset
54995  // that should be used.
54996
54997  const value = injectorView[injectorIndex + (bloomHash >> BLOOM_BUCKET_BITS)]; // If the bloom filter value has the bit corresponding to the directive's bloomBit flipped on,
54998  // this injector is a potential match.
54999
55000  return !!(value & mask);
55001}
55002/** Returns true if flags prevent parent injector from being searched for tokens */
55003
55004
55005function shouldSearchParent(flags, isFirstHostTNode) {
55006  return !(flags & InjectFlags.Self) && !(flags & InjectFlags.Host && isFirstHostTNode);
55007}
55008
55009class NodeInjector {
55010  constructor(_tNode, _lView) {
55011    this._tNode = _tNode;
55012    this._lView = _lView;
55013  }
55014
55015  get(token, notFoundValue, flags) {
55016    return getOrCreateInjectable(this._tNode, this._lView, token, flags, notFoundValue);
55017  }
55018
55019}
55020/** Creates a `NodeInjector` for the current node. */
55021
55022
55023function createNodeInjector() {
55024  return new NodeInjector(getCurrentTNode(), getLView());
55025}
55026/**
55027 * @codeGenApi
55028 */
55029
55030
55031function ɵɵgetInheritedFactory(type) {
55032  return noSideEffects(() => {
55033    const ownConstructor = type.prototype.constructor;
55034    const ownFactory = ownConstructor[NG_FACTORY_DEF] || getFactoryOf(ownConstructor);
55035    const objectPrototype = Object.prototype;
55036    let parent = Object.getPrototypeOf(type.prototype).constructor; // Go up the prototype until we hit `Object`.
55037
55038    while (parent && parent !== objectPrototype) {
55039      const factory = parent[NG_FACTORY_DEF] || getFactoryOf(parent); // If we hit something that has a factory and the factory isn't the same as the type,
55040      // we've found the inherited factory. Note the check that the factory isn't the type's
55041      // own factory is redundant in most cases, but if the user has custom decorators on the
55042      // class, this lookup will start one level down in the prototype chain, causing us to
55043      // find the own factory first and potentially triggering an infinite loop downstream.
55044
55045      if (factory && factory !== ownFactory) {
55046        return factory;
55047      }
55048
55049      parent = Object.getPrototypeOf(parent);
55050    } // There is no factory defined. Either this was improper usage of inheritance
55051    // (no Angular decorator on the superclass) or there is no constructor at all
55052    // in the inheritance chain. Since the two cases cannot be distinguished, the
55053    // latter has to be assumed.
55054
55055
55056    return t => new t();
55057  });
55058}
55059
55060function getFactoryOf(type) {
55061  if (isForwardRef(type)) {
55062    return () => {
55063      const factory = getFactoryOf(resolveForwardRef(type));
55064      return factory && factory();
55065    };
55066  }
55067
55068  return getFactoryDef(type);
55069}
55070/**
55071 * Returns a value from the closest embedded or node injector.
55072 *
55073 * @param tNode The Node where the search for the injector should start
55074 * @param lView The `LView` that contains the `tNode`
55075 * @param token The token to look for
55076 * @param flags Injection flags
55077 * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
55078 * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
55079 */
55080
55081
55082function lookupTokenUsingEmbeddedInjector(tNode, lView, token, flags, notFoundValue) {
55083  let currentTNode = tNode;
55084  let currentLView = lView; // When an LView with an embedded view injector is inserted, it'll likely be interlaced with
55085  // nodes who may have injectors (e.g. node injector -> embedded view injector -> node injector).
55086  // Since the bloom filters for the node injectors have already been constructed and we don't
55087  // have a way of extracting the records from an injector, the only way to maintain the correct
55088  // hierarchy when resolving the value is to walk it node-by-node while attempting to resolve
55089  // the token at each level.
55090
55091  while (currentTNode !== null && currentLView !== null && currentLView[FLAGS] & 1024
55092  /* LViewFlags.HasEmbeddedViewInjector */
55093  && !(currentLView[FLAGS] & 256
55094  /* LViewFlags.IsRoot */
55095  )) {
55096    ngDevMode && assertTNodeForLView(currentTNode, currentLView); // Note that this lookup on the node injector is using the `Self` flag, because
55097    // we don't want the node injector to look at any parent injectors since we
55098    // may hit the embedded view injector first.
55099
55100    const nodeInjectorValue = lookupTokenUsingNodeInjector(currentTNode, currentLView, token, flags | InjectFlags.Self, NOT_FOUND);
55101
55102    if (nodeInjectorValue !== NOT_FOUND) {
55103      return nodeInjectorValue;
55104    } // Has an explicit type due to a TS bug: https://github.com/microsoft/TypeScript/issues/33191
55105
55106
55107    let parentTNode = currentTNode.parent; // `TNode.parent` includes the parent within the current view only. If it doesn't exist,
55108    // it means that we've hit the view boundary and we need to go up to the next view.
55109
55110    if (!parentTNode) {
55111      // Before we go to the next LView, check if the token exists on the current embedded injector.
55112      const embeddedViewInjector = currentLView[EMBEDDED_VIEW_INJECTOR];
55113
55114      if (embeddedViewInjector) {
55115        const embeddedViewInjectorValue = embeddedViewInjector.get(token, NOT_FOUND, flags);
55116
55117        if (embeddedViewInjectorValue !== NOT_FOUND) {
55118          return embeddedViewInjectorValue;
55119        }
55120      } // Otherwise keep going up the tree.
55121
55122
55123      parentTNode = getTNodeFromLView(currentLView);
55124      currentLView = currentLView[DECLARATION_VIEW];
55125    }
55126
55127    currentTNode = parentTNode;
55128  }
55129
55130  return notFoundValue;
55131}
55132/** Gets the TNode associated with an LView inside of the declaration view. */
55133
55134
55135function getTNodeFromLView(lView) {
55136  const tView = lView[TVIEW];
55137  const tViewType = tView.type; // The parent pointer differs based on `TView.type`.
55138
55139  if (tViewType === 2
55140  /* TViewType.Embedded */
55141  ) {
55142    ngDevMode && assertDefined(tView.declTNode, 'Embedded TNodes should have declaration parents.');
55143    return tView.declTNode;
55144  } else if (tViewType === 1
55145  /* TViewType.Component */
55146  ) {
55147    // Components don't have `TView.declTNode` because each instance of component could be
55148    // inserted in different location, hence `TView.declTNode` is meaningless.
55149    return lView[T_HOST];
55150  }
55151
55152  return null;
55153}
55154/**
55155 * @license
55156 * Copyright Google LLC All Rights Reserved.
55157 *
55158 * Use of this source code is governed by an MIT-style license that can be
55159 * found in the LICENSE file at https://angular.io/license
55160 */
55161
55162/**
55163 * Facade for the attribute injection from DI.
55164 *
55165 * @codeGenApi
55166 */
55167
55168
55169function ɵɵinjectAttribute(attrNameToInject) {
55170  return injectAttributeImpl(getCurrentTNode(), attrNameToInject);
55171}
55172/**
55173 * @license
55174 * Copyright Google LLC All Rights Reserved.
55175 *
55176 * Use of this source code is governed by an MIT-style license that can be
55177 * found in the LICENSE file at https://angular.io/license
55178 */
55179
55180
55181const ANNOTATIONS = '__annotations__';
55182const PARAMETERS = '__parameters__';
55183const PROP_METADATA = '__prop__metadata__';
55184/**
55185 * @suppress {globalThis}
55186 */
55187
55188function makeDecorator(name, props, parentClass, additionalProcessing, typeFn) {
55189  return noSideEffects(() => {
55190    const metaCtor = makeMetadataCtor(props);
55191
55192    function DecoratorFactory(...args) {
55193      if (this instanceof DecoratorFactory) {
55194        metaCtor.call(this, ...args);
55195        return this;
55196      }
55197
55198      const annotationInstance = new DecoratorFactory(...args);
55199      return function TypeDecorator(cls) {
55200        if (typeFn) typeFn(cls, ...args); // Use of Object.defineProperty is important since it creates non-enumerable property which
55201        // prevents the property is copied during subclassing.
55202
55203        const annotations = cls.hasOwnProperty(ANNOTATIONS) ? cls[ANNOTATIONS] : Object.defineProperty(cls, ANNOTATIONS, {
55204          value: []
55205        })[ANNOTATIONS];
55206        annotations.push(annotationInstance);
55207        if (additionalProcessing) additionalProcessing(cls);
55208        return cls;
55209      };
55210    }
55211
55212    if (parentClass) {
55213      DecoratorFactory.prototype = Object.create(parentClass.prototype);
55214    }
55215
55216    DecoratorFactory.prototype.ngMetadataName = name;
55217    DecoratorFactory.annotationCls = DecoratorFactory;
55218    return DecoratorFactory;
55219  });
55220}
55221
55222function makeMetadataCtor(props) {
55223  return function ctor(...args) {
55224    if (props) {
55225      const values = props(...args);
55226
55227      for (const propName in values) {
55228        this[propName] = values[propName];
55229      }
55230    }
55231  };
55232}
55233
55234function makeParamDecorator(name, props, parentClass) {
55235  return noSideEffects(() => {
55236    const metaCtor = makeMetadataCtor(props);
55237
55238    function ParamDecoratorFactory(...args) {
55239      if (this instanceof ParamDecoratorFactory) {
55240        metaCtor.apply(this, args);
55241        return this;
55242      }
55243
55244      const annotationInstance = new ParamDecoratorFactory(...args);
55245      ParamDecorator.annotation = annotationInstance;
55246      return ParamDecorator;
55247
55248      function ParamDecorator(cls, unusedKey, index) {
55249        // Use of Object.defineProperty is important since it creates non-enumerable property which
55250        // prevents the property is copied during subclassing.
55251        const parameters = cls.hasOwnProperty(PARAMETERS) ? cls[PARAMETERS] : Object.defineProperty(cls, PARAMETERS, {
55252          value: []
55253        })[PARAMETERS]; // there might be gaps if some in between parameters do not have annotations.
55254        // we pad with nulls.
55255
55256        while (parameters.length <= index) {
55257          parameters.push(null);
55258        }
55259
55260        (parameters[index] = parameters[index] || []).push(annotationInstance);
55261        return cls;
55262      }
55263    }
55264
55265    if (parentClass) {
55266      ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
55267    }
55268
55269    ParamDecoratorFactory.prototype.ngMetadataName = name;
55270    ParamDecoratorFactory.annotationCls = ParamDecoratorFactory;
55271    return ParamDecoratorFactory;
55272  });
55273}
55274
55275function makePropDecorator(name, props, parentClass, additionalProcessing) {
55276  return noSideEffects(() => {
55277    const metaCtor = makeMetadataCtor(props);
55278
55279    function PropDecoratorFactory(...args) {
55280      if (this instanceof PropDecoratorFactory) {
55281        metaCtor.apply(this, args);
55282        return this;
55283      }
55284
55285      const decoratorInstance = new PropDecoratorFactory(...args);
55286
55287      function PropDecorator(target, name) {
55288        const constructor = target.constructor; // Use of Object.defineProperty is important because it creates a non-enumerable property
55289        // which prevents the property from being copied during subclassing.
55290
55291        const meta = constructor.hasOwnProperty(PROP_METADATA) ? constructor[PROP_METADATA] : Object.defineProperty(constructor, PROP_METADATA, {
55292          value: {}
55293        })[PROP_METADATA];
55294        meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
55295        meta[name].unshift(decoratorInstance);
55296        if (additionalProcessing) additionalProcessing(target, name, ...args);
55297      }
55298
55299      return PropDecorator;
55300    }
55301
55302    if (parentClass) {
55303      PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
55304    }
55305
55306    PropDecoratorFactory.prototype.ngMetadataName = name;
55307    PropDecoratorFactory.annotationCls = PropDecoratorFactory;
55308    return PropDecoratorFactory;
55309  });
55310}
55311/**
55312 * @license
55313 * Copyright Google LLC All Rights Reserved.
55314 *
55315 * Use of this source code is governed by an MIT-style license that can be
55316 * found in the LICENSE file at https://angular.io/license
55317 */
55318
55319/**
55320 * Attribute decorator and metadata.
55321 *
55322 * @Annotation
55323 * @publicApi
55324 */
55325
55326
55327const Attribute = makeParamDecorator('Attribute', attributeName => ({
55328  attributeName,
55329  __NG_ELEMENT_ID__: () => ɵɵinjectAttribute(attributeName)
55330}));
55331/**
55332 * @license
55333 * Copyright Google LLC All Rights Reserved.
55334 *
55335 * Use of this source code is governed by an MIT-style license that can be
55336 * found in the LICENSE file at https://angular.io/license
55337 */
55338
55339/**
55340 * Creates a token that can be used in a DI Provider.
55341 *
55342 * Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
55343 * runtime representation) such as when injecting an interface, callable type, array or
55344 * parameterized type.
55345 *
55346 * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
55347 * the `Injector`. This provides an additional level of type safety.
55348 *
55349 * ```
55350 * interface MyInterface {...}
55351 * const myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
55352 * // myInterface is inferred to be MyInterface.
55353 * ```
55354 *
55355 * When creating an `InjectionToken`, you can optionally specify a factory function which returns
55356 * (possibly by creating) a default value of the parameterized type `T`. This sets up the
55357 * `InjectionToken` using this factory as a provider as if it was defined explicitly in the
55358 * application's root injector. If the factory function, which takes zero arguments, needs to inject
55359 * dependencies, it can do so using the `inject` function.
55360 * As you can see in the Tree-shakable InjectionToken example below.
55361 *
55362 * Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
55363 * overrides the above behavior and marks the token as belonging to a particular `@NgModule`. As
55364 * mentioned above, `'root'` is the default value for `providedIn`.
55365 *
55366 * @usageNotes
55367 * ### Basic Examples
55368 *
55369 * ### Plain InjectionToken
55370 *
55371 * {@example core/di/ts/injector_spec.ts region='InjectionToken'}
55372 *
55373 * ### Tree-shakable InjectionToken
55374 *
55375 * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
55376 *
55377 *
55378 * @publicApi
55379 */
55380
55381class InjectionToken {
55382  /**
55383   * @param _desc   Description for the token,
55384   *                used only for debugging purposes,
55385   *                it should but does not need to be unique
55386   * @param options Options for the token's usage, as described above
55387   */
55388  constructor(_desc, options) {
55389    this._desc = _desc;
55390    /** @internal */
55391
55392    this.ngMetadataName = 'InjectionToken';
55393    this.ɵprov = undefined;
55394
55395    if (typeof options == 'number') {
55396      (typeof ngDevMode === 'undefined' || ngDevMode) && assertLessThan(options, 0, 'Only negative numbers are supported here'); // This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
55397      // See `InjectorMarkers`
55398
55399      this.__NG_ELEMENT_ID__ = options;
55400    } else if (options !== undefined) {
55401      this.ɵprov = ɵɵdefineInjectable({
55402        token: this,
55403        providedIn: options.providedIn || 'root',
55404        factory: options.factory
55405      });
55406    }
55407  }
55408  /**
55409   * @internal
55410   */
55411
55412
55413  get multi() {
55414    return this;
55415  }
55416
55417  toString() {
55418    return `InjectionToken ${this._desc}`;
55419  }
55420
55421}
55422/**
55423 * @license
55424 * Copyright Google LLC All Rights Reserved.
55425 *
55426 * Use of this source code is governed by an MIT-style license that can be
55427 * found in the LICENSE file at https://angular.io/license
55428 */
55429
55430/**
55431 * A DI token that you can use to create a virtual [provider](guide/glossary#provider)
55432 * that will populate the `entryComponents` field of components and NgModules
55433 * based on its `useValue` property value.
55434 * All components that are referenced in the `useValue` value (either directly
55435 * or in a nested array or map) are added to the `entryComponents` property.
55436 *
55437 * @usageNotes
55438 *
55439 * The following example shows how the router can populate the `entryComponents`
55440 * field of an NgModule based on a router configuration that refers
55441 * to components.
55442 *
55443 * ```typescript
55444 * // helper function inside the router
55445 * function provideRoutes(routes) {
55446 *   return [
55447 *     {provide: ROUTES, useValue: routes},
55448 *     {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: routes, multi: true}
55449 *   ];
55450 * }
55451 *
55452 * // user code
55453 * let routes = [
55454 *   {path: '/root', component: RootComp},
55455 *   {path: '/teams', component: TeamsComp}
55456 * ];
55457 *
55458 * @NgModule({
55459 *   providers: [provideRoutes(routes)]
55460 * })
55461 * class ModuleWithRoutes {}
55462 * ```
55463 *
55464 * @publicApi
55465 * @deprecated Since 9.0.0. With Ivy, this property is no longer necessary.
55466 */
55467
55468
55469const ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken('AnalyzeForEntryComponents'); // Stores the default value of `emitDistinctChangesOnly` when the `emitDistinctChangesOnly` is not
55470// explicitly set.
55471
55472const emitDistinctChangesOnlyDefaultValue = true;
55473/**
55474 * Base class for query metadata.
55475 *
55476 * @see `ContentChildren`.
55477 * @see `ContentChild`.
55478 * @see `ViewChildren`.
55479 * @see `ViewChild`.
55480 *
55481 * @publicApi
55482 */
55483
55484class Query {}
55485/**
55486 * ContentChildren decorator and metadata.
55487 *
55488 *
55489 * @Annotation
55490 * @publicApi
55491 */
55492
55493
55494const ContentChildren = makePropDecorator('ContentChildren', (selector, data = {}) => ({
55495  selector,
55496  first: false,
55497  isViewQuery: false,
55498  descendants: false,
55499  emitDistinctChangesOnly: emitDistinctChangesOnlyDefaultValue,
55500  ...data
55501}), Query);
55502/**
55503 * ContentChild decorator and metadata.
55504 *
55505 *
55506 * @Annotation
55507 *
55508 * @publicApi
55509 */
55510
55511const ContentChild = makePropDecorator('ContentChild', (selector, data = {}) => ({
55512  selector,
55513  first: true,
55514  isViewQuery: false,
55515  descendants: true,
55516  ...data
55517}), Query);
55518/**
55519 * ViewChildren decorator and metadata.
55520 *
55521 * @Annotation
55522 * @publicApi
55523 */
55524
55525const ViewChildren = makePropDecorator('ViewChildren', (selector, data = {}) => ({
55526  selector,
55527  first: false,
55528  isViewQuery: true,
55529  descendants: true,
55530  emitDistinctChangesOnly: emitDistinctChangesOnlyDefaultValue,
55531  ...data
55532}), Query);
55533/**
55534 * ViewChild decorator and metadata.
55535 *
55536 * @Annotation
55537 * @publicApi
55538 */
55539
55540const ViewChild = makePropDecorator('ViewChild', (selector, data) => ({
55541  selector,
55542  first: true,
55543  isViewQuery: true,
55544  descendants: true,
55545  ...data
55546}), Query);
55547/**
55548 * @license
55549 * Copyright Google LLC All Rights Reserved.
55550 *
55551 * Use of this source code is governed by an MIT-style license that can be
55552 * found in the LICENSE file at https://angular.io/license
55553 */
55554
55555var FactoryTarget;
55556
55557(function (FactoryTarget) {
55558  FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
55559  FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
55560  FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
55561  FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
55562  FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
55563})(FactoryTarget || (FactoryTarget = {}));
55564
55565var R3TemplateDependencyKind;
55566
55567(function (R3TemplateDependencyKind) {
55568  R3TemplateDependencyKind[R3TemplateDependencyKind["Directive"] = 0] = "Directive";
55569  R3TemplateDependencyKind[R3TemplateDependencyKind["Pipe"] = 1] = "Pipe";
55570  R3TemplateDependencyKind[R3TemplateDependencyKind["NgModule"] = 2] = "NgModule";
55571})(R3TemplateDependencyKind || (R3TemplateDependencyKind = {}));
55572
55573var ViewEncapsulation;
55574
55575(function (ViewEncapsulation) {
55576  ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated"; // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
55577
55578  ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
55579  ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
55580})(ViewEncapsulation || (ViewEncapsulation = {}));
55581/**
55582 * @license
55583 * Copyright Google LLC All Rights Reserved.
55584 *
55585 * Use of this source code is governed by an MIT-style license that can be
55586 * found in the LICENSE file at https://angular.io/license
55587 */
55588
55589
55590function getCompilerFacade(request) {
55591  const globalNg = _global['ng'];
55592
55593  if (globalNg && globalNg.ɵcompilerFacade) {
55594    return globalNg.ɵcompilerFacade;
55595  }
55596
55597  if (typeof ngDevMode === 'undefined' || ngDevMode) {
55598    // Log the type as an error so that a developer can easily navigate to the type from the
55599    // console.
55600    console.error(`JIT compilation failed for ${request.kind}`, request.type);
55601    let message = `The ${request.kind} '${request.type.name}' needs to be compiled using the JIT compiler, but '@angular/compiler' is not available.\n\n`;
55602
55603    if (request.usage === 1
55604    /* JitCompilerUsage.PartialDeclaration */
55605    ) {
55606      message += `The ${request.kind} is part of a library that has been partially compiled.\n`;
55607      message += `However, the Angular Linker has not processed the library such that JIT compilation is used as fallback.\n`;
55608      message += '\n';
55609      message += `Ideally, the library is processed using the Angular Linker to become fully AOT compiled.\n`;
55610    } else {
55611      message += `JIT compilation is discouraged for production use-cases! Consider using AOT mode instead.\n`;
55612    }
55613
55614    message += `Alternatively, the JIT compiler should be loaded by bootstrapping using '@angular/platform-browser-dynamic' or '@angular/platform-server',\n`;
55615    message += `or manually provide the compiler with 'import "@angular/compiler";' before bootstrapping.`;
55616    throw new Error(message);
55617  } else {
55618    throw new Error('JIT compiler unavailable');
55619  }
55620}
55621/**
55622 * @license
55623 * Copyright Google LLC All Rights Reserved.
55624 *
55625 * Use of this source code is governed by an MIT-style license that can be
55626 * found in the LICENSE file at https://angular.io/license
55627 */
55628
55629/**
55630 * @description
55631 *
55632 * Represents a type that a Component or other object is instances of.
55633 *
55634 * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is represented by
55635 * the `MyCustomComponent` constructor function.
55636 *
55637 * @publicApi
55638 */
55639
55640
55641const Type = Function;
55642
55643function isType(v) {
55644  return typeof v === 'function';
55645}
55646/**
55647 * @license
55648 * Copyright Google LLC All Rights Reserved.
55649 *
55650 * Use of this source code is governed by an MIT-style license that can be
55651 * found in the LICENSE file at https://angular.io/license
55652 */
55653
55654/**
55655 * Equivalent to ES6 spread, add each item to an array.
vendor: 18,225 bytes, lines 55656-56280
55656 *
55657 * @param items The items to add
55658 * @param arr The array to which you want to add the items
55659 */
55660
55661
55662function addAllToArray(items, arr) {
55663  for (let i = 0; i < items.length; i++) {
55664    arr.push(items[i]);
55665  }
55666}
55667/**
55668 * Determines if the contents of two arrays is identical
55669 *
55670 * @param a first array
55671 * @param b second array
55672 * @param identityAccessor Optional function for extracting stable object identity from a value in
55673 *     the array.
55674 */
55675
55676
55677function arrayEquals(a, b, identityAccessor) {
55678  if (a.length !== b.length) return false;
55679
55680  for (let i = 0; i < a.length; i++) {
55681    let valueA = a[i];
55682    let valueB = b[i];
55683
55684    if (identityAccessor) {
55685      valueA = identityAccessor(valueA);
55686      valueB = identityAccessor(valueB);
55687    }
55688
55689    if (valueB !== valueA) {
55690      return false;
55691    }
55692  }
55693
55694  return true;
55695}
55696/**
55697 * Flattens an array.
55698 */
55699
55700
55701function flatten(list, dst) {
55702  if (dst === undefined) dst = list;
55703
55704  for (let i = 0; i < list.length; i++) {
55705    let item = list[i];
55706
55707    if (Array.isArray(item)) {
55708      // we need to inline it.
55709      if (dst === list) {
55710        // Our assumption that the list was already flat was wrong and
55711        // we need to clone flat since we need to write to it.
55712        dst = list.slice(0, i);
55713      }
55714
55715      flatten(item, dst);
55716    } else if (dst !== list) {
55717      dst.push(item);
55718    }
55719  }
55720
55721  return dst;
55722}
55723
55724function deepForEach(input, fn) {
55725  input.forEach(value => Array.isArray(value) ? deepForEach(value, fn) : fn(value));
55726}
55727
55728function addToArray(arr, index, value) {
55729  // perf: array.push is faster than array.splice!
55730  if (index >= arr.length) {
55731    arr.push(value);
55732  } else {
55733    arr.splice(index, 0, value);
55734  }
55735}
55736
55737function removeFromArray(arr, index) {
55738  // perf: array.pop is faster than array.splice!
55739  if (index >= arr.length - 1) {
55740    return arr.pop();
55741  } else {
55742    return arr.splice(index, 1)[0];
55743  }
55744}
55745
55746function newArray(size, value) {
55747  const list = [];
55748
55749  for (let i = 0; i < size; i++) {
55750    list.push(value);
55751  }
55752
55753  return list;
55754}
55755/**
55756 * Remove item from array (Same as `Array.splice()` but faster.)
55757 *
55758 * `Array.splice()` is not as fast because it has to allocate an array for the elements which were
55759 * removed. This causes memory pressure and slows down code when most of the time we don't
55760 * care about the deleted items array.
55761 *
55762 * https://jsperf.com/fast-array-splice (About 20x faster)
55763 *
55764 * @param array Array to splice
55765 * @param index Index of element in array to remove.
55766 * @param count Number of items to remove.
55767 */
55768
55769
55770function arraySplice(array, index, count) {
55771  const length = array.length - count;
55772
55773  while (index < length) {
55774    array[index] = array[index + count];
55775    index++;
55776  }
55777
55778  while (count--) {
55779    array.pop(); // shrink the array
55780  }
55781}
55782/**
55783 * Same as `Array.splice(index, 0, value)` but faster.
55784 *
55785 * `Array.splice()` is not fast because it has to allocate an array for the elements which were
55786 * removed. This causes memory pressure and slows down code when most of the time we don't
55787 * care about the deleted items array.
55788 *
55789 * @param array Array to splice.
55790 * @param index Index in array where the `value` should be added.
55791 * @param value Value to add to array.
55792 */
55793
55794
55795function arrayInsert(array, index, value) {
55796  ngDevMode && assertLessThanOrEqual(index, array.length, 'Can\'t insert past array end.');
55797  let end = array.length;
55798
55799  while (end > index) {
55800    const previousEnd = end - 1;
55801    array[end] = array[previousEnd];
55802    end = previousEnd;
55803  }
55804
55805  array[index] = value;
55806}
55807/**
55808 * Same as `Array.splice2(index, 0, value1, value2)` but faster.
55809 *
55810 * `Array.splice()` is not fast because it has to allocate an array for the elements which were
55811 * removed. This causes memory pressure and slows down code when most of the time we don't
55812 * care about the deleted items array.
55813 *
55814 * @param array Array to splice.
55815 * @param index Index in array where the `value` should be added.
55816 * @param value1 Value to add to array.
55817 * @param value2 Value to add to array.
55818 */
55819
55820
55821function arrayInsert2(array, index, value1, value2) {
55822  ngDevMode && assertLessThanOrEqual(index, array.length, 'Can\'t insert past array end.');
55823  let end = array.length;
55824
55825  if (end == index) {
55826    // inserting at the end.
55827    array.push(value1, value2);
55828  } else if (end === 1) {
55829    // corner case when we have less items in array than we have items to insert.
55830    array.push(value2, array[0]);
55831    array[0] = value1;
55832  } else {
55833    end--;
55834    array.push(array[end - 1], array[end]);
55835
55836    while (end > index) {
55837      const previousEnd = end - 2;
55838      array[end] = array[previousEnd];
55839      end--;
55840    }
55841
55842    array[index] = value1;
55843    array[index + 1] = value2;
55844  }
55845}
55846/**
55847 * Insert a `value` into an `array` so that the array remains sorted.
55848 *
55849 * NOTE:
55850 * - Duplicates are not allowed, and are ignored.
55851 * - This uses binary search algorithm for fast inserts.
55852 *
55853 * @param array A sorted array to insert into.
55854 * @param value The value to insert.
55855 * @returns index of the inserted value.
55856 */
55857
55858
55859function arrayInsertSorted(array, value) {
55860  let index = arrayIndexOfSorted(array, value);
55861
55862  if (index < 0) {
55863    // if we did not find it insert it.
55864    index = ~index;
55865    arrayInsert(array, index, value);
55866  }
55867
55868  return index;
55869}
55870/**
55871 * Remove `value` from a sorted `array`.
55872 *
55873 * NOTE:
55874 * - This uses binary search algorithm for fast removals.
55875 *
55876 * @param array A sorted array to remove from.
55877 * @param value The value to remove.
55878 * @returns index of the removed value.
55879 *   - positive index if value found and removed.
55880 *   - negative index if value not found. (`~index` to get the value where it should have been
55881 *     inserted)
55882 */
55883
55884
55885function arrayRemoveSorted(array, value) {
55886  const index = arrayIndexOfSorted(array, value);
55887
55888  if (index >= 0) {
55889    arraySplice(array, index, 1);
55890  }
55891
55892  return index;
55893}
55894/**
55895 * Get an index of an `value` in a sorted `array`.
55896 *
55897 * NOTE:
55898 * - This uses binary search algorithm for fast removals.
55899 *
55900 * @param array A sorted array to binary search.
55901 * @param value The value to look for.
55902 * @returns index of the value.
55903 *   - positive index if value found.
55904 *   - negative index if value not found. (`~index` to get the value where it should have been
55905 *     located)
55906 */
55907
55908
55909function arrayIndexOfSorted(array, value) {
55910  return _arrayIndexOfSorted(array, value, 0);
55911}
55912/**
55913 * Set a `value` for a `key`.
55914 *
55915 * @param keyValueArray to modify.
55916 * @param key The key to locate or create.
55917 * @param value The value to set for a `key`.
55918 * @returns index (always even) of where the value vas set.
55919 */
55920
55921
55922function keyValueArraySet(keyValueArray, key, value) {
55923  let index = keyValueArrayIndexOf(keyValueArray, key);
55924
55925  if (index >= 0) {
55926    // if we found it set it.
55927    keyValueArray[index | 1] = value;
55928  } else {
55929    index = ~index;
55930    arrayInsert2(keyValueArray, index, key, value);
55931  }
55932
55933  return index;
55934}
55935/**
55936 * Retrieve a `value` for a `key` (on `undefined` if not found.)
55937 *
55938 * @param keyValueArray to search.
55939 * @param key The key to locate.
55940 * @return The `value` stored at the `key` location or `undefined if not found.
55941 */
55942
55943
55944function keyValueArrayGet(keyValueArray, key) {
55945  const index = keyValueArrayIndexOf(keyValueArray, key);
55946
55947  if (index >= 0) {
55948    // if we found it retrieve it.
55949    return keyValueArray[index | 1];
55950  }
55951
55952  return undefined;
55953}
55954/**
55955 * Retrieve a `key` index value in the array or `-1` if not found.
55956 *
55957 * @param keyValueArray to search.
55958 * @param key The key to locate.
55959 * @returns index of where the key is (or should have been.)
55960 *   - positive (even) index if key found.
55961 *   - negative index if key not found. (`~index` (even) to get the index where it should have
55962 *     been inserted.)
55963 */
55964
55965
55966function keyValueArrayIndexOf(keyValueArray, key) {
55967  return _arrayIndexOfSorted(keyValueArray, key, 1);
55968}
55969/**
55970 * Delete a `key` (and `value`) from the `KeyValueArray`.
55971 *
55972 * @param keyValueArray to modify.
55973 * @param key The key to locate or delete (if exist).
55974 * @returns index of where the key was (or should have been.)
55975 *   - positive (even) index if key found and deleted.
55976 *   - negative index if key not found. (`~index` (even) to get the index where it should have
55977 *     been.)
55978 */
55979
55980
55981function keyValueArrayDelete(keyValueArray, key) {
55982  const index = keyValueArrayIndexOf(keyValueArray, key);
55983
55984  if (index >= 0) {
55985    // if we found it remove it.
55986    arraySplice(keyValueArray, index, 2);
55987  }
55988
55989  return index;
55990}
55991/**
55992 * INTERNAL: Get an index of an `value` in a sorted `array` by grouping search by `shift`.
55993 *
55994 * NOTE:
55995 * - This uses binary search algorithm for fast removals.
55996 *
55997 * @param array A sorted array to binary search.
55998 * @param value The value to look for.
55999 * @param shift grouping shift.
56000 *   - `0` means look at every location
56001 *   - `1` means only look at every other (even) location (the odd locations are to be ignored as
56002 *         they are values.)
56003 * @returns index of the value.
56004 *   - positive index if value found.
56005 *   - negative index if value not found. (`~index` to get the value where it should have been
56006 * inserted)
56007 */
56008
56009
56010function _arrayIndexOfSorted(array, value, shift) {
56011  ngDevMode && assertEqual(Array.isArray(array), true, 'Expecting an array');
56012  let start = 0;
56013  let end = array.length >> shift;
56014
56015  while (end !== start) {
56016    const middle = start + (end - start >> 1); // find the middle.
56017
56018    const current = array[middle << shift];
56019
56020    if (value === current) {
56021      return middle << shift;
56022    } else if (current > value) {
56023      end = middle;
56024    } else {
56025      start = middle + 1; // We already searched middle so make it non-inclusive by adding 1
56026    }
56027  }
56028
56029  return ~(end << shift);
56030}
56031/**
56032 * @license
56033 * Copyright Google LLC All Rights Reserved.
56034 *
56035 * Use of this source code is governed by an MIT-style license that can be
56036 * found in the LICENSE file at https://angular.io/license
56037 */
56038
56039/*
56040 * #########################
56041 * Attention: These Regular expressions have to hold even if the code is minified!
56042 * ##########################
56043 */
56044
56045/**
56046 * Regular expression that detects pass-through constructors for ES5 output. This Regex
56047 * intends to capture the common delegation pattern emitted by TypeScript and Babel. Also
56048 * it intends to capture the pattern where existing constructors have been downleveled from
56049 * ES2015 to ES5 using TypeScript w/ downlevel iteration. e.g.
56050 *
56051 * ```
56052 *   function MyClass() {
56053 *     var _this = _super.apply(this, arguments) || this;
56054 * ```
56055 *
56056 * downleveled to ES5 with `downlevelIteration` for TypeScript < 4.2:
56057 * ```
56058 *   function MyClass() {
56059 *     var _this = _super.apply(this, __spread(arguments)) || this;
56060 * ```
56061 *
56062 * or downleveled to ES5 with `downlevelIteration` for TypeScript >= 4.2:
56063 * ```
56064 *   function MyClass() {
56065 *     var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
56066 * ```
56067 *
56068 * More details can be found in: https://github.com/angular/angular/issues/38453.
56069 */
56070
56071
56072const ES5_DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*(arguments|(?:[^()]+\(\[\],)?[^()]+\(arguments\).*)\)/;
56073/** Regular expression that detects ES2015 classes which extend from other classes. */
56074
56075const ES2015_INHERITED_CLASS = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{/;
56076/**
56077 * Regular expression that detects ES2015 classes which extend from other classes and
56078 * have an explicit constructor defined.
56079 */
56080
56081const ES2015_INHERITED_CLASS_WITH_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(/;
56082/**
56083 * Regular expression that detects ES2015 classes which extend from other classes
56084 * and inherit a constructor.
56085 */
56086
56087const ES2015_INHERITED_CLASS_WITH_DELEGATE_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(\)\s*{[^}]*super\(\.\.\.arguments\)/;
56088/**
56089 * Determine whether a stringified type is a class which delegates its constructor
56090 * to its parent.
56091 *
56092 * This is not trivial since compiled code can actually contain a constructor function
56093 * even if the original source code did not. For instance, when the child class contains
56094 * an initialized instance property.
56095 */
56096
56097function isDelegateCtor(typeStr) {
56098  return ES5_DELEGATE_CTOR.test(typeStr) || ES2015_INHERITED_CLASS_WITH_DELEGATE_CTOR.test(typeStr) || ES2015_INHERITED_CLASS.test(typeStr) && !ES2015_INHERITED_CLASS_WITH_CTOR.test(typeStr);
56099}
56100
56101class ReflectionCapabilities {
56102  constructor(reflect) {
56103    this._reflect = reflect || _global['Reflect'];
56104  }
56105
56106  factory(t) {
56107    return (...args) => new t(...args);
56108  }
56109  /** @internal */
56110
56111
56112  _zipTypesAndAnnotations(paramTypes, paramAnnotations) {
56113    let result;
56114
56115    if (typeof paramTypes === 'undefined') {
56116      result = newArray(paramAnnotations.length);
56117    } else {
56118      result = newArray(paramTypes.length);
56119    }
56120
56121    for (let i = 0; i < result.length; i++) {
56122      // TS outputs Object for parameters without types, while Traceur omits
56123      // the annotations. For now we preserve the Traceur behavior to aid
56124      // migration, but this can be revisited.
56125      if (typeof paramTypes === 'undefined') {
56126        result[i] = [];
56127      } else if (paramTypes[i] && paramTypes[i] != Object) {
56128        result[i] = [paramTypes[i]];
56129      } else {
56130        result[i] = [];
56131      }
56132
56133      if (paramAnnotations && paramAnnotations[i] != null) {
56134        result[i] = result[i].concat(paramAnnotations[i]);
56135      }
56136    }
56137
56138    return result;
56139  }
56140
56141  _ownParameters(type, parentCtor) {
56142    const typeStr = type.toString(); // If we have no decorators, we only have function.length as metadata.
56143    // In that case, to detect whether a child class declared an own constructor or not,
56144    // we need to look inside of that constructor to check whether it is
56145    // just calling the parent.
56146    // This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
56147    // that sets 'design:paramtypes' to []
56148    // if a class inherits from another class but has no ctor declared itself.
56149
56150    if (isDelegateCtor(typeStr)) {
56151      return null;
56152    } // Prefer the direct API.
56153
56154
56155    if (type.parameters && type.parameters !== parentCtor.parameters) {
56156      return type.parameters;
56157    } // API of tsickle for lowering decorators to properties on the class.
56158
56159
56160    const tsickleCtorParams = type.ctorParameters;
56161
56162    if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
56163      // Newer tsickle uses a function closure
56164      // Retain the non-function case for compatibility with older tsickle
56165      const ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
56166      const paramTypes = ctorParameters.map(ctorParam => ctorParam && ctorParam.type);
56167      const paramAnnotations = ctorParameters.map(ctorParam => ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators));
56168      return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
56169    } // API for metadata created by invoking the decorators.
56170
56171
56172    const paramAnnotations = type.hasOwnProperty(PARAMETERS) && type[PARAMETERS];
56173
56174    const paramTypes = this._reflect && this._reflect.getOwnMetadata && this._reflect.getOwnMetadata('design:paramtypes', type);
56175
56176    if (paramTypes || paramAnnotations) {
56177      return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
56178    } // If a class has no decorators, at least create metadata
56179    // based on function.length.
56180    // Note: We know that this is a real constructor as we checked
56181    // the content of the constructor above.
56182
56183
56184    return newArray(type.length);
56185  }
56186
56187  parameters(type) {
56188    // Note: only report metadata if we have at least one class decorator
56189    // to stay in sync with the static reflector.
56190    if (!isType(type)) {
56191      return [];
56192    }
56193
56194    const parentCtor = getParentCtor(type);
56195
56196    let parameters = this._ownParameters(type, parentCtor);
56197
56198    if (!parameters && parentCtor !== Object) {
56199      parameters = this.parameters(parentCtor);
56200    }
56201
56202    return parameters || [];
56203  }
56204
56205  _ownAnnotations(typeOrFunc, parentCtor) {
56206    // Prefer the direct API.
56207    if (typeOrFunc.annotations && typeOrFunc.annotations !== parentCtor.annotations) {
56208      let annotations = typeOrFunc.annotations;
56209
56210      if (typeof annotations === 'function' && annotations.annotations) {
56211        annotations = annotations.annotations;
56212      }
56213
56214      return annotations;
56215    } // API of tsickle for lowering decorators to properties on the class.
56216
56217
56218    if (typeOrFunc.decorators && typeOrFunc.decorators !== parentCtor.decorators) {
56219      return convertTsickleDecoratorIntoMetadata(typeOrFunc.decorators);
56220    } // API for metadata created by invoking the decorators.
56221
56222
56223    if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {
56224      return typeOrFunc[ANNOTATIONS];
56225    }
56226
56227    return null;
56228  }
56229
56230  annotations(typeOrFunc) {
56231    if (!isType(typeOrFunc)) {
56232      return [];
56233    }
56234
56235    const parentCtor = getParentCtor(typeOrFunc);
56236    const ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
56237    const parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
56238    return parentAnnotations.concat(ownAnnotations);
56239  }
56240
56241  _ownPropMetadata(typeOrFunc, parentCtor) {
56242    // Prefer the direct API.
56243    if (typeOrFunc.propMetadata && typeOrFunc.propMetadata !== parentCtor.propMetadata) {
56244      let propMetadata = typeOrFunc.propMetadata;
56245
56246      if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
56247        propMetadata = propMetadata.propMetadata;
56248      }
56249
56250      return propMetadata;
56251    } // API of tsickle for lowering decorators to properties on the class.
56252
56253
56254    if (typeOrFunc.propDecorators && typeOrFunc.propDecorators !== parentCtor.propDecorators) {
56255      const propDecorators = typeOrFunc.propDecorators;
56256      const propMetadata = {};
56257      Object.keys(propDecorators).forEach(prop => {
56258        propMetadata[prop] = convertTsickleDecoratorIntoMetadata(propDecorators[prop]);
56259      });
56260      return propMetadata;
56261    } // API for metadata created by invoking the decorators.
56262
56263
56264    if (typeOrFunc.hasOwnProperty(PROP_METADATA)) {
56265      return typeOrFunc[PROP_METADATA];
56266    }
56267
56268    return null;
56269  }
56270
56271  propMetadata(typeOrFunc) {
56272    if (!isType(typeOrFunc)) {
56273      return {};
56274    }
56275
56276    const parentCtor = getParentCtor(typeOrFunc);
56277    const propMetadata = {};
56278
56279    if (parentCtor !== Object) {
56280      const parentPropMetadata = this.propMetadata(parentCtor);
56281      Object.keys(parentPropMetadata).forEach(propName => {
56282        propMetadata[propName] = parentPropMetadata[propName];
56283      });
56284    }
56285
56286    const ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
56287
56288    if (ownPropMetadata) {
56289      Object.keys(ownPropMetadata).forEach(propName => {
56290        const decorators = [];
56291
56292        if (propMetadata.hasOwnProperty(propName)) {
56293          decorators.push(...propMetadata[propName]);
56294        }
56295
56296        decorators.push(...ownPropMetadata[propName]);
56297        propMetadata[propName] = decorators;
56298      });
56299    }
56300
56301    return propMetadata;
56302  }
56303
56304  ownPropMetadata(typeOrFunc) {
56305    if (!isType(typeOrFunc)) {
56306      return {};
56307    }
56308
56309    return this._ownPropMetadata(typeOrFunc, getParentCtor(typeOrFunc)) || {};
56310  }
56311
56312  hasLifecycleHook(type, lcProperty) {
56313    return type instanceof Type && lcProperty in type.prototype;
56314  }
56315
56316}
56317
56318function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
56319  if (!decoratorInvocations) {
56320    return [];
56321  }
56322
56323  return decoratorInvocations.map(decoratorInvocation => {
56324    const decoratorType = decoratorInvocation.type;
56325    const annotationCls = decoratorType.annotationCls;
56326    const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
56327    return new annotationCls(...annotationArgs);
56328  });
56329}
56330
56331function getParentCtor(ctor) {
56332  const parentProto = ctor.prototype ? Object.getPrototypeOf(ctor.prototype) : null;
56333  const parentCtor = parentProto ? parentProto.constructor : null; // Note: We always use `Object` as the null value
56334  // to simplify checking later on.
56335
56336  return parentCtor || Object;
56337}
56338/**
56339 * @license
56340 * Copyright Google LLC All Rights Reserved.
56341 *
56342 * Use of this source code is governed by an MIT-style license that can be
56343 * found in the LICENSE file at https://angular.io/license
56344 */
56345
56346
56347const _THROW_IF_NOT_FOUND = {};
56348const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
56349/*
56350 * Name of a property (that we patch onto DI decorator), which is used as an annotation of which
56351 * InjectFlag this decorator represents. This allows to avoid direct references to the DI decorators
56352 * in the code, thus making them tree-shakable.
56353 */
56354
56355const DI_DECORATOR_FLAG = '__NG_DI_FLAG__';
56356const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
56357const NG_TOKEN_PATH = 'ngTokenPath';
56358const NEW_LINE = /\n/gm;
56359const NO_NEW_LINE = 'ɵ';
56360const SOURCE = '__source';
56361/**
56362 * Current injector value used by `inject`.
56363 * - `undefined`: it is an error to call `inject`
56364 * - `null`: `inject` can be called but there is no injector (limp-mode).
56365 * - Injector instance: Use the injector for resolution.
56366 */
56367
56368let _currentInjector = undefined;
56369
56370function setCurrentInjector(injector) {
56371  const former = _currentInjector;
56372  _currentInjector = injector;
56373  return former;
56374}
56375
56376function injectInjectorOnly(token, flags = InjectFlags.Default) {
56377  if (_currentInjector === undefined) {
56378    throw new RuntimeError(-203
56379    /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */
56380    , ngDevMode && `inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with \`EnvironmentInjector#runInContext\`.`);
56381  } else if (_currentInjector === null) {
56382    return injectRootLimpMode(token, undefined, flags);
56383  } else {
56384    return _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
56385  }
56386}
56387
56388function ɵɵinject(token, flags = InjectFlags.Default) {
56389  return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);
56390}
56391/**
56392 * Throws an error indicating that a factory function could not be generated by the compiler for a
56393 * particular class.
56394 *
56395 * The name of the class is not mentioned here, but will be in the generated factory function name
56396 * and thus in the stack trace.
56397 *
56398 * @codeGenApi
56399 */
56400
56401
56402function ɵɵinvalidFactoryDep(index) {
56403  throw new RuntimeError(202
56404  /* RuntimeErrorCode.INVALID_FACTORY_DEPENDENCY */
56405  , ngDevMode && `This constructor is not compatible with Angular Dependency Injection because its dependency at index ${index} of the parameter list is invalid.
56406This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
56407
56408Please check that 1) the type for the parameter at index ${index} is correct and 2) the correct Angular decorators are defined for this class and its ancestors.`);
56409}
56410/**
56411 * Injects a token from the currently active injector.
56412 * `inject` is only supported during instantiation of a dependency by the DI system. It can be used
56413 * during:
56414 * - Construction (via the `constructor`) of a class being instantiated by the DI system, such
56415 * as an `@Injectable` or `@Component`.
56416 * - In the initializer for fields of such classes.
56417 * - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
56418 * - In the `factory` function specified for an `InjectionToken`.
56419 *
56420 * @param token A token that represents a dependency that should be injected.
56421 * @param flags Optional flags that control how injection is executed.
56422 * The flags correspond to injection strategies that can be specified with
56423 * parameter decorators `@Host`, `@Self`, `@SkipSef`, and `@Optional`.
56424 * @returns the injected value if operation is successful, `null` otherwise.
56425 * @throws if called outside of a supported context.
56426 *
56427 * @usageNotes
56428 * In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a
56429 * field initializer:
56430 *
56431 * ```typescript
56432 * @Injectable({providedIn: 'root'})
56433 * export class Car {
56434 *   radio: Radio|undefined;
56435 *   // OK: field initializer
56436 *   spareTyre = inject(Tyre);
56437 *
56438 *   constructor() {
56439 *     // OK: constructor body
56440 *     this.radio = inject(Radio);
56441 *   }
56442 * }
56443 * ```
56444 *
56445 * It is also legal to call `inject` from a provider's factory:
56446 *
56447 * ```typescript
56448 * providers: [
56449 *   {provide: Car, useFactory: () => {
56450 *     // OK: a class factory
56451 *     const engine = inject(Engine);
56452 *     return new Car(engine);
56453 *   }}
56454 * ]
56455 * ```
56456 *
56457 * Calls to the `inject()` function outside of the class creation context will result in error. Most
56458 * notably, calls to `inject()` are disallowed after a class instance was created, in methods
56459 * (including lifecycle hooks):
56460 *
56461 * ```typescript
56462 * @Component({ ... })
56463 * export class CarComponent {
56464 *   ngOnInit() {
56465 *     // ERROR: too late, the component instance was already created
56466 *     const engine = inject(Engine);
56467 *     engine.start();
56468 *   }
56469 * }
56470 * ```
56471 *
56472 * @publicApi
56473 */
56474
56475
56476function inject(token, flags = InjectFlags.Default) {
56477  if (typeof flags !== 'number') {
vendor: 5,697 bytes, lines 56478-56687
56478    // While TypeScript doesn't accept it without a cast, bitwise OR with false-y values in
56479    // JavaScript is a no-op. We can use that for a very codesize-efficient conversion from
56480    // `InjectOptions` to `InjectFlags`.
56481    flags = 0
56482    /* InternalInjectFlags.Default */
56483    | ( // comment to force a line break in the formatter
56484    flags.optional && 8
56485    /* InternalInjectFlags.Optional */
56486    ) | (flags.host && 1
56487    /* InternalInjectFlags.Host */
56488    ) | (flags.self && 2
56489    /* InternalInjectFlags.Self */
56490    ) | (flags.skipSelf && 4
56491    /* InternalInjectFlags.SkipSelf */
56492    );
56493  }
56494
56495  return ɵɵinject(token, flags);
56496}
56497
56498function injectArgs(types) {
56499  const args = [];
56500
56501  for (let i = 0; i < types.length; i++) {
56502    const arg = resolveForwardRef(types[i]);
56503
56504    if (Array.isArray(arg)) {
56505      if (arg.length === 0) {
56506        throw new RuntimeError(900
56507        /* RuntimeErrorCode.INVALID_DIFFER_INPUT */
56508        , ngDevMode && 'Arguments array must have arguments.');
56509      }
56510
56511      let type = undefined;
56512      let flags = InjectFlags.Default;
56513
56514      for (let j = 0; j < arg.length; j++) {
56515        const meta = arg[j];
56516        const flag = getInjectFlag(meta);
56517
56518        if (typeof flag === 'number') {
56519          // Special case when we handle @Inject decorator.
56520          if (flag === -1
56521          /* DecoratorFlags.Inject */
56522          ) {
56523            type = meta.token;
56524          } else {
56525            flags |= flag;
56526          }
56527        } else {
56528          type = meta;
56529        }
56530      }
56531
56532      args.push(ɵɵinject(type, flags));
56533    } else {
56534      args.push(ɵɵinject(arg));
56535    }
56536  }
56537
56538  return args;
56539}
56540/**
56541 * Attaches a given InjectFlag to a given decorator using monkey-patching.
56542 * Since DI decorators can be used in providers `deps` array (when provider is configured using
56543 * `useFactory`) without initialization (e.g. `Host`) and as an instance (e.g. `new Host()`), we
56544 * attach the flag to make it available both as a static property and as a field on decorator
56545 * instance.
56546 *
56547 * @param decorator Provided DI decorator.
56548 * @param flag InjectFlag that should be applied.
56549 */
56550
56551
56552function attachInjectFlag(decorator, flag) {
56553  decorator[DI_DECORATOR_FLAG] = flag;
56554  decorator.prototype[DI_DECORATOR_FLAG] = flag;
56555  return decorator;
56556}
56557/**
56558 * Reads monkey-patched property that contains InjectFlag attached to a decorator.
56559 *
56560 * @param token Token that may contain monkey-patched DI flags property.
56561 */
56562
56563
56564function getInjectFlag(token) {
56565  return token[DI_DECORATOR_FLAG];
56566}
56567
56568function catchInjectorError(e, token, injectorErrorName, source) {
56569  const tokenPath = e[NG_TEMP_TOKEN_PATH];
56570
56571  if (token[SOURCE]) {
56572    tokenPath.unshift(token[SOURCE]);
56573  }
56574
56575  e.message = formatError('\n' + e.message, tokenPath, injectorErrorName, source);
56576  e[NG_TOKEN_PATH] = tokenPath;
56577  e[NG_TEMP_TOKEN_PATH] = null;
56578  throw e;
56579}
56580
56581function formatError(text, obj, injectorErrorName, source = null) {
56582  text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.slice(2) : text;
56583  let context = stringify(obj);
56584
56585  if (Array.isArray(obj)) {
56586    context = obj.map(stringify).join(' -> ');
56587  } else if (typeof obj === 'object') {
56588    let parts = [];
56589
56590    for (let key in obj) {
56591      if (obj.hasOwnProperty(key)) {
56592        let value = obj[key];
56593        parts.push(key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));
56594      }
56595    }
56596
56597    context = `{${parts.join(', ')}}`;
56598  }
56599
56600  return `${injectorErrorName}${source ? '(' + source + ')' : ''}[${context}]: ${text.replace(NEW_LINE, '\n  ')}`;
56601}
56602/**
56603 * @license
56604 * Copyright Google LLC All Rights Reserved.
56605 *
56606 * Use of this source code is governed by an MIT-style license that can be
56607 * found in the LICENSE file at https://angular.io/license
56608 */
56609
56610/**
56611 * Inject decorator and metadata.
56612 *
56613 * @Annotation
56614 * @publicApi
56615 */
56616
56617
56618const Inject = attachInjectFlag( // Disable tslint because `DecoratorFlags` is a const enum which gets inlined.
56619// tslint:disable-next-line: no-toplevel-property-access
56620makeParamDecorator('Inject', token => ({
56621  token
56622})), -1
56623/* DecoratorFlags.Inject */
56624);
56625/**
56626 * Optional decorator and metadata.
56627 *
56628 * @Annotation
56629 * @publicApi
56630 */
56631
56632const Optional = // Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
56633// tslint:disable-next-line: no-toplevel-property-access
56634attachInjectFlag(makeParamDecorator('Optional'), 8
56635/* InternalInjectFlags.Optional */
56636);
56637/**
56638 * Self decorator and metadata.
56639 *
56640 * @Annotation
56641 * @publicApi
56642 */
56643
56644const Self = // Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
56645// tslint:disable-next-line: no-toplevel-property-access
56646attachInjectFlag(makeParamDecorator('Self'), 2
56647/* InternalInjectFlags.Self */
56648);
56649/**
56650 * `SkipSelf` decorator and metadata.
56651 *
56652 * @Annotation
56653 * @publicApi
56654 */
56655
56656const SkipSelf = // Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
56657// tslint:disable-next-line: no-toplevel-property-access
56658attachInjectFlag(makeParamDecorator('SkipSelf'), 4
56659/* InternalInjectFlags.SkipSelf */
56660);
56661/**
56662 * Host decorator and metadata.
56663 *
56664 * @Annotation
56665 * @publicApi
56666 */
56667
56668const Host = // Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
56669// tslint:disable-next-line: no-toplevel-property-access
56670attachInjectFlag(makeParamDecorator('Host'), 1
56671/* InternalInjectFlags.Host */
56672);
56673/**
56674 * @license
56675 * Copyright Google LLC All Rights Reserved.
56676 *
56677 * Use of this source code is governed by an MIT-style license that can be
56678 * found in the LICENSE file at https://angular.io/license
56679 */
56680
56681let _reflect = null;
56682
56683function getReflect() {
56684  return _reflect = _reflect || new ReflectionCapabilities();
56685}
56686
56687function reflectDependencies(type) {
56688  return convertDependencies(getReflect().parameters(type));
56689}
56690
56691function convertDependencies(deps) {
56692  return deps.map(dep => reflectDependency(dep));
56693}
56694
56695function reflectDependency(dep) {
56696  const meta = {
56697    token: null,
56698    attribute: null,
56699    host: false,
56700    optional: false,
56701    self: false,
56702    skipSelf: false
56703  };
56704
56705  if (Array.isArray(dep) && dep.length > 0) {
56706    for (let j = 0; j < dep.length; j++) {
56707      const param = dep[j];
56708
56709      if (param === undefined) {
56710        // param may be undefined if type of dep is not set by ngtsc
56711        continue;
56712      }
56713
56714      const proto = Object.getPrototypeOf(param);
56715
56716      if (param instanceof Optional || proto.ngMetadataName === 'Optional') {
56717        meta.optional = true;
56718      } else if (param instanceof SkipSelf || proto.ngMetadataName === 'SkipSelf') {
56719        meta.skipSelf = true;
56720      } else if (param instanceof Self || proto.ngMetadataName === 'Self') {
56721        meta.self = true;
56722      } else if (param instanceof Host || proto.ngMetadataName === 'Host') {
56723        meta.host = true;
56724      } else if (param instanceof Inject) {
56725        meta.token = param.token;
56726      } else if (param instanceof Attribute) {
56727        if (param.attributeName === undefined) {
56728          throw new RuntimeError(204
56729          /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */
56730          , ngDevMode && `Attribute name must be defined.`);
56731        }
56732
56733        meta.attribute = param.attributeName;
56734      } else {
56735        meta.token = param;
56736      }
56737    }
56738  } else if (dep === undefined || Array.isArray(dep) && dep.length === 0) {
56739    meta.token = null;
56740  } else {
56741    meta.token = dep;
56742  }
56743
56744  return meta;
56745}
56746/**
56747 * @license
56748 * Copyright Google LLC All Rights Reserved.
56749 *
56750 * Use of this source code is governed by an MIT-style license that can be
56751 * found in the LICENSE file at https://angular.io/license
56752 */
56753
56754/**
56755 * Used to resolve resource URLs on `@Component` when used with JIT compilation.
56756 *
56757 * Example:
56758 * ```
56759 * @Component({
56760 *   selector: 'my-comp',
56761 *   templateUrl: 'my-comp.html', // This requires asynchronous resolution
56762 * })
56763 * class MyComponent{
56764 * }
56765 *
56766 * // Calling `renderComponent` will fail because `renderComponent` is a synchronous process
56767 * // and `MyComponent`'s `@Component.templateUrl` needs to be resolved asynchronously.
56768 *
56769 * // Calling `resolveComponentResources()` will resolve `@Component.templateUrl` into
56770 * // `@Component.template`, which allows `renderComponent` to proceed in a synchronous manner.
56771 *
56772 * // Use browser's `fetch()` function as the default resource resolution strategy.
56773 * resolveComponentResources(fetch).then(() => {
56774 *   // After resolution all URLs have been converted into `template` strings.
56775 *   renderComponent(MyComponent);
56776 * });
56777 *
56778 * ```
56779 *
56780 * NOTE: In AOT the resolution happens during compilation, and so there should be no need
56781 * to call this method outside JIT mode.
56782 *
56783 * @param resourceResolver a function which is responsible for returning a `Promise` to the
56784 * contents of the resolved URL. Browser's `fetch()` method is a good default implementation.
56785 */
56786
56787
56788function resolveComponentResources(resourceResolver) {
56789  // Store all promises which are fetching the resources.
56790  const componentResolved = []; // Cache so that we don't fetch the same resource more than once.
56791
56792  const urlMap = new Map();
56793
56794  function cachedResourceResolve(url) {
56795    let promise = urlMap.get(url);
56796
56797    if (!promise) {
56798      const resp = resourceResolver(url);
56799      urlMap.set(url, promise = resp.then(unwrapResponse));
56800    }
56801
56802    return promise;
56803  }
56804
56805  componentResourceResolutionQueue.forEach((component, type) => {
56806    const promises = [];
56807
56808    if (component.templateUrl) {
56809      promises.push(cachedResourceResolve(component.templateUrl).then(template => {
56810        component.template = template;
56811      }));
56812    }
56813
56814    const styleUrls = component.styleUrls;
56815    const styles = component.styles || (component.styles = []);
56816    const styleOffset = component.styles.length;
56817    styleUrls && styleUrls.forEach((styleUrl, index) => {
56818      styles.push(''); // pre-allocate array.
56819
56820      promises.push(cachedResourceResolve(styleUrl).then(style => {
56821        styles[styleOffset + index] = style;
56822        styleUrls.splice(styleUrls.indexOf(styleUrl), 1);
56823
56824        if (styleUrls.length == 0) {
56825          component.styleUrls = undefined;
56826        }
56827      }));
56828    });
56829    const fullyResolved = Promise.all(promises).then(() =>
56829 componentDefResolved(type));
56830    componentResolved.push(fullyResolved);
56831  });
56832  clearResolutionOfComponentResourcesQueue();
56833  return Promise.all(componentResolved).then(() => undefined);
56834}
56835
56836let componentResourceResolutionQueue = new Map(); // Track when existing ɵcmp for a Type is waiting on resources.
56837
56838const componentDefPendingResolution = new Set();
56839
56840function maybeQueueResolutionOfComponentResources(type, metadata) {
56841  if (componentNeedsResolution(metadata)) {
56842    componentResourceResolutionQueue.set(type, metadata);
56843    componentDefPendingResolution.add(type);
56844  }
56845}
56846
56847function isComponentDefPendingResolution(type) {
56848  return componentDefPendingResolution.has(type);
56849}
56850
56851function componentNeedsResolution(component) {
56852  return !!(component.templateUrl && !component.hasOwnProperty('template') || component.styleUrls && component.styleUrls.length);
56853}
56854
56855function clearResolutionOfComponentResourcesQueue() {
56856  const old = componentResourceResolutionQueue;
56857  componentResourceResolutionQueue = new Map();
56858  return old;
56859}
56860
56861function restoreComponentResolutionQueue(queue) {
56862  componentDefPendingResolution.clear();
56863  queue.forEach((_, type) => componentDefPendingResolution.add(type));
56864  componentResourceResolutionQueue = queue;
56865}
56866
56867function isComponentResourceResolutionQueueEmpty() {
56868  return componentResourceResolutionQueue.size === 0;
56869}
56870
56871function unwrapResponse(response) {
56872  return typeof response == 'string' ? response : response.text();
56873}
56874
56875function componentDefResolved(type) {
56876  componentDefPendingResolution.delete(type);
56877}
56878/**
56879 * @license
56880 * Copyright Google LLC All Rights Reserved.
56881 *
56882 * Use of this source code is governed by an MIT-style license that can be
56883 * found in the LICENSE file at https://angular.io/license
56884 */
56885
56886/**
56887 * Map of module-id to the corresponding NgModule.
56888 */
56889
56890
56891const modules = new Map();
56892/**
56893 * Whether to check for duplicate NgModule registrations.
56894 *
56895 * This can be disabled for testing.
56896 */
56897
56898let checkForDuplicateNgModules = true;
56899
56900function assertSameOrNotExisting(id, type, incoming) {
56901  if (type && type !== incoming && checkForDuplicateNgModules) {
56902    throw new Error(`Duplicate module registered for ${id} - ${stringify(type)} vs ${stringify(type.name)}`);
56903  }
56904}
56905/**
56906 * Adds the given NgModule type to Angular's NgModule registry.
56907 *
56908 * This is generated as a side-effect of NgModule compilation. Note that the `id` is passed in
56909 * explicitly and not read from the NgModule definition. This is for two reasons: it avoids a
56910 * megamorphic read, and in JIT there's a chicken-and-egg problem where the NgModule may not be
56911 * fully resolved when it's registered.
56912 *
56913 * @codeGenApi
56914 */
56915
56916
56917function registerNgModuleType(ngModuleType, id) {
56918  const existing = modules.get(id) || null;
56919  assertSameOrNotExisting(id, existing, ngModuleType);
56920  modules.set(id, ngModuleType);
56921}
56922
56923function clearModulesForTest() {
56924  modules.clear();
56925}
56926
56927function getRegisteredNgModuleType(id) {
56928  return modules.get(id);
56929}
56930/**
56931 * Control whether the NgModule registration system enforces that each NgModule type registered has
56932 * a unique id.
56933 *
56934 * This is useful for testing as the NgModule registry cannot be properly reset between tests with
56935 * Angular's current API.
56936 */
56937
56938
56939function setAllowDuplicateNgModuleIdsForTest(allowDuplicates) {
56940  checkForDuplicateNgModules = !allowDuplicates;
56941}
56942/**
56943 * @license
56944 * Copyright Google LLC All Rights Reserved.
56945 *
56946 * Use of this source code is governed by an MIT-style license that can be
56947 * found in the LICENSE file at https://angular.io/license
56948 */
56949
56950/**
56951 * Most of the use of `document` in Angular is from within the DI system so it is possible to simply
56952 * inject the `DOCUMENT` token and are done.
56953 *
56954 * Ivy is special because it does not rely upon the DI and must get hold of the document some other
56955 * way.
56956 *
56957 * The solution is to define `getDocument()` and `setDocument()` top-level functions for ivy.
56958 * Wherever ivy needs the global document, it calls `getDocument()` instead.
56959 *
56960 * When running ivy outside of a browser environment, it is necessary to call `setDocument()` to
56961 * tell ivy what the global `document` is.
56962 *
56963 * Angular does this for us in each of the standard platforms (`Browser`, `Server`, and `WebWorker`)
56964 * by calling `setDocument()` when providing the `DOCUMENT` token.
56965 */
56966
56967
56968let DOCUMENT = undefined;
56969/**
56970 * Tell ivy what the `document` is for this platform.
56971 *
56972 * It is only necessary to call this if the current platform is not a browser.
56973 *
56974 * @param document The object representing the global `document` in this environment.
56975 */
56976
56977function setDocument(document) {
56978  DOCUMENT = document;
56979}
56980/**
56981 * Access the object that represents the `document` for this platform.
56982 *
56983 * Ivy calls this whenever it needs to access the `document` object.
56984 * For example to create the renderer or to do sanitization.
56985 */
56986
56987
56988function getDocument() {
56989  if (DOCUMENT !== undefined) {
56990    return DOCUMENT;
56991  } else if (typeof document !== 'undefined') {
56992    return document;
56993  } // No "document" can be found. This should only happen if we are running iv
56993y outside Angular and
56994  // the current platform is not a browser. Since this is not a supported scenario at the moment
56995  // this should not happen in Angular apps.
56996  // Once we support running ivy outside of Angular we will need to publish `setDocument()` as a
56997  // public API. Meanwhile we just return `undefined` and let the application fail.
56998
56999
57000  return undefined;
57001}
57002/**
57003 * @license
57004 * Copyright Google LLC All Rights Reserved.
57005 *
57006 * Use of this source code is governed by an MIT-style license that can be
57007 * found in the LICENSE file at https://angular.io/license
57008 */
57009
57010/**
57011 * The Trusted Types policy, or null if Trusted Types are not
57012 * enabled/supported, or undefined if the policy has not been created yet.
57013 */
57014
57015
57016let policy$1;
57017/**
57018 * Returns the Trusted Types policy, or null if Trusted Types are not
57019 * enabled/supported. The first call to this function will create the policy.
57020 */
57021
57022function getPolicy$1() {
57023  if (policy$1 === undefined) {
57024    policy$1 = null;
57025
57026    if (_global.trustedTypes) {
57027      try {
57028        policy$1 = _global.trustedTypes.createPolicy('angular', {
57029          createHTML: s => s,
57030          createScript: s => s,
57031          createScriptURL: s => s
57032        });
57033      } catch {// trustedTypes.createPolicy throws if called with a name that is
57034        // already registered, even in report-only mode. Until the API changes,
57035        // catch the error not to break the applications functionally. In such
57036        // cases, the code will fall back to using strings.
57037      }
57038    }
57039  }
57040
57041  return policy$1;
57042}
57043/**
57044 * Unsafely promote a string to a TrustedHTML, falling back to strings when
57045 * Trusted Types are not available.
57046 * @security This is a security-sensitive function; any use of this function
57047 * must go through security review. In particular, it must be assured that the
57048 * provided string will never cause an XSS vulnerability if used in a context
57049 * that will be interpreted as HTML by a browser, e.g. when assigning to
57050 * element.innerHTML.
57051 */
57052
57053
57054function trustedHTMLFromString(html) {
57055  return getPolicy$1()?.createHTML(html) || html;
57056}
57057/**
57058 * Unsafely promote a string to a TrustedScript, falling back to strings when
57059 * Trusted Types are not available.
57060 * @security In particular, it must be assured that the provided string will
57061 * never cause an XSS vulnerability if used in a context that will be
57062 * interpreted and executed as a script by a browser, e.g. when calling eval.
57063 */
57064
57065
57066function trustedScriptFromString(script) {
57067  return getPolicy$1()?.createScript(script) || script;
57068}
57069/**
57070 * Unsafely promote a string to a TrustedScriptURL, falling back to strings
57071 * when Trusted Types are not available.
57072 * @security This is a security-sensitive function; any use of this function
57073 * must go through security review. In particular, it must be assured that the
57074 * provided string will never cause an XSS vulnerability if used in a context
57075 * that will cause a browser to load and execute a resource, e.g. when
57076 * assigning to script.src.
57077 */
57078
57079
57080function trustedScriptURLFromString(url) {
57081  return getPolicy$1()?.createScriptURL(url) || url;
57082}
57083/**
57084 * Unsafely call the Function constructor with the given string arguments. It
57085 * is only available in development mode, and should be stripped out of
57086 * production code.
57087 * @security This is a security-sensitive function; any use of this function
57088 * must go through security review. In particular, it must be assured that it
57089 * is only called from development code, as use in production code can lead to
57090 * XSS vulnerabilities.
57091 */
57092
57093
57094function newTrustedFunctionForDev(...args) {
57095  if (typeof ngDevMode === 'undefined') {
57096    throw new Error('newTrustedFunctionForDev should never be called in production');
57097  }
57098
57099  if (!_global.trustedTypes) {
57100    // In environments that don't support Trusted Types, fall back to the most
57101    // straightforward implementation:
57102    return new Function(...args);
57103  } // Chrome currently does not support passing TrustedScript to the Function
57104  // constructor. The following implements the workaround proposed on the page
57105  // below, where the Chromium bug is also referenced:
57106  // https://github.com/w3c/webappsec-trusted-types/wiki/Trusted-Types-for-function-constructor
57107
57108
57109  const fnArgs = args.slice(0, -1).join(',');
57110  const fnBody = args[args.length - 1];
57111  const body = `(function anonymous(${fnArgs}
57112) { ${fnBody}
57113})`; // Using eval directly confuses the compiler and prevents this module from
57114  // being stripped out of JS binaries even if not used. The global['eval']
57115  // indirection fixes that.
57116
57117  const fn = _global['eval'](trustedScriptFromString(body));
57118
57119  if (fn.bind === undefined) {
57120    // Workaround for a browser bug that only exists in Chrome 83, where passing
57121    // a TrustedScript to eval just returns the TrustedScript back without
57122    // evaluating it. In that case, fall back to the most straightforward
57123    // implementation:
57124    return new Function(...args);
57125  } // To completely mimic the behavior of calling "new Function", two more
57126  // things need to happen:
57127  // 1. Stringifying the resulting function should return its source code
57128
57129
57130  fn.toString = () => body; // 2. When calling the resulting function, `this` should refer to `global`
57131
57132
57133  return fn.bind(_global); // When Trusted Types support in Function constructors is widely available,
57134  // the implementation of this function can be simplified to:
57135  // return new Function(...args.map(a => trustedScriptFromString(a)));
57136}
57137/**
57138 * @license
57139 * Copyright Google LLC All Rights Reserved.
57140 *
57141 * Use of this source code is governed by an MIT-style license that can be
57142 * found in the LICENSE file at https://angular.io/license
57143 */
57144
57145/**
57146 * The Trusted Types policy, or null if Trusted Types are not
57147 * enabled/supported, or undefined if the policy has not been created yet.
57148 */
57149
57150
57151let policy;
57152/**
57153 * Returns the Trusted Types policy, or null if Trusted Types are not
57154 * enabled/supported. The first call to this function will create the policy.
57155 */
57156
57157function getPolicy() {
57158  if (policy === undefined) {
57159    policy = null;
57160
57161    if (_global.trustedTypes) {
57162      try {
57163        policy = _global.trustedTypes.createPolicy('angular#unsafe-bypass', {
57164          createHTML: s => s,
57165          createScript: s => s,
57166          createScriptURL: s => s
57167        });
57168      } catch {// trustedTypes.createPolicy throws if called with a name that is
57169        // already registered, even in report-only mode. Until the API changes,
57170        // catch the error not to break the applications functionally. In such
57171        // cases, the code will fall back to using strings.
57172      }
57173    }
57174  }
57175
57176  return policy;
57177}
57178/**
57179 * Unsafely promote a string to a TrustedHTML, falling back to strings when
57180 * Trusted Types are not available.
57181 * @security This is a security-sensitive function; any use of this function
57182 * must go through security review. In particular, it must be assured that it
57183 * is only passed strings that come directly from custom sanitizers or the
57184 * bypassSecurityTrust* functions.
57185 */
57186
57187
57188function trustedHTMLFromStringBypass(html) {
57189  return getPolicy()?.createHTML(html) || html;
57190}
57191/**
57192 * Unsafely promote a string to a TrustedScript, falling back to strings when
57193 * Trusted Types are not available.
57194 * @security This is a security-sensitive function; any use of this function
57195 * must go through security review. In particular, it must be assured that it
57196 * is only passed strings that come directly from custom sanitizers or the
57197 * bypassSecurityTrust* functions.
57198 */
57199
57200
57201function trustedScriptFromStringBypass(script) {
57202  return getPolicy()?.createScript(script) || script;
57203}
57204/**
57205 * Unsafely promote a string to a TrustedScriptURL, falling back to strings
57206 * when Trusted Types are not available.
57207 * @security This is a security-sensitive function; any use of this function
57208 * must go through security review. In particular, it must be assured that it
57209 * is only passed strings that come directly from custom sanitizers or the
57210 * bypassSecurityTrust* functions.
57211 */
57212
57213
57214function trustedScriptURLFromStringBypass(url) {
57215  return getPolicy()?.createScriptURL(url) || url;
57216}
57217/**
57218 * @license
57219 * Copyright Google LLC All Rights Reserved.
57220 *
57221 * Use of this source code is governed by an MIT-style license that can be
57222 * found in the LICENSE file at https://angular.io/license
57223 */
57224
57225
57226class SafeValueImpl {
57227  constructor(changingThisBreaksApplicationSecurity) {
57228    this.changingThisBreaksApplicationSecurity = changingThisBreaksApplicationSecurity;
57229  }
57230
57231  toString() {
57232    return `SafeValue must use [property]=binding: ${this.changingThisBreaksApplicationSecurity}` + ` (see https://g.co/ng/security#xss)`;
57233  }
57234
57235}
57236
57237class SafeHtmlImpl extends SafeValueImpl {
57238  getTypeName() {
57239    return "HTML"
57240    /* BypassType.Html */
57241    ;
57242  }
57243
57244}
57245
57246class SafeStyleImpl extends SafeValueImpl {
57247  getTypeName() {
57248    return "Style"
57249    /* BypassType.Style */
57250    ;
57251  }
57252
57253}
57254
57255class SafeScriptImpl extends SafeValueImpl {
57256  getTypeName() {
57257    return "Script"
57258    /* BypassType.Script */
57259    ;
57260  }
57261
57262}
57263
57264class SafeUrlImpl extends SafeValueImpl {
57265  getTypeName() {
57266    return "URL"
57267    /* BypassType.Url */
57268    ;
57269  }
57270
57271}
57272
57273class SafeResourceUrlImpl extends SafeValueImpl {
57274  getTypeName() {
57275    return "ResourceURL"
57276    /* BypassType.ResourceUrl */
57277    ;
57278  }
57279
57280}
57281
57282function unwrapSafeValue(value) {
57283  return value instanceof SafeValueImpl ? value.changingThisBreaksApplicationSecurity : value;
57284}
57285
57286function allowSanitizationBypassAndThrow(value, type) {
57287  const actualType = getSanitizationBypassType(value);
57288
57289  if (actualType != null && actualType !== type) {
57290    // Allow ResourceURLs in URL contexts, they are strictly more trusted.
57291    if (actualType === "ResourceURL"
57292    /* BypassType.ResourceUrl */
57293    && type === "URL"
57294    /* BypassType.Url */
57295    ) return true;
57296    throw new Error(`Required a safe ${type}, got a ${actualType} (see https://g.co/ng/security#xss)`);
57297  }
57298
57299  return actualType === type;
57300}
57301
57302function getSanitizationBypassType(value) {
57303  return value instanceof SafeValueImpl && value.getTypeName() || null;
57304}
57305/**
57306 * Mark `html` string as trusted.
57307 *
57308 * This function wraps the trusted string in `String` and brands it in a way which makes it
57309 * recognizable to {@link htmlSanitizer} to be trusted implicitly.
57310 *
57311 * @param trustedHtml `html` string which needs to be implicitly trusted.
57312 * @returns a `html` which has been branded to be implicitly trusted.
57313 */
57314
57315
57316function bypassSanitizationTrustHtml(trustedHtml) {
57317  return new SafeHtmlImpl(trustedHtml);
57318}
57319/**
57320 * Mark `style` string as trusted.
57321 *
57322 * This function wraps the trusted string in `String` and brands it in a way which makes it
57323 * recognizable to {@link styleSanitizer} to be trusted implicitly.
57324 *
57325 * @param trustedStyle `style` string which needs to be implicitly trusted.
57326 * @returns a `style` hich has been branded to be implicitly trusted.
57327 */
57328
57329
57330function bypassSanitizationTrustStyle(trustedStyle) {
57331  return new SafeStyleImpl(trustedStyle);
57332}
57333/**
57334 * Mark `script` string as trusted.
57335 *
57336 * This function wraps the trusted string in `String` and brands it in a way which makes it
57337 * recognizable to {@link scriptSanitizer} to be trusted implicitly.
57338 *
57339 * @param trustedScript `script` string which needs to be implicitly trusted.
57340 * @returns a `script` which has been branded to be implicitly trusted.
57341 */
57342
57343
57344function bypassSanitizationTrustScript(trustedScript) {
57345  return new SafeScriptImpl(trustedScript);
57346}
57347/**
57348 * Mark `url` string as trusted.
57349 *
57350 * This function wraps the trusted string in `String` and brands it in a way which makes it
57351 * recognizable to {@link urlSanitizer} to be trusted implicitly.
57352 *
57353 * @param trustedUrl `url` string which needs to be implicitly trusted.
57354 * @returns a `url`  which has been branded to be implicitly trusted.
57355 */
57356
57357
57358function bypassSanitizationTrustUrl(trustedUrl) {
57359  return new SafeUrlImpl(trustedUrl);
57360}
57361/**
57362 * Mark `url` string as trusted.
57363 *
57364 * This function wraps the trusted string in `String` and brands it in a way which makes it
57365 * recognizable to {@link resourceUrlSanitizer} to be trusted implicitly.
57366 *
57367 * @param trustedResourceUrl `url` string which needs to be implicitly trusted.
57368 * @returns a `url` which has been branded to be implicitly trusted.
57369 */
57370
57371
57372function bypassSanitizationTrustResourceUrl(trustedResourceUrl) {
57373  return new SafeResourceUrlImpl(trustedResourceUrl);
57374}
57375/**
57376 * @license
57377 * Copyright Google LLC All Rights Reserved.
57378 *
57379 * Use of this source code is governed by an MIT-style license that can be
57380 * found in the LICENSE file at https://angular.io/license
57381 */
57382
57383/**
57384 * This helper is used to get hold of an inert tree of DOM elements containing dirty HTML
57385 * that needs sanitizing.
57386 * Depending upon browser support we use one of two strategies for doing this.
57387 * Default: DOMParser strategy
57388 * Fallback: InertDocument strategy
57389 */
57390
57391
57392function getInertBodyHelper(defaultDoc) {
57393  const inertDocumentHelper = new InertDocumentHelper(defaultDoc);
57394  return isDOMParserAvailable() ? new DOMParserHelper(inertDocumentHelper) : inertDocumentHelper;
57395}
57396/**
57397 * Uses DOMParser to create and fill an inert body element.
57398 * This is the default strategy used in browsers that support it.
57399 */
57400
57401
57402class DOMParserHelper {
57403  constructor(inertDocumentHelper) {
57404    this.inertDocumentHelper = inertDocumentHelper;
57405  }
57406
57407  getInertBodyElement(html) {
57408    // We add these extra elements to ensure that the rest of the content is parsed as expected
57409    // e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the
57410    // `<head>` tag. Note that the `<body>` tag is closed implicitly to prevent unclosed tags
57411    // in `html` from consuming the otherwise explicit `</body>` tag.
57412    html = '<body><remove></remove>' + html;
57413
57414    try {
57415      const body = new window.DOMParser().parseFromString(trustedHTMLFromString(html), 'text/html').body;
57416
57417      if (body === null) {
57418        // In some browsers (e.g. Mozilla/5.0 iPad AppleWebKit Mobile) the `body` property only
57419        // becomes available in the following tick of the JS engine. In that case we fall back to
57420        // the `inertDocumentHelper` instead.
57421        return this.inertDocumentHelper.getInertBodyElement(html);
57422      }
57423
57424      body.removeChild(body.firstChild);
57425      return body;
57426    } catch {
57427      return null;
57428    }
57429  }
57430
57431}
57432/**
57433 * Use an HTML5 `template` element, if supported, or an inert body element created via
57434 * `createHtmlDocument` to create and fill an inert DOM element.
57435 * This is the fallback strategy if the browser does not support DOMParser.
57436 */
57437
57438
57439class InertDocumentHelper {
57440  constructor(defaultDoc) {
57441    this.defaultDoc = defaultDoc;
57442    this.inertDocument = this.defaultDoc.implementation.createHTMLDocument('sanitization-inert');
57443
57444    if (this.inertDocument.body == null) {
57445      // usually there should be only one body element in the document, but IE doesn't have any, so
57446      // we need to create one.
57447      const inertHtml = this.inertDocument.createElement('html');
57448      this.inertDocument.appendChild(inertHtml);
57449      const inertBodyElement = this.inertDocument.createElement('body');
57450      inertHtml.appendChild(inertBodyElement);
57451    }
57452  }
57453
57454  getInertBodyElement(html) {
57455    // Prefer using <template> element if supported.
57456    const templateEl = this.inertDocument.createElement('template');
57457
57458    if ('content' in templateEl) {
57459      templateEl.innerHTML = trustedHTMLFromString(html);
57460      return templateEl;
57461    } // Note that previously we used to do something like `this.inertDocument.body.innerHTML = html`
57462    // and we returned the inert `body` node. This was changed, because IE seems to treat setting
57463    // `innerHTML` on an inserted element differently, compared to one that hasn't been inserted
57464    // yet. In particular, IE appears to split some of the text into multiple text nodes rather
57465    // than keeping them in a single one which ends up messing with Ivy's i18n parsing further
57466    // down the line. This has been worked around by creating a new inert `body` and using it as
57467    // the root node in which we insert the HTML.
57468
57469
57470    const inertBody = this.inertDocument.createElement('body');
57471    inertBody.innerHTML = trustedHTMLFromString(html); // Support: IE 11 only
57472    // strip custom-namespaced attributes on IE<=11
57473
57474    if (this.defaultDoc.documentMode) {
57475      this.stripCustomNsAttrs(inertBody);
57476    }
57477
57478    return inertBody;
57479  }
57480  /**
57481   * When IE11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1'
57482   * attribute to declare ns1 namespace and prefixes the attribute with 'ns1' (e.g.
57483   * 'ns1:xlink:foo').
57484   *
57485   * This is undesirable since we don't want to allow any of these custom attributes. This method
57486   * strips them all.
57487   */
57488
57489
57490  stripCustomNsAttrs(el) {
57491    const elAttrs = el.attributes; // loop backwards so that we can support removals.
57492
57493    for (let i = elAttrs.length - 1; 0 < i; i--) {
57494      const attrib = elAttrs.item(i);
57495      const attrName = attrib.name;
57496
57497      if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) {
57498        el.removeAttribute(attrName);
57499      }
57500    }
57501
57502    let childNode = el.firstChild;
57503
57504    while (childNode) {
57505      if (childNode.nodeType === Node.ELEMENT_NODE) this.stripCustomNsAttrs(childNode);
57506      childNode = childNode.nextSibling;
57507    }
57508  }
57509
57510}
57511/**
57512 * We need to determine whether the DOMParser exists in the global context and
57513 * supports parsing HTML; HTML parsing support is not as wide as other formats, see
57514 * https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Browser_compatibility.
57515 *
57516 * @suppress {uselessCode}
57517 */
57518
57519
57520function isDOMParserAvailable() {
57521  try {
57522    return !!new window.DOMParser().parseFromString(trustedHTMLFromString(''), 'text/html');
57523  } catch {
57524    return false;
57525  }
57526}
57527/**
57528 * @license
57529 * Copyright Google LLC All Rights Reserved.
57530 *
57531 * Use of this source code is governed by an MIT-style license that can be
57532 * found in the LICENSE file at https://angular.io/license
57533 */
57534
57535/**
57536 * A pattern that recognizes a commonly useful subset of URLs that are safe.
57537 *
57538 * This regular expression matches a subset of URLs that will not cause script
57539 * execution if used in URL context within a HTML document. Specifically, this
57540 * regular expression matches if (comment from here on and regex copied from
57541 * Soy's EscapingConventions):
57542 * (1) Either an allowed protocol (http, https, mailto or ftp).
57543 * (2) or no protocol.  A protocol must be followed by a colon. The below
57544 *     allows that by allowing colons only after one of the characters [/?#].
57545 *     A colon after a hash (#) must be in the fragment.
57546 *     Otherwise, a colon after a (?) must be in a query.
57547 *     Otherwise, a colon after a single solidus (/) must be in a path.
57548 *     Otherwise, a colon after a double solidus (//) must be in the authority
57549 *     (before port).
57550 *
57551 * The pattern disallows &, used in HTML entity declarations before
57552 * one of the characters in [/?#]. This disallows HTML entities used in the
57553 * protocol name, which should never happen, e.g. "h&#116;tp" for "http".
57554 * It also disallows HTML entities in the first path part of a relative path,
57555 * e.g. "foo&lt;bar/baz".  Our existing escaping functions should not produce
57556 * that. More importantly, it disallows masking of a colon,
57557 * e.g. "javascript&#58;...".
57558 *
57559 * This regular expression was taken from the Closure sanitization library.
57560 */
57561
57562
57563const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|data|ftp|tel|file|sms):|[^&:/?#]*(?:[/?#]|$))/gi;
57564
57565function _sanitizeUrl(url) {
57566  url = String(url);
57567  if (url.match(SAFE_URL_PATTERN)) return url;
57568
57569  if (typeof ngDevMode === 'undefined' || ngDevMode) {
57570    console.warn(`WARNING: sanitizing unsafe URL value ${url} (see https://g.co/ng/security#xss)`);
57571  }
57572
57573  return 'unsafe:' + url;
57574}
57575/**
57576 * @license
57577 * Copyright Google LLC All Rights Reserved.
57578 *
57579 * Use of this source code is governed by an MIT-style license that can be
57580 * found in the LICENSE file at https://angular.io/license
57581 */
57582
57583
57584function tagSet(tags) {
57585  const res = {};
57586
57587  for (const t of tags.split(',')) res[t] = true;
57588
57589  return res;
57590}
57591
57592function merge(...sets) {
57593  const res = {};
57594
57595  for (const s of sets) {
57596    for (const v in s) {
57597      if (s.hasOwnProperty(v)) res[v] = true;
57598    }
57599  }
57600
57601  return res;
57602} // Good source of info about elements and attributes
57603// https://html.spec.whatwg.org/#semantics
57604// https://simon.html5.org/html-elements
57605// Safe Void Elements - HTML5
57606// https://html.spec.whatwg.org/#void-elements
57607
57608
57609const VOID_ELEMENTS = tagSet('area,br,col,hr,img,wbr'); // Elements that you can, intentionally, leave open (and which close themselves)
57610// https://html.spec.whatwg.org/#optional-tags
57611
57612const OPTIONAL_END_TAG_BLOCK_ELEMENTS = tagSet('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr');
57613const OPTIONAL_END_TAG_INLINE_ELEMENTS = tagSet('rp,rt');
57614const OPTIONAL_END_TAG_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, OPTIONAL_END_TAG_BLOCK_ELEMENTS); // Safe Block Elements - HTML5
57615
57616const BLOCK_ELEMENTS = merge(OPTIONAL_END_TAG_BLOCK_ELEMENTS, tagSet('address,article,' + 'aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' + 'h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul')); // Inline Elements - HTML5
57617
57618const INLINE_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, tagSet('a,abbr,acronym,audio,b,' + 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,' + 'samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video'));
57619const VALID_ELEMENTS = merge(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS); // Attributes that have href and hence need to be sanitized
57620
57621const URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href');
57622const HTML_ATTRS = tagSet('abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' + 'compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,' + 'ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,' + 'scope,scrolling,shape,size,sizes,span,srclang,srcset,start,summary,tabindex,target,title,translate,type,usemap,' + 'valign,value,vspace,width'); // Accessibility attributes as per WAI-ARIA 1.1 (W3C Working Draft 14 December 2018)
57623
57624const ARIA_ATTRS = tagSet('aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,' + 'aria-colspan,aria-controls,aria-current,aria-describedby,aria-details,aria-disabled,aria-dropeffect,' + 'aria-errormessage,aria-expanded,aria-flowto,aria-grabbed,aria-haspopup,aria-hidden,aria-invalid,' + 'aria-keyshortcuts,aria-label,aria-labelledby,aria-level,aria-live,aria-modal,aria-multiline,' + 'aria-multiselectable,aria-orientation,aria-owns,aria-placeholder,aria-posinset,aria-pressed,aria-readonly,' + 'aria-relevant,aria-required,aria-roledescription,aria-rowcount,aria-rowindex,aria-rowspan,aria-selected,' + 'aria-setsize,aria-sort,aria-valuemax,aria-valuemin,aria-valuenow,aria-valuetext'); // NB: This currently consciously doesn't support SVG. SVG sanitization has had several security
57625// issues in the past, so it seems safer to leave it out if possible. If support for binding SVG via
57626// innerHTML is required, SVG attributes should be added here.
57627// NB: Sanitization does not allow <form> elements or other active elements (<button> etc). Those
57628// can be sanitized, but they increase security surface area without a legitimate use case, so they
57629// are left out here.
57630
57631const VALID_ATTRS = merge(URI_ATTRS, HTML_ATTRS, ARIA_ATTRS); // Elements whose content should not be traversed/preserved, if the elements themselves are invalid.
57632//
57633// Typically, `<invalid>Some content</invalid>` would traverse (and in this case preserve)
57634// `Some content`, but strip `invalid-element` opening/closing tags. For some elements, though, we
57635// don't want to preserve the content, if the elements themselves are going to be removed.
57636
57637const SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS = tagSet('script,style,template');
57638/**
57639 * SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
57640 * attributes.
57641 */
57642
57643class SanitizingHtmlSerializer {
57644  constructor() {
57645    // Explicitly track if something was stripped, to avoid accidentally warning of sanitization just
57646    // because characters were re-encoded.
57647    this.sanitizedSomething = false;
57648    this.buf = [];
57649  }
57650
57651  sanitizeChildren(el) {
57652    // This cannot use a TreeWalker, as it has to run on Angular's various DOM adapters.
57653    // However this code never accesses properties off of `document` before deleting its contents
57654    // again, so it shouldn't be vulnerable to DOM clobbering.
57655    let current = el.firstChild;
57656    let traverseContent = true;
57657
57658    while (current) {
57659      if (current.nodeType === Node.ELEMENT_NODE) {
57660        traverseContent = this.startElement(current);
57661      } else if (current.nodeType === Node.TEXT_NODE) {
57662        this.chars(current.nodeValue);
57663      } else {
57664        // Strip non-element, non-text nodes.
57665        this.sanitizedSomething = true;
57666      }
57667
57668      if (traverseContent && current.firstChild) {
57669        current = current.firstChild;
57670        continue;
57671      }
57672
57673      while (current) {
57674        // Leaving the element. Walk up and to the right, closing tags as we go.
57675        if (current.nodeType === Node.ELEMENT_NODE) {
57676          this.endElement(current);
57677        }
57678
57679        let next = this.checkClobberedElement(current, current.nextSibling);
57680
57681        if (next) {
57682          current = next;
57683          break;
57684        }
57685
57686        current = this.checkClobberedElement(current, current.parentNode);
57687      }
57688    }
57689
57690    return this.buf.join('');
57691  }
57692  /**
57693   * Sanitizes an opening element tag (if valid) and returns whether the element's contents should
57694   * be traversed. Element content must always be traversed (even if the element itself is not
57695   * valid/safe), unless the element is one of `SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS`.
57696   *
57697   * @param element The element to sanitize.
57698   * @return True if the element's contents should be traversed.
57699   */
57700
57701
57702  startElement(element) {
57703    const tagName = element.nodeName.toLowerCase();
57704
57705    if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
57706      this.sanitizedSomething = true;
57707      return !SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS.hasOwnProperty(tagName);
57708    }
57709
57710    this.buf.push('<');
57711    this.buf.push(tagName);
57712    const elAttrs = element.attributes;
57713
57714    for (let i = 0; i < elAttrs.length; i++) {
57715      const elAttr = elAttrs.item(i);
57716      const attrName = elAttr.name;
57717      const lower = attrName.toLowerCase();
57718
57719      if (!VALID_ATTRS.hasOwnProperty(lower)) {
57720        this.sanitizedSomething = true;
57721        continue;
57722      }
57723
57724      let value = elAttr.value; // TODO(martinprobst): Special case image URIs for data:image/...
57725
57726      if (URI_ATTRS[lower]) value = _sanitizeUrl(value);
57727      this.buf.push(' ', attrName, '="', encodeEntities(value), '"');
57728    }
57729
57730    this.buf.push('>');
57731    return true;
57732  }
57733
57734  endElement(current) {
57735    const tagName = current.nodeName.toLowerCase();
57736
57737    if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
57738      this.buf.push('</');
57739      this.buf.push(tagName);
57740      this.buf.push('>');
57741    }
57742  }
57743
57744  chars(chars) {
57745    this.buf.push(encodeEntities(chars));
57746  }
57747
57748  checkClobberedElement(node, nextNode) {
57749    if (nextNode && (node.compareDocumentPosition(nextNode) & Node.DOCUMENT_POSITION_CONTAINED_BY) === Node.DOCUMENT_POSITION_CONTAINED_BY) {
57750      throw new Error(`Failed to sanitize html because the element is clobbered: ${node.outerHTML}`);
57751    }
57752
57753    return nextNode;
57754  }
57755
57756} // Regular Expressions for parsing tags and attributes
57757
57758
57759const SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; // ! to ~ is the ASCII range.
57760
57761const NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g;
57762/**
57763 * Escapes all potentially dangerous characters, so that the
57764 * resulting string can be safely inserted into attribute or
57765 * element text.
57766 * @param value
57767 */
57768
57769function encodeEntities(value) {
57770  return value.replace(/&/g, '&amp;').replace(SURROGATE_PAIR_REGEXP, function (match) {
vendor: 13,587 bytes, lines 57771-58170
57771    const hi = match.charCodeAt(0);
57772    const low = match.charCodeAt(1);
57773    return '&#' + ((hi - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000) + ';';
57774  }).replace(NON_ALPHANUMERIC_REGEXP, function (match) {
57775    return '&#' + match.charCodeAt(0) + ';';
57776  }).replace(/</g, '&lt;').replace(/>/g, '&gt;');
57777}
57778
57779let inertBodyHelper;
57780/**
57781 * Sanitizes the given unsafe, untrusted HTML fragment, and returns HTML text that is safe to add to
57782 * the DOM in a browser environment.
57783 */
57784
57785function _sanitizeHtml(defaultDoc, unsafeHtmlInput) {
57786  let inertBodyElement = null;
57787
57788  try {
57789    inertBodyHelper = inertBodyHelper || getInertBodyHelper(defaultDoc); // Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime).
57790
57791    let unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : '';
57792    inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml); // mXSS protection. Repeatedly parse the document to make sure it stabilizes, so that a browser
57793    // trying to auto-correct incorrect HTML cannot cause formerly inert HTML to become dangerous.
57794
57795    let mXSSAttempts = 5;
57796    let parsedHtml = unsafeHtml;
57797
57798    do {
57799      if (mXSSAttempts === 0) {
57800        throw new Error('Failed to sanitize html because the input is unstable');
57801      }
57802
57803      mXSSAttempts--;
57804      unsafeHtml = parsedHtml;
57805      parsedHtml = inertBodyElement.innerHTML;
57806      inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
57807    } while (unsafeHtml !== parsedHtml);
57808
57809    const sanitizer = new SanitizingHtmlSerializer();
57810    const safeHtml = sanitizer.sanitizeChildren(getTemplateContent(inertBodyElement) || inertBodyElement);
57811
57812    if ((typeof ngDevMode === 'undefined' || ngDevMode) && sanitizer.sanitizedSomething) {
57813      console.warn('WARNING: sanitizing HTML stripped some content, see https://g.co/ng/security#xss');
57814    }
57815
57816    return trustedHTMLFromString(safeHtml);
57817  } finally {
57818    // In case anything goes wrong, clear out inertElement to reset the entire DOM structure.
57819    if (inertBodyElement) {
57820      const parent = getTemplateContent(inertBodyElement) || inertBodyElement;
57821
57822      while (parent.firstChild) {
57823        parent.removeChild(parent.firstChild);
57824      }
57825    }
57826  }
57827}
57828
57829function getTemplateContent(el) {
57830  return 'content' in el
57831  /** Microsoft/TypeScript#21517 */
57832  && isTemplateElement(el) ? el.content : null;
57833}
57834
57835function isTemplateElement(el) {
57836  return el.nodeType === Node.ELEMENT_NODE && el.nodeName === 'TEMPLATE';
57837}
57838/**
57839 * @license
57840 * Copyright Google LLC All Rights Reserved.
57841 *
57842 * Use of this source code is governed by an MIT-style license that can be
57843 * found in the LICENSE file at https://angular.io/license
57844 */
57845
57846/**
57847 * A SecurityContext marks a location that has dangerous security implications, e.g. a DOM property
57848 * like `innerHTML` that could cause Cross Site Scripting (XSS) security bugs when improperly
57849 * handled.
57850 *
57851 * See DomSanitizer for more details on security in Angular applications.
57852 *
57853 * @publicApi
57854 */
57855
57856
57857var SecurityContext;
57858
57859(function (SecurityContext) {
57860  SecurityContext[SecurityContext["NONE"] = 0] = "NONE";
57861  SecurityContext[SecurityContext["HTML"] = 1] = "HTML";
57862  SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE";
57863  SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
57864  SecurityContext[SecurityContext["URL"] = 4] = "URL";
57865  SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
57866})(SecurityContext || (SecurityContext = {}));
57867/**
57868 * @license
57869 * Copyright Google LLC All Rights Reserved.
57870 *
57871 * Use of this source code is governed by an MIT-style license that can be
57872 * found in the LICENSE file at https://angular.io/license
57873 */
57874
57875/**
57876 * An `html` sanitizer which converts untrusted `html` **string** into trusted string by removing
57877 * dangerous content.
57878 *
57879 * This method parses the `html` and locates potentially dangerous content (such as urls and
57880 * javascript) and removes it.
57881 *
57882 * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustHtml}.
57883 *
57884 * @param unsafeHtml untrusted `html`, typically from the user.
57885 * @returns `html` string which is safe to display to user, because all of the dangerous javascript
57886 * and urls have been removed.
57887 *
57888 * @codeGenApi
57889 */
57890
57891
57892function ɵɵsanitizeHtml(unsafeHtml) {
57893  const sanitizer = getSanitizer();
57894
57895  if (sanitizer) {
57896    return trustedHTMLFromStringBypass(sanitizer.sanitize(SecurityContext.HTML, unsafeHtml) || '');
57897  }
57898
57899  if (allowSanitizationBypassAndThrow(unsafeHtml, "HTML"
57900  /* BypassType.Html */
57901  )) {
57902    return trustedHTMLFromStringBypass(unwrapSafeValue(unsafeHtml));
57903  }
57904
57905  return _sanitizeHtml(getDocument(), renderStringify(unsafeHtml));
57906}
57907/**
57908 * A `style` sanitizer which converts untrusted `style` **string** into trusted string by removing
57909 * dangerous content.
57910 *
57911 * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustStyle}.
57912 *
57913 * @param unsafeStyle untrusted `style`, typically from the user.
57914 * @returns `style` string which is safe to bind to the `style` properties.
57915 *
57916 * @codeGenApi
57917 */
57918
57919
57920function ɵɵsanitizeStyle(unsafeStyle) {
57921  const sanitizer = getSanitizer();
57922
57923  if (sanitizer) {
57924    return sanitizer.sanitize(SecurityContext.STYLE, unsafeStyle) || '';
57925  }
57926
57927  if (allowSanitizationBypassAndThrow(unsafeStyle, "Style"
57928  /* BypassType.Style */
57929  )) {
57930    return unwrapSafeValue(unsafeStyle);
57931  }
57932
57933  return renderStringify(unsafeStyle);
57934}
57935/**
57936 * A `url` sanitizer which converts untrusted `url` **string** into trusted string by removing
57937 * dangerous
57938 * content.
57939 *
57940 * This method parses the `url` and locates potentially dangerous content (such as javascript) and
57941 * removes it.
57942 *
57943 * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustUrl}.
57944 *
57945 * @param unsafeUrl untrusted `url`, typically from the user.
57946 * @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
57947 * all of the dangerous javascript has been removed.
57948 *
57949 * @codeGenApi
57950 */
57951
57952
57953function ɵɵsanitizeUrl(unsafeUrl) {
57954  const sanitizer = getSanitizer();
57955
57956  if (sanitizer) {
57957    return sanitizer.sanitize(SecurityContext.URL, unsafeUrl) || '';
57958  }
57959
57960  if (allowSanitizationBypassAndThrow(unsafeUrl, "URL"
57961  /* BypassType.Url */
57962  )) {
57963    return unwrapSafeValue(unsafeUrl);
57964  }
57965
57966  return _sanitizeUrl(renderStringify(unsafeUrl));
57967}
57968/**
57969 * A `url` sanitizer which only lets trusted `url`s through.
57970 *
57971 * This passes only `url`s marked trusted by calling {@link bypassSanitizationTrustResourceUrl}.
57972 *
57973 * @param unsafeResourceUrl untrusted `url`, typically from the user.
57974 * @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
57975 * only trusted `url`s have been allowed to pass.
57976 *
57977 * @codeGenApi
57978 */
57979
57980
57981function ɵɵsanitizeResourceUrl(unsafeResourceUrl) {
57982  const sanitizer = getSanitizer();
57983
57984  if (sanitizer) {
57985    return trustedScriptURLFromStringBypass(sanitizer.sanitize(SecurityContext.RESOURCE_URL, unsafeResourceUrl) || '');
57986  }
57987
57988  if (allowSanitizationBypassAndThrow(unsafeResourceUrl, "ResourceURL"
57989  /* BypassType.ResourceUrl */
57990  )) {
57991    return trustedScriptURLFromStringBypass(unwrapSafeValue(unsafeResourceUrl));
57992  }
57993
57994  throw new RuntimeError(904
57995  /* RuntimeErrorCode.UNSAFE_VALUE_IN_RESOURCE_URL */
57996  , ngDevMode && 'unsafe value used in a resource URL context (see https://g.co/ng/security#xss)');
57997}
57998/**
57999 * A `script` sanitizer which only lets trusted javascript through.
58000 *
58001 * This passes only `script`s marked trusted by calling {@link
58002 * bypassSanitizationTrustScript}.
58003 *
58004 * @param unsafeScript untrusted `script`, typically from the user.
58005 * @returns `url` string which is safe to bind to the `<script>` element such as `<img src>`,
58006 * because only trusted `scripts` have been allowed to pass.
58007 *
58008 * @codeGenApi
58009 */
58010
58011
58012function ɵɵsanitizeScript(unsafeScript) {
58013  const sanitizer = getSanitizer();
58014
58015  if (sanitizer) {
58016    return trustedScriptFromStringBypass(sanitizer.sanitize(SecurityContext.SCRIPT, unsafeScript) || '');
58017  }
58018
58019  if (allowSanitizationBypassAndThrow(unsafeScript, "Script"
58020  /* BypassType.Script */
58021  )) {
58022    return trustedScriptFromStringBypass(unwrapSafeValue(unsafeScript));
58023  }
58024
58025  throw new RuntimeError(905
58026  /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */
58027  , ngDevMode && 'unsafe value used in a script context');
58028}
58029/**
58030 * A template tag function for promoting the associated constant literal to a
58031 * TrustedHTML. Interpolation is explicitly not allowed.
58032 *
58033 * @param html constant template literal containing trusted HTML.
58034 * @returns TrustedHTML wrapping `html`.
58035 *
58036 * @security This is a security-sensitive function and should only be used to
58037 * convert constant values of attributes and properties found in
58038 * application-provided Angular templates to TrustedHTML.
58039 *
58040 * @codeGenApi
58041 */
58042
58043
58044function ɵɵtrustConstantHtml(html) {
58045  // The following runtime check ensures that the function was called as a
58046  // template tag (e.g. ɵɵtrustConstantHtml`content`), without any interpolation
58047  // (e.g. not ɵɵtrustConstantHtml`content ${variable}`). A TemplateStringsArray
58048  // is an array with a `raw` property that is also an array. The associated
58049  // template literal has no interpolation if and only if the length of the
58050  // TemplateStringsArray is 1.
58051  if (ngDevMode && (!Array.isArray(html) || !Array.isArray(html.raw) || html.length !== 1)) {
58052    throw new Error(`Unexpected interpolation in trusted HTML constant: ${html.join('?')}`);
58053  }
58054
58055  return trustedHTMLFromString(html[0]);
58056}
58057/**
58058 * A template tag function for promoting the associated constant literal to a
58059 * TrustedScriptURL. Interpolation is explicitly not allowed.
58060 *
58061 * @param url constant template literal containing a trusted script URL.
58062 * @returns TrustedScriptURL wrapping `url`.
58063 *
58064 * @security This is a security-sensitive function and should only be used to
58065 * convert constant values of attributes and properties found in
58066 * application-provided Angular templates to TrustedScriptURL.
58067 *
58068 * @codeGenApi
58069 */
58070
58071
58072function ɵɵtrustConstantResourceUrl(url) {
58073  // The following runtime check ensures that the function was called as a
58074  // template tag (e.g. ɵɵtrustConstantResourceUrl`content`), without any
58075  // interpolation (e.g. not ɵɵtrustConstantResourceUrl`content ${variable}`). A
58076  // TemplateStringsArray is an array with a `raw` property that is also an
58077  // array. The associated template literal has no interpolation if and only if
58078  // the length of the TemplateStringsArray is 1.
58079  if (ngDevMode && (!Array.isArray(url) || !Array.isArray(url.raw) || url.length !== 1)) {
58080    throw new Error(`Unexpected interpolation in trusted URL constant: ${url.join('?')}`);
58081  }
58082
58083  return trustedScriptURLFromString(url[0]);
58084}
58085/**
58086 * Detects which sanitizer to use for URL property, based on tag name and prop name.
58087 *
58088 * The rules are based on the RESOURCE_URL context config from
58089 * `packages/compiler/src/schema/dom_security_schema.ts`.
58090 * If tag and prop names don't match Resource URL schema, use URL sanitizer.
58091 */
58092
58093
58094function getUrlSanitizer(tag, prop) {
58095  if (prop === 'src' && (tag === 'embed' || tag === 'frame' || tag === 'iframe' || tag === 'media' || tag === 'script') || prop === 'href' && (tag === 'base' || tag === 'link')) {
58096    return ɵɵsanitizeResourceUrl;
58097  }
58098
58099  return ɵɵsanitizeUrl;
58100}
58101/**
58102 * Sanitizes URL, selecting sanitizer function based on tag and property names.
58103 *
58104 * This function is used in case we can't define security context at compile time, when only prop
58105 * name is available. This happens when we generate host bindings for Directives/Components. The
58106 * host element is unknown at compile time, so we defer calculation of specific sanitizer to
58107 * runtime.
58108 *
58109 * @param unsafeUrl untrusted `url`, typically from the user.
58110 * @param tag target element tag name.
58111 * @param prop name of the property that contains the value.
58112 * @returns `url` string which is safe to bind.
58113 *
58114 * @codeGenApi
58115 */
58116
58117
58118function ɵɵsanitizeUrlOrResourceUrl(unsafeUrl, tag, prop) {
58119  return getUrlSanitizer(tag, prop)(unsafeUrl);
58120}
58121
58122function validateAgainstEventProperties(name) {
58123  if (name.toLowerCase().startsWith('on')) {
58124    const errorMessage = `Binding to event property '${name}' is disallowed for security reasons, ` + `please use (${name.slice(2)})=...` + `\nIf '${name}' is a directive input, make sure the directive is imported by the` + ` current module.`;
58125    throw new RuntimeError(306
58126    /* RuntimeErrorCode.INVALID_EVENT_BINDING */
58127    , errorMessage);
58128  }
58129}
58130
58131function validateAgainstEventAttributes(name) {
58132  if (name.toLowerCase().startsWith('on')) {
58133    const errorMessage = `Binding to event attribute '${name}' is disallowed for security reasons, ` + `please use (${name.slice(2)})=...`;
58134    throw new RuntimeError(306
58135    /* RuntimeErrorCode.INVALID_EVENT_BINDING */
58136    , errorMessage);
58137  }
58138}
58139
58140function getSanitizer() {
58141  const lView = getLView();
58142  return lView && lView[SANITIZER];
58143}
58144/**
58145 * @license
58146 * Copyright Google LLC All Rights Reserved.
58147 *
58148 * Use of this source code is governed by an MIT-style license that can be
58149 * found in the LICENSE file at https://angular.io/license
58150 */
58151
58152/**
58153 * A multi-provider token for initialization functions that will run upon construction of an
58154 * environment injector.
58155 *
58156 * @publicApi
58157 */
58158
58159
58160const ENVIRONMENT_INITIALIZER = new InjectionToken('ENVIRONMENT_INITIALIZER');
58161/**
58162 * @license
58163 * Copyright Google LLC All Rights Reserved.
58164 *
58165 * Use of this source code is governed by an MIT-style license that can be
58166 * found in the LICENSE file at https://angular.io/license
58167 */
58168
58169/**
58170 * An InjectionToken that gets the current `Injector` for `createInjector()`
58170-style injectors.
58171 *
58172 * Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
58173 * project.
58174 *
58175 * @publicApi
58176 */
58177
58178const INJECTOR = new InjectionToken('INJECTOR', // Disable tslint because this is const enum which gets inlined not top level prop access.
58179// tslint:disable-next-line: no-toplevel-property-access
58180-1
58181/* InjectorMarkers.Injector */
58182);
58183/**
58184 * @license
58185 * Copyright Google LLC All Rights Reserved.
58186 *
58187 * Use of this source code is governed by an MIT-style license that can be
58188 * found in the LICENSE file at https://angular.io/license
58189 */
58190
58191const INJECTOR_DEF_TYPES = new InjectionToken('INJECTOR_DEF_TYPES');
58192/**
58193 * @license
58194 * Copyright Google LLC All Rights Reserved.
58195 *
58196 * Use of this source code is governed by an MIT-style license that can be
58197 * found in the LICENSE file at https://angular.io/license
58198 */
58199
58200class NullInjector {
58201  get(token, notFoundValue = THROW_IF_NOT_FOUND) {
58202    if (notFoundValue === THROW_IF_NOT_FOUND) {
58203      const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
58204      error.name = 'NullInjectorError';
58205      throw error;
58206    }
58207
58208    return notFoundValue;
58209  }
58210
58211}
58212/**
58213 * @license
58214 * Copyright Google LLC All Rights Reserved.
58215 *
58216 * Use of this source code is governed by an MIT-style license that can be
58217 * found in the LICENSE file at https://angular.io/license
58218 */
58219
58220/**
58221 * @license
58222 * Copyright Google LLC All Rights Reserved.
58223 *
58224 * Use of this source code is governed by an MIT-style license that can be
58225 * found in the LICENSE file at https://angular.io/license
58226 */
58227
58228/**
58229 * Collects providers from all NgModules and standalone components, including transitively imported
58230 * ones.
58231 *
58232 * Providers extracted via `importProvidersFrom` are only usable in an application injector or
58233 * another environment injector (such as a route injector). They should not be used in component
58234 * providers.
58235 *
58236 * More information about standalone components can be found in [this
58237 * guide](guide/standalone-components).
58238 *
58239 * @usageNotes
58240 * The results of the `importProvidersFrom` call can be used in the `bootstrapApplication` call:
58241 *
58242 * ```typescript
58243 * await bootstrapApplication(RootComponent, {
58244 *   providers: [
58245 *     importProvidersFrom(NgModuleOne, NgModuleTwo)
58246 *   ]
58247 * });
58248 * ```
58249 *
58250 * You can also use the `importProvidersFrom` results in the `providers` field of a route, when a
58251 * standalone component is used:
58252 *
58253 * ```typescript
58254 * export const ROUTES: Route[] = [
58255 *   {
58256 *     path: 'foo',
58257 *     providers: [
58258 *       importProvidersFrom(NgModuleOne, NgModuleTwo)
58259 *     ],
58260 *     component: YourStandaloneComponent
58261 *   }
58262 * ];
58263 * ```
58264 *
58265 * @returns Collected providers from the specified list of types.
58266 * @publicApi
58267 * @developerPreview
58268 */
58269
58270
58271function importProvidersFrom(...sources) {
58272  return {
58273    ɵproviders: internalImportProvidersFrom(true, sources)
58274  };
58275}
58276
58277function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
58278  const providersOut = [];
58279  const dedup = new Set(); // already seen types
58280
58281  let injectorTypesWithProviders;
58282  deepForEach(sources, source => {
58283    if ((typeof ngDevMode === 'undefined' || ngDevMode) && checkForStandaloneCmp) {
58284      const cmpDef = getComponentDef(source);
58285
58286      if (cmpDef?.standalone) {
58287        throw new RuntimeError(800
58288        /* RuntimeErrorCode.IMPORT_PROVIDERS_FROM_STANDALONE */
58289        , `Importing providers supports NgModule or ModuleWithProviders but got a standalone component "${stringifyForError(source)}"`);
58290      }
58291    } // Narrow `source` to access the internal type analogue for `ModuleWithProviders`.
58292
58293
58294    const internalSource = source;
58295
58296    if (walkProviderTree(internalSource, providersOut, [], dedup)) {
58297      injectorTypesWithProviders || (injectorTypesWithProviders = []);
58298      injectorTypesWithProviders.push(internalSource);
58299    }
58300  }); // Collect all providers from `ModuleWithProviders` types.
58301
58302  if (injectorTypesWithProviders !== undefined) {
58303    processInjectorTypesWithProviders(injectorTypesWithProviders, providersOut);
58304  }
58305
58306  return providersOut;
58307}
58308/**
58309 * Collects all providers from the list of `ModuleWithProviders` and appends them to the provided
58310 * array.
vendor: 4,938 bytes, lines 58311-58438
58311 */
58312
58313
58314function processInjectorTypesWithProviders(typesWithProviders, providersOut) {
58315  for (let i = 0; i < typesWithProviders.length; i++) {
58316    const {
58317      ngModule,
58318      providers
58319    } = typesWithProviders[i];
58320    deepForEach(providers, provider => {
58321      ngDevMode && validateProvider(provider, providers || EMPTY_ARRAY, ngModule);
58322      providersOut.push(provider);
58323    });
58324  }
58325}
58326/**
58327 * The logic visits an `InjectorType`, an `InjectorTypeWithProviders`, or a standalone
58328 * `ComponentType`, and all of its transitive providers and collects providers.
58329 *
58330 * If an `InjectorTypeWithProviders` that declares providers besides the type is specified,
58331 * the function will return "true" to indicate that the providers of the type definition need
58332 * to be processed. This allows us to process providers of injector types after all imports of
58333 * an injector definition are processed. (following View Engine semantics: see FW-1349)
58334 */
58335
58336
58337function walkProviderTree(container, providersOut, parents, dedup) {
58338  container = resolveForwardRef(container);
58339  if (!container) return false; // The actual type which had the definition. Usually `container`, but may be an unwrapped type
58340  // from `InjectorTypeWithProviders`.
58341
58342  let defType = null;
58343  let injDef = getInjectorDef(container);
58344  const cmpDef = !injDef && getComponentDef(container);
58345
58346  if (!injDef && !cmpDef) {
58347    // `container` is not an injector type or a component type. It might be:
58348    //  * An `InjectorTypeWithProviders` that wraps an injector type.
58349    //  * A standalone directive or pipe that got pulled in from a standalone component's
58350    //    dependencies.
58351    // Try to unwrap it as an `InjectorTypeWithProviders` first.
58352    const ngModule = container.ngModule;
58353    injDef = getInjectorDef(ngModule);
58354
58355    if (injDef) {
58356      defType = ngModule;
58357    } else {
58358      // Not a component or injector type, so ignore it.
58359      return false;
58360    }
58361  } else if (cmpDef && !cmpDef.standalone) {
58362    return false;
58363  } else {
58364    defType = container;
58365  } // Check for circular dependencies.
58366
58367
58368  if (ngDevMode && parents.indexOf(defType) !== -1) {
58369    const defName = stringify(defType);
58370    const path = parents.map(stringify);
58371    throwCyclicDependencyError(defName, path);
58372  } // Check for multiple imports of the same module
58373
58374
58375  const isDuplicate = dedup.has(defType);
58376
58377  if (cmpDef) {
58378    if (isDuplicate) {
58379      // This component definition has already been processed.
58380      return false;
58381    }
58382
58383    dedup.add(defType);
58384
58385    if (cmpDef.dependencies) {
58386      const deps = typeof cmpDef.dependencies === 'function' ? cmpDef.dependencies() : cmpDef.dependencies;
58387
58388      for (const dep of deps) {
58389        walkProviderTree(dep, providersOut, parents, dedup);
58390      }
58391    }
58392  } else if (injDef) {
58393    // First, include providers from any imports.
58394    if (injDef.imports != null && !isDuplicate) {
58395      // Before processing defType's imports, add it to the set of parents. This way, if it ends
58396      // up deeply importing itself, this can be detected.
58397      ngDevMode && parents.push(defType); // Add it to the set of dedups. This way we can detect multiple imports of the same module
58398
58399      dedup.add(defType);
58400      let importTypesWithProviders;
58401
58402      try {
58403        deepForEach(injDef.imports, imported => {
58404          if (walkProviderTree(imported, providersOut, parents, dedup)) {
58405            importTypesWithProviders || (importTypesWithProviders = []); // If the processed import is an injector type with providers, we store it in the
58406            // list of import types with providers, so that we can process those afterwards.
58407
58408            importTypesWithProviders.push(imported);
58409          }
58410        });
58411      } finally {
58412        // Remove it from the parents set when finished.
58413        ngDevMode && parents.pop();
58414      } // Imports which are declared with providers (TypeWithProviders) need to be processed
58415      // after all imported modules are processed. This is similar to how View Engine
58416      // processes/merges module imports in the metadata resolver. See: FW-1349.
58417
58418
58419      if (importTypesWithProviders !== undefined) {
58420        processInjectorTypesWithProviders(importTypesWithProviders, providersOut);
58421      }
58422    }
58423
58424    if (!isDuplicate) {
58425      // Track the InjectorType and add a provider for it.
58426      // It's important that this is done after the def's imports.
58427      const factory = getFactoryDef(defType) || (() => new defType()); // Append extra providers to make more info available for consumers (to retrieve an injector
58428      // type), as well as internally (to calculate an injection scope correctly and eagerly
58429      // instantiate a `defType` when an injector is created).
58430
58431
58432      providersOut.push( // Provider to create `defType` using its factory.
58433      {
58434        provide: defType,
58435        useFactory: factory,
58436        deps: EMPTY_ARRAY
58437      }, // Make this `defType` available to an internal logic that calculates injector scope.
58438      {
58439        provide: INJECTOR_DEF_TYPES,
58440        useValue: defType,
58441        multi: true
58442      }, // Provider to eagerly instantiate `defType` via `ENVIRONMENT_INITIALIZER`.
58443      {
58444        provide: ENVIRONMENT_INITIALIZER,
58445        useValue: () => ɵɵinject(defType),
58446        multi: true
58447      } //
58448      );
58449    } // Next, include providers listed on the definition itself.
58450
58451
58452    const defProviders = injDef.providers;
58453
58454    if (defProviders != null && !isDuplicate) {
58455      const injectorType = container;
58456      deepForEach(defProviders, provider => {
58457        ngDevMode && validateProvider(provider, defProviders, injectorType);
58458        providersOut.push(provider);
58459      });
58460    }
58461  } else {
58462    // Should not happen, but just in case.
58463    return false;
58464  }
58465
58466  return defType !== container && container.providers !== undefined;
58467}
58468
58469function validateProvider(provider, providers, containerType) {
58470  if (isTypeProvider(provider) || isValueProvider(provider) || isFactoryProvider(provider) || isExistingProvider(provider)) {
58471    return;
58472  } // Here we expect the provider to be a `useClass` provider (by elimination).
58473
58474
58475  const classRef = resolveForwardRef(provider && (provider.useClass || provider.provide));
58476
58477  if (!classRef) {
58478    throwInvalidProviderError(containerType, providers, provider);
58479  }
58480}
58481
58482const USE_VALUE$1 = getClosureSafeProperty({
58483  provide: String,
58484  useValue: getClosureSafeProperty
58485});
58486
58487function isValueProvider(value) {
58488  return value !== null && typeof value == 'object' && USE_VALUE$1 in value;
58489}
58490
58491function isExistingProvider(value) {
58492  return !!(value && value.useExisting);
58493}
58494
58495function isFactoryProvider(value) {
58496  return !!(value && value.useFactory);
58497}
58498
58499function isTypeProvider(value) {
58500  return typeof value === 'function';
58501}
58502
58503function isClassProvider(value) {
58504  return !!value.useClass;
58505}
58506/**
58507 * @license
58508 * Copyright Google LLC All Rights Reserved.
58509 *
58510 * Use of this source code is governed by an MIT-style license that can be
58511 * found in the LICENSE file at https://angular.io/license
58512 */
58513
58514/**
58515 * An internal token whose presence in an injector indicates that the injector should treat itself
58516 * as a root scoped injector when processing requests for unknown tokens which may indicate
58517 * they are provided in the root scope.
58518 */
58519
58520
58521const INJECTOR_SCOPE = new InjectionToken('Set Injector scope.');
58522/**
58523 * @license
58524 * Copyright Google LLC All Rights Reserved.
58525 *
58526 * Use of this source code is governed by an MIT-style license that can be
58527 * found in the LICENSE file at https://angular.io/license
58528 */
58529
58530/**
58531 * Marker which indicates that a value has not yet been created from the factory function.
58532 */
58533
58534const NOT_YET = {};
58535/**
58536 * Marker which indicates that the factory function for a token is in the process of being called.
58537 *
58538 * If the injector is asked to inject a token with its value set to CIRCULAR, that indicates
58539 * injection of a dependency has recursively attempted to inject the original token, and there is
58540 * a circular dependency among the providers.
58541 */
58542
58543const CIRCULAR = {};
58544/**
58545 * A lazily initialized NullInjector.
58546 */
58547
58548let NULL_INJECTOR$1 = undefined;
58549
58550function getNullInjector() {
58551  if (NULL_INJECTOR$1 === undefined) {
58552    NULL_INJECTOR$1 = new NullInjector();
58553  }
58554
58555  return NULL_INJECTOR$1;
58556}
58557/**
58558 * An `Injector` that's part of the environment injector hierarchy, which exists outside of the
58559 * component tree.
58560 *
58561 * @developerPreview
58562 */
58563
58564
58565class EnvironmentInjector {}
58566
58567class R3Injector extends EnvironmentInjector {
58568  constructor(providers, parent, source, scopes) {
58569    super();
58570    this.parent = parent;
58571    this.source = source;
58572    this.scopes = scopes;
58573    /**
58574     * Map of tokens to records which contain the instances of those tokens.
58575     * - `null` value implies that we don't have the record. Used by tree-shakable injectors
58576     * to prevent further searches.
58577     */
58578
58579    this.records = new Map();
58580    /**
58581     * Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
58582     */
58583
58584    this._ngOnDestroyHooks = new Set();
58585    this._onDestroyHooks = [];
58586    this._destroyed = false; // Start off by creating Records for every provider.
58587
58588    forEachSingleProvider(providers, provider => this.processProvider(provider)); // Make sure the INJECTOR token provides this injector.
58589
58590    this.records.set(INJECTOR, makeRecord(undefined, this)); // And `EnvironmentInjector` if the current injector is supposed to be env-scoped.
58591
58592    if (scopes.has('environment')) {
58593      this.records.set(EnvironmentInjector, makeRecord(undefined, this));
58594    } // Detect whether this injector has the APP_ROOT_SCOPE token and thus should provide
58595    // any injectable scoped to APP_ROOT_SCOPE.
58596
58597
58598    const record = this.records.get(INJECTOR_SCOPE);
58599
58600    if (record != null && typeof record.value === 'string') {
58601      this.scopes.add(record.value);
58602    }
58603
58604    this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES.multi, EMPTY_ARRAY, InjectFlags.Self));
58605  }
58606  /**
58607   * Flag indicating that this injector was previously destroyed.
58608   */
58609
58610
58611  get destroyed() {
58612    return this._destroyed;
58613  }
58614  /**
58615   * Destroy the injector and release references to every instance or provider associated with it.
58616   *
58617   * Also calls the `OnDestroy` lifecycle hooks of every instance that was created for which a
58618   * hook was found.
58619   */
58620
58621
58622  destroy() {
58623    this.assertNotDestroyed(); // Set destroyed = true first, in case lifecycle hooks re-enter destroy().
58624
58625    this._destroyed = true;
58626
58627    try {
58628      // Call all the lifecycle hooks.
58629      for (const service of this._ngOnDestroyHooks) {
58630        service.ngOnDestroy();
58631      }
58632
58633      for (const hook of this._onDestroyHooks) {
58634        hook();
58635      }
58636    } finally {
58637      // Release all references.
58638      this.records.clear();
58639
58640      this._ngOnDestroyHooks.clear();
58641
58642      this.injectorDefTypes.clear();
58643      this._onDestroyHooks.length = 0;
58644    }
58645  }
58646
58647  onDestroy(callback) {
58648    this._onDestroyHooks.push(callback);
58649  }
58650
58651  runInContext(fn) {
58652    this.assertNotDestroyed();
58653    const previousInjector = setCurrentInjector(this);
58654    const previousInjectImplementation = setInjectImplementation(undefined);
58655
58656    try {
58657      return fn();
58658    } finally {
58659      setCurrentInjector(previousInjector);
58660      setInjectImplementation(previousInjectImplementation);
58661    }
58662  }
58663
58664  get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
58665    this.assertNotDestroyed(); // Set the injection context.
58666
58667    const previousInjector = setCurrentInjector(this);
58668    const previousInjectImplementation = setInjectImplementation(undefined);
58669
58670    try {
58671      // Check for the SkipSelf flag.
58672      if (!(flags & InjectFlags.SkipSelf)) {
58673        // SkipSelf isn't set, check if the record belongs to this injector.
58674        let record = this.records.get(token);
58675
58676        if (record === undefined) {
58677          // No record, but maybe the token is scoped to this injector. Look for an injectable
58678          // def with a scope matching this injector.
58679          const def = couldBeInjectableType(token) && getInjectableDef(token);
58680
58681          if (def && this.injectableDefInScope(def)) {
58682            // Found an injectable def and it's scoped to this injector. Pretend as if it was here
58683            // all along.
58684            record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
58685          } else {
58686            record = null;
58687          }
58688
58689          this.records.set(token, record);
58690        } // If a record was found, get the instance for it and return it.
58691
58692
58693        if (record != null
58694        /* NOT null || undefined */
58695        ) {
58696          return this.hydrate(token, record);
58697        }
58698      } // Select the next injector based on the Self flag - if self is set, the next injector is
58699      // the NullInjector, otherwise it's the parent.
58700
58701
58702      const nextInjector = !(flags & InjectFlags.Self) ? this.parent : getNullInjector(); // Set the notFoundValue based on the Optional flag - if optional is set and notFoundValue
58703      // is undefined, the value is null, otherwise it's the notFoundValue.
58704
58705      notFoundValue = flags & InjectFlags.Optional && notFoundValue === THROW_IF_NOT_FOUND ? null : notFoundValue;
58706      return nextInjector.get(token, notFoundValue);
58707    } catch (e) {
58708      if (e.name === 'NullInjectorError') {
58709        const path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
58710        path.unshift(stringify(token));
58711
58712        if (previousInjector) {
58713          // We still have a parent injector, keep throwing
58714          throw e;
58715        } else {
58716          // Format & throw the final error message when we don't have any previous injector
58717          return catchInjectorError(e, token, 'R3InjectorError', this.source);
58718        }
58719      } else {
58720        throw e;
58721      }
58722    } finally {
58723      // Lastly, restore the previous injection context.
58724      setInjectImplementation(previousInjectImplementation);
58725      setCurrentInjector(previousInjector);
58726    }
58727  }
58728  /** @internal */
58729
58730
58731  resolveInjectorInitializers() {
58732    const previousInjector = setCurrentInjector(this);
58733    const previousInjectImplementation = setInjectImplementation(undefined);
58734
58735    try {
58736      const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);
58737
58738      if (ngDevMode && !Array.isArray(initializers)) {
58739        throw new RuntimeError(209
58740        /* RuntimeErrorCode.INVALID_MULTI_PROVIDER */
58741        , 'Unexpected type of the `ENVIRONMENT_INITIALIZER` token value ' + `(expected an array, but got ${typeof initializers}). ` + 'Please check that the `ENVIRONMENT_INITIALIZER` token is configured as a ' + '`multi: true` provider.');
58742      }
58743
58744      for (const initializer of initializers) {
58745        initializer();
58746      }
58747    } finally {
58748      setCurrentInjector(previousInjector);
58749      setInjectImplementation(previousInjectImplementation);
58750    }
58751  }
58752
58753  toString() {
58754    const tokens = [];
58755    const records = this.records;
58756
58757    for (const token of records.keys()) {
58758      tokens.push(stringify(token));
58759    }
58760
58761    return `R3Injector[${tokens.join(', ')}]`;
58762  }
58763
58764  assertNotDestroyed() {
58765    if (this._destroyed) {
58766      throw new RuntimeError(205
58767      /* RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED */
58768      , ngDevMode && 'Injector has already been destroyed.');
58769    }
58770  }
58771  /**
58772   * Process a `SingleProvider` and add it.
58773   */
58774
58775
58776  processProvider(provider) {
58777    // Determine the token from the provider. Either it's its own token, or has a {provide: ...}
58778    // property.
58779    provider = resolveForwardRef(provider);
58780    let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider && provider.provide); // Construct a `Record` for the provider.
58781
58782    const record = providerToRecord(provider);
58783
58784    if (!isTypeProvider(provider) && provider.multi === true) {
58785      // If the provider indicates that it's a multi-provider, process it specially.
58786      // First check whether it's been defined already.
58787      let multiRecord = this.records.get(token);
58788
58789      if (multiRecord) {
58790        // It has. Throw a nice error if
58791        if (ngDevMode && multiRecord.multi === undefined) {
58792          throwMixedMultiProviderError();
58793        }
58794      } else {
58795        multiRecord = makeRecord(undefined, NOT_YET, true);
58796
58797        multiRecord.factory = () => injectArgs(multiRecord.multi);
58798
58799        this.records.set(token, multiRecord);
58800      }
58801
58802      token = provider;
58803      multiRecord.multi.push(provider);
58804    } else {
58805      const existing = this.records.get(token);
58806
58807      if (ngDevMode && existing && existing.multi !== undefined) {
58808        throwMixedMultiProviderError();
58809      }
58810    }
58811
58812    this.records.set(token, record);
58813  }
58814
58815  hydrate(token, record) {
58816    if (ngDevMode && record.value === CIRCULAR) {
58817      throwCyclicDependencyError(stringify(token));
58818    } else if (record.value === NOT_YET) {
58819      record.value = CIRCULAR;
58820      record.value = record.factory();
58821    }
58822
58823    if (typeof record.value === 'object' && record.value && hasOnDestroy(record.value)) {
58824      this._ngOnDestroyHooks.add(record.value);
58825    }
58826
58827    return record.value;
58828  }
58829
58830  injectableDefInScope(def) {
58831    if (!def.providedIn) {
58832      return false;
58833    }
58834
58835    const providedIn = resolveForwardRef(def.providedIn);
58836
58837    if (typeof providedIn === 'string') {
58838      return providedIn === 'any' || this.scopes.has(providedIn);
58839    } else {
58840      return this.injectorDefTypes.has(providedIn);
58841    }
58842  }
58843
58844}
58845
58846function injectableDefOrInjectorDefFactory(token) {
58847  // Most tokens will have an injectable def directly on them, which specifies a factory directly.
58848  const injectableDef = getInjectableDef(token);
58849  const factory = injectableDef !== null ? injectableDef.factory : getFactoryDef(token);
58850
58851  if (factory !== null) {
58852    return factory;
58853  } // InjectionTokens should have an injectable def (ɵprov) and thus should be handled above.
58854  // If it's missing that, it's an error.
58855
58856
58857  if (token instanceof InjectionToken) {
58858    throw new RuntimeError(204
58859    /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */
58860    , ngDevMode && `Token ${stringify(token)} is missing a ɵprov definition.`);
58861  } // Undecorated types can sometimes be created if they have no constructor arguments.
58862
58863
58864  if (token instanceof Function) {
58865    return getUndecoratedInjectableFactory(token);
58866  } // There was no way to resolve a factory for this token.
58867
58868
58869  throw new RuntimeError(204
58870  /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */
58871  , ngDevMode && 'unreachable');
58872}
58873
58874function getUndecoratedInjectableFactory(token) {
58875  // If the token has parameters then it has dependencies that we cannot resolve implicitly.
58876  const paramLength = token.length;
58877
58878  if (paramLength > 0) {
58879    const args = newArray(paramLength, '?');
58880    throw new RuntimeError(204
58881    /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */
58882    , ngDevMode && `Can't resolve all parameters for ${stringify(token)}: (${args.join(', ')}).`);
58883  } // The constructor function appears to have no parameters.
58884  // This might be because it inherits from a super-class. In which case, use an injectable
58885  // def from an ancestor if there is one.
58886  // Otherwise this really is a simple class with no dependencies, so return a factory that
58887  // just instantiates the zero-arg constructor.
58888
58889
58890  const inheritedInjectableDef = getInheritedInjectableDef(token);
58891
58892  if (inheritedInjectableDef !== null) {
58893    return () => inheritedInjectableDef.factory(token);
58894  } else {
58895    return () => new token();
58896  }
58897}
58898
58899function providerToRecord(provider) {
58900  if (isValueProvider(provider)) {
58901    return makeRecord(undefined, provider.useValue);
58902  } else {
58903    const factory = providerToFactory(provider);
58904    return makeRecord(factory, NOT_YET);
58905  }
58906}
58907/**
58908 * Converts a `SingleProvider` into a factory function.
58909 *
58910 * @param provider provider to convert to factory
58911 */
58912
58913
58914function providerToFactory(provider, ngModuleType, providers) {
58915  let factory = undefined;
58916
58917  if (ngDevMode && isImportedNgModuleProviders(provider)) {
58918    throwInvalidProviderError(undefined, providers, provider);
58919  }
58920
58921  if (isTypeProvider(provider)) {
58922    const unwrappedProvider = resolveForwardRef(provider);
58923    return getFactoryDef(unwrappedProvider) || injectableDefOrInjectorDefFactory(unwrappedProvider);
58924  } else {
58925    if (isValueProvider(provider)) {
58926      factory = () => resolveForwardRef(provider.useValue);
58927    } else if (isFactoryProvider(provider)) {
58928      factory = () => provider.useFactory(...injectArgs(provider.deps || []));
58929    } else if (isExistingProvider(provider)) {
58930      factory = () => ɵɵinject(resolveForwardRef(provider.useExisting));
58931    } else {
58932      const classRef = resolveForwardRef(provider && (provider.useClass || provider.provide));
58933
58934      if (ngDevMode && !classRef) {
58935        throwInvalidProviderError(ngModuleType, providers, provider);
58936      }
58937
58938      if (hasDeps(provider)) {
58939        factory = () => new classRef(...injectArgs(provider.deps));
58940      } else {
58941        return getFactoryDef(classRef) || injectableDefOrInjectorDefFactory(classRef);
58942      }
58943    }
58944  }
58945
58946  return factory;
58947}
58948
58949function makeRecord(factory, value, multi = false) {
58950  return {
58951    factory: factory,
58952    value: value,
58953    multi: multi ? [] : undefined
58954  };
58955}
58956
58957function hasDeps(value) {
58958  return !!value.deps;
58959}
58960
58961function hasOnDestroy(value) {
58962  return value !== null && typeof value === 'object' && typeof value.ngOnDestroy === 'function';
58963}
58964
58965function couldBeInjectableType(value) {
58966  return typeof value === 'function' || typeof value === 'object' && value instanceof InjectionToken;
58967}
58968
58969function isImportedNgModuleProviders(provider) {
58970  return !!provider.ɵproviders;
58971}
58972
58973function forEachSingleProvider(providers, fn) {
58974  for (const provider of providers) {
58975    if (Array.isArray(provider)) {
58976      forEachSingleProvider(provider, fn);
58977    } else if (isImportedNgModuleProviders(provider)) {
58978      forEachSingleProvider(provider.ɵproviders, fn);
58979    } else {
58980      fn(provider);
58981    }
58982  }
58983}
58984/**
58985 * @license
58986 * Copyright Google LLC All Rights Reserved.
58987 *
58988 * Use of this source code is governed by an MIT-style license that can be
58989 * found in the LICENSE file at https://angular.io/license
58990 */
58991
58992/**
58993 * Represents a component created by a `ComponentFactory`.
58994 * Provides access to the component instance and related objects,
58995 * and provides the means of destroying the instance.
58996 *
58997 * @publicApi
58998 */
58999
59000
59001class ComponentRef$1 {}
59002/**
59003 * Base class for a factory that can create a component dynamically.
59004 * Instantiate a factory for a given type of component with `resolveComponentFactory()`.
59005 * Use the resulting `ComponentFactory.create()` method to create a component of that type.
59006 *
59007 * @see [Dynamic Components](guide/dynamic-component-loader)
59008 *
59009 * @publicApi
59010 *
59011 * @deprecated Angular no longer requires Component factories. Please use other APIs where
59012 *     Component class can be used directly.
59013 */
59014
59015
59016class ComponentFactory$1 {}
59017/**
59018 * @license
59019 * Copyright Google LLC All Rights Reserved.
59020 *
59021 * Use of this source code is governed by an MIT-style license that can be
59022 * found in the LICENSE file at https://angular.io/license
59023 */
59024
59025
59026function noComponentFactoryError(component) {
59027  const error = Error(`No component factory found for ${stringify(component)}. Did you add it to @NgModule.entryComponents?`);
59028  error[ERROR_COMPONENT] = component;
59029  return error;
59030}
59031
59032const ERROR_COMPONENT = 'ngComponent';
59033
59034function getComponent$1(error) {
59035  return error[ERROR_COMPONENT];
59036}
59037
59038class _NullComponentFactoryResolver {
59039  resolveComponentFactory(component) {
59040    throw noComponentFactoryError(component);
59041  }
59042
59043}
59044/**
59045 * A simple registry that maps `Components` to generated `ComponentFactory` classes
59046 * that can be used to create instances of components.
59047 * Use to obtain the factory for a given component type,
59048 * then use the factory's `create()` method to create a component of that type.
59049 *
59050 * Note: since v13, dynamic component creation via
59051 * [`ViewContainerRef.createComponent`](api/core/ViewContainerRef#createComponent)
59052 * does **not** require resolving component factory: component class can be used directly.
59053 *
59054 * @publicApi
59055 *
59056 * @deprecated Angular no longer requires Component factories. Please use other APIs where
59057 *     Component class can be used directly.
59058 */
59059
59060
59061class ComponentFactoryResolver$1 {}
59062
59063ComponentFactoryResolver$1.NULL = /* @__PURE__ */new _NullComponentFactoryResolver();
59064/**
59065 * @license
59066 * Copyright Google LLC All Rights Reserved.
59067 *
59068 * Use of this source code is governed by an MIT-style license that can be
59069 * found in the LICENSE file at https://angular.io/license
59070 */
59071
59072/**
59073 * Creates an ElementRef from the most recent node.
59074 *
59075 * @returns The ElementRef instance to use
59076 */
59077
59078function injectElementRef() {
59079  return createElementRef(getCurrentTNode(), getLView());
59080}
59081/**
59082 * Creates an ElementRef given a node.
59083 *
59084 * @param tNode The node for which you'd like an ElementRef
59085 * @param lView The view to which the node belongs
59086 * @returns The ElementRef instance to use
59087 */
59088
59089
59090function createElementRef(tNode, lView) {
59091  return new ElementRef(getNativeByTNode(tNode, lView));
59092}
59093/**
59094 * A wrapper around a native element inside of a View.
59095 *
59096 * An `ElementRef` is backed by a render-specific element. In the browser, this is usually a DOM
59097 * element.
59098 *
59099 * @security Permitting direct access to the DOM can make your application more vulnerable to
59100 * XSS attacks. Carefully review any use of `ElementRef` in your code. For more detail, see the
59101 * [Security Guide](https://g.co/ng/security).
59102 *
59103 * @publicApi
59104 */
59105// Note: We don't expose things like `Injector`, `ViewContainer`, ... here,
59106// i.e. users have to ask for what they need. With that, we can build better analysis tools
59107// and could do better codegen in the future.
59108
59109
59110class ElementRef {
59111  constructor(nativeElement) {
59112    this.nativeElement = nativeElement;
59113  }
59114
59115}
59116/**
59117 * @internal
59118 * @nocollapse
59119 */
59120
59121
59122ElementRef.__NG_ELEMENT_ID__ = injectElementRef;
59123/**
59124 * Unwraps `ElementRef` and return the `nativeElement`.
59125 *
59126 * @param value value to unwrap
59127 * @returns `nativeElement` if `ElementRef` otherwise returns value as is.
59128 */
59129
59130function unwrapElementRef(value) {
59131  return value instanceof ElementRef ? value.nativeElement : value;
59132}
59133/**
59134 * @license
59135 * Copyright Google LLC All Rights Reserved.
59136 *
59137 * Use of this source code is governed by an MIT-style license that can be
59138 * found in the LICENSE file at https://angular.io/license
59139 */
59140
59141
59142const Renderer2Interceptor = new InjectionToken('Renderer2Interceptor');
59143/**
59144 * Creates and initializes a custom renderer that implements the `Renderer2` base class.
59145 *
59146 * @publicApi
59147 */
59148
59149class RendererFactory2 {}
59150/**
59151 * Extend this base class to implement custom rendering. By default, Angular
59152 * renders a template into DOM. You can use custom rendering to intercept
59153 * rendering calls, or to render to something other than DOM.
59154 *
59155 * Create your custom renderer using `RendererFactory2`.
59156 *
59157 * Use a custom renderer to bypass Angular's templating and
59158 * make custom UI changes that can't be expressed declaratively.
59159 * For example if you need to set a property or an attribute whose name is
59160 * not statically known, use the `setProperty()` or
59161 * `setAttribute()` method.
59162 *
59163 * @publicApi
59164 */
59165
59166
59167class Renderer2 {}
59168/**
59169 * @internal
59170 * @nocollapse
59171 */
59172
59173
59174Renderer2.__NG_ELEMENT_ID__ = () => injectRenderer2();
59175/** Injects a Renderer2 for the current component. */
59176
59177
59178function injectRenderer2() {
59179  // We need the Renderer to be based on the component that it's being injected into, however since
59180  // DI happens before we've entered its view, `getLView` will return the parent view instead.
59181  const lView = getLView();
59182  const tNode = getCurrentTNode();
59183  const nodeAtIndex = getComponentLViewByIndex(tNode.index, lView);
59184  return (isLView(nodeAtIndex) ? nodeAtIndex : lView)[RENDERER];
59185}
59186/**
59187 * @license
59188 * Copyright Google LLC All Rights Reserved.
59189 *
59190 * Use of this source code is governed by an MIT-style license that can be
59191 * found in the LICENSE file at https://angular.io/license
59192 */
59193
59194/**
59195 * Sanitizer is used by the views to sanitize potentially dangerous values.
59196 *
59197 * @publicApi
59198 */
59199
59200
59201class Sanitizer {}
59202/** @nocollapse */
59203
59204
59205Sanitizer.ɵprov = ɵɵdefineInjectable({
59206  token: Sanitizer,
59207  providedIn: 'root',
59208  factory: () => null
59209});
59210/**
59211 * @license
59212 * Copyright Google LLC All Rights Reserved.
59213 *
59214 * Use of this source code is governed by an MIT-style license that can be
59215 * found in the LICENSE file at https://angular.io/license
59216 */
59217
59218/**
59219 * @description Represents the version of Angular
59220 *
59221 * @publicApi
59222 */
59223
59224class Version {
59225  constructor(full) {
59226    this.full = full;
59227    this.major = full.split('.')[0];
59228    this.minor = full.split('.')[1];
59229    this.patch = full.split('.').slice(2).join('.');
59230  }
59231
59232}
59233/**
59234 * @publicApi
59235 */
59236
59237
59238const VERSION = new Version('14.2.10');
59239/**
59240 * @license
59241 * Copyright Google LLC All Rights Reserved.
59242 *
59243 * Use of this source code is governed by an MIT-style license that can be
59244 * found in the LICENSE file at https://angular.io/license
59245 */
59246// This default value is when checking the hierarchy for a token.
59247//
59248// It means both:
59249// - the token is not provided by the current injector,
59250// - only the element injectors should be checked (ie do not check module injectors
59251//
59252//          mod1
59253//         /
59254//       el1   mod2
59255//         \  /
59256//         el2
59257//
59258// When requesting el2.injector.get(token), we should check in the following order and return the
59259// first found value:
59260// - el2.injector.get(token, default)
59261// - el1.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) -> do not check the module
59262// - mod2.injector.get(token, default)
59263
59264const NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
59265/**
59266 * @license
59267 * Copyright Google LLC All Rights Reserved.
59268 *
59269 * Use of this source code is governed by an MIT-style license that can be
59270 * found in the LICENSE file at https://angular.io/license
59271 */
59272
59273/**
59274 * Defines a schema that allows an NgModule to contain the following:
59275 * - Non-Angular elements named with dash case (`-`).
59276 * - Element properties named with dash case (`-`).
59277 * Dash case is the naming convention for custom elements.
59278 *
59279 * @publicApi
59280 */
59281
59282const CUSTOM_ELEMENTS_SCHEMA = {
59283  name: 'custom-elements'
59284};
59285/**
59286 * Defines a schema that allows any property on any element.
59287 *
59288 * This schema allows you to ignore the errors related to any unknown elements or properties in a
59289 * template. The usage of this schema is generally discouraged because it prevents useful validation
59290 * and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
59291 *
59292 * @publicApi
59293 */
59294
vendor: 11,085 bytes, lines 59295-59545
59295const NO_ERRORS_SCHEMA = {
59296  name: 'no-errors-schema'
59297};
59298/**
59299 * @license
59300 * Copyright Google LLC All Rights Reserved.
59301 *
59302 * Use of this source code is governed by an MIT-style license that can be
59303 * found in the LICENSE file at https://angular.io/license
59304 */
59305
59306let shouldThrowErrorOnUnknownElement = false;
59307/**
59308 * Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
59309 * instead of just logging the error.
59310 * (for AOT-compiled ones this check happens at build time).
59311 */
59312
59313function ɵsetUnknownElementStrictMode(shouldThrow) {
59314  shouldThrowErrorOnUnknownElement = shouldThrow;
59315}
59316/**
59317 * Gets the current value of the strict mode.
59318 */
59319
59320
59321function ɵgetUnknownElementStrictMode() {
59322  return shouldThrowErrorOnUnknownElement;
59323}
59324
59325let shouldThrowErrorOnUnknownProperty = false;
59326/**
59327 * Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
59328 * instead of just logging the error.
59329 * (for AOT-compiled ones this check happens at build time).
59330 */
59331
59332function ɵsetUnknownPropertyStrictMode(shouldThrow) {
59333  shouldThrowErrorOnUnknownProperty = shouldThrow;
59334}
59335/**
59336 * Gets the current value of the strict mode.
59337 */
59338
59339
59340function ɵgetUnknownPropertyStrictMode() {
59341  return shouldThrowErrorOnUnknownProperty;
59342}
59343/**
59344 * Validates that the element is known at runtime and produces
59345 * an error if it's not the case.
59346 * This check is relevant for JIT-compiled components (for AOT-compiled
59347 * ones this check happens at build time).
59348 *
59349 * The element is considered known if either:
59350 * - it's a known HTML element
59351 * - it's a known custom element
59352 * - the element matches any directive
59353 * - the element is allowed by one of the schemas
59354 *
59355 * @param element Element to validate
59356 * @param lView An `LView` that represents a current component that is being rendered
59357 * @param tagName Name of the tag to check
59358 * @param schemas Array of schemas
59359 * @param hasDirectives Boolean indicating that the element matches any directive
59360 */
59361
59362
59363function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
59364  // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
59365  // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
59366  // defined as an array (as an empty array in case `schemas` field is not defined) and we should
59367  // execute the check below.
59368  if (schemas === null) return; // If the element matches any directive, it's considered as valid.
59369
59370  if (!hasDirectives && tagName !== null) {
59371    // The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
59372    // as a custom element. Note that unknown elements with a dash in their name won't be instances
59373    // of HTMLUnknownElement in browsers that support web components.
59374    const isUnknown = // Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
59375    // because while most browsers return 'function', IE returns 'object'.
59376    typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement && element instanceof HTMLUnknownElement || typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 && !customElements.get(tagName);
59377
59378    if (isUnknown && !matchingSchemas(schemas, tagName)) {
59379      const isHostStandalone = isHostComponentStandalone(lView);
59380      const templateLocation = getTemplateLocationDetails(lView);
59381      const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
59382      let message = `'${tagName}' is not a known element${templateLocation}:\n`;
59383      message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' : 'a part of an @NgModule where this component is declared'}.\n`;
59384
59385      if (tagName && tagName.indexOf('-') > -1) {
59386        message += `2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
59387      } else {
59388        message += `2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
59389      }
59390
59391      if (shouldThrowErrorOnUnknownElement) {
59392        throw new RuntimeError(304
59393        /* RuntimeErrorCode.UNKNOWN_ELEMENT */
59394        , message);
59395      } else {
59396        console.error(formatRuntimeError(304
59397        /* RuntimeErrorCode.UNKNOWN_ELEMENT */
59398        , message));
59399      }
59400    }
59401  }
59402}
59403/**
59404 * Validates that the property of the element is known at runtime and returns
59405 * false if it's not the case.
59406 * This check is relevant for JIT-compiled components (for AOT-compiled
59407 * ones this check happens at build time).
59408 *
59409 * The property is considered known if either:
59410 * - it's a known property of the element
59411 * - the element is allowed by one of the schemas
59412 * - the property is used for animations
59413 *
59414 * @param element Element to validate
59415 * @param propName Name of the property to check
59416 * @param tagName Name of the tag hosting the property
59417 * @param schemas Array of schemas
59418 */
59419
59420
59421function isPropertyValid(element, propName, tagName, schemas) {
59422  // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
59423  // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
59424  // defined as an array (as an empty array in case `schemas` field is not defined) and we should
59425  // execute the check below.
59426  if (schemas === null) return true; // The property is considered valid if the element matches the schema, it exists on the element,
59427  // or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
59428
59429  if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
59430    return true;
59431  } // Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
59432  // need to account for both here, while being careful with `typeof null` also returning 'object'.
59433
59434
59435  return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
59436}
59437/**
59438 * Logs or throws an error that a property is not supported on an element.
59439 *
59440 * @param propName Name of the invalid property
59441 * @param tagName Name of the tag hosting the property
59442 * @param nodeType Type of the node hosting the property
59443 * @param lView An `LView` that represents a current component
59444 */
59445
59446
59447function handleUnknownPropertyError(propName, tagName, nodeType, lView) {
59448  // Special-case a situation when a structural directive is applied to
59449  // an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
59450  // In this case the compiler generates the `ɵɵtemplate` instruction with
59451  // the `null` as the tagName. The directive matching logic at runtime relies
59452  // on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
59453  // a default value of the `tNode.value` is not feasible at this moment.
59454  if (!tagName && nodeType === 4
59455  /* TNodeType.Container */
59456  ) {
59457    tagName = 'ng-template';
59458  }
59459
59460  const isHostStandalone = isHostComponentStandalone(lView);
59461  const templateLocation = getTemplateLocationDetails(lView);
59462  let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
59463  const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
59464  const importLocation = isHostStandalone ? 'included in the \'@Component.imports\' of this component' : 'a part of an @NgModule where this component is declared';
59465
59466  if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
59467    // Most likely this is a control flow directive (such as `*ngIf`) used in
59468    // a template, but the directive or the `CommonModule` is not imported.
59469    const correspondingImport = KNOWN_CONTROL_FLOW_DIRECTIVES.get(propName);
59470    message += `\nIf the '${propName}' is an Angular control flow directive, ` + `please make sure that either the '${correspondingImport}' directive or the 'CommonModule' is ${importLocation}.`;
59471  } else {
59472    // May be an Angular component, which is not imported/declared?
59473    message += `\n1. If '${tagName}' is an Angular component and it has the ` + `'${propName}' input, then verify that it is ${importLocation}.`; // May be a Web Component?
59474
59475    if (tagName && tagName.indexOf('-') > -1) {
59476      message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` + `to the ${schemas} of this component to suppress this message.`;
59477      message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` + `the ${schemas} of this component.`;
59478    } else {
59479      // If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
59480      message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` + `the ${schemas} of this component.`;
59481    }
59482  }
59483
59484  reportUnknownPropertyError(message);
59485}
59486
59487function reportUnknownPropertyError(message) {
59488  if (shouldThrowErrorOnUnknownProperty) {
59489    throw new RuntimeError(303
59490    /* RuntimeErrorCode.UNKNOWN_BINDING */
59491    , message);
59492  } else {
59493    console.error(formatRuntimeError(303
59494    /* RuntimeErrorCode.UNKNOWN_BINDING */
59495    , message));
59496  }
59497}
59498/**
59499 * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
59500 * and must **not** be used in production bundles. The function makes megamorphic reads, which might
59501 * be too slow for production mode and also it relies on the constructor function being available.
59502 *
59503 * Gets a reference to the host component def (where a current component is declared).
59504 *
59505 * @param lView An `LView` that represents a current component that is being rendered.
59506 */
59507
59508
59509function getDeclarationComponentDef(lView) {
59510  !ngDevMode && throwError('Must never be called in production mode');
59511  const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
59512  const context = declarationLView[CONTEXT]; // Unable to obtain a context.
59513
59514  if (!context) return null;
59515  return context.constructor ? getComponentDef(context.constructor) : null;
59516}
59517/**
59518 * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
59519 * and must **not** be used in production bundles. The function makes megamorphic reads, which might
59520 * be too slow for production mode.
59521 *
59522 * Checks if the current component is declared inside of a standalone component template.
59523 *
59524 * @param lView An `LView` that represents a current component that is being rendered.
59525 */
59526
59527
59528function isHostComponentStandalone(lView) {
59529  !ngDevMode && throwError('Must never be called in production mode');
59530  const componentDef = getDeclarationComponentDef(lView); // Treat host component as non-standalone if we can't obtain the def.
59531
59532  return !!componentDef?.standalone;
59533}
59534/**
59535 * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
59536 * and must **not** be used in production bundles. The function makes megamorphic reads, which might
59537 * be too slow for production mode.
59538 *
59539 * Constructs a string describing the location of the host component template. The function is used
59540 * in dev mode to produce error messages.
59541 *
59542 * @param lView An `LView` that represents a current component that is being rendered.
59543 */
59544
59545
59546function getTemplateLocationDetails(lView) {
59547  !ngDevMode && throwError('Must never be called in production mode');
59548  const hostComponentDef = getDeclarationComponentDef(lView);
59549  const componentClassName = hostComponentDef?.type?.name;
59550  return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
59551}
59552/**
59553 * The set of known control flow directives and their corresponding imports.
59554 * We use this set to produce a more precises error message with a note
59555 * that the `CommonModule` should also be included.
59556 */
59557
59558
59559const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([['ngIf', 'NgIf'], ['ngFor', 'NgFor'], ['ngSwitchCase', 'NgSwitchCase'], ['ngSwitchDefault', 'NgSwitchDefault']]);
59560/**
59561 * Returns true if the tag name is allowed by specified schemas.
59562 * @param schemas Array of schemas
59563 * @param tagName Name of the tag
59564 */
59565
59566function matchingSchemas(schemas, tagName) {
59567  if (schemas !== null) {
59568    for (let i = 0; i < schemas.length; i++) {
59569      const schema = schemas[i];
59570
59571      if (schema === NO_ERRORS_SCHEMA || schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
59572        return true;
59573      }
59574    }
59575  }
59576
59577  return false;
59578}
59579/**
59580 * @license
59581 * Copyright Google LLC All Rights Reserved.
59582 *
59583 * Use of this source code is governed by an MIT-style license that can be
59584 * found in the LICENSE file at https://angular.io/license
59585 */
59586
59587
59588const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
59589
59590function wrappedError(message, originalError) {
59591  const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
59592  const error = Error(msg);
59593  error[ERROR_ORIGINAL_ERROR] = originalError;
59594  return error;
59595}
59596
59597function getOriginalError(error) {
59598  return error[ERROR_ORIGINAL_ERROR];
59599}
59600/**
59601 * @license
59602 * Copyright Google LLC All Rights Reserved.
59603 *
59604 * Use of this source code is governed by an MIT-style license that can be
59605 * found in the LICENSE file at https://angular.io/license
59606 */
59607
59608/**
59609 * Provides a hook for centralized exception handling.
59610 *
59611 * The default implementation of `ErrorHandler` prints error messages to the `console`. To
59612 * intercept error handling, write a custom exception handler that replaces this default as
59613 * appropriate for your app.
59614 *
59615 * @usageNotes
59616 * ### Example
59617 *
59618 * ```
59619 * class MyErrorHandler implements ErrorHandler {
59620 *   handleError(error) {
59621 *     // do something with the exception
59622 *   }
59623 * }
59624 *
59625 * @NgModule({
59626 *   providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
59627 * })
59628 * class MyModule {}
59629 * ```
59630 *
59631 * @publicApi
59632 */
59633
59634
59635class ErrorHandler {
59636  constructor() {
59637    /**
59638     * @internal
59639     */
59640    this._console = console;
59641  }
59642
59643  handleError(error) {
59644    const originalError = this._findOriginalError(error);
59645
59646    this._console.error('ERROR', error);
59647
59648    if (originalError) {
59649      this._console.error('ORIGINAL ERROR', originalError);
59650    }
59651  }
59652  /** @internal */
59653
59654
59655  _findOriginalError(error) {
59656    let e = error && getOriginalError(error);
59657
59658    while (e && getOriginalError(e)) {
59659      e = getOriginalError(e);
59660    }
59661
59662    return e || null;
59663  }
59664
59665}
59666/**
59667 * @license
59668 * Copyright Google LLC All Rights Reserved.
59669 *
59670 * Use of this source code is governed by an MIT-style license that can be
59671 * found in the LICENSE file at https://angular.io/license
59672 */
59673
59674/**
59675 * Disallowed strings in the comment.
59676 *
59677 * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
59678 */
59679
59680
59681const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
59682/**
59683 * Delimiter in the disallowed strings which needs to be wrapped with zero with character.
59684 */
59685
59686const COMMENT_DELIMITER = /(<|>)/;
59687const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
59688/**
59689 * Escape the content of comment strings so that it can be safely inserted into a comment node.
59690 *
59691 * The issue is that HTML does not specify any way to escape comment end text inside the comment.
59692 * Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
59693 * "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
59694 * can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
59695 *
59696 * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
59697 *
59698 * ```
59699 * div.innerHTML = div.innerHTML
59700 * ```
59701 *
59702 * One would expect that the above code would be safe to do, but it turns out that because comment
59703 * text is not escaped, the comment may contain text which will prematurely close the comment
59704 * opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
59705 * may contain such text and expect them to be safe.)
59706 *
59707 * This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
59708 * surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
59709 * comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
59710 * text it will render normally but it will not cause the HTML parser to close/open the comment.
59711 *
59712 * @param value text to make safe for comment node by escaping the comment open/close character
59713 *     sequence.
59714 */
59715
59716function escapeCommentText(value) {
59717  return value.replace(COMMENT_DISALLOWED, text => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
59718}
59719/**
59720 * @license
59721 * Copyright Google LLC All Rights Reserved.
59722 *
59723 * Use of this source code is governed by an MIT-style license that can be
59724 * found in the LICENSE file at https://angular.io/license
59725 */
59726
59727
59728function normalizeDebugBindingName(name) {
59729  // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
59730  name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
59731  return `ng-reflect-${name}`;
59732}
59733
59734const CAMEL_CASE_REGEXP = /([A-Z])/g;
59735
59736function camelCaseToDashCase(input) {
59737  return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
59738}
59739
59740function normalizeDebugBindingValue(value) {
59741  try {
59742    // Limit the size of the value as otherwise the DOM just gets polluted.
59743    return value != null ? value.toString().slice(0, 30) : value;
59744  } catch (e) {
59745    return '[ERROR] Exception while trying to serialize the value';
59746  }
59747}
59748/**
59749 * @license
59750 * Copyright Google LLC All Rights Reserved.
59751 *
59752 * Use of this source code is governed by an MIT-style license that can be
59753 * found in the LICENSE file at https://angular.io/license
59754 */
59755// Keeps track of the currently-active LViews.
59756
59757
59758const TRACKED_LVIEWS = new Map(); // Used for generating unique IDs for LViews.
59759
59760let uniqueIdCounter = 0;
59761/** Gets a unique ID that can be assigned to an LView. */
59762
59763function getUniqueLViewId() {
59764  return uniqueIdCounter++;
59765}
59766/** Starts tracking an LView. */
59767
59768
59769function registerLView(lView) {
59770  ngDevMode && assertNumber(lView[ID], 'LView must have an ID in order to be registered');
59771  TRACKED_LVIEWS.set(lView[ID], lView);
59772}
59773/** Gets an LView by its unique ID. */
59774
59775
59776function getLViewById(id) {
59777  ngDevMode && assertNumber(id, 'ID used for LView lookup must be a number');
59778  return TRACKED_LVIEWS.get(id) || null;
59779}
59780/** Stops tracking an LView. */
59781
59782
59783function unregisterLView(lView) {
59784  ngDevMode && assertNumber(lView[ID], 'Cannot stop tracking an LView that does not have an ID');
59785  TRACKED_LVIEWS.delete(lView[ID]);
59786}
59787/**
59788 * @license
59789 * Copyright Google LLC All Rights Reserved.
59790 *
59791 * Use of this source code is governed by an MIT-style license that can be
59792 * found in the LICENSE file at https://angular.io/license
59793 */
59794
59795/**
59796 * The internal view context which is specific to a given DOM element, directive or
59797 * component instance. Each value in here (besides the LView and element node details)
59798 * can be present, null or undefined. If undefined then it implies the value has not been
59799 * looked up yet, otherwise, if null, then a lookup was executed and nothing was found.
59800 *
59801 * Each value will get filled when the respective value is examined within the getContext
59802 * function. The component, element and each directive instance will share the same instance
59803 * of the context.
59804 */
59805
59806
59807class LContext {
59808  constructor(
59809  /**
59810   * ID of the component's parent view data.
59811   */
59812  lViewId,
59813  /**
59814   * The index instance of the node.
59815   */
59816  nodeIndex,
59817  /**
59818   * The instance of the DOM node that is attached to the lNode.
59819   */
59820  native) {
59821    this.lViewId = lViewId;
59822    this.nodeIndex = nodeIndex;
59823    this.native = native;
59824  }
59825  /** Component's parent view data. */
59826
59827
59828  get lView() {
59829    return getLViewById(this.lViewId);
59830  }
59831
59832}
59833/**
59834 * @license
59835 * Copyright Google LLC All Rights Reserved.
59836 *
59837 * Use of this source code is governed by an MIT-style license that can be
59838 * found in the LICENSE file at https://angular.io/license
59839 */
59840
59841/**
59842 * Returns the matching `LContext` data for a given DOM node, directive or component instance.
59843 *
59844 * This function will examine the provided DOM element, component, or directive instance\'s
59845 * monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
59846 * value will be that of the newly created `LContext`.
59847 *
59848 * If the monkey-patched value is the `LView` instance then the context value for that
59849 * target will be created and the monkey-patch reference will be updated. Therefore when this
59850 * function is called it may mutate the provided element\'s, component\'s or any of the associated
59851 * directive\'s monkey-patch values.
59852 *
59853 * If the monkey-patch value is not detected then the code will walk up the DOM until an element
59854 * is found which contains a monkey-patch reference. When that occurs then the provided element
59855 * will be updated with a new context (which is then returned). If the monkey-patch value is not
59856 * detected for a component/directive instance then it will throw an error (all components and
59857 * directives should be automatically monkey-patched by ivy).
59858 *
59859 * @param target Component, Directive or DOM Node.
59860 */
59861
59862
59863function getLContext(target) {
59864  let mpValue = readPatchedData(target);
59865
59866  if (mpValue) {
59867    // only when it's an array is it considered an LView instance
59868    // ... otherwise it's an already constructed LContext instance
59869    if (isLView(mpValue)) {
59870      const lView = mpValue;
59871      let nodeIndex;
59872      let component = undefined;
59873      let directives = undefined;
59874
59875      if (isComponentInstance(target)) {
59876        nodeIndex = findViaComponent(lView, target);
59877
59878        if (nodeIndex == -1) {
59879          throw new Error('The provided component was not found in the application');
59880        }
59881
59882        component = target;
59883      } else if (isDirectiveInstance(target)) {
59884        nodeIndex = findViaDirective(lView, target);
59885
59886        if (nodeIndex == -1) {
59887          throw new Error('The provided directive was not found in the application');
59888        }
59889
59890        directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
59891      } else {
59892        nodeIndex = findViaNativeElement(lView, target);
59893
59894        if (nodeIndex == -1) {
59895          return null;
59896        }
59897      } // the goal is not to fill the entire context full of data because the lookups
59898      // are expensive. Instead, only the target data (the element, component, container, ICU
vendor: 4,954 bytes, lines 59899-60062
59899      // expression or directive details) are filled into the context. If called multiple times
59900      // with different target values then the missing target data will be filled in.
59901
59902
59903      const native = unwrapRNode(lView[nodeIndex]);
59904      const existingCtx = readPatchedData(native);
59905      const context = existingCtx && !Array.isArray(existingCtx) ? existingCtx : createLContext(lView, nodeIndex, native); // only when the component has been discovered then update the monkey-patch
59906
59907      if (component && context.component === undefined) {
59908        context.component = component;
59909        attachPatchData(context.component, context);
59910      } // only when the directives have been discovered then update the monkey-patch
59911
59912
59913      if (directives && context.directives === undefined) {
59914        context.directives = directives;
59915
59916        for (let i = 0; i < directives.length; i++) {
59917          attachPatchData(directives[i], context);
59918        }
59919      }
59920
59921      attachPatchData(context.native, context);
59922      mpValue = context;
59923    }
59924  } else {
59925    const rElement = target;
59926    ngDevMode && assertDomNode(rElement); // if the context is not found then we need to traverse upwards up the DOM
59927    // to find the nearest element that has already been monkey patched with data
59928
59929    let parent = rElement;
59930
59931    while (parent = parent.parentNode) {
59932      const parentContext = readPatchedData(parent);
59933
59934      if (parentContext) {
59935        const lView = Array.isArray(parentContext) ? parentContext : parentContext.lView; // the edge of the app was also reached here through another means
59936        // (maybe because the DOM was changed manually).
59937
59938        if (!lView) {
59939          return null;
59940        }
59941
59942        const index = findViaNativeElement(lView, rElement);
59943
59944        if (index >= 0) {
59945          const native = unwrapRNode(lView[index]);
59946          const context = createLContext(lView, index, native);
59947          attachPatchData(native, context);
59948          mpValue = context;
59949          break;
59950        }
59951      }
59952    }
59953  }
59954
59955  return mpValue || null;
59956}
59957/**
59958 * Creates an empty instance of a `LContext` context
59959 */
59960
59961
59962function createLContext(lView, nodeIndex, native) {
59963  return new LContext(lView[ID], nodeIndex, native);
59964}
59965/**
59966 * Takes a component instance and returns the view for that component.
59967 *
59968 * @param componentInstance
59969 * @returns The component's view
59970 */
59971
59972
59973function getComponentViewByInstance(componentInstance) {
59974  let patchedData = readPatchedData(componentInstance);
59975  let lView;
59976
59977  if (isLView(patchedData)) {
59978    const contextLView = patchedData;
59979    const nodeIndex = findViaComponent(contextLView, componentInstance);
59980    lView = getComponentLViewByIndex(nodeIndex, contextLView);
59981    const context = createLContext(contextLView, nodeIndex, lView[HOST]);
59982    context.component = componentInstance;
59983    attachPatchData(componentInstance, context);
59984    attachPatchData(context.native, context);
59985  } else {
59986    const context = patchedData;
59987    const contextLView = context.lView;
59988    ngDevMode && assertLView(contextLView);
59989    lView = getComponentLViewByIndex(context.nodeIndex, contextLView);
59990  }
59991
59992  return lView;
59993}
59994/**
59995 * This property will be monkey-patched on elements, components and directives.
59996 */
59997
59998
59999const MONKEY_PATCH_KEY_NAME = '__ngContext__';
60000/**
60001 * Assigns the given data to the given target (which could be a component,
60002 * directive or DOM node instance) using monkey-patching.
60003 */
60004
60005function attachPatchData(target, data) {
60006  ngDevMode && assertDefined(target, 'Target expected'); // Only attach the ID of the view in order to avoid memory leaks (see #41047). We only do this
60007  // for `LView`, because we have control over when an `LView` is created and destroyed, whereas
60008  // we can't know when to remove an `LContext`.
60009
60010  if (isLView(data)) {
60011    target[MONKEY_PATCH_KEY_NAME] = data[ID];
60012    registerLView(data);
60013  } else {
60014    target[MONKEY_PATCH_KEY_NAME] = data;
60015  }
60016}
60017/**
60018 * Returns the monkey-patch value data present on the target (which could be
60019 * a component, directive or a DOM node).
60020 */
60021
60022
60023function readPatchedData(target) {
60024  ngDevMode && assertDefined(target, 'Target expected');
60025  const data = target[MONKEY_PATCH_KEY_NAME];
60026  return typeof data === 'number' ? getLViewById(data) : data || null;
60027}
60028
60029function readPatchedLView(target) {
60030  const value = readPatchedData(target);
60031
60032  if (value) {
60033    return isLView(value) ? value : value.lView;
60034  }
60035
60036  return null;
60037}
60038
60039function isComponentInstance(instance) {
60040  return instance && instance.constructor && instance.constructor.ɵcmp;
60041}
60042
60043function isDirectiveInstance(instance) {
60044  return instance && instance.constructor && instance.constructor.ɵdir;
60045}
60046/**
60047 * Locates the element within the given LView and returns the matching index
60048 */
60049
60050
60051function findViaNativeElement(lView, target) {
60052  const tView = lView[TVIEW];
60053
60054  for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
60055    if (unwrapRNode(lView[i]) === target) {
60056      return i;
60057    }
60058  }
60059
60060  return -1;
60061}
60062/**
60063 * Locates the next tNode (child, sibling or parent).
60064 */
60065
60066
60067function traverseNextElement(tNode) {
60068  if (tNode.child) {
60069    return tNode.child;
60070  } else if (tNode.next) {
60071    return tNode.next;
60072  } else {
60073    // Let's take the following template: <div><span>text</span></div><component/>
60074    // After checking the text node, we need to find the next parent that has a "next" TNode,
60075    // in this case the parent `div`, so that we can find the component.
60076    while (tNode.parent && !tNode.parent.next) {
60077      tNode = tNode.parent;
60078    }
60079
60080    return tNode.parent && tNode.parent.next;
60081  }
60082}
60083/**
60084 * Locates the component within the given LView and returns the matching index
60085 */
60086
60087
60088function findViaComponent(lView, componentInstance) {
60089  const componentIndices = lView[TVIEW].components;
60090
60091  if (componentIndices) {
60092    for (let i = 0; i < componentIndices.length; i++) {
60093      const elementComponentIndex = componentIndices[i];
60094      const componentView = getComponentLViewByIndex(elementComponentIndex, lView);
60095
60096      if (componentView[CONTEXT] === componentInstance) {
60097        return elementComponentIndex;
60098      }
60099    }
60100  } else {
60101    const rootComponentView = getComponentLViewByIndex(HEADER_OFFSET, lView);
60102    const rootComponent = rootComponentView[CONTEXT];
60103
60104    if (rootComponent === componentInstance) {
60105      // we are dealing with the root element here therefore we know that the
60106      // element is the very first element after the HEADER data in the lView
60107      return HEADER_OFFSET;
60108    }
60109  }
60110
60111  return -1;
60112}
60113/**
60114 * Locates the directive within the given LView and returns the matching index
60115 */
60116
60117
60118function findViaDirective(lView, directiveInstance) {
60119  // if a directive is monkey patched then it will (by default)
60120  // have a reference to the LView of the current view. The
60121  // element bound to the directive being search lives somewhere
60122  // in the view data. We loop through the nodes and check their
60123  // list of directives for the instance.
60124  let tNode = lView[TVIEW].firstChild;
60125
60126  while (tNode) {
60127    const directiveIndexStart = tNode.directiveStart;
60128    const directiveIndexEnd = tNode.directiveEnd;
60129
60130    for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {
60131      if (lView[i] === directiveInstance) {
60132        return tNode.index;
60133      }
60134    }
60135
60136    tNode = traverseNextElement(tNode);
60137  }
60138
60139  return -1;
60140}
60141/**
60142 * Returns a list of directives extracted from the given view based on the
60143 * provided list of directive index values.
60144 *
60145 * @param nodeIndex The node index
60146 * @param lView The target view data
60147 * @param includeComponents Whether or not to include components in returned directives
60148 */
60149
60150
60151function getDirectivesAtNodeIndex(nodeIndex, lView, includeComponents) {
60152  const tNode = lView[TVIEW].data[nodeIndex];
60153  let directiveStartIndex = tNode.directiveStart;
60154  if (directiveStartIndex == 0) return EMPTY_ARRAY;
60155  const directiveEndIndex = tNode.directiveEnd;
60156  if (!includeComponents && tNode.flags & 2
60157  /* TNodeFlags.isComponentHost */
60158  ) directiveStartIndex++;
60159  return lView.slice(directiveStartIndex, directiveEndIndex);
60160}
60161
60162function getComponentAtNodeIndex(nodeIndex, lView) {
60163  const tNode = lView[TVIEW].data[nodeIndex];
60164  let directiveStartIndex = tNode.directiveStart;
60165  return tNode.flags & 2
60166  /* TNodeFlags.isComponentHost */
60167  ? lView[directiveStartIndex] : null;
60168}
60169/**
60170 * Returns a map of local references (local reference name => element or directive instance) that
60171 * exist on a given element.
60172 */
60173
60174
60175function discoverLocalRefs(lView, nodeIndex) {
60176  const tNode = lView[TVIEW].data[nodeIndex];
60177
60178  if (tNode && tNode.localNames) {
60179    const result = {};
60180    let localIndex = tNode.index + 1;
60181
60182    for (let i = 0; i < tNode.localNames.length; i += 2) {
60183      result[tNode.localNames[i]] = lView[localIndex];
60184      localIndex++;
60185    }
60186
60187    return result;
60188  }
60189
60190  return null;
60191}
60192/**
60193 * @license
60194 * Copyright Google LLC All Rights Reserved.
60195 *
60196 * Use of this source code is governed by an MIT-style license that can be
60197 * found in the LICENSE file at https://angular.io/license
60198 */
60199
60200/**
60201 *
60202 * @codeGenApi
60203 */
60204
60205
60206function ɵɵresolveWindow(element) {
60207  return element.ownerDocument.defaultView;
60208}
60209/**
60210 *
60211 * @codeGenApi
60212 */
60213
60214
60215function ɵɵresolveDocument(element) {
60216  return element.ownerDocument;
60217}
60218/**
60219 *
60220 * @codeGenApi
60221 */
60222
60223
60224function ɵɵresolveBody(element) {
60225  return element.ownerDocument.body;
60226}
60227/**
60228 * The special delimiter we use to separate property names, prefixes, and suffixes
60229 * in property binding metadata. See storeBindingMetadata().
60230 *
60231 * We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
60232 * because it is a very uncommon character that is unlikely to be part of a user's
60233 * property names or interpolation strings. If it is in fact used in a property
60234 * binding, DebugElement.properties will not return the correct value for that
60235 * binding. However, there should be no runtime effect for real applications.
60236 *
60237 * This character is typically rendered as a question mark inside of a diamond.
60238 * See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
60239 *
60240 */
60241
60242
60243const INTERPOLATION_DELIMITER = `�`;
60244/**
60245 * Unwrap a value which might be behind a closure (for forward declaration reasons).
60246 */
60247
60248function maybeUnwrapFn(value) {
60249  if (value instanceof Function) {
60250    return value();
60251  } else {
60252    return value;
60253  }
60254}
60255/**
60256 * @license
60257 * Copyright Google LLC All Rights Reserved.
60258 *
60259 * Use of this source code is governed by an MIT-style license that can be
60260 * found in the LICENSE file at https://angular.io/license
60261 */
60262
60263/** Verifies that a given type is a Standalone Component. */
60264
60265
60266function assertStandaloneComponentType(type) {
60267  assertComponentDef(type);
60268  const componentDef = getComponentDef(type);
60269
60270  if (!componentDef.standalone) {
60271    throw new RuntimeError(907
60272    /* RuntimeErrorCode.TYPE_IS_NOT_STANDALONE */
60273    , `The ${stringifyForError(type)} component is not marked as standalone, ` + `but Angular expects to have a standalone component here. ` + `Please make sure the ${stringifyForError(type)} component has ` + `the \`standalone: true\` flag in the decorator.`);
60274  }
60275}
60276/** Verifies whether a given type is a component */
60277
60278
60279function assertComponentDef(type) {
60280  if (!getComponentDef(type)) {
60281    throw new RuntimeError(906
60282    /* RuntimeErrorCode.MISSING_GENERATED_DEF */
60283    , `The ${stringifyForError(type)} is not an Angular component, ` + `make sure it has the \`@Component\` decorator.`);
60284  }
60285}
60286/** Called when there are multiple component selectors that match a given node */
60287
60288
60289function throwMultipleComponentError(tNode, first, second) {
60290  throw new RuntimeError(-300
60291  /* RuntimeErrorCode.MULTIPLE_COMPONENTS_MATCH */
60292  , `Multiple components match node with tagname ${tNode.value}: ` + `${stringifyForError(first)} and ` + `${stringifyForError(second)}`);
60293}
60294/** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */
60295
60296
vendor: 50,051 bytes, lines 60297-61754
60297function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName) {
60298  const field = propName ? ` for '${propName}'` : '';
60299  let msg = `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value${field}: '${oldValue}'. Current value: '${currValue}'.`;
60300
60301  if (creationMode) {
60302    msg += ` It seems like the view has been created after its parent and its children have been dirty checked.` + ` Has it been created in a change detection hook?`;
60303  }
60304
60305  throw new RuntimeError(-100
60306  /* RuntimeErrorCode.EXPRESSION_CHANGED_AFTER_CHECKED */
60307  , msg);
60308}
60309
60310function constructDetailsForInterpolation(lView, rootIndex, expressionIndex, meta, changedValue) {
60311  const [propName, prefix, ...chunks] = meta.split(INTERPOLATION_DELIMITER);
60312  let oldValue = prefix,
60313      newValue = prefix;
60314
60315  for (let i = 0; i < chunks.length; i++) {
60316    const slotIdx = rootIndex + i;
60317    oldValue += `${lView[slotIdx]}${chunks[i]}`;
60318    newValue += `${slotIdx === expressionIndex ? changedValue : lView[slotIdx]}${chunks[i]}`;
60319  }
60320
60321  return {
60322    propName,
60323    oldValue,
60324    newValue
60325  };
60326}
60327/**
60328 * Constructs an object that contains details for the ExpressionChangedAfterItHasBeenCheckedError:
60329 * - property name (for property bindings or interpolations)
60330 * - old and new values, enriched using information from metadata
60331 *
60332 * More information on the metadata storage format can be found in `storePropertyBindingMetadata`
60333 * function description.
60334 */
60335
60336
60337function getExpressionChangedErrorDetails(lView, bindingIndex, oldValue, newValue) {
60338  const tData = lView[TVIEW].data;
60339  const metadata = tData[bindingIndex];
60340
60341  if (typeof metadata === 'string') {
60342    // metadata for property interpolation
60343    if (metadata.indexOf(INTERPOLATION_DELIMITER) > -1) {
60344      return constructDetailsForInterpolation(lView, bindingIndex, bindingIndex, metadata, newValue);
60345    } // metadata for property binding
60346
60347
60348    return {
60349      propName: metadata,
60350      oldValue,
60351      newValue
60352    };
60353  } // metadata is not available for this expression, check if this expression is a part of the
60354  // property interpolation by going from the current binding index left and look for a string that
60355  // contains INTERPOLATION_DELIMITER, the layout in tView.data for this case will look like this:
60356  // [..., 'id�Prefix � and � suffix', null, null, null, ...]
60357
60358
60359  if (metadata === null) {
60360    let idx = bindingIndex - 1;
60361
60362    while (typeof tData[idx] !== 'string' && tData[idx + 1] === null) {
60363      idx--;
60364    }
60365
60366    const meta = tData[idx];
60367
60368    if (typeof meta === 'string') {
60369      const matches = meta.match(new RegExp(INTERPOLATION_DELIMITER, 'g')); // first interpolation delimiter separates property name from interpolation parts (in case of
60370      // property interpolations), so we subtract one from total number of found delimiters
60371
60372      if (matches && matches.length - 1 > bindingIndex - idx) {
60373        return constructDetailsForInterpolation(lView, idx, bindingIndex, meta, newValue);
60374      }
60375    }
60376  }
60377
60378  return {
60379    propName: undefined,
60380    oldValue,
60381    newValue
60382  };
60383}
60384/**
60385 * @license
60386 * Copyright Google LLC All Rights Reserved.
60387 *
60388 * Use of this source code is governed by an MIT-style license that can be
60389 * found in the LICENSE file at https://angular.io/license
60390 */
60391
60392/**
60393 * Flags for renderer-specific style modifiers.
60394 * @publicApi
60395 */
60396
60397
60398var RendererStyleFlags2;
60399
60400(function (RendererStyleFlags2) {
60401  // TODO(misko): This needs to be refactored into a separate file so that it can be imported from
60402  // `node_manipulation.ts` Currently doing the import cause resolution order to change and fails
60403  // the tests. The work around is to have hard coded value in `node_manipulation.ts` for now.
60404
60405  /**
60406   * Marks a style as important.
60407   */
60408  RendererStyleFlags2[RendererStyleFlags2["Important"] = 1] = "Important";
60409  /**
60410   * Marks a style as using dash case naming (this-is-dash-case).
60411   */
60412
60413  RendererStyleFlags2[RendererStyleFlags2["DashCase"] = 2] = "DashCase";
60414})(RendererStyleFlags2 || (RendererStyleFlags2 = {}));
60415/**
60416 * @license
60417 * Copyright Google LLC All Rights Reserved.
60418 *
60419 * Use of this source code is governed by an MIT-style license that can be
60420 * found in the LICENSE file at https://angular.io/license
60421 */
60422
60423
60424let _icuContainerIterate;
60425/**
60426 * Iterator which provides ability to visit all of the `TIcuContainerNode` root `RNode`s.
60427 */
60428
60429
60430function icuContainerIterate(tIcuContainerNode, lView) {
60431  return _icuContainerIterate(tIcuContainerNode, lView);
60432}
60433/**
60434 * Ensures that `IcuContainerVisitor`'s implementation is present.
60435 *
60436 * This function is invoked when i18n instruction comes across an ICU. The purpose is to allow the
60437 * bundler to tree shake ICU logic and only load it if ICU instruction is executed.
60438 */
60439
60440
60441function ensureIcuContainerVisitorLoaded(loader) {
60442  if (_icuContainerIterate === undefined) {
60443    // Do not inline this function. We want to keep `ensureIcuContainerVisitorLoaded` light, so it
60444    // can be inlined into call-site.
60445    _icuContainerIterate = loader();
60446  }
60447}
60448/**
60449 * @license
60450 * Copyright Google LLC All Rights Reserved.
60451 *
60452 * Use of this source code is governed by an MIT-style license that can be
60453 * found in the LICENSE file at https://angular.io/license
60454 */
60455// Note: This hack is necessary so we don't erroneously get a circular dependency
60456// failure based on types.
60457
60458
60459const unusedValueExportToPlacateAjd$4 = 1;
60460/**
60461 * @license
60462 * Copyright Google LLC All Rights Reserved.
60463 *
60464 * Use of this source code is governed by an MIT-style license that can be
60465 * found in the LICENSE file at https://angular.io/license
60466 */
60467// Note: This hack is necessary so we don't erroneously get a circular dependency
60468// failure based on types.
60469
60470const unusedValueExportToPlacateAjd$3 = 1;
60471/**
60472 * @license
60473 * Copyright Google LLC All Rights Reserved.
60474 *
60475 * Use of this source code is governed by an MIT-style license that can be
60476 * found in the LICENSE file at https://angular.io/license
60477 */
60478
60479/**
60480 * Gets the parent LView of the passed LView, if the PARENT is an LContainer, will get the parent of
60481 * that LContainer, which is an LView
60482 * @param lView the lView whose parent to get
60483 */
60484
60485function getLViewParent(lView) {
60486  ngDevMode && assertLView(lView);
60487  const parent = lView[PARENT];
60488  return isLContainer(parent) ? parent[PARENT] : parent;
60489}
60490/**
60491 * Retrieve the root view from any component or `LView` by walking the parent `LView` until
60492 * reaching the root `LView`.
60493 *
60494 * @param componentOrLView any component or `LView`
60495 */
60496
60497
60498function getRootView(componentOrLView) {
60499  ngDevMode && assertDefined(componentOrLView, 'component');
60500  let lView = isLView(componentOrLView) ? componentOrLView : readPatchedLView(componentOrLView);
60501
60502  while (lView && !(lView[FLAGS] & 256
60503  /* LViewFlags.IsRoot */
60504  )) {
60505    lView = getLViewParent(lView);
60506  }
60507
60508  ngDevMode && assertLView(lView);
60509  return lView;
60510}
60511/**
60512 * Returns the context information associated with the application where the target is situated. It
60513 * does this by walking the parent views until it gets to the root view, then getting the context
60514 * off of that.
60515 *
60516 * @param viewOrComponent the `LView` or component to get the root context for.
60517 */
60518
60519
60520function getRootContext(viewOrComponent) {
60521  const rootView = getRootView(viewOrComponent);
60522  ngDevMode && assertDefined(rootView[CONTEXT], 'Root view has no context. Perhaps it is disconnected?');
60523  return rootView[CONTEXT];
60524}
60525/**
60526 * Gets the first `LContainer` in the LView or `null` if none exists.
60527 */
60528
60529
60530function getFirstLContainer(lView) {
60531  return getNearestLContainer(lView[CHILD_HEAD]);
60532}
60533/**
60534 * Gets the next `LContainer` that is a sibling of the given container.
60535 */
60536
60537
60538function getNextLContainer(container) {
60539  return getNearestLContainer(container[NEXT]);
60540}
60541
60542function getNearestLContainer(viewOrContainer) {
60543  while (viewOrContainer !== null && !isLContainer(viewOrContainer)) {
60544    viewOrContainer = viewOrContainer[NEXT];
60545  }
60546
60547  return viewOrContainer;
60548}
60549/**
60550 * @license
60551 * Copyright Google LLC All Rights Reserved.
60552 *
60553 * Use of this source code is governed by an MIT-style license that can be
60554 * found in the LICENSE file at https://angular.io/license
60555 */
60556
60557
60558const unusedValueToPlacateAjd$2 = unusedValueExportToPlacateAjd$7 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3 + unusedValueExportToPlacateAjd$8;
60559/**
60560 * NOTE: for performance reasons, the possible actions are inlined within the function instead of
60561 * being passed as an argument.
60562 */
60563
60564function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode) {
60565  // If this slot was allocated for a text node dynamically created by i18n, the text node itself
60566  // won't be created until i18nApply() in the update block, so this node should be skipped.
60567  // For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
60568  // in `i18n_spec.ts`.
60569  if (lNodeToHandle != null) {
60570    let lContainer;
60571    let isComponent = false; // We are expecting an RNode, but in the case of a component or LContainer the `RNode` is
60572    // wrapped in an array which needs to be unwrapped. We need to know if it is a component and if
60573    // it has LContainer so that we can process all of those cases appropriately.
60574
60575    if (isLContainer(lNodeToHandle)) {
60576      lContainer = lNodeToHandle;
60577    } else if (isLView(lNodeToHandle)) {
60578      isComponent = true;
60579      ngDevMode && assertDefined(lNodeToHandle[HOST], 'HOST must be defined for a component LView');
60580      lNodeToHandle = lNodeToHandle[HOST];
60581    }
60582
60583    const rNode = unwrapRNode(lNodeToHandle);
60584
60585    if (action === 0
60586    /* WalkTNodeTreeAction.Create */
60587    && parent !== null) {
60588      if (beforeNode == null) {
60589        nativeAppendChild(renderer, parent, rNode);
60590      } else {
60591        nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
60592      }
60593    } else if (action === 1
60594    /* WalkTNodeTreeAction.Insert */
60595    && parent !== null) {
60596      nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
60597    } else if (action === 2
60598    /* WalkTNodeTreeAction.Detach */
60599    ) {
60600      nativeRemoveNode(renderer, rNode, isComponent);
60601    } else if (action === 3
60602    /* WalkTNodeTreeAction.Destroy */
60603    ) {
60604      ngDevMode && ngDevMode.rendererDestroyNode++;
60605      renderer.destroyNode(rNode);
60606    }
60607
60608    if (lContainer != null) {
60609      applyContainer(renderer, action, lContainer, parent, beforeNode);
60610    }
60611  }
60612}
60613
60614function createTextNode(renderer, value) {
60615  ngDevMode && ngDevMode.rendererCreateTextNode++;
60616  ngDevMode && ngDevMode.rendererSetText++;
60617  return renderer.createText(value);
60618}
60619
60620function updateTextNode(renderer, rNode, value) {
60621  ngDevMode && ngDevMode.rendererSetText++;
60622  renderer.setValue(rNode, value);
60623}
60624
60625function createCommentNode(renderer, value) {
60626  ngDevMode && ngDevMode.rendererCreateComment++;
60627  return renderer.createComment(escapeCommentText(value));
60628}
60629/**
60630 * Creates a native element from a tag name, using a renderer.
60631 * @param renderer A renderer to use
60632 * @param name the tag name
60633 * @param namespace Optional namespace for element.
60634 * @returns the element created
60635 */
60636
60637
60638function createElementNode(renderer, name, namespace) {
60639  ngDevMode && ngDevMode.rendererCreateElement++;
60640  return renderer.createElement(name, namespace);
60641}
60642/**
60643 * Removes all DOM elements associated with a view.
60644 *
60645 * Because some root nodes of the view may be containers, we sometimes need
60646 * to propagate deeply into the nested containers to remove all elements in the
60647 * views beneath it.
60648 *
60649 * @param tView The `TView' of the `LView` from which elements should be added or removed
60650 * @param lView The view from which elements should be added or removed
60651 */
60652
60653
60654function removeViewFromContainer(tView, lView) {
60655  const renderer = lView[RENDERER];
60656  applyView(tView, lView, renderer, 2
60657  /* WalkTNodeTreeAction.Detach */
60658  , null, null);
60659  lView[HOST] = null;
60660  lView[T_HOST] = null;
60661}
60662/**
60663 * Adds all DOM elements associated with a view.
60664 *
60665 * Because some root nodes of the view may be containers, we sometimes need
60666 * to propagate deeply into the nested containers to add all elements in the
60667 * views beneath it.
60668 *
60669 * @param tView The `TView' of the `LView` from which elements should be added or removed
60670 * @param parentTNode The `TNode` where the `LView` should be attached to.
60671 * @param renderer Current renderer to use for DOM manipulations.
60672 * @param lView The view from which elements should be added or removed
60673 * @param parentNativeNode The parent `RElement` where it should be inserted into.
60674 * @param beforeNode The node before which elements should be added, if insert mode
60675 */
60676
60677
60678function addViewToContainer(tView, parentTNode, renderer, lView, parentNativeNode, beforeNode) {
60679  lView[HOST] = parentNativeNode;
60680  lView[T_HOST] = parentTNode;
60681  applyView(tView, lView, renderer, 1
60682  /* WalkTNodeTreeAction.Insert */
60683  , parentNativeNode, beforeNode);
60684}
60685/**
60686 * Detach a `LView` from the DOM by detaching its nodes.
60687 *
60688 * @param tView The `TView' of the `LView` to be detached
60689 * @param lView the `LView` to be detached.
60690 */
60691
60692
60693function renderDetachView(tView, lView) {
60694  applyView(tView, lView, lView[RENDERER], 2
60695  /* WalkTNodeTreeAction.Detach */
60696  , null, null);
60697}
60698/**
60699 * Traverses down and up the tree of views and containers to remove listeners and
60700 * call onDestroy callbacks.
60701 *
60702 * Notes:
60703 *  - Because it's used for onDestroy calls, it needs to be bottom-up.
60704 *  - Must process containers instead of their views to avoid splicing
60705 *  when views are destroyed and re-added.
60706 *  - Using a while loop because it's faster than recursion
60707 *  - Destroy only called on movement to sibling or movement to parent (laterally or up)
60708 *
60709 *  @param rootView The view to destroy
60710 */
60711
60712
60713function destroyViewTree(rootView) {
60714  // If the view has no children, we can clean it up and return early.
60715  let lViewOrLContainer = rootView[CHILD_HEAD];
60716
60717  if (!lViewOrLContainer) {
60718    return cleanUpView(rootView[TVIEW], rootView);
60719  }
60720
60721  while (lViewOrLContainer) {
60722    let next = null;
60723
60724    if (isLView(lViewOrLContainer)) {
60725      // If LView, traverse down to child.
60726      next = lViewOrLContainer[CHILD_HEAD];
60727    } else {
60728      ngDevMode && assertLContainer(lViewOrLContainer); // If container, traverse down to its first LView.
60729
60730      const firstView = lViewOrLContainer[CONTAINER_HEADER_OFFSET];
60731      if (firstView) next = firstView;
60732    }
60733
60734    if (!next) {
60735      // Only clean up view when moving to the side or up, as destroy hooks
60736      // should be called in order from the bottom up.
60737      while (lViewOrLContainer && !lViewOrLContainer[NEXT] && lViewOrLContainer !== rootView) {
60738        if (isLView(lViewOrLContainer)) {
60739          cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
60740        }
60741
60742        lViewOrLContainer = lViewOrLContainer[PARENT];
60743      }
60744
60745      if (lViewOrLContainer === null) lViewOrLContainer = rootView;
60746
60747      if (isLView(lViewOrLContainer)) {
60748        cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
60749      }
60750
60751      next = lViewOrLContainer && lViewOrLContainer[NEXT];
60752    }
60753
60754    lViewOrLContainer = next;
60755  }
60756}
60757/**
60758 * Inserts a view into a container.
60759 *
60760 * This adds the view to the container's array of active views in the correct
60761 * position. It also adds the view's elements to the DOM if the container isn't a
60762 * root node of another view (in that case, the view's elements will be added when
60763 * the container's parent view is added later).
60764 *
60765 * @param tView The `TView' of the `LView` to insert
60766 * @param lView The view to insert
60767 * @param lContainer The container into which the view should be inserted
60768 * @param index Which index in the container to insert the child view into
60769 */
60770
60771
60772function insertView(tView, lView, lContainer, index) {
60773  ngDevMode && assertLView(lView);
60774  ngDevMode && assertLContainer(lContainer);
60775  const indexInContainer = CONTAINER_HEADER_OFFSET + index;
60776  const containerLength = lContainer.length;
60777
60778  if (index > 0) {
60779    // This is a new view, we need to add it to the children.
60780    lContainer[indexInContainer - 1][NEXT] = lView;
60781  }
60782
60783  if (index < containerLength - CONTAINER_HEADER_OFFSET) {
60784    lView[NEXT] = lContainer[indexInContainer];
60785    addToArray(lContainer, CONTAINER_HEADER_OFFSET + index, lView);
60786  } else {
60787    lContainer.push(lView);
60788    lView[NEXT] = null;
60789  }
60790
60791  lView[PARENT] = lContainer; // track views where declaration and insertion points are different
60792
60793  const declarationLContainer = lView[DECLARATION_LCONTAINER];
60794
60795  if (declarationLContainer !== null && lContainer !== declarationLContainer) {
60796    trackMovedView(declarationLContainer, lView);
60797  } // notify query that a new view has been added
60798
60799
60800  const lQueries = lView[QUERIES];
60801
60802  if (lQueries !== null) {
60803    lQueries.insertView(tView);
60804  } // Sets the attached flag
60805
60806
60807  lView[FLAGS] |= 64
60808  /* LViewFlags.Attached */
60809  ;
60810}
60811/**
60812 * Track views created from the declaration container (TemplateRef) and inserted into a
60813 * different LContainer.
60814 */
60815
60816
60817function trackMovedView(declarationContainer, lView) {
60818  ngDevMode && assertDefined(lView, 'LView required');
60819  ngDevMode && assertLContainer(declarationContainer);
60820  const movedViews = declarationContainer[MOVED_VIEWS];
60821  const insertedLContainer = lView[PARENT];
60822  ngDevMode && assertLContainer(insertedLContainer);
60823  const insertedComponentLView = insertedLContainer[PARENT][DECLARATION_COMPONENT_VIEW];
60824  ngDevMode && assertDefined(insertedComponentLView, 'Missing insertedComponentLView');
60825  const declaredComponentLView = lView[DECLARATION_COMPONENT_VIEW];
60826  ngDevMode && assertDefined(declaredComponentLView, 'Missing declaredComponentLView');
60827
60828  if (declaredComponentLView !== insertedComponentLView) {
60829    // At this point the declaration-component is not same as insertion-component; this means that
60830    // this is a transplanted view. Mark the declared lView as having transplanted views so that
60831    // those views can participate in CD.
60832    declarationContainer[HAS_TRANSPLANTED_VIEWS] = true;
60833  }
60834
60835  if (movedViews === null) {
60836    declarationContainer[MOVED_VIEWS] = [lView];
60837  } else {
60838    movedViews.push(lView);
60839  }
60840}
60841
60842function detachMovedView(declarationContainer, lView) {
60843  ngDevMode && assertLContainer(declarationContainer);
60844  ngDevMode && assertDefined(declarationContainer[MOVED_VIEWS], 'A projected view should belong to a non-empty projected views collection');
60845  const movedViews = declarationContainer[MOVED_VIEWS];
60846  const declarationViewIndex = movedViews.indexOf(lView);
60847  const insertionLContainer = lView[PARENT];
60848  ngDevMode && assertLContainer(insertionLContainer); // If the view was marked for refresh but then detached before it was checked (where the flag
60849  // would be cleared and the counter decremented), we need to decrement the view counter here
60850  // instead.
60851
60852  if (lView[FLAGS] & 512
60853  /* LViewFlags.RefreshTransplantedView */
60854  ) {
60855    lView[FLAGS] &= ~512
60856    /* LViewFlags.RefreshTransplantedView */
60857    ;
60858    updateTransplantedViewCount(insertionLContainer, -1);
60859  }
60860
60861  movedViews.splice(declarationViewIndex, 1);
60862}
60863/**
60864 * Detaches a view from a container.
60865 *
60866 * This method removes the view from the container's array of active views. It also
60867 * removes the view's elements from the DOM.
60868 *
60869 * @param lContainer The container from which to detach a view
60870 * @param removeIndex The index of the view to detach
60871 * @returns Detached LView instance.
60872 */
60873
60874
60875function detachView(lContainer, removeIndex) {
60876  if (lContainer.length <= CONTAINER_HEADER_OFFSET) return;
60877  const indexInContainer = CONTAINER_HEADER_OFFSET + removeIndex;
60878  const viewToDetach = lContainer[indexInContainer];
60879
60880  if (viewToDetach) {
60881    const declarationLContainer = viewToDetach[DECLARATION_LCONTAINER];
60882
60883    if (declarationLContainer !== null && declarationLContainer !== lContainer) {
60884      detachMovedView(declarationLContainer, viewToDetach);
60885    }
60886
60887    if (removeIndex > 0) {
60888      lContainer[indexInContainer - 1][NEXT] = viewToDetach[NEXT];
60889    }
60890
60891    const removedLView = removeFromArray(lContainer, CONTAINER_HEADER_OFFSET + removeIndex);
60892    removeViewFromContainer(viewToDetach[TVIEW], viewToDetach); // notify query that a view has been removed
60893
60894    const lQueries = removedLView[QUERIES];
60895
60896    if (lQueries !== null) {
60897      lQueries.detachView(removedLView[TVIEW]);
60898    }
60899
60900    viewToDetach[PARENT] = null;
60901    viewToDetach[NEXT] = null; // Unsets the attached flag
60902
60903    viewToDetach[FLAGS] &= ~64
60904    /* LViewFlags.Attached */
60905    ;
60906  }
60907
60908  return viewToDetach;
60909}
60910/**
60911 * A standalone function which destroys an LView,
60912 * conducting clean up (e.g. removing listeners, calling onDestroys).
60913 *
60914 * @param tView The `TView' of the `LView` to be destroyed
60915 * @param lView The view to be destroyed.
60916 */
60917
60918
60919function destroyLView(tView, lView) {
60920  if (!(lView[FLAGS] & 128
60921  /* LViewFlags.Destroyed */
60922  )) {
60923    const renderer = lView[RENDERER];
60924
60925    if (renderer.destroyNode) {
60926      applyView(tView, lView, renderer, 3
60927      /* WalkTNodeTreeAction.Destroy */
60928      , null, null);
60929    }
60930
60931    destroyViewTree(lView);
60932  }
60933}
60934/**
60935 * Calls onDestroys hooks for all directives and pipes in a given view and then removes all
60936 * listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks
60937 * can be propagated to @Output listeners.
60938 *
60939 * @param tView `TView` for the `LView` to clean up.
60940 * @param lView The LView to clean up
60941 */
60942
60943
60944function cleanUpView(tView, lView) {
60945  if (!(lView[FLAGS] & 128
60946  /* LViewFlags.Destroyed */
60947  )) {
60948    // Usually the Attached flag is removed when the view is detached from its parent, however
60949    // if it's a root view, the flag won't be unset hence why we're also removing on destroy.
60950    lView[FLAGS] &= ~64
60951    /* LViewFlags.Attached */
60952    ; // Mark the LView as destroyed *before* executing the onDestroy hooks. An onDestroy hook
60953    // runs arbitrary user code, which could include its own `viewRef.destroy()` (or similar). If
60954    // We don't flag the view as destroyed before the hooks, this could lead to an infinite loop.
60955    // This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is
60956    // really more of an "afterDestroy" hook if you think about it.
60957
60958    lView[FLAGS] |= 128
60959    /* LViewFlags.Destroyed */
60960    ;
60961    executeOnDestroys(tView, lView);
60962    processCleanups(tView, lView); // For component views only, the local renderer is destroyed at clean up time.
60963
60964    if (lView[TVIEW].type === 1
60965    /* TViewType.Component */
60966    ) {
60967      ngDevMode && ngDevMode.rendererDestroy++;
60968      lView[RENDERER].destroy();
60969    }
60970
60971    const declarationContainer = lView[DECLARATION_LCONTAINER]; // we are dealing with an embedded view that is still inserted into a container
60972
60973    if (declarationContainer !== null && isLContainer(lView[PARENT])) {
60974      // and this is a projected view
60975      if (declarationContainer !== lView[PARENT]) {
60976        detachMovedView(declarationContainer, lView);
60977      } // For embedded views still attached to a container: remove query result from this view.
60978
60979
60980      const lQueries = lView[QUERIES];
60981
60982      if (lQueries !== null) {
60983        lQueries.detachView(tView);
60984      }
60985    } // Unregister the view once everything else has been cleaned up.
60986
60987
60988    unregisterLView(lView);
60989  }
60990}
60991/** Removes listeners and unsubscribes from output subscriptions */
60992
60993
60994function processCleanups(tView, lView) {
60995  const tCleanup = tView.cleanup;
60996  const lCleanup = lView[CLEANUP]; // `LCleanup` contains both share information with `TCleanup` as well as instance specific
60997  // information appended at the end. We need to know where the end of the `TCleanup` information
60998  // is, and we track this with `lastLCleanupIndex`.
60999
61000  let lastLCleanupIndex = -1;
61001
61002  if (tCleanup !== null) {
61003    for (let i = 0; i < tCleanup.length - 1; i += 2) {
61004      if (typeof tCleanup[i] === 'string') {
61005        // This is a native DOM listener
61006        const idxOrTargetGetter = tCleanup[i + 1];
61007        const target = typeof idxOrTargetGetter === 'function' ? idxOrTargetGetter(lView) : unwrapRNode(lView[idxOrTargetGetter]);
61008        const listener = lCleanup[lastLCleanupIndex = tCleanup[i + 2]];
61009        const useCaptureOrSubIdx = tCleanup[i + 3];
61010
61011        if (typeof useCaptureOrSubIdx === 'boolean') {
61012          // native DOM listener registered with Renderer3
61013          target.removeEventListener(tCleanup[i], listener, useCaptureOrSubIdx);
61014        } else {
61015          if (useCaptureOrSubIdx >= 0) {
61016            // unregister
61017            lCleanup[lastLCleanupIndex = useCaptureOrSubIdx]();
61018          } else {
61019            // Subscription
61020            lCleanup[lastLCleanupIndex = -useCaptureOrSubIdx].unsubscribe();
61021          }
61022        }
61023
61024        i += 2;
61025      } else {
61026        // This is a cleanup function that is grouped with the index of its context
61027        const context = lCleanup[lastLCleanupIndex = tCleanup[i + 1]];
61028        tCleanup[i].call(context);
61029      }
61030    }
61031  }
61032
61033  if (lCleanup !== null) {
61034    for (let i = lastLCleanupIndex + 1; i < lCleanup.length; i++) {
61035      const instanceCleanupFn = lCleanup[i];
61036      ngDevMode && assertFunction(instanceCleanupFn, 'Expecting instance cleanup function.');
61037      instanceCleanupFn();
61038    }
61039
61040    lView[CLEANUP] = null;
61041  }
61042}
61043/** Calls onDestroy hooks for this view */
61044
61045
61046function executeOnDestroys(tView, lView) {
61047  let destroyHooks;
61048
61049  if (tView != null && (destroyHooks = tView.destroyHooks) != null) {
61050    for (let i = 0; i < destroyHooks.length; i += 2) {
61051      const context = lView[destroyHooks[i]]; // Only call the destroy hook if the context has been requested.
61052
61053      if (!(context instanceof NodeInjectorFactory)) {
61054        const toCall = destroyHooks[i + 1];
61055
61056        if (Array.isArray(toCall)) {
61057          for (let j = 0; j < toCall.length; j += 2) {
61058            const callContext = context[toCall[j]];
61059            const hook = toCall[j + 1];
61060            profiler(4
61061            /* ProfilerEvent.LifecycleHookStart */
61062            , callContext, hook);
61063
61064            try {
61065              hook.call(callContext);
61066            } finally {
61067              profiler(5
61068              /* ProfilerEvent.LifecycleHookEnd */
61069              , callContext, hook);
61070            }
61071          }
61072        } else {
61073          profiler(4
61074          /* ProfilerEvent.LifecycleHookStart */
61075          , context, toCall);
61076
61077          try {
61078            toCall.call(context);
61079          } finally {
61080            profiler(5
61081            /* ProfilerEvent.LifecycleHookEnd */
61082            , context, toCall);
61083          }
61084        }
61085      }
61086    }
61087  }
61088}
61089/**
61090 * Returns a native element if a node can be inserted into the given parent.
61091 *
61092 * There are two reasons why we may not be able to insert a element immediately.
61093 * - Projection: When creating a child content element of a component, we have to skip the
61094 *   insertion because the content of a component will be projected.
61095 *   `<component><content>delayed due to projection</content></component>`
61096 * - Parent container is disconnected: This can happen when we are inserting a view into
61097 *   parent container, which itself is disconnected. For example the parent container is part
61098 *   of a View which has not be inserted or is made for projection but has not been inserted
61099 *   into destination.
61100 *
61101 * @param tView: Current `TView`.
61102 * @param tNode: `TNode` for which we wish to retrieve render parent.
61103 * @param lView: Current `LView`.
61104 */
61105
61106
61107function getParentRElement(tView, tNode, lView) {
61108  return getClosestRElement(tView, tNode.parent, lView);
61109}
61110/**
61111 * Get closest `RElement` or `null` if it can't be found.
61112 *
61113 * If `TNode` is `TNodeType.Element` => return `RElement` at `LView[tNode.index]` location.
61114 * If `TNode` is `TNodeType.ElementContainer|IcuContain` => return the parent (recursively).
61115 * If `TNode` is `null` then return host `RElement`:
61116 *   - return `null` if projection
61117 *   - return `null` if parent container is disconnected (we have no parent.)
61118 *
61119 * @param tView: Current `TView`.
61120 * @param tNode: `TNode` for which we wish to retrieve `RElement` (or `null` if host element is
61121 *     needed).
61122 * @param lView: Current `LView`.
61123 * @returns `null` if the `RElement` can't be determined at this time (no parent / projection)
61124 */
61125
61126
61127function getClosestRElement(tView, tNode, lView) {
61128  let parentTNode = tNode; // Skip over element and ICU containers as those are represented by a comment node and
61129  // can't be used as a render parent.
61130
61131  while (parentTNode !== null && parentTNode.type & (8
61132  /* TNodeType.ElementContainer */
61133  | 32
61134  /* TNodeType.Icu */
61135  )) {
61136    tNode = parentTNode;
61137    parentTNode = tNode.parent;
61138  } // If the parent tNode is null, then we are inserting across views: either into an embedded view
61139  // or a component view.
61140
61141
61142  if (parentTNode === null) {
61143    // We are inserting a root element of the component view into the component host element and
61144    // it should always be eager.
61145    return lView[HOST];
61146  } else {
61147    ngDevMode && assertTNodeType(parentTNode, 3
61148    /* TNodeType.AnyRNode */
61149    | 4
61150    /* TNodeType.Container */
61151    );
61152
61153    if (parentTNode.flags & 2
61154    /* TNodeFlags.isComponentHost */
61155    ) {
61156      ngDevMode && assertTNodeForLView(parentTNode, lView);
61157      const encapsulation = tView.data[parentTNode.directiveStart].encapsulation; // We've got a parent which is an element in the current view. We just need to verify if the
61158      // parent element is not a component. Component's content nodes are not inserted immediately
61159      // because they will be projected, and so doing insert at this point would be wasteful.
61160      // Since the projection would then move it to its final destination. Note that we can't
61161      // make this assumption when using the Shadow DOM, because the native projection placeholders
61162      // (<content> or <slot>) have to be in place as elements are being inserted.
61163
61164      if (encapsulation === ViewEncapsulation$1.None || encapsulation === ViewEncapsulation$1.Emulated) {
61165        return null;
61166      }
61167    }
61168
61169    return getNativeByTNode(parentTNode, lView);
61170  }
61171}
61172/**
61173 * Inserts a native node before another native node for a given parent.
61174 * This is a utility function that can be used when native nodes were determined.
61175 */
61176
61177
61178function nativeInsertBefore(renderer, parent, child, beforeNode, isMove) {
61179  ngDevMode && ngDevMode.rendererInsertBefore++;
61180  renderer.insertBefore(parent, child, beforeNode, isMove);
61181}
61182
61183function nativeAppendChild(renderer, parent, child) {
61184  ngDevMode && ngDevMode.rendererAppendChild++;
61185  ngDevMode && assertDefined(parent, 'parent node must be defined');
61186  renderer.appendChild(parent, child);
61187}
61188
61189function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove) {
61190  if (beforeNode !== null) {
61191    nativeInsertBefore(renderer, parent, child, beforeNode, isMove);
61192  } else {
61193    nativeAppendChild(renderer, parent, child);
61194  }
61195}
61196/** Removes a node from the DOM given its native parent. */
61197
61198
61199function nativeRemoveChild(renderer, parent, child, isHostElement) {
61200  renderer.removeChild(parent, child, isHostElement);
61201}
61202/** Checks if an element is a `<template>` node. */
61203
61204
61205function isTemplateNode(node) {
61206  return node.tagName === 'TEMPLATE' && node.content !== undefined;
61207}
61208/**
61209 * Returns a native parent of a given native node.
61210 */
61211
61212
61213function nativeParentNode(renderer, node) {
61214  return renderer.parentNode(node);
61215}
61216/**
61217 * Returns a native sibling of a given native node.
61218 */
61219
61220
61221function nativeNextSibling(renderer, node) {
61222  return renderer.nextSibling(node);
61223}
61224/**
61225 * Find a node in front of which `currentTNode` should be inserted.
61226 *
61227 * This method determines the `RNode` in front of which we should insert the `currentRNode`. This
61228 * takes `TNode.insertBeforeIndex` into account if i18n code has been invoked.
61229 *
61230 * @param parentTNode parent `TNode`
61231 * @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
61232 * @param lView current `LView`
61233 */
61234
61235
61236function getInsertInFrontOfRNode(parentTNode, currentTNode, lView) {
61237  return _getInsertInFrontOfRNodeWithI18n(parentTNode, currentTNode, lView);
61238}
61239/**
61240 * Find a node in front of which `currentTNode` should be inserted. (Does not take i18n into
61241 * account)
61242 *
61243 * This method determines the `RNode` in front of which we should insert the `currentRNode`. This
61244 * does not take `TNode.insertBeforeIndex` into account.
61245 *
61246 * @param parentTNode parent `TNode`
61247 * @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
61248 * @param lView current `LView`
61249 */
61250
61251
61252function getInsertInFrontOfRNodeWithNoI18n(parentTNode, currentTNode, lView) {
61253  if (parentTNode.type & (8
61254  /* TNodeType.ElementContainer */
61255  | 32
61256  /* TNodeType.Icu */
61257  )) {
61258    return getNativeByTNode(parentTNode, lView);
61259  }
61260
61261  return null;
61262}
61263/**
61264 * Tree shakable boundary for `getInsertInFrontOfRNodeWithI18n` function.
61265 *
61266 * This function will only be set if i18n code runs.
61267 */
61268
61269
61270let _getInsertInFrontOfRNodeWithI18n = getInsertInFrontOfRNodeWithNoI18n;
61271/**
61272 * Tree shakable boundary for `processI18nInsertBefore` function.
61273 *
61274 * This function will only be set if i18n code runs.
61275 */
61276
61277let _processI18nInsertBefore;
61278
61279function setI18nHandling(getInsertInFrontOfRNodeWithI18n, processI18nInsertBefore) {
61280  _getInsertInFrontOfRNodeWithI18n = getInsertInFrontOfRNodeWithI18n;
61281  _processI18nInsertBefore = processI18nInsertBefore;
61282}
61283/**
61284 * Appends the `child` native node (or a collection of nodes) to the `parent`.
61285 *
61286 * @param tView The `TView' to be appended
61287 * @param lView The current LView
61288 * @param childRNode The native child (or children) that should be appended
61289 * @param childTNode The TNode of the child element
61290 */
61291
61292
61293function appendChild(tView, lView, childRNode, childTNode) {
61294  const parentRNode = getParentRElement(tView, childTNode, lView);
61295  const renderer = lView[RENDERER];
61296  const parentTNode = childTNode.parent || lView[T_HOST];
61297  const anchorNode = getInsertInFrontOfRNode(parentTNode, childTNode, lView);
61298
61299  if (parentRNode != null) {
61300    if (Array.isArray(childRNode)) {
61301      for (let i = 0; i < childRNode.length; i++) {
61302        nativeAppendOrInsertBefore(renderer, parentRNode, childRNode[i], anchorNode, false);
61303      }
61304    } else {
61305      nativeAppendOrInsertBefore(renderer, parentRNode, childRNode, anchorNode, false);
61306    }
61307  }
61308
61309  _processI18nInsertBefore !== undefined && _processI18nInsertBefore(renderer, childTNode, lView, childRNode, parentRNode);
61310}
61311/**
61312 * Returns the first native node for a given LView, starting from the provided TNode.
61313 *
61314 * Native nodes are returned in the order in which those appear in the native tree (DOM).
61315 */
61316
61317
61318function getFirstNativeNode(lView, tNode) {
61319  if (tNode !== null) {
61320    ngDevMode && assertTNodeType(tNode, 3
61321    /* TNodeType.AnyRNode */
61322    | 12
61323    /* TNodeType.AnyContainer */
61324    | 32
61325    /* TNodeType.Icu */
61326    | 16
61327    /* TNodeType.Projection */
61328    );
61329    const tNodeType = tNode.type;
61330
61331    if (tNodeType & 3
61332    /* TNodeType.AnyRNode */
61333    ) {
61334      return getNativeByTNode(tNode, lView);
61335    } else if (tNodeType & 4
61336    /* TNodeType.Container */
61337    ) {
61338      return getBeforeNodeForView(-1, lView[tNode.index]);
61339    } else if (tNodeType & 8
61340    /* TNodeType.ElementContainer */
61341    ) {
61342      const elIcuContainerChild = tNode.child;
61343
61344      if (elIcuContainerChild !== null) {
61345        return getFirstNativeNode(lView, elIcuContainerChild);
61346      } else {
61347        const rNodeOrLContainer = lView[tNode.index];
61348
61349        if (isLContainer(rNodeOrLContainer)) {
61350          return getBeforeNodeForView(-1, rNodeOrLContainer);
61351        } else {
61352          return unwrapRNode(rNodeOrLContainer);
61353        }
61354      }
61355    } else if (tNodeType & 32
61356    /* TNodeType.Icu */
61357    ) {
61358      let nextRNode = icuContainerIterate(tNode, lView);
61359      let rNode = nextRNode(); // If the ICU container has no nodes, than we use the ICU anchor as the node.
61360
61361      return rNode || unwrapRNode(lView[tNode.index]);
61362    } else {
61363      const projectionNodes = getProjectionNodes(lView, tNode);
61364
61365      if (projectionNodes !== null) {
61366        if (Array.isArray(projectionNodes)) {
61367          return projectionNodes[0];
61368        }
61369
61370        const parentView = getLViewParent(lView[DECLARATION_COMPONENT_VIEW]);
61371        ngDevMode && assertParentView(parentView);
61372        return getFirstNativeNode(parentView, projectionNodes);
61373      } else {
61374        return getFirstNativeNode(lView, tNode.next);
61375      }
61376    }
61377  }
61378
61379  return null;
61380}
61381
61382function getProjectionNodes(lView, tNode) {
61383  if (tNode !== null) {
61384    const componentView = lView[DECLARATION_COMPONENT_VIEW];
61385    const componentHost = componentView[T_HOST];
61386    const slotIdx = tNode.projection;
61387    ngDevMode && assertProjectionSlots(lView);
61388    return componentHost.projection[slotIdx];
61389  }
61390
61391  return null;
61392}
61393
61394function getBeforeNodeForView(viewIndexInContainer, lContainer) {
61395  const nextViewIndex = CONTAINER_HEADER_OFFSET + viewIndexInContainer + 1;
61396
61397  if (nextViewIndex < lContainer.length) {
61398    const lView = lContainer[nextViewIndex];
61399    const firstTNodeOfView = lView[TVIEW].firstChild;
61400
61401    if (firstTNodeOfView !== null) {
61402      return getFirstNativeNode(lView, firstTNodeOfView);
61403    }
61404  }
61405
61406  return lContainer[NATIVE];
61407}
61408/**
61409 * Removes a native node itself using a given renderer. To remove the node we are looking up its
61410 * parent from the native tree as not all platforms / browsers support the equivalent of
61411 * node.remove().
61412 *
61413 * @param renderer A renderer to be used
61414 * @param rNode The native node that should be removed
61415 * @param isHostElement A flag indicating if a node to be removed is a host of a component.
61416 */
61417
61418
61419function nativeRemoveNode(renderer, rNode, isHostElement) {
61420  ngDevMode && ngDevMode.rendererRemoveNode++;
61421  const nativeParent = nativeParentNode(renderer, rNode);
61422
61423  if (nativeParent) {
61424    nativeRemoveChild(renderer, nativeParent, rNode, isHostElement);
61425  }
61426}
61427/**
61428 * Performs the operation of `action` on the node. Typically this involves inserting or removing
61429 * nodes on the LView or projection boundary.
61430 */
61431
61432
61433function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode, isProjection) {
61434  while (tNode != null) {
61435    ngDevMode && assertTNodeForLView(tNode, lView);
61436    ngDevMode && assertTNodeType(tNode, 3
61437    /* TNodeType.AnyRNode */
61438    | 12
61439    /* TNodeType.AnyContainer */
61440    | 16
61441    /* TNodeType.Projection */
61442    | 32
61443    /* TNodeType.Icu */
61444    );
61445    const rawSlotValue = lView[tNode.index];
61446    const tNodeType = tNode.type;
61447
61448    if (isProjection) {
61449      if (action === 0
61450      /* WalkTNodeTreeAction.Create */
61451      ) {
61452        rawSlotValue && attachPatchData(unwrapRNode(rawSlotValue), lView);
61453        tNode.flags |= 4
61454        /* TNodeFlags.isProjected */
61455        ;
61456      }
61457    }
61458
61459    if ((tNode.flags & 64
61460    /* TNodeFlags.isDetached */
61461    ) !== 64
61462    /* TNodeFlags.isDetached */
61463    ) {
61464      if (tNodeType & 8
61465      /* TNodeType.ElementContainer */
61466      ) {
61467        applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
61468        applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
61469      } else if (tNodeType & 32
61470      /* TNodeType.Icu */
61471      ) {
61472        const nextRNode = icuContainerIterate(tNode, lView);
61473        let rNode;
61474
61475        while (rNode = nextRNode()) {
61476          applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
61477        }
61478
61479        applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
61480      } else if (tNodeType & 16
61481      /* TNodeType.Projection */
61482      ) {
61483        applyProjectionRecursive(renderer, action, lView, tNode, parentRElement, beforeNode);
61484      } else {
61485        ngDevMode && assertTNodeType(tNode, 3
61486        /* TNodeType.AnyRNode */
61487        | 4
61488        /* TNodeType.Container */
61489        );
61490        applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
61491      }
61492    }
61493
61494    tNode = isProjection ? tNode.projectionNext : tNode.next;
61495  }
61496}
61497
61498function applyView(tView, lView, renderer, action, parentRElement, beforeNode) {
61499  applyNodes(renderer, action, tView.firstChild, lView, parentRElement, beforeNode, false);
61500}
61501/**
61502 * `applyProjection` performs operation on the projection.
61503 *
61504 * Inserting a projection requires us to locate the projected nodes from the parent component. The
61505 * complication is that those nodes themselves could be re-projected from their parent component.
61506 *
61507 * @param tView The `TView` of `LView` which needs to be inserted, detached, destroyed
61508 * @param lView The `LView` which needs to be inserted, detached, destroyed.
61509 * @param tProjectionNode node to project
61510 */
61511
61512
61513function applyProjection(tView, lView, tProjectionNode) {
61514  const renderer = lView[RENDERER];
61515  const parentRNode = getParentRElement(tView, tProjectionNode, lView);
61516  const parentTNode = tProjectionNode.parent || lView[T_HOST];
61517  let beforeNode = getInsertInFrontOfRNode(parentTNode, tProjectionNode, lView);
61518  applyProjectionRecursive(renderer, 0
61519  /* WalkTNodeTreeAction.Create */
61520  , lView, tProjectionNode, parentRNode, beforeNode);
61521}
61522/**
61523 * `applyProjectionRecursive` performs operation on the projection specified by `action` (insert,
61524 * detach, destroy)
61525 *
61526 * Inserting a projection requires us to locate the projected nodes from the parent component. The
61527 * complication is that those nodes themselves could be re-projected from their parent component.
61528 *
61529 * @param renderer Render to use
61530 * @param action action to perform (insert, detach, destroy)
61531 * @param lView The LView which needs to be inserted, detached, destroyed.
61532 * @param tProjectionNode node to project
61533 * @param parentRElement parent DOM element for insertion/removal.
61534 * @param beforeNode Before which node the insertions should happen.
61535 */
61536
61537
61538function applyProjectionRecursive(renderer, action, lView, tProjectionNode, parentRElement, beforeNode) {
61539  const componentLView = lView[DECLARATION_COMPONENT_VIEW];
61540  const componentNode = componentLView[T_HOST];
61541  ngDevMode && assertEqual(typeof tProjectionNode.projection, 'number', 'expecting projection index');
61542  const nodeToProjectOrRNodes = componentNode.projection[tProjectionNode.projection];
61543
61544  if (Array.isArray(nodeToProjectOrRNodes)) {
61545    // This should not exist, it is a bit of a hack. When we bootstrap a top level node and we
61546    // need to support passing projectable nodes, so we cheat and put them in the TNode
61547    // of the Host TView. (Yes we put instance info at the T Level). We can get away with it
61548    // because we know that that TView is not shared and therefore it will not be a problem.
61549    // This should be refactored and cleaned up.
61550    for (let i = 0; i < nodeToProjectOrRNodes.length; i++) {
61551      const rNode = nodeToProjectOrRNodes[i];
61552      applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
61553    }
61554  } else {
61555    let nodeToProject = nodeToProjectOrRNodes;
61556    const projectedComponentLView = componentLView[PARENT];
61557    applyNodes(renderer, action, nodeToProject, projectedComponentLView, parentRElement, beforeNode, true);
61558  }
61559}
61560/**
61561 * `applyContainer` performs an operation on the container and its views as specified by
61562 * `action` (insert, detach, destroy)
61563 *
61564 * Inserting a Container is complicated by the fact that the container may have Views which
61565 * themselves have containers or projections.
61566 *
61567 * @param renderer Renderer to use
61568 * @param action action to perform (insert, detach, destroy)
61569 * @param lContainer The LContainer which needs to be inserted, detached, destroyed.
61570 * @param parentRElement parent DOM element for insertion/removal.
61571 * @param beforeNode Before which node the insertions should happen.
61572 */
61573
61574
61575function applyContainer(renderer, action, lContainer, parentRElement, beforeNode) {
61576  ngDevMode && assertLContainer(lContainer);
61577  const anchor = lContainer[NATIVE]; // LContainer has its own before node.
61578
61579  const native = unwrapRNode(lContainer); // An LContainer can be created dynamically on any node by injecting ViewContainerRef.
61580  // Asking for a ViewContainerRef on an element will result in a creation of a separate anchor
61581  // node (comment in the DOM) that will be different from the LContainer's host node. In this
61582  // particular case we need to execute action on 2 nodes:
61583  // - container's host node (this is done in the executeActionOnElementOrContainer)
61584  // - container's host node (this is done here)
61585
61586  if (anchor !== native) {
61587    // This is very strange to me (Misko). I would expect that the native is same as anchor. I
61588    // don't see a reason why they should be different, but they are.
61589    //
61590    // If they are we need to process the second anchor as well.
61591    applyToElementOrContainer(action, renderer, parentRElement, anchor, beforeNode);
61592  }
61593
61594  for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
61595    const lView = lContainer[i];
61596    applyView(lView[TVIEW], lView, renderer, action, parentRElement, anchor);
61597  }
61598}
61599/**
61600 * Writes class/style to element.
61601 *
61602 * @param renderer Renderer to use.
61603 * @param isClassBased `true` if it should be written to `class` (`false` to write to `style`)
61604 * @param rNode The Node to write to.
61605 * @param prop Property to write to. This would be the class/style name.
61606 * @param value Value to write. If `null`/`undefined`/`false` this is considered a remove (set/add
61607 *        otherwise).
61608 */
61609
61610
61611function applyStyling(renderer, isClassBased, rNode, prop, value) {
61612  if (isClassBased) {
61613    // We actually want JS true/false here because any truthy value should add the class
61614    if (!value) {
61615      ngDevMode && ngDevMode.rendererRemoveClass++;
61616      renderer.removeClass(rNode, prop);
61617    } else {
61618      ngDevMode && ngDevMode.rendererAddClass++;
61619      renderer.addClass(rNode, prop);
61620    }
61621  } else {
61622    let flags = prop.indexOf('-') === -1 ? undefined : RendererStyleFlags2.DashCase;
61623
61624    if (value == null
61625    /** || value === undefined */
61626    ) {
61627      ngDevMode && ngDevMode.rendererRemoveStyle++;
61628      renderer.removeStyle(rNode, prop, flags);
61629    } else {
61630      // A value is important if it ends with `!important`. The style
61631      // parser strips any semicolons at the end of the value.
61632      const isImportant = typeof value === 'string' ? value.endsWith('!important') : false;
61633
61634      if (isImportant) {
61635        // !important has to be stripped from the value for it to be valid.
61636        value = value.slice(0, -10);
61637        flags |= RendererStyleFlags2.Important;
61638      }
61639
61640      ngDevMode && ngDevMode.rendererSetStyle++;
61641      renderer.setStyle(rNode, prop, value, flags);
61642    }
61643  }
61644}
61645/**
61646 * Write `cssText` to `RElement`.
61647 *
61648 * This function does direct write without any reconciliation. Used for writing initial values, so
61649 * that static styling values do not pull in the style parser.
61650 *
61651 * @param renderer Renderer to use
61652 * @param element The element which needs to be updated.
61653 * @param newValue The new class list to write.
61654 */
61655
61656
61657function writeDirectStyle(renderer, element, newValue) {
61658  ngDevMode && assertString(newValue, '\'newValue\' should be a string');
61659  renderer.setAttribute(element, 'style', newValue);
61660  ngDevMode && ngDevMode.rendererSetStyle++;
61661}
61662/**
61663 * Write `className` to `RElement`.
61664 *
61665 * This function does direct write without any reconciliation. Used for writing initial values, so
61666 * that static styling values do not pull in the style parser.
61667 *
61668 * @param renderer Renderer to use
61669 * @param element The element which needs to be updated.
61670 * @param newValue The new class list to write.
61671 */
61672
61673
61674function writeDirectClass(renderer, element, newValue) {
61675  ngDevMode && assertString(newValue, '\'newValue\' should be a string');
61676
61677  if (newValue === '') {
61678    // There are tests in `google3` which expect `element.getAttribute('class')` to be `null`.
61679    renderer.removeAttribute(element, 'class');
61680  } else {
61681    renderer.setAttribute(element, 'class', newValue);
61682  }
61683
61684  ngDevMode && ngDevMode.rendererSetClassName++;
61685}
61686/**
61687 * @license
61688 * Copyright Google LLC All Rights Reserved.
61689 *
61690 * Use of this source code is governed by an MIT-style license that can be
61691 * found in the LICENSE file at https://angular.io/license
61692 */
61693
61694/**
61695 * Returns an index of `classToSearch` in `className` taking token boundaries into account.
61696 *
61697 * `classIndexOf('AB A', 'A', 0)` will be 3 (not 0 since `AB!==A`)
61698 *
61699 * @param className A string containing classes (whitespace separated)
61700 * @param classToSearch A class name to locate
61701 * @param startingIndex Starting location of search
61702 * @returns an index of the located class (or -1 if not found)
61703 */
61704
61705
61706function classIndexOf(className, classToSearch, startingIndex) {
61707  ngDevMode && assertNotEqual(classToSearch, '', 'can not look for "" string.');
61708  let end = className.length;
61709
61710  while (true) {
61711    const foundIndex = className.indexOf(classToSearch, startingIndex);
61712    if (foundIndex === -1) return foundIndex;
61713
61714    if (foundIndex === 0 || className.charCodeAt(foundIndex - 1) <= 32
61715    /* CharCode.SPACE */
61716    ) {
61717      // Ensure that it has leading whitespace
61718      const length = classToSearch.length;
61719
61720      if (foundIndex + length === end || className.charCodeAt(foundIndex + length) <= 32
61721      /* CharCode.SPACE */
61722      ) {
61723        // Ensure that it has trailing whitespace
61724        return foundIndex;
61725      }
61726    } // False positive, keep searching from where we left off.
61727
61728
61729    startingIndex = foundIndex + 1;
61730  }
61731}
61732/**
61733 * @license
61734 * Copyright Google LLC All Rights Reserved.
61735 *
61736 * Use of this source code is governed by an MIT-style license that can be
61737 * found in the LICENSE file at https://angular.io/license
61738 */
61739
61740
61741const unusedValueToPlacateAjd$1 = unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4;
61742const NG_TEMPLATE_SELECTOR = 'ng-template';
61743/**
61744 * Search the `TAttributes` to see if it contains `cssClassToMatch` (case insensitive)
61745 *
61746 * @param attrs `TAttributes` to search through.
61747 * @param cssClassToMatch class to match (lowercase)
61748 * @param isProjectionMode Whether or not class matching should look into the attribute `class` in
61749 *    addition to the `AttributeMarker.Classes`.
61750 */
61751
61752function isCssClassMatching(attrs, cssClassToMatch, isProjectionMode) {
61753  // TODO(misko): The fact that this function needs to know about `isProjectionMode` seems suspect.
61754  // It is strange to me that sometimes the class information comes in form of `class` attribute
61755  // and sometimes in form of `AttributeMarker.Classes`. Some investigation is needed to determine
61756  // if that is the right behavior.
61757  ngDevMode && assertEqual(cssClassToMatch, cssClassToMatch.toLowerCase(), 'Class name expected to be lowercase.');
61758  let i = 0;
61759
61760  while (i < attrs.length) {
61761    let item = attrs[i++];
61762
61763    if (isProjectionMode && item === 'class') {
61764      item = attrs[i];
61765
61766      if (classIndexOf(item.toLowerCase(), cssClassToMatch, 0) !== -1) {
61767        return true;
61768      }
61769    } else if (item === 1
61770    /* AttributeMarker.Classes */
61771    ) {
61772      // We found the classes section. Start searching for the class.
61773      while (i < attrs.length && typeof (item = attrs[i++]) == 'string') {
61774        // while we have strings
61775        if (item.toLowerCase() === cssClassToMatch) return true;
61776      }
61777
61778      return false;
61779    }
61780  }
61781
61782  return false;
61783}
61784/**
61785 * Checks whether the `tNode` represents an inline template (e.g. `*ngFor`).
61786 *
61787 * @param tNode current TNode
61788 */
61789
61790
61791function isInlineTemplate(tNode) {
61792  return tNode.type === 4
61793  /* TNodeType.Container */
61794  && tNode.value !== NG_TEMPLATE_SELECTOR;
61795}
61796/**
61797 * Function that checks whether a given tNode matches tag-based selector and has a valid type.
61798 *
61799 * Matching can be performed in 2 modes: projection mode (when we project nodes) and regular
61800 * directive matching mode:
61801 * - in the "directive matching" mode we do _not_ take TContainer's tagName into account if it is
61802 * different from NG_TEMPLATE_SELECTOR (value different from NG_TEMPLATE_SELECTOR indicates that a
61803 * tag name was extracted from * syntax so we would match the same directive twice);
61804 * - in the "projection" mode, we use a tag name potentially extracted from the * syntax processing
61805 * (applicable to TNodeType.Container only).
61806 */
61807
61808
61809function hasTagAndTypeMatch(tNode, currentSelector, isProjectionMode) {
61810  const tagNameToCompare = tNode.type === 4
61811  /* TNodeType.Container */
61812  && !isProjectionMode ? NG_TEMPLATE_SELECTOR : tNode.value;
61813  return currentSelector === tagNameToCompare;
61814}
61815/**
61816 * A utility function to match an Ivy node static data against a simple CSS selector
61817 *
61818 * @param node static data of the node to match
61819 * @param selector The selector to try matching against the node.
61820 * @param isProjectionMode if `true` we are matching for content projection, otherwise we are doing
61821 * directive matching.
61822 * @returns true if node matches the selector.
61823 */
61824
61825
61826function isNodeMatchingSelector(tNode, selector, isProjectionMode) {
61827  ngDevMode && assertDefined(selector[0], 'Selector should have a tag name');
61828  let mode = 4
61829  /* SelectorFlags.ELEMENT */
61830  ;
61831  const nodeAttrs = tNode.attrs || []; // Find the index of first attribute that has no value, only a name.
61832
61833  const nameOnlyMarkerIdx = getNameOnlyMarkerIndex(nodeAttrs); // When processing ":not" selectors, we skip to the next ":not" if the
61834  // current one doesn't match
61835
61836  let skipToNextSelector = false;
61837
61838  for (let i = 0; i < selector.length; i++) {
61839    const current = selector[i];
61840
61841    if (typeof current === 'number') {
61842      // If we finish processing a :not selector and it hasn't failed, return false
61843      if (!skipToNextSelector && !isPositive(mode) && !isPositive(current)) {
61844        return false;
61845      } // If we are skipping to the next :not() and this mode flag is positive,
61846      // it's a part of the current :not() selector, and we should keep skipping
61847
61848
61849      if (skipToNextSelector && isPositive(current)) continue;
61850      skipToNextSelector = false;
61851      mode = current | mode & 1
61852      /* SelectorFlags.NOT */
61853      ;
61854      continue;
61855    }
61856
61857    if (skipToNextSelector) continue;
61858
61859    if (mode & 4
61860    /* SelectorFlags.ELEMENT */
61861    ) {
61862      mode = 2
61863      /* SelectorFlags.ATTRIBUTE */
61864      | mode & 1
61865      /* SelectorFlags.NOT */
61866      ;
61867
61868      if (current !== '' && !hasTagAndTypeMatch(tNode, current, isProjectionMode) || current === '' && selector.length === 1) {
61869        if (isPositive(mode)) return false;
61870        skipToNextSelector = true;
61871      }
61872    } else {
61873      const selectorAttrValue = mode & 8
61874      /* SelectorFlags.CLASS */
61875      ? current : selector[++i]; // special case for matching against classes when a tNode has been instantiated with
61876      // class and style values as separate attribute values (e.g. ['title', CLASS, 'foo'])
61877
61878      if (mode & 8
61879      /* SelectorFlags.CLASS */
61880      && tNode.attrs !== null) {
61881        if (!isCssClassMatching(tNode.attrs, selectorAttrValue, isProjectionMode)) {
61882          if (isPositive(mode)) return false;
vendor: 9,500 bytes, lines 61883-62180
61883          skipToNextSelector = true;
61884        }
61885
61886        continue;
61887      }
61888
61889      const attrName = mode & 8
61890      /* SelectorFlags.CLASS */
61891      ? 'class' : current;
61892      const attrIndexInNode = findAttrIndexInNode(attrName, nodeAttrs, isInlineTemplate(tNode), isProjectionMode);
61893
61894      if (attrIndexInNode === -1) {
61895        if (isPositive(mode)) return false;
61896        skipToNextSelector = true;
61897        continue;
61898      }
61899
61900      if (selectorAttrValue !== '') {
61901        let nodeAttrValue;
61902
61903        if (attrIndexInNode > nameOnlyMarkerIdx) {
61904          nodeAttrValue = '';
61905        } else {
61906          ngDevMode && assertNotEqual(nodeAttrs[attrIndexInNode], 0
61907          /* AttributeMarker.NamespaceURI */
61908          , 'We do not match directives on namespaced attributes'); // we lowercase the attribute value to be able to match
61909          // selectors without case-sensitivity
61910          // (selectors are already in lowercase when generated)
61911
61912          nodeAttrValue = nodeAttrs[attrIndexInNode + 1].toLowerCase();
61913        }
61914
61915        const compareAgainstClassName = mode & 8
61916        /* SelectorFlags.CLASS */
61917        ? nodeAttrValue : null;
61918
61919        if (compareAgainstClassName && classIndexOf(compareAgainstClassName, selectorAttrValue, 0) !== -1 || mode & 2
61920        /* SelectorFlags.ATTRIBUTE */
61921        && selectorAttrValue !== nodeAttrValue) {
61922          if (isPositive(mode)) return false;
61923          skipToNextSelector = true;
61924        }
61925      }
61926    }
61927  }
61928
61929  return isPositive(mode) || skipToNextSelector;
61930}
61931
61932function isPositive(mode) {
61933  return (mode & 1
61934  /* SelectorFlags.NOT */
61935  ) === 0;
61936}
61937/**
61938 * Examines the attribute's definition array for a node to find the index of the
61939 * attribute that matches the given `name`.
61940 *
61941 * NOTE: This will not match namespaced attributes.
61942 *
61943 * Attribute matching depends upon `isInlineTemplate` and `isProjectionMode`.
61944 * The following table summarizes which types of attributes we attempt to match:
61945 *
61946 * ===========================================================================================================
61947 * Modes                   | Normal Attributes | Bindings Attributes | Template Attributes | I18n
61948 * Attributes
61949 * ===========================================================================================================
61950 * Inline + Projection     | YES               | YES                 | NO                  | YES
61951 * -----------------------------------------------------------------------------------------------------------
61952 * Inline + Directive      | NO                | NO                  | YES                 | NO
61953 * -----------------------------------------------------------------------------------------------------------
61954 * Non-inline + Projection | YES               | YES                 | NO                  | YES
61955 * -----------------------------------------------------------------------------------------------------------
61956 * Non-inline + Directive  | YES               | YES                 | NO                  | YES
61957 * ===========================================================================================================
61958 *
61959 * @param name the name of the attribute to find
61960 * @param attrs the attribute array to examine
61961 * @param isInlineTemplate true if the node being matched is an inline template (e.g. `*ngFor`)
61962 * rather than a manually expanded template node (e.g `<ng-template>`).
61963 * @param isProjectionMode true if we are matching against content projection otherwise we are
61964 * matching against directives.
61965 */
61966
61967
61968function findAttrIndexInNode(name, attrs, isInlineTemplate, isProjectionMode) {
61969  if (attrs === null) return -1;
61970  let i = 0;
61971
61972  if (isProjectionMode || !isInlineTemplate) {
61973    let bindingsMode = false;
61974
61975    while (i < attrs.length) {
61976      const maybeAttrName = attrs[i];
61977
61978      if (maybeAttrName === name) {
61979        return i;
61980      } else if (maybeAttrName === 3
61981      /* AttributeMarker.Bindings */
61982      || maybeAttrName === 6
61983      /* AttributeMarker.I18n */
61984      ) {
61985        bindingsMode = true;
61986      } else if (maybeAttrName === 1
61987      /* AttributeMarker.Classes */
61988      || maybeAttrName === 2
61989      /* AttributeMarker.Styles */
61990      ) {
61991        let value = attrs[++i]; // We should skip classes here because we have a separate mechanism for
61992        // matching classes in projection mode.
61993
61994        while (typeof value === 'string') {
61995          value = attrs[++i];
61996        }
61997
61998        continue;
61999      } else if (maybeAttrName === 4
62000      /* AttributeMarker.Template */
62001      ) {
62002        // We do not care about Template attributes in this scenario.
62003        break;
62004      } else if (maybeAttrName === 0
62005      /* AttributeMarker.NamespaceURI */
62006      ) {
62007        // Skip the whole namespaced attribute and value. This is by design.
62008        i += 4;
62009        continue;
62010      } // In binding mode there are only names, rather than name-value pairs.
62011
62012
62013      i += bindingsMode ? 1 : 2;
62014    } // We did not match the attribute
62015
62016
62017    return -1;
62018  } else {
62019    return matchTemplateAttribute(attrs, name);
62020  }
62021}
62022
62023function isNodeMatchingSelectorList(tNode, selector, isProjectionMode = false) {
62024  for (let i = 0; i < selector.length; i++) {
62025    if (isNodeMatchingSelector(tNode, selector[i], isProjectionMode)) {
62026      return true;
62027    }
62028  }
62029
62030  return false;
62031}
62032
62033function getProjectAsAttrValue(tNode) {
62034  const nodeAttrs = tNode.attrs;
62035
62036  if (nodeAttrs != null) {
62037    const ngProjectAsAttrIdx = nodeAttrs.indexOf(5
62038    /* AttributeMarker.ProjectAs */
62039    ); // only check for ngProjectAs in attribute names, don't accidentally match attribute's value
62040    // (attribute names are stored at even indexes)
62041
62042    if ((ngProjectAsAttrIdx & 1) === 0) {
62043      return nodeAttrs[ngProjectAsAttrIdx + 1];
62044    }
62045  }
62046
62047  return null;
62048}
62049
62050function getNameOnlyMarkerIndex(nodeAttrs) {
62051  for (let i = 0; i < nodeAttrs.length; i++) {
62052    const nodeAttr = nodeAttrs[i];
62053
62054    if (isNameOnlyAttributeMarker(nodeAttr)) {
62055      return i;
62056    }
62057  }
62058
62059  return nodeAttrs.length;
62060}
62061
62062function matchTemplateAttribute(attrs, name) {
62063  let i = attrs.indexOf(4
62064  /* AttributeMarker.Template */
62065  );
62066
62067  if (i > -1) {
62068    i++;
62069
62070    while (i < attrs.length) {
62071      const attr = attrs[i]; // Return in case we checked all template attrs and are switching to the next section in the
62072      // attrs array (that starts with a number that represents an attribute marker).
62073
62074      if (typeof attr === 'number') return -1;
62075      if (attr === name) return i;
62076      i++;
62077    }
62078  }
62079
62080  return -1;
62081}
62082/**
62083 * Checks whether a selector is inside a CssSelectorList
62084 * @param selector Selector to be checked.
62085 * @param list List in which to look for the selector.
62086 */
62087
62088
62089function isSelectorInSelectorList(selector, list) {
62090  selectorListLoop: for (let i = 0; i < list.length; i++) {
62091    const currentSelectorInList = list[i];
62092
62093    if (selector.length !== currentSelectorInList.length) {
62094      continue;
62095    }
62096
62097    for (let j = 0; j < selector.length; j++) {
62098      if (selector[j] !== currentSelectorInList[j]) {
62099        continue selectorListLoop;
62100      }
62101    }
62102
62103    return true;
62104  }
62105
62106  return false;
62107}
62108
62109function maybeWrapInNotSelector(isNegativeMode, chunk) {
62110  return isNegativeMode ? ':not(' + chunk.trim() + ')' : chunk;
62111}
62112
62113function stringifyCSSSelector(selector) {
62114  let result = selector[0];
62115  let i = 1;
62116  let mode = 2
62117  /* SelectorFlags.ATTRIBUTE */
62118  ;
62119  let currentChunk = '';
62120  let isNegativeMode = false;
62121
62122  while (i < selector.length) {
62123    let valueOrMarker = selector[i];
62124
62125    if (typeof valueOrMarker === 'string') {
62126      if (mode & 2
62127      /* SelectorFlags.ATTRIBUTE */
62128      ) {
62129        const attrValue = selector[++i];
62130        currentChunk += '[' + valueOrMarker + (attrValue.length > 0 ? '="' + attrValue + '"' : '') + ']';
62131      } else if (mode & 8
62132      /* SelectorFlags.CLASS */
62133      ) {
62134        currentChunk += '.' + valueOrMarker;
62135      } else if (mode & 4
62136      /* SelectorFlags.ELEMENT */
62137      ) {
62138        currentChunk += ' ' + valueOrMarker;
62139      }
62140    } else {
62141      //
62142      // Append current chunk to the final result in case we come across SelectorFlag, which
62143      // indicates that the previous section of a selector is over. We need to accumulate content
62144      // between flags to make sure we wrap the chunk later in :not() selector if needed, e.g.
62145      // ```
62146      //  ['', Flags.CLASS, '.classA', Flags.CLASS | Flags.NOT, '.classB', '.classC']
62147      // ```
62148      // should be transformed to `.classA :not(.classB .classC)`.
62149      //
62150      // Note: for negative selector part, we accumulate content between flags until we find the
62151      // next negative flag. This is needed to support a case where `:not()` rule contains more than
62152      // one chunk, e.g. the following selector:
62153      // ```
62154      //  ['', Flags.ELEMENT | Flags.NOT, 'p', Flags.CLASS, 'foo', Flags.CLASS | Flags.NOT, 'bar']
62155      // ```
62156      // should be stringified to `:not(p.foo) :not(.bar)`
62157      //
62158      if (currentChunk !== '' && !isPositive(valueOrMarker)) {
62159        result += maybeWrapInNotSelector(isNegativeMode, currentChunk);
62160        currentChunk = '';
62161      }
62162
62163      mode = valueOrMarker; // According to CssSelector spec, once we come across `SelectorFlags.NOT` flag, the negative
62164      // mode is maintained for remaining chunks of a selector.
62165
62166      isNegativeMode = isNegativeMode || !isPositive(mode);
62167    }
62168
62169    i++;
62170  }
62171
62172  if (currentChunk !== '') {
62173    result += maybeWrapInNotSelector(isNegativeMode, currentChunk);
62174  }
62175
62176  return result;
62177}
62178/**
62179 * Generates string representation of CSS selector in parsed form.
62180 *
62181 * ComponentDef and DirectiveDef are generated with the selector in parsed form to avoid doing
62182 * additional parsing at runtime (for example, for directive matching). However in some cases (for
62183 * example, while bootstrapping a component), a string version of the selector is required to query
62184 * for the host element on the page. This function takes the parsed form of a selector and returns
62185 * its string representation.
62186 *
62187 * @param selectorList selector in parsed form
62188 * @returns string representation of a given selector
62189 */
62190
62191
62192function stringifyCSSSelectorList(selectorList) {
62193  return selectorList.map(stringifyCSSSelector).join(',');
62194}
62195/**
62196 * Extracts attributes and classes information from a given CSS selector.
62197 *
62198 * This function is used while creating a component dynamically. In this case, the host element
62199 * (that is created dynamically) should contain attributes and classes specified in component's CSS
62200 * selector.
62201 *
62202 * @param selector CSS selector in parsed form (in a form of array)
62203 * @returns object with `attrs` and `classes` fields that contain extracted information
62204 */
62205
62206
62207function extractAttrsAndClassesFromSelector(selector) {
62208  const attrs = [];
62209  const classes = [];
62210  let i = 1;
62211  let mode = 2
62212  /* SelectorFlags.ATTRIBUTE */
62213  ;
62214
62215  while (i < selector.length) {
62216    let valueOrMarker = selector[i];
62217
62218    if (typeof valueOrMarker === 'string') {
62219      if (mode === 2
62220      /* SelectorFlags.ATTRIBUTE */
62221      ) {
62222        if (valueOrMarker !== '') {
62223          attrs.push(valueOrMarker, selector[++i]);
62224        }
62225      } else if (mode === 8
62226      /* SelectorFlags.CLASS */
62227      ) {
62228        classes.push(valueOrMarker);
62229      }
62230    } else {
62231      // According to CssSelector spec, once we come across `SelectorFlags.NOT` flag, the negative
62232      // mode is maintained for remaining chunks of a selector. Since attributes and classes are
62233      // extracted only for "positive" part of the selector, we can stop here.
62234      if (!isPositive(mode)) break;
62235      mode = valueOrMarker;
62236    }
62237
62238    i++;
62239  }
62240
62241  return {
62242    attrs,
62243    classes
62244  };
62245}
62246/**
62247 * @license
62248 * Copyright Google LLC All Rights Reserved.
62249 *
62250 * Use of this source code is governed by an MIT-style license that can be
62251 * found in the LICENSE file at https://angular.io/license
62252 */
62253
62254/** A special value which designates that a value has not changed. */
62255
62256
62257const NO_CHANGE = typeof ngDevMode === 'undefined' || ngDevMode ? {
62258  __brand__: 'NO_CHANGE'
62259} : {};
62260/**
62261 * @license
62262 * Copyright Google LLC All Rights Reserved.
62263 *
62264 * Use of this source code is governed by an MIT-style license that can be
62265 * found in the LICENSE file at https://angular.io/license
62266 */
62267
62268/**
62269 * Advances to an element for later binding instructions.
62270 *
62271 * Used in conjunction with instructions like {@link property} to act on elements with specified
62272 * indices, for example those created with {@link element} or {@link elementStart}.
62273 *
62274 * ```ts
62275 * (rf: RenderFlags, ctx: any) => {
62276 *   if (rf & 1) {
62277 *     text(0, 'Hello');
62278 *     text(1, 'Goodbye')
62279 *     element(2, 'div');
62280 *   }
62281 *   if (rf & 2) {
62282 *     advance(2); // Advance twice to the <div>.
62283 *     property('title', 'test');
62284 *   }
62285 *  }
62286 * ```
62287 * @param delta Number of elements to advance forwards by.
62288 *
62289 * @codeGenApi
62290 */
62291
62292function ɵɵadvance(delta) {
62293  ngDevMode && assertGreaterThan(delta, 0, 'Can only advance forward');
62294  selectIndexInternal(getTView(), getLView(), getSelectedIndex() + delta, !!ngDevMode && isInCheckNoChangesMode());
62295}
62296
62297function selectIndexInternal(tView, lView, index, checkNoChangesMode) {
62298  ngDevMode && assertIndexInDeclRange(lView, index); // Flush the initial hooks for elements in the view that have been added up to this point.
62299  // PERF WARNING: do NOT extract this to a separate function without running benchmarks
62300
62301  if (!checkNoChangesMode) {
62302    const hooksInitPhaseCompleted = (lView[FLAGS] & 3
62303    /* LViewFlags.InitPhaseStateMask */
62304    ) === 3
62305    /* InitPhaseState.InitPhaseCompleted */
62306    ;
62307
62308    if (hooksInitPhaseCompleted) {
62309      const preOrderCheckHooks = tView.preOrderCheckHooks;
62310
62311      if (preOrderCheckHooks !== null) {
62312        executeCheckHooks(lView, preOrderCheckHooks, index);
62313      }
62314    } else {
vendor: 4,068 bytes, lines 62315-62451
62315      const preOrderHooks = tView.preOrderHooks;
62316
62317      if (preOrderHooks !== null) {
62318        executeInitAndCheckHooks(lView, preOrderHooks, 0
62319        /* InitPhaseState.OnInitHooksToBeRun */
62320        , index);
62321      }
62322    }
62323  } // We must set the selected index *after* running the hooks, because hooks may have side-effects
62324  // that cause other template functions to run, thus updating the selected index, which is global
62325  // state. If we run `setSelectedIndex` *before* we run the hooks, in some cases the selected index
62326  // will be altered by the time we leave the `ɵɵadvance` instruction.
62327
62328
62329  setSelectedIndex(index);
62330}
62331/**
62332 * @license
62333 * Copyright Google LLC All Rights Reserved.
62334 *
62335 * Use of this source code is governed by an MIT-style license that can be
62336 * found in the LICENSE file at https://angular.io/license
62337 */
62338
62339/**
62340 * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
62341 *
62342 * This should be kept up to date with the public exports of @angular/core.
62343 */
62344
62345
62346const angularCoreDiEnv = {
62347  'ɵɵdefineInjectable': ɵɵdefineInjectable,
62348  'ɵɵdefineInjector': ɵɵdefineInjector,
62349  'ɵɵinject': ɵɵinject,
62350  'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
62351  'resolveForwardRef': resolveForwardRef
62352};
62353/**
62354 * @license
62355 * Copyright Google LLC All Rights Reserved.
62356 *
62357 * Use of this source code is governed by an MIT-style license that can be
62358 * found in the LICENSE file at https://angular.io/license
62359 */
62360
62361/**
62362 * Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
62363 * injectable def (`ɵprov`) onto the injectable type.
62364 */
62365
62366function compileInjectable(type, meta) {
62367  let ngInjectableDef = null;
62368  let ngFactoryDef = null; // if NG_PROV_DEF is already defined on this class then don't overwrite it
62369
62370  if (!type.hasOwnProperty(NG_PROV_DEF)) {
62371    Object.defineProperty(type, NG_PROV_DEF, {
62372      get: () => {
62373        if (ngInjectableDef === null) {
62374          const compiler = getCompilerFacade({
62375            usage: 0
62376            /* JitCompilerUsage.Decorator */
62377            ,
62378            kind: 'injectable',
62379            type
62380          });
62381          ngInjectableDef = compiler.compileInjectable(angularCoreDiEnv, `ng:///${type.name}/ɵprov.js`, getInjectableMetadata(type, meta));
62382        }
62383
62384        return ngInjectableDef;
62385      }
62386    });
62387  } // if NG_FACTORY_DEF is already defined on this class then don't overwrite it
62388
62389
62390  if (!type.hasOwnProperty(NG_FACTORY_DEF)) {
62391    Object.defineProperty(type, NG_FACTORY_DEF, {
62392      get: () => {
62393        if (ngFactoryDef === null) {
62394          const compiler = getCompilerFacade({
62395            usage: 0
62396            /* JitCompilerUsage.Decorator */
62397            ,
62398            kind: 'injectable',
62399            type
62400          });
62401          ngFactoryDef = compiler.compileFactory(angularCoreDiEnv, `ng:///${type.name}/ɵfac.js`, {
62402            name: type.name,
62403            type,
62404            typeArgumentCount: 0,
62405            deps: reflectDependencies(type),
62406            target: compiler.FactoryTarget.Injectable
62407          });
62408        }
62409
62410        return ngFactoryDef;
62411      },
62412      // Leave this configurable so that the factories from directives or pipes can take precedence.
62413      configurable: true
62414    });
62415  }
62416}
62417
62418const USE_VALUE = getClosureSafeProperty({
62419  provide: String,
62420  useValue: getClosureSafeProperty
62421});
62422
62423function isUseClassProvider(meta) {
62424  return meta.useClass !== undefined;
62425}
62426
62427function isUseValueProvider(meta) {
62428  return USE_VALUE in meta;
62429}
62430
62431function isUseFactoryProvider(meta) {
62432  return meta.useFactory !== undefined;
62433}
62434
62435function isUseExistingProvider(meta) {
62436  return meta.useExisting !== undefined;
62437}
62438
62439function getInjectableMetadata(type, srcMeta) {
62440  // Allow the compilation of a class with a `@Injectable()` decorator without parameters
62441  const meta = srcMeta || {
62442    providedIn: null
62443  };
62444  const compilerMeta = {
62445    name: type.name,
62446    type: type,
62447    typeArgumentCount: 0,
62448    providedIn: meta.providedIn
62449  };
62450
62451  if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
62452    compilerMeta.deps = convertDependencies(meta.deps);
62453  } // Check to see if the user explicitly provided a `useXxxx` property.
62454
62455
62456  if (isUseClassProvider(meta)) {
62457    compilerMeta.useClass = meta.useClass;
62458  } else if (isUseValueProvider(meta)) {
62459    compilerMeta.useValue = meta.useValue;
62460  } else if (isUseFactoryProvider(meta)) {
62461    compilerMeta.useFactory = meta.useFactory;
62462  } else if (isUseExistingProvider(meta)) {
62463    compilerMeta.useExisting = meta.useExisting;
62464  }
62465
62466  return compilerMeta;
62467}
62468/**
62469 * @license
62470 * Copyright Google LLC All Rights Reserved.
62471 *
62472 * Use of this source code is governed by an MIT-style license that can be
62473 * found in the LICENSE file at https://angular.io/license
62474 */
62475
62476/**
62477 * Injectable decorator and metadata.
62478 *
62479 * @Annotation
62480 * @publicApi
62481 */
62482
62483
62484const Injectable = makeDecorator('Injectable', undefined, undefined, undefined, (type, meta) => compileInjectable(type, meta));
62485/**
62486 * @license
62487 * Copyright Google LLC All Rights Reserved.
62488 *
62489 * Use of this source code is governed by an MIT-style license that can be
62490 * found in the LICENSE file at https://angular.io/license
62491 */
62492
62493/**
62494 * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
62495 *
62496 * @publicApi
62497 */
62498
62499function createInjector(defType, parent = null, additionalProviders = null, name) {
62500  const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
62501  injector.resolveInjectorInitializers();
62502  return injector;
62503}
62504/**
62505 * Creates a new injector without eagerly resolving its injector types. Can be used in places
62506 * where resolving the injector types immediately can lead to an infinite loop. The injector types
62507 * should be resolved at a later point by calling `_resolveInjectorDefTypes`.
62508 */
62509
62510
62511function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
62512  const providers = [additionalProviders || EMPTY_ARRAY, importProvidersFrom(defType)];
62513  name = name || (typeof defType === 'object' ? undefined : stringify(defType));
62514  return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
62515}
62516/**
62517 * @license
62518 * Copyright Google LLC All Rights Reserved.
62519 *
62520 * Use of this source code is governed by an MIT-style license that can be
62521 * found in the LICENSE file at https://angular.io/license
62522 */
62523
62524/**
62525 * Concrete injectors implement this interface. Injectors are configured
62526 * with [providers](guide/glossary#provider) that associate
62527 * dependencies of various types with [injection tokens](guide/glossary#di-token).
62528 *
62529 * @see ["DI Providers"](guide/dependency-injection-providers).
62530 * @see `StaticProvider`
62531 *
62532 * @usageNotes
62533 *
62534 *  The following example creates a service injector instance.
62535 *
62536 * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
62537 *
62538 * ### Usage example
62539 *
62540 * {@example core/di/ts/injector_spec.ts region='Injector'}
62541 *
62542 * `Injector` returns itself when given `Injector` as a token:
62543 *
62544 * {@example core/di/ts/injector_spec.ts region='injectInjector'}
62545 *
62546 * @publicApi
62547 */
62548
62549
62550class Injector {
62551  static create(options, parent) {
62552    if (Array.isArray(options)) {
62553      return createInjector({
62554        name: ''
62555      }, parent, options, '');
62556    } else {
62557      const name = options.name ?? '';
62558      return createInjector({
62559        name
62560      }, options.parent, options.providers, name);
62561    }
62562  }
62563
62564}
62565
62566Injector.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
62567Injector.NULL = /* @__PURE__ */new NullInjector();
62568/** @nocollapse */
62569
62570Injector.ɵprov = ɵɵdefineInjectable({
62571  token: Injector,
62572  providedIn: 'any',
62573  factory: () => ɵɵinject(INJECTOR)
62574});
62575/**
62576 * @internal
62577 * @nocollapse
62578 */
62579
62580Injector.__NG_ELEMENT_ID__ = -1
62581/* InjectorMarkers.Injector */
62582;
62583/**
62584 * @license
62585 * Copyright Google LLC All Rights Reserved.
62586 *
62587 * Use of this source code is governed by an MIT-style license that can be
62588 * found in the LICENSE file at https://angular.io/license
62589 */
62590
62591function findFirstClosedCycle(keys) {
62592  const res = [];
62593
62594  for (let i = 0; i < keys.length; ++i) {
62595    if (res.indexOf(keys[i]) > -1) {
62596      res.push(keys[i]);
62597      return res;
62598    }
62599
62600    res.push(keys[i]);
62601  }
62602
62603  return res;
62604}
62605
62606function constructResolvingPath(keys) {
62607  if (keys.length > 1) {
62608    const reversed = findFirstClosedCycle(keys.slice().reverse());
62609    const tokenStrs = reversed.map(k => stringify(k.token));
62610    return ' (' + tokenStrs.join(' -> ') + ')';
62611  }
62612
62613  return '';
62614}
62615
62616function injectionError(injector, key, constructResolvingMessage, originalError) {
62617  const keys = [key];
62618  const errMsg = constructResolvingMessage(keys);
62619  const error = originalError ? wrappedError(errMsg, originalError) : Error(errMsg);
62620  error.addKey = addKey;
62621  error.keys = keys;
62622  error.injectors = [injector];
62623  error.constructResolvingMessage = constructResolvingMessage;
62624  error[ERROR_ORIGINAL_ERROR] = originalError;
62625  return error;
62626}
62627
62628function addKey(injector, key) {
62629  this.injectors.push(injector);
62630  this.keys.push(key); // Note: This updated message won't be reflected in the `.stack` property
62631
62632  this.message = this.constructResolvingMessage(this.keys);
62633}
62634/**
62635 * Thrown when trying to retrieve a dependency by key from {@link Injector}, but the
62636 * {@link Injector} does not have a {@link Provider} for the given key.
62637 *
62638 * @usageNotes
62639 * ### Example
62640 *
62641 * ```typescript
62642 * class A {
62643 *   constructor(b:B) {}
62644 * }
62645 *
62646 * expect(() => Injector.resolveAndCreate([A])).toThrowError();
62647 * ```
62648 */
62649
62650
62651function noProviderError(injector, key) {
62652  return injectionError(injector, key, function (keys) {
62653    const first = stringify(keys[0].token);
62654    return `No provider for ${first}!${constructResolvingPath(keys)}`;
62655  });
62656}
62657/**
62658 * Thrown when dependencies form a cycle.
62659 *
62660 * @usageNotes
62661 * ### Example
62662 *
62663 * ```typescript
62664 * var injector = Injector.resolveAndCreate([
62665 *   {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
62666 *   {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
62667 * ]);
62668 *
62669 * expect(() => injector.get("one")).toThrowError();
62670 * ```
62671 *
62672 * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
62673 */
62674
62675
62676function cyclicDependencyError(injector, key) {
62677  return injectionError(injector, key, function (keys) {
62678    return `Cannot instantiate cyclic dependency!${constructResolvingPath(keys)}`;
62679  });
62680}
62681/**
62682 * Thrown when a constructing type returns with an Error.
62683 *
62684 * The `InstantiationError` class contains the original error plus the dependency graph which caused
62685 * this object to be instantiated.
62686 *
62687 * @usageNotes
62688 * ### Example
62689 *
62690 * ```typescript
62691 * class A {
62692 *   constructor() {
62693 *     throw new Error('message');
62694 *   }
62695 * }
62696 *
62697 * var injector = Injector.resolveAndCreate([A]);
62698
62699 * try {
62700 *   injector.get(A);
62701 * } catch (e) {
62702 *   expect(e instanceof InstantiationError).toBe(true);
62703 *   expect(e.originalException.message).toEqual("message");
62704 *   expect(e.originalStack).toBeDefined();
62705 * }
62706 * ```
62707 */
62708
62709
62710function instantiationError(injector, originalException, originalStack, key) {
62711  return injectionError(injector, key, function (keys) {
62712    const first = stringify(keys[0].token);
62713    return `${originalException.message}: Error during instantiation of ${first}!${constructResolvingPath(keys)}.`;
62714  }, originalException);
62715}
62716/**
62717 * Thrown when an object other then {@link Provider} (or `Type`) is passed to {@link Injector}
62718 * creation.
62719 *
62720 * @usageNotes
62721 * ### Example
62722 *
62723 * ```typescript
62724 * expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
62725 * ```
62726 */
62727
62728
62729function invalidProviderError(provider) {
62730  return Error(`Invalid provider - only instances of Provider and Type are allowed, got: ${provider}`);
62731}
62732/**
62733 * Thrown when the class has no annotation information.
62734 *
62735 * Lack of annotation information prevents the {@link Injector} from determining which dependencies
62736 * need to be injected into the constructor.
62737 *
62738 * @usageNotes
62739 * ### Example
62740 *
62741 * ```typescript
62742 * class A {
62743 *   constructor(b) {}
62744 * }
62745 *
62746 * expect(() => Injector.resolveAndCreate([A])).toThrowError();
62747 * ```
62748 *
62749 * This error is also thrown when the class not marked with {@link Injectable} has parameter types.
62750 *
62751 * ```typescript
62752 * class B {}
62753 *
62754 * class A {
62755 *   constructor(b:B) {} // no information about the parameter types of A is available at runtime.
62756 * }
62757 *
62758 * expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
62759 * ```
62760 *
62761 */
62762
62763
62764function noAnnotationError(typeOrFunc, params) {
62765  const signature = [];
62766
62767  for (let i = 0, ii = params.length; i < ii; i++) {
62768    const parameter = params[i];
62769
62770    if (!parameter || parameter.length == 0) {
62771      signature.push('?');
62772    } else {
62773      signature.push(parameter.map(stringify).join(' '));
62774    }
62775  }
62776
62777  return Error('Cannot resolve all parameters for \'' + stringify(typeOrFunc) + '\'(' + signature.join(', ') + '). ' + 'Make sure that all the parameters are decorated with Inject or have valid type annotations and that \'' + stringify(typeOrFunc) + '\' is decorated with Injectable.');
62778}
62779/**
62780 * Thrown when getting an object by index.
62781 *
62782 * @usageNotes
62783 * ### Example
62784 *
62785 * ```typescript
62786 * class A {}
62787 *
62788 * var injector = Injector.resolveAndCreate([A]);
62789 *
62790 * expect(() => injector.getAt(100)).toThrowError();
62791 * ```
62792 *
62793 */
62794
62795
62796function outOfBoundsError(index) {
62797  return Error(`Index ${index} is out-of-bounds.`);
62798} // TODO: add a working example after alpha38 is released
62799
62800/**
62801 * Thrown when a multi provider and a regular provider are bound to the same token.
62802 *
62803 * @usageNotes
62804 * ### Example
62805 *
62806 * ```typescript
62807 * expect(() => Injector.resolveAndCreate([
62808 *   { provide: "Strings", useValue: "string1", multi: true},
62809 *   { provide: "Strings", useValue: "string2", multi: false}
62810 * ])).toThrowError();
62811 * ```
62812 */
62813
62814
62815function mixingMultiProvidersWithRegularProvidersError(provider1, provider2) {
62816  return Error(`Cannot mix multi providers and regular providers, got: ${provider1} ${provider2}`);
62817}
62818/**
62819 * @license
62820 * Copyright Google LLC All Rights Reserved.
62821 *
62822 * Use of this source code is governed by an MIT-style license that can be
62823 * found in the LICENSE file at https://angular.io/license
62824 */
62825
62826/**
62827 * A unique object used for retrieving items from the {@link ReflectiveInjector}.
62828 *
62829 * Keys have:
62830 * - a system-wide unique `id`.
62831 * - a `token`.
62832 *
62833 * `Key` is used internally by {@link ReflectiveInjector} because its system-wide unique `id` allows
62834 * the
62835 * injector to store created objects in a more efficient way.
62836 *
62837 * `Key` should not be created directly. {@link ReflectiveInjector} creates keys automatically when
62838 * resolving
62839 * providers.
62840 *
62841 * @deprecated No replacement
62842 * @publicApi
62843 */
62844
62845
62846class ReflectiveKey {
62847  /**
62848   * Private
62849   */
62850  constructor(token, id) {
62851    this.token = token;
62852    this.id = id;
62853
62854    if (!token) {
62855      throw new RuntimeError(208
62856      /* RuntimeErrorCode.MISSING_INJECTION_TOKEN */
62857      , ngDevMode && 'Token must be defined!');
62858    }
62859
62860    this.displayName = stringify(this.token);
62861  }
62862  /**
62863   * Retrieves a `Key` for a token.
62864   */
62865
62866
62867  static get(token) {
62868    return _globalKeyRegistry.get(resolveForwardRef(token));
62869  }
62870  /**
62871   * @returns the number of keys registered in the system.
62872   */
62873
62874
62875  static get numberOfKeys() {
62876    return _globalKeyRegistry.numberOfKeys;
62877  }
62878
62879}
62880
62881class KeyRegistry {
62882  constructor() {
62883    this._allKeys = new Map();
62884  }
62885
62886  get(token) {
62887    if (token instanceof ReflectiveKey) return token;
62888
62889    if (this._allKeys.has(token)) {
62890      return this._allKeys.get(token);
62891    }
62892
62893    const newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys);
62894
62895    this._allKeys.set(token, newKey);
62896
62897    return newKey;
62898  }
62899
62900  get numberOfKeys() {
62901    return this._allKeys.size;
62902  }
62903
62904}
62905
62906const _globalKeyRegistry = new KeyRegistry();
62907/**
62908 * @license
62909 * Copyright Google LLC All Rights Reserved.
62910 *
62911 * Use of this source code is governed by an MIT-style license that can be
62912 * found in the LICENSE file at https://angular.io/license
62913 */
62914
62915/**
62916 * `Dependency` is used by the framework to extend DI.
62917 * This is internal to Angular and should not be used directly.
62918 */
62919
62920
62921class ReflectiveDependency {
62922  constructor(key, optional, visibility) {
62923    this.key = key;
62924    this.optional = optional;
62925    this.visibility = visibility;
62926  }
62927
62928  static fromKey(key) {
62929    return new ReflectiveDependency(key, false, null);
62930  }
62931
62932}
62933
62934const _EMPTY_LIST = [];
62935
62936class ResolvedReflectiveProvider_ {
62937  constructor(key, resolvedFactories, multiProvider) {
62938    this.key = key;
62939    this.resolvedFactories = resolvedFactories;
62940    this.multiProvider = multiProvider;
62941    this.resolvedFactory = this.resolvedFactories[0];
62942  }
62943
62944}
62945/**
62946 * An internal resolved representation of a factory function created by resolving `Provider`.
62947 * @publicApi
62948 */
62949
62950
62951class ResolvedReflectiveFactory {
62952  constructor(
62953  /**
62954   * Factory function which can return an instance of an object represented by a key.
62955   */
62956  factory,
62957  /**
62958   * Arguments (dependencies) to the `factory` function.
62959   */
62960  dependencies) {
62961    this.factory = factory;
62962    this.dependencies = dependencies;
62963  }
62964
62965}
62966/**
62967 * Resolve a single provider.
62968 */
62969
62970
62971function resolveReflectiveFactory(provider) {
62972  let factoryFn;
62973  let resolvedDeps;
62974
62975  if (provider.useClass) {
62976    const useClass = resolveForwardRef(provider.useClass);
62977    factoryFn = getReflect().factory(useClass);
62978    resolvedDeps = _dependenciesFor(useClass);
62979  } else if (provider.useExisting) {
62980    factoryFn = aliasInstance => aliasInstance;
62981
62982    resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
62983  } else if (provider.useFactory) {
62984    factoryFn = provider.useFactory;
62985    resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
62986  } else {
62987    factoryFn = () => provider.useValue;
62988
62989    resolvedDeps = _EMPTY_LIST;
62990  }
62991
62992  return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);
62993}
62994/**
62995 * Converts the `Provider` into `ResolvedProvider`.
62996 *
62997 * `Injector` internally only uses `ResolvedProvider`, `Provider` contains convenience provider
62998 * syntax.
62999 */
63000
63001
63002function resolveReflectiveProvider(provider) {
63003  return new ResolvedReflectiveProvider_(ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false);
63004}
63005/**
63006 * Resolve a list of Providers.
63007 */
63008
63009
63010function resolveReflectiveProviders(providers) {
63011  const normalized = _normalizeProviders(providers, []);
63012
63013  const resolved = normalized.map(resolveReflectiveProvider);
63014  const resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());
63015  return Array.from(resolvedProviderMap.values());
63016}
63017/**
63018 * Merges a list of ResolvedProviders into a list where each key is contained exactly once and
63019 * multi providers have been merged.
63020 */
63021
63022
63023function mergeResolvedReflectiveProviders(providers, normalizedProvidersMap) {
63024  for (let i = 0; i < providers.length; i++) {
63025    const provider = providers[i];
63026    const existing = normalizedProvidersMap.get(provider.key.id);
63027
63028    if (existing) {
63029      if (provider.multiProvider !== existing.multiProvider) {
63030        throw mixingMultiProvidersWithRegularProvidersError(existing, provider);
63031      }
63032
63033      if (provider.multiProvider) {
63034        for (let j = 0; j < provider.resolvedFactories.length; j++) {
63035          existing.resolvedFactories.push(provider.resolvedFactories[j]);
63036        }
63037      } else {
63038        normalizedProvidersMap.set(provider.key.id, provider);
63039      }
63040    } else {
63041      let resolvedProvider;
63042
63043      if (provider.multiProvider) {
63044        resolvedProvider = new ResolvedReflectiveProvider_(provider.key, provider.resolvedFactories.slice(), provider.multiProvider);
63045      } else {
63046        resolvedProvider = provider;
63047      }
63048
63049      normalizedProvidersMap.set(provider.key.id, resolvedProvider);
63050    }
63051  }
63052
63053  return normalizedProvidersMap;
63054}
63055
63056function _normalizeProviders(providers, res) {
63057  providers.forEach(b => {
63058    if (b instanceof Type) {
63059      res.push({
63060        provide: b,
63061        useClass: b
63062      });
63063    } else if (b && typeof b == 'object' && b.provide !== undefined) {
63064      res.push(b);
63065    } else if (Array.isArray(b)) {
63066      _normalizeProviders(b, res);
63067    } else {
63068      throw invalidProviderError(b);
63069    }
63070  });
63071  return res;
63072}
63073
63074function constructDependencies(typeOrFunc, dependencies) {
63075  if (!dependencies) {
63076    return _dependenciesFor(typeOrFunc);
63077  } else {
63078    const params = dependencies.map(t => [t]);
63079    return dependencies.map(t => _extractToken(typeOrFunc, t, params));
63080  }
63081}
63082
63083function _dependenciesFor(typeOrFunc) {
63084  const params = getReflect().parameters(typeOrFunc);
63085  if (!params) return [];
63086
63087  if (params.some(p => p == null)) {
63088    throw noAnnotationError(typeOrFunc, params);
63089  }
63090
63091  return params.map(p => _extractToken(typeOrFunc, p, params));
63092}
63093
63094function _extractToken(typeOrFunc, metadata, params) {
63095  let token = null;
63096  let optional = false;
63097
63098  if (!Array.isArray(metadata)) {
63099    if (metadata instanceof Inject) {
63100      return _createDependency(metadata.token, optional, null);
63101    } else {
63102      return _createDependency(metadata, optional, null);
63103    }
63104  }
63105
63106  let visibility = null;
63107
63108  for (let i = 0; i < metadata.length; ++i) {
63109    const paramMetadata = metadata[i];
63110
63111    if (paramMetadata instanceof Type) {
63112      token = paramMetadata;
63113    } else if (paramMetadata instanceof Inject) {
63114      token = paramMetadata.token;
63115    } else if (paramMetadata instanceof Optional) {
63116      optional = true;
63117    } else if (paramMetadata instanceof Self || paramMetadata instanceof SkipSelf) {
63118      visibility = paramMetadata;
63119    } else if (paramMetadata instanceof InjectionToken) {
63120      token = paramMetadata;
63121    }
63122  }
63123
63124  token = resolveForwardRef(token);
63125
63126  if (token != null) {
63127    return _createDependency(token, optional, visibility);
63128  } else {
63129    throw noAnnotationError(typeOrFunc, params);
63130  }
63131}
63132
63133function _createDependency(token, optional, visibility) {
63134  return new ReflectiveDependency(ReflectiveKey.get(token), optional, visibility);
63135}
63136/**
63137 * @license
63138 * Copyright Google LLC All Rights Reserved.
63139 *
63140 * Use of this source code is governed by an MIT-style license that can be
63141 * found in the LICENSE file at https://angular.io/license
63142 */
63143// Threshold for the dynamic version
63144
63145
63146const UNDEFINED = {};
63147/**
63148 * A ReflectiveDependency injection container used for instantiating objects and resolving
63149 * dependencies.
63150 *
63151 * An `Injector` is a replacement for a `new` operator, which can automatically resolve the
63152 * constructor dependencies.
63153 *
63154 * In typical use, application code asks for the dependencies in the constructor and they are
63155 * resolved by the `Injector`.
63156 *
63157 * @usageNotes
63158 * ### Example
63159 *
63160 * The following example creates an `Injector` configured to create `Engine` and `Car`.
63161 *
63162 * ```typescript
63163 * @Injectable()
63164 * class Engine {
63165 * }
63166 *
63167 * @Injectable()
63168 * class Car {
63169 *   constructor(public engine:Engine) {}
63170 * }
63171 *
63172 * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
63173 * var car = injector.get(Car);
63174 * expect(car instanceof Car).toBe(true);
63175 * expect(car.engine instanceof Engine).toBe(true);
63176 * ```
63177 *
63178 * Notice, we don't use the `new` operator because we explicitly want to have the `Injector`
63179 * resolve all of the object's dependencies automatically.
63180 *
63181 * TODO: delete in v14.
63182 *
63183 * @deprecated from v5 - slow and brings in a lot of code, Use `Injector.create` instead.
63184 * @publicApi
63185 */
63186
63187class ReflectiveInjector {
63188  /**
63189   * Turns an array of provider definitions into an array of resolved providers.
63190   *
63191   * A resolution is a process of flattening multiple nested arrays and convert
63191ing individual
63192   * providers into an array of `ResolvedReflectiveProvider`s.
63193   *
63194   * @usageNotes
63195   * ### Example
63196   *
63197   * ```typescript
63198   * @Injectable()
63199   * class Engine {
63200   * }
63201   *
63202   * @Injectable()
63203   * class Car {
63204   *   constructor(public engine:Engine) {}
63205   * }
63206   *
63207   * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
63208   *
63209   * expect(providers.length).toEqual(2);
63210   *
63211   * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
63212   * expect(providers[0].key.displayName).toBe("Car");
63213   * expect(providers[0].dependencies.length).toEqual(1);
63214   * expect(providers[0].factory).toBeDefined();
63215   *
63216   * expect(providers[1].key.displayName).toBe("Engine");
63217   * });
63218   * ```
63219   *
63220   */
63221  static resolve(providers) {
63222    return resolveReflectiveProviders(providers);
63223  }
63224  /**
63225   * Resolves an array of providers and creates an injector from those providers.
63226   *
63227   * The passed-in providers can be an array of `Type`, `Provider`,
63228   * or a recursive array of more providers.
63229   *
63230   * @usageNotes
63231   * ### Example
63232   *
63233   * ```typescript
63234   * @Injectable()
63235   * class Engine {
63236   * }
63237   *
63238   * @Injectable()
63239   * class Car {
63240   *   constructor(public engine:Engine) {}
63241   * }
63242   *
63243   * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
63244   * expect(injector.get(Car) instanceof Car).toBe(true);
63245   * ```
63246   */
63247
63248
63249  static resolveAndCreate(providers, parent) {
63250    const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
63251    return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
63252  }
63253  /**
63254   * Creates an injector from previously resolved providers.
63255   *
63256   * This API is the recommended way to construct injectors in performance-sensitive parts.
63257   *
63258   * @usageNotes
63259   * ### Example
63260   *
63261   * ```typescript
63262   * @Injectable()
63263   * class Engine {
63264   * }
63265   *
63266   * @Injectable()
63267   * class Car {
63268   *   constructor(public engine:Engine) {}
63269   * }
63270   *
63271   * var providers = ReflectiveInjector.resolve([Car, Engine]);
63272   * var injector = ReflectiveInjector.fromResolvedProviders(providers);
63273   * expect(injector.get(Car) instanceof Car).toBe(true);
63274   * ```
63275   */
63276
63277
63278  static fromResolvedProviders(providers, parent) {
63279    return new ReflectiveInjector_(providers, parent);
63280  }
63281
63282}
63283
63284class ReflectiveInjector_ {
63285  /**
63286   * Private
63287   */
63288  constructor(_providers, _parent) {
63289    /** @internal */
63290    this._constructionCounter = 0;
63291    this._providers = _providers;
63292    this.parent = _parent || null;
63293    const len = _providers.length;
63294    this.keyIds = [];
63295    this.objs = [];
63296
63297    for (let i = 0; i < len; i++) {
63298      this.keyIds[i] = _providers[i].key.id;
63299      this.objs[i] = UNDEFINED;
63300    }
63301  }
63302
63303  get(token, notFoundValue = THROW_IF_NOT_FOUND) {
63304    return this._getByKey(ReflectiveKey.get(token), null, notFoundValue);
63305  }
63306
63307  resolveAndCreateChild(providers) {
63308    const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
63309    return this.createChildFromResolved(ResolvedReflectiveProviders);
63310  }
63311
63312  createChildFromResolved(providers) {
63313    const inj = new ReflectiveInjector_(providers);
63314    inj.parent = this;
63315    return inj;
63316  }
63317
63318  resolveAndInstantiate(provider) {
63319    return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]);
63320  }
63321
63322  instantiateResolved(provider) {
63323    return this._instantiateProvider(provider);
63324  }
63325
63326  getProviderAtIndex(index) {
63327    if (index < 0 || index >= this._providers.length) {
63328      throw outOfBoundsError(index);
63329    }
63330
63331    return this._providers[index];
63332  }
63333  /** @internal */
63334
63335
63336  _new(provider) {
63337    if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
63338      throw cyclicDependencyError(this, provider.key);
63339    }
63340
63341    return this._instantiateProvider(provider);
63342  }
63343
63344  _getMaxNumberOfObjects() {
63345    return this.objs.length;
63346  }
63347
63348  _instantiateProvider(provider) {
63349    if (provider.multiProvider) {
63350      const res = [];
63351
63352      for (let i = 0; i < provider.resolvedFactories.length; ++i) {
63353        res[i] = this._instantiate(provider, provider.resolvedFactories[i]);
63354      }
63355
63356      return res;
63357    } else {
63358      return this._instantiate(provider, provider.resolvedFactories[0]);
63359    }
63360  }
63361
63362  _instantiate(provider, ResolvedReflectiveFactory) {
63363    const factory = ResolvedReflectiveFactory.factory;
63364    let deps;
63365
63366    try {
63367      deps = ResolvedReflectiveFactory.dependencies.map(dep => this._getByReflectiveDependency(dep));
63368    } catch (e) {
63369      if (e.addKey) {
63370        e.addKey(this, provider.key);
63371      }
63372
63373      throw e;
63374    }
63375
63376    let obj;
63377
63378    try {
63379      obj = factory(...deps);
63380    } catch (e) {
63381      throw instantiationError(this, e, e.stack, provider.key);
63382    }
63383
63384    return obj;
63385  }
63386
63387  _getByReflectiveDependency(dep) {
63388    return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);
63389  }
63390
63391  _getByKey(key, visibility, notFoundValue) {
63392    if (key === ReflectiveInjector_.INJECTOR_KEY) {
63393      return this;
63394    }
63395
63396    if (visibility instanceof Self) {
63397      return this._getByKeySelf(key, notFoundValue);
63398    } else {
63399      return this._getByKeyDefault(key, notFoundValue, visibility);
63400    }
63401  }
63402
63403  _getObjByKeyId(keyId) {
63404    for (let i = 0; i < this.keyIds.length; i++) {
63405      if (this.keyIds[i] === keyId) {
63406        if (this.objs[i] === UNDEFINED) {
63407          this.objs[i] = this._new(this._providers[i]);
63408        }
63409
63410        return this.objs[i];
63411      }
63412    }
63413
63414    return UNDEFINED;
63415  }
63416  /** @internal */
63417
63418
63419  _throwOrNull(key, notFoundValue) {
63420    if (notFoundValue !== THROW_IF_NOT_FOUND) {
63421      return notFoundValue;
63422    } else {
63423      throw noProviderError(this, key);
63424    }
63425  }
63426  /** @internal */
63427
63428
63429  _getByKeySelf(key, notFoundValue) {
63430    const obj = this._getObjByKeyId(key.id);
63431
63432    return obj !== UNDEFINED ? obj : this._throwOrNull(key, notFoundValue);
63433  }
63434  /** @internal */
63435
63436
63437  _getByKeyDefault(key, notFoundValue, visibility) {
63438    let inj;
63439
63440    if (visibility instanceof SkipSelf) {
63441      inj = this.parent;
63442    } else {
63443      inj = this;
63444    }
63445
63446    while (inj instanceof ReflectiveInjector_) {
63447      const inj_ = inj;
63448
63449      const obj = inj_._getObjByKeyId(key.id);
63450
63451      if (obj !== UNDEFINED) return obj;
63452      inj = inj_.parent;
63453    }
63454
63455    if (inj !== null) {
63456      return inj.get(key.token, notFoundValue);
63457    } else {
63458      return this._throwOrNull(key, notFoundValue);
63459    }
63460  }
63461
63462  get displayName() {
63463    const providers = _mapProviders(this, b => ' "' + b.key.displayName + '" ').join(', ');
63464
63465    return `ReflectiveInjector(providers: [${providers}])`;
63466  }
63467
63468  toString() {
63469    return this.displayName;
63470  }
63471
63472}
63473
63474ReflectiveInjector_.INJECTOR_KEY = /* @__PURE__ */ReflectiveKey.get(Injector);
63475
63476function _mapProviders(injector, fn) {
63477  const res = [];
63478
63479  for (let i = 0; i < injector._providers.length; ++i) {
63480    res[i] = fn(injector.getProviderAtIndex(i));
63481  }
63482
63483  return res;
63484}
63485/**
63486 * @license
63487 * Copyright Google LLC All Rights Reserved.
63488 *
63489 * Use of this source code is governed by an MIT-style license that can be
63490 * found in the LICENSE file at https://angular.io/license
63491 */
63492
63493/**
63494 * @license
63495 * Copyright Google LLC All Rights Reserved.
63496 *
63497 * Use of this source code is governed by an MIT-style license that can be
63498 * found in the LICENSE file at https://angular.io/license
63499 */
63500
63501/**
63502 * @license
63503 * Copyright Google LLC All Rights Reserved.
63504 *
63505 * Use of this source code is governed by an MIT-style license that can be
63506 * found in the LICENSE file at https://angular.io/license
63507 */
63508
63509
63510function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
63511  const lView = getLView(); // Fall back to inject() if view hasn't been created. This situation can happen in tests
63512  // if inject utilities are used before bootstrapping.
63513
63514  if (lView === null) {
63515    // Verify that we will not get into infinite loop.
63516    ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
63517    return ɵɵinject(token, flags);
63518  }
63519
63520  const tNode = getCurrentTNode();
63521  return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
63522}
63523/**
63524 * Throws an error indicating that a factory function could not be generated by the compiler for a
63525 * particular class.
63526 *
63527 * This instruction allows the actual error message to be optimized away when ngDevMode is turned
63528 * off, saving bytes of generated code while still providing a good experience in dev mode.
63529 *
63530 * The name of the class is not mentioned here, but will be in the generated factory function name
63531 * and thus in the stack trace.
63532 *
63533 * @codeGenApi
63534 */
63535
63536
63537function ɵɵinvalidFactory() {
63538  const msg = ngDevMode ? `This constructor was not compatible with Dependency Injection.` : 'invalid';
63539  throw new Error(msg);
63540}
63541/**
63542 * @license
63543 * Copyright Google LLC All Rights Reserved.
63544 *
63545 * Use of this source code is governed by an MIT-style license that can be
63546 * found in the LICENSE file at https://angular.io/license
63547 */
63548
63549/**
63550 * THIS FILE CONTAINS CODE WHICH SHOULD BE TREE SHAKEN AND NEVER CALLED FROM PRODUCTION CODE!!!
63551 */
63552
63553/**
63554 * Creates an `Array` construction with a given name. This is useful when
63555 * looking for memory consumption to see what time of array it is.
63556 *
63557 *
63558 * @param name Name to give to the constructor
63559 * @returns A subclass of `Array` if possible. This can only be done in
63560 *          environments which support `class` construct.
63561 */
63562
63563
63564function createNamedArrayType(name) {
63565  // This should never be called in prod mode, so let's verify that is the case.
63566  if (ngDevMode) {
63567    try {
63568      // If this function were compromised the following could lead to arbitrary
63569      // script execution. We bless it with Trusted Types anyway since this
63570      // function is stripped out of production binaries.
63571      return newTrustedFunctionForDev('Array', `return class ${name} extends Array{}`)(Array);
63572    } catch (e) {
63573      // If it does not work just give up and fall back to regular Array.
63574      return Array;
63575    }
63576  } else {
63577    throw new Error('Looks like we are in \'prod mode\', but we are creating a named Array type, which is wrong! Check your code');
63578  }
63579}
63580/**
63581 * @license
63582 * Copyright Google LLC All Rights Reserved.
63583 *
63584 * Use of this source code is governed by an MIT-style license that can be
63585 * found in the LICENSE file at https://angular.io/license
63586 */
63587
63588
63589function toTStylingRange(prev, next) {
63590  ngDevMode && assertNumberInRange(prev, 0, 32767
63591  /* StylingRange.UNSIGNED_MASK */
63592  );
63593  ngDevMode && assertNumberInRange(next, 0, 32767
63594  /* StylingRange.UNSIGNED_MASK */
63595  );
63596  return prev << 17
63597  /* StylingRange.PREV_SHIFT */
63598  | next << 2
63599  /* StylingRange.NEXT_SHIFT */
63600  ;
63601}
63602
63603function getTStylingRangePrev(tStylingRange) {
63604  ngDevMode && assertNumber(tStylingRange, 'expected number');
63605  return tStylingRange >> 17
vendor: 1,591 bytes, lines 63606-63666
63606  /* StylingRange.PREV_SHIFT */
63607  & 32767
63608  /* StylingRange.UNSIGNED_MASK */
63609  ;
63610}
63611
63612function getTStylingRangePrevDuplicate(tStylingRange) {
63613  ngDevMode && assertNumber(tStylingRange, 'expected number');
63614  return (tStylingRange & 2
63615  /* StylingRange.PREV_DUPLICATE */
63616  ) == 2
63617  /* StylingRange.PREV_DUPLICATE */
63618  ;
63619}
63620
63621function setTStylingRangePrev(tStylingRange, previous) {
63622  ngDevMode && assertNumber(tStylingRange, 'expected number');
63623  ngDevMode && assertNumberInRange(previous, 0, 32767
63624  /* StylingRange.UNSIGNED_MASK */
63625  );
63626  return tStylingRange & ~4294836224
63627  /* StylingRange.PREV_MASK */
63628  | previous << 17
63629  /* StylingRange.PREV_SHIFT */
63630  ;
63631}
63632
63633function setTStylingRangePrevDuplicate(tStylingRange) {
63634  ngDevMode && assertNumber(tStylingRange, 'expected number');
63635  return tStylingRange | 2
63636  /* StylingRange.PREV_DUPLICATE */
63637  ;
63638}
63639
63640function getTStylingRangeNext(tStylingRange) {
63641  ngDevMode && assertNumber(tStylingRange, 'expected number');
63642  return (tStylingRange & 131068
63643  /* StylingRange.NEXT_MASK */
63644  ) >> 2
63645  /* StylingRange.NEXT_SHIFT */
63646  ;
63647}
63648
63649function setTStylingRangeNext(tStylingRange, next) {
63650  ngDevMode && assertNumber(tStylingRange, 'expected number');
63651  ngDevMode && assertNumberInRange(next, 0, 32767
63652  /* StylingRange.UNSIGNED_MASK */
63653  );
63654  return tStylingRange & ~131068
63655  /* StylingRange.NEXT_MASK */
63656  | //
63657  next << 2
63658  /* StylingRange.NEXT_SHIFT */
63659  ;
63660}
63661
63662function getTStylingRangeNextDuplicate(tStylingRange) {
63663  ngDevMode && assertNumber(tStylingRange, 'expected number');
63664  return (tStylingRange & 1
63665  /* StylingRange.NEXT_DUPLICATE */
63666  ) === 1
63667  /* StylingRange.NEXT_DUPLICATE */
63668  ;
63669}
63670
63671function setTStylingRangeNextDuplicate(tStylingRange) {
63672  ngDevMode && assertNumber(tStylingRange, 'expected number');
63673  return tStylingRange | 1
63674  /* StylingRange.NEXT_DUPLICATE */
63675  ;
63676}
63677
63678function getTStylingRangeTail(tStylingRange) {
63679  ngDevMode && assertNumber(tStylingRange, 'expected number');
63680  const next = getTStylingRangeNext(tStylingRange);
63681  return next === 0 ? getTStylingRangePrev(tStylingRange) : next;
63682}
63683/**
63684 * @license
63685 * Copyright Google LLC All Rights Reserved.
63686 *
63687 * Use of this source code is governed by an MIT-style license that can be
63688 * found in the LICENSE file at https://angular.io/license
63689 */
63690
63691/**
63692 * Patch a `debug` property on top of the existing object.
63693 *
63694 * NOTE: always call this method with `ngDevMode && attachDebugObject(...)`
63695 *
63696 * @param obj Object to patch
63697 * @param debug Value to patch
63698 */
63699
63700
63701function attachDebugObject(obj, debug) {
63702  if (ngDevMode) {
63703    Object.defineProperty(obj, 'debug', {
63704      value: debug,
63705      enumerable: false
63706    });
63707  } else {
63708    throw new Error('This method should be guarded with `ngDevMode` so that it can be tree shaken in production!');
63709  }
63710}
63711/**
63712 * Patch a `debug` property getter on top of the existing object.
63713 *
63714 * NOTE: always call this method with `ngDevMode && attachDebugObject(...)`
63715 *
63716 * @param obj Object to patch
63717 * @param debugGetter Getter returning a value to patch
63718 */
63719
63720
63721function attachDebugGetter(obj, debugGetter) {
63722  if (ngDevMode) {
63723    Object.defineProperty(obj, 'debug', {
63724      get: debugGetter,
63725      enumerable: false
63726    });
63727  } else {
63728    throw new Error('This method should be guarded with `ngDevMode` so that it can be tree shaken in production!');
63729  }
63730}
63731/**
63732 * @license
63733 * Copyright Google LLC All Rights Reserved.
63734 *
63735 * Use of this source code is governed by an MIT-style license that can be
63736 * found in the LICENSE file at https://angular.io/license
63737 */
63738
63739/*
63740 * This file contains conditionally attached classes which provide human readable (debug) level
63741 * information for `LView`, `LContainer` and other internal data structures. These data structures
63742 * are stored internally as array which makes it very difficult during debugging to reason about the
63743 * current state of the system.
63744 *
63745 * Patching the array with extra property does change the array's hidden class' but it does not
63746 * change the cost of access, therefore this patching should not have significant if any impact in
63747 * `ngDevMode` mode. (see: https://jsperf.com/array-vs-monkey-patch-array)
63748 *
63749 * So instead of seeing:
63750 * ```
63751 * Array(30) [Object, 659, null, …]
63752 * ```
63753 *
63754 * You get to see:
63755 * ```
63756 * LViewDebug {
63757 *   views: [...],
63758 *   flags: {attached: true, ...}
63759 *   nodes: [
63760 *     {html: '<div id="123">', ..., nodes: [
63761 *       {html: '<span>', ..., nodes: null}
63762 *     ]}
63763 *   ]
63764 * }
63765 * ```
63766 */
63767
63768
63769let LVIEW_COMPONENT_CACHE;
63770let LVIEW_EMBEDDED_CACHE;
63771let LVIEW_ROOT;
63772let LVIEW_COMPONENT;
63773let LVIEW_EMBEDDED;
63774/**
63775 * This function clones a blueprint and creates LView.
63776 *
63777 * Simple slice will keep the same type, and we need it to be LView
63778 */
63779
63780function cloneToLViewFromTViewBlueprint(tView) {
63781  const debugTView = tView;
63782  const lView = getLViewToClone(debugTView.type, tView.template && tView.template.name);
63783  return lView.concat(tView.blueprint);
63784}
63785
63786class LRootView extends Array {}
63787
63788class LComponentView extends Array {}
63789
63790class LEmbeddedView extends Array {}
63791
63792function getLViewToClone(type, name) {
63793  switch (type) {
63794    case 0
63795    /* TViewType.Root */
63796    :
63797      if (LVIEW_ROOT === undefined) LVIEW_ROOT = new LRootView();
63798      return LVIEW_ROOT;
63799
63800    case 1
63801    /* TViewType.Component */
63802    :
63803      if (!ngDevMode || !ngDevMode.namedConstructors) {
63804        if (LVIEW_COMPONENT === undefined) LVIEW_COMPONENT = new LComponentView();
63805        return LVIEW_COMPONENT;
63806      }
63807
63808      if (LVIEW_COMPONENT_CACHE === undefined) LVIEW_COMPONENT_CACHE = new Map();
63809      let componentArray = LVIEW_COMPONENT_CACHE.get(name);
63810
63811      if (componentArray === undefined) {
63812        componentArray = new (createNamedArrayType('LComponentView' + nameSuffix(name)))();
63813        LVIEW_COMPONENT_CACHE.set(name, componentArray);
63814      }
63815
63816      return componentArray;
63817
63818    case 2
63819    /* TViewType.Embedded */
63820    :
63821      if (!ngDevMode || !ngDevMode.namedConstructors) {
63822        if (LVIEW_EMBEDDED === undefined) LVIEW_EMBEDDED = new LEmbeddedView();
63823        return LVIEW_EMBEDDED;
63824      }
63825
63826      if (LVIEW_EMBEDDED_CACHE === undefined) LVIEW_EMBEDDED_CACHE = new Map();
63827      let embeddedArray = LVIEW_EMBEDDED_CACHE.get(name);
63828
63829      if (embeddedArray === undefined) {
63830        embeddedArray = new (createNamedArrayType('LEmbeddedView' + nameSuffix(name)))();
63831        LVIEW_EMBEDDED_CACHE.set(name, embeddedArray);
63832      }
63833
63834      return embeddedArray;
63835  }
63836}
63837
63838function nameSuffix(text) {
63839  if (text == null) return '';
63840  const index = text.lastIndexOf('_Template');
63841  return '_' + (index === -1 ? text : text.slice(0, index));
63842}
63843/**
63844 * This class is a debug version of Object literal so that we can have constructor name show up
63845 * in
63846 * debug tools in ngDevMode.
63847 */
63848
63849
63850const TViewConstructor = class TView {
63851  constructor(type, blueprint, template, queries, viewQuery, declTNode, data, bindingStartIndex, expandoStartIndex, hostBindingOpCodes, firstCreatePass, firstUpdatePass, staticViewQueries, staticContentQueries, preOrderHooks, preOrderCheckHooks, contentHooks, c
63851ontentCheckHooks, viewHooks, viewCheckHooks, destroyHooks, cleanup, contentQueries, components, directiveRegistry, pipeRegistry, firstChild, schemas, consts, incompleteFirstPass, _decls, _vars) {
63852    this.type = type;
63853    this.blueprint = blueprint;
63854    this.template = template;
63855    this.queries = queries;
63856    this.viewQuery = viewQuery;
63857    this.declTNode = declTNode;
63858    this.data = data;
63859    this.bindingStartIndex = bindingStartIndex;
63860    this.expandoStartIndex = expandoStartIndex;
63861    this.hostBindingOpCodes = hostBindingOpCodes;
63862    this.firstCreatePass = firstCreatePass;
63863    this.firstUpdatePass = firstUpdatePass;
63864    this.staticViewQueries = staticViewQueries;
63865    this.staticContentQueries = staticContentQueries;
63866    this.preOrderHooks = preOrderHooks;
63867    this.preOrderCheckHooks = preOrderCheckHooks;
63868    this.contentHooks = contentHooks;
63869    this.contentCheckHooks = contentCheckHooks;
63870    this.viewHooks = viewHooks;
63871    this.viewCheckHooks = viewCheckHooks;
63872    this.destroyHooks = destroyHooks;
63873    this.cleanup = cleanup;
63874    this.contentQueries = contentQueries;
63875    this.components = components;
63876    this.directiveRegistry = directiveRegistry;
63877    this.pipeRegistry = pipeRegistry;
63878    this.firstChild = firstChild;
63879    this.schemas = schemas;
63880    this.consts = consts;
63881    this.incompleteFirstPass = incompleteFirstPass;
63882    this._decls = _decls;
63883    this._vars = _vars;
63884  }
63885
63886  get template_() {
63887    const buf = [];
63888    processTNodeChildren(this.firstChild, buf);
63889    return buf.join('');
63890  }
63891
63892  get type_() {
63893    return TViewTypeAsString[this.type] || `TViewType.?${this.type}?`;
63894  }
63895
63896};
63897
63898class TNode {
63899  constructor(tView_, //
63900  type, //
63901  index, //
63902  insertBeforeIndex, //
63903  injectorIndex, //
63904  directiveStart, //
63905  directiveEnd, //
63906  directiveStylingLast, //
63907  propertyBindings, //
63908  flags, //
63909  providerIndexes, //
63910  value, //
63911  attrs, //
63912  mergedAttrs, //
63913  localNames, //
63914  initialInputs, //
63915  inputs, //
63916  outputs, //
63917  tViews, //
63918  next, //
63919  projectionNext, //
63920  child, //
63921  parent, //
63922  projection, //
63923  styles, //
63924  stylesWithoutHost, //
63925  residualStyles, //
63926  classes, //
63927  classesWithoutHost, //
63928  residualClasses, //
63929  classBindings, //
63930  styleBindings) {
63931    this.tView_ = tView_;
63932    this.type = type;
63933    this.index = index;
63934    this.insertBeforeIndex = insertBeforeIndex;
63935    this.injectorIndex = injectorIndex;
63936    this.directiveStart = directiveStart;
63937    this.directiveEnd = directiveEnd;
63938    this.directiveStylingLast = directiveStylingLast;
63939    this.propertyBindings = propertyBindings;
63940    this.flags = flags;
63941    this.providerIndexes = providerIndexes;
63942    this.value = value;
63943    this.attrs = attrs;
63944    this.mergedAttrs = mergedAttrs;
63945    this.localNames = localNames;
63946    this.initialInputs = initialInputs;
63947    this.inputs = inputs;
63948    this.outputs = outputs;
63949    this.tViews = tViews;
63950    this.next = next;
63951    this.projectionNext = projectionNext;
63952    this.child = child;
63953    this.parent = parent;
63954    this.projection = projection;
63955    this.styles = styles;
63956    this.stylesWithoutHost = stylesWithoutHost;
63957    this.residualStyles = residualStyles;
63958    this.classes = classes;
63959    this.classesWithoutHost = classesWithoutHost;
63960    this.residualClasses = residualClasses;
63961    this.classBindings = classBindings;
63962    this.styleBindings = styleBindings;
63963  }
63964  /**
63965   * Return a human debug version of the set of `NodeInjector`s which will be consulted when
63966   * resolving tokens from this `TNode`.
63967   *
63968   * When debugging applications, it is often difficult to determine which `NodeInjector`s will be
63969   * consulted. This method shows a list of `DebugNode`s representing the `TNode`s which will be
63970   * consulted in order when resolving a token starting at this `TNode`.
63971   *
63972   * The original data is stored in `LView` and `TView` with a lot of offset indexes, and so it is
63973   * difficult to reason about.
63974   *
63975   * @param lView The `LView` instance for this `TNode`.
63976   */
63977
63978
63979  debugNodeInjectorPath(lView) {
63980    const path = [];
63981    let injectorIndex = getInjectorIndex(this, lView);
63982
63983    if (injectorIndex === -1) {
63984      // Looks like the current `TNode` does not have `NodeInjector` associated with it => look for
63985      // parent NodeInjector.
63986      const parentLocation = getParentInjectorLocation(this, lView);
63987
63988      if (parentLocation !== NO_PARENT_INJECTOR) {
63989        // We found a parent, so start searching from the parent location.
63990        injectorIndex = getParentInjectorIndex(parentLocation);
63991        lView = getParentInjectorView(parentLocation, lView);
63992      } else {// No parents have been found, so there are no `NodeInjector`s to consult.
63993      }
63994    }
63995
63996    while (injectorIndex !== -1) {
63997      ngDevMode && assertNodeInjector(lView, injectorIndex);
63998      const tNode = lView[TVIEW].data[injectorIndex + 8
63999      /* NodeInjectorOffset.TNODE */
64000      ];
64001      path.push(buildDebugNode(tNode, lView));
64002      const parentLocation = lView[injectorIndex + 8
64003      /* NodeInjectorOffset.PARENT */
64004      ];
64005
64006      if (parentLocation === NO_PARENT_INJECTOR) {
64007        injectorIndex = -1;
64008      } else {
64009        injectorIndex = getParentInjectorIndex(parentLocation);
64010        lView = getParentInjectorView(parentLocation, lView);
64011      }
64012    }
64013
64014    return path;
64015  }
64016
64017  get type_() {
64018    return toTNodeTypeAsString(this.type) || `TNodeType.?${this.type}?`;
64019  }
64020
64021  get flags_() {
64022    const flags = [];
64023    if (this.flags & 16
64024    /* TNodeFlags.hasClassInput */
64025    ) flags.push('TNodeFlags.hasClassInput');
64026    if (this.flags & 8
64027    /* TNodeFlags.hasContentQuery */
64028    ) flags.push('TNodeFlags.hasContentQuery');
64029    if (this.flags & 32
64030    /* TNodeFlags.hasStyleInput */
64031    ) flags.push('TNodeFlags.hasStyleInput');
64032    if (this.flags & 128
64033    /* TNodeFlags.hasHostBindings */
64034    ) flags.push('TNodeFlags.hasHostBindings');
64035    if (this.flags & 2
64036    /* TNodeFlags.isComponentHost */
64037    ) flags.push('TNodeFlags.isComponentHost');
64038    if (this.flags & 1
64039    /* TNodeFlags.isDirectiveHost */
64040    ) flags.push('TNodeFlags.isDirectiveHost');
64041    if (this.flags & 64
64042    /* TNodeFlags.isDetached */
64043    ) flags.push('TNodeFlags.isDetached');
64044    if (this.flags & 4
64045    /* TNodeFlags.isProjected */
64046    ) flags.push('TNodeFlags.isProjected');
64047    return flags.join('|');
64048  }
64049
64050  get template_() {
64051    if (this.type & 1
64052    /* TNodeType.Text */
64053    ) return this.value;
64054    const buf = [];
64055    const tagName = typeof this.value === 'string' && this.value || this.type_;
64056    buf.push('<', tagName);
64057
64058    if (this.flags) {
64059      buf.push(' ', this.flags_);
64060    }
64061
64062    if (this.attrs) {
64063      for (let i = 0; i < this.attrs.length;) {
64064        const attrName = this.attrs[i++];
64065
64066        if (typeof attrName == 'number') {
64067          break;
64068        }
64069
64070        const attrValue = this.attrs[i++];
64071        buf.push(' ', attrName, '="', attrValue, '"');
64072      }
64073    }
64074
64075    buf.push('>');
64076    processTNodeChildren(this.child, buf);
64077    buf.push('</', tagName, '>');
64078    return buf.join('');
64079  }
64080
64081  get styleBindings_() {
64082    return toDebugStyleBinding(this, false);
64083  }
64084
64085  get classBindings_() {
64086    return toDebugStyleBinding(this, true);
64087  }
64088
64089  get providerIndexStart_() {
64090    return this.providerIndexes & 1048575
64091    /* TNodeProviderIndexes.ProvidersStartIndexMask */
64092    ;
64093  }
64094
64095  get providerIndexEnd_() {
64096    return this.providerIndexStart_ + (this.providerIndexes >>> 20
64097    /* TNodeProviderIndexes.CptViewProvidersCountShift */
64098    );
64099  }
64100
64101}
64102
64103const TNodeDebug = TNode;
64104
64105function toDebugStyleBinding(tNode, isClassBased) {
64106  const tData = tNode.tView_.data;
64107  const bindings = [];
64108  const range = isClassBased ? tNode.classBindings : tNode.styleBindings;
64109  const prev = getTStylingRangePrev(range);
64110  const next = getTStylingRangeNext(range);
64111  let isTemplate = next !== 0;
64112  let cursor = isTemplate ? next : prev;
64113
64114  while (cursor !== 0) {
64115    const itemKey = tData[cursor];
64116    const itemRange = tData[cursor + 1];
64117    bindings.unshift({
64118      key: itemKey,
64119      index: cursor,
64120      isTemplate: isTemplate,
64121      prevDuplicate: getTStylingRangePrevDuplicate(itemRange),
64122      nextDuplicate: getTStylingRangeNextDuplicate(itemRange),
64123      nextIndex: getTStylingRangeNext(itemRange),
64124      prevIndex: getTStylingRangePrev(itemRange)
64125    });
64126    if (cursor === prev) isTemplate = false;
64127    cursor = getTStylingRangePrev(itemRange);
64128  }
64129
64130  bindings.push((isClassBased ? tNode.residualClasses : tNode.residualStyles) || null);
64131  return bindings;
64132}
64133
64134function processTNodeChildren(tNode, buf) {
64135  while (tNode) {
64136    buf.push(tNode.template_);
64137    tNode = tNode.next;
64138  }
64139}
64140
64141class TViewData extends Array {}
64142
64143let TVIEWDATA_EMPTY; // can't initialize here or it will not be tree shaken, because
64144// `LView` constructor could have side-effects.
64145
64146/**
64147 * This function clones a blueprint and creates TData.
64148 *
64149 * Simple slice will keep the same type, and we need it to be TData
64150 */
64151
64152function cloneToTViewData(list) {
64153  if (TVIEWDATA_EMPTY === undefined) TVIEWDATA_EMPTY = new TViewData();
64154  return TVIEWDATA_EMPTY.concat(list);
64155}
64156
64157class LViewBlueprint extends Array {}
64158
64159class MatchesArray extends Array {}
64160
64161class TViewComponents extends Array {}
64162
64163class TNodeLocalNames extends Array {}
64164
64165class TNodeInitialInputs extends Array {}
64166
64167class LCleanup extends Array {}
64168
64169class TCleanup extends Array {}
64170
64171function attachLViewDebug(lView) {
64172  attachDebugObject(lView, new LViewDebug(lView));
64173}
64174
64175function attachLContainerDebug(lContainer) {
64176  attachDebugObject(lContainer, new LContainerDebug(lContainer));
64177}
64178
64179function toDebug(obj) {
64180  if (obj) {
64181    const debug = obj.debug;
64182    assertDefined(debug, 'Object does not have a debug representation.');
64183    return debug;
64184  } else {
64185    return obj;
64186  }
64187}
64188/**
64189 * Use this method to unwrap a native element in `LView` and convert it into HTML for easier
64190 * reading.
64191 *
64192 * @param value possibly wrapped native DOM node.
64193 * @param includeChildren If `true` then the serialized HTML form will include child elements
64194 * (same
64195 * as `outerHTML`). If `false` then the serialized HTML form will only contain the element
64196 * itself
64197 * (will not serialize child elements).
64198 */
64199
64200
64201function toHtml(value, includeChildren = false) {
64202  const node = unwrapRNode(value);
64203
64204  if (node) {
64205    switch (node.nodeType) {
64206      case Node.TEXT_NODE:
64207        return node.textContent;
64208
64209      case Node.COMMENT_NODE:
64210        return `<!--${node.textContent}-->`;
64211
64212      case Node.ELEMENT_NODE:
64213        const outerHTML = node.outerHTML;
64214
64215        if (includeChildren) {
64216          return outerHTML;
64217        } else {
64218          const innerHTML = '>' + node.innerHTML + '<';
64219          return outerHTML.split(innerHTML)[0] + '>';
64220        }
64221
64222    }
64223  }
64224
64225  return null;
64226}
64227
64228class LViewDebug {
64229  constructor(_raw_lView) {
64230    this._raw_lView = _raw_lView;
64231  }
64232  /**
64233   * Flags associated with the `LView` unpacked into a more readable state.
64234   */
64235
64236
64237  get flags() {
64238    const flags = this._raw_lView[FLAGS];
64239    return {
64240      __raw__flags__: flags,
64241      initPhaseState: flags & 3
64242      /* LViewFlags.InitPhaseStateMask */
64243      ,
64244      creationMode: !!(flags & 4
64245      /* LViewFlags.CreationMode */
64246      ),
64247      firstViewPass: !!(flags & 8
64248      /* LViewFlags.FirstLViewPass */
64249      ),
64250      checkAlways: !!(flags & 16
64251      /* LViewFlags.CheckAlways */
64252      ),
64253      dirty: !!(flags & 32
64254      /* LViewFlags.Dirty */
64255      ),
64256      attached: !!(flags & 64
64257      /* LViewFlags.Attached */
64258      ),
64259      destroyed: !!(flags & 128
64260      /* LViewFlags.Destroyed */
64261      ),
64262      isRoot: !!(flags & 256
64263      /* LViewFlags.IsRoot */
64264      ),
64265      indexWithinInitPhase: flags >> 11
64266      /* LViewFlags.IndexWithinInitPhaseShift */
64267
64268    };
64269  }
64270
64271  get parent() {
64272    return toDebug(this._raw_lView[PARENT]);
64273  }
64274
64275  get hostHTML() {
64276    return toHtml(this._raw_lView[HOST], true);
64277  }
64278
64279  get html() {
64280    return (this.nodes || []).map(mapToHTML).join('');
64281  }
64282
64283  get context() {
64284    return this._raw_lView[CONTEXT];
64285  }
64286  /**
64287   * The tree of nodes associated with the current `LView`. The nodes have been normalized into
64288   * a tree structure with relevant details pulled out for readability.
64289   */
64290
64291
64292  get nodes() {
64293    const lView = this._raw_lView;
64294    const tNode = lView[TVIEW].firstChild;
64295    return toDebugNodes(tNode, lView);
64296  }
64297
64298  get template() {
64299    return this.tView.template_;
64300  }
64301
64302  get tView() {
64303    return this._raw_lView[TVIEW];
64304  }
64305
64306  get cleanup() {
64307    return this._raw_lView[CLEANUP];
64308  }
64309
64310  get injector() {
64311    return this._raw_lView[INJECTOR$1];
64312  }
64313
64314  get rendererFactory() {
64315    return this._raw_lView[RENDERER_FACTORY];
64316  }
64317
64318  get renderer() {
64319    return this._raw_lView[RENDERER];
64320  }
64321
64322  get sanitizer() {
64323    return this._raw_lView[SANITIZER];
64324  }
64325
64326  get childHead() {
64327    return toDebug(this._raw_lView[CHILD_HEAD]);
64328  }
64329
64330  get next() {
64331    return toDebug(this._raw_lView[NEXT]);
64332  }
64333
64334  get childTail() {
64335    return toDebug(this._raw_lView[CHILD_TAIL]);
64336  }
64337
64338  get declarationView() {
64339    return toDebug(this._raw_lView[DECLARATION_VIEW]);
64340  }
64341
64342  get queries() {
64343    return this._raw_lView[QUERIES];
64344  }
64345
64346  get tHost() {
64347    return this._raw_lView[T_HOST];
64348  }
64349
64350  get id() {
64351    return this._raw_lView[ID];
64352  }
64353
64354  get decls() {
64355    return toLViewRange(this.tView, this._raw_lView, HEADER_OFFSET, this.tView.bindingStartIndex);
64356  }
64357
64358  get vars() {
64359    return toLViewRange(this.tView, this._raw_lView, this.tView.bindingStartIndex, this.tView.expandoStartIndex);
64360  }
64361
64362  get expando() {
64363    return toLViewRange(this.tView, this._raw_lView, this.tView.expandoStartIndex, this._raw_lView.length);
64364  }
64365  /**
64366   * Normalized view of child views (and containers) attached at this location.
64367   */
64368
64369
64370  get childViews() {
64371    const childViews = [];
64372    let child = this.childHead;
64373
64374    while (child) {
64375      childViews.push(child);
64376      child = child.next;
64377    }
64378
64379    return childViews;
64380  }
64381
64382}
64383
64384function mapToHTML(node) {
64385  if (node.type === 'ElementContainer') {
64386    return (node.children || []).map(mapToHTML).join('');
64387  } else if (node.type === 'IcuContainer') {
64388    throw new Error('Not implemented');
64389  } else {
64390    return toHtml(node.native, true) || '';
64391  }
64392}
64393
64394function toLViewRange(tView, lView, start, end) {
64395  let content = [];
64396
64397  for (let index = start; index < end; index++) {
64398    content.push({
64399      index: index,
64400      t: tView.data[index],
64401      l: lView[index]
64402    });
64403  }
64404
64405  return {
64406    start: start,
64407    end: end,
64408    length: end - start,
64409    content: content
64410  };
64411}
64412/**
64413 * Turns a flat list of nodes into a tree by walking the associated `TNode` tree.
64414 *
64415 * @param tNode
64416 * @param lView
64417 */
64418
64419
64420function toDebugNodes(tNode, lView) {
64421  if (tNode) {
64422    const debugNodes = [];
64423    let tNodeCursor = tNode;
64424
64425    while (tNodeCursor) {
64426      debugNodes.push(buildDebugNode(tNodeCursor, lView));
64427      tNodeCursor = tNodeCursor.next;
64428    }
64429
64430    return debugNodes;
64431  } else {
64432    return [];
64433  }
64434}
64435
64436function buildDebugNode(tNode, lView) {
64437  const rawValue = lView[tNode.index];
64438  const native = unwrapRNode(rawValue);
64439  const factories = [];
64440  const instances = [];
64441  const tView = lView[TVIEW];
64442
64443  for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
64444    const def = tView.data[i];
64445    factories.push(def.type);
64446    instances.push(lView[i]);
64447  }
64448
64449  return {
64450    html: toHtml(native),
64451    type: toTNodeTypeAsString(tNode.type),
64452    tNode,
64453    native: native,
64454    children: toDebugNodes(tNode.child, lView),
64455    factories,
64456    instances,
64457    injector: buildNodeInjectorDebug(tNode, tView, lView),
64458
64459    get injectorResolutionPath() {
64460      return tNode.debugNodeInjectorPath(lView);
64461    }
64462
64463  };
64464}
64465
64466function buildNodeInjectorDebug(tNode, tView, lView) {
64467  const viewProviders = [];
64468
64469  for (let i = tNode.providerIndexStart_; i < tNode.providerIndexEnd_; i++) {
64470    viewProviders.push(tView.data[i]);
64471  }
64472
64473  const providers = [];
64474
64475  for (let i = tNode.providerIndexEnd_; i < tNode.directiveEnd; i++) {
64476    providers.push(tView.data[i]);
64477  }
64478
64479  const nodeInjectorDebug = {
64480    bloom: toBloom(lView, tNode.injectorIndex),
64481    cumulativeBloom: toBloom(tView.data, tNode.injectorIndex),
64482    providers,
64483    viewProviders,
64484    parentInjectorIndex: lView[tNode.providerIndexStart_ - 1]
64485  };
64486  return nodeInjectorDebug;
64487}
64488/**
64489 * Convert a number at `idx` location in `array` into binary representation.
64490 *
64491 * @param array
64492 * @param idx
64493 */
64494
64495
64496function binary(array, idx) {
64497  const value = array[idx]; // If not a number we print 8 `?` to retain alignment but let user know that it was called on
64498  // wrong type.
64499
64500  if (typeof value !== 'number') return '????????'; // We prefix 0s so that we have constant length number
64501
64502  const text = '00000000' + value.toString(2);
64503  return text.substring(text.length - 8);
64504}
64505/**
64506 * Convert a bloom filter at location `idx` in `array` into binary representation.
64507 *
64508 * @param array
64509 * @param idx
64510 */
64511
64512
64513function toBloom(array, idx) {
64514  if (idx < 0) {
64515    return 'NO_NODE_INJECTOR';
64516  }
64517
64518  return `${binary(array, idx + 7)}_${binary(array, idx + 6)}_${binary(array, idx + 5)}_${binary(array, idx + 4)}_${binary(array, idx + 3)}_${binary(array, idx + 2)}_${binary(array, idx + 1)}_${binary(array, idx + 0)}`;
64519}
64520
64521class LContainerDebug {
64522  constructor(_raw_lContainer) {
64523    this._raw_lContainer = _raw_lContainer;
64524  }
64525
64526  get hasTransplantedViews() {
64527    return this._raw_lContainer[HAS_TRANSPLANTED_VIEWS];
64528  }
64529
64530  get views() {
64531    return this._raw_lContainer.slice(CONTAINER_HEADER_OFFSET).map(toDebug);
64532  }
64533
64534  get parent() {
64535    return toDebug(this._raw_lContainer[PARENT]);
64536  }
64537
64538  get movedViews() {
64539    return this._raw_lContainer[MOVED_VIEWS];
64540  }
64541
64542  get host() {
64543    return this._raw_lContainer[HOST];
64544  }
64545
64546  get native() {
64547    return this._raw_lContainer[NATIVE];
64548  }
64549
64550  get next() {
64551    return toDebug(this._raw_lContainer[NEXT]);
64552  }
64553
64554}
64555/**
64556 * @license
64557 * Copyright Google LLC All Rights Reserved.
64558 *
64559 * Use of this source code is governed by an MIT-style license that can be
64560 * found in the LICENSE file at https://angular.io/license
64561 */
64562
64563/**
64564 * Invoke `HostBindingsFunction`s for view.
64565 *
64566 * This methods executes `TView.hostBindingOpCodes`. It is used to execute the
64567 * `HostBindingsFunction`s associated with the current `LView`.
64568 *
64569 * @param tView Current `TView`.
64570 * @param lView Current `LView`.
64571 */
64572
64573
64574function processHostBindingOpCodes(tView, lView) {
64575  const hostBindingOpCodes = tView.hostBindingOpCodes;
64576  if (hostBindingOpCodes === null) return;
64577
64578  try {
64579    for (let i = 0; i < hostBindingOpCodes.length; i++) {
64580      const opCode = hostBindingOpCodes[i];
64581
64582      if (opCode < 0) {
64583        // Negative numbers are element indexes.
64584        setSelectedIndex(~opCode);
64585      } else {
64586        // Positive numbers are NumberTuple which store bindingRootIndex and directiveIndex.
64587        const directiveIdx = opCode;
64588        const bindingRootIndx = hostBindingOpCodes[++i];
64589        const hostBindingFn = hostBindingOpCodes[++i];
64590        setBindingRootForHostBindings(bindingRootIndx, directiveIdx);
64591        const context = lView[directiveIdx];
64592        hostBindingFn(2
64593        /* RenderFlags.Update */
64594        , context);
64595      }
64596    }
64597  } finally {
64598    setSelectedIndex(-1);
64599  }
64600}
64601/** Refreshes all content queries declared by directives in a given view */
64602
64603
64604function refreshContentQueries(tView, lView) {
64605  const contentQueries = tView.contentQueries;
64606
64607  if (contentQueries !== null) {
64608    for (let i = 0; i < contentQueries.length; i += 2) {
64609      const queryStartIdx = contentQueries[i];
64610      const directiveDefIdx = contentQueries[i + 1];
64611
64612      if (directiveDefIdx !== -1) {
64613        const directiveDef = tView.data[directiveDefIdx];
64614        ngDevMode && assertDefined(directiveDef, 'DirectiveDef not found.');
64615        ngDevMode && assertDefined(directiveDef.contentQueries, 'contentQueries function should be defined');
64616        setCurrentQueryIndex(queryStartIdx);
64617        directiveDef.contentQueries(2
64618        /* RenderFlags.Update */
64619        , lView[directiveDefIdx], directiveDefIdx);
64620      }
64621    }
64622  }
64623}
64624/** Refreshes child components in the current view (update mode). */
64625
64626
64627function refreshChildComponents(hostLView, components) {
64628  for (let i = 0; i < components.length; i++) {
64629    refreshComponent(hostLView, components[i]);
64630  }
64631}
64632/** Renders child components in the current view (creation mode). */
64633
64634
64635function renderChildComponents(hostLView, components) {
64636  for (let i = 0; i < components.length; i++) {
64637    renderComponent(hostLView, components[i]);
64638  }
64639}
64640
64641function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector, embeddedViewInjector) {
64642  const lView = ngDevMode ? cloneToLViewFromTViewBlueprint(tView) : tView.blueprint.slice();
64643  lView[HOST] = host;
64644  lView[FLAGS] = flags | 4
64645  /* LViewFlags.CreationMode */
64646  | 64
64647  /* LViewFlags.Attached */
64648  | 8
64649  /* LViewFlags.FirstLViewPass */
64650  ;
64651
64652  if (embeddedViewInjector !== null || parentLView && parentLView[FLAGS] & 1024
64653  /* LViewFlags.HasEmbeddedViewInjector */
64654  ) {
64655    lView[FLAGS] |= 1024
64656    /* LViewFlags.HasEmbeddedViewInjector */
64657    ;
64658  }
64659
64660  resetPreOrderHookFlags(lView);
64661  ngDevMode && tView.declTNode && parentLView && assertTNodeForLView(tView.declTNode, parentLView);
64662  lView[PARENT] = lView[DECLARATION_VIEW] = parentLView;
64663  lView[CONTEXT] = context;
64664  lView[RENDERER_FACTORY] = rendererFactory || parentLView && parentLView[RENDERER_FACTORY];
64665  ngDevMode && assertDefined(lView[RENDERER_FACTORY], 'RendererFactory is required');
64666  lView[RENDERER] = renderer || parentLView && parentLView[RENDERER];
64667  ngDevMode && assertDefined(lView[RENDERER], 'Renderer is required');
vendor: 18,305 bytes, lines 64668-65183
64668  lView[SANITIZER] = sanitizer || parentLView && parentLView[SANITIZER] || null;
64669  lView[INJECTOR$1] = injector || parentLView && parentLView[INJECTOR$1] || null;
64670  lView[T_HOST] = tHostNode;
64671  lView[ID] = getUniqueLViewId();
64672  lView[EMBEDDED_VIEW_INJECTOR] = embeddedViewInjector;
64673  ngDevMode && assertEqual(tView.type == 2
64674  /* TViewType.Embedded */
64675  ? parentLView !== null : true, true, 'Embedded views must have parentLView');
64676  lView[DECLARATION_COMPONENT_VIEW] = tView.type == 2
64677  /* TViewType.Embedded */
64678  ? parentLView[DECLARATION_COMPONENT_VIEW] : lView;
64679  ngDevMode && attachLViewDebug(lView);
64680  return lView;
64681}
64682
64683function getOrCreateTNode(tView, index, type, name, attrs) {
64684  ngDevMode && index !== 0 && // 0 are bogus nodes and they are OK. See `createContainerRef` in
64685  // `view_engine_compatibility` for additional context.
64686  assertGreaterThanOrEqual(index, HEADER_OFFSET, 'TNodes can\'t be in the LView header.'); // Keep this function short, so that the VM will inline it.
64687
64688  ngDevMode && assertPureTNodeType(type);
64689  let tNode = tView.data[index];
64690
64691  if (tNode === null) {
64692    tNode = createTNodeAtIndex(tView, index, type, name, attrs);
64693
64694    if (isInI18nBlock()) {
64695      // If we are in i18n block then all elements should be pre declared through `Placeholder`
64696      // See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
64697      // If the `TNode` was not pre-declared than it means it was not mentioned which means it was
64698      // removed, so we mark it as detached.
64699      tNode.flags |= 64
64700      /* TNodeFlags.isDetached */
64701      ;
64702    }
64703  } else if (tNode.type & 64
64704  /* TNodeType.Placeholder */
64705  ) {
64706    tNode.type = type;
64707    tNode.value = name;
64708    tNode.attrs = attrs;
64709    const parent = getCurrentParentTNode();
64710    tNode.injectorIndex = parent === null ? -1 : parent.injectorIndex;
64711    ngDevMode && assertTNodeForTView(tNode, tView);
64712    ngDevMode && assertEqual(index, tNode.index, 'Expecting same index');
64713  }
64714
64715  setCurrentTNode(tNode, true);
64716  return tNode;
64717}
64718
64719function createTNodeAtIndex(tView, index, type, name, attrs) {
64720  const currentTNode = getCurrentTNodePlaceholderOk();
64721  const isParent = isCurrentTNodeParent();
64722  const parent = isParent ? currentTNode : currentTNode && currentTNode.parent; // Parents cannot cross component boundaries because components will be used in multiple places.
64723
64724  const tNode = tView.data[index] = createTNode(tView, parent, type, index, name, attrs); // Assign a pointer to the first child node of a given view. The first node is not always the one
64725  // at index 0, in case of i18n, index 0 can be the instruction `i18nStart` and the first node has
64726  // the index 1 or more, so we can't just check node index.
64727
64728  if (tView.firstChild === null) {
64729    tView.firstChild = tNode;
64730  }
64731
64732  if (currentTNode !== null) {
64733    if (isParent) {
64734      // FIXME(misko): This logic looks unnecessarily complicated. Could we simplify?
64735      if (currentTNode.child == null && tNode.parent !== null) {
64736        // We are in the same view, which means we are adding content node to the parent view.
64737        currentTNode.child = tNode;
64738      }
64739    } else {
64740      if (currentTNode.next === null) {
64741        // In the case of i18n the `currentTNode` may already be linked, in which case we don't want
64742        // to break the links which i18n created.
64743        currentTNode.next = tNode;
64744      }
64745    }
64746  }
64747
64748  return tNode;
64749}
64750/**
64751 * When elements are created dynamically after a view blueprint is created (e.g. through
64752 * i18nApply()), we need to adjust the blueprint for future
64753 * template passes.
64754 *
64755 * @param tView `TView` associated with `LView`
64756 * @param lView The `LView` containing the blueprint to adjust
64757 * @param numSlotsToAlloc The number of slots to alloc in the LView, should be >0
64758 * @param initialValue Initial value to store in blueprint
64759 */
64760
64761
64762function allocExpando(tView, lView, numSlotsToAlloc, initialValue) {
64763  if (numSlotsToAlloc === 0) return -1;
64764
64765  if (ngDevMode) {
64766    assertFirstCreatePass(tView);
64767    assertSame(tView, lView[TVIEW], '`LView` must be associated with `TView`!');
64768    assertEqual(tView.data.length, lView.length, 'Expecting LView to be same size as TView');
64769    assertEqual(tView.data.length, tView.blueprint.length, 'Expecting Blueprint to be same size as TView');
64770    assertFirstUpdatePass(tView);
64771  }
64772
64773  const allocIdx = lView.length;
64774
64775  for (let i = 0; i < numSlotsToAlloc; i++) {
64776    lView.push(initialValue);
64777    tView.blueprint.push(initialValue);
64778    tView.data.push(null);
64779  }
64780
64781  return allocIdx;
64782} //////////////////////////
64783//// Render
64784//////////////////////////
64785
64786/**
64787 * Processes a view in the creation mode. This includes a number of steps in a specific order:
64788 * - creating view query functions (if any);
64789 * - executing a template function in the creation mode;
64790 * - updating static queries (if any);
64791 * - creating child components defined in a given view.
64792 */
64793
64794
64795function renderView(tView, lView, context) {
64796  ngDevMode && assertEqual(isCreationMode(lView), true, 'Should be run in creation mode');
64797  enterView(lView);
64798
64799  try {
64800    const viewQuery = tView.viewQuery;
64801
64802    if (viewQuery !== null) {
64803      executeViewQueryFn(1
64804      /* RenderFlags.Create */
64805      , viewQuery, context);
64806    } // Execute a template associated with this view, if it exists. A template function might not be
64807    // defined for the root component views.
64808
64809
64810    const templateFn = tView.template;
64811
64812    if (templateFn !== null) {
64813      executeTemplate(tView, lView, templateFn, 1
64814      /* RenderFlags.Create */
64815      , context);
64816    } // This needs to be set before children are processed to support recursive components.
64817    // This must be set to false immediately after the first creation run because in an
64818    // ngFor loop, all the views will be created together before update mode runs and turns
64819    // off firstCreatePass. If we don't set it here, instances will perform directive
64820    // matching, etc again and again.
64821
64822
64823    if (tView.firstCreatePass) {
64824      tView.firstCreatePass = false;
64825    } // We resolve content queries specifically marked as `static` in creation mode. Dynamic
64826    // content queries are resolved during change detection (i.e. update mode), after embedded
64827    // views are refreshed (see block above).
64828
64829
64830    if (tView.staticContentQueries) {
64831      refreshContentQueries(tView, lView);
64832    } // We must materialize query results before child components are processed
64833    // in case a child component has projected a container. The LContainer needs
64834    // to exist so the embedded views are properly attached by the container.
64835
64836
64837    if (tView.staticViewQueries) {
64838      executeViewQueryFn(2
64839      /* RenderFlags.Update */
64840      , tView.viewQuery, context);
64841    } // Render child component views.
64842
64843
64844    const components = tView.components;
64845
64846    if (components !== null) {
64847      renderChildComponents(lView, components);
64848    }
64849  } catch (error) {
64850    // If we didn't manage to get past the first template pass due to
64851    // an error, mark the view as corrupted so we can try to recover.
64852    if (tView.firstCreatePass) {
64853      tView.incompleteFirstPass = true;
64854      tView.firstCreatePass = false;
64855    }
64856
64857    throw error;
64858  } finally {
64859    lView[FLAGS] &= ~4
64860    /* LViewFlags.CreationMode */
64861    ;
64862    leaveView();
64863  }
64864}
64865/**
64866 * Processes a view in update mode. This includes a number of steps in a specific order:
64867 * - executing a template function in update mode;
64868 * - executing hooks;
64869 * - refreshing queries;
64870 * - setting host bindings;
64871 * - refreshing child (embedded and component) views.
64872 */
64873
64874
64875function refreshView(tView, lView, templateFn, context) {
64876  ngDevMode && assertEqual(isCreationMode(lView), false, 'Should be run in update mode');
64877  const flags = lView[FLAGS];
64878  if ((flags & 128
64879  /* LViewFlags.Destroyed */
64880  ) === 128
64881  /* LViewFlags.Destroyed */
64882  ) return;
64883  enterView(lView); // Check no changes mode is a dev only mode used to verify that bindings have not changed
64884  // since they were assigned. We do not want to execute lifecycle hooks in that mode.
64885
64886  const isInCheckNoChangesPass = ngDevMode && isInCheckNoChangesMode();
64887
64888  try {
64889    resetPreOrderHookFlags(lView);
64890    setBindingIndex(tView.bindingStartIndex);
64891
64892    if (templateFn !== null) {
64893      executeTemplate(tView, lView, templateFn, 2
64894      /* RenderFlags.Update */
64895      , context);
64896    }
64897
64898    const hooksInitPhaseCompleted = (flags & 3
64899    /* LViewFlags.InitPhaseStateMask */
64900    ) === 3
64901    /* InitPhaseState.InitPhaseCompleted */
64902    ; // execute pre-order hooks (OnInit, OnChanges, DoCheck)
64903    // PERF WARNING: do NOT extract this to a separate function without running benchmarks
64904
64905    if (!isInCheckNoChangesPass) {
64906      if (hooksInitPhaseCompleted) {
64907        const preOrderCheckHooks = tView.preOrderCheckHooks;
64908
64909        if (preOrderCheckHooks !== null) {
64910          executeCheckHooks(lView, preOrderCheckHooks, null);
64911        }
64912      } else {
64913        const preOrderHooks = tView.preOrderHooks;
64914
64915        if (preOrderHooks !== null) {
64916          executeInitAndCheckHooks(lView, preOrderHooks, 0
64917          /* InitPhaseState.OnInitHooksToBeRun */
64918          , null);
64919        }
64920
64921        incrementInitPhaseFlags(lView, 0
64922        /* InitPhaseState.OnInitHooksToBeRun */
64923        );
64924      }
64925    } // First mark transplanted views that are declared in this lView as needing a refresh at their
64926    // insertion points. This is needed to avoid the situation where the template is defined in this
64927    // `LView` but its declaration appears after the insertion component.
64928
64929
64930    markTransplantedViewsForRefresh(lView);
64931    refreshEmbeddedViews(lView); // Content query results must be refreshed before content hooks are called.
64932
64933    if (tView.contentQueries !== null) {
64934      refreshContentQueries(tView, lView);
64935    } // execute content hooks (AfterContentInit, AfterContentChecked)
64936    // PERF WARNING: do NOT extract this to a separate function without running benchmarks
64937
64938
64939    if (!isInCheckNoChangesPass) {
64940      if (hooksInitPhaseCompleted) {
64941        const contentCheckHooks = tView.contentCheckHooks;
64942
64943        if (contentCheckHooks !== null) {
64944          executeCheckHooks(lView, contentCheckHooks);
64945        }
64946      } else {
64947        const contentHooks = tView.contentHooks;
64948
64949        if (contentHooks !== null) {
64950          executeInitAndCheckHooks(lView, contentHooks, 1
64951          /* InitPhaseState.AfterContentInitHooksToBeRun */
64952          );
64953        }
64954
64955        incrementInitPhaseFlags(lView, 1
64956        /* InitPhaseState.AfterContentInitHooksToBeRun */
64957        );
64958      }
64959    }
64960
64961    processHostBindingOpCodes(tView, lView); // Refresh child component views.
64962
64963    const components = tView.components;
64964
64965    if (components !== null) {
64966      refreshChildComponents(lView, components);
64967    } // View queries must execute after refreshing child components because a template in this view
64968    // could be inserted in a child component. If the view query executes before child component
64969    // refresh, the template might not yet be inserted.
64970
64971
64972    const viewQuery = tView.viewQuery;
64973
64974    if (viewQuery !== null) {
64975      executeViewQueryFn(2
64976      /* RenderFlags.Update */
64977      , viewQuery, context);
64978    } // execute view hooks (AfterViewInit, AfterViewChecked)
64979    // PERF WARNING: do NOT extract this to a separate function without running benchmarks
64980
64981
64982    if (!isInCheckNoChangesPass) {
64983      if (hooksInitPhaseCompleted) {
64984        const viewCheckHooks = tView.viewCheckHooks;
64985
64986        if (viewCheckHooks !== null) {
64987          executeCheckHooks(lView, viewCheckHooks);
64988        }
64989      } else {
64990        const viewHooks = tView.viewHooks;
64991
64992        if (viewHooks !== null) {
64993          executeInitAndCheckHooks(lView, viewHooks, 2
64994          /* InitPhaseState.AfterViewInitHooksToBeRun */
64995          );
64996        }
64997
64998        incrementInitPhaseFlags(lView, 2
64999        /* InitPhaseState.AfterViewInitHooksToBeRun */
65000        );
65001      }
65002    }
65003
65004    if (tView.firstUpdatePass === true) {
65005      // We need to make sure that we only flip the flag on successful `refreshView` only
65006      // Don't do this in `finally` block.
65007      // If we did this in `finally` block then an exception could block the execution of styling
65008      // instructions which in turn would be unable to insert themselves into the styling linked
65009      // list. The result of this would be that if the exception would not be throw on subsequent CD
65010      // the styling would be unable to process it data and reflect to the DOM.
65011      tView.firstUpdatePass = false;
65012    } // Do not reset the dirty state when running in check no changes mode. We don't want components
65013    // to behave differently depending on whether check no changes is enabled or not. For example:
65014    // Marking an OnPush component as dirty from within the `ngAfterViewInit` hook in order to
65015    // refresh a `NgClass` binding should work. If we would reset the dirty state in the check
65016    // no changes cycle, the component would be not be dirty for the next update pass. This would
65017    // be different in production mode where the component dirty state is not reset.
65018
65019
65020    if (!isInCheckNoChangesPass) {
65021      lView[FLAGS] &= ~(32
65022      /* LViewFlags.Dirty */
65023      | 8
65024      /* LViewFlags.FirstLViewPass */
65025      );
65026    }
65027
65028    if (lView[FLAGS] & 512
65029    /* LViewFlags.RefreshTransplantedView */
65030    ) {
65031      lView[FLAGS] &= ~512
65032      /* LViewFlags.RefreshTransplantedView */
65033      ;
65034      updateTransplantedViewCount(lView[PARENT], -1);
65035    }
65036  } finally {
65037    leaveView();
65038  }
65039}
65040
65041function executeTemplate(tView, lView, templateFn, rf, context) {
65042  const prevSelectedIndex = getSelectedIndex();
65043  const isUpdatePhase = rf & 2
65044  /* RenderFlags.Update */
65045  ;
65046
65047  try {
65048    setSelectedIndex(-1);
65049
65050    if (isUpdatePhase && lView.length > HEADER_OFFSET) {
65051      // When we're updating, inherently select 0 so we don't
65052      // have to generate that instruction for most update blocks.
65053      selectIndexInternal(tView, lView, HEADER_OFFSET, !!ngDevMode && isInCheckNoChangesMode());
65054    }
65055
65056    const preHookType = isUpdatePhase ? 2
65057    /* ProfilerEvent.TemplateUpdateStart */
65058    : 0
65059    /* ProfilerEvent.TemplateCreateStart */
65060    ;
65061    profiler(preHookType, context);
65062    templateFn(rf, context);
65063  } finally {
65064    setSelectedIndex(prevSelectedIndex);
65065    const postHookType = isUpdatePhase ? 3
65066    /* ProfilerEvent.TemplateUpdateEnd */
65067    : 1
65068    /* ProfilerEvent.TemplateCreateEnd */
65069    ;
65070    profiler(postHookType, context);
65071  }
65072} //////////////////////////
65073//// Element
65074//////////////////////////
65075
65076
65077function executeContentQueries(tView, tNode, lView) {
65078  if (isContentQueryHost(tNode)) {
65079    const start = tNode.directiveStart;
65080    const end = tNode.directiveEnd;
65081
65082    for (let directiveIndex = start; directiveIndex < end; directiveIndex++) {
65083      const def = tView.data[directiveIndex];
65084
65085      if (def.contentQueries) {
65086        def.contentQueries(1
65087        /* RenderFlags.Create */
65088        , lView[directiveIndex], directiveIndex);
65089      }
65090    }
65091  }
65092}
65093/**
65094 * Creates directive instances.
65095 */
65096
65097
65098function createDirectivesInstances(tView, lView, tNode) {
65099  if (!getBindingsEnabled()) return;
65100  instantiateAllDirectives(tView, lView, tNode, getNativeByTNode(tNode, lView));
65101
65102  if ((tNode.flags & 128
65103  /* TNodeFlags.hasHostBindings */
65104  ) === 128
65105  /* TNodeFlags.hasHostBindings */
65106  ) {
65107    invokeDirectivesHostBindings(tView, lView, tNode);
65108  }
65109}
65110/**
65111 * Takes a list of local names and indices and pushes the resolved local variable values
65112 * to LView in the same order as they are loaded in the template with load().
65113 */
65114
65115
65116function saveResolvedLocalsInData(viewData, tNode, localRefExtractor = getNativeByTNode) {
65117  const localNames = tNode.localNames;
65118
65119  if (localNames !== null) {
65120    let localIndex = tNode.index + 1;
65121
65122    for (let i = 0; i < localNames.length; i += 2) {
65123      const index = localNames[i + 1];
65124      const value = index === -1 ? localRefExtractor(tNode, viewData) : viewData[index];
65125      viewData[localIndex++] = value;
65126    }
65127  }
65128}
65129/**
65130 * Gets TView from a template function or creates a new TView
65131 * if it doesn't already exist.
65132 *
65133 * @param def ComponentDef
65134 * @returns TView
65135 */
65136
65137
65138function getOrCreateComponentTView(def) {
65139  const tView = def.tView; // Create a TView if there isn't one, or recreate it if the first create pass didn't
65140  // complete successfully since we can't know for sure whether it's in a usable shape.
65141
65142  if (tView === null || tView.incompleteFirstPass) {
65143    // Declaration node here is null since this function is called when we dynamically create a
65144    // component and hence there is no declaration.
65145    const declTNode = null;
65146    return def.tView = createTView(1
65147    /* TViewType.Component */
65148    , declTNode, def.template, def.decls, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery, def.schemas, def.consts);
65149  }
65150
65151  return tView;
65152}
65153/**
65154 * Creates a TView instance
65155 *
65156 * @param type Type of `TView`.
65157 * @param declTNode Declaration location of this `TView`.
65158 * @param templateFn Template function
65159 * @param decls The number of nodes, local refs, and pipes in this template
65160 * @param directives Registry of directives for this view
65161 * @param pipes Registry of pipes for this view
65162 * @param viewQuery View queries for this view
65163 * @param schemas Schemas for this view
65164 * @param consts Constants for this view
65165 */
65166
65167
65168function createTView(type, declTNode, templateFn, decls, vars, directives, pipes, viewQuery, schemas, constsOrFactory) {
65169  ngDevMode && ngDevMode.tView++;
65170  const bindingStartIndex = HEADER_OFFSET + decls; // This length does not yet contain host bindings from child directives because at this point,
65171  // we don't know which directives are active on this template. As soon as a directive is matched
65172  // that has a host binding, we will update the blueprint with that def's hostVars count.
65173
65174  const initialViewLength = bindingStartIndex + vars;
65175  const blueprint = createViewBlueprint(bindingStartIndex, initialViewLength);
65176  const consts = typeof constsOrFactory === 'function' ? constsOrFactory() : constsOrFactory;
65177  const tView = blueprint[TVIEW] = ngDevMode ? new TViewConstructor(type, // type: TViewType,
65178  blueprint, // blueprint: LView,
65179  templateFn, // template: ComponentTemplate<{}>|null,
65180  null, // queries: TQueries|null
65181  viewQuery, // viewQuery: ViewQueriesFunction<{}>|null,
65182  declTNode, // declTNode: TNode|null,
65183  cloneToTViewData(blueprint).fill(null, bindingStartIndex), // data: TData,
65184  bindingStartIndex, // bindingStartIndex: number,
65185  initialViewLength, // expandoStartIndex: number,
65186  null, // hostBindingOpCodes: HostBindingOpCodes,
65187  true, // firstCreatePass: boolean,
65188  true, // firstUpdatePass: boolean,
65189  false, // staticViewQueries: boolean,
65190  false, // staticContentQueries: boolean,
65191  null, // preOrderHooks: HookData|null,
65192  null, // preOrderCheckHooks: HookData|null,
65193  null, // contentHooks: HookData|null,
65194  null, // contentCheckHooks: HookData|null,
65195  null, // viewHooks: HookData|null,
65196  null, // viewCheckHooks: HookData|null,
65197  null, // destroyHooks: DestroyHookData|null,
65198  null, // cleanup: any[]|null,
65199  null, // contentQueries: number[]|null,
65200  null, // components: number[]|null,
65201  typeof directives === 'function' ? //
65202  directives() : //
65203  directives, // directiveRegistry: DirectiveDefList|null,
65204  typeof pipes === 'function' ? pipes() : pipes, // pipeRegistry: PipeDefList|null,
65205  null, // firstChild: TNode|null,
65206  schemas, // schemas: SchemaMetadata[]|null,
65207  consts, // consts: TConstants|null
65208  false, // incompleteFirstPass: boolean
65209  decls, // ngDevMode only: decls
65210  vars) : {
65211    type: type,
65212    blueprint: blueprint,
65213    template: templateFn,
65214    queries: null,
65215    viewQuery: viewQuery,
65216    declTNode: declTNode,
65217    data: blueprint.slice().fill(null, bindingStartIndex),
65218    bindingStartIndex: bindingStartIndex,
65219    expandoStartIndex: initialViewLength,
65220    hostBindingOpCodes: null,
65221    firstCreatePass: true,
65222    firstUpdatePass: true,
65223    staticViewQueries: false,
65224    staticContentQueries: false,
65225    preOrderHooks: null,
65226    preOrderCheckHooks: null,
65227    contentHooks: null,
65228    contentCheckHooks: null,
65229    viewHooks: null,
65230    viewCheckHooks: null,
65231    destroyHooks: null,
65232    cleanup: null,
65233    contentQueries: null,
65234    components: null,
65235    directiveRegistry: typeof directives === 'function' ? directives() : directives,
65236    pipeRegistry: typeof pipes === 'function' ? pipes() : pipes,
65237    firstChild: null,
65238    schemas: schemas,
65239    consts: consts,
65240    incompleteFirstPass: false
65241  };
65242
65243  if (ngDevMode) {
65244    // For performance reasons it is important that the tView retains the same shape during runtime.
65245    // (To make sure that all of the code is monomorphic.) For this reason we seal the object to
65246    // prevent class transitions.
65247    Object.seal(tView);
65248  }
65249
65250  return tView;
65251}
65252
65253function createViewBlueprint(bindingStartIndex, initialViewLength) {
65254  const blueprint = ngDevMode ? new LViewBlueprint() : [];
65255
65256  for (let i = 0; i < initialViewLength; i++) {
65257    blueprint.push(i < bindingStartIndex ? null : NO_CHANGE);
65258  }
65259
65260  return blueprint;
65261}
65262
65263function createError(text, token) {
65264  return new Error(`Renderer: ${text} [${stringifyForError(token)}]`);
65265}
65266/**
65267 * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
65268 *
65269 * @param rendererFactory Factory function to create renderer instance.
65270 * @param elementOrSelector Render element or CSS selector to locate the element.
65271 * @param encapsulation View Encapsulation defined for component that requests host element.
65272 */
65273
65274
65275function locateHostElement(renderer, elementOrSelector, encapsulation) {
65276  // When using native Shadow DOM, do not clear host element to allow native slot projection
65277  const preserveContent = encapsulation === ViewEncapsulation$1.ShadowDom;
65278  return renderer.selectRootElement(elementOrSelector, preserveContent);
65279}
65280/**
65281 * Saves context for this cleanup function in LView.cleanupInstances.
65282 *
65283 * On the first template pass, saves in TView:
65284 * - Cleanup function
65285 * - Index of context we just saved in LView.cleanupInstances
65286 *
65287 * This function can also be used to store instance specific cleanup fns. In that case the `context`
65288 * is `null` and the function is store in `LView` (rather than it `TView`).
65289 */
65290
65291
65292function storeCleanupWithContext(tView, lView, context, cleanupFn) {
65293  const lCleanup = getOrCreateLViewCleanup(lView);
65294
65295  if (context === null) {
65296    // If context is null that this is instance specific callback. These callbacks can only be
65297    // inserted after template shared instances. For this reason in ngDevMode we freeze the TView.
65298    if (ngDevMode) {
65299      Object.freeze(getOrCreateTViewCleanup(tView));
65300    }
65301
65302    lCleanup.push(cleanupFn);
65303  } else {
65304    lCleanup.push(context);
65305
65306    if (tView.firstCreatePass) {
65307      getOrCreateTViewCleanup(tView).push(cleanupFn, lCleanup.length - 1);
65308    }
65309  }
65310}
65311
65312function createTNode(tView, tParent, type, index, value, attrs) {
65313  ngDevMode && index !== 0 && // 0 are bogus nodes and they are OK. See `createContainerRef` in
65314  // `view_engine_compatibility` for additional context.
65315  assertGreaterThanOrEqual(index, HEADER_OFFSET, 'TNodes can\'t be in the LView header.');
65316  ngDevMode && assertNotSame(attrs, undefined, '\'undefined\' is not val
65316id value for \'attrs\'');
65317  ngDevMode && ngDevMode.tNode++;
65318  ngDevMode && tParent && assertTNodeForTView(tParent, tView);
65319  let injectorIndex = tParent ? tParent.injectorIndex : -1;
65320  const tNode = ngDevMode ? new TNodeDebug(tView, // tView_: TView
65321  type, // type: TNodeType
65322  index, // index: number
65323  null, // insertBeforeIndex: null|-1|number|number[]
65324  injectorIndex, // injectorIndex: number
65325  -1, // directiveStart: number
65326  -1, // directiveEnd: number
65327  -1, // directiveStylingLast: number
65328  null, // propertyBindings: number[]|null
65329  0, // flags: TNodeFlags
65330  0, // providerIndexes: TNodeProviderIndexes
65331  value, // value: string|null
65332  attrs, // attrs: (string|AttributeMarker|(string|SelectorFlags)[])[]|null
65333  null, // mergedAttrs
65334  null, // localNames: (string|number)[]|null
65335  undefined, // initialInputs: (string[]|null)[]|null|undefined
65336  null, // inputs: PropertyAliases|null
65337  null, // outputs: PropertyAliases|null
65338  null, // tViews: ITView|ITView[]|null
65339  null, // next: ITNode|null
65340  null, // projectionNext: ITNode|null
65341  null, // child: ITNode|null
65342  tParent, // parent: TElementNode|TContainerNode|null
65343  null, // projection: number|(ITNode|RNode[])[]|null
65344  null, // styles: string|null
65345  null, // stylesWithoutHost: string|null
65346  undefined, // residualStyles: string|null
65347  null, // classes: string|null
65348  null, // classesWithoutHost: string|null
65349  undefined, // residualClasses: string|null
65350  0, // classBindings: TStylingRange;
65351  0) : {
65352    type,
65353    index,
65354    insertBeforeIndex: null,
65355    injectorIndex,
65356    directiveStart: -1,
65357    directiveEnd: -1,
65358    directiveStylingLast: -1,
65359    propertyBindings: null,
65360    flags: 0,
65361    providerIndexes: 0,
65362    value: value,
65363    attrs: attrs,
65364    mergedAttrs: null,
65365    localNames: null,
65366    initialInputs: undefined,
65367    inputs: null,
65368    outputs: null,
65369    tViews: null,
65370    next: null,
65371    projectionNext: null,
65372    child: null,
65373    parent: tParent,
65374    projection: null,
65375    styles: null,
65376    stylesWithoutHost: null,
65377    residualStyles: undefined,
65378    classes: null,
65379    classesWithoutHost: null,
65380    residualClasses: undefined,
65381    classBindings: 0,
65382    styleBindings: 0
65383  };
65384
65385  if (ngDevMode) {
65386    // For performance reasons it is important that the tNode retains the same shape during runtime.
65387    // (To make sure that all of the code is monomorphic.) For this reason we seal the object to
65388    // prevent class transitions.
65389    Object.seal(tNode);
65390  }
65391
65392  return tNode;
65393}
65394
65395function generatePropertyAliases(inputAliasMap, directiveDefIdx, propStore) {
65396  for (let publicName in inputAliasMap) {
65397    if (inputAliasMap.hasOwnProperty(publicName)) {
65398      propStore = propStore === null ? {} : propStore;
65399      const internalName = inputAliasMap[publicName];
65400
65401      if (propStore.hasOwnProperty(publicName)) {
65402        propStore[publicName].push(directiveDefIdx, internalName);
65403      } else {
65404        propStore[publicName] = [directiveDefIdx, internalName];
65405      }
65406    }
65407  }
65408
65409  return propStore;
65410}
65411/**
65412 * Initializes data structures required to work with directive inputs and outputs.
65413 * Initialization is done for all directives matched on a given TNode.
65414 */
65415
65416
65417function initializeInputAndOutputAliases(tView, tNode) {
65418  ngDevMode && assertFirstCreatePass(tView);
65419  const start = tNode.directiveStart;
65420  const end = tNode.directiveEnd;
65421  const tViewData = tView.data;
65422  const tNodeAttrs = tNode.attrs;
65423  const inputsFromAttrs = ngDevMode ? new TNodeInitialInputs() : [];
65424  let inputsStore = null;
65425  let outputsStore = null;
65426
65427  for (let i = start; i < end; i++) {
65428    const directiveDef = tViewData[i];
65429    const directiveInputs = directiveDef.inputs; // Do not use unbound attributes as inputs to structural directives, since structural
65430    // directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
65431    // TODO(FW-1930): microsyntax expressions may also contain unbound/static attributes, which
65432    // should be set for inline templates.
65433
65434    const initialInputs = tNodeAttrs !== null && !isInlineTemplate(tNode) ? generateInitialInputs(directiveInputs, tNodeAttrs) : null;
65435    inputsFromAttrs.push(initialInputs);
65436    inputsStore = generatePropertyAliases(directiveInputs, i, inputsStore);
65437    outputsStore = generatePropertyAliases(directiveDef.outputs, i, outputsStore);
65438  }
65439
65440  if (inputsStore !== null) {
65441    if (inputsStore.hasOwnProperty('class')) {
65442      tNode.flags |= 16
65443      /* TNodeFlags.hasClassInput */
65444      ;
65445    }
65446
65447    if (inputsStore.hasOwnProperty('style')) {
65448      tNode.flags |= 32
65449      /* TNodeFlags.hasStyleInput */
65450      ;
65451    }
65452  }
65453
vendor: 12,372 bytes, lines 65454-65814
65454  tNode.initialInputs = inputsFromAttrs;
65455  tNode.inputs = inputsStore;
65456  tNode.outputs = outputsStore;
65457}
65458/**
65459 * Mapping between attributes names that don't correspond to their element property names.
65460 *
65461 * Performance note: this function is written as a series of if checks (instead of, say, a property
65462 * object lookup) for performance reasons - the series of `if` checks seems to be the fastest way of
65463 * mapping property names. Do NOT change without benchmarking.
65464 *
65465 * Note: this mapping has to be kept in sync with the equally named mapping in the template
65466 * type-checking machinery of ngtsc.
65467 */
65468
65469
65470function mapPropName(name) {
65471  if (name === 'class') return 'className';
65472  if (name === 'for') return 'htmlFor';
65473  if (name === 'formaction') return 'formAction';
65474  if (name === 'innerHtml') return 'innerHTML';
65475  if (name === 'readonly') return 'readOnly';
65476  if (name === 'tabindex') return 'tabIndex';
65477  return name;
65478}
65479
65480function elementPropertyInternal(tView, tNode, lView, propName, value, renderer, sanitizer, nativeOnly) {
65481  ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
65482  const element = getNativeByTNode(tNode, lView);
65483  let inputData = tNode.inputs;
65484  let dataValue;
65485
65486  if (!nativeOnly && inputData != null && (dataValue = inputData[propName])) {
65487    setInputsForProperty(tView, lView, dataValue, propName, value);
65488    if (isComponentHost(tNode)) markDirtyIfOnPush(lView, tNode.index);
65489
65490    if (ngDevMode) {
65491      setNgReflectProperties(lView, element, tNode.type, dataValue, value);
65492    }
65493  } else if (tNode.type & 3
65494  /* TNodeType.AnyRNode */
65495  ) {
65496    propName = mapPropName(propName);
65497
65498    if (ngDevMode) {
65499      validateAgainstEventProperties(propName);
65500
65501      if (!isPropertyValid(element, propName, tNode.value, tView.schemas)) {
65502        handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
65503      }
65504
65505      ngDevMode.rendererSetProperty++;
65506    } // It is assumed that the sanitizer is only added when the compiler determines that the
65507    // property is risky, so sanitization can be done without further checks.
65508
65509
65510    value = sanitizer != null ? sanitizer(value, tNode.value || '', propName) : value;
65511    renderer.setProperty(element, propName, value);
65512  } else if (tNode.type & 12
65513  /* TNodeType.AnyContainer */
65514  ) {
65515    // If the node is a container and the property didn't
65516    // match any of the inputs or schemas we should throw.
65517    if (ngDevMode && !matchingSchemas(tView.schemas, tNode.value)) {
65518      handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
65519    }
65520  }
65521}
65522/** If node is an OnPush component, marks its LView dirty. */
65523
65524
65525function markDirtyIfOnPush(lView, viewIndex) {
65526  ngDevMode && assertLView(lView);
65527  const childComponentLView = getComponentLViewByIndex(viewIndex, lView);
65528
65529  if (!(childComponentLView[FLAGS] & 16
65530  /* LViewFlags.CheckAlways */
65531  )) {
65532    childComponentLView[FLAGS] |= 32
65533    /* LViewFlags.Dirty */
65534    ;
65535  }
65536}
65537
65538function setNgReflectProperty(lView, element, type, attrName, value) {
65539  const renderer = lView[RENDERER];
65540  attrName = normalizeDebugBindingName(attrName);
65541  const debugValue = normalizeDebugBindingValue(value);
65542
65543  if (type & 3
65544  /* TNodeType.AnyRNode */
65545  ) {
65546    if (value == null) {
65547      renderer.removeAttribute(element, attrName);
65548    } else {
65549      renderer.setAttribute(element, attrName, debugValue);
65550    }
65551  } else {
65552    const textContent = escapeCommentText(`bindings=${JSON.stringify({
65553      [attrName]: debugValue
65554    }, null, 2)}`);
65555    renderer.setValue(element, textContent);
65556  }
65557}
65558
65559function setNgReflectProperties(lView, element, type, dataValue, value) {
65560  if (type & (3
65561  /* TNodeType.AnyRNode */
65562  | 4
65563  /* TNodeType.Container */
65564  )) {
65565    /**
65566     * dataValue is an array containing runtime input or output names for the directives:
65567     * i+0: directive instance index
65568     * i+1: privateName
65569     *
65570     * e.g. [0, 'change', 'change-minified']
65571     * we want to set the reflected property with the privateName: dataValue[i+1]
65572     */
65573    for (let i = 0; i < dataValue.length; i += 2) {
65574      setNgReflectProperty(lView, element, type, dataValue[i + 1], value);
65575    }
65576  }
65577}
65578/**
65579 * Instantiate a root component.
65580 */
65581
65582
65583function instantiateRootComponent(tView, lView, def) {
65584  const rootTNode = getCurrentTNode();
65585
65586  if (tView.firstCreatePass) {
65587    if (def.providersResolver) def.providersResolver(def);
65588    const directiveIndex = allocExpando(tView, lView, 1, null);
65589    ngDevMode && assertEqual(directiveIndex, rootTNode.directiveStart, 'Because this is a root component the allocated expando should match the TNode component.');
65590    configureViewWithDirective(tView, rootTNode, lView, directiveIndex, def);
65591    initializeInputAndOutputAliases(tView, rootTNode);
65592  }
65593
65594  const directive = getNodeInjectable(lView, tView, rootTNode.directiveStart, rootTNode);
65595  attachPatchData(directive, lView);
65596  const native = getNativeByTNode(rootTNode, lView);
65597
65598  if (native) {
65599    attachPatchData(native, lView);
65600  }
65601
65602  return directive;
65603}
65604/**
65605 * Resolve the matched directives on a node.
65606 */
65607
65608
65609function resolveDirectives(tView, lView, tNode, localRefs) {
65610  // Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in
65611  // tsickle.
65612  ngDevMode && assertFirstCreatePass(tView);
65613  let hasDirectives = false;
65614
65615  if (getBindingsEnabled()) {
65616    const directiveDefs = findDirectiveDefMatches(tView, lView, tNode);
65617    const exportsMap = localRefs === null ? null : {
65618      '': -1
65619    };
65620
65621    if (directiveDefs !== null) {
65622      hasDirectives = true;
65623      initTNodeFlags(tNode, tView.data.length, directiveDefs.length); // When the same token is provided by several directives on the same node, some rules apply in
65624      // the viewEngine:
65625      // - viewProviders have priority over providers
65626      // - the last directive in NgModule.declarations has priority over the previous one
65627      // So to match these rules, the order in which providers are added in the arrays is very
65628      // important.
65629
65630      for (let i = 0; i < directiveDefs.length; i++) {
65631        const def = directiveDefs[i];
65632        if (def.providersResolver) def.providersResolver(def);
65633      }
65634
65635      let preOrderHooksFound = false;
65636      let preOrderCheckHooksFound = false;
65637      let directiveIdx = allocExpando(tView, lView, directiveDefs.length, null);
65638      ngDevMode && assertSame(directiveIdx, tNode.directiveStart, 'TNode.directiveStart should point to just allocated space');
65639
65640      for (let i = 0; i < directiveDefs.length; i++) {
65641        const def = directiveDefs[i]; // Merge the attrs in the order of matches. This assumes that the first directive is the
65642        // component itself, so that the component has the least priority.
65643
65644        tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
65645        configureViewWithDirective(tView, tNode, lView, directiveIdx, def);
65646        saveNameToExportMap(directiveIdx, def, exportsMap);
65647        if (def.contentQueries !== null) tNode.flags |= 8
65648        /* TNodeFlags.hasContentQuery */
65649        ;
65650        if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0) tNode.flags |= 128
65651        /* TNodeFlags.hasHostBindings */
65652        ;
65653        const lifeCycleHooks = def.type.prototype; // Only push a node index into the preOrderHooks array if this is the first
65654        // pre-order hook found on this node.
65655
65656        if (!preOrderHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngOnInit || lifeCycleHooks.ngDoCheck)) {
65657          // We will push the actual hook function into this array later during dir instantiation.
65658          // We cannot do it now because we must ensure hooks are registered in the same
65659          // order that directives are created (i.e. injection order).
65660          (tView.preOrderHooks || (tView.preOrderHooks = [])).push(tNode.index);
65661          preOrderHooksFound = true;
65662        }
65663
65664        if (!preOrderCheckHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngDoCheck)) {
65665          (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(tNode.index);
65666          preOrderCheckHooksFound = true;
65667        }
65668
65669        directiveIdx++;
65670      }
65671
65672      initializeInputAndOutputAliases(tView, tNode);
65673    }
65674
65675    if (exportsMap) cacheMatchingLocalNames(tNode, localRefs, exportsMap);
65676  } // Merge the template attrs last so that they have the highest priority.
65677
65678
65679  tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
65680  return hasDirectives;
65681}
65682/**
65683 * Add `hostBindings` to the `TView.hostBindingOpCodes`.
65684 *
65685 * @param tView `TView` to which the `hostBindings` should be added.
65686 * @param tNode `TNode` the element which contains the directive
65687 * @param lView `LView` current `LView`
65688 * @param directiveIdx Directive index in view.
65689 * @param directiveVarsIdx Where will the directive's vars be stored
65690 * @param def `ComponentDef`/`DirectiveDef`, which contains the `hostVars`/`hostBindings` to add.
65691 */
65692
65693
65694function registerHostBindingOpCodes(tView, tNode, lView, directiveIdx, directiveVarsIdx, def) {
65695  ngDevMode && assertFirstCreatePass(tView);
65696  const hostBindings = def.hostBindings;
65697
65698  if (hostBindings) {
65699    let hostBindingOpCodes = tView.hostBindingOpCodes;
65700
65701    if (hostBindingOpCodes === null) {
65702      hostBindingOpCodes = tView.hostBindingOpCodes = [];
65703    }
65704
65705    const elementIndx = ~tNode.index;
65706
65707    if (lastSelectedElementIdx(hostBindingOpCodes) != elementIndx) {
65708      // Conditionally add select element so that we are more efficient in execution.
65709      // NOTE: this is strictly not necessary and it trades code size for runtime perf.
65710      // (We could just always add it.)
65711      hostBindingOpCodes.push(elementIndx);
65712    }
65713
65714    hostBindingOpCodes.push(directiveIdx, directiveVarsIdx, hostBindings);
65715  }
65716}
65717/**
65718 * Returns the last selected element index in the `HostBindingOpCodes`
65719 *
65720 * For perf reasons we don't need to update the selected element index in `HostBindingOpCodes` only
65721 * if it changes. This method returns the last index (or '0' if not found.)
65722 *
65723 * Selected element index are only the ones which are negative.
65724 */
65725
65726
65727function lastSelectedElementIdx(hostBindingOpCodes) {
65728  let i = hostBindingOpCodes.length;
65729
65730  while (i > 0) {
65731    const value = hostBindingOpCodes[--i];
65732
65733    if (typeof value === 'number' && value < 0) {
65734      return value;
65735    }
65736  }
65737
65738  return 0;
65739}
65740/**
65741 * Instantiate all the directives that were previously resolved on the current node.
65742 */
65743
65744
65745function instantiateAllDirectives(tView, lView, tNode, native) {
65746  const start = tNode.directiveStart;
65747  const end = tNode.directiveEnd;
65748
65749  if (!tView.firstCreatePass) {
65750    getOrCreateNodeInjectorForNode(tNode, lView);
65751  }
65752
65753  attachPatchData(native, lView);
65754  const initialInputs = tNode.initialInputs;
65755
65756  for (let i = start; i < end; i++) {
65757    const def = tView.data[i];
65758    const isComponent = isComponentDef(def);
65759
65760    if (isComponent) {
65761      ngDevMode && assertTNodeType(tNode, 3
65762      /* TNodeType.AnyRNode */
65763      );
65764      addComponentLogic(lView, tNode, def);
65765    }
65766
65767    const directive = getNodeInjectable(lView, tView, i, tNode);
65768    attachPatchData(directive, lView);
65769
65770    if (initialInputs !== null) {
65771      setInputsFromAttrs(lView, i - start, directive, def, tNode, initialInputs);
65772    }
65773
65774    if (isComponent) {
65775      const componentView = getComponentLViewByIndex(tNode.index, lView);
65776      componentView[CONTEXT] = directive;
65777    }
65778  }
65779}
65780
65781function invokeDirectivesHostBindings(tView, lView, tNode) {
65782  const start = tNode.directiveStart;
65783  const end = tNode.directiveEnd;
65784  const elementIndex = tNode.index;
65785  const currentDirectiveIndex = getCurrentDirectiveIndex();
65786
65787  try {
65788    setSelectedIndex(elementIndex);
65789
65790    for (let dirIndex = start; dirIndex < end; dirIndex++) {
65791      const def = tView.data[dirIndex];
65792      const directive = lView[dirIndex];
65793      setCurrentDirectiveIndex(dirIndex);
65794
65795      if (def.hostBindings !== null || def.hostVars !== 0 || def.hostAttrs !== null) {
65796        invokeHostBindingsInCreationMode(def, directive);
65797      }
65798    }
65799  } finally {
65800    setSelectedIndex(-1);
65801    setCurrentDirectiveIndex(currentDirectiveIndex);
65802  }
65803}
65804/**
65805 * Invoke the host bindings in creation mode.
65806 *
65807 * @param def `DirectiveDef` which may contain the `hostBindings` function.
65808 * @param directive Instance of directive.
65809 */
65810
65811
65812function invokeHostBindingsInCreationMode(def, directive) {
65813  if (def.hostBindings !== null) {
65814    def.hostBindings(1
65815    /* RenderFlags.Create */
65816    , directive);
65817  }
65818}
65819/**
65820 * Matches the current node against all available selectors.
65821 * If a component is matched (at most one), it is returned in first position in the array.
65822 */
65823
65824
65825function findDirectiveDefMatches(tView, viewData, tNode) {
65826  ngDevMode && assertFirstCreatePass(tView);
65827  ngDevMode && assertTNodeType(tNode, 3
65828  /* TNodeType.AnyRNode */
65829  | 12
65830  /* TNodeType.AnyContainer */
65831  );
65832  const registry = tView.directiveRegistry;
65833  let matches = null;
65834
65835  if (registry) {
65836    for (let i = 0; i < registry.length; i++) {
65837      const def = registry[i];
65838
65839      if (isNodeMatchingSelectorList(tNode, def.selectors,
65840      /* isProjectionMode */
65841      false)) {
65842        matches || (matches = ngDevMode ? new MatchesArray() : []);
65843        diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, viewData), tView, def.type);
65844
65845        if (isComponentDef(def)) {
65846          if (ngDevMode) {
65847            assertTNodeType(tNode, 2
65848            /* TNodeType.Element */
65849            , `"${tNode.value}" tags cannot be used as component hosts. ` + `Please use a different tag to activate the ${stringify(def.type)} component.`);
65850
65851            if (tNode.flags & 2
65852            /* TNodeFlags.isComponentHost */
65853            ) {
65854              // If another component has been matched previously, it's the first element in the
65855              // `matches` array, see how we store components/directives in `matches` below.
65856              throwMultipleComponentError(tNode, matches[0].type, def.type);
65857            }
65858          }
65859
65860          markAsComponentHost(tView, tNode); // The component is always stored first with directives after.
65861
65862          matches.unshift(def);
65863        } else {
65864          matches.push(def);
65865        }
65866      }
65867    }
65868  }
65869
65870  return matches;
65871}
65872/**
65873 * Marks a given TNode as a component's host. This consists of:
65874 * - setting appropriate TNode flags;
65875 * - storing index of component's host element so it will be queued for view refresh during CD.
65876 */
65877
65878
65879function markAsComponentHost(tView, hostTNode) {
65880  ngDevMode && assertFirstCreatePass(tView);
65881  hostTNode.flags |= 2
65882  /* TNodeFlags.isComponentHost */
65883  ;
65884  (tView.components || (tView.components = ngDevMode ? new TViewComponents() : [])).push(hostTNode.index);
65885}
65886/** Caches local names and their matching directive indices for query and template lookups. */
65887
65888
65889function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
65890  if (localRefs) {
65891    const localNames = tNode.localNames = ngDevMode ? new TNodeLocalNames() : []; // Local names must be stored in tNode in the same order that localRefs are defined
65892    // in the template to ensure the data is loaded in the same slots as their refs
65893    // in the template (for template queries).
65894
65895    for (let i = 0; i < localRefs.length; i += 2) {
65896      const index = exportsMap[localRefs[i + 1]];
65897      if (index == null) throw new RuntimeError(-301
65898      /* RuntimeErrorCode.EXPORT_NOT_FOUND */
65899      , ngDevMode && `Export of name '${localRefs[i + 1]}' not found!`);
65900      localNames.push(localRefs[i], index);
65901    }
65902  }
65903}
65904/**
65905 * Builds up an export map as directives are created, so local refs can be quickly mapped
65906 * to their directive instances.
65907 */
65908
65909
65910function saveNameToExportMap(directiveIdx, def, exportsMap) {
65911  if (exportsMap) {
65912    if (def.exportAs) {
65913      for (let i = 0; i < def.exportAs.length; i++) {
65914        exportsMap[def.exportAs[i]] = directiveIdx;
65915      }
65916    }
65917
65918    if (isComponentDef(def)) exportsMap[''] = directiveIdx;
65919  }
65920}
65921/**
65922 * Initializes the flags on the current node, setting all indices to the initial index,
65923 * the directive count to 0, and adding the isComponent flag.
65924 * @param index the initial index
65925 */
65926
65927
65928function initTNodeFlags(tNode, index, numberOfDirectives) {
65929  ngDevMode && assertNotEqual(numberOfDirectives, tNode.directiveEnd - tNode.directiveStart, 'Reached the max number of directives');
65930  tNode.flags |= 1
65931  /* TNodeFlags.isDirectiveHost */
65932  ; // When the first directive is created on a node, save the index
65933
65934  tNode.directiveStart = index;
65935  tNode.directiveEnd = index + numberOfDirectives;
65936  tNode.providerIndexes = index;
65937}
65938/**
65939 * Setup directive for instantiation.
65940 *
65941 * We need to create a `NodeInjectorFactory` which is then inserted in both the `Blueprint` as well
65942 * as `LView`. `TView` gets the `DirectiveDef`.
65943 *
65944 * @param tView `TView`
65945 * @param tNode `TNode`
65946 * @param lView `LView`
65947 * @param directiveIndex Index where the directive will be stored in the Expando.
65948 * @param def `DirectiveDef`
65949 */
65950
65951
65952function configureViewWithDirective(tView, tNode, lView, directiveIndex, def) {
65953  ngDevMode && assertGreaterThanOrEqual(directiveIndex, HEADER_OFFSET, 'Must be in Expando section');
65954  tView.data[directiveIndex] = def;
65955  const directiveFactory = def.factory || (def.factory = getFactoryDef(def.type, true)); // Even though `directiveFactory` will already be using `ɵɵdirectiveInject` in its generated code,
vendor: 4,739 bytes, lines 65956-66074
65956  // we also want to support `inject()` directly from the directive constructor context so we set
65957  // `ɵɵdirectiveInject` as the inject implementation here too.
65958
65959  const nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), ɵɵdirectiveInject);
65960  tView.blueprint[directiveIndex] = nodeInjectorFactory;
65961  lView[directiveIndex] = nodeInjectorFactory;
65962  registerHostBindingOpCodes(tView, tNode, lView, directiveIndex, allocExpando(tView, lView, def.hostVars, NO_CHANGE), def);
65963}
65964
65965function addComponentLogic(lView, hostTNode, def) {
65966  const native = getNativeByTNode(hostTNode, lView);
65967  const tView = getOrCreateComponentTView(def); // Only component views should be added to the view tree directly. Embedded views are
65968  // accessed through their containers because they may be removed / re-added later.
65969
65970  const rendererFactory = lView[RENDERER_FACTORY];
65971  const componentView = addToViewTree(lView, createLView(lView, tView, null, def.onPush ? 32
65972  /* LViewFlags.Dirty */
65973  : 16
65974  /* LViewFlags.CheckAlways */
65975  , native, hostTNode, rendererFactory, rendererFactory.createRenderer(native, def), null, null, null)); // Component view will always be created before any injected LContainers,
65976  // so this is a regular element, wrap it with the component view
65977
65978  lView[hostTNode.index] = componentView;
65979}
65980
65981function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace) {
65982  if (ngDevMode) {
65983    assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
65984    validateAgainstEventAttributes(name);
65985    assertTNodeType(tNode, 2
65986    /* TNodeType.Element */
65987    , `Attempted to set attribute \`${name}\` on a container node. ` + `Host bindings are not valid on ng-container or ng-template.`);
65988  }
65989
65990  const element = getNativeByTNode(tNode, lView);
65991  setElementAttribute(lView[RENDERER], element, namespace, tNode.value, name, value, sanitizer);
65992}
65993
65994function setElementAttribute(renderer, element, namespace, tagName, name, value, sanitizer) {
65995  if (value == null) {
65996    ngDevMode && ngDevMode.rendererRemoveAttribute++;
65997    renderer.removeAttribute(element, name, namespace);
65998  } else {
65999    ngDevMode && ngDevMode.rendererSetAttribute++;
66000    const strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tagName || '', name);
66001    renderer.setAttribute(element, name, strValue, namespace);
66002  }
66003}
66004/**
66005 * Sets initial input properties on directive instances from attribute data
66006 *
66007 * @param lView Current LView that is being processed.
66008 * @param directiveIndex Index of the directive in directives array
66009 * @param instance Instance of the directive on which to set the initial inputs
66010 * @param def The directive def that contains the list of inputs
66011 * @param tNode The static data for this node
66012 */
66013
66014
66015function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initialInputData) {
66016  const initialInputs = initialInputData[directiveIndex];
66017
66018  if (initialInputs !== null) {
66019    const setInput = def.setInput;
66020
66021    for (let i = 0; i < initialInputs.length;) {
66022      const publicName = initialInputs[i++];
66023      const privateName = initialInputs[i++];
66024      const value = initialInputs[i++];
66025
66026      if (setInput !== null) {
66027        def.setInput(instance, value, publicName, privateName);
66028      } else {
66029        instance[privateName] = value;
66030      }
66031
66032      if (ngDevMode) {
66033        const nativeElement = getNativeByTNode(tNode, lView);
66034        setNgReflectProperty(lView, nativeElement, tNode.type, privateName, value);
66035      }
66036    }
66037  }
66038}
66039/**
66040 * Generates initialInputData for a node and stores it in the template's static storage
66041 * so subsequent template invocations don't have to recalculate it.
66042 *
66043 * initialInputData is an array containing values that need to be set as input properties
66044 * for directives on this node, but only once on creation. We need this array to support
66045 * the case where you set an @Input property of a directive using attribute-like syntax.
66046 * e.g. if you have a `name` @Input, you can set it once like this:
66047 *
66048 * <my-component name="Bess"></my-component>
66049 *
66050 * @param inputs The list of inputs from the directive def
66051 * @param attrs The static attrs on this node
66052 */
66053
66054
66055function generateInitialInputs(inputs, attrs) {
66056  let inputsToStore = null;
66057  let i = 0;
66058
66059  while (i < attrs.length) {
66060    const attrName = attrs[i];
66061
66062    if (attrName === 0
66063    /* AttributeMarker.NamespaceURI */
66064    ) {
66065      // We do not allow inputs on namespaced attributes.
66066      i += 4;
66067      continue;
66068    } else if (attrName === 5
66069    /* AttributeMarker.ProjectAs */
66070    ) {
66071      // Skip over the `ngProjectAs` value.
66072      i += 2;
66073      continue;
66074    } // If we hit any other attribute markers, we're done anyway. None of those are valid input
66074s.
66075
66076
66077    if (typeof attrName === 'number') break;
66078
66079    if (inputs.hasOwnProperty(attrName)) {
66080      if (inputsToStore === null) inputsToStore = [];
66081      inputsToStore.push(attrName, inputs[attrName], attrs[i + 1]);
66082    }
66083
66084    i += 2;
66085  }
66086
66087  return inputsToStore;
66088} //////////////////////////
66089//// ViewContainer & View
66090//////////////////////////
66091// Not sure why I need to do `any` here but TS complains later.
66092
66093
66094const LContainerArray = class LContainer extends Array {};
66095/**
66096 * Creates a LContainer, either from a container instruction, or for a ViewContainerRef.
66097 *
66098 * @param hostNative The host element for the LContainer
66099 * @param hostTNode The host TNode for the LContainer
66100 * @param currentView The parent view of the LContainer
66101 * @param native The native comment element
66102 * @param isForViewContainerRef Optional a flag indicating the ViewContainerRef case
66103 * @returns LContainer
66104 */
66105
66106function createLContainer(hostNative, currentView, native, tNode) {
66107  ngDevMode && assertLView(currentView); // https://jsperf.com/array-literal-vs-new-array-really
66108
66109  const lContainer = new (ngDevMode ? LContainerArray : Array)(hostNative, // host native
66110  true, // Boolean `true` in this position signifies that this is an `LContainer`
66111  false, // has transplanted views
66112  currentView, // parent
66113  null, // next
66114  0, // transplanted views to refresh count
66115  tNode, // t_host
66116  native, // native,
66117  null, // view refs
66118  null);
66119  ngDevMode && assertEqual(lContainer.length, CONTAINER_HEADER_OFFSET, 'Should allocate correct number of slots for LContainer header.');
66120  ngDevMode && attachLContainerDebug(lContainer);
66121  return lContainer;
66122}
66123/**
66124 * Goes over embedded views (ones created through ViewContainerRef APIs) and refreshes
66125 * them by executing an associated template function.
66126 */
66127
66128
66129function refreshEmbeddedViews(lView) {
66130  for (let lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
66131    for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
66132      const embeddedLView = lContainer[i];
66133      const embeddedTView = embeddedLView[TVIEW];
66134      ngDevMode && assertDefined(embeddedTView, 'TView must be allocated');
66135
66136      if (viewAttachedToChangeDetector(embeddedLView)) {
66137        refreshView(embeddedTView, embeddedLView, embeddedTView.template, embeddedLView[CONTEXT]);
66138      }
66139    }
66140  }
66141}
66142/**
66143 * Mark transplanted views as needing to be refreshed at their insertion points.
66144 *
66145 * @param lView The `LView` that may have transplanted views.
66146 */
66147
66148
66149function markTransplantedViewsForRefresh(lView) {
66150  for (let lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
66151    if (!lContainer[HAS_TRANSPLANTED_VIEWS]) continue;
66152    const movedViews = lContainer[MOVED_VIEWS];
66153    ngDevMode && assertDefined(movedViews, 'Transplanted View flags set but missing MOVED_VIEWS');
66154
66155    for (let i = 0; i < movedViews.length; i++) {
66156      const movedLView = movedViews[i];
66157      const insertionLContainer = movedLView[PARENT];
66158      ngDevMode && assertLContainer(insertionLContainer); // We don't want to increment the counter if the moved LView was already marked for
66159      // refresh.
66160
66161      if ((movedLView[FLAGS] & 512
66162      /* LViewFlags.RefreshTransplantedView */
66163      ) === 0) {
66164        updateTransplantedViewCount(insertionLContainer, 1);
66165      } // Note, it is possible that the `movedViews` is tracking views that are transplanted *and*
66166      // those that aren't (declaration component === insertion component). In the latter case,
66167      // it's fine to add the flag, as we will clear it immediately in
66168      // `refreshEmbeddedViews` for the view currently being refreshed.
66169
66170
66171      movedLView[FLAGS] |= 512
66172      /* LViewFlags.RefreshTransplantedView */
66173      ;
66174    }
66175  }
66176} /////////////
66177
66178/**
66179 * Refreshes components by entering the component view and processing its bindings, queries, etc.
66180 *
66181 * @param componentHostIdx  Element index in LView[] (adjusted for HEADER_OFFSET)
66182 */
66183
66184
66185function refreshComponent(hostLView, componentHostIdx) {
66186  ngDevMode && assertEqual(isCreationMode(hostLView), false, 'Should be run in update mode');
66187  const componentView = getComponentLViewByIndex(componentHostIdx, hostLView); // Only attached components that are CheckAlways or OnPush and dirty should be refreshed
66188
66189  if (viewAttachedToChangeDetector(componentView)) {
66190    const tView = componentView[TVIEW];
66191
66192    if (componentView[FLAGS] & (16
66193    /* LViewFlags.CheckAlways */
66194    | 32
66195    /* LViewFlags.Dirty */
66196    )) {
66197      refreshView(tView, componentView, tView.template, componentView[CONTEXT]);
66198    } else if (componentView[TRANSPLANTED_VIEWS_TO_REFRESH] > 0) {
66199      // Only attached components that are CheckAlways or OnPush and dirty should be refreshed
66200      refreshContainsDirtyView(componentView);
66201    }
66202  }
66203}
66204/**
66205 * Refreshes all transplanted views marked with `LViewFlags.RefreshTransplantedView` that are
66206 * children or descendants of the given lView.
66207 *
66208 * @param lView The lView which contains descendant transplanted views that need to be refreshed.
66209 */
66210
66211
66212function refreshContainsDirtyView(lView) {
66213  for (let lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
66214    for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
66215      const embeddedLView = lContainer[i];
66216
66217      if (viewAttachedToChangeDetector(embeddedLView)) {
66218        if (embeddedLView[FLAGS] & 512
66219        /* LViewFlags.RefreshTransplantedView */
66220        ) {
66221          const embeddedTView = embeddedLView[TVIEW];
66222          ngDevMode && assertDefined(embeddedTView, 'TView must be allocated');
66223          refreshView(embeddedTView, embeddedLView, embeddedTView.template, embeddedLView[CONTEXT]);
66224        } else if (embeddedLView[TRANSPLANTED_VIEWS_TO_REFRESH] > 0) {
66225          refreshContainsDirtyView(embeddedLView);
66226        }
66227      }
66228    }
66229  }
66230
66231  const tView = lView[TVIEW]; // Refresh child component views.
66232
66233  const components = tView.components;
66234
66235  if (components !== null) {
66236    for (let i = 0; i < components.length; i++) {
66237      const componentView = getComponentLViewByIndex(components[i], lView); // Only attached components that are CheckAlways or OnPush and dirty should be refreshed
66238
66239      if (viewAttachedToChangeDetector(componentView) && componentView[TRANSPLANTED_VIEWS_TO_REFRESH] > 0) {
66240        refreshContainsDirtyView(componentView);
66241      }
66242    }
66243  }
66244}
66245
66246function renderComponent(hostLView, componentHostIdx) {
66247  ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode');
66248  const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
66249  const componentTView = componentView[TVIEW];
66250  syncViewWithBlueprint(componentTView, componentView);
66251  renderView(componentTView, componentView, componentView[CONTEXT]);
66252}
66253/**
66254 * Syncs an LView instance with its blueprint if they have gotten out of sync.
66255 *
66256 * Typically, blueprints and their view instances should always be in sync, so the loop here
66257 * will be skipped. However, consider this case of two components side-by-side:
66258 *
66259 * App template:
66260 * ```
66261 * <comp></comp>
66262 * <comp></comp>
66263 * ```
66264 *
66265 * The following will happen:
66266 * 1. App template begins processing.
66267 * 2. First <comp> is matched as a component and its LView is created.
66268 * 3. Second <comp> is matched as a component and its LView is created.
66269 * 4. App template completes processing, so it's time to check child templates.
66270 * 5. First <comp> template is checked. It has a directive, so its def is pushed to blueprint.
66271 * 6. Second <comp> template is checked. Its blueprint has been updated by the first
66272 * <comp> template, but its LView was created before this update, so it is out of sync.
66273 *
66274 * Note that embedded views inside ngFor loops will never be out of sync because these views
66275 * are processed as soon as they are created.
66276 *
66277 * @param tView The `TView` that contains the blueprint for syncing
66278 * @param lView The view to sync
66279 */
66280
66281
66282function syncViewWithBlueprint(tView, lView) {
66283  for (let i = lView.length; i < tView.blueprint.length; i++) {
66284    lView.push(tView.blueprint[i]);
66285  }
66286}
66287/**
66288 * Adds LView or LContainer to the end of the current view tree.
66289 *
66290 * This structure will be used to traverse through nested views to remove listeners
66291 * and call onDestroy callbacks.
66292 *
66293 * @param lView The view where LView or LContainer should be added
66294 * @param adjustedHostIndex Index of the view's host node in LView[], adjusted for header
66295 * @param lViewOrLContainer The LView or LContainer to add to the view tree
66296 * @returns The state passed in
66297 */
66298
66299
66300function addToViewTree(lView, lViewOrLContainer) {
66301  // TODO(benlesh/misko): This implementation is incorrect, because it always adds the LContainer
66302  // to the end of the queue, which means if the developer retrieves the LContainers from RNodes out
66303  // of order, the change detection will run out of order, as the act of retrieving the the
66304  // LContainer from the RNode is what adds it to the queue.
66305  if (lView[CHILD_HEAD]) {
66306    lView[CHILD_TAIL][NEXT] = lViewOrLContainer;
66307  } else {
66308    lView[CHILD_HEAD] = lViewOrLContainer;
66309  }
66310
66311  lView[CHILD_TAIL] = lViewOrLContainer;
66312  return lViewOrLContainer;
66313} ///////////////////////////////
66314//// Change detection
66315///////////////////////////////
66316
66317/**
66318 * Marks current view and all ancestors dirty.
66319 *
66320 * Returns the root view because it is found as a byproduct of marking the view tree
66321 * dirty, and can be used by methods that consume markViewDirty() to easily schedule
66322 * change detection. Otherwise, such methods would need to traverse up the view tree
66323 * an additional time to get the root view and schedule a tick on it.
66324 *
66325 * @param lView The starting LView to mark dirty
66326 * @returns the root LView
66327 */
66328
66329
66330function markViewDirty(lView) {
66331  while (lView) {
66332    lView[FLAGS] |= 32
66333    /* LViewFlags.Dirty */
66334    ;
66335    const parent = getLViewParent(lView); // Stop traversing up as soon as you find a root view that wasn't attached to any container
66336
66337    if (isRootView(lView) && !parent) {
66338      return lView;
66339    } // continue otherwise
66340
66341
66342    lView = parent;
66343  }
66344
66345  return null;
66346}
66347
66348function detectChangesInternal(tView, lView, context, notifyErrorHandler = true) {
66349  const rendererFactory = lView[RENDERER_FACTORY]; // Check no changes mode is a dev only mode used to verify that bindings have not changed
66350  // since they were assigned. We do not want to invoke renderer factory functions in that mode
66351  // to avoid any possible side-effects.
66352
66353  const checkNoChangesMode = !!ngDevMode && isInCheckNoChangesMode();
66354  if (!checkNoChangesMode && rendererFactory.begin) rendererFactory.begin();
66355
66356  try {
66357    refreshView(tView, lView, tView.template, context);
66358  } catch (error) {
66359    if (notifyErrorHandler) {
66360      handleError(lView, error);
66361    }
66362
66363    throw error;
66364  } finally {
66365    if (!checkNoChangesMode && rendererFactory.end) rendererFactory.end();
66366  }
66367}
66368
66369function checkNoChangesInternal(tView, lView, context, notifyErrorHandler = true) {
66370  setIsInCheckNoChangesMode(true);
66371
66372  try {
66373    detectChangesInternal(tView, lView, context, notifyErrorHandler);
66374  } finally {
66375    setIsInCheckNoChangesMode(false);
66376  }
66377}
66378
66379function executeViewQueryFn(flags, viewQueryFn, component) {
66380  ngDevMode && assertDefined(viewQueryFn, 'View queries function to execute must be defined.');
66381  setCurrentQueryIndex(0);
66382  viewQueryFn(flags, component);
66383} ///////////////////////////////
66384//// Bindings & interpolations
66385///////////////////////////////
66386
66387/**
66388 * Stores meta-data for a property binding to be used by TestBed's `DebugElement.properties`.
66389 *
66390 * In order to support TestBed's `DebugElement.properties` we need to save, for each binding:
66391 * - a bound property name;
66392 * - a static parts of interpolated strings;
66393 *
66394 * A given property metadata is saved at the binding's index in the `TView.data` (in other words, a
66395 * property binding metadata will be stored in `TView.data` at the same index as a bound value in
66396 * `LView`). Metadata are represented as `INTERPOLATION_DELIMITER`-delimited string with the
66397 * following format:
66398 * - `propertyName` for bound properties;
66399 * - `propertyName�prefix�interpolation_static_part1�..interpolation_static_partN�suffix` for
66400 * interpolated properties.
66401 *
66402 * @param tData `TData` where meta-data will be saved;
66403 * @param tNode `TNode` that is a target of the binding;
66404 * @param propertyName bound property name;
66405 * @param bindingIndex binding index in `LView`
66406 * @param interpolationParts static interpolation parts (for property interpolations)
66407 */
66408
66409
66410function storePropertyBindingMetadata(tData, tNode, propertyName, bindingIndex, ...interpolationParts) {
66411  // Binding meta-data are stored only the first time a given property instruction is processed.
66412  // Since we don't have a concept of the "first update pass" we need to check for presence of the
66413  // binding meta-data to decide if one should be stored (or if was stored already).
66414  if (tData[bindingIndex] === null) {
vendor: 9,123 bytes, lines 66415-66702
66415    if (tNode.inputs == null || !tNode.inputs[propertyName]) {
66416      const propBindingIdxs = tNode.propertyBindings || (tNode.propertyBindings = []);
66417      propBindingIdxs.push(bindingIndex);
66418      let bindingMetadata = propertyName;
66419
66420      if (interpolationParts.length > 0) {
66421        bindingMetadata += INTERPOLATION_DELIMITER + interpolationParts.join(INTERPOLATION_DELIMITER);
66422      }
66423
66424      tData[bindingIndex] = bindingMetadata;
66425    }
66426  }
66427}
66428
66429function getOrCreateLViewCleanup(view) {
66430  // top level variables should not be exported for performance reasons (PERF_NOTES.md)
66431  return view[CLEANUP] || (view[CLEANUP] = ngDevMode ? new LCleanup() : []);
66432}
66433
66434function getOrCreateTViewCleanup(tView) {
66435  return tView.cleanup || (tView.cleanup = ngDevMode ? new TCleanup() : []);
66436}
66437/**
66438 * There are cases where the sub component's renderer needs to be included
66439 * instead of the current renderer (see the componentSyntheticHost* instructions).
66440 */
66441
66442
66443function loadComponentRenderer(currentDef, tNode, lView) {
66444  // TODO(FW-2043): the `currentDef` is null when host bindings are invoked while creating root
66445  // component (see packages/core/src/render3/component.ts). This is not consistent with the process
66446  // of creating inner components, when current directive index is available in the state. In order
66447  // to avoid relying on current def being `null` (thus special-casing root component creation), the
66448  // process of creating root component should be unified with the process of creating inner
66449  // components.
66450  if (currentDef === null || isComponentDef(currentDef)) {
66451    lView = unwrapLView(lView[tNode.index]);
66452  }
66453
66454  return lView[RENDERER];
66455}
66456/** Handles an error thrown in an LView. */
66457
66458
66459function handleError(lView, error) {
66460  const injector = lView[INJECTOR$1];
66461  const errorHandler = injector ? injector.get(ErrorHandler, null) : null;
66462  errorHandler && errorHandler.handleError(error);
66463}
66464/**
66465 * Set the inputs of directives at the current node to corresponding value.
66466 *
66467 * @param tView The current TView
66468 * @param lView the `LView` which contains the directives.
66469 * @param inputs mapping between the public "input" name and privately-known,
66470 *        possibly minified, property names to write to.
66471 * @param value Value to set.
66472 */
66473
66474
66475function setInputsForProperty(tView, lView, inputs, publicName, value) {
66476  for (let i = 0; i < inputs.length;) {
66477    const index = inputs[i++];
66478    const privateName = inputs[i++];
66479    const instance = lView[index];
66480    ngDevMode && assertIndexInRange(lView, index);
66481    const def = tView.data[index];
66482
66483    if (def.setInput !== null) {
66484      def.setInput(instance, value, publicName, privateName);
66485    } else {
66486      instance[privateName] = value;
66487    }
66488  }
66489}
66490/**
66491 * Updates a text binding at a given index in a given LView.
66492 */
66493
66494
66495function textBindingInternal(lView, index, value) {
66496  ngDevMode && assertString(value, 'Value should be a string');
66497  ngDevMode && assertNotSame(value, NO_CHANGE, 'value should not be NO_CHANGE');
66498  ngDevMode && assertIndexInRange(lView, index);
66499  const element = getNativeByIndex(index, lView);
66500  ngDevMode && assertDefined(element, 'native element should exist');
66501  updateTextNode(lView[RENDERER], element, value);
66502}
66503/**
66504 * @license
66505 * Copyright Google LLC All Rights Reserved.
66506 *
66507 * Use of this source code is governed by an MIT-style license that can be
66508 * found in the LICENSE file at https://angular.io/license
66509 */
66510
66511/**
66512 * Compute the static styling (class/style) from `TAttributes`.
66513 *
66514 * This function should be called during `firstCreatePass` only.
66515 *
66516 * @param tNode The `TNode` into which the styling information should be loaded.
66517 * @param attrs `TAttributes` containing the styling information.
66518 * @param writeToHost Where should the resulting static styles be written?
66519 *   - `false` Write to `TNode.stylesWithoutHost` / `TNode.classesWithoutHost`
66520 *   - `true` Write to `TNode.styles` / `TNode.classes`
66521 */
66522
66523
66524function computeStaticStyling(tNode, attrs, writeToHost) {
66525  ngDevMode && assertFirstCreatePass(getTView(), 'Expecting to be called in first template pass only');
66526  let styles = writeToHost ? tNode.styles : null;
66527  let classes = writeToHost ? tNode.classes : null;
66528  let mode = 0;
66529
66530  if (attrs !== null) {
66531    for (let i = 0; i < attrs.length; i++) {
66532      const value = attrs[i];
66533
66534      if (typeof value === 'number') {
66535        mode = value;
66536      } else if (mode == 1
66537      /* AttributeMarker.Classes */
66538      ) {
66539        classes = concatStringsWithSpace(classes, value);
66540      } else if (mode == 2
66541      /* AttributeMarker.Styles */
66542      ) {
66543        const style = value;
66544        const styleValue = attrs[++i];
66545        styles = concatStringsWithSpace(styles, style + ': ' + styleValue + ';');
66546      }
66547    }
66548  }
66549
66550  writeToHost ? tNode.styles = styles : tNode.stylesWithoutHost = styles;
66551  writeToHost ? tNode.classes = classes : tNode.classesWithoutHost = classes;
66552}
66553/**
66554 * @license
66555 * Copyright Google LLC All Rights Reserved.
66556 *
66557 * Use of this source code is governed by an MIT-style license that can be
66558 * found in the LICENSE file at https://angular.io/license
66559 */
66560
66561
66562function collectNativeNodes(tView, lView, tNode, result, isProjection = false) {
66563  while (tNode !== null) {
66564    ngDevMode && assertTNodeType(tNode, 3
66565    /* TNodeType.AnyRNode */
66566    | 12
66567    /* TNodeType.AnyContainer */
66568    | 16
66569    /* TNodeType.Projection */
66570    | 32
66571    /* TNodeType.Icu */
66572    );
66573    const lNode = lView[tNode.index];
66574
66575    if (lNode !== null) {
66576      result.push(unwrapRNode(lNode));
66577    } // A given lNode can represent either a native node or a LContainer (when it is a host of a
66578    // ViewContainerRef). When we find a LContainer we need to descend into it to collect root nodes
66579    // from the views in this container.
66580
66581
66582    if (isLContainer(lNode)) {
66583      for (let i = CONTAINER_HEADER_OFFSET; i < lNode.length; i++) {
66584        const lViewInAContainer = lNode[i];
66585        const lViewFirstChildTNode = lViewInAContainer[TVIEW].firstChild;
66586
66587        if (lViewFirstChildTNode !== null) {
66588          collectNativeNodes(lViewInAContainer[TVIEW], lViewInAContainer, lViewFirstChildTNode, result);
66589        }
66590      }
66591    }
66592
66593    const tNodeType = tNode.type;
66594
66595    if (tNodeType & 8
66596    /* TNodeType.ElementContainer */
66597    ) {
66598      collectNativeNodes(tView, lView, tNode.child, result);
66599    } else if (tNodeType & 32
66600    /* TNodeType.Icu */
66601    ) {
66602      const nextRNode = icuContainerIterate(tNode, lView);
66603      let rNode;
66604
66605      while (rNode = nextRNode()) {
66606        result.push(rNode);
66607      }
66608    } else if (tNodeType & 16
66609    /* TNodeType.Projection */
66610    ) {
66611      const nodesInSlot = getProjectionNodes(lView, tNode);
66612
66613      if (Array.isArray(nodesInSlot)) {
66614        result.push(...nodesInSlot);
66615      } else {
66616        const parentView = getLViewParent(lView[DECLARATION_COMPONENT_VIEW]);
66617        ngDevMode && assertParentView(parentView);
66618        collectNativeNodes(parentView[TVIEW], parentView, nodesInSlot, result, true);
66619      }
66620    }
66621
66622    tNode = isProjection ? tNode.projectionNext : tNode.next;
66623  }
66624
66625  return result;
66626}
66627/**
66628 * @license
66629 * Copyright Google LLC All Rights Reserved.
66630 *
66631 * Use of this source code is governed by an MIT-style license that can be
66632 * found in the LICENSE file at https://angular.io/license
66633 */
66634
66635
66636class ViewRef$1 {
66637  constructor(
66638  /**
66639   * This represents `LView` associated with the component when ViewRef is a ChangeDetectorRef.
66640   *
66641   * When ViewRef is created for a dynamic component, this also represents the `LView` for the
66642   * component.
66643   *
66644   * For a "regular" ViewRef created for an embedded view, this is the `LView` for the embedded
66645   * view.
66646   *
66647   * @internal
66648   */
66649  _lView,
66650  /**
66651   * This represents the `LView` associated with the point where `ChangeDetectorRef` was
66652   * requested.
66653   *
66654   * This may be different from `_lView` if the `_cdRefInjectingView` is an embedded view.
66655   */
66656  _cdRefInjectingView) {
66657    this._lView = _lView;
66658    this._cdRefInjectingView = _cdRefInjectingView;
66659    this._appRef = null;
66660    this._attachedToViewContainer = false;
66661  }
66662
66663  get rootNodes() {
66664    const lView = this._lView;
66665    const tView = lView[TVIEW];
66666    return collectNativeNodes(tView, lView, tView.firstChild, []);
66667  }
66668
66669  get context() {
66670    return this._lView[CONTEXT];
66671  }
66672
66673  set context(value) {
66674    this._lView[CONTEXT] = value;
66675  }
66676
66677  get destroyed() {
66678    return (this._lView[FLAGS] & 128
66679    /* LViewFlags.Destroyed */
66680    ) === 128
66681    /* LViewFlags.Destroyed */
66682    ;
66683  }
66684
66685  destroy() {
66686    if (this._appRef) {
66687      this._appRef.detachView(this);
66688    } else if (this._attachedToViewContainer) {
66689      const parent = this._lView[PARENT];
66690
66691      if (isLContainer(parent)) {
66692        const viewRefs = parent[VIEW_REFS];
66693        const index = viewRefs ? viewRefs.indexOf(this) : -1;
66694
66695        if (index > -1) {
66696          ngDevMode && assertEqual(index, parent.indexOf(this._lView) - CONTAINER_HEADER_OFFSET, 'An attached view should be in the same position within its container as its ViewRef in the VIEW_REFS array.');
66697          detachView(parent, index);
66698          removeFromArray(viewRefs, index);
66699        }
66700      }
66701
66702      this._attachedToViewContainer = false;
66703    }
66704
66705    destroyLView(this._lView[TVIEW], this._lView);
66706  }
66707
66708  onDestroy(callback) {
66709    storeCleanupWithContext(this._lView[TVIEW], this._lView, null, callback);
66710  }
66711  /**
66712   * Marks a view and all of its ancestors dirty.
66713   *
66714   * This can be used to ensure an {@link ChangeDetectionStrategy#OnPush OnPush} component is
66715   * checked when it needs to be re-rendered but the two normal triggers haven't marked it
66716   * dirty (i.e. inputs haven't changed and events haven't fired in the view).
66717   *
66718   * <!-- TODO: Add a link to a chapter on OnPush components -->
66719   *
66720   * @usageNotes
66721   * ### Example
66722   *
66723   * ```typescript
66724   * @Component({
66725   *   selector: 'app-root',
66726   *   template: `Number of ticks: {{numberOfTicks}}`
66727   *   changeDetection: ChangeDetectionStrategy.OnPush,
66728   * })
66729   * class AppComponent {
66730   *   numberOfTicks = 0;
66731   *
66732   *   constructor(private ref: ChangeDetectorRef) {
66733   *     setInterval(() => {
66734   *       this.numberOfTicks++;
66735   *       // the following is required, otherwise the view will not be updated
66736   *       this.ref.markForCheck();
66737   *     }, 1000);
66738   *   }
66739   * }
66740   * ```
66741   */
66742
66743
66744  markForCheck() {
66745    markViewDirty(this._cdRefInjectingView || this._lView);
66746  }
66747  /**
66748   * Detaches the view from the change detection tree.
66749   *
66750   * Detached views will not be checked during change detection runs until they are
66751   * re-attached, even if they are dirty. `detach` can be used in combination with
66752   * {@link ChangeDetectorRef#detectChanges detectChanges} to implement local change
66753   * detection checks.
66754   *
66755   * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
66756   * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
66757   *
66758   * @usageNotes
66759   * ### Example
66760   *
66761   * The following example defines a component with a large list of readonly data.
66762   * Imagine the data changes constantly, many times per second. For performance reasons,
66763   * we want to check and update the list every five seconds. We can do that by detaching
66764   * the component's change detector and doing a local check every five seconds.
66765   *
66766   * ```typescript
66767   * class DataProvider {
66768   *   // in a real application the returned data will be different every time
66769   *   get data() {
66770   *     return [1,2,3,4,5];
66771   *   }
66772   * }
66773   *
66774   * @Component({
66775   *   selector: 'giant-list',
66776   *   template: `
66777   *     <li *ngFor="let d of dataProvider.data">Data {{d}}</li>
66778   *   `,
66779   * })
66780   * class GiantList {
66781   *   constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {
66782   *     ref.detach();
66783   *     setInterval(() => {
66784   *       this.ref.detectChanges();
66785   *     }, 5000);
66786   *   }
66787   * }
66788   *
66789   * @Component({
66790   *   selector: 'app',
66791   *   providers: [DataProvider],
66792   *   template: `
66793   *     <giant-list><giant-list>
66794   *   `,
66795   * })
66796   * class App {
66797   * }
66798   * ```
66799   */
66800
66801
66802  detach() {
66803    this._lView[FLAGS] &= ~64
66804    /* LViewFlags.Attached */
66805    ;
66806  }
66807  /**
66808   * Re-attaches a view to the change detection tree.
66809   *
66810   * This can be used to re-attach views that were previously detached from the tree
66811   * using {@link ChangeDetectorRef#detach detach}. Views are attached to the tree by default.
66812   *
66813   * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
66814   *
66815   * @usageNotes
66816   * ### Example
66817   *
66818   * The following example creates a component displaying `live` data. The component will detach
66819   * its change detector from the main change detector tree when the component's live property
66820   * is set to false.
66821   *
66822   * ```typescript
66823   * class DataProvider {
66824   *   data = 1;
66825   *
66826   *   constructor() {
66827   *     setInterval(() => {
66828   *       this.data = this.data * 2;
66829   *     }, 500);
66830   *   }
66831   * }
66832   *
66833   * @Component({
66834   *   selector: 'live-data',
66835   *   inputs: ['live'],
66836   *   template: 'Data: {{dataProvider.data}}'
66837   * })
66838   * class LiveData {
66839   *   constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {}
66840   *
66841   *   set live(value) {
66842   *     if (value) {
66843   *       this.ref.reattach();
66844   *     } else {
66845   *       this.ref.detach();
66846   *     }
66847   *   }
66848   * }
66849   *
66850   * @Component({
66851   *   selector: 'app-root',
66852   *   providers: [DataProvider],
66853   *   template: `
66854   *     Live Update: <input type="checkbox" [(ngModel)]="live">
66855   *     <live-data [live]="live"><live-data>
66856   *   `,
66857   * })
66858   * class AppComponent {
66859   *   live = true;
66860   * }
66861   * ```
66862   */
66863
66864
66865  reattach() {
66866    this._lView[FLAGS] |= 64
66867    /* LViewFlags.Attached */
66868    ;
66869  }
66870  /**
66871   * Checks the view and its children.
66872   *
66873   * This can also be used in combination with {@link ChangeDetectorRef#detach detach} to implement
66874   * local change detection checks.
66875   *
66876   * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
66877   * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
66878   *
66879   * @usageNotes
66880   * ### Example
66881   *
66882   * The following example defines a component with a large list of readonly data.
66883   * Imagine, the data changes constantly, many times per second. For performance reasons,
66884   * we want to check and update the list every five seconds.
66885   *
66886   * We can do that by detaching the component's change detector and doing a local change detection
66887   * check every five seconds.
66888   *
66889   * See {@link ChangeDetectorRef#detach detach} for more information.
66890   */
66891
66892
66893  detectChanges() {
66894    detectChangesInternal(this._lView[TVIEW], this._lView, this.context);
66895  }
66896  /**
66897   * Checks the change detector and its children, and throws if any changes are detected.
66898   *
66899   * This is used in development mode to verify that running change detection doesn't
66900   * introduce other changes.
66901   */
66902
66903
66904  checkNoChanges() {
66905    if (ngDevMode) {
66906      checkNoChangesInternal(this._lView[TVIEW], this._lView, this.context);
66907    }
66908  }
66909
66910  attachToViewContainerRef() {
66911    if (this._appRef) {
66912      throw new RuntimeError(902
66913      /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */
66914      , ngDevMode && 'This view is already attached directly to the ApplicationRef!');
66915    }
66916
66917    this._attachedToViewContainer = true;
66918  }
66919
66920  detachFromAppRef() {
66921    this._appRef = null;
66922    renderDetachView(this._lView[TVIEW], this._lView);
66923  }
66924
66925  attachToAppRef(appRef) {
66926    if (this._attachedToViewContainer) {
66927      throw new RuntimeError(902
66928      /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */
66929      , ngDevMode && 'This view is already attached to a ViewContainer!');
66930    }
66931
66932    this._appRef = appRef;
66933  }
66934
66935}
66936/** @internal */
66937
66938
66939class RootViewRef extends ViewRef$1 {
66940  constructor(_view) {
66941    super(_view);
66942    this._view = _view;
66943  }
66944
66945  detectChanges() {
66946    const lView = this._view;
66947    const tView = lView[TVIEW];
66948    const context = lView[CONTEXT];
66949    detectChangesInternal(tView, lView, context, false);
66950  }
66951
66952  checkNoChanges() {
66953    if (ngDevMode) {
66954      const lView = this._view;
66955      const tView = lView[TVIEW];
66956      const context = lView[CONTEXT];
66957      checkNoChangesInternal(tView, lView, context, false);
66958    }
66959  }
66960
66961  get context() {
66962    return null;
66963  }
66964
66965}
66966/**
66967 * @license
66968 * Copyright Google LLC All Rights Reserved.
66969 *
66970 * Use of this source code is governed by an MIT-style license that can be
66971 * found in the LICENSE file at https://angular.io/license
66972 */
66973
66974
66975class ComponentFactoryResolver extends ComponentFactoryResolver$1 {
66976  /**
66977   * @param ngModule The NgModuleRef to which all resolved factories are bound.
66978   */
66979  constructor(ngModule) {
66980    super();
66981    this.ngModule = ngModule;
66982  }
66983
66984  resolveComponentFactory(component) {
66985    ngDevMode && assertComponentType(component);
66986    const componentDef = getComponentDef(component);
66987    return new ComponentFactory(componentDef, this.ngModule);
66988  }
66989
66990}
66991
66992function toRefArray(map) {
66993  const array = [];
66994
66995  for (let nonMinified in map) {
66996    if (map.hasOwnProperty(nonMinified)) {
66997      const minified = map[nonMinified];
66998      array.push({
66999        propName: minified,
67000        templateName: nonMinified
67001      });
67002    }
67003  }
67004
67005  return array;
67006}
67007
67008function getNamespace(elementName) {
67009  const name = elementName.toLowerCase();
67010  return name === 'svg' ? SVG_NAMESPACE : name === 'math' ? MATH_ML_NAMESPACE : null;
67011}
67012/**
67013 * Injector that looks up a value using a specific injector, before falling back to the module
67014 * injector. Used primarily when creating components or embedded views dynamically.
67015 */
67016
67017
67018class ChainedInjector {
67019  constructor(injector, parentInjector) {
67020    this.injector = injector;
67021    this.parentInjector = parentInjector;
67022  }
67023
67024  get(token, notFoundValue, flags) {
67025    const value = this.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, flags);
67026
67027    if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR || notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
67028      // Return the value from the root element injector when
67029      // - it provides it
67030      //   (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
67031      // - the module injector should not be checked
67032      //   (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
67033      return value;
67034    }
67035
67036    return this.parentInjector.get(token, notFoundValue, flags);
67037  }
67038
67039}
67040/**
67041 * ComponentFactory interface implementation.
67042 */
67043
67044
67045class ComponentFactory extends ComponentFactory$1 {
67046  /**
67047   * @param componentDef The component definition.
67048   * @param ngModule The NgModuleRef to which the factory is bound.
67049   */
67050  constructor(componentDef, ngModule) {
67051    super();
67052    this.componentDef = componentDef;
67053    this.ngModule = ngModule;
67054    this.componentType = componentDef.type;
67055    this.selector = stringifyCSSSelectorList(componentDef.selectors);
67056    this.ngContentSelectors = componentDef.ngContentSelectors ? componentDef.ngContentSelectors : [];
67057    this.isBoundToModule = !!ngModule;
67058  }
67059
67060  get inputs() {
67061    return toRefArray(this.componentDef.inputs);
67062  }
67063
67064  get outputs() {
67065    return toRefArray(this.componentDef.outputs);
67066  }
67067
67068  create(injector, projectableNodes, rootSelectorOrNode, environmentInjector) {
67069    environmentInjector = environmentInjector || this.ngModule;
67070    let realEnvironmentInjector = environmentInjector instanceof EnvironmentInjector ? environmentInjector : environmentInjector?.injector;
67071
67072    if (realEnvironmentInjector && this.componentDef.getStandaloneInjector !== null) {
67073      realEnvironmentInjector = this.componentDef.getStandaloneInjector(realEnvironmentInjector) || realEnvironmentInjector;
67074    }
67075
67076    const rootViewInjector = realEnvironmentInjector ? new ChainedInjector(injector, realEnvironmentInjector) : injector;
67077    const rendererFactory = rootViewInjector.get(RendererFactory2, null);
67078
67079    if (rendererFactory === null) {
67080      throw new RuntimeError(407
67081      /* RuntimeErrorCode.RENDERER_NOT_FOUND */
67082      , ngDevMode && 'Angular was not able to inject a renderer (RendererFactory2). ' + 'Likely this is due to a broken DI hierarchy. ' + 'Make sure that any injector used to create this component has a correct parent.');
67083    }
67084
67085    const sanitizer = rootViewInjector.get(Sanitizer, null);
67086    const hostRenderer = rendererFactory.createRenderer(null, this.componentDef); // Determine a tag name used for creating host elements when this component is created
67087    // dynamically. Default to 'div' if this component did not specify any tag name in its selector.
67088
67089    const elementName = this.componentDef.selectors[0][0] || 'div';
67090    const hostRNode = rootSelectorOrNode ? locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation) : createElementNode(hostRenderer, elementName, getNamespace(elementName));
67091    const rootFlags = this.componentDef.onPush ? 32
67092    /* LViewFlags.Dirty */
67093    | 256
67094    /* LViewFlags.IsRoot */
67095    : 16
67096    /* LViewFlags.CheckAlways */
67097    | 256
67098    /* LViewFlags.IsRoot */
67099    ; // Create the root view. Uses empty TView and ContentTemplate.
67100
67101    const rootTView = createTView(0
67102    /* TViewType.Root */
67103    , null, null, 1, 0, null, null, null, null, null);
67104    const rootLView = createLView(null, rootTView, null, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null); // rootView is the parent when bootstrapping
67105    // TODO(misko): it looks like we are entering view here but we don't really need to as
67106    // `renderView` does that. However as the code is written it is needed because
67107    // `createRootComponentView` and `createRootComponent` both read global state. Fixing those
67108    // issues would allow us to drop this.
67109
67110    enterView(rootLView);
67111    let component;
67112    let tElementNode;
67113
67114    try {
67115      const componentView = createRootComponentView(hostRNode, this.componentDef, rootLView, rendererFactory, hostRenderer);
67116
67117      if (hostRNode) {
67118        if (rootSelectorOrNode) {
67119          setUpAttributes(hostRenderer, hostRNode, ['ng-version', VERSION.full]);
67120        } else {
67121          // If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
67122          // is not defined), also apply attributes and classes extracted from component selector.
67123          // Extract attributes and classes from the first selector only to match VE behavior.
67124          const {
67125            attrs,
67126            classes
67127          } = extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);
67128
67129          if (attrs) {
67130            setUpAttributes(hostRenderer, hostRNode, attrs);
67131          }
67132
67133          if (classes && classes.length > 0) {
67134            writeDirectClass(hostRenderer, hostRNode, classes.join(' '));
67135          }
67136        }
67137      }
67138
67139      tElementNode = getTNode(rootTView, HEADER_OFFSET);
67140
67141      if (projectableNodes !== undefined) {
67142        const projection = tElementNode.projection = [];
67143
67144        for (let i = 0; i < this.ngContentSelectors.length; i++) {
67145          const nodesforSlot = projectableNodes[i]; // Projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade
67146          // case). Here we do normalize passed data structure to be an array of arrays to avoid
67147          // complex checks down the line.
67148          // We also normalize the length of the passed in projectable nodes (to match the number of
67149          // <ng-container> slots defined by a component).
67150
67151          projection.push(nodesforSlot != null ? Array.from(nodesforSlot) : null);
67152        }
67153      } // TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
67154      // executed here?
67155      // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
67156
67157
67158      component = createRootComponent(componentView, this.componentDef, rootLView, [LifecycleHooksFeature]);
67159      renderView(rootTView, rootLView, null);
67160    } finally {
67161      leaveView();
67162    }
67163
67164    return new ComponentRef(this.componentType, component, createElementRef(tElementNode, rootLView), rootLView, tElementNode);
67165  }
67166
67167}
67168
67169const componentFactoryResolver = new ComponentFactoryResolver();
67170/**
67171 * Creates a ComponentFactoryResolver and stores it on the injector. Or, if the
67172 * ComponentFactoryResolver
67173 * already exists, retrieves the existing ComponentFactoryResolver.
67174 *
67175 * @returns The ComponentFactoryResolver instance to use
67176 */
67177
67178function injectComponentFactoryResolver() {
67179  return componentFactoryResolver;
67180}
67181/**
67182 * Represents an instance of a Component created via a {@link ComponentFactory}.
67183 *
67184 * `ComponentRef` provides access to the Component Instance as well other objects related to this
67185 * Component Instance and allows you to destroy the Component Instance via the {@link #destroy}
67186 * method.
67187 *
67188 */
67189
67190
67191class ComponentRef extends ComponentRef$1 {
67192  constructor(componentType, instance, location, _rootLView, _tNode) {
67193    super();
67194    this.location = location;
67195    this._rootLView = _rootLView;
67196    this._tNode = _tNode;
67197    this.instance = instance;
67198    this.hostView = this.changeDetectorRef = new RootViewRef(_rootLView);
67199    this.componentType = componentType;
67200  }
67201
67202  setInput(name, value) {
67203    const inputData = this._tNode.inputs;
67204    let dataValue;
67205
67206    if (inputData !== null && (dataValue = inputData[name])) {
67207      const lView = this._rootLView;
67208      setInputsForProperty(lView[TVIEW], lView, dataValue, name, value);
67209      markDirtyIfOnPush(lView, this._tNode.index);
67210    } else {
67211      if (ngDevMode) {
67212        const cmpNameForError = stringifyForError(this.componentType);
67213        let message = `Can't set value of the '${name}' input on the '${cmpNameForError}' component. `;
67214        message += `Make sure that the '${name}' property is annotated with @Input() or a mapped @Input('${name}') exists.`;
67215        reportUnknownPropertyError(message);
67216      }
67217    }
67218  }
67219
67220  get injector() {
67221    return new NodeInjector(this._tNode, this._rootLView);
67222  }
67223
67224  destroy() {
67225    this.hostView.destroy();
67226  }
67227
67228  onDestroy(callback) {
67229    this.hostView.onDestroy(callback);
67230  }
67231
67232} // TODO: A hack to not pull in the NullInjector from @angular/core.
67233
67234
67235const NULL_INJECTOR = {
67236  get: (token, notFoundValue) => {
67237    throwProviderNotFoundError(token, 'NullInjector');
67238  }
67239};
67240/**
67241 * Creates the root component view and the root component node.
67242 *
67243 * @param rNode Render host element.
67244 * @param def ComponentDef
67245 * @param rootView The parent view where the host node is stored
67246 * @param rendererFactory Factory to be used for creating child renderers.
67247 * @param hostRenderer The current renderer
67248 * @param sanitizer The sanitizer, if provided
67249 *
67250 * @returns Component view created
67251 */
67252
67253function createRootComponentView(rNode, def, rootView, rendererFactory, hostRenderer, sanitizer) {
67254  const tView = rootView[TVIEW];
67255  const index = HEADER_OFFSET;
67256  ngDevMode && assertIndexInRange(rootView, index);
67257  rootView[index] = rNode; // '#host' is added here as we don't know the real host DOM name (we don't want to read it) and at
67258  // the same time we want to communicate the debug `TNode` that this is a special `TNode`
67259  // representing a host element.
67260
67261  const tNode = getOrCreateTNode(tView, index, 2
67262  /* TNodeType.Element */
67263  , '#host', null);
67264  const mergedAttrs = tNode.mergedAttrs = def.hostAttrs;
67265
67266  if (mergedAttrs !== null) {
67267    computeStaticStyling(tNode, mergedAttrs, true);
67268
67269    if (rNode !== null) {
67270      setUpAttributes(hostRenderer, rNode, mergedAttrs);
67271
67272      if (tNode.classes !== null) {
67273        writeDirectClass(hostRenderer, rNode, tNode.classes);
67274      }
67275
67276      if (tNode.styles !== null) {
67277        writeDirectStyle(hostRenderer, rNode, tNode.styles);
67278      }
67279    }
67280  }
67281
67282  const viewRenderer = rendererFactory.createRenderer(rNode, def);
67283  const componentView = createLView(rootView, getOrCreateComponentTView(def), null, def.onPush ? 32
67284  /* LViewFlags.Dirty */
67285  : 16
67286  /* LViewFlags.CheckAlways */
67287  , rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
67288
67289  if (tView.firstCreatePass) {
67290    diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
67291    markAsComponentHost(tView, tNode);
67292    initTNodeFlags(tNode, rootView.length, 1);
67293  }
67294
67295  addToViewTree(rootView, componentView); // Store component view at node index, with node as the HOST
67296
67297  return rootView[index] = componentView;
67298}
67299/**
67300 * Creates a root component and sets it up with features and host bindings.Shared by
67301 * renderComponent() and ViewContainerRef.createComponent().
67302 */
67303
67304
67305function createRootComponent(componentView, componentDef, rootLView, hostFeatures) {
67306  const tView = rootLView[TVIEW]; // Create directive instance with factory() and store at next index in viewData
67307
67308  const component = instantiateRootComponent(tView, rootLView, componentDef); // Root view only contains an instance of this component,
67309  // so we use a reference to that component instance as a context.
67310
67311  componentView[CONTEXT] = rootLView[CONTEXT] = component;
67312
67313  if (hostFeatures !== null) {
67314    for (const feature of hostFeatures) {
67315      feature(component, componentDef);
67316    }
67317  } // We want to generate an empty QueryList for root content queries for backwards
67318  // compatibility with ViewEngine.
67319
67320
67321  if (componentDef.contentQueries) {
67322    const tNode = getCurrentTNode();
67323    ngDevMode && assertDefined(tNode, 'TNode expected');
67324    componentDef.contentQueries(1
vendor: 23,684 bytes, lines 67325-67999
67325    /* RenderFlags.Create */
67326    , component, tNode.directiveStart);
67327  }
67328
67329  const rootTNode = getCurrentTNode();
67330  ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
67331
67332  if (tView.firstCreatePass && (componentDef.hostBindings !== null || componentDef.hostAttrs !== null)) {
67333    setSelectedIndex(rootTNode.index);
67334    const rootTView = rootLView[TVIEW];
67335    registerHostBindingOpCodes(rootTView, rootTNode, rootLView, rootTNode.directiveStart, rootTNode.directiveEnd, componentDef);
67336    invokeHostBindingsInCreationMode(componentDef, component);
67337  }
67338
67339  return component;
67340}
67341/**
67342 * Used to enable lifecycle hooks on the root component.
67343 *
67344 * Include this feature when calling `renderComponent` if the root component
67345 * you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
67346 * be called properly.
67347 *
67348 * Example:
67349 *
67350 * ```
67351 * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
67352 * ```
67353 */
67354
67355
67356function LifecycleHooksFeature() {
67357  const tNode = getCurrentTNode();
67358  ngDevMode && assertDefined(tNode, 'TNode is required');
67359  registerPostOrderHooks(getLView()[TVIEW], tNode);
67360}
67361/**
67362 * @license
67363 * Copyright Google LLC All Rights Reserved.
67364 *
67365 * Use of this source code is governed by an MIT-style license that can be
67366 * found in the LICENSE file at https://angular.io/license
67367 */
67368
67369
67370function getSuperType(type) {
67371  return Object.getPrototypeOf(type.prototype).constructor;
67372}
67373/**
67374 * Merges the definition from a super class to a sub class.
67375 * @param definition The definition that is a SubClass of another directive of component
67376 *
67377 * @codeGenApi
67378 */
67379
67380
67381function ɵɵInheritDefinitionFeature(definition) {
67382  let superType = getSuperType(definition.type);
67383  let shouldInheritFields = true;
67384  const inheritanceChain = [definition];
67385
67386  while (superType) {
67387    let superDef = undefined;
67388
67389    if (isComponentDef(definition)) {
67390      // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
67391      superDef = superType.ɵcmp || superType.ɵdir;
67392    } else {
67393      if (superType.ɵcmp) {
67394        throw new RuntimeError(903
67395        /* RuntimeErrorCode.INVALID_INHERITANCE */
67396        , ngDevMode && `Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}`);
67397      } // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
67398
67399
67400      superDef = superType.ɵdir;
67401    }
67402
67403    if (superDef) {
67404      if (shouldInheritFields) {
67405        inheritanceChain.push(superDef); // Some fields in the definition may be empty, if there were no values to put in them that
67406        // would've justified object creation. Unwrap them if necessary.
67407
67408        const writeableDef = definition;
67409        writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
67410        writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
67411        writeableDef.outputs = maybeUnwrapEmpty(definition.outputs); // Merge hostBindings
67412
67413        const superHostBindings = superDef.hostBindings;
67414        superHostBindings && inheritHostBindings(definition, superHostBindings); // Merge queries
67415
67416        const superViewQuery = superDef.viewQuery;
67417        const superContentQueries = superDef.contentQueries;
67418        superViewQuery && inheritViewQuery(definition, superViewQuery);
67419        superContentQueries && inheritContentQueries(definition, superContentQueries); // Merge inputs and outputs
67420
67421        fillProperties(definition.inputs, superDef.inputs);
67422        fillProperties(definition.declaredInputs, superDef.declaredInputs);
67423        fillProperties(definition.outputs, superDef.outputs); // Merge animations metadata.
67424        // If `superDef` is a Component, the `data` field is present (defaults to an empty object).
67425
67426        if (isComponentDef(superDef) && superDef.data.animation) {
67427          // If super def is a Component, the `definition` is also a Component, since Directives can
67428          // not inherit Components (we throw an error above and cannot reach this code).
67429          const defData = definition.data;
67430          defData.animation = (defData.animation || []).concat(superDef.data.animation);
67431        }
67432      } // Run parent features
67433
67434
67435      const features = superDef.features;
67436
67437      if (features) {
67438        for (let i = 0; i < features.length; i++) {
67439          const feature = features[i];
67440
67441          if (feature && feature.ngInherit) {
67442            feature(definition);
67443          } // If `InheritDefinitionFeature` is a part of the current `superDef`, it means that this
67444          // def already has all the necessary information inherited from its super class(es), so we
67445          // can stop merging fields from super classes. However we need to iterate through the
67446          // prototype chain to look for classes that might contain other "features" (like
67447          // NgOnChanges), which we should invoke for the original `definition`. We set the
67448          // `shouldInheritFields` flag to indicate that, essentially skipping fields inheritance
67449          // logic and only invoking functions from the "features" list.
67450
67451
67452          if (feature === ɵɵInheritDefinitionFeature) {
67453            shouldInheritFields = false;
67454          }
67455        }
67456      }
67457    }
67458
67459    superType = Object.getPrototypeOf(superType);
67460  }
67461
67462  mergeHostAttrsAcrossInheritance(inheritanceChain);
67463}
67464/**
67465 * Merge the `hostAttrs` and `hostVars` from the inherited parent to the base class.
67466 *
67467 * @param inheritanceChain A list of `WritableDefs` starting at the top most type and listing
67468 * sub-types in order. For each type take the `hostAttrs` and `hostVars` and merge it with the child
67469 * type.
67470 */
67471
67472
67473function mergeHostAttrsAcrossInheritance(inheritanceChain) {
67474  let hostVars = 0;
67475  let hostAttrs = null; // We process the inheritance order from the base to the leaves here.
67476
67477  for (let i = inheritanceChain.length - 1; i >= 0; i--) {
67478    const def = inheritanceChain[i]; // For each `hostVars`, we need to add the superclass amount.
67479
67480    def.hostVars = hostVars += def.hostVars; // for each `hostAttrs` we need to merge it with superclass.
67481
67482    def.hostAttrs = mergeHostAttrs(def.hostAttrs, hostAttrs = mergeHostAttrs(hostAttrs, def.hostAttrs));
67483  }
67484}
67485
67486function maybeUnwrapEmpty(value) {
67487  if (value === EMPTY_OBJ) {
67488    return {};
67489  } else if (value === EMPTY_ARRAY) {
67490    return [];
67491  } else {
67492    return value;
67493  }
67494}
67495
67496function inheritViewQuery(definition, superViewQuery) {
67497  const prevViewQuery = definition.viewQuery;
67498
67499  if (prevViewQuery) {
67500    definition.viewQuery = (rf, ctx) => {
67501      superViewQuery(rf, ctx);
67502      prevViewQuery(rf, ctx);
67503    };
67504  } else {
67505    definition.viewQuery = superViewQuery;
67506  }
67507}
67508
67509function inheritContentQueries(definition, superContentQueries) {
67510  const prevContentQueries = definition.contentQueries;
67511
67512  if (prevContentQueries) {
67513    definition.contentQueries = (rf, ctx, directiveIndex) => {
67514      superContentQueries(rf, ctx, directiveIndex);
67515      prevContentQueries(rf, ctx, directiveIndex);
67516    };
67517  } else {
67518    definition.contentQueries = superContentQueries;
67519  }
67520}
67521
67522function inheritHostBindings(definition, superHostBindings) {
67523  const prevHostBindings = definition.hostBindings;
67524
67525  if (prevHostBindings) {
67526    definition.hostBindings = (rf, ctx) => {
67527      superHostBindings(rf, ctx);
67528      prevHostBindings(rf, ctx);
67529    };
67530  } else {
67531    definition.hostBindings = superHostBindings;
67532  }
67533}
67534/**
67535 * @license
67536 * Copyright Google LLC All Rights Reserved.
67537 *
67538 * Use of this source code is governed by an MIT-style license that can be
67539 * found in the LICENSE file at https://angular.io/license
67540 */
67541
67542/**
67543 * Fields which exist on either directive or component definitions, and need to be copied from
67544 * parent to child classes by the `ɵɵCopyDefinitionFeature`.
67545 */
67546
67547
67548const COPY_DIRECTIVE_FIELDS = [// The child class should use the providers of its parent.
67549'providersResolver' // Not listed here are any fields which are handled by the `ɵɵInheritDefinitionFeature`, such
67550// as inputs, outputs, and host binding functions.
67551];
67552/**
67553 * Fields which exist only on component definitions, and need to be copied from parent to child
67554 * classes by the `ɵɵCopyDefinitionFeature`.
67555 *
67556 * The type here allows any field of `ComponentDef` which is not also a property of `DirectiveDef`,
67557 * since those should go in `COPY_DIRECTIVE_FIELDS` above.
67558 */
67559
67560const COPY_COMPONENT_FIELDS = [// The child class should use the template function of its parent, including all template
67561// semantics.
67562'template', 'decls', 'consts', 'vars', 'onPush', 'ngContentSelectors', // The child class should use the CSS styles of its parent, including all styling semantics.
67563'styles', 'encapsulation', // The child class should be checked by the runtime in the same way as its parent.
67564'schemas'];
67565/**
67566 * Copies the fields not handled by the `ɵɵInheritDefinitionFeature` from the supertype of a
67567 * definition.
67568 *
67569 * This exists primarily to support ngcc migration of an existing View Engine pattern, where an
67570 * entire decorator is inherited from a parent to a child class. When ngcc detects this case, it
67571 * generates a skeleton definition on the child class, and applies this feature.
67572 *
67573 * The `ɵɵCopyDefinitionFeature` then copies any needed fields from the parent class' definition,
67574 * including things like the component template function.
67575 *
67576 * @param definition The definition of a child class which inherits from a parent class with its
67577 * own definition.
67578 *
67579 * @codeGenApi
67580 */
67581
67582function ɵɵCopyDefinitionFeature(definition) {
67583  let superType = getSuperType(definition.type);
67584  let superDef = undefined;
67585
67586  if (isComponentDef(definition)) {
67587    // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
67588    superDef = superType.ɵcmp;
67589  } else {
67590    // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
67591    superDef = superType.ɵdir;
67592  } // Needed because `definition` fields are readonly.
67593
67594
67595  const defAny = definition; // Copy over any fields that apply to either directives or components.
67596
67597  for (const field of COPY_DIRECTIVE_FIELDS) {
67598    defAny[field] = superDef[field];
67599  }
67600
67601  if (isComponentDef(superDef)) {
67602    // Copy over any component-specific fields.
67603    for (const field of COPY_COMPONENT_FIELDS) {
67604      defAny[field] = superDef[field];
67605    }
67606  }
67607}
67608/**
67609 * @license
67610 * Copyright Google LLC All Rights Reserved.
67611 *
67612 * Use of this source code is governed by an MIT-style license that can be
67613 * found in the LICENSE file at https://angular.io/license
67614 */
67615
67616
67617let _symbolIterator = null;
67618
67619function getSymbolIterator() {
67620  if (!_symbolIterator) {
67621    const Symbol = _global['Symbol'];
67622
67623    if (Symbol && Symbol.iterator) {
67624      _symbolIterator = Symbol.iterator;
67625    } else {
67626      // es6-shim specific logic
67627      const keys = Object.getOwnPropertyNames(Map.prototype);
67628
67629      for (let i = 0; i < keys.length; ++i) {
67630        const key = keys[i];
67631
67632        if (key !== 'entries' && key !== 'size' && Map.prototype[key] === Map.prototype['entries']) {
67633          _symbolIterator = key;
67634        }
67635      }
67636    }
67637  }
67638
67639  return _symbolIterator;
67640}
67641/**
67642 * @license
67643 * Copyright Google LLC All Rights Reserved.
67644 *
67645 * Use of this source code is governed by an MIT-style license that can be
67646 * found in the LICENSE file at https://angular.io/license
67647 */
67648
67649
67650function isIterable(obj) {
67651  return obj !== null && typeof obj === 'object' && obj[getSymbolIterator()] !== undefined;
67652}
67653
67654function isListLikeIterable(obj) {
67655  if (!isJsObject(obj)) return false;
67656  return Array.isArray(obj) || !(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
67657  getSymbolIterator() in obj; // JS Iterable have a Symbol.iterator prop
67658}
67659
67660function areIterablesEqual(a, b, comparator) {
67661  const iterator1 = a[getSymbolIterator()]();
67662  const iterator2 = b[getSymbolIterator()]();
67663
67664  while (true) {
67665    const item1 = iterator1.next();
67666    const item2 = iterator2.next();
67667    if (item1.done && item2.done) return true;
67668    if (item1.done || item2.done) return false;
67669    if (!comparator(item1.value, item2.value)) return false;
67670  }
67671}
67672
67673function iterateListLike(obj, fn) {
67674  if (Array.isArray(obj)) {
67675    for (let i = 0; i < obj.length; i++) {
67676      fn(obj[i]);
67677    }
67678  } else {
67679    const iterator = obj[getSymbolIterator()]();
67680    let item;
67681
67682    while (!(item = iterator.next()).done) {
67683      fn(item.value);
67684    }
67685  }
67686}
67687
67688function isJsObject(o) {
67689  return o !== null && (typeof o === 'function' || typeof o === 'object');
67690}
67691/**
67692 * @license
67693 * Copyright Google LLC All Rights Reserved.
67694 *
67695 * Use of this source code is governed by an MIT-style license that can be
67696 * found in the LICENSE file at https://angular.io/license
67697 */
67698
67699
67700function devModeEqual(a, b) {
67701  const isListLikeIterableA = isListLikeIterable(a);
67702  const isListLikeIterableB = isListLikeIterable(b);
67703
67704  if (isListLikeIterableA && isListLikeIterableB) {
67705    return areIterablesEqual(a, b, devModeEqual);
67706  } else {
67707    const isAObject = a && (typeof a === 'object' || typeof a === 'function');
67708    const isBObject = b && (typeof b === 'object' || typeof b === 'function');
67709
67710    if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
67711      return true;
67712    } else {
67713      return Object.is(a, b);
67714    }
67715  }
67716}
67717/**
67718 * @license
67719 * Copyright Google LLC All Rights Reserved.
67720 *
67721 * Use of this source code is governed by an MIT-style license that can be
67722 * found in the LICENSE file at https://angular.io/license
67723 */
67724// TODO(misko): consider inlining
67725
67726/** Updates binding and returns the value. */
67727
67728
67729function updateBinding(lView, bindingIndex, value) {
67730  return lView[bindingIndex] = value;
67731}
67732/** Gets the current binding value. */
67733
67734
67735function getBinding(lView, bindingIndex) {
67736  ngDevMode && assertIndexInRange(lView, bindingIndex);
67737  ngDevMode && assertNotSame(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
67738  return lView[bindingIndex];
67739}
67740/**
67741 * Updates binding if changed, then returns whether it was updated.
67742 *
67743 * This function also checks the `CheckNoChangesMode` and throws if changes are made.
67744 * Some changes (Objects/iterables) during `CheckNoChangesMode` are exempt to comply with VE
67745 * behavior.
67746 *
67747 * @param lView current `LView`
67748 * @param bindingIndex The binding in the `LView` to check
67749 * @param value New value to check against `lView[bindingIndex]`
67750 * @returns `true` if the bindings has changed. (Throws if binding has changed during
67751 *          `CheckNoChangesMode`)
67752 */
67753
67754
67755function bindingUpdated(lView, bindingIndex, value) {
67756  ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
67757  ngDevMode && assertLessThan(bindingIndex, lView.length, `Slot should have been initialized to NO_CHANGE`);
67758  const oldValue = lView[bindingIndex];
67759
67760  if (Object.is(oldValue, value)) {
67761    return false;
67762  } else {
67763    if (ngDevMode && isInCheckNoChangesMode()) {
67764      // View engine didn't report undefined values as changed on the first checkNoChanges pass
67765      // (before the change detection was run).
67766      const oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
67767
67768      if (!devModeEqual(oldValueToCompare, value)) {
67769        const details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
67770        throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName);
67771      } // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
67772      // For this reason we exit as if no change. The early exit is needed to prevent the changed
67773      // value to be written into `LView` (If we would write the new value that we would not see it
67774      // as change on next CD.)
67775
67776
67777      return false;
67778    }
67779
67780    lView[bindingIndex] = value;
67781    return true;
67782  }
67783}
67784/** Updates 2 bindings if changed, then returns whether either was updated. */
67785
67786
67787function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
67788  const different = bindingUpdated(lView, bindingIndex, exp1);
67789  return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
67790}
67791/** Updates 3 bindings if changed, then returns whether any was updated. */
67792
67793
67794function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
67795  const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
67796  return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
67797}
67798/** Updates 4 bindings if changed, then returns whether any was updated. */
67799
67800
67801function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
67802  const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
67803  return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
67804}
67805/**
67806 * @license
67807 * Copyright Google LLC All Rights Reserved.
67808 *
67809 * Use of this source code is governed by an MIT-style license that can be
67810 * found in the LICENSE file at https://angular.io/license
67811 */
67812
67813/**
67814 * Updates the value of or removes a bound attribute on an Element.
67815 *
67816 * Used in the case of `[attr.title]="value"`
67817 *
67818 * @param name name The name of the attribute.
67819 * @param value value The attribute is removed when value is `null` or `undefined`.
67820 *                  Otherwise the attribute value is set to the stringified value.
67821 * @param sanitizer An optional function used to sanitize the value.
67822 * @param namespace Optional namespace to use when setting the attribute.
67823 *
67824 * @codeGenApi
67825 */
67826
67827
67828function ɵɵattribute(name, value, sanitizer, namespace) {
67829  const lView = getLView();
67830  const bindingIndex = nextBindingIndex();
67831
67832  if (bindingUpdated(lView, bindingIndex, value)) {
67833    const tView = getTView();
67834    const tNode = getSelectedTNode();
67835    elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace);
67836    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex);
67837  }
67838
67839  return ɵɵattribute;
67840}
67841/**
67842 * @license
67843 * Copyright Google LLC All Rights Reserved.
67844 *
67845 * Use of this source code is governed by an MIT-style license that can be
67846 * found in the LICENSE file at https://angular.io/license
67847 */
67848
67849/**
67850 * Create interpolation bindings with a variable number of expressions.
67851 *
67852 * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
67853 * Those are faster because there is no need to create an array of expressions and iterate over it.
67854 *
67855 * `values`:
67856 * - has static text at even indexes,
67857 * - has evaluated expressions at odd indexes.
67858 *
67859 * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
67860 */
67861
67862
67863function interpolationV(lView, values) {
67864  ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
67865  ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
67866  let isBindingUpdated = false;
67867  let bindingIndex = getBindingIndex();
67868
67869  for (let i = 1; i < values.length; i += 2) {
67870    // Check if bindings (odd indexes) have changed
67871    isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated;
67872  }
67873
67874  setBindingIndex(bindingIndex);
67875
67876  if (!isBindingUpdated) {
67877    return NO_CHANGE;
67878  } // Build the updated content
67879
67880
67881  let content = values[0];
67882
67883  for (let i = 1; i < values.length; i += 2) {
67884    content += renderStringify(values[i]) + values[i + 1];
67885  }
67886
67887  return content;
67888}
67889/**
67890 * Creates an interpolation binding with 1 expression.
67891 *
67892 * @param prefix static value used for concatenation only.
67893 * @param v0 value checked for change.
67894 * @param suffix static value used for concatenation only.
67895 */
67896
67897
67898function interpolation1(lView, prefix, v0, suffix) {
67899  const different = bindingUpdated(lView, nextBindingIndex(), v0);
67900  return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE;
67901}
67902/**
67903 * Creates an interpolation binding with 2 expressions.
67904 */
67905
67906
67907function interpolation2(lView, prefix, v0, i0, v1, suffix) {
67908  const bindingIndex = getBindingIndex();
67909  const different = bindingUpdated2(lView, bindingIndex, v0, v1);
67910  incrementBindingIndex(2);
67911  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE;
67912}
67913/**
67914 * Creates an interpolation binding with 3 expressions.
67915 */
67916
67917
67918function interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix) {
67919  const bindingIndex = getBindingIndex();
67920  const different = bindingUpdated3(lView, bindingIndex, v0, v1, v2);
67921  incrementBindingIndex(3);
67922  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix : NO_CHANGE;
67923}
67924/**
67925 * Create an interpolation binding with 4 expressions.
67926 */
67927
67928
67929function interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
67930  const bindingIndex = getBindingIndex();
67931  const different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
67932  incrementBindingIndex(4);
67933  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + suffix : NO_CHANGE;
67934}
67935/**
67936 * Creates an interpolation binding with 5 expressions.
67937 */
67938
67939
67940function interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
67941  const bindingIndex = getBindingIndex();
67942  let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
67943  different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
67944  incrementBindingIndex(5);
67945  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + suffix : NO_CHANGE;
67946}
67947/**
67948 * Creates an interpolation binding with 6 expressions.
67949 */
67950
67951
67952function interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
67953  const bindingIndex = getBindingIndex();
67954  let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
67955  different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
67956  incrementBindingIndex(6);
67957  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix : NO_CHANGE;
67958}
67959/**
67960 * Creates an interpolation binding with 7 expressions.
67961 */
67962
67963
67964function interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
67965  const bindingIndex = getBindingIndex();
67966  let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
67967  different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
67968  incrementBindingIndex(7);
67969  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 + renderStringify(v6) + suffix : NO_CHANGE;
67970}
67971/**
67972 * Creates an interpolation binding with 8 expressions.
67973 */
67974
67975
67976function interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
67977  const bindingIndex = getBindingIndex();
67978  let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
67979  different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
67980  incrementBindingIndex(8);
67981  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 + renderStringify(v6) + i6 + renderStringify(v7) + suffix : NO_CHANGE;
67982}
67983/**
67984 *
67985 * Update an interpolated attribute on an element with single bound value surrounded by text.
67986 *
67987 * Used when the value passed to a property has 1 interpolated value in it:
67988 *
67989 * ```html
67990 * <div attr.title="prefix{{v0}}suffix"></div>
67991 * ```
67992 *
67993 * Its compiled representation is::
67994 *
67995 * ```ts
67996 * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
67997 * ```
67998 *
67999 * @param attrName The name of the attribute to update
68000 * @param prefix Static value used for concatenation only.
68001 * @param v0 Value checked for change.
68002 * @param suffix Static value used for concatenation only.
68003 * @param sanitizer An optional sanitizer function
68004 * @returns itself, so that it may be chained.
68005 * @codeGenApi
68006 */
68007
68008
68009function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
68010  const lView = getLView();
68011  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
68012
68013  if (interpolatedValue !== NO_CHANGE) {
68014    const tNode = getSelectedTNode();
68015    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
68016    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix);
68017  }
68018
68019  return ɵɵattributeInterpolate1;
68020}
68021/**
68022 *
68023 * Update an interpolated attribute on an element with 2 bound values surrounded by text.
68024 *
68025 * Used when the value passed to a property has 2 interpolated values in it:
68026 *
68027 * ```html
68028 * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
68029 * ```
68030 *
68031 * Its compiled representation is::
68032 *
68033 * ```ts
68034 * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
68035 * ```
68036 *
68037 * @param attrName The name of the attribute to update
68038 * @param prefix Static value used for concatenation only.
68039 * @param v0 Value checked for change.
68040 * @param i0 Static value used for concatenation only.
68041 * @param v1 Value checked for change.
68042 * @param suffix Static value used for concatenation only.
68043 * @param sanitizer An optional sanitizer function
68044 * @returns itself, so that it may be chained.
68045 * @codeGenApi
68046 */
68047
68048
68049function ɵɵattributeInterpolate2(attrName, prefix, v0, i0, v1, suffix, sanitizer, namespace) {
68050  const lView = getLView();
68051  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
68052
68053  if (interpolatedValue !== NO_CHANGE) {
68054    const tNode = getSelectedTNode();
68055    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
68056    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix);
68057  }
68058
68059  return ɵɵattributeInterpolate2;
68060}
68061/**
68062 *
68063 * Update an interpolated attribute on an element with 3 bound values surrounded by text.
68064 *
68065 * Used when the value passed to a property has 3 interpolated values in it:
68066 *
68067 * ```html
68068 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
68069 * ```
68070 *
68071 * Its compiled representation is::
68072 *
68073 * ```ts
68074 * ɵɵattributeInterpolate3(
68075 * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
68076 * ```
68077 *
68078 * @param attrName The name of the attribute to update
68079 * @param prefix Static value used for concatenation only.
68080 * @param v0 Value checked for change.
68081 * @param i0 Static value used for concatenation only.
68082 * @param v1 Value checked for change.
68083 * @param i1 Static value used for concatenation only.
68084 * @param v2 Value checked for change.
68085 * @param suffix Static value used for concatenation only.
68086 * @param sanitizer An optional sanitizer function
68087 * @returns itself, so that it may be chained.
68088 * @codeGenApi
68089 */
68090
68091
68092function ɵɵattributeInterpolate3(attrName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer, namespace) {
68093  const lView = getLView();
68094  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
68095
68096  if (interpolatedValue !== NO_CHANGE) {
68097    const tNode = getSelectedTNode();
68098    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
68099    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, i1, suffix);
68100  }
68101
68102  return ɵɵattributeInterpolate3;
68103}
68104/**
68105 *
68106 * Update an interpolated attribute on an element with 4 bound values surrounded by text.
68107 *
68108 * Used when the value passed to a property has 4 interpolated values in it:
68109 *
68110 * ```html
68111 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
68112 * ```
68113 *
68114 * Its compiled representation is::
68115 *
68116 * ```ts
68117 * ɵɵattributeInterpolate4(
68118 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
68119 * ```
68120 *
68121 * @param attrName The name of the attribute to update
68122 * @param prefix Static value used for concatenation only.
68123 * @param v0 Value checked for change.
68124 * @param i0 Static value used for concatenation only.
68125 * @param v1 Value checked for change.
68126 * @param i1 Static value used for concatenation only.
68127 * @param v2 Value checked for change.
68128 * @param i2 Static value used for concatenation only.
68129 * @param v3 Value checked for change.
68130 * @param suffix Static value used for concatenation only.
68131 * @param sanitizer An optional sanitizer function
68132 * @returns itself, so that it may be chained.
68133 * @codeGenApi
68134 */
68135
68136
68137function ɵɵattributeInterpolate4(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer, namespace) {
68138  const lView = getLView();
68139  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
68140
68141  if (interpolatedValue !== NO_CHANGE) {
68142    const tNode = getSelectedTNode();
68143    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
68144    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix);
68145  }
68146
68147  return ɵɵattributeInterpolate4;
68148}
68149/**
68150 *
68151 * Update an interpolated attribute on an element with 5 bound values surrounded by text.
68152 *
68153 * Used when the value passed to a property has 5 interpolated values in it:
68154 *
68155 * ```html
68156 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
68157 * ```
68158 *
68159 * Its compiled representation is::
68160 *
68161 * ```ts
68162 * ɵɵattributeInterpolate5(
68163 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
68164 * ```
68165 *
68166 * @param attrName The name of the attribute to update
68167 * @param prefix Static value used for concatenation only.
68168 * @param v0 Value checked for change.
68169 * @param i0 Static value used for concatenation only.
68170 * @param v1 Value checked for change.
68171 * @param i1 Static value used for concatenation only.
68172 * @param v2 Value checked for change.
68173 * @param i2 Static value used for concatenation only.
68174 * @param v3 Value checked for change.
68175 * @param i3 Static value used for concatenation only.
68176 * @param v4 Value checked for change.
68177 * @param suffix Static value used for concatenation only.
68178 * @param sanitizer An optional sanitizer function
68179 * @returns itself, so that it may be chained.
68180 * @codeGenApi
68181 */
68182
68183
68184function ɵɵattributeInterpolate5(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer, namespace) {
68185  const lView = getLView();
68186  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
68187
68188  if (interpolatedValue !== NO_CHANGE) {
68189    const tNode = getSelectedTNode();
68190    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
68191    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix);
68192  }
68193
68194  return ɵɵattributeInterpolate5;
68195}
68196/**
68197 *
68198 * Update an interpolated attribute on an element with 6 bound values surrounded by text.
68199 *
68200 * Used when the value passed to a property has 6 interpolated values in it:
68201 *
68202 * ```html
68203 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
68204 * ```
68205 *
68206 * Its compiled representation is::
68207 *
68208 * ```ts
68209 * ɵɵattributeInterpolate6(
68210 *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
68211 * ```
68212 *
68213 * @param attrName The name of the attribute to update
68214 * @param prefix Static value used for concatenation only.
68215 * @param v0 Value checked for change.
68216 * @param i0 Static value used for concatenation only.
68217 * @param v1 Value checked for change.
68218 * @param i1 Static value used for concatenation only.
68219 * @param v2 Value checked for change.
68220 * @param i2 Static value used for concatenation only.
68221 * @param v3 Value checked for change.
68222 * @param i3 Static value used for concatenation only.
68223 * @param v4 Value checked for change.
68224 * @param i4 Static value used for concatenation only.
68225 * @param v5 Value checked for change.
68226 * @param suffix Static value used for concatenation only.
68227 * @param sanitizer An optional sanitizer function
68228 * @returns itself, so that it may be chained.
68229 * @codeGenApi
68230 */
68231
68232
68233function ɵɵattributeInterpolate6(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer, namespace) {
68234  const lView = getLView();
68235  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
68236
68237  if (interpolatedValue !== NO_CHANGE) {
68238    const tNode = getSelectedTNode();
68239    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
68240    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix
vendor: 13,750 bytes, lines 68240-68624
68240);
68241  }
68242
68243  return ɵɵattributeInterpolate6;
68244}
68245/**
68246 *
68247 * Update an interpolated attribute on an element with 7 bound values surrounded by text.
68248 *
68249 * Used when the value passed to a property has 7 interpolated values in it:
68250 *
68251 * ```html
68252 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
68253 * ```
68254 *
68255 * Its compiled representation is::
68256 *
68257 * ```ts
68258 * ɵɵattributeInterpolate7(
68259 *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
68260 * ```
68261 *
68262 * @param attrName The name of the attribute to update
68263 * @param prefix Static value used for concatenation only.
68264 * @param v0 Value checked for change.
68265 * @param i0 Static value used for concatenation only.
68266 * @param v1 Value checked for change.
68267 * @param i1 Static value used for concatenation only.
68268 * @param v2 Value checked for change.
68269 * @param i2 Static value used for concatenation only.
68270 * @param v3 Value checked for change.
68271 * @param i3 Static value used for concatenation only.
68272 * @param v4 Value checked for change.
68273 * @param i4 Static value used for concatenation only.
68274 * @param v5 Value checked for change.
68275 * @param i5 Static value used for concatenation only.
68276 * @param v6 Value checked for change.
68277 * @param suffix Static value used for concatenation only.
68278 * @param sanitizer An optional sanitizer function
68279 * @returns itself, so that it may be chained.
68280 * @codeGenApi
68281 */
68282
68283
68284function ɵɵattributeInterpolate7(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer, namespace) {
68285  const lView = getLView();
68286  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
68287
68288  if (interpolatedValue !== NO_CHANGE) {
68289    const tNode = getSelectedTNode();
68290    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
68291    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, i5, suffix);
68292  }
68293
68294  return ɵɵattributeInterpolate7;
68295}
68296/**
68297 *
68298 * Update an interpolated attribute on an element with 8 bound values surrounded by text.
68299 *
68300 * Used when the value passed to a property has 8 interpolated values in it:
68301 *
68302 * ```html
68303 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
68304 * ```
68305 *
68306 * Its compiled representation is::
68307 *
68308 * ```ts
68309 * ɵɵattributeInterpolate8(
68310 *  'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
68311 * ```
68312 *
68313 * @param attrName The name of the attribute to update
68314 * @param prefix Static value used for concatenation only.
68315 * @param v0 Value checked for change.
68316 * @param i0 Static value used for concatenation only.
68317 * @param v1 Value checked for change.
68318 * @param i1 Static value used for concatenation only.
68319 * @param v2 Value checked for change.
68320 * @param i2 Static value used for concatenation only.
68321 * @param v3 Value checked for change.
68322 * @param i3 Static value used for concatenation only.
68323 * @param v4 Value checked for change.
68324 * @param i4 Static value used for concatenation only.
68325 * @param v5 Value checked for change.
68326 * @param i5 Static value used for concatenation only.
68327 * @param v6 Value checked for change.
68328 * @param i6 Static value used for concatenation only.
68329 * @param v7 Value checked for change.
68330 * @param suffix Static value used for concatenation only.
68331 * @param sanitizer An optional sanitizer function
68332 * @returns itself, so that it may be chained.
68333 * @codeGenApi
68334 */
68335
68336
68337function ɵɵattributeInterpolate8(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer, namespace) {
68338  const lView = getLView();
68339  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
68340
68341  if (interpolatedValue !== NO_CHANGE) {
68342    const tNode = getSelectedTNode();
68343    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
68344    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, i5, i6, suffix);
68345  }
68346
68347  return ɵɵattributeInterpolate8;
68348}
68349/**
68350 * Update an interpolated attribute on an element with 9 or more bound values surrounded by text.
68351 *
68352 * Used when the number of interpolated values exceeds 8.
68353 *
68354 * ```html
68355 * <div
68356 *  title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
68357 * ```
68358 *
68359 * Its compiled representation is::
68360 *
68361 * ```ts
68362 * ɵɵattributeInterpolateV(
68363 *  'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
68364 *  'suffix']);
68365 * ```
68366 *
68367 * @param attrName The name of the attribute to update.
68368 * @param values The collection of values and the strings in-between those values, beginning with
68369 * a string prefix and ending with a string suffix.
68370 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
68371 * @param sanitizer An optional sanitizer function
68372 * @returns itself, so that it may be chained.
68373 * @codeGenApi
68374 */
68375
68376
68377function ɵɵattributeInterpolateV(attrName, values, sanitizer, namespace) {
68378  const lView = getLView();
68379  const interpolated = interpolationV(lView, values);
68380
68381  if (interpolated !== NO_CHANGE) {
68382    const tNode = getSelectedTNode();
68383    elementAttributeInternal(tNode, lView, attrName, interpolated, sanitizer, namespace);
68384
68385    if (ngDevMode) {
68386      const interpolationInBetween = [values[0]]; // prefix
68387
68388      for (let i = 2; i < values.length; i += 2) {
68389        interpolationInBetween.push(values[i]);
68390      }
68391
68392      storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween);
68393    }
68394  }
68395
68396  return ɵɵattributeInterpolateV;
68397}
68398/**
68399 * @license
68400 * Copyright Google LLC All Rights Reserved.
68401 *
68402 * Use of this source code is governed by an MIT-style license that can be
68403 * found in the LICENSE file at https://angular.io/license
68404 */
68405
68406/**
68407 * Synchronously perform change detection on a component (and possibly its sub-components).
68408 *
68409 * This function triggers change detection in a synchronous way on a component.
68410 *
68411 * @param component The component which the change detection should be performed on.
68412 */
68413
68414
68415function detectChanges(component) {
68416  const view = getComponentViewByInstance(component);
68417  detectChangesInternal(view[TVIEW], view, component);
68418}
68419/**
68420 * @license
68421 * Copyright Google LLC All Rights Reserved.
68422 *
68423 * Use of this source code is governed by an MIT-style license that can be
68424 * found in the LICENSE file at https://angular.io/license
68425 */
68426
68427
68428function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) {
68429  ngDevMode && assertFirstCreatePass(tView);
68430  ngDevMode && ngDevMode.firstCreatePass++;
68431  const tViewConsts = tView.consts; // TODO(pk): refactor getOrCreateTNode to have the "create" only version
68432
68433  const tNode = getOrCreateTNode(tView, index, 4
68434  /* TNodeType.Container */
68435  , tagName || null, getConstant(tViewConsts, attrsIndex));
68436  resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
68437  registerPostOrderHooks(tView, tNode);
68438  const embeddedTView = tNode.tViews = createTView(2
68439  /* TViewType.Embedded */
68440  , tNode, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts);
68441
68442  if (tView.queries !== null) {
68443    tView.queries.template(tView, tNode);
68444    embeddedTView.queries = tView.queries.embeddedTView(tNode);
68445  }
68446
68447  return tNode;
68448}
68449/**
68450 * Creates an LContainer for an ng-template (dynamically-inserted view), e.g.
68451 *
68452 * <ng-template #foo>
68453 *    <div></div>
68454 * </ng-template>
68455 *
68456 * @param index The index of the container in the data array
68457 * @param templateFn Inline template
68458 * @param decls The number of nodes, local refs, and pipes for this template
68459 * @param vars The number of bindings for this template
68460 * @param tagName The name of the container element, if applicable
68461 * @param attrsIndex Index of template attributes in the `consts` array.
68462 * @param localRefs Index of the local references in the `consts` array.
68463 * @param localRefExtractor A function which extracts local-refs values from the template.
68464 *        Defaults to the current element associated with the local-ref.
68465 *
68466 * @codeGenApi
68467 */
68468
68469
68470function ɵɵtemplate(index, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex, localRefExtractor) {
68471  const lView = getLView();
68472  const tView = getTView();
68473  const adjustedIndex = index + HEADER_OFFSET;
68474  const tNode = tView.firstCreatePass ? templateFirstCreatePass(adjustedIndex, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) : tView.data[adjustedIndex];
68475  setCurrentTNode(tNode, false);
68476  const comment = lView[RENDERER].createComment(ngDevMode ? 'container' : '');
68477  appendChild(tView, lView, comment, tNode);
68478  attachPatchData(comment, lView);
68479  addToViewTree(lView, lView[adjustedIndex] = createLContainer(comment, lView, comment, tNode));
68480
68481  if (isDirectiveHost(tNode)) {
68482    createDirectivesInstances(tView, lView, tNode);
68483  }
68484
68485  if (localRefsIndex != null) {
68486    saveResolvedLocalsInData(lView, tNode, localRefExtractor);
68487  }
68488}
68489/**
68490 * @license
68491 * Copyright Google LLC All Rights Reserved.
68492 *
68493 * Use of this source code is governed by an MIT-style license that can be
68494 * found in the LICENSE file at https://angular.io/license
68495 */
68496
68497/** Store a value in the `data` at a given `index`. */
68498
68499
68500function store(tView, lView, index, value) {
68501  // We don't store any static data for local variables, so the first time
68502  // we see the template, we should store as null to avoid a sparse array
68503  if (index >= tView.data.length) {
68504    tView.data[index] = null;
68505    tView.blueprint[index] = null;
68506  }
68507
68508  lView[index] = value;
68509}
68510/**
68511 * Retrieves a local reference from the current contextViewData.
68512 *
68513 * If the reference to retrieve is in a parent view, this instruction is used in conjunction
68514 * with a nextContext() call, which walks up the tree and updates the contextViewData instance.
68515 *
68516 * @param index The index of the local ref in contextViewData.
68517 *
68518 * @codeGenApi
68519 */
68520
68521
68522function ɵɵreference(index) {
68523  const contextLView = getContextLView();
68524  return load(contextLView, HEADER_OFFSET + index);
68525}
68526/**
68527 * @license
68528 * Copyright Google LLC All Rights Reserved.
68529 *
68530 * Use of this source code is governed by an MIT-style license that can be
68531 * found in the LICENSE file at https://angular.io/license
68532 */
68533
68534/**
68535 * Update a property on a selected element.
68536 *
68537 * Operates on the element selected by index via the {@link select} instruction.
68538 *
68539 * If the property name also exists as an input property on one of the element's directives,
68540 * the component property will be set instead of the element property. This check must
68541 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled
68542 *
68543 * @param propName Name of property. Because it is going to DOM, this is not subject to
68544 *        renaming as part of minification.
68545 * @param value New value to write.
68546 * @param sanitizer An optional function used to sanitize the value.
68547 * @returns This function returns itself so that it may be chained
68548 * (e.g. `property('name', ctx.name)('title', ctx.title)`)
68549 *
68550 * @codeGenApi
68551 */
68552
68553
68554function ɵɵproperty(propName, value, sanitizer) {
68555  const lView = getLView();
68556  const bindingIndex = nextBindingIndex();
68557
68558  if (bindingUpdated(lView, bindingIndex, value)) {
68559    const tView = getTView();
68560    const tNode = getSelectedTNode();
68561    elementPropertyInternal(tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, false);
68562    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
68563  }
68564
68565  return ɵɵproperty;
68566}
68567/**
68568 * Given `<div style="..." my-dir>` and `MyDir` with `@Input('style')` we need to write to
68569 * directive input.
68570 */
68571
68572
68573function setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isClassBased) {
68574  const inputs = tNode.inputs;
68575  const property = isClassBased ? 'class' : 'style'; // We support both 'class' and `className` hence the fallback.
68576
68577  setInputsForProperty(tView, lView, inputs[property], property, value);
68578}
68579/**
68580 * @license
68581 * Copyright Google LLC All Rights Reserved.
68582 *
68583 * Use of this source code is governed by an MIT-style license that can be
68584 * found in the LICENSE file at https://angular.io/license
68585 */
68586
68587
68588function elementStartFirstCreatePass(index, tView, lView, native, name, attrsIndex, localRefsIndex) {
68589  ngDevMode && assertFirstCreatePass(tView);
68590  ngDevMode && ngDevMode.firstCreatePass++;
68591  const tViewConsts = tView.consts;
68592  const attrs = getConstant(tViewConsts, attrsIndex);
68593  const tNode = getOrCreateTNode(tView, index, 2
68594  /* TNodeType.Element */
68595  , name, attrs);
68596  const hasDirectives = resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
68597
68598  if (ngDevMode) {
68599    validateElementIsKnown(native, lView, tNode.value, tView.schemas, hasDirectives);
68600  }
68601
68602  if (tNode.attrs !== null) {
68603    computeStaticStyling(tNode, tNode.attrs, false);
68604  }
68605
68606  if (tNode.mergedAttrs !== null) {
68607    computeStaticStyling(tNode, tNode.mergedAttrs, true);
68608  }
68609
68610  if (tView.queries !== null) {
68611    tView.queries.elementStart(tView, tNode);
68612  }
68613
68614  return tNode;
68615}
68616/**
68617 * Create DOM element. The instruction must later be followed by `elementEnd()` call.
68618 *
68619 * @param index Index of the element in the LView array
68620 * @param name Name of the DOM Node
68621 * @param attrsIndex Index of the element's attributes in the `consts` array.
68622 * @param localRefsIndex Index of the element's local references in the `consts` array.
68623 * @returns This function returns itself so that it may be chained.
68624 *
68625 * Attributes and localRefs are passed as an array of strings where elements with an even index
68626 * hold an attribute name and elements with an odd index hold an attribute value, ex.:
68627 * ['id', 'warning5', 'class', 'alert']
68628 *
68629 * @codeGenApi
68630 */
68631
68632
68633function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
68634  const lView = getLView();
68635  const tView = getTView();
68636  const adjustedIndex = HEADER_OFFSET + index;
68637  ngDevMode && assertEqual(getBindingIndex(), tView.bindingStartIndex, 'elements should be created before any bindings');
68638  ngDevMode && assertIndexInRange(lView, adjustedIndex);
68639  const renderer = lView[RENDERER];
68640  const native = lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1());
68641  const tNode = tView.firstCreatePass ? elementStartFirstCreatePass(adjustedIndex, tView, lView, native, name, attrsIndex, localRefsIndex) : tView.data[adjustedIndex];
68642  setCurrentTNode(tNode, true);
68643  const mergedAttrs = tNode.mergedAttrs;
68644
68645  if (mergedAttrs !== null) {
68646    setUpAttributes(renderer, native, mergedAttrs);
68647  }
68648
68649  const classes = tNode.classes;
68650
68651  if (classes !== null) {
68652    writeDirectClass(renderer, native, classes);
68653  }
68654
68655  const styles = tNode.styles;
68656
68657  if (styles !== null) {
68658    writeDirectStyle(renderer, native, styles);
68659  }
68660
68661  if ((tNode.flags & 64
68662  /* TNodeFlags.isDetached */
68663  ) !== 64
68664  /* TNodeFlags.isDetached */
68665  ) {
68666    // In the i18n case, the translation may have removed this element, so only add it if it is not
68667    // detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
68668    appendChild(tView, lView, native, tNode);
68669  } // any immediate children of a component or template container must be pre-emptively
68670  // monkey-patched with the component view data so that the element can be inspected
68671  // later on using any element discovery utility methods (see `element_discovery.ts`)
68672
68673
68674  if (getElementDepthCount() === 0) {
68675    attachPatchData(native, lView);
68676  }
68677
68678  increaseElementDepthCount();
68679
68680  if (isDirectiveHost(tNode)) {
68681    createDirectivesInstances(tView, lView, tNode);
68682    executeContentQueries(tView, tNode, lView);
68683  }
68684
68685  if (localRefsIndex !== null) {
68686    saveResolvedLocalsInData(lView, tNode);
68687  }
68688
68689  return ɵɵelementStart;
68690}
68691/**
68692 * Mark the end of the element.
68693 * @returns This function returns itself so that it may be chained.
68694 *
68695 * @codeGenApi
68696 */
68697
68698
68699function ɵɵelementEnd() {
68700  let currentTNode = getCurrentTNode();
68701  ngDevMode && assertDefined(currentTNode, 'No parent node to close.');
68702
68703  if (isCurrentTNodeParent()) {
68704    setCurrentTNodeAsNotParent();
68705  } else {
68706    ngDevMode && assertHasParent(getCurrentTNode());
68707    currentTNode = currentTNode.parent;
68708    setCurrentTNode(currentTNode, false);
68709  }
68710
68711  const tNode = currentTNode;
68712  ngDevMode && assertTNodeType(tNode, 3
68713  /* TNodeType.AnyRNode */
68714  );
68715  decreaseElementDepthCount();
68716  const tView = getTView();
68717
68718  if (tView.firstCreatePass) {
68719    registerPostOrderHooks(tView, currentTNode);
68720
68721    if (isContentQueryHost(currentTNode)) {
68722      tView.queries.elementEnd(currentTNode);
68723    }
68724  }
68725
68726  if (tNode.classesWithoutHost != null && hasClassInput(tNode)) {
68727    setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.classesWithoutHost, true);
68728  }
68729
68730  if (tNode.stylesWithoutHost != null && hasStyleInput(tNode)) {
68731    setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.stylesWithoutHost, false);
68732  }
68733
68734  return ɵɵelementEnd;
68735}
68736/**
68737 * Creates an empty element using {@link elementStart} and {@link elementEnd}
68738 *
68739 * @param index Index of the element in the data array
68740 * @param name Name of the DOM Node
68741 * @param attrsIndex Index of the element's attributes in the `consts` array.
68742 * @param localRefsIndex Index of the element's local references in the `consts` array.
68743 * @returns This function returns itself so that it may be chained.
68744 *
68745 * @codeGenApi
68746 */
68747
68748
68749function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
68750  ɵɵelementStart(index, name, attrsIndex, localRefsIndex);
68751  ɵɵelementEnd();
68752  return ɵɵelement;
68753}
68754/**
68755 * @license
68756 * Copyright Google LLC All Rights Reserved.
68757 *
68758 * Use of this source code is governed by an MIT-style license that can be
68759 * found in the LICENSE file at https://angular.io/license
68760 */
68761
68762
68763function elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, localRefsIndex) {
68764  ngDevMode && ngDevMode.firstCreatePass++;
68765  const tViewConsts = tView.consts;
68766  const attrs = getConstant(tViewConsts, attrsIndex);
68767  const tNode = getOrCreateTNode(tView, index, 8
68768  /* TNodeType.ElementContainer */
68769  , 'ng-container', attrs); // While ng-container doesn't necessarily support styling, we use the style context to identify
68770  // and execute directives on the ng-container.
68771
68772  if (attrs !== null) {
68773    computeStaticStyling(tNode, attrs, true);
68774  }
68775
68776  const localRefs = getConstant(tViewConsts, localRefsIndex);
68777  resolveDirectives(tView, lView, tNode, localRefs);
68778
68779  if (tView.queries !== null) {
68780    tView.queries.elementStart(tView, tNode);
68781  }
68782
68783  return tNode;
68784}
68785/**
68786 * Creates a logical container for other nodes (<ng-container>) backed by a comment node in the DOM.
68787 * The instruction must later be followed by `elementContainerEnd()` call.
68788 *
68789 * @param index Index of the element in the LView array
68790 * @param attrsIndex Index of the container attributes in the `consts` array.
68791 * @param localRefsIndex Index of the container's local references in the `consts` array.
68792 * @returns This function returns itself so that it may be chained.
68793 *
68794 * Even if this instruction accepts a set of attributes no actual attribute values are propagated to
68795 * the DOM (as a comment node can't have attributes). Attributes are here only for directive
68796 * matching purposes and setting initial inputs of directives.
68797 *
68798 * @codeGenApi
68799 */
68800
68801
68802function ɵɵelementContainerStart(index, attrsIndex, localRefsIndex) {
68803  const lView = getLView();
68804  const tView = getTView();
68805  const adjustedIndex = index + HEADER_OFFSET;
68806  ngDevMode && assertIndexInRange(lView, adjustedIndex);
68807  ngDevMode && assertEqual(getBindingIndex(), tView.bindingStartIndex, 'element containers should be created before any bindings');
68808  const tNode = tView.firstCreatePass ? elementContainerStartFirstCreatePass(adjustedIndex, tView, lView, attrsIndex, localRefsIndex) : tView.data[adjustedIndex];
68809  setCurrentTNode(tNode, true);
68810  ngDevMode && ngDevMode.rendererCreateComment++;
68811  const native = lView[adjustedIndex] = lView[RENDERER].createComment(ngDevMode ? 'ng-container' : '');
68812  appendChild(tView, lView, native, tNode);
vendor: 15,556 bytes, lines 68813-69216
68813  attachPatchData(native, lView);
68814
68815  if (isDirectiveHost(tNode)) {
68816    createDirectivesInstances(tView, lView, tNode);
68817    executeContentQueries(tView, tNode, lView);
68818  }
68819
68820  if (localRefsIndex != null) {
68821    saveResolvedLocalsInData(lView, tNode);
68822  }
68823
68824  return ɵɵelementContainerStart;
68825}
68826/**
68827 * Mark the end of the <ng-container>.
68828 * @returns This function returns itself so that it may be chained.
68829 *
68830 * @codeGenApi
68831 */
68832
68833
68834function ɵɵelementContainerEnd() {
68835  let currentTNode = getCurrentTNode();
68836  const tView = getTView();
68837
68838  if (isCurrentTNodeParent()) {
68839    setCurrentTNodeAsNotParent();
68840  } else {
68841    ngDevMode && assertHasParent(currentTNode);
68842    currentTNode = currentTNode.parent;
68843    setCurrentTNode(currentTNode, false);
68844  }
68845
68846  ngDevMode && assertTNodeType(currentTNode, 8
68847  /* TNodeType.ElementContainer */
68848  );
68849
68850  if (tView.firstCreatePass) {
68851    registerPostOrderHooks(tView, currentTNode);
68852
68853    if (isContentQueryHost(currentTNode)) {
68854      tView.queries.elementEnd(currentTNode);
68855    }
68856  }
68857
68858  return ɵɵelementContainerEnd;
68859}
68860/**
68861 * Creates an empty logical container using {@link elementContainerStart}
68862 * and {@link elementContainerEnd}
68863 *
68864 * @param index Index of the element in the LView array
68865 * @param attrsIndex Index of the container attributes in the `consts` array.
68866 * @param localRefsIndex Index of the container's local references in the `consts` array.
68867 * @returns This function returns itself so that it may be chained.
68868 *
68869 * @codeGenApi
68870 */
68871
68872
68873function ɵɵelementContainer(index, attrsIndex, localRefsIndex) {
68874  ɵɵelementContainerStart(index, attrsIndex, localRefsIndex);
68875  ɵɵelementContainerEnd();
68876  return ɵɵelementContainer;
68877}
68878/**
68879 * Returns the current OpaqueViewState instance.
68880 *
68881 * Used in conjunction with the restoreView() instruction to save a snapshot
68882 * of the current view and restore it when listeners are invoked. This allows
68883 * walking the declaration view tree in listeners to get vars from parent views.
68884 *
68885 * @codeGenApi
68886 */
68887
68888
68889function ɵɵgetCurrentView() {
68890  return getLView();
68891}
68892/**
68893 * @license
68894 * Copyright Google LLC All Rights Reserved.
68895 *
68896 * Use of this source code is governed by an MIT-style license that can be
68897 * found in the LICENSE file at https://angular.io/license
68898 */
68899
68900/**
68901 * Determine if the argument is shaped like a Promise
68902 */
68903
68904
68905function isPromise(obj) {
68906  // allow any Promise/A+ compliant thenable.
68907  // It's up to the caller to ensure that obj.then conforms to the spec
68908  return !!obj && typeof obj.then === 'function';
68909}
68910/**
68911 * Determine if the argument is a Subscribable
68912 */
68913
68914
68915function isSubscribable(obj) {
68916  return !!obj && typeof obj.subscribe === 'function';
68917}
68918/**
68919 * Determine if the argument is an Observable
68920 *
68921 * Strictly this tests that the `obj` is `Subscribable`, since `Observable`
68922 * types need additional methods, such as `lift()`. But it is adequate for our
68923 * needs since within the Angular framework code we only ever need to use the
68924 * `subscribe()` method, and RxJS has mechanisms to wrap `Subscribable` objects
68925 * into `Observable` as needed.
68926 */
68927
68928
68929const isObservable = isSubscribable;
68930/**
68931 * @license
68932 * Copyright Google LLC All Rights Reserved.
68933 *
68934 * Use of this source code is governed by an MIT-style license that can be
68935 * found in the LICENSE file at https://angular.io/license
68936 */
68937
68938/**
68939 * Adds an event listener to the current node.
68940 *
68941 * If an output exists on one of the node's directives, it also subscribes to the output
68942 * and saves the subscription for later cleanup.
68943 *
68944 * @param eventName Name of the event
68945 * @param listenerFn The function to be called when event emits
68946 * @param useCapture Whether or not to use capture in event listener
68947 * @param eventTargetResolver Function that returns global target information in case this listener
68948 * should be attached to a global object like window, document or body
68949 *
68950 * @codeGenApi
68951 */
68952
68953function ɵɵlistener(eventName, listenerFn, useCapture, eventTargetResolver) {
68954  const lView = getLView();
68955  const tView = getTView();
68956  const tNode = getCurrentTNode();
68957  listenerInternal(tView, lView, lView[RENDERER], tNode, eventName, listenerFn, !!useCapture, eventTargetResolver);
68958  return ɵɵlistener;
68959}
68960/**
68961 * Registers a synthetic host listener (e.g. `(@foo.start)`) on a component or directive.
68962 *
68963 * This instruction is for compatibility purposes and is designed to ensure that a
68964 * synthetic host listener (e.g. `@HostListener('@foo.start')`) properly gets rendered
68965 * in the component's renderer. Normally all host listeners are evaluated with the
68966 * parent component's renderer, but, in the case of animation @triggers, they need
68967 * to be evaluated with the sub component's renderer (because that's where the
68968 * animation triggers are defined).
68969 *
68970 * Do not use this instruction as a replacement for `listener`. This instruction
68971 * only exists to ensure compatibility with the ViewEngine's host binding behavior.
68972 *
68973 * @param eventName Name of the event
68974 * @param listenerFn The function to be called when event emits
68975 * @param useCapture Whether or not to use capture in event listener
68976 * @param eventTargetResolver Function that returns global target information in case this listener
68977 * should be attached to a global object like window, document or body
68978 *
68979 * @codeGenApi
68980 */
68981
68982
68983function ɵɵsyntheticHostListener(eventName, listenerFn) {
68984  const tNode = getCurrentTNode();
68985  const lView = getLView();
68986  const tView = getTView();
68987  const currentDef = getCurrentDirectiveDef(tView.data);
68988  const renderer = loadComponentRenderer(currentDef, tNode, lView);
68989  listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn, false);
68990  return ɵɵsyntheticHostListener;
68991}
68992/**
68993 * A utility function that checks if a given element has already an event handler registered for an
68994 * event with a specified name. The TView.cleanup data structure is used to find out which events
68995 * are registered for a given element.
68996 */
68997
68998
68999function findExistingListener(tView, lView, eventName, tNodeIdx) {
69000  const tCleanup = tView.cleanup;
69001
69002  if (tCleanup != null) {
69003    for (let i = 0; i < tCleanup.length - 1; i += 2) {
69004      const cleanupEventName = tCleanup[i];
69005
69006      if (cleanupEventName === eventName && tCleanup[i + 1] === tNodeIdx) {
69007        // We have found a matching event name on the same node but it might not have been
69008        // registered yet, so we must explicitly verify entries in the LView cleanup data
69009        // structures.
69010        const lCleanup = lView[CLEANUP];
69011        const listenerIdxInLCleanup = tCleanup[i + 2];
69012        return lCleanup.length > listenerIdxInLCleanup ? lCleanup[listenerIdxInLCleanup] : null;
69013      } // TView.cleanup can have a mix of 4-elements entries (for event handler cleanups) or
69014      // 2-element entries (for directive and queries destroy hooks). As such we can encounter
69015      // blocks of 4 or 2 items in the tView.cleanup and this is why we iterate over 2 elements
69016      // first and jump another 2 elements if we detect listeners cleanup (4 elements). Also check
69017      // documentation of TView.cleanup for more details of this data structure layout.
69018
69019
69020      if (typeof cleanupEventName === 'string') {
69021        i += 2;
69022      }
69023    }
69024  }
69025
69026  return null;
69027}
69028
69029function listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn, useCapture, eventTargetResolver) {
69030  const isTNodeDirectiveHost = isDirectiveHost(tNode);
69031  const firstCreatePass = tView.firstCreatePass;
69032  const tCleanup = firstCreatePass && getOrCreateTViewCleanup(tView);
69033  const context = lView[CONTEXT]; // When the ɵɵlistener instruction was generated and is executed we know that there is either a
69034  // native listener or a directive output on this element. As such we we know that we will have to
69035  // register a listener and store its cleanup function on LView.
69036
69037  const lCleanup = getOrCreateLViewCleanup(lView);
69038  ngDevMode && assertTNodeType(tNode, 3
69039  /* TNodeType.AnyRNode */
69040  | 12
69041  /* TNodeType.AnyContainer */
69042  );
69043  let processOutputs = true; // Adding a native event listener is applicable when:
69044  // - The corresponding TNode represents a DOM element.
69045  // - The event target has a resolver (usually resulting in a global object,
69046  //   such as `window` or `document`).
69047
69048  if (tNode.type & 3
69049  /* TNodeType.AnyRNode */
69050  || eventTargetResolver) {
69051    const native = getNativeByTNode(tNode, lView);
69052    const target = eventTargetResolver ? eventTargetResolver(native) : native;
69053    const lCleanupIndex = lCleanup.length;
69054    const idxOrTargetGetter = eventTargetResolver ? _lView => eventTargetResolver(unwrapRNode(_lView[tNode.index])) : tNode.index; // In order to match current behavior, native DOM event listeners must be added for all
69055    // events (including outputs).
69056    // There might be cases where multiple directives on the same element try to register an event
69057    // handler function for the same event. In this situation we want to avoid registration of
69058    // several native listeners as each registration would be intercepted by NgZone and
69059    // trigger change detection. This would mean that a single user action would result in several
69060    // change detections being invoked. To avoid this situation we want to have only one call to
69061    // native handler registration (for the same element and same type of event).
69062    //
69063    // In order to have just one native event handler in presence of multiple handler functions,
69064    // we just register a first handler function as a native event listener and then chain
69065    // (coalesce) other handler functions on top of the first native handler function.
69066
69067    let existingListener = null; // Please note that the coalescing described here doesn't happen for events specifying an
69068    // alternative target (ex. (document:click)) - this is to keep backward compatibility with the
69069    // view engine.
69070    // Also, we don't have to search for existing listeners is there are no directives
69071    // matching on a given node as we can't register multiple event handlers for the same event in
69072    // a template (this would mean having duplicate attributes).
69073
69074    if (!eventTargetResolver && isTNodeDirectiveHost) {
69075      existingListener = findExistingListener(tView, lView, eventName, tNode.index);
69076    }
69077
69078    if (existingListener !== null) {
69079      // Attach a new listener to coalesced listeners list, maintaining the order in which
69080      // listeners are registered. For performance reasons, we keep a reference to the last
69081      // listener in that list (in `__ngLastListenerFn__` field), so we can avoid going through
69082      // the entire set each time we need to add a new listener.
69083      const lastListenerFn = existingListener.__ngLastListenerFn__ || existingListener;
69084      lastListenerFn.__ngNextListenerFn__ = listenerFn;
69085      existingListener.__ngLastListenerFn__ = listenerFn;
69086      processOutputs = false;
69087    } else {
69088      listenerFn = wrapListener(tNode, lView, context, listenerFn, false
69089      /** preventDefault */
69090      );
69091      const cleanupFn = renderer.listen(target, eventName, listenerFn);
69092      ngDevMode && ngDevMode.rendererAddEventListener++;
69093      lCleanup.push(listenerFn, cleanupFn);
69094      tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, lCleanupIndex + 1);
69095    }
69096  } else {
69097    // Even if there is no native listener to add, we still need to wrap the listener so that OnPush
69098    // ancestors are marked dirty when an event occurs.
69099    listenerFn = wrapListener(tNode, lView, context, listenerFn, false
69100    /** preventDefault */
69101    );
69102  } // subscribe to directive outputs
69103
69104
69105  const outputs = tNode.outputs;
69106  let props;
69107
69108  if (processOutputs && outputs !== null && (props = outputs[eventName])) {
69109    const propsLength = props.length;
69110
69111    if (propsLength) {
69112      for (let i = 0; i < propsLength; i += 2) {
69113        const index = props[i];
69114        ngDevMode && assertIndexInRange(lView, index);
69115        const minifiedName = props[i + 1];
69116        const directiveInstance = lView[index];
69117        const output = directiveInstance[minifiedName];
69118
69119        if (ngDevMode && !isObservable(output)) {
69120          throw new Error(`@Output ${minifiedName} not initialized in '${directiveInstance.constructor.name}'.`);
69121        }
69122
69123        const subscription = output.subscribe(listenerFn);
69124        const idx = lCleanup.length;
69125        lCleanup.push(listenerFn, subscription);
69126        tCleanup && tCleanup.push(eventName, tNode.index, idx, -(idx + 1));
69127      }
69128    }
69129  }
69130}
69131
69132function executeListenerWithErrorHandling(lView, context, listenerFn, e) {
69133  try {
69134    profiler(6
69135    /* ProfilerEvent.OutputStart */
69136    , context, listenerFn); // Only explicitly returning false from a listener should preventDefault
69137
69138    return listenerFn(e) !== false;
69139  } catch (error) {
69140    handleError(lView, error);
69141    return false;
69142  } finally {
69143    profiler(7
69144    /* ProfilerEvent.OutputEnd */
69145    , context, listenerFn);
69146  }
69147}
69148/**
69149 * Wraps an event listener with a function that marks ancestors dirty and prevents default behavior,
69150 * if applicable.
69151 *
69152 * @param tNode The TNode associated with this listener
69153 * @param lView The LView that contains this listener
69154 * @param listenerFn The listener function to call
69155 * @param wrapWithPreventDefault Whether or not to prevent default behavior
69156 * (the procedural renderer does this already, so in those cases, we should skip)
69157 */
69158
69159
69160function wrapListener(tNode, lView, context, listenerFn, wrapWithPreventDefault) {
69161  // Note: we are performing most of the work in the listener function itself
69162  // to optimize listener registration.
69163  return function wrapListenerIn_markDirtyAndPreventDefault(e) {
69164    // Ivy uses `Function` as a special token that allows us to unwrap the function
69165    // so that it can be invoked programmatically by `DebugNode.triggerEventHandler`.
69166    if (e === Function) {
69167      return listenerFn;
69168    } // In order to be backwards compatible with View Engine, events on component host nodes
69169    // must also mark the component view itself dirty (i.e. the view that it owns).
69170
69171
69172    const startView = tNode.flags & 2
69173    /* TNodeFlags.isComponentHost */
69174    ? getComponentLViewByIndex(tNode.index, lView) : lView;
69175    markViewDirty(startView);
69176    let result = executeListenerWithErrorHandling(lView, context, listenerFn, e); // A just-invoked listener function might have coalesced listeners so we need to check for
69177    // their presence and invoke as needed.
69178
69179    let nextListenerFn = wrapListenerIn_markDirtyAndPreventDefault.__ngNextListenerFn__;
69180
69181    while (nextListenerFn) {
69182      // We should prevent default if any of the listeners explicitly return false
69183      result = executeListenerWithErrorHandling(lView, context, nextListenerFn, e) && result;
69184      nextListenerFn = nextListenerFn.__ngNextListenerFn__;
69185    }
69186
69187    if (wrapWithPreventDefault && result === false) {
69188      e.preventDefault(); // Necessary for legacy browsers that don't support preventDefault (e.g. IE)
69189
69190      e.returnValue = false;
69191    }
69192
69193    return result;
69194  };
69195}
69196/**
69197 * @license
69198 * Copyright Google LLC All Rights Reserved.
69199 *
69200 * Use of this source code is governed by an MIT-style license that can be
69201 * found in the LICENSE file at https://angular.io/license
69202 */
69203
69204/**
69205 * @license
69206 * Copyright Google LLC All Rights Reserved.
69207 *
69208 * Use of this source code is governed by an MIT-style license that can be
69209 * found in the LICENSE file at https://angular.io/license
69210 */
69211
69212/**
69213 * Retrieves a context at the level specified and saves it as the global, contextViewData.
69214 * Will get the next level up if level is not specified.
69215 *
69216 * This is used to save contexts of parent views so they can be bound in embedded views, or
69217 * in conjunction with reference() to bind a ref from a parent view.
69218 *
69219 * @param level The relative level of the view from which to grab context compared to contextVewData
69220 * @returns context
69221 *
69222 * @codeGenApi
69223 */
69224
69225
69226function ɵɵnextContext(level = 1) {
69227  return nextContextImpl(level);
69228}
69229/**
69230 * @license
69231 * Copyright Google LLC All Rights Reserved.
69232 *
69233 * Use of this source code is governed by an MIT-style license that can be
69234 * found in the LICENSE file at https://angular.io/license
69235 */
69236
69237/**
69238 * Checks a given node against matching projection slots and returns the
69239 * determined slot index. Returns "null" if no slot matched the given node.
69240 *
69241 * This function takes into account the parsed ngProjectAs selector from the
69242 * node's attributes. If present, it will check whether the ngProjectAs selector
69243 * matches any of the projection slot selectors.
69244 */
69245
69246
69247function matchingProjectionSlotIndex(tNode, projectionSlots) {
69248  let wildcardNgContentIndex = null;
69249  const ngProjectAsAttrVal = getProjectAsAttrValue(tNode);
69250
69251  for (let i = 0; i < projectionSlots.length; i++) {
69252    const slotValue = projectionSlots[i]; // The last wildcard projection slot should match all nodes which aren't matching
69253    // any selector. This is necessary to be backwards compatible with view engine.
69254
69255    if (slotValue === '*') {
69256      wildcardNgContentIndex = i;
69257      continue;
69258    } // If we ran into an `ngProjectAs` attribute, we should match its parsed selector
69259    // to the list of selectors, otherwise we fall back to matching against the node.
69260
69261
69262    if (ngProjectAsAttrVal === null ? isNodeMatchingSelectorList(tNode, slotValue,
69263    /* isProjectionMode */
69264    true) : isSelectorInSelectorList(ngProjectAsAttrVal, slotValue)) {
69265      return i; // first matching selector "captures" a given node
69266    }
69267  }
69268
69269  return wildcardNgContentIndex;
69270}
69271/**
69272 * Instruction to distribute projectable nodes among <ng-content> occurrences in a given template.
69273 * It takes all the selectors from the entire component's template and decides where
69274 * each projected node belongs (it re-distributes nodes among "buckets" where each "bucket" is
69275 * backed by a selector).
69276 *
69277 * This function requires CSS selectors to be provided in 2 forms: parsed (by a compiler) and text,
69278 * un-parsed form.
69279 *
69280 * The parsed form is needed for efficient matching of a node against a given CSS selector.
69281 * The un-parsed, textual form is needed for support of the ngProjectAs attribute.
69282 *
69283 * Having a CSS selector in 2 different formats is not ideal, but alternatives have even more
69284 * drawbacks:
69285 * - having only a textual form would require runtime parsing of CSS selectors;
69286 * - we can't have only a parsed as we can't re-construct textual form from it (as entered by a
69287 * template author).
69288 *
69289 * @param projectionSlots? A collection of projection slots. A projection slot can be based
69290 *        on a parsed CSS selectors or set to the wildcard selector ("*") in order to match
69291 *        all nodes which do not match any selector. If not specified, a single wildcard
69292 *        selector projection slot will be defined.
69293 *
69294 * @codeGenApi
69295 */
69296
69297
69298function ɵɵprojectionDef(projectionSlots) {
69299  const componentNode = getLView()[DECLARATION_COMPONENT_VIEW][T_HOST];
69300
69301  if (!componentNode.projection) {
69302    // If no explicit projection slots are defined, fall back to a single
69303    // projection slot with the wildcard selector.
69304    const numProjectionSlots = projectionSlots ? projectionSlots.length : 1;
69305    const projectionHeads = componentNode.projection = newArray(numProjectionSlots, null);
69306    const tails = projectionHeads.slice();
69307    let componentChild = componentNode.child;
69308
69309    while (componentChild !== null) {
69310      const slotIndex = projectionSlots ? matchingProjectionSlotIndex(componentChild, projectionSlots) : 0;
69311
69312      if (slotIndex !== null) {
69313        if (tails[slotIndex]) {
69314          tails[slotIndex].projectionNext = componentChild;
69315        } else {
69316          projectionHeads[slotIndex] = componentChild;
69317        }
69318
69319        tails[slotIndex] = componentChild;
69320      }
69321
69322      componentChild = componentChild.next;
69323    }
69324  }
69325}
69326/**
69327 * Inserts previously re-distributed projected nodes. This instruction must be preceded by a call
69328 * to the projectionDef instruction.
69329 *
69330 * @param nodeIndex
69331 * @param selectorIndex:
69332 *        - 0 when the selector is `*` (or unspecified as this is the default value),
69333 *        - 1 based index of the selector from the {@link projectionDef}
69334 *
69335 * @codeGenApi
69336 */
69337
69338
69339function ɵɵprojection(nodeIndex, selectorIndex = 0, attrs) {
69340  const lView = getLView();
69341  const tView = getTView();
69342  const tProjectionNode = getOrCreateTNode(tView, HEADER_OFFSET + nodeIndex, 16
69343  /* TNodeType.Projection */
69344  , null, attrs || null); // We can't use viewData[HOST_NODE] because projection nodes can be nested in embedded views.
69345
69346  if (tProjectionNode.projection === null) tProjectionNode.projection = selectorIndex; // `<ng-content>` has no content
69347
69348  setCurrentTNodeAsNotParent();
69349
69350  if ((tProjectionNode.flags & 64
69351  /* TNodeFlags.isDetached */
69352  ) !== 64
69353  /* TNodeFlags.isDetached */
69354  ) {
69355    // re-distribution of projectable nodes is stored on a component's view level
69356    applyProjection(tView, lView, tProjectionNode);
69357  }
69358}
69359/**
69360 *
69361 * Update an interpolated property on an element with a lone bound value
69362 *
69363 * Used when the value passed to a property has 1 interpolated value in it, an no additional text
69364 * surrounds that interpolated value:
69365 *
69366 * ```html
69367 * <div title="{{v0}}"></div>
69368 * ```
69369 *
69370 * Its compiled representation is::
69371 *
69372 * ```ts
69373 * ɵɵpropertyInterpolate('title', v0);
69374 * ```
69375 *
69376 * If the property name also exists as an input property on one of the element's directives,
69377 * the component property will be set instead of the element property. This check must
69378 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69379 *
69380 * @param propName The name of the property to update
69381 * @param prefix Static value used for concatenation only.
69382 * @param v0 Value checked for change.
69383 * @param suffix Static value used for concatenation only.
69384 * @param sanitizer An optional sanitizer function
69385 * @returns itself, so that it may be chained.
69386 * @codeGenApi
69387 */
69388
69389
69390function ɵɵpropertyInterpolate(propName, v0, sanitizer) {
69391  ɵɵpropertyInterpolate1(propName, '', v0, '', sanitizer);
69392  return ɵɵpropertyInterpolate;
69393}
69394/**
69395 *
69396 * Update an interpolated property on an element with single bound value surrounded by text.
69397 *
69398 * Used when the value passed to a property has 1 interpolated value in it:
69399 *
69400 * ```html
69401 * <div title="prefix{{v0}}suffix"></div>
69402 * ```
69403 *
69404 * Its compiled representation is::
69405 *
69406 * ```ts
69407 * ɵɵpropertyInterpolate1('title', 'prefix', v0, 'suffix');
69408 * ```
69409 *
69410 * If the property name also exists as an input property on one of the element's directives,
69411 * the component property will be set instead of the element property. This check must
69412 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69413 *
69414 * @param propName The name of the property to update
69415 * @param prefix Static value used for concatenation only.
69416 * @param v0 Value checked for change.
69417 * @param suffix Static value used for concatenation only.
69418 * @param sanitizer An optional sanitizer function
69419 * @returns itself, so that it may be chained.
69420 * @codeGenApi
69421 */
69422
69423
69424function ɵɵpropertyInterpolate1(propName, prefix, v0, suffix, sanitizer) {
69425  const lView = getLView();
69426  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
69427
69428  if (interpolatedValue !== NO_CHANGE) {
69429    const tView = getTView();
69430    const tNode = getSelectedTNode();
69431    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
69432    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 1, prefix, suffix);
69433  }
69434
69435  return ɵɵpropertyInterpolate1;
69436}
69437/**
69438 *
69439 * Update an interpolated property on an element with 2 bound values surrounded by text.
69440 *
69441 * Used when the value passed to a property has 2 interpolated values in it:
69442 *
69443 * ```html
69444 * <div title="prefix{{v0}}-{{v1}}suffix"></div>
69445 * ```
69446 *
69447 * Its compiled representation is::
69448 *
69449 * ```ts
69450 * ɵɵpropertyInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
69451 * ```
69452 *
69453 * If the property name also exists as an input property on one of the element's directives,
69454 * the component property will be set instead of the element property. This check must
69455 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69456 *
69457 * @param propName The name of the property to update
69458 * @param prefix Static value used for concatenation only.
69459 * @param v0 Value checked for change.
69460 * @param i0 Static value used for concatenation only.
69461 * @param v1 Value checked for change.
69462 * @param suffix Static value used for concatenation only.
69463 * @param sanitizer An optional sanitizer function
69464 * @returns itself, so that it may be chained.
69465 * @codeGenApi
69466 */
69467
69468
69469function ɵɵpropertyInterpolate2(propName, prefix, v0, i0, v1, suffix, sanitizer) {
69470  const lView = getLView();
69471  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
69472
69473  if (interpolatedValue !== NO_CHANGE) {
69474    const tView = getTView();
69475    const tNode = getSelectedTNode();
69476    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
69477    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 2, prefix, i0, suffix);
69478  }
69479
69480  return ɵɵpropertyInterpolate2;
69481}
69482/**
69483 *
69484 * Update an interpolated property on an element with 3 bound values surrounded by text.
69485 *
69486 * Used when the value passed to a property has 3 interpolated values in it:
69487 *
69488 * ```html
69489 * <div title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
69490 * ```
69491 *
69492 * Its compiled representation is::
69493 *
69494 * ```ts
69495 * ɵɵpropertyInterpolate3(
69496 * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
69497 * ```
69498 *
69499 * If the property name also exists as an input property on one of the element's directives,
69500 * the component property will be set instead of the element property. This check must
69501 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69502 *
69503 * @param propName The name of the property to update
69504 * @param prefix Static value used for concatenation only.
69505 * @param v0 Value checked for change.
69506 * @param i0 Static value used for concatenation only.
69507 * @param v1 Value checked for change.
69508 * @param i1 Static value used for concatenation only.
69509 * @param v2 Value checked for change.
69510 * @param suffix Static value used for concatenation only.
69511 * @param sanitizer An optional sanitizer function
69512 * @returns itself, so that it may be chained.
69513 * @codeGenApi
69514 */
69515
69516
69517function ɵɵpropertyInterpolate3(propName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer) {
69518  const lView = getLView();
69519  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
69520
69521  if (interpolatedValue !== NO_CHANGE) {
69522    const tView = getTView();
69523    const tNode = getSelectedTNode();
69524    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
69525    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 3, prefix, i0, i1, suffix);
69526  }
69527
69528  return ɵɵpropertyInterpolate3;
69529}
69530/**
69531 *
69532 * Update an interpolated property on an element with 4 bound values surrounded by text.
69533 *
69534 * Used when the value passed to a property has 4 interpolated values in it:
69535 *
69536 * ```html
69537 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
69538 * ```
69539 *
69540 * Its compiled representation is::
69541 *
69542 * ```ts
69543 * ɵɵpropertyInterpolate4(
69544 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
69545 * ```
69546 *
69547 * If the property name also exists as an input property on one of the element's directives,
69548 * the component property will be set instead of the element property. This check must
69549 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69550 *
69551 * @param propName The name of the property to update
69552 * @param prefix Static value used for concatenation only.
69553 * @param v0 Value checked for change.
69554 * @param i0 Static value used for concatenation only.
69555 * @param v1 Value checked for change.
69556 * @param i1 Static value used for concatenation only.
69557 * @param v2 Value checked for change.
69558 * @param i2 Static value used for concatenation only.
69559 * @param v3 Value checked for change.
69560 * @param suffix Static value used for concatenation only.
69561 * @param sanitizer An optional sanitizer function
69562 * @returns itself, so that it may be chained.
69563 * @codeGenApi
69564 */
69565
69566
69567function ɵɵpropertyInterpolate4(propName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer) {
69568  const lView = getLView();
69569  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
69570
69571  if (interpolatedValue !== NO_CHANGE) {
69572    const tView = getTView();
69573    const tNode = getSelectedTNode();
69574    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
69575    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix);
69576  }
69577
69578  return ɵɵpropertyInterpolate4;
69579}
69580/**
69581 *
69582 * Update an interpolated property on an element with 5 bound values surrounded by text.
69583 *
69584 * Used when the value passed to a property has 5 interpolated values in it:
69585 *
69586 * ```html
69587 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
69588 * ```
69589 *
69590 * Its compiled representation is::
69591 *
69592 * ```ts
69593 * ɵɵpropertyInterpolate5(
69594 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
69595 * ```
69596 *
69597 * If the property name also exists as an input property on one of the element's directives,
69598 * the component property will be set instead of the element property. This check must
69599 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69600 *
69601 * @param propName The name of the property to update
69602 * @param prefix Static value used for concatenation only.
69603 * @param v0 Value checked for change.
69604 * @param i0 Static value used for concatenation only.
69605 * @param v1 Value checked for change.
69606 * @param i1 Static value used for concatenation only.
69607 * @param v2 Value checked for change.
69608 * @param i2 Static value used for concatenation only.
69609 * @param v3 Value checked for change.
69610 * @param i3 Static value used for concatenation only.
69611 * @param v4 Value checked for change.
69612 * @param suffix Static value used for concatenation only.
69613 * @param sanitizer An optional sanitizer function
69614 * @returns itself, so that it may be chained.
69615 * @codeGenApi
69616 */
69617
69618
69619function ɵɵpropertyInterpolate5(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer) {
69620  const lView = getLView();
69621  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
69622
69623  if (interpolatedValue !== NO_CHANGE) {
69624    const tView = getTView();
69625    const tNode = getSelectedTNode();
69626    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
69627    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix);
69628  }
69629
69630  return ɵɵpropertyInterpolate5;
69631}
69632/**
69633 *
69634 * Update an interpolated property on an element with 6 bound values surrounded by text.
69635 *
69636 * Used when the value passed to a property has 6 interpolated values in it:
69637 *
69638 * ```html
69639 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
69640 * ```
69641 *
69642 * Its compiled representation is::
69643 *
69644 * ```ts
69645 * ɵɵpropertyInterpolate6(
69646 *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
69647 * ```
69648 *
69649 * If the property name also exists as an input property on one of the element's directives,
69650 * the component property will be set instead of the element property. This check must
69651 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69652 *
69653 * @param propName The name of the property to update
69654 * @param prefix Static value used for concatenation only.
69655 * @param v0 Value checked for change.
69656 * @param i0 Static value used for concatenation only.
69657 * @param v1 Value checked for change.
69658 * @param i1 Static value used for concatenation only.
69659 * @param v2 Value checked for change.
69660 * @param i2 Static value used for concatenation only.
69661 * @param v3 Value checked for change.
69662 * @param i3 Static value used for concatenation only.
69663 * @param v4 Value checked for change.
69664 * @param i4 Static value used for concatenation only.
69665 * @param v5 Value checked for change.
69666 * @param suffix Static value used for concatenation only.
69667 * @param sanitizer An optional sanitizer function
69668 * @returns itself, so that it may be chained.
69669 * @codeGenApi
69670 */
69671
69672
69673function ɵɵpropertyInterpolate6(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer) {
69674  const lView = getLView();
69675  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
69676
69677  if (interpolatedValue !== NO_CHANGE) {
69678    const tView = getTView();
69679    const tNode = getSelectedTNode();
69680    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
69681    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix);
69682  }
69683
69684  return ɵɵpropertyInterpolate6;
69685}
69686/**
69687 *
69688 * Update an interpolated property on an element with 7 bound values surrounded by text.
69689 *
69690 * Used when the value passed to a property has 7 interpolated values in it:
69691 *
69692 * ```html
69693 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
69694 * ```
69695 *
69696 * Its compiled representation is::
69697 *
69698 * ```ts
69699 * ɵɵpropertyInterpolate7(
69700 *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
69701 * ```
69702 *
69703 * If the property name also exists as an input property on one of the element's directives,
69704 * the component property will be set instead of the element property. This check must
69705 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69706 *
69707 * @param propName The name of the property to update
69708 * @param prefix Static value used for concatenation only.
69709 * @param v0 Value checked for change.
69710 * @param i0 Static value used for concatenation only.
69711 * @param v1 Value checked for change.
69712 * @param i1 Static value used for concatenation only.
69713 * @param v2 Value checked for change.
69714 * @param i2 Static value used for concatenation only.
69715 * @param v3 Value checked for change.
69716 * @param i3 Static value used for concatenation only.
69717 * @param v4 Value checked for change.
69718 * @param i4 Static value used for concatenation only.
69719 * @param v5 Value checked for change.
69720 * @param i5 Static value used for concatenation only.
69721 * @param v6 Value checked for change.
69722 * @param suffix Static value used for concatenation only.
69723 * @param sanitizer An optional sanitizer function
69724 * @returns itself, so that it may be chained.
69725 * @codeGenApi
69726 */
69727
69728
69729function ɵɵpropertyInterpolate7(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer) {
69730  const lView = getLView();
69731  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
69732
69733  if (interpolatedValue !== NO_CHANGE) {
69734    const tView = getTView();
69735    const tNode = getSelectedTNode();
69736    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
69737    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, i5, suffix);
69738  }
69739
69740  return ɵɵpropertyInterpolate7;
69741}
69742/**
69743 *
69744 * Update an interpolated property on an element with 8 bound values surrounded by text.
69745 *
69746 * Used when the value passed to a property has 8 interpolated values in it:
69747 *
69748 * ```html
69749 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
69750 * ```
69751 *
69752 * Its compiled representation is::
69753 *
69754 * ```ts
69755 * ɵɵpropertyInterpolate8(
69756 *  'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
69757 * ```
69758 *
69759 * If the property name also exists as an input property on one of the element's directives,
69760 * the component property will be set instead of the element property. This check must
69761 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69762 *
69763 * @param propName The name of the property to update
69764 * @param prefix Static value used for concatenation only.
69765 * @param v0 Value checked for change.
69766 * @param i0 Static value used for concatenation only.
69767 * @param v1 Value checked for change.
69768 * @param i1 Static value used for concatenation only.
69769 * @param v2 Value checked for change.
69770 * @param i2 Static value used for concatenation only.
69771 * @param v3 Value checked for change.
69772 * @param i3 Static value used for concatenation only.
69773 * @param v4 Value checked for change.
69774 * @param i4 Static value used for concatenation only.
69775 * @param v5 Value checked for change.
69776 * @param i5 Static value used for concatenation only.
69777 * @param v6 Value checked for change.
69778 * @param i6 Static value used for concatenation only.
69779 * @param v7 Value checked for change.
69780 * @param suffix Static value used for concatenation only.
69781 * @param sanitizer An optional sanitizer function
69782 * @returns itself, so that it may be chained.
69783 * @codeGenApi
69784 */
69785
69786
69787function ɵɵpropertyInterpolate8(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer) {
69788  const lView = getLView();
69789  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
69790
69791  if (interpolatedValue !== NO_CHANGE) {
69792    const tView = getTView();
69793    const tNode = getSelectedTNode();
69794    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
69795    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, i5, i6, suffix);
69796  }
69797
69798  return ɵɵpropertyInterpolate8;
69799}
69800/**
69801 * Update an interpolated property on an element with 9 or more bound values surrounded by text.
69802 *
69803 * Used when the number of interpolated values exceeds 8.
69804 *
69805 * ```html
69806 * <div
69807 *  title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
69808 * ```
69809 *
69810 * Its compiled representation is::
69811 *
69812 * ```ts
69813 * ɵɵpropertyInterpolateV(
69814 *  'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
69815 *  'suffix']);
69816 * ```
69817 *
69818 * If the property name also exists as an input property on one of the element's directives,
69819 * the component property will be set instead of the element property. This check must
69820 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
69821 *
69822 * @param propName The name of the property to update.
69823 * @param values The collection of values and the strings in between those values, beginning with a
69824 * string prefix and ending with a string suffix.
69825 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
69826 * @param sanitizer An optional sanitizer function
69827 * @returns itself, so that it may be chained.
69828 * @codeGenApi
69829 */
69830
69831
69832function ɵɵpropertyInterpolateV(propName, values, sanitizer) {
69833  const lView = getLView();
69834  const interpolatedValue = interpolationV(lView, values);
69835
69836  if (interpolatedValue !== NO_CHANGE) {
69837    const tView = getTView();
69838    const tNode = getSelectedTNode();
69839    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
69840
69841    if (ngDevMode) {
69842      const interpolationInBetween = [values[0]]; // prefix
69843
69844      for (let i = 2; i < values.length; i += 2) {
69845        interpolationInBetween.push(values[i]);
69846      }
69847
69848      storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween);
69849    }
69850  }
69851
69852  return ɵɵpropertyInterpolateV;
69853}
69854/**
69855 * @license
69856 * Copyright Google LLC All Rights Reserved.
69857 *
69858 * Use of this source code is governed by an MIT-style license that can be
69859 * found in the LICENSE file at https://angular.io/license
69860 */
69861
69862/**
69863 * NOTE: The word `styling` is used interchangeably as style or class styling.
69864 *
69865 * This file contains code to link styling instructions together so that they can be replayed in
69866 * priority order. The file exists because Ivy styling instruction execution order does not match
69867 * that of the priority order. The purpose of this code is to create a linked list so that the
69868 * instructions can be traversed in priority order when computing the styles.
69869 *
69870 * Assume we are dealing with the following code:
69871 * ```
69872 * @Component({
69873 *   template: `
69874 *     <my-cmp [style]=" {color: '#001'} "
69875 *             [style.color]=" #002 "
69876 *             dir-style-color-1
69877 *             dir-style-color-2> `
69878 * })
69879 * class ExampleComponent {
69880 *   static ngComp = ... {
69881 *     ...
69882 *     // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
69883 *     ɵɵstyleMap({color: '#001'});
69884 *     ɵɵstyleProp('color', '#002');
69885 *     ...
69886 *   }
69887 * }
69888 *
69889 * @Directive({
69890 *   selector: `[dir-style-color-1]',
69891 * })
69892 * class Style1Directive {
69893 *   @HostBinding('style') style = {color: '#005'};
69894 *   @HostBinding('style.color') color = '#006';
69895 *
69896 *   static ngDir = ... {
69897 *     ...
69898 *     // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
69899 *     ɵɵstyleMap({color: '#005'});
69900 *     ɵɵstyleProp('color', '#006');
69901 *     ...
69902 *   }
69903 * }
69904 *
69905 * @Directive({
69906 *   selector: `[dir-style-color-2]',
69907 * })
69908 * class Style2Directive {
69909 *   @HostBinding('style') style = {color: '#007'};
69910 *   @HostBinding('style.color') color = '#008';
69911 *
69912 *   static ngDir = ... {
69913 *     ...
69914 *     // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
69915 *     ɵɵstyleMap({color: '#007'});
69916 *     ɵɵstyleProp('color', '#008');
69917 *     ...
69918 *   }
69919 * }
69920 *
69921 * @Directive({
69922 *   selector: `my-cmp',
69923 * })
69924 * class MyComponent {
69925 *   @HostBinding('style') style = {color: '#003'};
69926 *   @HostBinding('style.color') color = '#004';
69927 *
69928 *   static ngComp = ... {
69929 *     ...
69930 *     // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
69931 *     ɵɵstyleMap({color: '#003'});
69932 *     ɵɵstyleProp('color', '#004');
69933 *     ...
69934 *   }
69935 * }
69936 * ```
69937 *
69938 * The Order of instruction execution is:
69939 *
69940 * NOTE: the comment binding location is for illustrative purposes only.
69941 *
69942 * ```
69943 * // Template: (ExampleComponent)
69944 *     ɵɵstyleMap({color: '#001'});   // Binding index: 10
69945 *     ɵɵstyleProp('color', '#002');  // Binding index: 12
69946 * // MyComponent
69947 *     ɵɵstyleMap({color: '#003'});   // Binding index: 20
69948 *     ɵɵstyleProp('color', '#004');  // Binding index: 22
69949 * // Style1Directive
69950 *     ɵɵstyleMap({color: '#005'});   // Binding index: 24
69951 *     ɵɵstyleProp('color', '#006');  // Binding index: 26
69952 * // Style2Directive
69953 *     ɵɵstyleMap({color: '#007'});   // Binding index: 28
69954 *     ɵɵstyleProp('color', '#008');  // Binding index: 30
69955 * ```
69956 *
69957 * The correct priority order of concatenation is:
69958 *
69959 * ```
69960 * // MyComponent
69961 *     ɵɵstyleMap({color: '#003'});   // Binding index: 20
69962 *     ɵɵstyleProp('color', '#004');  // Binding index: 22
69963 * // Style1Directive
69964 *     ɵɵstyleMap({color: '#005'});   // Binding index: 24
69965 *     ɵɵstyleProp('color', '#006');  // Binding index: 26
69966 * // Style2Directive
69967 *     ɵɵstyleMap({color: '#007'});   // Binding index: 28
69968 *     ɵɵstyleProp('color', '#008');  // Binding index: 30
69969 * // Template: (ExampleComponent)
69970 *     ɵɵstyleMap({color: '#001'});   // Binding index: 10
69971 *     ɵɵstyleProp('color', '#002');  // Binding index: 12
69972 * ```
69973 *
69974 * What color should be rendered?
69975 *
69976 * Once the items are correctly sorted in the list, the answer is simply the last item in the
69977 * concatenation list which is `#002`.
69978 *
69979 * To do so we keep a linked list of all of the bindings which pertain to this element.
69980 * Notice that the bindings are inserted in the order of execution, but the `TView.data` allows
69981 * us to traverse them in the order of priority.
69982 *
69983 * |Idx|`TView.data`|`LView`          | Notes
69984 * |---|------------|-----------------|--------------
69985 * |...|            |                 |
69986 * |10 |`null`      |`{color: '#001'}`| `ɵɵstyleMap('color', {color: '#001'})`
69987 * |11 |`30 | 12`   | ...             |
69988 * |12 |`color`     |`'#002'`         | `ɵɵstyleProp('color', '#002')`
69989 * |13 |`10 | 0`    | ...             |
69990 * |...|            |                 |
69991 * |20 |`null`      |`{color: '#003'}`| `ɵɵstyleMap('color', {color: '#003'})`
69992 * |21 |`0 | 22`    | ...             |
69993 * |22 |`color`     |`'#004'`         | `ɵɵstyleProp('color', '#004')`
69994 * |23 |`20 | 24`   | ...             |
69995 * |24 |`null`      |`{color: '#005'}`| `ɵɵstyleMap('color', {color: '#005'})`
69996 * |25 |`22 | 26`   | ...             |
69997 * |26 |`color`     |`'#006'`         | `ɵɵstyleProp('color', '#006')`
69998 * |27 |`24 | 28`   | ...             |
69999 * |28 |`null`      |`{color: '#007'}`| `ɵɵstyleMap('color', {color: '#007'})`
70000 * |29 |`26 | 30`   | ...             |
70001 * |30 |`color`     |`'#008'`         | `ɵɵstyleProp('color', '#008')`
70002 * |31 |`28 | 10`   | ...             |
70003 *
70004 * The above data structure allows us to re-concatenate the styling no matter which data binding
70005 * changes.
70006 *
70007 * NOTE: in addition to keeping track of next/previous index the `TView.data` also stores prev/next
70008 * duplicate bit. The duplicate bit if true says there either is a binding with the same name or
70009 * there is a map (which may contain the name). This information is useful in knowing if other
70010 * styles with higher priority need to be searched for overwrites.
70011 *
70012 * NOTE: See `should support example in 'tnode_linked_list.ts' documentation` in
70013 * `tnode_linked_list_spec.ts` for working example.
70014 */
70015
70016
70017let __unused_const_as_closure_does_not_like_standalone_comment_blocks__;
70018/**
70019 * Insert new `tStyleValue` at `TData` and link existing style bindings such that we maintain linked
70020 * list of styles and compute the duplicate flag.
70021 *
70022 * Note: this function is executed during `firstUpdatePass` only to populate the `TView.data`.
70023 *
70024 * The function works by keeping track of `tStylingRange` which contains two pointers pointing to
70025 * the head/tail of the template portion of the styles.
70026 *  - if `isHost === false` (we are template) then insertion is at tail of `TStylingRange`
70027 *  - if `isHost === true` (we are host binding) then insertion is at head of `TStylingRange`
70028 *
70029 * @param tData The `TData` to insert into.
70030 * @param tNode `TNode` associated with the styling element.
70031 * @param tStylingKey See `TStylingKey`.
70032 * @param index location of where `tStyleValue` should be stored (and linked into list.)
70033 * @param isHostBinding `true` if the insertion is for a `hostBinding`. (insertion is in front of
70034 *               template.)
70035 * @param isClassBinding True if the associated `tStylingKey` as a `class` styling.
70036 *                       `tNode.classBindings` should be used (or `tNode.styleBindings` otherwise.)
70037 */
70038
70039
70040function insertTStylingBinding(tData, tNode, tStylingKeyWithStatic, index, isHostBinding, isClassBinding) {
70041  ngDevMode && assertFirstUpdatePass(getTView());
70042  let tBindings = isClassBinding ? tNode.classBindings : tNode.styleBindings;
70043  let tmplHead = getTStylingRangePrev(tBindings);
70044  let tmplTail = getTStylingRangeNext(tBindings);
70045  tData[index] = tStylingKeyWithStatic;
70046  let isKeyDuplicateOfStatic = false;
vendor: 4,725 bytes, lines 70047-70155
70047  let tStylingKey;
70048
70049  if (Array.isArray(tStylingKeyWithStatic)) {
70050    // We are case when the `TStylingKey` contains static fields as well.
70051    const staticKeyValueArray = tStylingKeyWithStatic;
70052    tStylingKey = staticKeyValueArray[1]; // unwrap.
70053    // We need to check if our key is present in the static so that we can mark it as duplicate.
70054
70055    if (tStylingKey === null || keyValueArrayIndexOf(staticKeyValueArray, tStylingKey) > 0) {
70056      // tStylingKey is present in the statics, need to mark it as duplicate.
70057      isKeyDuplicateOfStatic = true;
70058    }
70059  } else {
70060    tStylingKey = tStylingKeyWithStatic;
70061  }
70062
70063  if (isHostBinding) {
70064    // We are inserting host bindings
70065    // If we don't have template bindings then `tail` is 0.
70066    const hasTemplateBindings = tmplTail !== 0; // This is important to know because that means that the `head` can't point to the first
70067    // template bindings (there are none.) Instead the head points to the tail of the template.
70068
70069    if (hasTemplateBindings) {
70070      // template head's "prev" will point to last host binding or to 0 if no host bindings yet
70071      const previousNode = getTStylingRangePrev(tData[tmplHead + 1]);
70072      tData[index + 1] = toTStylingRange(previousNode, tmplHead); // if a host binding has already been registered, we need to update the next of that host
70073      // binding to point to this one
70074
70075      if (previousNode !== 0) {
70076        // We need to update the template-tail value to point to us.
70077        tData[previousNode + 1] = setTStylingRangeNext(tData[previousNode + 1], index);
70078      } // The "previous" of the template binding head should point to this host binding
70079
70080
70081      tData[tmplHead + 1] = setTStylingRangePrev(tData[tmplHead + 1], index);
70082    } else {
70083      tData[index + 1] = toTStylingRange(tmplHead, 0); // if a host binding has already been registered, we need to update the next of that host
70084      // binding to point to this one
70085
70086      if (tmplHead !== 0) {
70087        // We need to update the template-tail value to point to us.
70088        tData[tmplHead + 1] = setTStylingRangeNext(tData[tmplHead + 1], index);
70089      } // if we don't have template, the head points to template-tail, and needs to be advanced.
70090
70091
70092      tmplHead = index;
70093    }
70094  } else {
70095    // We are inserting in template section.
70096    // We need to set this binding's "previous" to the current template tail
70097    tData[index + 1] = toTStylingRange(tmplTail, 0);
70098    ngDevMode && assertEqual(tmplHead !== 0 && tmplTail === 0, false, 'Adding template bindings after hostBindings is not allowed.');
70099
70100    if (tmplHead === 0) {
70101      tmplHead = index;
70102    } else {
70103      // We need to update the previous value "next" to point to this binding
70104      tData[tmplTail + 1] = setTStylingRangeNext(tData[tmplTail + 1], index);
70105    }
70106
70107    tmplTail = index;
70108  } // Now we need to update / compute the duplicates.
70109  // Starting with our location search towards head (least priority)
70110
70111
70112  if (isKeyDuplicateOfStatic) {
70113    tData[index + 1] = setTStylingRangePrevDuplicate(tData[index + 1]);
70114  }
70115
70116  markDuplicates(tData, tStylingKey, index, true, isClassBinding);
70117  markDuplicates(tData, tStylingKey, index, false, isClassBinding);
70118  markDuplicateOfResidualStyling(tNode, tStylingKey, tData, index, isClassBinding);
70119  tBindings = toTStylingRange(tmplHead, tmplTail);
70120
70121  if (isClassBinding) {
70122    tNode.classBindings = tBindings;
70123  } else {
70124    tNode.styleBindings = tBindings;
70125  }
70126}
70127/**
70128 * Look into the residual styling to see if the current `tStylingKey` is duplicate of residual.
70129 *
70130 * @param tNode `TNode` where the residual is stored.
70131 * @param tStylingKey `TStylingKey` to store.
70132 * @param tData `TData` associated with the current `LView`.
70133 * @param index location of where `tStyleValue` should be stored (and linked into list.)
70134 * @param isClassBinding True if the associated `tStylingKey` as a `class` styling.
70135 *                       `tNode.classBindings` should be used (or `tNode.styleBindings` otherwise.)
70136 */
70137
70138
70139function markDuplicateOfResidualStyling(tNode, tStylingKey, tData, index, isClassBinding) {
70140  const residual = isClassBinding ? tNode.residualClasses : tNode.residualStyles;
70141
70142  if (residual != null
70143  /* or undefined */
70144  && typeof tStylingKey == 'string' && keyValueArrayIndexOf(residual, tStylingKey) >= 0) {
70145    // We have duplicate in the residual so mark ourselves as duplicate.
70146    tData[index + 1] = setTStylingRangeNextDuplicate(tData[index + 1]);
70147  }
70148}
70149/**
70150 * Marks `TStyleValue`s as duplicates if another style binding in the list has the same
70151 * `TStyleValue`.
70152 *
70153 * NOTE: this function is intended to be called twice once with `isPrevDir` set to `true` and once
70154 * with it set to `false` to search both the previous as well as next items in the list.
70155 *
70156 * No duplicate case
70157 * ```
70158 *   [style.color]
70159 *   [style.width.px] <<- index
70160 *   [style.height.px]
70161 * ```
70162 *
70163 * In the above case adding `[style.width.px]` to the existing `[style.color]` produces no
70164 * duplicates because `width` is not found in any other part of the linked list.
70165 *
70166 * Duplicate case
70167 * ```
70168 *   [style.color]
70169 *   [style.width.em]
70170 *   [style.width.px] <<- index
70171 * ```
70172 * In the above case adding `[style.width.px]` will produce a duplicate with `[style.width.em]`
70173 * because `width` is found in the chain.
70174 *
70175 * Map case 1
70176 * ```
70177 *   [style.width.px]
70178 *   [style.color]
70179 *   [style]  <<- index
70180 * ```
70181 * In the above case adding `[style]` will produce a duplicate with any other bindings because
70182 * `[style]` is a Map and as such is fully dynamic and could produce `color` or `width`.
70183 *
70184 * Map case 2
70185 * ```
70186 *   [style]
70187 *   [style.width.px]
70188 *   [style.color]  <<- index
70189 * ```
70190 * In the above case adding `[style.color]` will produce a duplicate because there is already a
70191 * `[style]` binding which is a Map and as such is fully dynamic and could produce `color` or
70192 * `width`.
70193 *
70194 * NOTE: Once `[style]` (Map) is added into the system all things are mapped as duplicates.
70195 * NOTE: We use `style` as example, but same logic is applied to `class`es as well.
70196 *
70197 * @param tData `TData` where the linked list is stored.
70198 * @param tStylingKey `TStylingKeyPrimitive` which contains the value to compare to other keys in
70199 *        the linked list.
70200 * @param index Starting location in the linked list to search from
70201 * @param isPrevDir Direction.
70202 *        - `true` for previous (lower priority);
70203 *        - `false` for next (higher priority).
70204 */
70205
70206
70207function markDuplicates(tData, tStylingKey, index, isPrevDir, isClassBinding) {
70208  const tStylingAtIndex = tData[index + 1];
70209  const isMap = tStylingKey === null;
70210  let cursor = isPrevDir ? getTStylingRangePrev(tStylingAtIndex) : getTStylingRangeNext(tStylingAtIndex);
70211  let foundDuplicate = false; // We keep iterating as long as we have a cursor
70212  // AND either:
70213  // - we found what we are looking for, OR
70214  // - we are a map in which case we have to continue searching even after we find what we were
70215  //   looking for since we are a wild card and everything needs to be flipped to duplicate.
70216
70217  while (cursor !== 0 && (foundDuplicate === false || isMap)) {
70218    ngDevMode && assertIndexInRange(tData, cursor);
70219    const tStylingValueAtCursor = tData[cursor];
70220    const tStyleRangeAtCursor = tData[cursor + 1];
70221
70222    if (isStylingMatch(tStylingValueAtCursor, tStylingKey)) {
70223      foundDuplicate = true;
70224      tData[cursor + 1] = isPrevDir ? setTStylingRangeNextDuplicate(tStyleRangeAtCursor) : setTStylingRangePrevDuplicate(tStyleRangeAtCursor);
70225    }
70226
70227    cursor = isPrevDir ? getTStylingRangePrev(tStyleRangeAtCursor) : getTStylingRangeNext(tStyleRangeAtCursor);
70228  }
70229
70230  if (foundDuplicate) {
70231    // if we found a duplicate, than mark ourselves.
70232    tData[index + 1] = isPrevDir ? setTStylingRangePrevDuplicate(tStylingAtIndex) : setTStylingRangeNextDuplicate(tStylingAtIndex);
70233  }
70234}
70235/**
70236 * Determines if two `TStylingKey`s are a match.
70237 *
70238 * When computing whether a binding contains a duplicate, we need to compare if the instruction
70239 * `TStylingKey` has a match.
70240 *
70241 * Here are examples of `TStylingKey`s which match given `tStylingKeyCursor` is:
70242 * - `color`
70243 *    - `color`    // Match another color
70244 *    - `null`     // That means that `tStylingKey` is a `classMap`/`styleMap` instruction
70245 *    - `['', 'color', 'other', true]` // wrapped `color` so match
70246 *    - `['', null, 'other', true]`       // wrapped `null` so match
70247 *    - `['', 'width', 'color', 'value']` // wrapped static value contains a match on `'color'`
70248 * - `null`       // `tStylingKeyCursor` always match as it is `classMap`/`styleMap` instruction
70249 *
70250 * @param tStylingKeyCursor
70251 * @param tStylingKey
70252 */
70253
70254
70255function isStylingMatch(tStylingKeyCursor, tStylingKey) {
70256  ngDevMode && assertNotEqual(Array.isArray(tStylingKey), true, 'Expected that \'tStylingKey\' has been unwrapped');
70257
70258  if (tStylingKeyCursor === null || // If the cursor is `null` it means that we have map at that
70259  // location so we must assume that we have a match.
70260  tStylingKey == null || // If `tStylingKey` is `null` then it is a map therefor assume that it
70261  // contains a match.
70262  (Array.isArray(tStylingKeyCursor) ? tStylingKeyCursor[1] : tStylingKeyCursor) === tStylingKey // If the keys match explicitly than we are a match.
70263  ) {
70264    return true;
70265  } else if (Array.isArray(tStylingKeyCursor) && typeof tStylingKey === 'string') {
70266    // if we did not find a match, but `tStylingKeyCursor` is `KeyValueArray` that means cursor has
70267    // statics and we need to check those as well.
70268    return keyValueArrayIndexOf(tStylingKeyCursor, tStylingKey) >= 0; // see if we are matching the key
70269  }
70270
70271  return false;
vendor: 27,108 bytes, lines 70272-71038
70272}
70273/**
70274 * @license
70275 * Copyright Google LLC All Rights Reserved.
70276 *
70277 * Use of this source code is governed by an MIT-style license that can be
70278 * found in the LICENSE file at https://angular.io/license
70279 */
70280// Global state of the parser. (This makes parser non-reentrant, but that is not an issue)
70281
70282
70283const parserState = {
70284  textEnd: 0,
70285  key: 0,
70286  keyEnd: 0,
70287  value: 0,
70288  valueEnd: 0
70289};
70290/**
70291 * Retrieves the last parsed `key` of style.
70292 * @param text the text to substring the key from.
70293 */
70294
70295function getLastParsedKey(text) {
70296  return text.substring(parserState.key, parserState.keyEnd);
70297}
70298/**
70299 * Retrieves the last parsed `value` of style.
70300 * @param text the text to substring the key from.
70301 */
70302
70303
70304function getLastParsedValue(text) {
70305  return text.substring(parserState.value, parserState.valueEnd);
70306}
70307/**
70308 * Initializes `className` string for parsing and parses the first token.
70309 *
70310 * This function is intended to be used in this format:
70311 * ```
70312 * for (let i = parseClassName(text); i >= 0; i = parseClassNameNext(text, i)) {
70313 *   const key = getLastParsedKey();
70314 *   ...
70315 * }
70316 * ```
70317 * @param text `className` to parse
70318 * @returns index where the next invocation of `parseClassNameNext` should resume.
70319 */
70320
70321
70322function parseClassName(text) {
70323  resetParserState(text);
70324  return parseClassNameNext(text, consumeWhitespace(text, 0, parserState.textEnd));
70325}
70326/**
70327 * Parses next `className` token.
70328 *
70329 * This function is intended to be used in this format:
70330 * ```
70331 * for (let i = parseClassName(text); i >= 0; i = parseClassNameNext(text, i)) {
70332 *   const key = getLastParsedKey();
70333 *   ...
70334 * }
70335 * ```
70336 *
70337 * @param text `className` to parse
70338 * @param index where the parsing should resume.
70339 * @returns index where the next invocation of `parseClassNameNext` should resume.
70340 */
70341
70342
70343function parseClassNameNext(text, index) {
70344  const end = parserState.textEnd;
70345
70346  if (end === index) {
70347    return -1;
70348  }
70349
70350  index = parserState.keyEnd = consumeClassToken(text, parserState.key = index, end);
70351  return consumeWhitespace(text, index, end);
70352}
70353/**
70354 * Initializes `cssText` string for parsing and parses the first key/values.
70355 *
70356 * This function is intended to be used in this format:
70357 * ```
70358 * for (let i = parseStyle(text); i >= 0; i = parseStyleNext(text, i))) {
70359 *   const key = getLastParsedKey();
70360 *   const value = getLastParsedValue();
70361 *   ...
70362 * }
70363 * ```
70364 * @param text `cssText` to parse
70365 * @returns index where the next invocation of `parseStyleNext` should resume.
70366 */
70367
70368
70369function parseStyle(text) {
70370  resetParserState(text);
70371  return parseStyleNext(text, consumeWhitespace(text, 0, parserState.textEnd));
70372}
70373/**
70374 * Parses the next `cssText` key/values.
70375 *
70376 * This function is intended to be used in this format:
70377 * ```
70378 * for (let i = parseStyle(text); i >= 0; i = parseStyleNext(text, i))) {
70379 *   const key = getLastParsedKey();
70380 *   const value = getLastParsedValue();
70381 *   ...
70382 * }
70383 *
70384 * @param text `cssText` to parse
70385 * @param index where the parsing should resume.
70386 * @returns index where the next invocation of `parseStyleNext` should resume.
70387 */
70388
70389
70390function parseStyleNext(text, startIndex) {
70391  const end = parserState.textEnd;
70392  let index = parserState.key = consumeWhitespace(text, startIndex, end);
70393
70394  if (end === index) {
70395    // we reached an end so just quit
70396    return -1;
70397  }
70398
70399  index = parserState.keyEnd = consumeStyleKey(text, index, end);
70400  index = consumeSeparator(text, index, end, 58
70401  /* CharCode.COLON */
70402  );
70403  index = parserState.value = consumeWhitespace(text, index, end);
70404  index = parserState.valueEnd = consumeStyleValue(text, index, end);
70405  return consumeSeparator(text, index, end, 59
70406  /* CharCode.SEMI_COLON */
70407  );
70408}
70409/**
70410 * Reset the global state of the styling parser.
70411 * @param text The styling text to parse.
70412 */
70413
70414
70415function resetParserState(text) {
70416  parserState.key = 0;
70417  parserState.keyEnd = 0;
70418  parserState.value = 0;
70419  parserState.valueEnd = 0;
70420  parserState.textEnd = text.length;
70421}
70422/**
70423 * Returns index of next non-whitespace character.
70424 *
70425 * @param text Text to scan
70426 * @param startIndex Starting index of character where the scan should start.
70427 * @param endIndex Ending index of character where the scan should end.
70428 * @returns Index of next non-whitespace character (May be the same as `start` if no whitespace at
70429 *          that location.)
70430 */
70431
70432
70433function consumeWhitespace(text, startIndex, endIndex) {
70434  while (startIndex < endIndex && text.charCodeAt(startIndex) <= 32
70435  /* CharCode.SPACE */
70436  ) {
70437    startIndex++;
70438  }
70439
70440  return startIndex;
70441}
70442/**
70443 * Returns index of last char in class token.
70444 *
70445 * @param text Text to scan
70446 * @param startIndex Starting index of character where the scan should start.
70447 * @param endIndex Ending index of character where the scan should end.
70448 * @returns Index after last char in class token.
70449 */
70450
70451
70452function consumeClassToken(text, startIndex, endIndex) {
70453  while (startIndex < endIndex && text.charCodeAt(startIndex) > 32
70454  /* CharCode.SPACE */
70455  ) {
70456    startIndex++;
70457  }
70458
70459  return startIndex;
70460}
70461/**
70462 * Consumes all of the characters belonging to style key and token.
70463 *
70464 * @param text Text to scan
70465 * @param startIndex Starting index of character where the scan should start.
70466 * @param endIndex Ending index of character where the scan should end.
70467 * @returns Index after last style key character.
70468 */
70469
70470
70471function consumeStyleKey(text, startIndex, endIndex) {
70472  let ch;
70473
70474  while (startIndex < endIndex && ((ch = text.charCodeAt(startIndex)) === 45
70475  /* CharCode.DASH */
70476  || ch === 95
70477  /* CharCode.UNDERSCORE */
70478  || (ch & -33
70479  /* CharCode.UPPER_CASE */
70480  ) >= 65
70481  /* CharCode.A */
70482  && (ch & -33
70483  /* CharCode.UPPER_CASE */
70484  ) <= 90
70485  /* CharCode.Z */
70486  || ch >= 48
70487  /* CharCode.ZERO */
70488  && ch <= 57
70489  /* CharCode.NINE */
70490  )) {
70491    startIndex++;
70492  }
70493
70494  return startIndex;
70495}
70496/**
70497 * Consumes all whitespace and the separator `:` after the style key.
70498 *
70499 * @param text Text to scan
70500 * @param startIndex Starting index of character where the scan should start.
70501 * @param endIndex Ending index of character where the scan should end.
70502 * @returns Index after separator and surrounding whitespace.
70503 */
70504
70505
70506function consumeSeparator(text, startIndex, endIndex, separator) {
70507  startIndex = consumeWhitespace(text, startIndex, endIndex);
70508
70509  if (startIndex < endIndex) {
70510    if (ngDevMode && text.charCodeAt(startIndex) !== separator) {
70511      malformedStyleError(text, String.fromCharCode(separator), startIndex);
70512    }
70513
70514    startIndex++;
70515  }
70516
70517  return startIndex;
70518}
70519/**
70520 * Consumes style value honoring `url()` and `""` text.
70521 *
70522 * @param text Text to scan
70523 * @param startIndex Starting index of character where the scan should start.
70524 * @param endIndex Ending index of character where the scan should end.
70525 * @returns Index after last style value character.
70526 */
70527
70528
70529function consumeStyleValue(text, startIndex, endIndex) {
70530  let ch1 = -1; // 1st previous character
70531
70532  let ch2 = -1; // 2nd previous character
70533
70534  let ch3 = -1; // 3rd previous character
70535
70536  let i = startIndex;
70537  let lastChIndex = i;
70538
70539  while (i < endIndex) {
70540    const ch = text.charCodeAt(i++);
70541
70542    if (ch === 59
70543    /* CharCode.SEMI_COLON */
70544    ) {
70545      return lastChIndex;
70546    } else if (ch === 34
70547    /* CharCode.DOUBLE_QUOTE */
70548    || ch === 39
70549    /* CharCode.SINGLE_QUOTE */
70550    ) {
70551      lastChIndex = i = consumeQuotedText(text, ch, i, endIndex);
70552    } else if (startIndex === i - 4 && // We have seen only 4 characters so far "URL(" (Ignore "foo_URL()")
70553    ch3 === 85
70554    /* CharCode.U */
70555    && ch2 === 82
70556    /* CharCode.R */
70557    && ch1 === 76
70558    /* CharCode.L */
70559    && ch === 40
70560    /* CharCode.OPEN_PAREN */
70561    ) {
70562      lastChIndex = i = consumeQuotedText(text, 41
70563      /* CharCode.CLOSE_PAREN */
70564      , i, endIndex);
70565    } else if (ch > 32
70566    /* CharCode.SPACE */
70567    ) {
70568      // if we have a non-whitespace character then capture its location
70569      lastChIndex = i;
70570    }
70571
70572    ch3 = ch2;
70573    ch2 = ch1;
70574    ch1 = ch & -33
70575    /* CharCode.UPPER_CASE */
70576    ;
70577  }
70578
70579  return lastChIndex;
70580}
70581/**
70582 * Consumes all of the quoted characters.
70583 *
70584 * @param text Text to scan
70585 * @param quoteCharCode CharCode of either `"` or `'` quote or `)` for `url(...)`.
70586 * @param startIndex Starting index of character where the scan should start.
70587 * @param endIndex Ending index of character where the scan should end.
70588 * @returns Index after quoted characters.
70589 */
70590
70591
70592function consumeQuotedText(text, quoteCharCode, startIndex, endIndex) {
70593  let ch1 = -1; // 1st previous character
70594
70595  let index = startIndex;
70596
70597  while (index < endIndex) {
70598    const ch = text.charCodeAt(index++);
70599
70600    if (ch == quoteCharCode && ch1 !== 92
70601    /* CharCode.BACK_SLASH */
70602    ) {
70603      return index;
70604    }
70605
70606    if (ch == 92
70607    /* CharCode.BACK_SLASH */
70608    && ch1 === 92
70609    /* CharCode.BACK_SLASH */
70610    ) {
70611      // two back slashes cancel each other out. For example `"\\"` should properly end the
70612      // quotation. (It should not assume that the last `"` is escaped.)
70613      ch1 = 0;
70614    } else {
70615      ch1 = ch;
70616    }
70617  }
70618
70619  throw ngDevMode ? malformedStyleError(text, String.fromCharCode(quoteCharCode), endIndex) : new Error();
70620}
70621
70622function malformedStyleError(text, expecting, index) {
70623  ngDevMode && assertEqual(typeof text === 'string', true, 'String expected here');
70624  throw throwError(`Malformed style at location ${index} in string '` + text.substring(0, index) + '[>>' + text.substring(index, index + 1) + '<<]' + text.slice(index + 1) + `'. Expecting '${expecting}'.`);
70625}
70626/**
70627 * @license
70628 * Copyright Google LLC All Rights Reserved.
70629 *
70630 * Use of this source code is governed by an MIT-style license that can be
70631 * found in the LICENSE file at https://angular.io/license
70632 */
70633
70634/**
70635 * Update a style binding on an element with the provided value.
70636 *
70637 * If the style value is falsy then it will be removed from the element
70638 * (or assigned a different value depending if there are any styles placed
70639 * on the element with `styleMap` or any static styles that are
70640 * present from when the element was created with `styling`).
70641 *
70642 * Note that the styling element is updated as part of `stylingApply`.
70643 *
70644 * @param prop A valid CSS property.
70645 * @param value New value to write (`null` or an empty string to remove).
70646 * @param suffix Optional suffix. Used with scalar values to add unit such as `px`.
70647 *
70648 * Note that this will apply the provided style value to the host element if this function is called
70649 * within a host binding function.
70650 *
70651 * @codeGenApi
70652 */
70653
70654
70655function ɵɵstyleProp(prop, value, suffix) {
70656  checkStylingProperty(prop, value, suffix, false);
70657  return ɵɵstyleProp;
70658}
70659/**
70660 * Update a class binding on an element with the provided value.
70661 *
70662 * This instruction is meant to handle the `[class.foo]="exp"` case and,
70663 * therefore, the class binding itself must already be allocated using
70664 * `styling` within the creation block.
70665 *
70666 * @param prop A valid CSS class (only one).
70667 * @param value A true/false value which will turn the class on or off.
70668 *
70669 * Note that this will apply the provided class value to the host element if this function
70670 * is called within a host binding function.
70671 *
70672 * @codeGenApi
70673 */
70674
70675
70676function ɵɵclassProp(className, value) {
70677  checkStylingProperty(className, value, null, true);
70678  return ɵɵclassProp;
70679}
70680/**
70681 * Update style bindings using an object literal on an element.
70682 *
70683 * This instruction is meant to apply styling via the `[style]="exp"` template bindings.
70684 * When styles are applied to the element they will then be updated with respect to
70685 * any styles/classes set via `styleProp`. If any styles are set to falsy
70686 * then they will be removed from the element.
70687 *
70688 * Note that the styling instruction will not be applied until `stylingApply` is called.
70689 *
70690 * @param styles A key/value style map of the styles that will be applied to the given element.
70691 *        Any missing styles (that have already been applied to the element beforehand) will be
70692 *        removed (unset) from the element's styling.
70693 *
70694 * Note that this will apply the provided styleMap value to the host element if this function
70695 * is called within a host binding.
70696 *
70697 * @codeGenApi
70698 */
70699
70700
70701function ɵɵstyleMap(styles) {
70702  checkStylingMap(styleKeyValueArraySet, styleStringParser, styles, false);
70703}
70704/**
70705 * Parse text as style and add values to KeyValueArray.
70706 *
70707 * This code is pulled out to a separate function so that it can be tree shaken away if it is not
70708 * needed. It is only referenced from `ɵɵstyleMap`.
70709 *
70710 * @param keyValueArray KeyValueArray to add parsed values to.
70711 * @param text text to parse.
70712 */
70713
70714
70715function styleStringParser(keyValueArray, text) {
70716  for (let i = parseStyle(text); i >= 0; i = parseStyleNext(text, i)) {
70717    styleKeyValueArraySet(keyValueArray, getLastParsedKey(text), getLastParsedValue(text));
70718  }
70719}
70720/**
70721 * Update class bindings using an object literal or class-string on an element.
70722 *
70723 * This instruction is meant to apply styling via the `[class]="exp"` template bindings.
70724 * When classes are applied to the element they will then be updated with
70725 * respect to any styles/classes set via `classProp`. If any
70726 * classes are set to falsy then they will be removed from the element.
70727 *
70728 * Note that the styling instruction will not be applied until `stylingApply` is called.
70729 * Note that this will the provided classMap value to the host element if this function is called
70730 * within a host binding.
70731 *
70732 * @param classes A key/value map or string of CSS classes that will be added to the
70733 *        given element. Any missing classes (that have already been applied to the element
70734 *        beforehand) will be removed (unset) from the element's list of CSS classes.
70735 *
70736 * @codeGenApi
70737 */
70738
70739
70740function ɵɵclassMap(classes) {
70741  checkStylingMap(keyValueArraySet, classStringParser, classes, true);
70742}
70743/**
70744 * Parse text as class and add values to KeyValueArray.
70745 *
70746 * This code is pulled out to a separate function so that it can be tree shaken away if it is not
70747 * needed. It is only referenced from `ɵɵclassMap`.
70748 *
70749 * @param keyValueArray KeyValueArray to add parsed values to.
70750 * @param text text to parse.
70751 */
70752
70753
70754function classStringParser(keyValueArray, text) {
70755  for (let i = parseClassName(text); i >= 0; i = parseClassNameNext(text, i)) {
70756    keyValueArraySet(keyValueArray, getLastParsedKey(text), true);
70757  }
70758}
70759/**
70760 * Common code between `ɵɵclassProp` and `ɵɵstyleProp`.
70761 *
70762 * @param prop property name.
70763 * @param value binding value.
70764 * @param suffix suffix for the property (e.g. `em` or `px`)
70765 * @param isClassBased `true` if `class` change (`false` if `style`)
70766 */
70767
70768
70769function checkStylingProperty(prop, value, suffix, isClassBased) {
70770  const lView = getLView();
70771  const tView = getTView(); // Styling instructions use 2 slots per binding.
70772  // 1. one for the value / TStylingKey
70773  // 2. one for the intermittent-value / TStylingRange
70774
70775  const bindingIndex = incrementBindingIndex(2);
70776
70777  if (tView.firstUpdatePass) {
70778    stylingFirstUpdatePass(tView, prop, bindingIndex, isClassBased);
70779  }
70780
70781  if (value !== NO_CHANGE && bindingUpdated(lView, bindingIndex, value)) {
70782    const tNode = tView.data[getSelectedIndex()];
70783    updateStyling(tView, tNode, lView, lView[RENDERER], prop, lView[bindingIndex + 1] = normalizeSuffix(value, suffix), isClassBased, bindingIndex);
70784  }
70785}
70786/**
70787 * Common code between `ɵɵclassMap` and `ɵɵstyleMap`.
70788 *
70789 * @param keyValueArraySet (See `keyValueArraySet` in "util/array_utils") Gets passed in as a
70790 *        function so that `style` can be processed. This is done for tree shaking purposes.
70791 * @param stringParser Parser used to parse `value` if `string`. (Passed in as `style` and `class`
70792 *        have different parsers.)
70793 * @param value bound value from application
70794 * @param isClassBased `true` if `class` change (`false` if `style`)
70795 */
70796
70797
70798function checkStylingMap(keyValueArraySet, stringParser, value, isClassBased) {
70799  const tView = getTView();
70800  const bindingIndex = incrementBindingIndex(2);
70801
70802  if (tView.firstUpdatePass) {
70803    stylingFirstUpdatePass(tView, null, bindingIndex, isClassBased);
70804  }
70805
70806  const lView = getLView();
70807
70808  if (value !== NO_CHANGE && bindingUpdated(lView, bindingIndex, value)) {
70809    // `getSelectedIndex()` should be here (rather than in instruction) so that it is guarded by the
70810    // if so as not to read unnecessarily.
70811    const tNode = tView.data[getSelectedIndex()];
70812
70813    if (hasStylingInputShadow(tNode, isClassBased) && !isInHostBindings(tView, bindingIndex)) {
70814      if (ngDevMode) {
70815        // verify that if we are shadowing then `TData` is appropriately marked so that we skip
70816        // processing this binding in styling resolution.
70817        const tStylingKey = tView.data[bindingIndex];
70818        assertEqual(Array.isArray(tStylingKey) ? tStylingKey[1] : tStylingKey, false, 'Styling linked list shadow input should be marked as \'false\'');
70819      } // VE does not concatenate the static portion like we are doing here.
70820      // Instead VE just ignores the static completely if dynamic binding is present.
70821      // Because of locality we have already set the static portion because we don't know if there
70822      // is a dynamic portion until later. If we would ignore the static portion it would look like
70823      // the binding has removed it. This would confuse `[ngStyle]`/`[ngClass]` to do the wrong
70824      // thing as it would think that the static portion was removed. For this reason we
70825      // concatenate it so that `[ngStyle]`/`[ngClass]`  can continue to work on changed.
70826
70827
70828      let staticPrefix = isClassBased ? tNode.classesWithoutHost : tNode.stylesWithoutHost;
70829      ngDevMode && isClassBased === false && staticPrefix !== null && assertEqual(staticPrefix.endsWith(';'), true, 'Expecting static portion to end with \';\'');
70830
70831      if (staticPrefix !== null) {
70832        // We want to make sure that falsy values of `value` become empty strings.
70833        value = concatStringsWithSpace(staticPrefix, value ? value : '');
70834      } // Given `<div [style] my-dir>` such that `my-dir` has `@Input('style')`.
70835      // This takes over the `[style]` binding. (Same for `[class]`)
70836
70837
70838      setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isClassBased);
70839    } else {
70840      updateStylingMap(tView, tNode, lView, lView[RENDERER], lView[bindingIndex + 1], lView[bindingIndex + 1] = toStylingKeyValueArray(keyValueArraySet, stringParser, value), isClassBased, bindingIndex);
70841    }
70842  }
70843}
70844/**
70845 * Determines when the binding is in `hostBindings` section
70846 *
70847 * @param tView Current `TView`
70848 * @param bindingIndex index of binding which we would like if it is in `hostBindings`
70849 */
70850
70851
70852function isInHostBindings(tView, bindingIndex) {
70853  // All host bindings are placed after the expando section.
70854  return bindingIndex >= tView.expandoStartIndex;
70855}
70856/**
70857 * Collects the necessary information to insert the binding into a linked list of style bindings
70858 * using `insertTStylingBinding`.
70859 *
70860 * @param tView `TView` where the binding linked list will be stored.
70861 * @param tStylingKey Property/key of the binding.
70862 * @param bindingIndex Index of binding associated with the `prop`
70863 * @param isClassBased `true` if `class` change (`false` if `style`)
70864 */
70865
70866
70867function stylingFirstUpdatePass(tView, tStylingKey, bindingIndex, isClassBased) {
70868  ngDevMode && assertFirstUpdatePass(tView);
70869  const tData = tView.data;
70870
70871  if (tData[bindingIndex + 1] === null) {
70872    // The above check is necessary because we don't clear first update pass until first successful
70873    // (no exception) template execution. This prevents the styling instruction from double adding
70874    // itself to the list.
70875    // `getSelectedIndex()` should be here (rather than in instruction) so that it is guarded by the
70876    // if so as not to read unnecessarily.
70877    const tNode = tData[getSelectedIndex()];
70878    ngDevMode && assertDefined(tNode, 'TNode expected');
70879    const isHostBindings = isInHostBindings(tView, bindingIndex);
70880
70881    if (hasStylingInputShadow(tNode, isClassBased) && tStylingKey === null && !isHostBindings) {
70882      // `tStylingKey === null` implies that we are either `[style]` or `[class]` binding.
70883      // If there is a directive which uses `@Input('style')` or `@Input('class')` than
70884      // we need to neutralize this binding since that directive is shadowing it.
70885      // We turn this into a noop by setting the key to `false`
70886      tStylingKey = false;
70887    }
70888
70889    tStylingKey = wrapInStaticStylingKey(tData, tNode, tStylingKey, isClassBased);
70890    insertTStylingBinding(tData, tNode, tStylingKey, bindingIndex, isHostBindings, isClassBased);
70891  }
70892}
70893/**
70894 * Adds static styling information to the binding if applicable.
70895 *
70896 * The linked list of styles not only stores the list and keys, but also stores static styling
70897 * information on some of the keys. This function determines if the key should contain the styling
70898 * information and computes it.
70899 *
70900 * See `TStylingStatic` for more details.
70901 *
70902 * @param tData `TData` where the linked list is stored.
70903 * @param tNode `TNode` for which the styling is being computed.
70904 * @param stylingKey `TStylingKeyPrimitive` which may need to be wrapped into `TStylingKey`
70905 * @param isClassBased `true` if `class` (`false` if `style`)
70906 */
70907
70908
70909function wrapInStaticStylingKey(tData, tNode, stylingKey, isClassBased) {
70910  const hostDirectiveDef = getCurrentDirectiveDef(tData);
70911  let residual = isClassBased ? tNode.residualClasses : tNode.residualStyles;
70912
70913  if (hostDirectiveDef === null) {
70914    // We are in template node.
70915    // If template node already had styling instruction then it has already collected the static
70916    // styling and there is no need to collect them again. We know that we are the first styling
70917    // instruction because the `TNode.*Bindings` points to 0 (nothing has been inserted yet).
70918    const isFirstStylingInstructionInTemplate = (isClassBased ? tNode.classBindings : tNode.styleBindings) === 0;
70919
70920    if (isFirstStylingInstructionInTemplate) {
70921      // It would be nice to be able to get the statics from `mergeAttrs`, however, at this point
70922      // they are already merged and it would not be possible to figure which property belongs where
70923      // in the priority.
70924      stylingKey = collectStylingFromDirectives(null, tData, tNode, stylingKey, isClassBased);
70925      stylingKey = collectStylingFromTAttrs(stylingKey, tNode.attrs, isClassBased); // We know that if we have styling binding in template we can't have residual.
70926
70927      residual = null;
70928    }
70929  } else {
70930    // We are in host binding node and there was no binding instruction in template node.
70931    // This means that we need to compute the residual.
70932    const directiveStylingLast = tNode.directiveStylingLast;
70933    const isFirstStylingInstructionInHostBinding = directiveStylingLast === -1 || tData[directiveStylingLast] !== hostDirectiveDef;
70934
70935    if (isFirstStylingInstructionInHostBinding) {
70936      stylingKey = collectStylingFromDirectives(hostDirectiveDef, tData, tNode, stylingKey, isClassBased);
70937
70938      if (residual === null) {
70939        // - If `null` than either:
70940        //    - Template styling instruction already ran and it has consumed the static
70941        //      styling into its `TStylingKey` and so there is no need to update residual. Instead
70942        //      we need to update the `TStylingKey` associated with the first template node
70943        //      instruction. OR
70944        //    - Some other styling instruction ran and determined that there are no residuals
70945        let templateStylingKey = getTemplateHeadTStylingKey(tData, tNode, isClassBased);
70946
70947        if (templateStylingKey !== undefined && Array.isArray(templateStylingKey)) {
70948          // Only recompute if `templateStylingKey` had static values. (If no static value found
70949          // then there is nothing to do since this operation can only produce less static keys, not
70950          // more.)
70951          templateStylingKey = collectStylingFromDirectives(null, tData, tNode, templateStylingKey[1]
70952          /* unwrap previous statics */
70953          , isClassBased);
70954          templateStylingKey = collectStylingFromTAttrs(templateStylingKey, tNode.attrs, isClassBased);
70955          setTemplateHeadTStylingKey(tData, tNode, isClassBased, templateStylingKey);
70956        }
70957      } else {
70958        // We only need to recompute residual if it is not `null`.
70959        // - If existing residual (implies there was no template styling). This means that some of
70960        //   the statics may have moved from the residual to the `stylingKey` and so we have to
70961        //   recompute.
70962        // - If `undefined` this is the first time we are running.
70963        residual = collectResidual(tData, tNode, isClassBased);
70964      }
70965    }
70966  }
70967
70968  if (residual !== undefined) {
70969    isClassBased ? tNode.residualClasses = residual : tNode.residualStyles = residual;
70970  }
70971
70972  return stylingKey;
70973}
70974/**
70975 * Retrieve the `TStylingKey` for the template styling instruction.
70976 *
70977 * This is needed since `hostBinding` styling instructions are inserted after the template
70978 * instruction. While the template instruction needs to update the residual in `TNode` the
70979 * `hostBinding` instructions need to update the `TStylingKey` of the template instruction because
70980 * the template instruction is downstream from the `hostBindings` instructions.
70981 *
70982 * @param tData `TData` where the linked list is stored.
70983 * @param tNode `TNode` for which the styling is being computed.
70984 * @param isClassBased `true` if `class` (`false` if `style`)
70985 * @return `TStylingKey` if found or `undefined` if not found.
70986 */
70987
70988
70989function getTemplateHeadTStylingKey(tData, tNode, isClassBased) {
70990  const bindings = isClassBased ? tNode.classBindings : tNode.styleBindings;
70991
70992  if (getTStylingRangeNext(bindings) === 0) {
70993    // There does not seem to be a styling instruction in the `template`.
70994    return undefined;
70995  }
70996
70997  return tData[getTStylingRangePrev(bindings)];
70998}
70999/**
71000 * Update the `TStylingKey` of the first template instruction in `TNode`.
71001 *
71002 * Logically `hostBindings` styling instructions are of lower priority than that of the template.
71003 * However, they execute after the template styling instructions. This means that they get inserted
71004 * in front of the template styling instructions.
71005 *
71006 * If we have a template styling instruction and a new `hostBindings` styling instruction is
71007 * executed it means that it may need to steal static fields from the template instruction. This
71008 * method allows us to update the first template instruction `TStylingKey` with a new value.
71009 *
71010 * Assume:
71011 * ```
71012 * <div my-dir style="color: red" [style.color]="tmplExp"></div>
71013 *
71014 * @Directive({
71015 *   host: {
71016 *     'style': 'width: 100px',
71017 *     '[style.color]': 'dirExp',
71018 *   }
71019 * })
71020 * class MyDir {}
71021 * ```
71022 *
71023 * when `[style.color]="tmplExp"` executes it creates this data structure.
71024 * ```
71025 *  ['', 'color', 'color', 'red', 'width', '100px'],
71026 * ```
71027 *
71028 * The reason for this is that the template instruction does not know if there are styling
71029 * instructions and must assume that there are none and must collect all of the static styling.
71030 * (both
71031 * `color' and 'width`)
71032 *
71033 * When `'[style.color]': 'dirExp',` executes we need to insert a new data into the linked list.
71034 * ```
71035 *  ['', 'color', 'width', '100px'],  // newly inserted
71036 *  ['', 'color', 'color', 'red', 'width', '100px'], // this is wrong
71037 * ```
71038 *
71039 * Notice that the template statics is now wrong as it incorrectly contains `width` so we need to
71040 * update it like so:
71041 * ```
71042 *  ['', 'color', 'width', '100px'],
71043 *  ['', 'color', 'color', 'red'],    // UPDATE
71044 * ```
71045 *
71046 * @param tData `TData` where the linked list is stored.
71047 * @param tNode `TNode` for which the styling is being computed.
71048 * @param isClassBased `true` if `class` (`false` if `style`)
71049 * @param tStylingKey New `TStylingKey` which is replacing the old one.
71050 */
71051
71052
71053function setTemplateHeadTStylingKey(tData, tNode, isClassBased, tStylingKey) {
71054  const bindings = isClassBased ? tNode.classBindings : tNode.styleBindings;
71055  ngDevMode && assertNotEqual(getTStylingRangeNext(bindings), 0, 'Expecting to have at least one template styling binding.');
71056  tData[getTStylingRangePrev(bindings)] = tStylingKey;
71057}
71058/**
71059 * Collect all static values after the current `TNode.directiveStylingLast` index.
71060 *
71061 * Collect the remaining styling information which has not yet been collected by an existing
71062 * styling instruction.
71063 *
71064 * @param tData `TData` where the `DirectiveDefs` are stored.
71065 * @param tNode `TNode` which contains the directive range.
71066 * @param isClassBased `true` if `class` (`false` if `style`)
71067 */
71068
71069
71070function collectResidual(tData, tNode, isClassBased) {
71071  let residual = undefined;
71072  const directiveEnd = tNode.directiveEnd;
71073  ngDevMode && assertNotEqual(tNode.directiveStylingLast, -1, 'By the time this function gets called at least one hostBindings-node styling instruction must have executed.'); // We add `1 + tNode.directiveStart` because we need to skip the current directive (as we are
71074  // collecting things after the last `hostBindings` directive which had a styling instruction.)
71075
71076  for (let i = 1 + tNode.directiveStylingLast; i < directiveEnd; i++) {
71077    const attrs = tData[i].hostAttrs;
71078    residual = collectStylingFromTAttrs(residual, attrs, isClassBased);
71079  }
71080
71081  return collectStylingFromTAttrs(residual, tNode.attrs, isClassBased);
71082}
71083/**
71084 * Collect the static styling information with lower priority than `hostDirectiveDef`.
71085 *
71086 * (This is opposite of residual styling.)
71087 *
71088 * @param hostDirectiveDef `DirectiveDef` for which we want to collect lower priority static
71089 *        styling. (Or `null` if template styling)
71090 * @param tData `TData` where the linked list is stored.
71091 * @param tNode `TNode` for which the styling is being computed.
71092 * @param stylingKey Existing `TStylingKey` to update or wrap.
71093 * @param isClassBased `true` if `class` (`false` if `style`)
71094 */
71095
71096
71097function collectStylingFromDirectives(hostDirectiveDef, tData, tNode, stylingKey, isClassBased) {
71098  // We need to loop because there can be directives which have `hostAttrs` but don't have
71099  // `hostBindings` so this loop catches up to the current directive..
71100  let currentDirective = null;
71101  const directiveEnd = tNode.directiveEnd;
71102  let directiveStylingLast = tNode.directiveStylingLast;
71103
71104  if (directiveStylingLast === -1) {
71105    directiveStylingLast = tNode.directiveStart;
71106  } else {
71107    directiveStylingLast++;
71108  }
71109
71110  while (directiveStylingLast < directiveEnd) {
71111    currentDirective = tData[directiveStylingLast];
71112    ngDevMode && assertDefined(currentDirective, 'expected to be defined');
71113    stylingKey = collectStylingFromTAttrs(stylingKey, currentDirective.hostAttrs, isClassBased);
71114    if (currentDirective === hostDirectiveDef) break;
71115    directiveStylingLast++;
71116  }
71117
71118  if (hostDirectiveDef !== null) {
71119    // we only advance the styling cursor if we are collecting data from host bindings.
71120    // Template executes before host bindings and so if we would update the index,
71121    // host bindings would not get their statics.
71122    tNode.directiveStylingLast = directiveStylingLast;
71123  }
71124
71125  return stylingKey;
71126}
71127/**
71128 * Convert `TAttrs` into `TStylingStatic`.
71129 *
71130 * @param stylingKey existing `TStylingKey` to update or wrap.
71131 * @param attrs `TAttributes` to process.
71132 * @param isClassBased `true` if `class` (`false` if `style`)
71133 */
71134
71135
71136function collectStylingFromTAttrs(stylingKey, attrs, isClassBased) {
71137  const desiredMarker = isClassBased ? 1
71138  /* AttributeMarker.Classes */
71139  : 2
71140  /* AttributeMarker.Styles */
71141  ;
71142  let currentMarker = -1
71143  /* AttributeMarker.ImplicitAttributes */
71144  ;
71145
71146  if (attrs !== null) {
71147    for (let i = 0; i < attrs.length; i++) {
71148      const item = attrs[i];
71149
71150      if (typeof item === 'number') {
71151        currentMarker = item;
71152      } else {
vendor: 17,808 bytes, lines 71153-71648
71153        if (currentMarker === desiredMarker) {
71154          if (!Array.isArray(stylingKey)) {
71155            stylingKey = stylingKey === undefined ? [] : ['', stylingKey];
71156          }
71157
71158          keyValueArraySet(stylingKey, item, isClassBased ? true : attrs[++i]);
71159        }
71160      }
71161    }
71162  }
71163
71164  return stylingKey === undefined ? null : stylingKey;
71165}
71166/**
71167 * Convert user input to `KeyValueArray`.
71168 *
71169 * This function takes user input which could be `string`, Object literal, or iterable and converts
71170 * it into a consistent representation. The output of this is `KeyValueArray` (which is an array
71171 * where
71172 * even indexes contain keys and odd indexes contain values for those keys).
71173 *
71174 * The advantage of converting to `KeyValueArray` is that we can perform diff in an input
71175 * independent
71176 * way.
71177 * (ie we can compare `foo bar` to `['bar', 'baz'] and determine a set of changes which need to be
71178 * applied)
71179 *
71180 * The fact that `KeyValueArray` is sorted is very important because it allows us to compute the
71181 * difference in linear fashion without the need to allocate any additional data.
71182 *
71183 * For example if we kept this as a `Map` we would have to iterate over previous `Map` to determine
71184 * which values need to be deleted, over the new `Map` to determine additions, and we would have to
71185 * keep additional `Map` to keep track of duplicates or items which have not yet been visited.
71186 *
71187 * @param keyValueArraySet (See `keyValueArraySet` in "util/array_utils") Gets passed in as a
71188 *        function so that `style` can be processed. This is done
71189 *        for tree shaking purposes.
71190 * @param stringParser The parser is passed in so that it will be tree shakable. See
71191 *        `styleStringParser` and `classStringParser`
71192 * @param value The value to parse/convert to `KeyValueArray`
71193 */
71194
71195
71196function toStylingKeyValueArray(keyValueArraySet, stringParser, value) {
71197  if (value == null
71198  /*|| value === undefined */
71199  || value === '') return EMPTY_ARRAY;
71200  const styleKeyValueArray = [];
71201  const unwrappedValue = unwrapSafeValue(value);
71202
71203  if (Array.isArray(unwrappedValue)) {
71204    for (let i = 0; i < unwrappedValue.length; i++) {
71205      keyValueArraySet(styleKeyValueArray, unwrappedValue[i], true);
71206    }
71207  } else if (typeof unwrappedValue === 'object') {
71208    for (const key in unwrappedValue) {
71209      if (unwrappedValue.hasOwnProperty(key)) {
71210        keyValueArraySet(styleKeyValueArray, key, unwrappedValue[key]);
71211      }
71212    }
71213  } else if (typeof unwrappedValue === 'string') {
71214    stringParser(styleKeyValueArray, unwrappedValue);
71215  } else {
71216    ngDevMode && throwError('Unsupported styling type ' + typeof unwrappedValue + ': ' + unwrappedValue);
71217  }
71218
71219  return styleKeyValueArray;
71220}
71221/**
71222 * Set a `value` for a `key`.
71223 *
71224 * See: `keyValueArraySet` for details
71225 *
71226 * @param keyValueArray KeyValueArray to add to.
71227 * @param key Style key to add.
71228 * @param value The value to set.
71229 */
71230
71231
71232function styleKeyValueArraySet(keyValueArray, key, value) {
71233  keyValueArraySet(keyValueArray, key, unwrapSafeValue(value));
71234}
71235/**
71236 * Update map based styling.
71237 *
71238 * Map based styling could be anything which contains more than one binding. For example `string`,
71239 * or object literal. Dealing with all of these types would complicate the logic so
71240 * instead this function expects that the complex input is first converted into normalized
71241 * `KeyValueArray`. The advantage of normalization is that we get the values sorted, which makes it
71242 * very cheap to compute deltas between the previous and current value.
71243 *
71244 * @param tView Associated `TView.data` contains the linked list of binding priorities.
71245 * @param tNode `TNode` where the binding is located.
71246 * @param lView `LView` contains the values associated with other styling binding at this `TNode`.
71247 * @param renderer Renderer to use if any updates.
71248 * @param oldKeyValueArray Previous value represented as `KeyValueArray`
71249 * @param newKeyValueArray Current value represented as `KeyValueArray`
71250 * @param isClassBased `true` if `class` (`false` if `style`)
71251 * @param bindingIndex Binding index of the binding.
71252 */
71253
71254
71255function updateStylingMap(tView, tNode, lView, renderer, oldKeyValueArray, newKeyValueArray, isClassBased, bindingIndex) {
71256  if (oldKeyValueArray === NO_CHANGE) {
71257    // On first execution the oldKeyValueArray is NO_CHANGE => treat it as empty KeyValueArray.
71258    oldKeyValueArray = EMPTY_ARRAY;
71259  }
71260
71261  let oldIndex = 0;
71262  let newIndex = 0;
71263  let oldKey = 0 < oldKeyValueArray.length ? oldKeyValueArray[0] : null;
71264  let newKey = 0 < newKeyValueArray.length ? newKeyValueArray[0] : null;
71265
71266  while (oldKey !== null || newKey !== null) {
71267    ngDevMode && assertLessThan(oldIndex, 999, 'Are we stuck in infinite loop?');
71268    ngDevMode && assertLessThan(newIndex, 999, 'Are we stuck in infinite loop?');
71269    const oldValue = oldIndex < oldKeyValueArray.length ? oldKeyValueArray[oldIndex + 1] : undefined;
71270    const newValue = newIndex < newKeyValueArray.length ? newKeyValueArray[newIndex + 1] : undefined;
71271    let setKey = null;
71272    let setValue = undefined;
71273
71274    if (oldKey === newKey) {
71275      // UPDATE: Keys are equal => new value is overwriting old value.
71276      oldIndex += 2;
71277      newIndex += 2;
71278
71279      if (oldValue !== newValue) {
71280        setKey = newKey;
71281        setValue = newValue;
71282      }
71283    } else if (newKey === null || oldKey !== null && oldKey < newKey) {
71284      // DELETE: oldKey key is missing or we did not find the oldKey in the newValue
71285      // (because the keyValueArray is sorted and `newKey` is found later alphabetically).
71286      // `"background" < "color"` so we need to delete `"background"` because it is not found in the
71287      // new array.
71288      oldIndex += 2;
71289      setKey = oldKey;
71290    } else {
71291      // CREATE: newKey's is earlier alphabetically than oldKey's (or no oldKey) => we have new key.
71292      // `"color" > "background"` so we need to add `color` because it is in new array but not in
71293      // old array.
71294      ngDevMode && assertDefined(newKey, 'Expecting to have a valid key');
71295      newIndex += 2;
71296      setKey = newKey;
71297      setValue = newValue;
71298    }
71299
71300    if (setKey !== null) {
71301      updateStyling(tView, tNode, lView, renderer, setKey, setValue, isClassBased, bindingIndex);
71302    }
71303
71304    oldKey = oldIndex < oldKeyValueArray.length ? oldKeyValueArray[oldIndex] : null;
71305    newKey = newIndex < newKeyValueArray.length ? newKeyValueArray[newIndex] : null;
71306  }
71307}
71308/**
71309 * Update a simple (property name) styling.
71310 *
71311 * This function takes `prop` and updates the DOM to that value. The function takes the binding
71312 * value as well as binding priority into consideration to determine which value should be written
71313 * to DOM. (For example it may be determined that there is a higher priority overwrite which blocks
71314 * the DOM write, or if the value goes to `undefined` a lower priority overwrite may be consulted.)
71315 *
71316 * @param tView Associated `TView.data` contains the linked list of binding priorities.
71317 * @param tNode `TNode` where the binding is located.
71318 * @param lView `LView` contains the values associated with other styling binding at this `TNode`.
71319 * @param renderer Renderer to use if any updates.
71320 * @param prop Either style property name or a class name.
71321 * @param value Either style value for `prop` or `true`/`false` if `prop` is class.
71322 * @param isClassBased `true` if `class` (`false` if `style`)
71323 * @param bindingIndex Binding index of the binding.
71324 */
71325
71326
71327function updateStyling(tView, tNode, lView, renderer, prop, value, isClassBased, bindingIndex) {
71328  if (!(tNode.type & 3
71329  /* TNodeType.AnyRNode */
71330  )) {
71331    // It is possible to have styling on non-elements (such as ng-container).
71332    // This is rare, but it does happen. In such a case, just ignore the binding.
71333    return;
71334  }
71335
71336  const tData = tView.data;
71337  const tRange = tData[bindingIndex + 1];
71338  const higherPriorityValue = getTStylingRangeNextDuplicate(tRange) ? findStylingValue(tData, tNode, lView, prop, getTStylingRangeNext(tRange), isClassBased) : undefined;
71339
71340  if (!isStylingValuePresent(higherPriorityValue)) {
71341    // We don't have a next duplicate, or we did not find a duplicate value.
71342    if (!isStylingValuePresent(value)) {
71343      // We should delete current value or restore to lower priority value.
71344      if (getTStylingRangePrevDuplicate(tRange)) {
71345        // We have a possible prev duplicate, let's retrieve it.
71346        value = findStylingValue(tData, null, lView, prop, bindingIndex, isClassBased);
71347      }
71348    }
71349
71350    const rNode = getNativeByIndex(getSelectedIndex(), lView);
71351    applyStyling(renderer, isClassBased, rNode, prop, value);
71352  }
71353}
71354/**
71355 * Search for styling value with higher priority which is overwriting current value, or a
71356 * value of lower priority to which we should fall back if the value is `undefined`.
71357 *
71358 * When value is being applied at a location, related values need to be consulted.
71359 * - If there is a higher priority binding, we should be using that one instead.
71360 *   For example `<div  [style]="{color:exp1}" [style.color]="exp2">` change to `exp1`
71361 *   requires that we check `exp2` to see if it is set to value other than `undefined`.
71362 * - If there is a lower priority binding and we are changing to `undefined`
71363 *   For example `<div  [style]="{color:exp1}" [style.color]="exp2">` change to `exp2` to
71364 *   `undefined` requires that we check `exp1` (and static values) and use that as new value.
71365 *
71366 * NOTE: The styling stores two values.
71367 * 1. The raw value which came from the application is stored at `index + 0` location. (This value
71368 *    is used for dirty checking).
71369 * 2. The normalized value is stored at `index + 1`.
71370 *
71371 * @param tData `TData` used for traversing the priority.
71372 * @param tNode `TNode` to use for resolving static styling. Also controls search direction.
71373 *   - `TNode` search next and quit as soon as `isStylingValuePresent(value)` is true.
71374 *      If no value found consult `tNode.residualStyle`/`tNode.residualClass` for default value.
71375 *   - `null` search prev and go all the way to end. Return last value where
71376 *     `isStylingValuePresent(value)` is true.
71377 * @param lView `LView` used for retrieving the actual values.
71378 * @param prop Property which we are interested in.
71379 * @param index Starting index in the linked list of styling bindings where the search should start.
71380 * @param isClassBased `true` if `class` (`false` if `style`)
71381 */
71382
71383
71384function findStylingValue(tData, tNode, lView, prop, index, isClassBased) {
71385  // `TNode` to use for resolving static styling. Also controls search direction.
71386  //   - `TNode` search next and quit as soon as `isStylingValuePresent(value)` is true.
71387  //      If no value found consult `tNode.residualStyle`/`tNode.residualClass` for default value.
71388  //   - `null` search prev and go all the way to end. Return last value where
71389  //     `isStylingValuePresent(value)` is true.
71390  const isPrevDirection = tNode === null;
71391  let value = undefined;
71392
71393  while (index > 0) {
71394    const rawKey = tData[index];
71395    const containsStatics = Array.isArray(rawKey); // Unwrap the key if we contain static values.
71396
71397    const key = containsStatics ? rawKey[1] : rawKey;
71398    const isStylingMap = key === null;
71399    let valueAtLViewIndex = lView[index + 1];
71400
71401    if (valueAtLViewIndex === NO_CHANGE) {
71402      // In firstUpdatePass the styling instructions create a linked list of styling.
71403      // On subsequent passes it is possible for a styling instruction to try to read a binding
71404      // which
71405      // has not yet executed. In that case we will find `NO_CHANGE` and we should assume that
71406      // we have `undefined` (or empty array in case of styling-map instruction) instead. This
71407      // allows the resolution to apply the value (which may later be overwritten when the
71408      // binding actually executes.)
71409      valueAtLViewIndex = isStylingMap ? EMPTY_ARRAY : undefined;
71410    }
71411
71412    let currentValue = isStylingMap ? keyValueArrayGet(valueAtLViewIndex, prop) : key === prop ? valueAtLViewIndex : undefined;
71413
71414    if (containsStatics && !isStylingValuePresent(currentValue)) {
71415      currentValue = keyValueArrayGet(rawKey, prop);
71416    }
71417
71418    if (isStylingValuePresent(currentValue)) {
71419      value = currentValue;
71420
71421      if (isPrevDirection) {
71422        return value;
71423      }
71424    }
71425
71426    const tRange = tData[index + 1];
71427    index = isPrevDirection ? getTStylingRangePrev(tRange) : getTStylingRangeNext(tRange);
71428  }
71429
71430  if (tNode !== null) {
71431    // in case where we are going in next direction AND we did not find anything, we need to
71432    // consult residual styling
71433    let residual = isClassBased ? tNode.residualClasses : tNode.residualStyles;
71434
71435    if (residual != null
71436    /** OR residual !=== undefined */
71437    ) {
71438      value = keyValueArrayGet(residual, prop);
71439    }
71440  }
71441
71442  return value;
71443}
71444/**
71445 * Determines if the binding value should be used (or if the value is 'undefined' and hence priority
71446 * resolution should be used.)
71447 *
71448 * @param value Binding style value.
71449 */
71450
71451
71452function isStylingValuePresent(value) {
71453  // Currently only `undefined` value is considered non-binding. That is `undefined` says I don't
71454  // have an opinion as to what this binding should be and you should consult other bindings by
71455  // priority to determine the valid value.
71456  // This is extracted into a single function so that we have a single place to control this.
71457  return value !== undefined;
71458}
71459/**
71460 * Normalizes and/or adds a suffix to the value.
71461 *
71462 * If value is `null`/`undefined` no suffix is added
71463 * @param value
71464 * @param suffix
71465 */
71466
71467
71468function normalizeSuffix(value, suffix) {
71469  if (value == null
71470  /** || value === undefined */
71471  ) {// do nothing
71472  } else if (typeof suffix === 'string') {
71473    value = value + suffix;
71474  } else if (typeof value === 'object') {
71475    value = stringify(unwrapSafeValue(value));
71476  }
71477
71478  return value;
71479}
71480/**
71481 * Tests if the `TNode` has input shadow.
71482 *
71483 * An input shadow is when a directive steals (shadows) the input by using `@Input('style')` or
71484 * `@Input('class')` as input.
71485 *
71486 * @param tNode `TNode` which we would like to see if it has shadow.
71487 * @param isClassBased `true` if `class` (`false` if `style`)
71488 */
71489
71490
71491function hasStylingInputShadow(tNode, isClassBased) {
71492  return (tNode.flags & (isClassBased ? 16
71493  /* TNodeFlags.hasClassInput */
71494  : 32
71495  /* TNodeFlags.hasStyleInput */
71496  )) !== 0;
71497}
71498/**
71499 * @license
71500 * Copyright Google LLC All Rights Reserved.
71501 *
71502 * Use of this source code is governed by an MIT-style license that can be
71503 * found in the LICENSE file at https://angular.io/license
71504 */
71505
71506/**
71507 * Create static text node
71508 *
71509 * @param index Index of the node in the data array
71510 * @param value Static string value to write.
71511 *
71512 * @codeGenApi
71513 */
71514
71515
71516function ɵɵtext(index, value = '') {
71517  const lView = getLView();
71518  const tView = getTView();
71519  const adjustedIndex = index + HEADER_OFFSET;
71520  ngDevMode && assertEqual(getBindingIndex(), tView.bindingStartIndex, 'text nodes should be created before any bindings');
71521  ngDevMode && assertIndexInRange(lView, adjustedIndex);
71522  const tNode = tView.firstCreatePass ? getOrCreateTNode(tView, adjustedIndex, 1
71523  /* TNodeType.Text */
71524  , value, null) : tView.data[adjustedIndex];
71525  const textNative = lView[adjustedIndex] = createTextNode(lView[RENDERER], value);
71526  appendChild(tView, lView, textNative, tNode); // Text nodes are self closing.
71527
71528  setCurrentTNode(tNode, false);
71529}
71530/**
71531 * @license
71532 * Copyright Google LLC All Rights Reserved.
71533 *
71534 * Use of this source code is governed by an MIT-style license that can be
71535 * found in the LICENSE file at https://angular.io/license
71536 */
71537
71538/**
71539 *
71540 * Update text content with a lone bound value
71541 *
71542 * Used when a text node has 1 interpolated value in it, an no additional text
71543 * surrounds that interpolated value:
71544 *
71545 * ```html
71546 * <div>{{v0}}</div>
71547 * ```
71548 *
71549 * Its compiled representation is:
71550 *
71551 * ```ts
71552 * ɵɵtextInterpolate(v0);
71553 * ```
71554 * @returns itself, so that it may be chained.
71555 * @see textInterpolateV
71556 * @codeGenApi
71557 */
71558
71559
71560function ɵɵtextInterpolate(v0) {
71561  ɵɵtextInterpolate1('', v0, '');
71562  return ɵɵtextInterpolate;
71563}
71564/**
71565 *
71566 * Update text content with single bound value surrounded by other text.
71567 *
71568 * Used when a text node has 1 interpolated value in it:
71569 *
71570 * ```html
71571 * <div>prefix{{v0}}suffix</div>
71572 * ```
71573 *
71574 * Its compiled representation is:
71575 *
71576 * ```ts
71577 * ɵɵtextInterpolate1('prefix', v0, 'suffix');
71578 * ```
71579 * @returns itself, so that it may be chained.
71580 * @see textInterpolateV
71581 * @codeGenApi
71582 */
71583
71584
71585function ɵɵtextInterpolate1(prefix, v0, suffix) {
71586  const lView = getLView();
71587  const interpolated = interpolation1(lView, prefix, v0, suffix);
71588
71589  if (interpolated !== NO_CHANGE) {
71590    textBindingInternal(lView, getSelectedIndex(), interpolated);
71591  }
71592
71593  return ɵɵtextInterpolate1;
71594}
71595/**
71596 *
71597 * Update text content with 2 bound values surrounded by other text.
71598 *
71599 * Used when a text node has 2 interpolated values in it:
71600 *
71601 * ```html
71602 * <div>prefix{{v0}}-{{v1}}suffix</div>
71603 * ```
71604 *
71605 * Its compiled representation is:
71606 *
71607 * ```ts
71608 * ɵɵtextInterpolate2('prefix', v0, '-', v1, 'suffix');
71609 * ```
71610 * @returns itself, so that it may be chained.
71611 * @see textInterpolateV
71612 * @codeGenApi
71613 */
71614
71615
71616function ɵɵtextInterpolate2(prefix, v0, i0, v1, suffix) {
71617  const lView = getLView();
71618  const interpolated = interpolation2(lView, prefix, v0, i0, v1, suffix);
71619
71620  if (interpolated !== NO_CHANGE) {
71621    textBindingInternal(lView, getSelectedIndex(), interpolated);
71622  }
71623
71624  return ɵɵtextInterpolate2;
71625}
71626/**
71627 *
71628 * Update text content with 3 bound values surrounded by other text.
71629 *
71630 * Used when a text node has 3 interpolated values in it:
71631 *
71632 * ```html
71633 * <div>prefix{{v0}}-{{v1}}-{{v2}}suffix</div>
71634 * ```
71635 *
71636 * Its compiled representation is:
71637 *
71638 * ```ts
71639 * ɵɵtextInterpolate3(
71640 * 'prefix', v0, '-', v1, '-', v2, 'suffix');
71641 * ```
71642 * @returns itself, so that it may be chained.
71643 * @see textInterpolateV
71644 * @codeGenApi
71645 */
71646
71647
71648function ɵɵtextInterpolate3(prefix, v0, i0, v1, i1, v2, suffix
71648) {
71649  const lView = getLView();
71650  const interpolated = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
71651
71652  if (interpolated !== NO_CHANGE) {
71653    textBindingInternal(lView, getSelectedIndex(), interpolated);
71654  }
71655
71656  return ɵɵtextInterpolate3;
71657}
71658/**
71659 *
71660 * Update text content with 4 bound values surrounded by other text.
71661 *
71662 * Used when a text node has 4 interpolated values in it:
71663 *
71664 * ```html
71665 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix</div>
71666 * ```
71667 *
71668 * Its compiled representation is:
71669 *
71670 * ```ts
71671 * ɵɵtextInterpolate4(
71672 * 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
71673 * ```
71674 * @returns itself, so that it may be chained.
71675 * @see ɵɵtextInterpolateV
71676 * @codeGenApi
71677 */
71678
71679
71680function ɵɵtextInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
71681  const lView = getLView();
71682  const interpolated = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
71683
71684  if (interpolated !== NO_CHANGE) {
71685    textBindingInternal(lView, getSelectedIndex(), interpolated);
71686  }
71687
71688  return ɵɵtextInterpolate4;
71689}
71690/**
71691 *
71692 * Update text content with 5 bound values surrounded by other text.
71693 *
71694 * Used when a text node has 5 interpolated values in it:
71695 *
71696 * ```html
71697 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix</div>
71698 * ```
71699 *
71700 * Its compiled representation is:
71701 *
71702 * ```ts
71703 * ɵɵtextInterpolate5(
71704 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
71705 * ```
71706 * @returns itself, so that it may be chained.
71707 * @see textInterpolateV
71708 * @codeGenApi
71709 */
71710
71711
71712function ɵɵtextInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
71713  const lView = getLView();
71714  const interpolated = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
71715
71716  if (interpolated !== NO_CHANGE) {
71717    textBindingInternal(lView, getSelectedIndex(), interpolated);
71718  }
71719
71720  return ɵɵtextInterpolate5;
71721}
71722/**
71723 *
71724 * Update text content with 6 bound values surrounded by other text.
71725 *
71726 * Used when a text node has 6 interpolated values in it:
71727 *
71728 * ```html
71729 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix</div>
71730 * ```
71731 *
71732 * Its compiled representation is:
71733 *
71734 * ```ts
71735 * ɵɵtextInterpolate6(
71736 *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
71737 * ```
71738 *
71739 * @param i4 Static value used for concatenation only.
71740 * @param v5 Value checked for change. @returns itself, so that it may be chained.
71741 * @see textInterpolateV
71742 * @codeGenApi
71743 */
71744
71745
71746function ɵɵtextInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
71747  const lView = getLView();
71748  const interpolated = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
71749
71750  if (interpolated !== NO_CHANGE) {
71751    textBindingInternal(lView, getSelectedIndex(), interpolated);
71752  }
71753
71754  return ɵɵtextInterpolate6;
71755}
71756/**
71757 *
71758 * Update text content with 7 bound values surrounded by other text.
71759 *
71760 * Used when a text node has 7 interpolated values in it:
71761 *
71762 * ```html
71763 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix</div>
71764 * ```
71765 *
71766 * Its compiled representation is:
71767 *
71768 * ```ts
71769 * ɵɵtextInterpolate7(
71770 *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
71771 * ```
71772 * @returns itself, so that it may be chained.
71773 * @see textInterpolateV
71774 * @codeGenApi
71775 */
71776
71777
71778function ɵɵtextInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
71779  const lView = getLView();
71780  const interpolated = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
71781
71782  if (interpolated !== NO_CHANGE) {
71783    textBindingInternal(lView, getSelectedIndex(), interpolated);
71784  }
71785
71786  return ɵɵtextInterpolate7;
71787}
71788/**
71789 *
71790 * Update text content with 8 bound values surrounded by other text.
71791 *
71792 * Used when a text node has 8 interpolated values in it:
71793 *
71794 * ```html
71795 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix</div>
71796 * ```
71797 *
71798 * Its compiled representation is:
71799 *
71800 * ```ts
71801 * ɵɵtextInterpolate8(
71802 *  'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
71803 * ```
71804 * @returns itself, so that it may be chained.
71805 * @see textInterpolateV
71806 * @codeGenApi
71807 */
71808
71809
71810function ɵɵtextInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
71811  const lView = getLView();
71812  const interpolated = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
71813
71814  if (interpolated !== NO_CHANGE) {
71815    textBindingInternal(lView, getSelectedIndex(), interpolated);
71816  }
71817
71818  return ɵɵtextInterpolate8;
71819}
71820/**
71821 * Update text content with 9 or more bound values other surrounded by text.
71822 *
71823 * Used when the number of interpolated values exceeds 8.
71824 *
71825 * ```html
71826 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix</div>
71827 * ```
71828 *
71829 * Its compiled representation is:
71830 *
71831 * ```ts
71832 * ɵɵtextInterpolateV(
71833 *  ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
71834 *  'suffix']);
71835 * ```
71836 *.
71837 * @param values The collection of values and the strings in between those values, beginning with
71838 * a string prefix and ending with a string suffix.
71839 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
71840 *
71841 * @returns itself, so that it may be chained.
71842 * @codeGenApi
71843 */
71844
71845
71846function ɵɵtextInterpolateV(values) {
71847  const lView = getLView();
71848  const interpolated = interpolationV(lView, values);
71849
71850  if (interpolated !== NO_CHANGE) {
71851    textBindingInternal(lView, getSelectedIndex(), interpolated);
71852  }
71853
71854  return ɵɵtextInterpolateV;
71855}
71856/**
71857 * @license
71858 * Copyright Google LLC All Rights Reserved.
71859 *
71860 * Use of this source code is governed by an MIT-style license that can be
71861 * found in the LICENSE file at https://angular.io/license
71862 */
71863
71864/**
71865 *
71866 * Update an interpolated class on an element with single bound value surrounded by text.
71867 *
71868 * Used when the value passed to a property has 1 interpolated value in it:
71869 *
71870 * ```html
71871 * <div class="prefix{{v0}}suffix"></div>
71872 * ```
71873 *
71874 * Its compiled representation is:
71875 *
71876 * ```ts
71877 * ɵɵclassMapInterpolate1('prefix', v0, 'suffix');
71878 * ```
71879 *
71880 * @param prefix Static value used for concatenation only.
71881 * @param v0 Value checked for change.
71882 * @param suffix Static value used for concatenation only.
71883 * @codeGenApi
71884 */
71885
71886
71887function ɵɵclassMapInterpolate1(prefix, v0, suffix) {
71888  const lView = getLView();
71889  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
71890  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
71891}
71892/**
71893 *
71894 * Update an interpolated class on an element with 2 bound values surrounded by text.
71895 *
71896 * Used when the value passed to a property has 2 interpolated values in it:
71897 *
71898 * ```html
71899 * <div class="prefix{{v0}}-{{v1}}suffix"></div>
71900 * ```
71901 *
71902 * Its compiled representation is:
71903 *
71904 * ```ts
71905 * ɵɵclassMapInterpolate2('prefix', v0, '-', v1, 'suffix');
71906 * ```
71907 *
71908 * @param prefix Static value used for concatenation only.
71909 * @param v0 Value checked for change.
71910 * @param i0 Static value used for concatenation only.
71911 * @param v1 Value checked for change.
71912 * @param suffix Static value used for concatenation only.
71913 * @codeGenApi
71914 */
71915
71916
71917function ɵɵclassMapInterpolate2(prefix, v0, i0, v1, suffix) {
71918  const lView = getLView();
71919  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
71920  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
71921}
71922/**
71923 *
71924 * Update an interpolated class on an element with 3 bound values surrounded by text.
71925 *
71926 * Used when the value passed to a property has 3 interpolated values in it:
71927 *
71928 * ```html
71929 * <div class="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
71930 * ```
71931 *
71932 * Its compiled representation is:
71933 *
71934 * ```ts
71935 * ɵɵclassMapInterpolate3(
71936 * 'prefix', v0, '-', v1, '-', v2, 'suffix');
71937 * ```
71938 *
71939 * @param prefix Static value used for concatenation only.
71940 * @param v0 Value checked for change.
71941 * @param i0 Static value used for concatenation only.
71942 * @param v1 Value checked for change.
71943 * @param i1 Static value used for concatenation only.
71944 * @param v2 Value checked for change.
71945 * @param suffix Static value used for concatenation only.
71946 * @codeGenApi
71947 */
71948
71949
71950function ɵɵclassMapInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
71951  const lView = getLView();
71952  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
71953  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
71954}
71955/**
71956 *
71957 * Update an interpolated class on an element with 4 bound values surrounded by text.
71958 *
71959 * Used when the value passed to a property has 4 interpolated values in it:
71960 *
71961 * ```html
71962 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
71963 * ```
71964 *
71965 * Its compiled representation is:
71966 *
71967 * ```ts
71968 * ɵɵclassMapInterpolate4(
71969 * 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
71970 * ```
71971 *
71972 * @param prefix Static value used for concatenation only.
71973 * @param v0 Value checked for change.
71974 * @param i0 Static value used for concatenation only.
71975 * @param v1 Value checked for change.
71976 * @param i1 Static value used for concatenation only.
71977 * @param v2 Value checked for change.
71978 * @param i2 Static value used for concatenation only.
71979 * @param v3 Value checked for change.
71980 * @param suffix Static value used for concatenation only.
71981 * @codeGenApi
71982 */
71983
71984
71985function ɵɵclassMapInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
71986  const lView = getLView();
71987  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
71988  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
71989}
71990/**
71991 *
71992 * Update an interpolated class on an element with 5 bound values surrounded by text.
71993 *
71994 * Used when the value passed to a property has 5 interpolated values in it:
71995 *
71996 * ```html
71997 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
71998 * ```
71999 *
72000 * Its compiled representation is:
72001 *
72002 * ```ts
72003 * ɵɵclassMapInterpolate5(
72004 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
72005 * ```
72006 *
72007 * @param prefix Static value used for concatenation only.
72008 * @param v0 Value checked for change.
72009 * @param i0 Static value used for concatenation only.
72010 * @param v1 Value checked for change.
72011 * @param i1 Static value used for concatenation only.
72012 * @param v2 Value checked for change.
72013 * @param i2 Static value used for concatenation only.
72014 * @param v3 Value checked for change.
72015 * @param i3 Static value used for concatenation only.
72016 * @param v4 Value checked for change.
72017 * @param suffix Static value used for concatenation only.
72018 * @codeGenApi
72019 */
72020
72021
72022function ɵɵclassMapInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
72023  const lView = getLView();
72024  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
72025  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
72026}
72027/**
72028 *
72029 * Update an interpolated class on an element with 6 bound values surrounded by text.
72030 *
72031 * Used when the value passed to a property has 6 interpolated values in it:
72032 *
72033 * ```html
72034 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
72035 * ```
72036 *
72037 * Its compiled representation is:
72038 *
72039 * ```ts
72040 * ɵɵclassMapInterpolate6(
72041 *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
72042 * ```
72043 *
72044 * @param prefix Static value used for concatenation only.
72045 * @param v0 Value checked for change.
72046 * @param i0 Static value used for concatenation only.
72047 * @param v1 Value checked for change.
72048 * @param i1 Static value used for concatenation only.
72049 * @param v2 Value checked for change.
72050 * @param i2 Static value used for concatenation only.
72051 * @param v3 Value checked for change.
72052 * @param i3 Static value used for concatenation only.
72053 * @param v4 Value checked for change.
72054 * @param i4 Static value used for concatenation only.
72055 * @param v5 Value checked for change.
72056 * @param suffix Static value used for concatenation only.
72057 * @codeGenApi
72058 */
72059
72060
72061function ɵɵclassMapInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
72062  const lView = getLView();
72063  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
72064  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
72065}
72066/**
72067 *
72068 * Update an interpolated class on an element with 7 bound values surrounded by text.
72069 *
72070 * Used when the value passed to a property has 7 interpolated values in it:
72071 *
72072 * ```html
72073 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
72074 * ```
72075 *
72076 * Its compiled representation is:
72077 *
72078 * ```ts
72079 * ɵɵclassMapInterpolate7(
72080 *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
72081 * ```
72082 *
72083 * @param prefix Static value used for concatenation only.
72084 * @param v0 Value checked for change.
72085 * @param i0 Static value used for concatenation only.
72086 * @param v1 Value checked for change.
72087 * @param i1 Static value used for concatenation only.
72088 * @param v2 Value checked for change.
72089 * @param i2 Static value used for concatenation only.
72090 * @param v3 Value checked for change.
72091 * @param i3 Static value used for concatenation only.
72092 * @param v4 Value checked for change.
72093 * @param i4 Static value used for concatenation only.
72094 * @param v5 Value checked for change.
72095 * @param i5 Static value used for concatenation only.
72096 * @param v6 Value checked for change.
72097 * @param suffix Static value used for concatenation only.
72098 * @codeGenApi
72099 */
72100
72101
72102function ɵɵclassMapInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
72103  const lView = getLView();
72104  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
72105  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
72106}
72107/**
72108 *
72109 * Update an interpolated class on an element with 8 bound values surrounded by text.
72110 *
72111 * Used when the value passed to a property has 8 interpolated values in it:
72112 *
72113 * ```html
72114 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
72115 * ```
72116 *
72117 * Its compiled representation is:
72118 *
72119 * ```ts
72120 * ɵɵclassMapInterpolate8(
72121 *  'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
72122 * ```
72123 *
72124 * @param prefix Static value used for concatenation only.
72125 * @param v0 Value checked for change.
72126 * @param i0 Static value used for concatenation only.
72127 * @param v1 Value checked for change.
72128 * @param i1 Static value used for concatenation only.
72129 * @param v2 Value checked for change.
72130 * @param i2 Static value used for concatenation only.
72131 * @param v3 Value checked for change.
72132 * @param i3 Static value used for concatenation only.
72133 * @param v4 Value checked for change.
72134 * @param i4 Static value used for concatenation only.
72135 * @param v5 Value checked for change.
72136 * @param i5 Static value used for concatenation only.
72137 * @param v6 Value checked for change.
72138 * @param i6 Static value used for concatenation only.
72139 * @param v7 Value checked for change.
72140 * @param suffix Static value used for concatenation only.
72141 * @codeGenApi
72142 */
72143
72144
72145function ɵɵclassMapInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
72146  const lView = getLView();
72147  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
72148  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
72149}
72150/**
72151 * Update an interpolated class on an element with 9 or more bound values surrounded by text.
72152 *
72153 * Used when the number of interpolated values exceeds 8.
72154 *
72155 * ```html
72156 * <div
72157 *  class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
72158 * ```
72159 *
72160 * Its compiled representation is:
72161 *
72162 * ```ts
72163 * ɵɵclassMapInterpolateV(
72164 *  ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
72165 *  'suffix']);
72166 * ```
72167 *.
72168 * @param values The collection of values and the strings in-between those values, beginning with
72169 * a string prefix and ending with a string suffix.
72170 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
72171 * @codeGenApi
72172 */
72173
72174
72175function ɵɵclassMapInterpolateV(values) {
72176  const lView = getLView();
72177  const interpolatedValue = interpolationV(lView, values);
72178  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
72179}
72180/**
72181 * @license
72182 * Copyright Google LLC All Rights Reserved.
72183 *
72184 * Use of this source code is governed by an MIT-style license that can be
72185 * found in the LICENSE file at https://angular.io/license
72186 */
72187
72188/**
72189 *
72190 * Update an interpolated style on an element with single bound value surrounded by text.
72191 *
72192 * Used when the value passed to a property has 1 interpolated value in it:
72193 *
72194 * ```html
72195 * <div style="key: {{v0}}suffix"></div>
72196 * ```
72197 *
72198 * Its compiled representation is:
72199 *
72200 * ```ts
72201 * ɵɵstyleMapInterpolate1('key: ', v0, 'suffix');
72202 * ```
72203 *
72204 * @param prefix Static value used for concatenation only.
72205 * @param v0 Value checked for change.
72206 * @param suffix Static value used for concatenation only.
72207 * @codeGenApi
72208 */
72209
72210
72211function ɵɵstyleMapInterpolate1(prefix, v0, suffix) {
72212  const lView = getLView();
72213  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
72214  ɵɵstyleMap(interpolatedValue);
72215}
72216/**
72217 *
72218 * Update an interpolated style on an element with 2 bound values surrounded by text.
72219 *
72220 * Used when the value passed to a property has 2 interpolated values in it:
72221 *
72222 * ```html
72223 * <div style="key: {{v0}}; key1: {{v1}}suffix"></div>
72224 * ```
72225 *
72226 * Its compiled representation is:
72227 *
72228 * ```ts
72229 * ɵɵstyleMapInterpolate2('key: ', v0, '; key1: ', v1, 'suffix');
72230 * ```
72231 *
72232 * @param prefix Static value used for concatenation only.
72233 * @param v0 Value checked for change.
72234 * @param i0 Static value used for concatenation only.
72235 * @param v1 Value checked for change.
72236 * @param suffix Static value used for concatenation only.
72237 * @codeGenApi
72238 */
72239
72240
72241function ɵɵstyleMapInterpolate2(prefix, v0, i0, v1, suffix) {
72242  const lView = getLView();
72243  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
72244  ɵɵstyleMap(interpolatedValue);
72245}
72246/**
72247 *
72248 * Update an interpolated style on an element with 3 bound values surrounded by text.
72249 *
72250 * Used when the value passed to a property has 3 interpolated values in it:
72251 *
72252 * ```html
72253 * <div style="key: {{v0}}; key2: {{v1}}; key2: {{v2}}suffix"></div>
72254 * ```
72255 *
72256 * Its compiled representation is:
72257 *
72258 * ```ts
72259 * ɵɵstyleMapInterpolate3(
72260 *     'key: ', v0, '; key1: ', v1, '; key2: ', v2, 'suffix');
72261 * ```
72262 *
72263 * @param prefix Static value used for concatenation only.
72264 * @param v0 Value checked for change.
72265 * @param i0 Static value used for concatenation only.
72266 * @param v1 Value checked for change.
72267 * @param i1 Static value used for concatenation only.
72268 * @param v2 Value checked for change.
72269 * @param suffix Static value used for concatenation only.
72270 * @codeGenApi
72271 */
72272
72273
72274function ɵɵstyleMapInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
72275  const lView = getLView();
72276  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
72277  ɵɵstyleMap(interpolatedValue);
72278}
72279/**
72280 *
72281 * Update an interpolated style on an element with 4 bound values surrounded by text.
72282 *
72283 * Used when the value passed to a property has 4 interpolated values in it:
72284 *
72285 * ```html
72286 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}suffix"></div>
72287 * ```
72288 *
72289 * Its compiled representation is:
72290 *
72291 * ```ts
72292 * ɵɵstyleMapInterpolate4(
72293 *     'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, 'suffix');
72294 * ```
72295 *
72296 * @param prefix Static value used for concatenation only.
72297 * @param v0 Value checked for change.
72298 * @param i0 Static value used for concatenation only.
72299 * @param v1 Value checked for change.
72300 * @param i1 Static value used for concatenation only.
72301 * @param v2 Value checked for change.
72302 * @param i2 Static value used for concatenation only.
72303 * @param v3 Value checked for change.
72304 * @param suffix Static value used for concatenation only.
72305 * @codeGenApi
72306 */
72307
72308
72309function ɵɵstyleMapInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
72310  const lView = getLView();
72311  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
72312  ɵɵstyleMap(interpolatedValue);
72313}
72314/**
72315 *
72316 * Update an interpolated style on an element with 5 bound values surrounded by text.
72317 *
72318 * Used when the value passed to a property has 5 interpolated values in it:
72319 *
72320 * ```html
72321 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}suffix"></div>
72322 * ```
72323 *
72324 * Its compiled representation is:
72325 *
72326 * ```ts
72327 * ɵɵstyleMapInterpolate5(
72328 *     'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, 'suffix');
72329 * ```
72330 *
72331 * @param prefix Static value used for concatenation only.
72332 * @param v0 Value checked for change.
72333 * @param i0 Static value used for concatenation only.
72334 * @param v1 Value checked for change.
72335 * @param i1 Static value used for concatenation only.
72336 * @param v2 Value checked for change.
72337 * @param i2 Static value used for concatenation only.
72338 * @param v3 Value checked for change.
72339 * @param i3 Static value used for concatenation only.
72340 * @param v4 Value checked for change.
72341 * @param suffix Static value used for concatenation only.
72342 * @codeGenApi
72343 */
72344
72345
72346function ɵɵstyleMapInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
72347  const lView = getLView();
72348  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
72349  ɵɵstyleMap(interpolatedValue);
72350}
72351/**
72352 *
72353 * Update an interpolated style on an element with 6 bound values surrounded by text.
72354 *
72355 * Used when the value passed to a property has 6 interpolated values in it:
72356 *
72357 * ```html
72358 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}};
72359 *             key5: {{v5}}suffix"></div>
72360 * ```
72361 *
72362 * Its compiled representation is:
72363 *
72364 * ```ts
72365 * ɵɵstyleMapInterpolate6(
72366 *    'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
72367 *    'suffix');
72368 * ```
72369 *
72370 * @param prefix Static value used for concatenation only.
72371 * @param v0 Value checked for change.
72372 * @param i0 Static value used for concatenation only.
72373 * @param v1 Value checked for change.
72374 * @param i1 Static value used for concatenation only.
72375 * @param v2 Value checked for change.
72376 * @param i2 Static value used for concatenation only.
72377 * @param v3 Value checked for change.
72378 * @param i3 Static value used for concatenation only.
72379 * @param v4 Value checked for change.
72380 * @param i4 Static value used for concatenation only.
72381 * @param v5 Value checked for change.
72382 * @param suffix Static value used for concatenation only.
72383 * @codeGenApi
72384 */
72385
72386
72387function ɵɵstyleMapInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
72388  const lView = getLView();
72389  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
72390  ɵɵstyleMap(interpolatedValue);
72391}
72392/**
72393 *
72394 * Update an interpolated style on an element with 7 bound values surrounded by text.
72395 *
72396 * Used when the value passed to a property has 7 interpolated values in it:
72397 *
72398 * ```html
72399 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}; key5: {{v5}};
72400 *             key6: {{v6}}suffix"></div>
72401 * ```
72402 *
72403 * Its compiled representation is:
72404 *
72405 * ```ts
72406 * ɵɵstyleMapInterpolate7(
72407 *    'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
72408 *    '; key6: ', v6, 'suffix');
72409 * ```
72410 *
72411 * @param prefix Static value used for concatenation only.
72412 * @param v0 Value checked for change.
72413 * @param i0 Static value used for concatenation only.
72414 * @param v1 Value checked for change.
72415 * @param i1 Static value used for concatenation only.
72416 * @param v2 Value checked for change.
72417 * @param i2 Static value used for concatenation only.
72418 * @param v3 Value checked for change.
72419 * @param i3 Static value used for concatenation only.
72420 * @param v4 Value checked for change.
72421 * @param i4 Static value used for concatenation only.
72422 * @param v5 Value checked for change.
72423 * @param i5 Static value used for concatenation only.
72424 * @param v6 Value checked for change.
72425 * @param suffix Static value used for concatenation only.
72426 * @codeGenApi
72427 */
72428
72429
72430function ɵɵstyleMapInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
72431  const lView = getLView();
72432  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
72433  ɵɵstyleMap(interpolatedValue);
72434}
72435/**
72436 *
72437 * Update an interpolated style on an element with 8 bound values surrounded by text.
72438 *
72439 * Used when the value passed to a property has 8 interpolated values in it:
72440 *
72441 * ```html
72442 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}; key5: {{v5}};
72443 *             key6: {{v6}}; key7: {{v7}}suffix"></div>
72444 * ```
72445 *
72446 * Its compiled representation is:
72447 *
72448 * ```ts
72449 * ɵɵstyleMapInterpolate8(
72450 *    'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
72451 *    '; key6: ', v6, '; key7: ', v7, 'suffix');
72452 * ```
72453 *
72454 * @param prefix Static value used for concatenation only.
72455 * @param v0 Value checked for change.
72456 * @param i0 Static value used for concatenation only.
72457 * @param v1 Value checked for change.
72458 * @param i1 Static value used for concatenation only.
72459 * @param v2 Value checked for change.
72460 * @param i2 Static value used for concatenation only.
72461 * @param v3 Value checked for change.
72462 * @param i3 Static value used for concatenation only.
72463 * @param v4 Value checked for change.
72464 * @param i4 Static value used for concatenation only.
72465 * @param v5 Value checked for change.
72466 * @param i5 Static value used for concatenation only.
72467 * @param v6 Value checked for change.
72468 * @param i6 Static value used for concatenation only.
72469 * @param v7 Value checked for change.
72470 * @param suffix Static value used for concatenation only.
72471 * @codeGenApi
72472 */
72473
72474
72475function ɵɵstyleMapInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
72476  const lView = getLView();
72477  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
72478  ɵɵstyleMap(interpolatedValue);
72479}
72480/**
72481 * Update an interpolated style on an element with 9 or more bound values surrounded by text.
72482 *
72483 * Used when the number of interpolated values exceeds 8.
72484 *
72485 * ```html
72486 * <div
72487 *  class="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}; key5: {{v5}};
72488 *         key6: {{v6}}; key7: {{v7}}; key8: {{v8}}; key9: {{v9}}suffix"></div>
72489 * ```
72490 *
72491 * Its compiled representation is:
72492 *
72493 * ```ts
72494 * ɵɵstyleMapInterpolateV(
72495 *    ['key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
72496 *     '; key6: ', v6, '; key7: ', v7, '; key8: ', v8, '; key9: ', v9, 'suffix']);
72497 * ```
72498 *.
72499 * @param values The collection of values and the strings in-between those values, beginning with
72500 * a string prefix and ending with a string suffix.
72501 * (e.g. `['prefix', value0, '; key2: ', value1, '; key2: ', value2, ..., value99, 'suffix']`)
72502 * @codeGenApi
72503 */
72504
72505
72506function ɵɵstyleMapInterpolateV(values) {
72507  const lView = getLView();
72508  const interpolatedValue = interpolationV(lView, values);
72509  ɵɵstyleMap(interpolatedValue);
72510}
72511/**
72512 * @license
72513 * Copyright Google LLC All Rights Reserved.
72514 *
72515 * Use of this source code is governed by an MIT-style license that can be
72516 * found in the LICENSE file at https://angular.io/license
72517 */
72518
72519/**
72520 *
72521 * Update an interpolated style property on an element with single bound value surrounded by text.
72522 *
72523 * Used when the value passed to a property has 1 interpolated value in it:
72524 *
72525 * ```html
72526 * <div style.color="prefix{{v0}}suffix"></div>
72527 * ```
72528 *
72529 * Its compiled representation is:
72530 *
72531 * ```ts
72532 * ɵɵstylePropInterpolate1(0, 'prefix', v0, 'suffix');
72533 * ```
72534 *
72535 * @param styleIndex Index of style to update. This index value refers to the
72536 *        index of the style in the style bindings array that was passed into
72537 *        `styling`.
72538 * @param prefix Static value used for concatenation only.
72539 * @param v0 Value checked for change.
72540 * @param suffix Static value used for concatenation only.
72541 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
72542 * @returns itself, so that it may be chained.
72543 * @codeGenApi
72544 */
72545
72546
72547function ɵɵstylePropInterpolate1(prop, prefix, v0, suffix, valueSuffix) {
72548  const lView = getLView();
72549  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
72550  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
72551  return ɵɵstylePropInterpolate1;
72552}
72553/**
72554 *
72555 * Update an interpolated style property on an element with 2 bound values surrounded by text.
72556 *
72557 * Used when the value passed to a property has 2 interpolated values in it:
72558 *
72559 * ```html
72560 * <div style.color="prefix{{v0}}-{{v1}}suffix"></div>
72561 * ```
72562 *
72563 * Its compiled representation is:
72564 *
72565 * ```ts
72566 * ɵɵstylePropInterpolate2(0, 'prefix', v0, '-', v1, 'suffix');
72567 * ```
72568 *
72569 * @param styleIndex Index of style to update. This index value refers to the
72570 *        index of the style in the style bindings array that was passed into
72571 *        `styling`.
72572 * @param prefix Static value used for concatenation only.
72573 * @param v0 Value checked for change.
72574 * @param i0 Static value used for concatenation only.
72575 * @param v1 Value checked for change.
72576 * @param suffix Static value used for concatenation only.
72577 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
72578 * @returns itself, so that it may be chained.
72579 * @codeGenApi
72580 */
72581
72582
72583function ɵɵstylePropInterpolate2(prop, prefix, v0, i0, v1, suffix, valueSuffix) {
72584  const lView = getLView();
72585  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
72586  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
72587  return ɵɵstylePropInterpolate2;
72588}
72589/**
72590 *
72591 * Update an interpolated style property on an element with 3 bound values surrounded by text.
72592 *
72593 * Used when the value passed to a property has 3 interpolated values in it:
72594 *
72595 * ```html
72596 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
72597 * ```
72598 *
72599 * Its compiled representation is:
72600 *
72601 * ```ts
72602 * ɵɵstylePropInterpolate3(0, 'prefix', v0, '-', v1, '-', v2, 'suffix');
72603 * ```
72604 *
72605 * @param styleIndex Index of style to update. This index value refers to the
72606 *        index of the style in the style bindings array that was passed into
72607 *        `styling`.
72608 * @param prefix Static value used for concatenation only.
72609 * @param v0 Value checked for change.
72610 * @param i0 Static value used for concatenation only.
72611 * @param v1 Value checked for change.
72612 * @param i1 Static value used for concatenation only.
72613 * @param v2 Value checked for change.
72614 * @param suffix Static value used for concatenation only.
72615 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
72616 * @returns itself, so that it may be chained.
72617 * @codeGenApi
72618 */
72619
72620
72621function ɵɵstylePropInterpolate3(prop, prefix, v0, i0, v1, i1, v2, suffix, valueSuffix) {
72622  const lView = getLView();
72623  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
72624  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
72625  return ɵɵstylePropInterpolate3;
72626}
72627/**
72628 *
72629 * Update an interpolated style property on an element with 4 bound values surrounded by text.
72630 *
72631 * Used when the value passed to a property has 4 interpolated values in it:
72632 *
72633 * ```html
72634 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
72635 * ```
72636 *
72637 * Its compiled representation is:
72638 *
72639 * ```ts
72640 * ɵɵstylePropInterpolate4(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
72641 * ```
72642 *
72643 * @param styleIndex Index of style to update. This index value refers to the
72644 *        index of the style in the style bindings array that was passed into
72645 *        `styling`.
72646 * @param prefix Static value used for concatenation only.
72647 * @param v0 Value checked for change.
72648 * @param i0 Static value used for concatenation only.
72649 * @param v1 Value checked for change.
72650 * @param i1 Static value used for concatenation only.
72651 * @param v2 Value checked for change.
72652 * @param i2 Static value used for concatenation only.
72653 * @param v3 Value checked for change.
72654 * @param suffix Static value used for concatenation only.
72655 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
72656 * @returns itself, so that it may be chained.
72657 * @codeGenApi
72658 */
72659
72660
72661function ɵɵstylePropInterpolate4(prop, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, valueSuffix) {
72662  const lView = getLView();
72663  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
72664  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
72665  return ɵɵstylePropInterpolate4;
72666}
72667/**
72668 *
72669 * Update an interpolated style property on an element with 5 bound values surrounded by text.
72670 *
72671 * Used when the value passed to a property has 5 interpolated values in it:
72672 *
72673 * ```html
72674 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
72675 * ```
72676 *
72677 * Its compiled representation is:
72678 *
72679 * ```ts
72680 * ɵɵstylePropInterpolate5(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
72681 * ```
72682 *
72683 * @param styleIndex Index of style to update. This index value refers to the
72684 *        index of the style in the style bindings array that was passed into
72685 *        `styling`.
72686 * @param prefix Static value used for concatenation only.
72687 * @param v0 Value checked for change.
72688 * @param i0 Static value used for concatenation only.
72689 * @param v1 Value checked for change.
72690 * @param i1 Static value used for concatenation only.
72691 * @param v2 Value checked for change.
72692 * @param i2 Static value used for concatenation only.
72693 * @param v3 Value checked for change.
72694 * @param i3 Static value used for concatenation only.
72695 * @param v4 Value checked for change.
72696 * @param suffix Static value used for concatenation only.
72697 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
72698 * @returns itself, so that it may be chained.
72699 * @codeGenApi
72700 */
72701
72702
72703function ɵɵstylePropInterpolate5(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, valueSuffix) {
72704  const lView = getLView();
72705  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
72706  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
72707  return ɵɵstylePropInterpolate5;
72708}
72709/**
72710 *
72711 * Update an interpolated style property on an element with 6 bound values surrounded by text.
72712 *
72713 * Used when the value passed to a property has 6 interpolated values in it:
72714 *
72715 * ```html
72716 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
72717 * ```
72718 *
72719 * Its compiled representation is:
72720 *
72721 * ```ts
72722 * ɵɵstylePropInterpolate6(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
72723 * ```
72724 *
72725 * @param styleIndex Index of style to update. This index value refers to the
72726 *        index of the style in the style bindings array that was passed into
72727 *        `styling`.
72728 * @param prefix Static value used for concatenation only.
72729 * @param v0 Value checked for change.
72730 * @param i0 Static value used for concatenation only.
72731 * @param v1 Value checked for change.
72732 * @param i1 Static value used for concatenation only.
72733 * @param v2 Value checked for change.
72734 * @param i2 Static value used for concatenation only.
72735 * @param v3 Value checked for change.
72736 * @param i3 Static value used for concatenation only.
72737 * @param v4 Value checked for change.
72738 * @param i4 Static value used for concatenation only.
72739 * @param v5 Value checked for change.
72740 * @param suffix Static value used for concatenation only.
72741 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
72742 * @returns itself, so that it may be chained.
72743 * @codeGenApi
72744 */
72745
72746
72747function ɵɵstylePropInterpolate6(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, valueSuffix) {
72748  const lView = getLView();
72749  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
72750  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
72751  return ɵɵstylePropInterpolate6;
72752}
72753/**
72754 *
72755 * Update an interpolated style property on an element with 7 bound values surrounded by text.
72756 *
72757 * Used when the value passed to a property has 7 interpolated values in it:
72758 *
72759 * ```html
72760 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
72761 * ```
72762 *
72763 * Its compiled representation is:
72764 *
72765 * ```ts
72766 * ɵɵstylePropInterpolate7(
72767 *    0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
72768 * ```
72769 *
72770 * @param styleIndex Index of style to update. This index value refers to the
72771 *        index of the style in the style bindings array that was passed into
72772 *        `styling`.
72773 * @param prefix Static value used for concatenation only.
72774 * @param v0 Value checked for change.
72775 * @param i0 Static value used for concatenation only.
72776 * @param v1 Value checked for change.
72777 * @param i1 Static value used for concatenation only.
72778 * @param v2 Value checked for change.
72779 * @param i2 Static value used for concatenation only.
72780 * @param v3 Value checked for change.
72781 * @param i3 Static value used for concatenation only.
72782 * @param v4 Value checked for change.
72783 * @param i4 Static value used for concatenation only.
72784 * @param v5 Value checked for change.
72785 * @param i5 Static value used for concatenation only.
72786 * @param v6 Value checked for change.
72787 * @param suffix Static value used for concatenation only.
72788 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
72789 * @returns itself, so that it may be chained.
72790 * @codeGenApi
72791 */
72792
72793
72794function ɵɵstylePropInterpolate7(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, valueSuffix) {
72795  const lView = getLView();
72796  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
72797  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
72798  return ɵɵstylePropInterpolate7;
72799}
72800/**
72801 *
72802 * Update an interpolated style property on an element with 8 bound values surrounded by text.
72803 *
72804 * Used when the value passed to a property has 8 interpolated values in it:
72805 *
72806 * ```html
72807 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
72808 * ```
72809 *
72810 * Its compiled representation is:
72811 *
72812 * ```ts
72813 * ɵɵstylePropInterpolate8(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6,
72814 * '-', v7, 'suffix');
72815 * ```
72816 *
72817 * @param styleIndex Index of style to update. This index value refers to the
72818 *        index of the style in the style bindings array that was passed into
72819 *        `styling`.
72820 * @param prefix Static value used for concatenation only.
72821 * @param v0 Value checked for change.
72822 * @param i0 Static value used for concatenation only.
72823 * @param v1 Value checked for change.
72824 * @param i1 Static value used for concatenation only.
72825 * @param v2 Value checked for change.
72826 * @param i2 Static value used for concatenation only.
72827 * @param v3 Value checked for change.
72828 * @param i3 Static value used for concatenation only.
72829 * @param v4 Value checked for change.
72830 * @param i4 Static value used for concatenation only.
72831 * @param v5 Value checked for change.
72832 * @param i5 Static value used for concatenation only.
72833 * @param v6 Value checked for change.
72834 * @param i6 Static value used for concatenation only.
72835 * @param v7 Value checked for change.
72836 * @param suffix Static value used for concatenation only.
72837 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
72838 * @returns itself, so that it may be chained.
72839 * @codeGenApi
72840 */
72841
72842
72843function ɵɵstylePropInterpolate8(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, valueSuffix) {
72844  const lView = getLView();
72845  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
72846  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
72847  return ɵɵstylePropInterpolate8;
72848}
72849/**
72850 * Update an interpolated style property on an element with 9 or more bound values surrounded by
72851 * text.
72852 *
72853 * Used when the number of interpolated values exceeds 8.
72854 *
72855 * ```html
72856 * <div
72857 *  style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix">
72858 * </div>
72859 * ```
72860 *
72861 * Its compiled representation is:
72862 *
72863 * ```ts
72864 * ɵɵstylePropInterpolateV(
72865 *  0, ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
72866 *  'suffix']);
72867 * ```
72868 *
72869 * @param styleIndex Index of style to update. This index value refers to the
72870 *        index of the style in the style bindings array that was passed into
72871 *        `styling`..
72872 * @param values The collection of values and the strings in-between those values, beginning with
72873 * a string prefix and ending with a string suffix.
72874 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
72875 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
72876 * @returns itself, so that it may be chained.
72877 * @codeGenApi
72878 */
72879
72880
vendor: 5,148 bytes, lines 72881-73007
72881function ɵɵstylePropInterpolateV(prop, values, valueSuffix) {
72882  const lView = getLView();
72883  const interpolatedValue = interpolationV(lView, values);
72884  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
72885  return ɵɵstylePropInterpolateV;
72886}
72887/**
72888 * @license
72889 * Copyright Google LLC All Rights Reserved.
72890 *
72891 * Use of this source code is governed by an MIT-style license that can be
72892 * found in the LICENSE file at https://angular.io/license
72893 */
72894
72895/**
72896 * Update a property on a host element. Only applies to native node properties, not inputs.
72897 *
72898 * Operates on the element selected by index via the {@link select} instruction.
72899 *
72900 * @param propName Name of property. Because it is going to DOM, this is not subject to
72901 *        renaming as part of minification.
72902 * @param value New value to write.
72903 * @param sanitizer An optional function used to sanitize the value.
72904 * @returns This function returns itself so that it may be chained
72905 * (e.g. `property('name', ctx.name)('title', ctx.title)`)
72906 *
72907 * @codeGenApi
72908 */
72909
72910
72911function ɵɵhostProperty(propName, value, sanitizer) {
72912  const lView = getLView();
72913  const bindingIndex = nextBindingIndex();
72914
72915  if (bindingUpdated(lView, bindingIndex, value)) {
72916    const tView = getTView();
72917    const tNode = getSelectedTNode();
72918    elementPropertyInternal(tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, true);
72919    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
72920  }
72921
72922  return ɵɵhostProperty;
72923}
72924/**
72925 * Updates a synthetic host binding (e.g. `[@foo]`) on a component or directive.
72926 *
72927 * This instruction is for compatibility purposes and is designed to ensure that a
72928 * synthetic host binding (e.g. `@HostBinding('@foo')`) properly gets rendered in
72929 * the component's renderer. Normally all host bindings are evaluated with the parent
72930 * component's renderer, but, in the case of animation @triggers, they need to be
72931 * evaluated with the sub component's renderer (because that's where the animation
72932 * triggers are defined).
72933 *
72934 * Do not use this instruction as a replacement for `elementProperty`. This instruction
72935 * only exists to ensure compatibility with the ViewEngine's host binding behavior.
72936 *
72937 * @param index The index of the element to update in the data array
72938 * @param propName Name of property. Because it is going to DOM, this is not subject to
72939 *        renaming as part of minification.
72940 * @param value New value to write.
72941 * @param sanitizer An optional function used to sanitize the value.
72942 *
72943 * @codeGenApi
72944 */
72945
72946
72947function ɵɵsyntheticHostProperty(propName, value, sanitizer) {
72948  const lView = getLView();
72949  const bindingIndex = nextBindingIndex();
72950
72951  if (bindingUpdated(lView, bindingIndex, value)) {
72952    const tView = getTView();
72953    const tNode = getSelectedTNode();
72954    const currentDef = getCurrentDirectiveDef(tView.data);
72955    const renderer = loadComponentRenderer(currentDef, tNode, lView);
72956    elementPropertyInternal(tView, tNode, lView, propName, value, renderer, sanitizer, true);
72957    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
72958  }
72959
72960  return ɵɵsyntheticHostProperty;
72961}
72962/**
72963 * @license
72964 * Copyright Google LLC All Rights Reserved.
72965 *
72966 * Use of this source code is governed by an MIT-style license that can be
72967 * found in the LICENSE file at https://angular.io/license
72968 */
72969
72970/**
72971 * NOTE: changes to the `ngI18nClosureMode` name must be synced with `compiler-cli/src/tooling.ts`.
72972 */
72973
72974
72975if (typeof ngI18nClosureMode === 'undefined') {
72976  // These property accesses can be ignored because ngI18nClosureMode will be set to false
72977  // when optimizing code and the whole if statement will be dropped.
72978  // Make sure to refer to ngI18nClosureMode as ['ngI18nClosureMode'] for closure.
72979  // NOTE: we need to have it in IIFE so that the tree-shaker is happy.
72980  (function () {
72981    // tslint:disable-next-line:no-toplevel-property-access
72982    _global['ngI18nClosureMode'] = // TODO(FW-1250): validate that this actually, you know, works.
72983    // tslint:disable-next-line:no-toplevel-property-access
72984    typeof goog !== 'undefined' && typeof goog.getMsg === 'function';
72985  })();
72986}
72987/**
72988 * @license
72989 * Copyright Google LLC All Rights Reserved.
72990 *
72991 * Use of this source code is governed by an MIT-style license that can be
72992 * found in the LICENSE file at https://angular.io/license
72993 */
72994// THIS CODE IS GENERATED - DO NOT MODIFY.
72995
72996
72997const u = undefined;
72998
72999function plural(val) {
73000  const n = val,
73001        i = Math.floor(Math.abs(val)),
73002        v = val.toString().replace(/^[^.]*\.?/, '').length;
73003  if (i === 1 && v === 0) return 1;
73004  return 5;
73005}
73006
73007var localeEn = ["en", [["a", "p"], ["AM", "PM"], u], [["AM", "PM"], u, u], [["S", "M", "T", "W", "T", "F", "S"], ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]], u, [["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
73007November", "December"]], u, [["B", "A"], ["BC", "AD"], ["Before Christ", "Anno Domini"]], 0, [6, 0], ["M/d/yy", "MMM d, y", "MMMM d, y", "EEEE, MMMM d, y"], ["h:mm a", "h:mm:ss a", "h:mm:ss a z", "h:mm:ss a zzzz"], ["{1}, {0}", u, "{1} 'at' {0}", u], [".", ",", ";", "%", "+", "-", "E", "×", "‰", "∞", "NaN", ":"], ["#,##0.###", "#,##0%", "¤#,##0.00", "#E0"], "USD", "$", "US Dollar", {}, "ltr", plural];
73008/**
73009 * @license
73010 * Copyright Google LLC All Rights Reserved.
73011 *
73012 * Use of this source code is governed by an MIT-style license that can be
73013 * found in the LICENSE file at https://angular.io/license
73014 */
73015
73016/**
73017 * This const is used to store the locale data registered with `registerLocaleData`
73018 */
73019
73020let LOCALE_DATA = {};
73021/**
73022 * Register locale data to be used internally by Angular. See the
73023 * ["I18n guide"](guide/i18n-common-format-data-locale) to know how to import additional locale
73024 * data.
73025 *
73026 * The signature `registerLocaleData(data: any, extraData?: any)` is deprecated since v5.1
73027 */
73028
73029function registerLocaleData(data, localeId, extraData) {
73030  if (typeof localeId !== 'string') {
73031    extraData = localeId;
73032    localeId = data[LocaleDataIndex.LocaleId];
73033  }
73034
73035  localeId = localeId.toLowerCase().replace(/_/g, '-');
73036  LOCALE_DATA[localeId] = data;
73037
73038  if (extraData) {
73039    LOCALE_DATA[localeId][LocaleDataIndex.ExtraData] = extraData;
73040  }
73041}
73042/**
73043 * Finds the locale data for a given locale.
73044 *
73045 * @param locale The locale code.
73046 * @returns The locale data.
73047 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
73048 */
73049
73050
73051function findLocaleData(locale) {
73052  const normalizedLocale = normalizeLocale(locale);
73053  let match = getLocaleData(normalizedLocale);
73054
73055  if (match) {
73056    return match;
73057  } // let's try to find a parent locale
73058
73059
73060  const parentLocale = normalizedLocale.split('-')[0];
73061  match = getLocaleData(parentLocale);
73062
73063  if (match) {
73064    return match;
73065  }
73066
73067  if (parentLocale === 'en') {
73068    return localeEn;
73069  }
73070
73071  throw new RuntimeError(701
73072  /* RuntimeErrorCode.MISSING_LOCALE_DATA */
73073  , ngDevMode && `Missing locale data for the locale "${locale}".`);
73074}
73075/**
73076 * Retrieves the default currency code for the given locale.
73077 *
73078 * The default is defined as the first currency which is still in use.
73079 *
73080 * @param locale The code of the locale whose currency code we want.
73081 * @returns The code of the default currency for the given locale.
73082 *
73083 */
73084
73085
73086function getLocaleCurrencyCode(locale) {
73087  const data = findLocaleData(locale);
73088  return data[LocaleDataIndex.CurrencyCode] || null;
73089}
73090/**
73091 * Retrieves the plural function used by ICU expressions to determine the plural case to use
73092 * for a given locale.
73093 * @param locale A locale code for the locale format rules to use.
73094 * @returns The plural function for the locale.
73095 * @see `NgPlural`
73096 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
73097 */
73098
73099
73100function getLocalePluralCase(locale) {
73101  const data = findLocaleData(locale);
73102  return data[LocaleDataIndex.PluralCase];
73103}
73104/**
73105 * Helper function to get the given `normalizedLocale` from `LOCALE_DATA`
73106 * or from the global `ng.common.locale`.
73107 */
73108
73109
73110function getLocaleData(normalizedLocale) {
73111  if (!(normalizedLocale in LOCALE_DATA)) {
73112    LOCALE_DATA[normalizedLocale] = _global.ng && _global.ng.common && _global.ng.common.locales && _global.ng.common.locales[normalizedLocale];
73113  }
73114
73115  return LOCALE_DATA[normalizedLocale];
73116}
73117/**
73118 * Helper function to remove all the locale data from `LOCALE_DATA`.
73119 */
73120
73121
73122function unregisterAllLocaleData() {
73123  LOCALE_DATA = {};
73124}
73125/**
73126 * Index of each type of locale data from the locale data array
73127 */
73128
73129
73130var LocaleDataIndex;
73131
73132(function (LocaleDataIndex) {
73133  LocaleDataIndex[LocaleDataIndex["LocaleId"] = 0] = "LocaleId";
73134  LocaleDataIndex[LocaleDataIndex["DayPeriodsFormat"] = 1] = "DayPeriodsFormat";
73135  LocaleDataIndex[LocaleDataIndex["DayPeriodsStandalone"] = 2] = "DayPeriodsStandalone";
73136  LocaleDataIndex[LocaleDataIndex["DaysFormat"] = 3] = "DaysFormat";
73137  LocaleDataIndex[LocaleDataIndex["DaysStandalone"] = 4] = "DaysStandalone";
73138  LocaleDataIndex[LocaleDataIndex["MonthsFormat"] = 5] = "MonthsFormat";
73139  LocaleDataIndex[LocaleDataIndex["MonthsStandalone"] = 6] = "MonthsStandalone";
73140  LocaleDataIndex[LocaleDataIndex["Eras"] = 7] = "Eras";
73141  LocaleDataIndex[LocaleDataIndex["FirstDayOfWeek"] = 8] = "FirstDayOfWeek";
73142  LocaleDataIndex[LocaleDataIndex["WeekendRange"] = 9] = "WeekendRange";
73143  LocaleDataIndex[LocaleDataIndex["DateFormat"] = 10] = "DateFormat";
73144  LocaleDataIndex[LocaleDataIndex["TimeFormat"] = 11] = "TimeFormat";
73145  LocaleDataIndex[LocaleDataIndex["DateTimeFormat"] = 12] = "DateTimeFormat";
73146  LocaleDataIndex[LocaleDataIndex["NumberSymbols"] = 13] = "NumberSymbols";
73147  LocaleDataIndex[LocaleDataIndex["NumberFormats"] = 14] = "NumberFormats";
73148  LocaleDataIndex[LocaleDataIndex["CurrencyCode"] = 15] = "CurrencyCode";
73149  LocaleDataIndex[LocaleDataIndex["CurrencySymbol"] = 16] = "CurrencySymbol";
73150  LocaleDataIndex[LocaleDataIndex["CurrencyName"] = 17] = "CurrencyName";
73151  LocaleDataIndex[LocaleDataIndex["Currencies"] = 18] = "Currencies";
73152  LocaleDataIndex[LocaleDataIndex["Directionality"] = 19] = "Directionality";
73153  LocaleDataIndex[LocaleDataIndex["PluralCase"] = 20] = "PluralCase";
73154  LocaleDataIndex[LocaleDataIndex["ExtraData"] = 21] = "ExtraData";
73155})(LocaleDataIndex || (LocaleDataIndex = {}));
73156/**
73157 * Returns the canonical form of a locale name - lowercase with `_` replaced with `-`.
73158 */
73159
73160
73161function normalizeLocale(locale) {
73162  return locale.toLowerCase().replace(/_/g, '-');
73163}
73164/**
73165 * @license
73166 * Copyright Google LLC All Rights Reserved.
73167 *
73168 * Use of this source code is governed by an MIT-style license that can be
73169 * found in the LICENSE file at https://angular.io/license
73170 */
73171
73172
73173const pluralMapping = ['zero', 'one', 'two', 'few', 'many'];
73174/**
73175 * Returns the plural case based on the locale
73176 */
73177
73178function getPluralCase(value, locale) {
73179  const plural = getLocalePluralCase(locale)(parseInt(value, 10));
73180  const result = pluralMapping[plural];
73181  return result !== undefined ? result : 'other';
73182}
73183/**
73184 * The locale id that the application is using by default (for translations and ICU expressions).
73185 */
73186
73187
73188const DEFAULT_LOCALE_ID = 'en-US';
73189/**
73190 * USD currency code that the application uses by default for CurrencyPipe when no
73191 * DEFAULT_CURRENCY_CODE is provided.
73192 */
73193
73194const USD_CURRENCY_CODE = 'USD';
73195/**
73196 * @license
73197 * Copyright Google LLC All Rights Reserved.
73198 *
73199 * Use of this source code is governed by an MIT-style license that can be
73200 * found in the LICENSE file at https://angular.io/license
73201 */
73202
73203/**
73204 * Marks that the next string is an element name.
73205 *
73206 * See `I18nMutateOpCodes` documentation.
73207 */
73208
73209const ELEMENT_MARKER = {
73210  marker: 'element'
73211};
73212/**
73213 * Marks that the next string is comment text need for ICU.
73214 *
73215 * See `I18nMutateOpCodes` documentation.
73216 */
73217
73218const ICU_MARKER = {
73219  marker: 'ICU'
73220};
73221/**
73222 * See `I18nCreateOpCodes`
73223 */
73224
73225var I18nCreateOpCode;
73226
73227(function (I18nCreateOpCode) {
73228  /**
73229   * Number of bits to shift index so that it can be combined with the `APPEND_EAGERLY` and
73230   * `COMMENT`.
73231   */
73232  I18nCreateOpCode[I18nCreateOpCode["SHIFT"] = 2] = "SHIFT";
73233  /**
73234   * Should the node be appended to parent immediately after creation.
73235   */
73236
73237  I18nCreateOpCode[I18nCreateOpCode["APPEND_EAGERLY"] = 1] = "APPEND_EAGERLY";
73238  /**
73239   * If set the node should be comment (rather than a text) node.
73240   */
73241
73242  I18nCreateOpCode[I18nCreateOpCode["COMMENT"] = 2] = "COMMENT";
73243})(I18nCreateOpCode || (I18nCreateOpCode = {})); // Note: This hack is necessary so we don't erroneously get a circular dependency
73244// failure based on types.
73245
73246
73247const unusedValueExportToPlacateAjd$2 = 1;
73248/**
73249 * @license
73250 * Copyright Google LLC All Rights Reserved.
73251 *
73252 * Use of this source code is governed by an MIT-style license that can be
73253 * found in the LICENSE file at https://angular.io/license
73254 */
73255
73256/**
73257 * The locale id that the application is currently using (for translations and ICU expressions).
73258 * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
73259 * but is now defined as a global value.
73260 */
73261
73262let LOCALE_ID$1 = DEFAULT_LOCALE_ID;
73263/**
73264 * Sets the locale id that will be used for translations and ICU expressions.
73265 * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
73266 * but is now defined as a global value.
73267 *
73268 * @param localeId
73269 */
73270
73271function setLocaleId(localeId) {
73272  assertDefined(localeId, `Expected localeId to be defined`);
73273
73274  if (typeof localeId === 'string') {
73275    LOCALE_ID$1 = localeId.toLowerCase().replace(/_/g, '-');
73276  }
73277}
73278/**
73279 * Gets the locale id that will be used for translations and ICU expressions.
73280 * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
73281 * but is now defined as a global value.
73282 */
73283
73284
73285function getLocaleId() {
73286  return LOCALE_ID$1;
73287}
73288/**
73289 * @license
73290 * Copyright Google LLC All Rights Reserved.
73291 *
73292 * Use of this source code is governed by an MIT-style license that can be
73293 * found in the LICENSE file at https://angular.io/license
73294 */
73295
73296/**
73297 * Find a node in front of which `currentTNode` should be inserted (takes i18n into account).
73298 *
73299 * This method determines the `RNode` in front of which we should insert the `currentRNode`. This
73300 * takes `TNode.insertBeforeIndex` into account.
73301 *
73302 * @param parentTNode parent `TNode`
73303 * @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
73304 * @param lView current `LView`
73305 */
73306
73307
73308function getInsertInFrontOfRNodeWithI18n(parentTNode, currentTNode, lView) {
73309  const tNodeInsertBeforeIndex = currentTNode.insertBeforeIndex;
73310  const insertBeforeIndex = Array.isArray(tNodeInsertBeforeIndex) ? tNodeInsertBeforeIndex[0] : tN
vendor: 5,669 bytes, lines 73310-73459
73310odeInsertBeforeIndex;
73311
73312  if (insertBeforeIndex === null) {
73313    return getInsertInFrontOfRNodeWithNoI18n(parentTNode, currentTNode, lView);
73314  } else {
73315    ngDevMode && assertIndexInRange(lView, insertBeforeIndex);
73316    return unwrapRNode(lView[insertBeforeIndex]);
73317  }
73318}
73319/**
73320 * Process `TNode.insertBeforeIndex` by adding i18n text nodes.
73321 *
73322 * See `TNode.insertBeforeIndex`
73323 */
73324
73325
73326function processI18nInsertBefore(renderer, childTNode, lView, childRNode, parentRElement) {
73327  const tNodeInsertBeforeIndex = childTNode.insertBeforeIndex;
73328
73329  if (Array.isArray(tNodeInsertBeforeIndex)) {
73330    // An array indicates that there are i18n nodes that need to be added as children of this
73331    // `childRNode`. These i18n nodes were created before this `childRNode` was available and so
73332    // only now can be added. The first element of the array is the normal index where we should
73333    // insert the `childRNode`. Additional elements are the extra nodes to be added as children of
73334    // `childRNode`.
73335    ngDevMode && assertDomNode(childRNode);
73336    let i18nParent = childRNode;
73337    let anchorRNode = null;
73338
73339    if (!(childTNode.type & 3
73340    /* TNodeType.AnyRNode */
73341    )) {
73342      anchorRNode = i18nParent;
73343      i18nParent = parentRElement;
73344    }
73345
73346    if (i18nParent !== null && (childTNode.flags & 2
73347    /* TNodeFlags.isComponentHost */
73348    ) === 0) {
73349      for (let i = 1; i < tNodeInsertBeforeIndex.length; i++) {
73350        // No need to `unwrapRNode` because all of the indexes point to i18n text nodes.
73351        // see `assertDomNode` below.
73352        const i18nChild = lView[tNodeInsertBeforeIndex[i]];
73353        nativeInsertBefore(renderer, i18nParent, i18nChild, anchorRNode, false);
73354      }
73355    }
73356  }
73357}
73358/**
73359 * @license
73360 * Copyright Google LLC All Rights Reserved.
73361 *
73362 * Use of this source code is governed by an MIT-style license that can be
73363 * found in the LICENSE file at https://angular.io/license
73364 */
73365
73366/**
73367 * Add `tNode` to `previousTNodes` list and update relevant `TNode`s in `previousTNodes` list
73368 * `tNode.insertBeforeIndex`.
73369 *
73370 * Things to keep in mind:
73371 * 1. All i18n text nodes are encoded as `TNodeType.Element` and are created eagerly by the
73372 *    `ɵɵi18nStart` instruction.
73373 * 2. All `TNodeType.Placeholder` `TNodes` are elements which will be created later by
73374 *    `ɵɵelementStart` instruction.
73375 * 3. `ɵɵelementStart` instruction will create `TNode`s in the ascending `TNode.index` order. (So a
73376 *    smaller index `TNode` is guaranteed to be created before a larger one)
73377 *
73378 * We use the above three invariants to determine `TNode.insertBeforeIndex`.
73379 *
73380 * In an ideal world `TNode.insertBeforeIndex` would always be `TNode.next.index`. However,
73381 * this will not work because `TNode.next.index` may be larger than `TNode.index` which means that
73382 * the next node is not yet created and therefore we can't insert in front of it.
73383 *
73384 * Rule1: `TNode.insertBeforeIndex = null` if `TNode.next === null` (Initial condition, as we don't
73385 *        know if there will be further `TNode`s inserted after.)
73386 * Rule2: If `previousTNode` is created after the `tNode` being inserted, then
73387 *        `previousTNode.insertBeforeNode = tNode.index` (So when a new `tNode` is added we check
73388 *        previous to see if we can update its `insertBeforeTNode`)
73389 *
73390 * See `TNode.insertBeforeIndex` for more context.
73391 *
73392 * @param previousTNodes A list of previous TNodes so that we can easily traverse `TNode`s in
73393 *     reverse order. (If `TNode` would have `previous` this would not be necessary.)
73394 * @param newTNode A TNode to add to the `previousTNodes` list.
73395 */
73396
73397
73398function addTNodeAndUpdateInsertBeforeIndex(previousTNodes, newTNode) {
73399  // Start with Rule1
73400  ngDevMode && assertEqual(newTNode.insertBeforeIndex, null, 'We expect that insertBeforeIndex is not set');
73401  previousTNodes.push(newTNode);
73402
73403  if (previousTNodes.length > 1) {
73404    for (let i = previousTNodes.length - 2; i >= 0; i--) {
73405      const existingTNode = previousTNodes[i]; // Text nodes are created eagerly and so they don't need their `indexBeforeIndex` updated.
73406      // It is safe to ignore them.
73407
73408      if (!isI18nText(existingTNode)) {
73409        if (isNewTNodeCreatedBefore(existingTNode, newTNode) && getInsertBeforeIndex(existingTNode) === null) {
73410          // If it was created before us in time, (and it does not yet have `insertBeforeIndex`)
73411          // then add the `insertBeforeIndex`.
73412          setInsertBeforeIndex(existingTNode, newTNode.index);
73413        }
73414      }
73415    }
73416  }
73417}
73418
73419function isI18nText(tNode) {
73420  return !(tNode.type & 64
73421  /* TNodeType.Placeholder */
73422  );
73423}
73424
73425function isNewTNodeCreatedBefore(existingTNode, newTNode) {
73426  return isI18nText(newTNode) || existingTNode.index > newTNode.index;
73427}
73428
73429function getInsertBeforeIndex(tNode) {
73430  const index = tNode.insertBeforeIndex;
73431  return Array.isArray(index) ? index[0] : index;
73432}
73433
73434function setInsertBeforeIndex(tNode, value) {
73435  const index = tNode.insertBeforeIndex;
73436
73437  if (Array.isArray(index)) {
73438    // Array is stored if we have to insert child nodes. See `TNode.insertBeforeIndex`
73439    index[0] = value;
73440  } else {
73441    setI18nHandling(getInsertInFrontOfRNodeWithI18n, processI18nInsertBefore);
73442    tNode.insertBeforeIndex = value;
73443  }
73444}
73445/**
73446 * @license
73447 * Copyright Google LLC All Rights Reserved.
73448 *
73449 * Use of this source code is governed by an MIT-style license that can be
73450 * found in the LICENSE file at https://angular.io/license
73451 */
73452
73453/**
73454 * Retrieve `TIcu` at a given `index`.
73455 *
73456 * The `TIcu` can be stored either directly (if it is nested ICU) OR
73457 * it is stored inside tho `TIcuContainer` if it is top level ICU.
73458 *
73459 * The reason for this is that the top level ICU need a `TNode` so that they are part of the render
73460 * tree, but nested ICU's have no TNode, because we don't know ahead of time if the nested ICU is
73461 * expressed (parent ICU may have selected a case which does not contain it.)
73462 *
73463 * @param tView Current `TView`.
73464 * @param index Index where the value should be read from.
73465 */
73466
73467
73468function getTIcu(tView, index) {
73469  const value = tView.data[index];
73470  if (value === null || typeof value === 'string') return null;
73471
73472  if (ngDevMode && !(value.hasOwnProperty('tViews') || value.hasOwnProperty('currentCaseLViewIndex'))) {
73473    throwError('We expect to get \'null\'|\'TIcu\'|\'TIcuContainer\', but got: ' + value);
73474  } // Here the `value.hasOwnProperty('currentCaseLViewIndex')` is a polymorphic read as it can be
73475  // either TIcu or TIcuContainerNode. This is not ideal, but we still think it is OK because it
73476  // will be just two cases which fits into the browser inline cache (inline cache can take up to
73477  // 4)
73478
73479
73480  const tIcu = value.hasOwnProperty('currentCaseLViewIndex') ? value : value.value;
73481  ngDevMode && assertTIcu(tIcu);
73482  return tIcu;
73483}
73484/**
73485 * Store `TIcu` at a give `index`.
73486 *
73487 * The `TIcu` can be stored either directly (if it is nested ICU) OR
73488 * it is stored inside tho `TIcuContainer` if it is top level ICU.
73489 *
73490 * The reason for this is that the top level ICU need a `TNode` so that they are part of the render
vendor: 84,070 bytes, lines 73491-75898
73491 * tree, but nested ICU's have no TNode, because we don't know ahead of time if the nested ICU is
73492 * expressed (parent ICU may have selected a case which does not contain it.)
73493 *
73494 * @param tView Current `TView`.
73495 * @param index Index where the value should be stored at in `Tview.data`
73496 * @param tIcu The TIcu to store.
73497 */
73498
73499
73500function setTIcu(tView, index, tIcu) {
73501  const tNode = tView.data[index];
73502  ngDevMode && assertEqual(tNode === null || tNode.hasOwnProperty('tViews'), true, 'We expect to get \'null\'|\'TIcuContainer\'');
73503
73504  if (tNode === null) {
73505    tView.data[index] = tIcu;
73506  } else {
73507    ngDevMode && assertTNodeType(tNode, 32
73508    /* TNodeType.Icu */
73509    );
73510    tNode.value = tIcu;
73511  }
73512}
73513/**
73514 * Set `TNode.insertBeforeIndex` taking the `Array` into account.
73515 *
73516 * See `TNode.insertBeforeIndex`
73517 */
73518
73519
73520function setTNodeInsertBeforeIndex(tNode, index) {
73521  ngDevMode && assertTNode(tNode);
73522  let insertBeforeIndex = tNode.insertBeforeIndex;
73523
73524  if (insertBeforeIndex === null) {
73525    setI18nHandling(getInsertInFrontOfRNodeWithI18n, processI18nInsertBefore);
73526    insertBeforeIndex = tNode.insertBeforeIndex = [null
73527    /* may be updated to number later */
73528    , index];
73529  } else {
73530    assertEqual(Array.isArray(insertBeforeIndex), true, 'Expecting array here');
73531    insertBeforeIndex.push(index);
73532  }
73533}
73534/**
73535 * Create `TNode.type=TNodeType.Placeholder` node.
73536 *
73537 * See `TNodeType.Placeholder` for more information.
73538 */
73539
73540
73541function createTNodePlaceholder(tView, previousTNodes, index) {
73542  const tNode = createTNodeAtIndex(tView, index, 64
73543  /* TNodeType.Placeholder */
73544  , null, null);
73545  addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tNode);
73546  return tNode;
73547}
73548/**
73549 * Returns current ICU case.
73550 *
73551 * ICU cases are stored as index into the `TIcu.cases`.
73552 * At times it is necessary to communicate that the ICU case just switched and that next ICU update
73553 * should update all bindings regardless of the mask. In such a case the we store negative numbers
73554 * for cases which have just been switched. This function removes the negative flag.
73555 */
73556
73557
73558function getCurrentICUCaseIndex(tIcu, lView) {
73559  const currentCase = lView[tIcu.currentCaseLViewIndex];
73560  return currentCase === null ? currentCase : currentCase < 0 ? ~currentCase : currentCase;
73561}
73562
73563function getParentFromIcuCreateOpCode(mergedCode) {
73564  return mergedCode >>> 17
73565  /* IcuCreateOpCode.SHIFT_PARENT */
73566  ;
73567}
73568
73569function getRefFromIcuCreateOpCode(mergedCode) {
73570  return (mergedCode & 131070
73571  /* IcuCreateOpCode.MASK_REF */
73572  ) >>> 1
73573  /* IcuCreateOpCode.SHIFT_REF */
73574  ;
73575}
73576
73577function getInstructionFromIcuCreateOpCode(mergedCode) {
73578  return mergedCode & 1
73579  /* IcuCreateOpCode.MASK_INSTRUCTION */
73580  ;
73581}
73582
73583function icuCreateOpCode(opCode, parentIdx, refIdx) {
73584  ngDevMode && assertGreaterThanOrEqual(parentIdx, 0, 'Missing parent index');
73585  ngDevMode && assertGreaterThan(refIdx, 0, 'Missing ref index');
73586  return opCode | parentIdx << 17
73587  /* IcuCreateOpCode.SHIFT_PARENT */
73588  | refIdx << 1
73589  /* IcuCreateOpCode.SHIFT_REF */
73590  ;
73591}
73592/**
73593 * @license
73594 * Copyright Google LLC All Rights Reserved.
73595 *
73596 * Use of this source code is governed by an MIT-style license that can be
73597 * found in the LICENSE file at https://angular.io/license
73598 */
73599
73600/**
73601 * Keep track of which input bindings in `ɵɵi18nExp` have changed.
73602 *
73603 * This is used to efficiently update expressions in i18n only when the corresponding input has
73604 * changed.
73605 *
73606 * 1) Each bit represents which of the `ɵɵi18nExp` has changed.
73607 * 2) There are 32 bits allowed in JS.
73608 * 3) Bit 32 is special as it is shared for all changes past 32. (In other words if you have more
73609 * than 32 `ɵɵi18nExp` then all changes past 32nd `ɵɵi18nExp` will be mapped to same bit. This means
73610 * that we may end up changing more than we need to. But i18n expressions with 32 bindings is rare
73611 * so in practice it should not be an issue.)
73612 */
73613
73614
73615let changeMask = 0b0;
73616/**
73617 * Keeps track of which bit needs to be updated in `changeMask`
73618 *
73619 * This value gets incremented on every call to `ɵɵi18nExp`
73620 */
73621
73622let changeMaskCounter = 0;
73623/**
73624 * Keep track of which input bindings in `ɵɵi18nExp` have changed.
73625 *
73626 * `setMaskBit` gets invoked by each call to `ɵɵi18nExp`.
73627 *
73628 * @param hasChange did `ɵɵi18nExp` detect a change.
73629 */
73630
73631function setMaskBit(hasChange) {
73632  if (hasChange) {
73633    changeMask = changeMask | 1 << Math.min(changeMaskCounter, 31);
73634  }
73635
73636  changeMaskCounter++;
73637}
73638
73639function applyI18n(tView, lView, index) {
73640  if (changeMaskCounter > 0) {
73641    ngDevMode && assertDefined(tView, `tView should be defined`);
73642    const tI18n = tView.data[index]; // When `index` points to an `ɵɵi18nAttributes` then we have an array otherwise `TI18n`
73643
73644    const updateOpCodes = Array.isArray(tI18n) ? tI18n : tI18n.update;
73645    const bindingsStartIndex = getBindingIndex() - changeMaskCounter - 1;
73646    applyUpdateOpCodes(tView, lView, updateOpCodes, bindingsStartIndex, changeMask);
73647  } // Reset changeMask & maskBit to default for the next update cycle
73648
73649
73650  changeMask = 0b0;
73651  changeMaskCounter = 0;
73652}
73653/**
73654 * Apply `I18nCreateOpCodes` op-codes as stored in `TI18n.create`.
73655 *
73656 * Creates text (and comment) nodes which are internationalized.
73657 *
73658 * @param lView Current lView
73659 * @param createOpCodes Set of op-codes to apply
73660 * @param parentRNode Parent node (so that direct children can be added eagerly) or `null` if it is
73661 *     a root node.
73662 * @param insertInFrontOf DOM node that should be used as an anchor.
73663 */
73664
73665
73666function applyCreateOpCodes(lView, createOpCodes, parentRNode, insertInFrontOf) {
73667  const renderer = lView[RENDERER];
73668
73669  for (let i = 0; i < createOpCodes.length; i++) {
73670    const opCode = createOpCodes[i++];
73671    const text = createOpCodes[i];
73672    const isComment = (opCode & I18nCreateOpCode.COMMENT) === I18nCreateOpCode.COMMENT;
73673    const appendNow = (opCode & I18nCreateOpCode.APPEND_EAGERLY) === I18nCreateOpCode.APPEND_EAGERLY;
73674    const index = opCode >>> I18nCreateOpCode.SHIFT;
73675    let rNode = lView[index];
73676
73677    if (rNode === null) {
73678      // We only create new DOM nodes if they don't already exist: If ICU switches case back to a
73679      // case which was already instantiated, no need to create new DOM nodes.
73680      rNode = lView[index] = isComment ? renderer.createComment(text) : createTextNode(renderer, text);
73681    }
73682
73683    if (appendNow && parentRNode !== null) {
73684      nativeInsertBefore(renderer, parentRNode, rNode, insertInFrontOf, false);
73685    }
73686  }
73687}
73688/**
73689 * Apply `I18nMutateOpCodes` OpCodes.
73690 *
73691 * @param tView Current `TView`
73692 * @param mutableOpCodes Mutable OpCodes to process
73693 * @param lView Current `LView`
73694 * @param anchorRNode place where the i18n node should be inserted.
73695 */
73696
73697
73698function applyMutableOpCodes(tView, mutableOpCodes, lView, anchorRNode) {
73699  ngDevMode && assertDomNode(anchorRNode);
73700  const renderer = lView[RENDERER]; // `rootIdx` represents the node into which all inserts happen.
73701
73702  let rootIdx = null; // `rootRNode` represents the real node into which we insert. This can be different from
73703  // `lView[rootIdx]` if we have projection.
73704  //  - null we don't have a parent (as can be the case in when we are inserting into a root of
73705  //    LView which has no parent.)
73706  //  - `RElement` The element representing the root after taking projection into account.
73707
73708  let rootRNode;
73709
73710  for (let i = 0; i < mutableOpCodes.length; i++) {
73711    const opCode = mutableOpCodes[i];
73712
73713    if (typeof opCode == 'string') {
73714      const textNodeIndex = mutableOpCodes[++i];
73715
73716      if (lView[textNodeIndex] === null) {
73717        ngDevMode && ngDevMode.rendererCreateTextNode++;
73718        ngDevMode && assertIndexInRange(lView, textNodeIndex);
73719        lView[textNodeIndex] = createTextNode(renderer, opCode);
73720      }
73721    } else if (typeof opCode == 'number') {
73722      switch (opCode & 1
73723      /* IcuCreateOpCode.MASK_INSTRUCTION */
73724      ) {
73725        case 0
73726        /* IcuCreateOpCode.AppendChild */
73727        :
73728          const parentIdx = getParentFromIcuCreateOpCode(opCode);
73729
73730          if (rootIdx === null) {
73731            // The first operation should save the `rootIdx` because the first operation
73732            // must insert into the root. (Only subsequent operations can insert into a dynamic
73733            // parent)
73734            rootIdx = parentIdx;
73735            rootRNode = nativeParentNode(renderer, anchorRNode);
73736          }
73737
73738          let insertInFrontOf;
73739          let parentRNode;
73740
73741          if (parentIdx === rootIdx) {
73742            insertInFrontOf = anchorRNode;
73743            parentRNode = rootRNode;
73744          } else {
73745            insertInFrontOf = null;
73746            parentRNode = unwrapRNode(lView[parentIdx]);
73747          } // FIXME(misko): Refactor with `processI18nText`
73748
73749
73750          if (parentRNode !== null) {
73751            // This can happen if the `LView` we are adding to is not attached to a parent `LView`.
73752            // In such a case there is no "root" we can attach to. This is fine, as we still need to
73753            // create the elements. When the `LView` gets later added to a parent these "root" nodes
73754            // get picked up and added.
73755            ngDevMode && assertDomNode(parentRNode);
73756            const refIdx = getRefFromIcuCreateOpCode(opCode);
73757            ngDevMode && assertGreaterThan(refIdx, HEADER_OFFSET, 'Missing ref'); // `unwrapRNode` is not needed here as all of these point to RNodes as part of the i18n
73758            // which can't have components.
73759
73760            const child = lView[refIdx];
73761            ngDevMode && assertDomNode(child);
73762            nativeInsertBefore(renderer, parentRNode, child, insertInFrontOf, false);
73763            const tIcu = getTIcu(tView, refIdx);
73764
73765            if (tIcu !== null && typeof tIcu === 'object') {
73766              // If we just added a comment node which has ICU then that ICU may have already been
73767              // rendered and therefore we need to re-add it here.
73768              ngDevMode && assertTIcu(tIcu);
73769              const caseIndex = getCurrentICUCaseIndex(tIcu, lView);
73770
73771              if (caseIndex !== null) {
73772                applyMutableOpCodes(tView, tIcu.create[caseIndex], lView, lView[tIcu.anchorIdx]);
73773              }
73774            }
73775          }
73776
73777          break;
73778
73779        case 1
73780        /* IcuCreateOpCode.Attr */
73781        :
73782          const elementNodeIndex = opCode >>> 1
73783          /* IcuCreateOpCode.SHIFT_REF */
73784          ;
73785          const attrName = mutableOpCodes[++i];
73786          const attrValue = mutableOpCodes[++i]; // This code is used for ICU expressions only, since we don't support
73787          // directives/components in ICUs, we don't need to worry about inputs here
73788
73789          setElementAttribute(renderer, getNativeByIndex(elementNodeIndex, lView), null, null, attrName, attrValue, null);
73790          break;
73791
73792        default:
73793          if (ngDevMode) {
73794            throw new RuntimeError(700
73795            /* RuntimeErrorCode.INVALID_I18N_STRUCTURE */
73796            , `Unable to determine the type of mutate operation for "${opCode}"`);
73797          }
73798
73799      }
73800    } else {
73801      switch (opCode) {
73802        case ICU_MARKER:
73803          const commentValue = mutableOpCodes[++i];
73804          const commentNodeIndex = mutableOpCodes[++i];
73805
73806          if (lView[commentNodeIndex] === null) {
73807            ngDevMode && assertEqual(typeof commentValue, 'string', `Expected "${commentValue}" to be a comment node value`);
73808            ngDevMode && ngDevMode.rendererCreateComment++;
73809            ngDevMode && assertIndexInExpandoRange(lView, commentNodeIndex);
73810            const commentRNode = lView[commentNodeIndex] = createCommentNode(renderer, commentValue); // FIXME(misko): Attaching patch data is only needed for the root (Also add tests)
73811
73812            attachPatchData(commentRNode, lView);
73813          }
73814
73815          break;
73816
73817        case ELEMENT_MARKER:
73818          const tagName = mutableOpCodes[++i];
73819          const elementNodeIndex = mutableOpCodes[++i];
73820
73821          if (lView[elementNodeIndex] === null) {
73822            ngDevMode && assertEqual(typeof tagName, 'string', `Expected "${tagName}" to be an element node tag name`);
73823            ngDevMode && ngDevMode.rendererCreateElement++;
73824            ngDevMode && assertIndexInExpandoRange(lView, elementNodeIndex);
73825            const elementRNode = lView[elementNodeIndex] = createElementNode(renderer, tagName, null); // FIXME(misko): Attaching patch data is only needed for the root (Also add tests)
73826
73827            attachPatchData(elementRNode, lView);
73828          }
73829
73830          break;
73831
73832        default:
73833          ngDevMode && throwError(`Unable to determine the type of mutate operation for "${opCode}"`);
73834      }
73835    }
73836  }
73837}
73838/**
73839 * Apply `I18nUpdateOpCodes` OpCodes
73840 *
73841 * @param tView Current `TView`
73842 * @param lView Current `LView`
73843 * @param updateOpCodes OpCodes to process
73844 * @param bindingsStartIndex Location of the first `ɵɵi18nApply`
73845 * @param changeMask Each bit corresponds to a `ɵɵi18nExp` (Counting backwards from
73846 *     `bindingsStartIndex`)
73847 */
73848
73849
73850function applyUpdateOpCodes(tView, lView, updateOpCodes, bindingsStartIndex, changeMask) {
73851  for (let i = 0; i < updateOpCodes.length; i++) {
73852    // bit code to check if we should apply the next update
73853    const checkBit = updateOpCodes[i]; // Number of opCodes to skip until next set of update codes
73854
73855    const skipCodes = updateOpCodes[++i];
73856
73857    if (checkBit & changeMask) {
73858      // The value has been updated since last checked
73859      let value = '';
73860
73861      for (let j = i + 1; j <= i + skipCodes; j++) {
73862        const opCode = updateOpCodes[j];
73863
73864        if (typeof opCode == 'string') {
73865          value += opCode;
73866        } else if (typeof opCode == 'number') {
73867          if (opCode < 0) {
73868            // Negative opCode represent `i18nExp` values offset.
73869            value += renderStringify(lView[bindingsStartIndex - opCode]);
73870          } else {
73871            const nodeIndex = opCode >>> 2
73872            /* I18nUpdateOpCode.SHIFT_REF */
73873            ;
73874
73875            switch (opCode & 3
73876            /* I18nUpdateOpCode.MASK_OPCODE */
73877            ) {
73878              case 1
73879              /* I18nUpdateOpCode.Attr */
73880              :
73881                const propName = updateOpCodes[++j];
73882                const sanitizeFn = updateOpCodes[++j];
73883                const tNodeOrTagName = tView.data[nodeIndex];
73884                ngDevMode && assertDefined(tNodeOrTagName, 'Experting TNode or string');
73885
73886                if (typeof tNodeOrTagName === 'string') {
73887                  // IF we don't have a `TNode`, then we are an element in ICU (as ICU content does
73888                  // not have TNode), in which case we know that there are no directives, and hence
73889                  // we use attribute setting.
73890                  setElementAttribute(lView[RENDERER], lView[nodeIndex], null, tNodeOrTagName, propName, value, sanitizeFn);
73891                } else {
73892                  elementPropertyInternal(tView, tNodeOrTagName, lView, propName, value, lView[RENDERER], sanitizeFn, false);
73893                }
73894
73895                break;
73896
73897              case 0
73898              /* I18nUpdateOpCode.Text */
73899              :
73900                const rText = lView[nodeIndex];
73901                rText !== null && updateTextNode(lView[RENDERER], rText, value);
73902                break;
73903
73904              case 2
73905              /* I18nUpdateOpCode.IcuSwitch */
73906              :
73907                applyIcuSwitchCase(tView, getTIcu(tView, nodeIndex), lView, value);
73908                break;
73909
73910              case 3
73911              /* I18nUpdateOpCode.IcuUpdate */
73912              :
73913                applyIcuUpdateCase(tView, getTIcu(tView, nodeIndex), bindingsStartIndex, lView);
73914                break;
73915            }
73916          }
73917        }
73918      }
73919    } else {
73920      const opCode = updateOpCodes[i + 1];
73921
73922      if (opCode > 0 && (opCode & 3
73923      /* I18nUpdateOpCode.MASK_OPCODE */
73924      ) === 3
73925      /* I18nUpdateOpCode.IcuUpdate */
73926      ) {
73927        // Special case for the `icuUpdateCase`. It could be that the mask did not match, but
73928        // we still need to execute `icuUpdateCase` because the case has changed recently due to
73929        // previous `icuSwitchCase` instruction. (`icuSwitchCase` and `icuUpdateCase` always come in
73930        // pairs.)
73931        const nodeIndex = opCode >>> 2
73932        /* I18nUpdateOpCode.SHIFT_REF */
73933        ;
73934        const tIcu = getTIcu(tView, nodeIndex);
73935        const currentIndex = lView[tIcu.currentCaseLViewIndex];
73936
73937        if (currentIndex < 0) {
73938          applyIcuUpdateCase(tView, tIcu, bindingsStartIndex, lView);
73939        }
73940      }
73941    }
73942
73943    i += skipCodes;
73944  }
73945}
73946/**
73947 * Apply OpCodes associated with updating an existing ICU.
73948 *
73949 * @param tView Current `TView`
73950 * @param tIcu Current `TIcu`
73951 * @param bindingsStartIndex Location of the first `ɵɵi18nApply`
73952 * @param lView Current `LView`
73953 */
73954
73955
73956function applyIcuUpdateCase(tView, tIcu, bindingsStartIndex, lView) {
73957  ngDevMode && assertIndexInRange(lView, tIcu.currentCaseLViewIndex);
73958  let activeCaseIndex = lView[tIcu.currentCaseLViewIndex];
73959
73960  if (activeCaseIndex !== null) {
73961    let mask = changeMask;
73962
73963    if (activeCaseIndex < 0) {
73964      // Clear the flag.
73965      // Negative number means that the ICU was freshly created and we need to force the update.
73966      activeCaseIndex = lView[tIcu.currentCaseLViewIndex] = ~activeCaseIndex; // -1 is same as all bits on, which simulates creation since it marks all bits dirty
73967
73968      mask = -1;
73969    }
73970
73971    applyUpdateOpCodes(tView, lView, tIcu.update[activeCaseIndex], bindingsStartIndex, mask);
73972  }
73973}
73974/**
73975 * Apply OpCodes associated with switching a case on ICU.
73976 *
73977 * This involves tearing down existing case and than building up a new case.
73978 *
73979 * @param tView Current `TView`
73980 * @param tIcu Current `TIcu`
73981 * @param lView Current `LView`
73982 * @param value Value of the case to update to.
73983 */
73984
73985
73986function applyIcuSwitchCase(tView, tIcu, lView, value) {
73987  // Rebuild a new case for this ICU
73988  const caseIndex = getCaseIndex(tIcu, value);
73989  let activeCaseIndex = getCurrentICUCaseIndex(tIcu, lView);
73990
73991  if (activeCaseIndex !== caseIndex) {
73992    applyIcuSwitchCaseRemove(tView, tIcu, lView);
73993    lView[tIcu.currentCaseLViewIndex] = caseIndex === null ? null : ~caseIndex;
73994
73995    if (caseIndex !== null) {
73996      // Add the nodes for the new case
73997      const anchorRNode = lView[tIcu.anchorIdx];
73998
73999      if (anchorRNode) {
74000        ngDevMode && assertDomNode(anchorRNode);
74001        applyMutableOpCodes(tView, tIcu.create[caseIndex], lView, anchorRNode);
74002      }
74003    }
74004  }
74005}
74006/**
74007 * Apply OpCodes associated with tearing ICU case.
74008 *
74009 * This involves tearing down existing case and than building up a new case.
74010 *
74011 * @param tView Current `TView`
74012 * @param tIcu Current `TIcu`
74013 * @param lView Current `LView`
74014 */
74015
74016
74017function applyIcuSwitchCaseRemove(tView, tIcu, lView) {
74018  let activeCaseIndex = getCurrentICUCaseIndex(tIcu, lView);
74019
74020  if (activeCaseIndex !== null) {
74021    const removeCodes = tIcu.remove[activeCaseIndex];
74022
74023    for (let i = 0; i < removeCodes.length; i++) {
74024      const nodeOrIcuIndex = removeCodes[i];
74025
74026      if (nodeOrIcuIndex > 0) {
74027        // Positive numbers are `RNode`s.
74028        const rNode = getNativeByIndex(nodeOrIcuIndex, lView);
74029        rNode !== null && nativeRemoveNode(lView[RENDERER], rNode);
74030      } else {
74031        // Negative numbers are ICUs
74032        applyIcuSwitchCaseRemove(tView, getTIcu(tView, ~nodeOrIcuIndex), lView);
74033      }
74034    }
74035  }
74036}
74037/**
74038 * Returns the index of the current case of an ICU expression depending on the main binding value
74039 *
74040 * @param icuExpression
74041 * @param bindingValue The value of the main binding used by this ICU expression
74042 */
74043
74044
74045function getCaseIndex(icuExpression, bindingValue) {
74046  let index = icuExpression.cases.indexOf(bindingValue);
74047
74048  if (index === -1) {
74049    switch (icuExpression.type) {
74050      case 1
74051      /* IcuType.plural */
74052      :
74053        {
74054          const resolvedCase = getPluralCase(bindingValue, getLocaleId());
74055          index = icuExpression.cases.indexOf(resolvedCase);
74056
74057          if (index === -1 && resolvedCase !== 'other') {
74058            index = icuExpression.cases.indexOf('other');
74059          }
74060
74061          break;
74062        }
74063
74064      case 0
74065      /* IcuType.select */
74066      :
74067        {
74068          index = icuExpression.cases.indexOf('other');
74069          break;
74070        }
74071    }
74072  }
74073
74074  return index === -1 ? null : index;
74075}
74076/**
74077 * @license
74078 * Copyright Google LLC All Rights Reserved.
74079 *
74080 * Use of this source code is governed by an MIT-style license that can be
74081 * found in the LICENSE file at https://angular.io/license
74082 */
74083
74084
74085function loadIcuContainerVisitor() {
74086  const _stack = [];
74087
74088  let _index = -1;
74089
74090  let _lView;
74091
74092  let _removes;
74093  /**
74094   * Retrieves a set of root nodes from `TIcu.remove`. Used by `TNodeType.ICUContainer`
74095   * to determine which root belong to the ICU.
74096   *
74097   * Example of usage.
74098   * ```
74099   * const nextRNode = icuContainerIteratorStart(tIcuContainerNode, lView);
74100   * let rNode: RNode|null;
74101   * while(rNode = nextRNode()) {
74102   *   console.log(rNode);
74103   * }
74104   * ```
74105   *
74106   * @param tIcuContainerNode Current `TIcuContainerNode`
74107   * @param lView `LView` where the `RNode`s should be looked up.
74108   */
74109
74110
74111  function icuContainerIteratorStart(tIcuContainerNode, lView) {
74112    _lView = lView;
74113
74114    while (_stack.length) _stack.pop();
74115
74116    ngDevMode && assertTNodeForLView(tIcuContainerNode, lView);
74117    enterIcu(tIcuContainerNode.value, lView);
74118    return icuContainerIteratorNext;
74119  }
74120
74121  function enterIcu(tIcu, lView) {
74122    _index = 0;
74123    const currentCase = getCurrentICUCaseIndex(tIcu, lView);
74124
74125    if (currentCase !== null) {
74126      ngDevMode && assertNumberInRange(currentCase, 0, tIcu.cases.length - 1);
74127      _removes = tIcu.remove[currentCase];
74128    } else {
74129      _removes = EMPTY_ARRAY;
74130    }
74131  }
74132
74133  function icuContainerIteratorNext() {
74134    if (_index < _removes.length) {
74135      const removeOpCode = _removes[_index++];
74136      ngDevMode && assertNumber(removeOpCode, 'Expecting OpCode number');
74137
74138      if (removeOpCode > 0) {
74139        const rNode = _lView[removeOpCode];
74140        ngDevMode && assertDomNode(rNode);
74141        return rNode;
74142      } else {
74143        _stack.push(_index, _removes); // ICUs are represented by negative indices
74144
74145
74146        const tIcuIndex = ~removeOpCode;
74147        const tIcu = _lView[TVIEW].data[tIcuIndex];
74148        ngDevMode && assertTIcu(tIcu);
74149        enterIcu(tIcu, _lView);
74150        return icuContainerIteratorNext();
74151      }
74152    } else {
74153      if (_stack.length === 0) {
74154        return null;
74155      } else {
74156        _removes = _stack.pop();
74157        _index = _stack.pop();
74158        return icuContainerIteratorNext();
74159      }
74160    }
74161  }
74162
74163  return icuContainerIteratorStart;
74164}
74165/**
74166 * @license
74167 * Copyright Google LLC All Rights Reserved.
74168 *
74169 * Use of this source code is governed by an MIT-style license that can be
74170 * found in the LICENSE file at https://angular.io/license
74171 */
74172
74173/**
74174 * Converts `I18nCreateOpCodes` array into a human readable format.
74175 *
74176 * This function is attached to the `I18nCreateOpCodes.debug` property if `ngDevMode` is enabled.
74177 * This function provides a human readable view of the opcodes. This is useful when debugging the
74178 * application as well as writing more readable tests.
74179 *
74180 * @param this `I18nCreateOpCodes` if attached as a method.
74181 * @param opcodes `I18nCreateOpCodes` if invoked as a function.
74182 */
74183
74184
74185function i18nCreateOpCodesToString(opcodes) {
74186  const createOpCodes = opcodes || (Array.isArray(this) ? this : []);
74187  let lines = [];
74188
74189  for (let i = 0; i < createOpCodes.length; i++) {
74190    const opCode = createOpCodes[i++];
74191    const text = createOpCodes[i];
74192    const isComment = (opCode & I18nCreateOpCode.COMMENT) === I18nCreateOpCode.COMMENT;
74193    const appendNow = (opCode & I18nCreateOpCode.APPEND_EAGERLY) === I18nCreateOpCode.APPEND_EAGERLY;
74194    const index = opCode >>> I18nCreateOpCode.SHIFT;
74195    lines.push(`lView[${index}] = document.${isComment ? 'createComment' : 'createText'}(${JSON.stringify(text)});`);
74196
74197    if (appendNow) {
74198      lines.push(`parent.appendChild(lView[${index}]);`);
74199    }
74200  }
74201
74202  return lines;
74203}
74204/**
74205 * Converts `I18nUpdateOpCodes` array into a human readable format.
74206 *
74207 * This function is attached to the `I18nUpdateOpCodes.debug` property if `ngDevMode` is enabled.
74208 * This function provides a human readable view of the opcodes. This is useful when debugging the
74209 * application as well as writing more readable tests.
74210 *
74211 * @param this `I18nUpdateOpCodes` if attached as a method.
74212 * @param opcodes `I18nUpdateOpCodes` if invoked as a function.
74213 */
74214
74215
74216function i18nUpdateOpCodesToString(opcodes) {
74217  const parser = new OpCodeParser(opcodes || (Array.isArray(this) ? this : []));
74218  let lines = [];
74219
74220  function consumeOpCode(value) {
74221    const ref = value >>> 2
74222    /* I18nUpdateOpCode.SHIFT_REF */
74223    ;
74224    const opCode = value & 3
74225    /* I18nUpdateOpCode.MASK_OPCODE */
74226    ;
74227
74228    switch (opCode) {
74229      case 0
74230      /* I18nUpdateOpCode.Text */
74231      :
74232        return `(lView[${ref}] as Text).textContent = $$$`;
74233
74234      case 1
74235      /* I18nUpdateOpCode.Attr */
74236      :
74237        const attrName = parser.consumeString();
74238        const sanitizationFn = parser.consumeFunction();
74239        const value = sanitizationFn ? `(${sanitizationFn})($$$)` : '$$$';
74240        return `(lView[${ref}] as Element).setAttribute('${attrName}', ${value})`;
74241
74242      case 2
74243      /* I18nUpdateOpCode.IcuSwitch */
74244      :
74245        return `icuSwitchCase(${ref}, $$$)`;
74246
74247      case 3
74248      /* I18nUpdateOpCode.IcuUpdate */
74249      :
74250        return `icuUpdateCase(${ref})`;
74251    }
74252
74253    throw new Error('unexpected OpCode');
74254  }
74255
74256  while (parser.hasMore()) {
74257    let mask = parser.consumeNumber();
74258    let size = parser.consumeNumber();
74259    const end = parser.i + size;
74260    const statements = [];
74261    let statement = '';
74262
74263    while (parser.i < end) {
74264      let value = parser.consumeNumberOrString();
74265
74266      if (typeof value === 'string') {
74267        statement += value;
74268      } else if (value < 0) {
74269        // Negative numbers are ref indexes
74270        // Here `i` refers to current binding index. It is to signify that the value is relative,
74271        // rather than absolute.
74272        statement += '${lView[i' + value + ']}';
74273      } else {
74274        // Positive numbers are operations.
74275        const opCodeText = consumeOpCode(value);
74276        statements.push(opCodeText.replace('$$$', '`' + statement + '`') + ';');
74277        statement = '';
74278      }
74279    }
74280
74281    lines.push(`if (mask & 0b${mask.toString(2)}) { ${statements.join(' ')} }`);
74282  }
74283
74284  return lines;
74285}
74286/**
74287 * Converts `I18nCreateOpCodes` array into a human readable format.
74288 *
74289 * This function is attached to the `I18nCreateOpCodes.debug` if `ngDevMode` is enabled. This
74290 * function provides a human readable view of the opcodes. This is useful when debugging the
74291 * application as well as writing more readable tests.
74292 *
74293 * @param this `I18nCreateOpCodes` if attached as a method.
74294 * @param opcodes `I18nCreateOpCodes` if invoked as a function.
74295 */
74296
74297
74298function icuCreateOpCodesToString(opcodes) {
74299  const parser = new OpCodeParser(opcodes || (Array.isArray(this) ? this : []));
74300  let lines = [];
74301
74302  function consumeOpCode(opCode) {
74303    const parent = getParentFromIcuCreateOpCode(opCode);
74304    const ref = getRefFromIcuCreateOpCode(opCode);
74305
74306    switch (getInstructionFromIcuCreateOpCode(opCode)) {
74307      case 0
74308      /* IcuCreateOpCode.AppendChild */
74309      :
74310        return `(lView[${parent}] as Element).appendChild(lView[${lastRef}])`;
74311
74312      case 1
74313      /* IcuCreateOpCode.Attr */
74314      :
74315        return `(lView[${ref}] as Element).setAttribute("${parser.consumeString()}", "${parser.consumeString()}")`;
74316    }
74317
74318    throw new Error('Unexpected OpCode: ' + getInstructionFromIcuCreateOpCode(opCode));
74319  }
74320
74321  let lastRef = -1;
74322
74323  while (parser.hasMore()) {
74324    let value = parser.consumeNumberStringOrMarker();
74325
74326    if (value === ICU_MARKER) {
74327      const text = parser.consumeString();
74328      lastRef = parser.consumeNumber();
74329      lines.push(`lView[${lastRef}] = document.createComment("${text}")`);
74330    } else if (value === ELEMENT_MARKER) {
74331      const text = parser.consumeString();
74332      lastRef = parser.consumeNumber();
74333      lines.push(`lView[${lastRef}] = document.createElement("${text}")`);
74334    } else if (typeof value === 'string') {
74335      lastRef = parser.consumeNumber();
74336      lines.push(`lView[${lastRef}] = document.createTextNode("${value}")`);
74337    } else if (typeof value === 'number') {
74338      const line = consumeOpCode(value);
74339      line && lines.push(line);
74340    } else {
74341      throw new Error('Unexpected value');
74342    }
74343  }
74344
74345  return lines;
74346}
74347/**
74348 * Converts `I18nRemoveOpCodes` array into a human readable format.
74349 *
74350 * This function is attached to the `I18nRemoveOpCodes.debug` if `ngDevMode` is enabled. This
74351 * function provides a human readable view of the opcodes. This is useful when debugging the
74352 * application as well as writing more readable tests.
74353 *
74354 * @param this `I18nRemoveOpCodes` if attached as a method.
74355 * @param opcodes `I18nRemoveOpCodes` if invoked as a function.
74356 */
74357
74358
74359function i18nRemoveOpCodesToString(opcodes) {
74360  const removeCodes = opcodes || (Array.isArray(this) ? this : []);
74361  let lines = [];
74362
74363  for (let i = 0; i < removeCodes.length; i++) {
74364    const nodeOrIcuIndex = removeCodes[i];
74365
74366    if (nodeOrIcuIndex > 0) {
74367      // Positive numbers are `RNode`s.
74368      lines.push(`remove(lView[${nodeOrIcuIndex}])`);
74369    } else {
74370      // Negative numbers are ICUs
74371      lines.push(`removeNestedICU(${~nodeOrIcuIndex})`);
74372    }
74373  }
74374
74375  return lines;
74376}
74377
74378class OpCodeParser {
74379  constructor(codes) {
74380    this.i = 0;
74381    this.codes = codes;
74382  }
74383
74384  hasMore() {
74385    return this.i < this.codes.length;
74386  }
74387
74388  consumeNumber() {
74389    let value = this.codes[this.i++];
74390    assertNumber(value, 'expecting number in OpCode');
74391    return value;
74392  }
74393
74394  consumeString() {
74395    let value = this.codes[this.i++];
74396    assertString(value, 'expecting string in OpCode');
74397    return value;
74398  }
74399
74400  consumeFunction() {
74401    let value = this.codes[this.i++];
74402
74403    if (value === null || typeof value === 'function') {
74404      return value;
74405    }
74406
74407    throw new Error('expecting function in OpCode');
74408  }
74409
74410  consumeNumberOrString() {
74411    let value = this.codes[this.i++];
74412
74413    if (typeof value === 'string') {
74414      return value;
74415    }
74416
74417    assertNumber(value, 'expecting number or string in OpCode');
74418    return value;
74419  }
74420
74421  consumeNumberStringOrMarker() {
74422    let value = this.codes[this.i++];
74423
74424    if (typeof value === 'string' || typeof value === 'number' || value == ICU_MARKER || value == ELEMENT_MARKER) {
74425      return value;
74426    }
74427
74428    assertNumber(value, 'expecting number, string, ICU_MARKER or ELEMENT_MARKER in OpCode');
74429    return value;
74430  }
74431
74432}
74433/**
74434 * @license
74435 * Copyright Google LLC All Rights Reserved.
74436 *
74437 * Use of this source code is governed by an MIT-style license that can be
74438 * found in the LICENSE file at https://angular.io/license
74439 */
74440
74441
74442const BINDING_REGEXP = /�(\d+):?\d*�/gi;
74443const ICU_REGEXP = /({\s*�\d+:?\d*�\s*,\s*\S{6}\s*,[\s\S]*})/gi;
74444const NESTED_ICU = /�(\d+)�/;
74445const ICU_BLOCK_REGEXP = /^\s*(�\d+:?\d*�)\s*,\s*(select|plural)\s*,/;
74446const MARKER = `�`;
74447const SUBTEMPLATE_REGEXP = /�\/?\*(\d+:\d+)�/gi;
74448const PH_REGEXP = /�(\/?[#*]\d+):?\d*�/gi;
74449/**
74450 * Angular Dart introduced &ngsp; as a placeholder for non-removable space, see:
74451 * https://github.com/dart-lang/angular/blob/0bb611387d29d65b5af7f9d2515ab571fd3fbee4/_tests/test/compiler/preserve_whitespace_test.dart#L25-L32
74452 * In Angular Dart &ngsp; is converted to the 0xE500 PUA (Private Use Areas) unicode character
74453 * and later on replaced by a space. We are re-implementing the same idea here, since translations
74454 * might contain this special character.
74455 */
74456
74457const NGSP_UNICODE_REGEXP = /\uE500/g;
74458
74459function replaceNgsp(value) {
74460  return value.replace(NGSP_UNICODE_REGEXP, ' ');
74461}
74462/**
74463 * Create dynamic nodes from i18n translation block.
74464 *
74465 * - Text nodes are created synchronously
74466 * - TNodes are linked into tree lazily
74467 *
74468 * @param tView Current `TView`
74469 * @parentTNodeIndex index to the parent TNode of this i18n block
74470 * @param lView Current `LView`
74471 * @param index Index of `ɵɵi18nStart` instruction.
74472 * @param message Message to translate.
74473 * @param subTemplateIndex Index into the sub template of message translation. (ie in case of
74474 *     `ngIf`) (-1 otherwise)
74475 */
74476
74477
74478function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message, subTemplateIndex) {
74479  const rootTNode = getCurrentParentTNode();
74480  const createOpCodes = [];
74481  const updateOpCodes = [];
74482  const existingTNodeStack = [[]];
74483
74484  if (ngDevMode) {
74485    attachDebugGetter(createOpCodes, i18nCreateOpCodesToString);
74486    attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
74487  }
74488
74489  message = getTranslationForTemplate(message, subTemplateIndex);
74490  const msgParts = replaceNgsp(message).split(PH_REGEXP);
74491
74492  for (let i = 0; i < msgParts.length; i++) {
74493    let value = msgParts[i];
74494
74495    if ((i & 1) === 0) {
74496      // Even indexes are text (including bindings & ICU expressions)
74497      const parts = i18nParseTextIntoPartsAndICU(value);
74498
74499      for (let j = 0; j < parts.length; j++) {
74500        let part = parts[j];
74501
74502        if ((j & 1) === 0) {
74503          // `j` is odd therefore `part` is string
74504          const text = part;
74505          ngDevMode && assertString(text, 'Parsed ICU part should be string');
74506
74507          if (text !== '') {
74508            i18nStartFirstCreatePassProcessTextNode(tView, rootTNode, existingTNodeStack[0], createOpCodes, updateOpCodes, lView, text);
74509          }
74510        } else {
74511          // `j` is Even therefor `part` is an `ICUExpression`
74512          const icuExpression = part; // Verify that ICU expression has the right shape. Translations might contain invalid
74513          // constructions (while original messages were correct), so ICU parsing at runtime may
74514          // not succeed (thus `icuExpression` remains a string).
74515          // Note: we intentionally retain the error here by not using `ngDevMode`, because
74516          // the value can change based on the locale and users aren't guaranteed to hit
74517          // an invalid string while they're developing.
74518
74519          if (typeof icuExpression !== 'object') {
74520            throw new Error(`Unable to parse ICU expression in "${message}" message.`);
74521          }
74522
74523          const icuContainerTNode = createTNodeAndAddOpCode(tView, rootTNode, existingTNodeStack[0], lView, createOpCodes, ngDevMode ? `ICU ${index}:${icuExpression.mainBinding}` : '', true);
74524          const icuNodeIndex = icuContainerTNode.index;
74525          ngDevMode && assertGreaterThanOrEqual(icuNodeIndex, HEADER_OFFSET, 'Index must be in absolute LView offset');
74526          icuStart(tView, lView, updateOpCodes, parentTNodeIndex, icuExpression, icuNodeIndex);
74527        }
74528      }
74529    } else {
74530      // Odd indexes are placeholders (elements and sub-templates)
74531      // At this point value is something like: '/#1:2' (originally coming from '�/#1:2�')
74532      const isClosing = value.charCodeAt(0) === 47
74533      /* CharCode.SLASH */
74534      ;
74535      const type = value.charCodeAt(isClosing ? 1 : 0);
74536      ngDevMode && assertOneOf(type, 42
74537      /* CharCode.STAR */
74538      , 35
74539      /* CharCode.HASH */
74540      );
74541      const index = HEADER_OFFSET + Number.parseInt(value.substring(isClosing ? 2 : 1));
74542
74543      if (isClosing) {
74544        existingTNodeStack.shift();
74545        setCurrentTNode(getCurrentParentTNode(), false);
74546      } else {
74547        const tNode = createTNodePlaceholder(tView, existingTNodeStack[0], index);
74548        existingTNodeStack.unshift([]);
74549        setCurrentTNode(tNode, true);
74550      }
74551    }
74552  }
74553
74554  tView.data[index] = {
74555    create: createOpCodes,
74556    update: updateOpCodes
74557  };
74558}
74559/**
74560 * Allocate space in i18n Range add create OpCode instruction to create a text or comment node.
74561 *
74562 * @param tView Current `TView` needed to allocate space in i18n range.
74563 * @param rootTNode Root `TNode` of the i18n block. This node determines if the new TNode will be
74564 *     added as part of the `i18nStart` instruction or as part of the `TNode.insertBeforeIndex`.
74565 * @param existingTNodes internal state for `addTNodeAndUpdateInsertBeforeIndex`.
74566 * @param lView Current `LView` needed to allocate space in i18n range.
74567 * @param createOpCodes Array storing `I18nCreateOpCodes` where new opCodes will be added.
74568 * @param text Text to be added when the `Text` or `Comment` node will be created.
74569 * @param isICU true if a `Comment` node for ICU (instead of `Text`) node should be created.
74570 */
74571
74572
74573function createTNodeAndAddOpCode(tView, rootTNode, existingTNodes, lView, createOpCodes, text, isICU) {
74574  const i18nNodeIdx = allocExpando(tView, lView, 1, null);
74575  let opCode = i18nNodeIdx << I18nCreateOpCode.SHIFT;
74576  let parentTNode = getCurrentParentTNode();
74577
74578  if (rootTNode === parentTNode) {
74579    // FIXME(misko): A null `parentTNode` should represent when we fall of the `LView` boundary.
74580    // (there is no parent), but in some circumstances (because we are inconsistent about how we set
74581    // `previousOrParentTNode`) it could point to `rootTNode` So this is a work around.
74582    parentTNode = null;
74583  }
74584
74585  if (parentTNode === null) {
74586    // If we don't have a parent that means that we can eagerly add nodes.
74587    // If we have a parent than these nodes can't be added now (as the parent has not been created
74588    // yet) and instead the `parentTNode` is responsible for adding it. See
74589    // `TNode.insertBeforeIndex`
74590    opCode |= I18nCreateOpCode.APPEND_EAGERLY;
74591  }
74592
74593  if (isICU) {
74594    opCode |= I18nCreateOpCode.COMMENT;
74595    ensureIcuContainerVisitorLoaded(loadIcuContainerVisitor);
74596  }
74597
74598  createOpCodes.push(opCode, text === null ? '' : text); // We store `{{?}}` so that when looking at debug `TNodeType.template` we can see where the
74599  // bindings are.
74600
74601  const tNode = createTNodeAtIndex(tView, i18nNodeIdx, isICU ? 32
74602  /* TNodeType.Icu */
74603  : 1
74604  /* TNodeType.Text */
74605  , text === null ? ngDevMode ? '{{?}}' : '' : text, null);
74606  addTNodeAndUpdateInsertBeforeIndex(existingTNodes, tNode);
74607  const tNodeIdx = tNode.index;
74608  setCurrentTNode(tNode, false
74609  /* Text nodes are self closing */
74610  );
74611
74612  if (parentTNode !== null && rootTNode !== parentTNode) {
74613    // We are a child of deeper node (rather than a direct child of `i18nStart` instruction.)
74614    // We have to make sure to add ourselves to the parent.
74615    setTNodeInsertBeforeIndex(parentTNode, tNodeIdx);
74616  }
74617
74618  return tNode;
74619}
74620/**
74621 * Processes text node in i18n block.
74622 *
74623 * Text nodes can have:
74624 * - Create instruction in `createOpCodes` for creating the text node.
74625 * - Allocate spec for text node in i18n range of `LView`
74626 * - If contains binding:
74627 *    - bindings => allocate space in i18n range of `LView` to store the binding value.
74628 *    - populate `updateOpCodes` with update instructions.
74629 *
74630 * @param tView Current `TView`
74631 * @param rootTNode Root `TNode` of the i18n block. This node determines if the new TNode will
74632 *     be added as part of the `i18nStart` instruction or as part of the
74633 *     `TNode.insertBeforeIndex`.
74634 * @param existingTNodes internal state for `addTNodeAndUpdateInsertBeforeIndex`.
74635 * @param createOpCodes Location where the creation OpCodes will be stored.
74636 * @param lView Current `LView`
74637 * @param text The translated text (which may contain binding)
74638 */
74639
74640
74641function i18nStartFirstCreatePassProcessTextNode(tView, rootTNode, existingTNodes, createOpCodes, updateOpCodes, lView, text) {
74642  const hasBinding = text.match(BINDING_REGEXP);
74643  const tNode = createTNodeAndAddOpCode(tView, rootTNode, existingTNodes, lView, createOpCodes, hasBinding ? null : text, false);
74644
74645  if (hasBinding) {
74646    generateBindingUpdateOpCodes(updateOpCodes, text, tNode.index, null, 0, null);
74647  }
74648}
74649/**
74650 * See `i18nAttributes` above.
74651 */
74652
74653
74654function i18nAttributesFirstPass(tView, index, values) {
74655  const previousElement = getCurrentTNode();
74656  const previousElementIndex = previousElement.index;
74657  const updateOpCodes = [];
74658
74659  if (ngDevMode) {
74660    attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
74661  }
74662
74663  if (tView.firstCreatePass && tView.data[index] === null) {
74664    for (let i = 0; i < values.length; i += 2) {
74665      const attrName = values[i];
74666      const message = values[i + 1];
74667
74668      if (message !== '') {
74669        // Check if attribute value contains an ICU and throw an error if that's the case.
74670        // ICUs in element attributes are not supported.
74671        // Note: we intentionally retain the error here by not using `ngDevMode`, because
74672        // the `value` can change based on the locale and users aren't guaranteed to hit
74673        // an invalid string while they're developing.
74674        if (ICU_REGEXP.test(message)) {
74675          throw new Error(`ICU expressions are not supported in attributes. Message: "${message}".`);
74676        } // i18n attributes that hit this code path are guaranteed to have bindings, because
74677        // the compiler treats static i18n attributes as regular attribute bindings.
74678        // Since this may not be the first i18n attribute on this element we need to pass in how
74679        // many previous bindings there have already been.
74680
74681
74682        generateBindingUpdateOpCodes(updateOpCodes, message, previousElementIndex, attrName, countBindings(updateOpCodes), null);
74683      }
74684    }
74685
74686    tView.data[index] = updateOpCodes;
74687  }
74688}
74689/**
74690 * Generate the OpCodes to update the bindings of a string.
74691 *
74692 * @param updateOpCodes Place where the update opcodes will be stored.
74693 * @param str The string containing the bindings.
74694 * @param destinationNode Index of the destination node which will receive the binding.
74695 * @param attrName Name of the attribute, if the string belongs to an attribute.
74696 * @param sanitizeFn Sanitization function used to sanitize the string after update, if necessary.
74697 * @param bindingStart The lView index of the next expression that can be bound via an opCode.
74698 * @returns The mask value for these bindings
74699 */
74700
74701
74702function generateBindingUpdateOpCodes(updateOpCodes, str, destinationNode, attrName, bindingStart, sanitizeFn) {
74703  ngDevMode && assertGreaterThanOrEqual(destinationNode, HEADER_OFFSET, 'Index must be in absolute LView offset');
74704  const maskIndex = updateOpCodes.length; // Location of mask
74705
74706  const sizeIndex = maskIndex + 1; // location of size for skipping
74707
74708  updateOpCodes.push(null, null); // Alloc space for mask and size
74709
74710  const startIndex = maskIndex + 2; // location of first allocation.
74711
74712  if (ngDevMode) {
74713    attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
74714  }
74715
74716  const textParts = str.split(BINDING_REGEXP);
74717  let mask = 0;
74718
74719  for (let j = 0; j < textParts.length; j++) {
74720    const textValue = textParts[j];
74721
74722    if (j & 1) {
74723      // Odd indexes are bindings
74724      const bindingIndex = bindingStart + parseInt(textValue, 10);
74725      updateOpCodes.push(-1 - bindingIndex);
74726      mask = mask | toMaskBit(bindingIndex);
74727    } else if (textValue !== '') {
74728      // Even indexes are text
74729      updateOpCodes.push(textValue);
74730    }
74731  }
74732
74733  updateOpCodes.push(destinationNode << 2
74734  /* I18nUpdateOpCode.SHIFT_REF */
74735  | (attrName ? 1
74736  /* I18nUpdateOpCode.Attr */
74737  : 0
74738  /* I18nUpdateOpCode.Text */
74739  ));
74740
74741  if (attrName) {
74742    updateOpCodes.push(attrName, sanitizeFn);
74743  }
74744
74745  updateOpCodes[maskIndex] = mask;
74746  updateOpCodes[sizeIndex] = updateOpCodes.length - startIndex;
74747  return mask;
74748}
74749/**
74750 * Count the number of bindings in the given `opCodes`.
74751 *
74752 * It could be possible to speed this up, by passing the number of bindings found back from
74753 * `generateBindingUpdateOpCodes()` to `i18nAttributesFirstPass()` but this would then require more
74754 * complexity in the code and/or transient objects to be created.
74755 *
74756 * Since this function is only called once when the template is instantiated, is trivial in the
74757 * first instance (since `opCodes` will be an empty array), and it is not common for elements to
74758 * contain multiple i18n bound attributes, it seems like this is a reasonable compromise.
74759 */
74760
74761
74762function countBindings(opCodes) {
74763  let count = 0;
74764
74765  for (let i = 0; i < opCodes.length; i++) {
74766    const opCode = opCodes[i]; // Bindings are negative numbers.
74767
74768    if (typeof opCode === 'number' && opCode < 0) {
74769      count++;
74770    }
74771  }
74772
74773  return count;
74774}
74775/**
74776 * Convert binding index to mask bit.
74777 *
74778 * Each index represents a single bit on the bit-mask. Because bit-mask only has 32 bits, we make
74779 * the 32nd bit share all masks for all bindings higher than 32. Since it is extremely rare to
74780 * have more than 32 bindings this will be hit very rarely. The downside of hitting this corner
74781 * case is that we will execute binding code more often than necessary. (penalty of performance)
74782 */
74783
74784
74785function toMaskBit(bindingIndex) {
74786  return 1 << Math.min(bindingIndex, 31);
74787}
74788
74789function isRootTemplateMessage(subTemplateIndex) {
74790  return subTemplateIndex === -1;
74791}
74792/**
74793 * Removes everything inside the sub-templates of a message.
74794 */
74795
74796
74797function removeInnerTemplateTranslation(message) {
74798  let match;
74799  let res = '';
74800  let index = 0;
74801  let inTemplate = false;
74802  let tagMatched;
74803
74804  while ((match = SUBTEMPLATE_REGEXP.exec(message)) !== null) {
74805    if (!inTemplate) {
74806      res += message.substring(index, match.index + match[0].length);
74807      tagMatched = match[1];
74808      inTemplate = true;
74809    } else {
74810      if (match[0] === `${MARKER}/*${tagMatched}${MARKER}`) {
74811        index = match.index;
74812        inTemplate = false;
74813      }
74814    }
74815  }
74816
74817  ngDevMode && assertEqual(inTemplate, false, `Tag mismatch: unable to find the end of the sub-template in the translation "${message}"`);
74818  res += message.slice(index);
74819  return res;
74820}
74821/**
74822 * Extracts a part of a message and removes the rest.
74823 *
74824 * This method is used for extracting a part of the message associated with a template. A
74825 * translated message can span multiple templates.
74826 *
74827 * Example:
74828 * ```
74829 * <div i18n>Translate <span *ngIf>me</span>!</div>
74830 * ```
74831 *
74832 * @param message The message to crop
74833 * @param subTemplateIndex Index of the sub-template to extract. If undefined it returns the
74834 * external template and removes all sub-templates.
74835 */
74836
74837
74838function getTranslationForTemplate(message, subTemplateIndex) {
74839  if (isRootTemplateMessage(subTemplateIndex)) {
74840    // We want the root template message, ignore all sub-templates
74841    return removeInnerTemplateTranslation(message);
74842  } else {
74843    // We want a specific sub-template
74844    const start = message.indexOf(`:${subTemplateIndex}${MARKER}`) + 2 + subTemplateIndex.toString().length;
74845    const end = message.search(new RegExp(`${MARKER}\\/\\*\\d+:${subTemplateIndex}${MARKER}`));
74846    return removeInnerTemplateTranslation(message.substring(start, end));
74847  }
74848}
74849/**
74850 * Generate the OpCodes for ICU expressions.
74851 *
74852 * @param icuExpression
74853 * @param index Index where the anchor is stored and an optional `TIcuContainerNode`
74854 *   - `lView[anchorIdx]` points to a `Comment` node representing the anchor for the ICU.
74855 *   - `tView.data[anchorIdx]` points to the `TIcuContainerNode` if ICU is root (`null` otherwise)
74856 */
74857
74858
74859function icuStart(tView, lView, updateOpCodes, parentIdx, icuExpression, anchorIdx) {
74860  ngDevMode && assertDefined(icuExpression, 'ICU expression must be defined');
74861  let bindingMask = 0;
74862  const tIcu = {
74863    type: icuExpression.type,
74864    currentCaseLViewIndex: allocExpando(tView, lView, 1, null),
74865    anchorIdx,
74866    cases: [],
74867    create: [],
74868    remove: [],
74869    update: []
74870  };
74871  addUpdateIcuSwitch(updateOpCodes, icuExpression, anchorIdx);
74872  setTIcu(tView, anchorIdx, tIcu);
74873  const values = icuExpression.values;
74874
74875  for (let i = 0; i < values.length; i++) {
74876    // Each value is an array of strings & other ICU expressions
74877    const valueArr = values[i];
74878    const nestedIcus = [];
74879
74880    for (let j = 0; j < valueArr.length; j++) {
74881      const value = valueArr[j];
74882
74883      if (typeof value !== 'string') {
74884        // It is an nested ICU expression
74885        const icuIndex = nestedIcus.push(value) - 1; // Replace nested ICU expression by a comment node
74886
74887        valueArr[j] = `<!--�${icuIndex}�-->`;
74888      }
74889    }
74890
74891    bindingMask = parseIcuCase(tView, tIcu, lView, updateOpCodes, parentIdx, icuExpression.cases[i], valueArr.join(''), nestedIcus) | bindingMask;
74892  }
74893
74894  if (bindingMask) {
74895    addUpdateIcuUpdate(updateOpCodes, bindingMask, anchorIdx);
74896  }
74897}
74898/**
74899 * Parses text containing an ICU expression and produces a JSON object for it.
74900 * Original code from closure library, modified for Angular.
74901 *
74902 * @param pattern Text containing an ICU expression that needs to be parsed.
74903 *
74904 */
74905
74906
74907function parseICUBlock(pattern) {
74908  const cases = [];
74909  const values = [];
74910  let icuType = 1
74911  /* IcuType.plural */
74912  ;
74913  let mainBinding = 0;
74914  pattern = pattern.replace(ICU_BLOCK_REGEXP, function (str, binding, type) {
74915    if (type === 'select') {
74916      icuType = 0
74917      /* IcuType.select */
74918      ;
74919    } else {
74920      icuType = 1
74921      /* IcuType.plural */
74922      ;
74923    }
74924
74925    mainBinding = parseInt(binding.slice(1), 10);
74926    return '';
74927  });
74928  const parts = i18nParseTextIntoPartsAndICU(pattern); // Looking for (key block)+ sequence. One of the keys has to be "other".
74929
74930  for (let pos = 0; pos < parts.length;) {
74931    let key = parts[pos++].trim();
74932
74933    if (icuType === 1
74934    /* IcuType.plural */
74935    ) {
74936      // Key can be "=x", we just want "x"
74937      key = key.replace(/\s*(?:=)?(\w+)\s*/, '$1');
74938    }
74939
74940    if (key.length) {
74941      cases.push(key);
74942    }
74943
74944    const blocks = i18nParseTextIntoPartsAndICU(parts[pos++]);
74945
74946    if (cases.length > values.length) {
74947      values.push(blocks);
74948    }
74949  } // TODO(ocombe): support ICU expressions in attributes, see #21615
74950
74951
74952  return {
74953    type: icuType,
74954    mainBinding: mainBinding,
74955    cases,
74956    values
74957  };
74958}
74959/**
74960 * Breaks pattern into strings and top level {...} blocks.
74961 * Can be used to break a message into text and ICU expressions, or to break an ICU expression
74962 * into keys and cases. Original code from closure library, modified for Angular.
74963 *
74964 * @param pattern (sub)Pattern to be broken.
74965 * @returns An `Array<string|IcuExpression>` where:
74966 *   - odd positions: `string` => text between ICU expressions
74967 *   - even positions: `ICUExpression` => ICU expression parsed into `ICUExpression` record.
74968 */
74969
74970
74971function i18nParseTextIntoPartsAndICU(pattern) {
74972  if (!pattern) {
74973    return [];
74974  }
74975
74976  let prevPos = 0;
74977  const braceStack = [];
74978  const results = [];
74979  const braces = /[{}]/g; // lastIndex doesn't get set to 0 so we have to.
74980
74981  braces.lastIndex = 0;
74982  let match;
74983
74984  while (match = braces.exec(pattern)) {
74985    const pos = match.index;
74986
74987    if (match[0] == '}') {
74988      braceStack.pop();
74989
74990      if (braceStack.length == 0) {
74991        // End of the block.
74992        const block = pattern.substring(prevPos, pos);
74993
74994        if (ICU_BLOCK_REGEXP.test(block)) {
74995          results.push(parseICUBlock(block));
74996        } else {
74997          results.push(block);
74998        }
74999
75000        prevPos = pos + 1;
75001      }
75002    } else {
75003      if (braceStack.length == 0) {
75004        const substring = pattern.substring(prevPos, pos);
75005        results.push(substring);
75006        prevPos = pos + 1;
75007      }
75008
75009      braceStack.push('{');
75010    }
75011  }
75012
75013  const substring = pattern.substring(prevPos);
75014  results.push(substring);
75015  return results;
75016}
75017/**
75018 * Parses a node, its children and its siblings, and generates the mutate & update OpCodes.
75019 *
75020 */
75021
75022
75023function parseIcuCase(tView, tIcu, lView, updateOpCodes, parentIdx, caseName, unsafeCaseHtml, nestedIcus) {
75024  const create = [];
75025  const remove = [];
75026  const update = [];
75027
75028  if (ngDevMode) {
75029    attachDebugGetter(create, icuCreateOpCodesToString);
75030    attachDebugGetter(remove, i18nRemoveOpCodesToString);
75031    attachDebugGetter(update, i18nUpdateOpCodesToString);
75032  }
75033
75034  tIcu.cases.push(caseName);
75035  tIcu.create.push(create);
75036  tIcu.remove.push(remove);
75037  tIcu.update.push(update);
75038  const inertBodyHelper = getInertBodyHelper(getDocument());
75039  const inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeCaseHtml);
75040  ngDevMode && assertDefined(inertBodyElement, 'Unable to generate inert body element');
75041  const inertRootNode = getTemplateContent(inertBodyElement) || inertBodyElement;
75042
75043  if (inertRootNode) {
75044    return walkIcuTree(tView, tIcu, lView, updateOpCodes, create, remove, update, inertRootNode, parentIdx, nestedIcus, 0);
75045  } else {
75046    return 0;
75047  }
75048}
75049
75050function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, parentNode, parentIdx, nestedIcus, depth) {
75051  let bindingMask = 0;
75052  let currentNode = parentNode.firstChild;
75053
75054  while (currentNode) {
75055    const newIndex = allocExpando(tView, lView, 1, null);
75056
75057    switch (currentNode.nodeType) {
75058      case Node.ELEMENT_NODE:
75059        const element = currentNode;
75060        const tagName = element.tagName.toLowerCase();
75061
75062        if (VALID_ELEMENTS.hasOwnProperty(tagName)) {
75063          addCreateNodeAndAppend(create, ELEMENT_MARKER, tagName, parentIdx, newIndex);
75064          tView.data[newIndex] = tagName;
75065          const elAttrs = element.attributes;
75066
75067          for (let i = 0; i < elAttrs.length; i++) {
75068            const attr = elAttrs.item(i);
75069            const lowerAttrName = attr.name.toLowerCase();
75070            const hasBinding = !!attr.value.match(BINDING_REGEXP); // we assume the input string is safe, unless it's using a binding
75071
75072            if (hasBinding) {
75073              if (VALID_ATTRS.hasOwnProperty(lowerAttrName)) {
75074                if (URI_ATTRS[lowerAttrName]) {
75075                  generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, _sanitizeUrl);
75076                } else {
75077                  generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, null);
75078                }
75079              } else {
75080                ngDevMode && console.warn(`WARNING: ignoring unsafe attribute value ` + `${lowerAttrName} on element ${tagName} ` + `(see https://g.co/ng/security#xss)`);
75081              }
75082            } else {
75083              addCreateAttribute(create, newIndex, attr);
75084            }
75085          } // Parse the children of this node (if any)
75086
75087
75088          bindingMask = walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, currentNode, newIndex, nestedIcus, depth + 1) | bindingMask;
75089          addRemoveNode(remove, newIndex, depth);
75090        }
75091
75092        break;
75093
75094      case Node.TEXT_NODE:
75095        const value = currentNode.textContent || '';
75096        const hasBinding = value.match(BINDING_REGEXP);
75097        addCreateNodeAndAppend(create, null, hasBinding ? '' : value, parentIdx, newIndex);
75098        addRemoveNode(remove, newIndex, depth);
75099
75100        if (hasBinding) {
75101          bindingMask = generateBindingUpdateOpCodes(update, value, newIndex, null, 0, null) | bindingMask;
75102        }
75103
75104        break;
75105
75106      case Node.COMMENT_NODE:
75107        // Check if the comment node is a placeholder for a nested ICU
75108        const isNestedIcu = NESTED_ICU.exec(currentNode.textContent || '');
75109
75110        if (isNestedIcu) {
75111          const nestedIcuIndex = parseInt(isNestedIcu[1], 10);
75112          const icuExpression = nestedIcus[nestedIcuIndex]; // Create the comment node that will anchor the ICU expression
75113
75114          addCreateNodeAndAppend(create, ICU_MARKER, ngDevMode ? `nested ICU ${nestedIcuIndex}` : '', parentIdx, newIndex);
75115          icuStart(tView, lView, sharedUpdateOpCodes, parentIdx, icuExpression, newIndex);
75116          addRemoveNestedIcu(remove, newIndex, depth);
75117        }
75118
75119        break;
75120    }
75121
75122    currentNode = currentNode.nextSibling;
75123  }
75124
75125  return bindingMask;
75126}
75127
75128function addRemoveNode(remove, index, depth) {
75129  if (depth === 0) {
75130    remove.push(index);
75131  }
75132}
75133
75134function addRemoveNestedIcu(remove, index, depth) {
75135  if (depth === 0) {
75136    remove.push(~index); // remove ICU at `index`
75137
75138    remove.push(index); // remove ICU comment at `index`
75139  }
75140}
75141
75142function addUpdateIcuSwitch(update, icuExpression, index) {
75143  update.push(toMaskBit(icuExpression.mainBinding), 2, -1 - icuExpression.mainBinding, index << 2
75144  /* I18nUpdateOpCode.SHIFT_REF */
75145  | 2
75146  /* I18nUpdateOpCode.IcuSwitch */
75147  );
75148}
75149
75150function addUpdateIcuUpdate(update, bindingMask, index) {
75151  update.push(bindingMask, 1, index << 2
75152  /* I18nUpdateOpCode.SHIFT_REF */
75153  | 3
75154  /* I18nUpdateOpCode.IcuUpdate */
75155  );
75156}
75157
75158function addCreateNodeAndAppend(create, marker, text, appendToParentIdx, createAtIdx) {
75159  if (marker !== null) {
75160    create.push(marker);
75161  }
75162
75163  create.push(text, createAtIdx, icuCreateOpCode(0
75164  /* IcuCreateOpCode.AppendChild */
75165  , appendToParentIdx, createAtIdx));
75166}
75167
75168function addCreateAttribute(create, newIndex, attr) {
75169  create.push(newIndex << 1
75170  /* IcuCreateOpCode.SHIFT_REF */
75171  | 1
75172  /* IcuCreateOpCode.Attr */
75173  , attr.name, attr.value);
75174}
75175/**
75176 * @license
75177 * Copyright Google LLC All Rights Reserved.
75178 *
75179 * Use of this source code is governed by an MIT-style license that can be
75180 * found in the LICENSE file at https://angular.io/license
75181 */
75182// i18nPostprocess consts
75183
75184
75185const ROOT_TEMPLATE_ID = 0;
75186const PP_MULTI_VALUE_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]/;
75187const PP_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]|(�\/?\*\d+:\d+�)/g;
75188const PP_ICU_VARS_REGEXP = /({\s*)(VAR_(PLURAL|SELECT)(_\d+)?)(\s*,)/g;
75189const PP_ICU_PLACEHOLDERS_REGEXP = /{([A-Z0-9_]+)}/g;
75190const PP_ICUS_REGEXP = /�I18N_EXP_(ICU(_\d+)?)�/g;
75191const PP_CLOSE_TEMPLATE_REGEXP = /\/\*/;
75192const PP_TEMPLATE_ID_REGEXP = /\d+\:(\d+)/;
75193/**
75194 * Handles message string post-processing for internationalization.
75195 *
75196 * Handles message string post-processing by transforming it from intermediate
75197 * format (that might contain some markers that we need to replace) to the final
75198 * form, consumable by i18nStart instruction. Post processing steps include:
75199 *
75200 * 1. Resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
75201 * 2. Replace all ICU vars (like "VAR_PLURAL")
75202 * 3. Replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
75203 * 4. Replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
75204 *    in case multiple ICUs have the same placeholder name
75205 *
75206 * @param message Raw translation string for post processing
75207 * @param replacements Set of replacements that should be applied
75208 *
75209 * @returns Transformed string that can be consumed by i18nStart instruction
75210 *
75211 * @codeGenApi
75212 */
75213
75214function i18nPostprocess(message, replacements = {}) {
75215  /**
75216   * Step 1: resolve all multi-value placeholders like [�#5�|�*1:1��#2:1�|�#4:1�]
75217   *
75218   * Note: due to the way we process nested templates (BFS), multi-value placeholders are typically
75219   * grouped by templates, for example: [�#5�|�#6�|�#1:1�|�#3:2�] where �#5� and �#6� belong to root
75220   * template, �#1:1� belong to nested template with index 1 and �#1:2� - nested template with index
75221   * 3. However in real templates the order might be different: i.e. �#1:1� and/or �#3:2� may go in
75222   * front of �#6�. The post processing step restores the right order by keeping track of the
75223   * template id stack and looks for placeholders that belong to the currently active template.
75224   */
75225  let result = message;
75226
75227  if (PP_MULTI_VALUE_PLACEHOLDERS_REGEXP.test(message)) {
75228    const matches = {};
75229    const templateIdsStack = [ROOT_TEMPLATE_ID];
75230    result = result.replace(PP_PLACEHOLDERS_REGEXP, (m, phs, tmpl) => {
75231      const content = phs || tmpl;
75232      const placeholders = matches[content] || [];
75233
75234      if (!placeholders.length) {
75235        content.split('|').forEach(placeholder => {
75236          const match = placeholder.match(PP_TEMPLATE_ID_REGEXP);
75237          const templateId = match ? parseInt(match[1], 10) : ROOT_TEMPLATE_ID;
75238          const isCloseTemplateTag = PP_CLOSE_TEMPLATE_REGEXP.test(placeholder);
75239          placeholders.push([templateId, isCloseTemplateTag, placeholder]);
75240        });
75241        matches[content] = placeholders;
75242      }
75243
75244      if (!placeholders.length) {
75245        throw new Error(`i18n postprocess: unmatched placeholder - ${content}`);
75246      }
75247
75248      const currentTemplateId = templateIdsStack[templateIdsStack.length - 1];
75249      let idx = 0; // find placeholder index that matches current template id
75250
75251      for (let i = 0; i < placeholders.length; i++) {
75252        if (placeholders[i][0] === currentTemplateId) {
75253          idx = i;
75254          break;
75255        }
75256      } // update template id stack based on the current tag extracted
75257
75258
75259      const [templateId, isCloseTemplateTag, placeholder] = placeholders[idx];
75260
75261      if (isCloseTemplateTag) {
75262        templateIdsStack.pop();
75263      } else if (currentTemplateId !== templateId) {
75264        templateIdsStack.push(templateId);
75265      } // remove processed tag from the list
75266
75267
75268      placeholders.splice(idx, 1);
75269      return placeholder;
75270    });
75271  } // return current result if no replacements specified
75272
75273
75274  if (!Object.keys(replacements).length) {
75275    return result;
75276  }
75277  /**
75278   * Step 2: replace all ICU vars (like "VAR_PLURAL")
75279   */
75280
75281
75282  result = result.replace(PP_ICU_VARS_REGEXP, (match, start, key, _type, _idx, end) => {
75283    return replacements.hasOwnProperty(key) ? `${start}${replacements[key]}${end}` : match;
75284  });
75285  /**
75286   * Step 3: replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
75287   */
75288
75289  result = result.replace(PP_ICU_PLACEHOLDERS_REGEXP, (match, key) => {
75290    return replacements.hasOwnProperty(key) ? replacements[key] : match;
75291  });
75292  /**
75293   * Step 4: replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�) in case
75294   * multiple ICUs have the same placeholder name
75295   */
75296
75297  result = result.replace(PP_ICUS_REGEXP, (match, key) => {
75298    if (replacements.hasOwnProperty(key)) {
75299      const list = replacements[key];
75300
75301      if (!list.length) {
75302        throw new Error(`i18n postprocess: unmatched ICU - ${match} with key: ${key}`);
75303      }
75304
75305      return list.shift();
75306    }
75307
75308    return match;
75309  });
75310  return result;
75311}
75312/**
75313 * @license
75314 * Copyright Google LLC All Rights Reserved.
75315 *
75316 * Use of this source code is governed by an MIT-style license that can be
75317 * found in the LICENSE file at https://angular.io/license
75318 */
75319
75320/**
75321 * Marks a block of text as translatable.
75322 *
75323 * The instructions `i18nStart` and `i18nEnd` mark the translation block in the template.
75324 * The translation `message` is the value which is locale specific. The translation string may
75325 * contain placeholders which associate inner elements and sub-templates within the translation.
75326 *
75327 * The translation `message` placeholders are:
75328 * - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
75329 *   interpolated into. The placeholder `index` points to the expression binding index. An optional
75330 *   `block` that matches the sub-template in which it was declared.
75331 * - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*:  Marks the beginning
75332 *   and end of DOM element that were embedded in the original translation block. The placeholder
75333 *   `index` points to the element index in the template instructions set. An optional `block` that
75334 *   matches the sub-template in which it was declared.
75335 * - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
75336 *   split up and translated separately in each angular template function. The `index` points to the
75337 *   `template` instruction index. A `block` that matches the sub-template in which it was declared.
75338 *
75339 * @param index A unique index of the translation in the static block.
75340 * @param messageIndex An index of the translation message from the `def.consts` array.
75341 * @param subTemplateIndex Optional sub-template index in the `message`.
75342 *
75343 * @codeGenApi
75344 */
75345
75346
75347function ɵɵi18nStart(index, messageIndex, subTemplateIndex = -1) {
75348  const tView = getTView();
75349  const lView = getLView();
75350  const adjustedIndex = HEADER_OFFSET + index;
75351  ngDevMode && assertDefined(tView, `tView should be defined`);
75352  const message = getConstant(tView.consts, messageIndex);
75353  const parentTNode = getCurrentParentTNode();
75354
75355  if (tView.firstCreatePass) {
75356    i18nStartFirstCreatePass(tView, parentTNode === null ? 0 : parentTNode.index, lView, adjustedIndex, message, subTemplateIndex);
75357  }
75358
75359  const tI18n = tView.data[adjustedIndex];
75360  const sameViewParentTNode = parentTNode === lView[T_HOST] ? null : parentTNode;
75361  const parentRNode = getClosestRElement(tView, sameViewParentTNode, lView); // If `parentTNode` is an `ElementContainer` than it has `<!--ng-container--->`.
75362  // When we do inserts we have to make sure to insert in front of `<!--ng-container--->`.
75363
75364  const insertInFrontOf = parentTNode && parentTNode.type & 8
75365  /* TNodeType.ElementContainer */
75366  ? lView[parentTNode.index] : null;
75367  applyCreateOpCodes(lView, tI18n.create, parentRNode, insertInFrontOf);
75368  setInI18nBlock(true);
75369}
75370/**
75371 * Translates a translation block marked by `i18nStart` and `i18nEnd`. It inserts the text/ICU nodes
75372 * into the render tree, moves the placeholder nodes and removes the deleted nodes.
75373 *
75374 * @codeGenApi
75375 */
75376
75377
75378function ɵɵi18nEnd() {
75379  setInI18nBlock(false);
75380}
75381/**
75382 *
75383 * Use this instruction to create a translation block that doesn't contain any placeholder.
75384 * It calls both {@link i18nStart} and {@link i18nEnd} in one instruction.
75385 *
75386 * The translation `message` is the value which is locale specific. The translation string may
75387 * contain placeholders which associate inner elements and sub-templates within the translation.
75388 *
75389 * The translation `message` placeholders are:
75390 * - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
75391 *   interpolated into. The placeholder `index` points to the expression binding index. An optional
75392 *   `block` that matches the sub-template in which it was declared.
75393 * - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*:  Marks the beginning
75394 *   and end of DOM element that were embedded in the original translation block. The placeholder
75395 *   `index` points to the element index in the template instructions set. An optional `block` that
75396 *   matches the sub-template in which it was declared.
75397 * - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
75398 *   split up and translated separately in each angular template function. The `index` points to the
75399 *   `template` instruction index. A `block` that matches the sub-template in which it was declared.
75400 *
75401 * @param index A unique index of the translation in the static block.
75402 * @param messageIndex An index of the translation message from the `def.consts` array.
75403 * @param subTemplateIndex Optional sub-template index in the `message`.
75404 *
75405 * @codeGenApi
75406 */
75407
75408
75409function ɵɵi18n(index, messageIndex, subTemplateIndex) {
75410  ɵɵi18nStart(index, messageIndex, subTemplateIndex);
75411  ɵɵi18nEnd();
75412}
75413/**
75414 * Marks a list of attributes as translatable.
75415 *
75416 * @param index A unique index in the static block
75417 * @param values
75418 *
75419 * @codeGenApi
75420 */
75421
75422
75423function ɵɵi18nAttributes(index, attrsIndex) {
75424  const tView = getTView();
75425  ngDevMode && assertDefined(tView, `tView should be defined`);
75426  const attrs = getConstant(tView.consts, attrsIndex);
75427  i18nAttributesFirstPass(tView, index + HEADER_OFFSET, attrs);
75428}
75429/**
75430 * Stores the values of the bindings during each update cycle in order to determine if we need to
75431 * update the translated nodes.
75432 *
75433 * @param value The binding's value
75434 * @returns This function returns itself so that it may be chained
75435 * (e.g. `i18nExp(ctx.name)(ctx.title)`)
75436 *
75437 * @codeGenApi
75438 */
75439
75440
75441function ɵɵi18nExp(value) {
75442  const lView = getLView();
75443  setMaskBit(bindingUpdated(lView, nextBindingIndex(), value));
75444  return ɵɵi18nExp;
75445}
75446/**
75447 * Updates a translation block or an i18n attribute when the bindings have changed.
75448 *
75449 * @param index Index of either {@link i18nStart} (translation block) or {@link i18nAttributes}
75450 * (i18n attribute) on which it should update the content.
75451 *
75452 * @codeGenApi
75453 */
75454
75455
75456function ɵɵi18nApply(index) {
75457  applyI18n(getTView(), getLView(), index + HEADER_OFFSET);
75458}
75459/**
75460 * Handles message string post-processing for internationalization.
75461 *
75462 * Handles message string post-processing by transforming it from intermediate
75463 * format (that might contain some markers that we need to replace) to the final
75464 * form, consumable by i18nStart instruction. Post processing steps include:
75465 *
75466 * 1. Resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
75467 * 2. Replace all ICU vars (like "VAR_PLURAL")
75468 * 3. Replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
75469 * 4. Replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
75470 *    in case multiple ICUs have the same placeholder name
75471 *
75472 * @param message Raw translation string for post processing
75473 * @param replacements Set of replacements that should be applied
75474 *
75475 * @returns Transformed string that can be consumed by i18nStart instruction
75476 *
75477 * @codeGenApi
75478 */
75479
75480
75481function ɵɵi18nPostprocess(message, replacements = {}) {
75482  return i18nPostprocess(message, replacements);
75483}
75484/**
75485 * @license
75486 * Copyright Google LLC All Rights Reserved.
75487 *
75488 * Use of this source code is governed by an MIT-style license that can be
75489 * found in the LICENSE file at https://angular.io/license
75490 */
75491
75492/**
75493 * @license
75494 * Copyright Google LLC All Rights Reserved.
75495 *
75496 * Use of this source code is governed by an MIT-style license that can be
75497 * found in the LICENSE file at https://angular.io/license
75498 */
75499
75500/**
75501 * Resolves the providers which are defined in the DirectiveDef.
75502 *
75503 * When inserting the tokens and the factories in their respective arrays, we can assume that
75504 * this method is called first for the component (if any), and then for other directives on the same
75505 * node.
75506 * As a consequence,the providers are always processed in that order:
75507 * 1) The view providers of the component
75508 * 2) The providers of the component
75509 * 3) The providers of the other directives
75510 * This matches the structure of the injectables arrays of a view (for each node).
75511 * So the tokens and the factories can be pushed at the end of the arrays, except
75512 * in one case for multi providers.
75513 *
75514 * @param def the directive definition
75515 * @param providers: Array of `providers`.
75516 * @param viewProviders: Array of `viewProviders`.
75517 */
75518
75519
75520function providersResolver(def, providers, viewProviders) {
75521  const tView = getTView();
75522
75523  if (tView.firstCreatePass) {
75524    const isComponent = isComponentDef(def); // The list of view providers is processed first, and the flags are updated
75525
75526    resolveProvider(viewProviders, tView.data, tView.blueprint, isComponent, true); // Then, the list of providers is processed, and the flags are updated
75527
75528    resolveProvider(providers, tView.data, tView.blueprint, isComponent, false);
75529  }
75530}
75531/**
75532 * Resolves a provider and publishes it to the DI system.
75533 */
75534
75535
75536function resolveProvider(provider, tInjectables, lInjectablesBlueprint, isComponent, isViewProvider) {
75537  provider = resolveForwardRef(provider);
75538
75539  if (Array.isArray(provider)) {
75540    // Recursively call `resolveProvider`
75541    // Recursion is OK in this case because this code will not be in hot-path once we implement
75542    // cloning of the initial state.
75543    for (let i = 0; i < provider.length; i++) {
75544      resolveProvider(provider[i], tInjectables, lInjectablesBlueprint, isComponent, isViewProvider);
75545    }
75546  } else {
75547    const tView = getTView();
75548    const lView = getLView();
75549    let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
75550    let providerFactory = providerToFactory(provider);
75551    const tNode = getCurrentTNode();
75552    const beginIndex = tNode.providerIndexes & 1048575
75553    /* TNodeProviderIndexes.ProvidersStartIndexMask */
75554    ;
75555    const endIndex = tNode.directiveStart;
75556    const cptViewProvidersCount = tNode.providerIndexes >> 20
75557    /* TNodeProviderIndexes.CptViewProvidersCountShift */
75558    ;
75559
75560    if (isTypeProvider(provider) || !provider.multi) {
75561      // Single provider case: the factory is created and pushed immediately
75562      const factory = new NodeInjectorFactory(providerFactory, isViewProvider, ɵɵdirectiveInject);
75563      const existingFactoryIndex = indexOf(token, tInjectables, isViewProvider ? beginIndex : beginIndex + cptViewProvidersCount, endIndex);
75564
75565      if (existingFactoryIndex === -1) {
75566        diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, token);
75567        registerDestroyHooksIfSupported(tView, provider, tInjectables.length);
75568        tInjectables.push(token);
75569        tNode.directiveStart++;
75570        tNode.directiveEnd++;
75571
75572        if (isViewProvider) {
75573          tNode.providerIndexes += 1048576
75574          /* TNodeProviderIndexes.CptViewProvidersCountShifter */
75575          ;
75576        }
75577
75578        lInjectablesBlueprint.push(factory);
75579        lView.push(factory);
75580      } else {
75581        lInjectablesBlueprint[existingFactoryIndex] = factory;
75582        lView[existingFactoryIndex] = factory;
75583      }
75584    } else {
75585      // Multi provider case:
75586      // We create a multi factory which is going to aggregate all the values.
75587      // Since the output of such a factory depends on content or view injection,
75588      // we create two of them, which are linked together.
75589      //
75590      // The first one (for view providers) is always in the first block of the injectables array,
75591      // and the second one (for providers) is always in the second block.
75592      // This is important because view providers have higher priority. When a multi token
75593      // is being looked up, the view providers should be found first.
75594      // Note that it is not possible to have a multi factory in the third block (directive block).
75595      //
75596      // The algorithm to process multi providers is as follows:
75597      // 1) If the multi provider comes from the `viewProviders` of the component:
75598      //   a) If the special view providers factory doesn't exist, it is created and pushed.
75599      //   b) Else, the multi provider is added to the existing multi factory.
75600      // 2) If the multi provider comes from the `providers` of the component or of another
75601      // directive:
75602      //   a) If the multi factory doesn't exist, it is created and provider pushed into it.
75603      //      It is also linked to the multi factory for view providers, if it exists.
75604      //   b) Else, the multi provider is added to the existing multi factory.
75605      const existingProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex + cptViewProvidersCount, endIndex);
75606      const existingViewProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex, beginIndex + cptViewProvidersCount);
75607      const doesProvidersFactoryExist = existingProvidersFactoryIndex >= 0 && lInjectablesBlueprint[existingProvidersFactoryIndex];
75608      const doesViewProvidersFactoryExist = existingViewProvidersFactoryIndex >= 0 && lInjectablesBlueprint[existingViewProvidersFactoryIndex];
75609
75610      if (isViewProvider && !doesViewProvidersFactoryExist || !isViewProvider && !doesProvidersFactoryExist) {
75611        // Cases 1.a and 2.a
75612        diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, token);
75613        const factory = multiFactory(isViewProvider ? multiViewProvidersFactoryResolver : multiProvidersFactoryResolver, lInjectablesBlueprint.length, isViewProvider, isComponent, providerFactory);
75614
75615        if (!isViewProvider && doesViewProvidersFactoryExist) {
75616          lInjectablesBlueprint[existingViewProvidersFactoryIndex].providerFactory = factory;
75617        }
75618
75619        registerDestroyHooksIfSupported(tView, provider, tInjectables.length, 0);
75620        tInjectables.push(token);
75621        tNode.directiveStart++;
75622        tNode.directiveEnd++;
75623
75624        if (isViewProvider) {
75625          tNode.providerIndexes += 1048576
75626          /* TNodeProviderIndexes.CptViewProvidersCountShifter */
75627          ;
75628        }
75629
75630        lInjectablesBlueprint.push(factory);
75631        lView.push(factory);
75632      } else {
75633        // Cases 1.b and 2.b
75634        const indexInFactory = multiFactoryAdd(lInjectablesBlueprint[isViewProvider ? existingViewProvidersFactoryIndex : existingProvidersFactoryIndex], providerFactory, !isViewProvider && isComponent);
75635        registerDestroyHooksIfSupported(tView, provider, existingProvidersFactoryIndex > -1 ? existingProvidersFactoryIndex : existingViewProvidersFactoryIndex, indexInFactory);
75636      }
75637
75638      if (!isViewProvider && isComponent && doesViewProvidersFactoryExist) {
75639        lInjectablesBlueprint[existingViewProvidersFactoryIndex].componentProviders++;
75640      }
75641    }
75642  }
75643}
75644/**
75645 * Registers the `ngOnDestroy` hook of a provider, if the provider supports destroy hooks.
75646 * @param tView `TView` in which to register the hook.
75647 * @param provider Provider whose hook should be registered.
75648 * @param contextIndex Index under which to find the context for the hook when it's being invoked.
75649 * @param indexInFactory Only required for `multi` providers. Index of the provider in the multi
75650 * provider factory.
75651 */
75652
75653
75654function registerDestroyHooksIfSupported(tView, provider, contextIndex, indexInFactory) {
75655  const providerIsTypeProvider = isTypeProvider(provider);
75656  const providerIsClassProvider = isClassProvider(provider);
75657
75658  if (providerIsTypeProvider || providerIsClassProvider) {
75659    // Resolve forward references as `useClass` can hold a forward reference.
75660    const classToken = providerIsClassProvider ? resolveForwardRef(provider.useClass) : provider;
75661    const prototype = classToken.prototype;
75662    const ngOnDestroy = prototype.ngOnDestroy;
75663
75664    if (ngOnDestroy) {
75665      const hooks = tView.destroyHooks || (tView.destroyHooks = []);
75666
75667      if (!providerIsTypeProvider && provider.multi) {
75668        ngDevMode && assertDefined(indexInFactory, 'indexInFactory when registering multi factory destroy hook');
75669        const existingCallbacksIndex = hooks.indexOf(contextIndex);
75670
75671        if (existingCallbacksIndex === -1) {
75672          hooks.push(contextIndex, [indexInFactory, ngOnDestroy]);
75673        } else {
75674          hooks[existingCallbacksIndex + 1].push(indexInFactory, ngOnDestroy);
75675        }
75676      } else {
75677        hooks.push(contextIndex, ngOnDestroy);
75678      }
75679    }
75680  }
75681}
75682/**
75683 * Add a factory in a multi factory.
75684 * @returns Index at which the factory was inserted.
75685 */
75686
75687
75688function multiFactoryAdd(multiFactory, factory, isComponentProvider) {
75689  if (isComponentProvider) {
75690    multiFactory.componentProviders++;
75691  }
75692
75693  return multiFactory.multi.push(factory) - 1;
75694}
75695/**
75696 * Returns the index of item in the array, but only in the begin to end range.
75697 */
75698
75699
75700function indexOf(item, arr, begin, end) {
75701  for (let i = begin; i < end; i++) {
75702    if (arr[i] === item) return i;
75703  }
75704
75705  return -1;
75706}
75707/**
75708 * Use this with `multi` `providers`.
75709 */
75710
75711
75712function multiProvidersFactoryResolver(_, tData, lData, tNode) {
75713  return multiResolve(this.multi, []);
75714}
75715/**
75716 * Use this with `multi` `viewProviders`.
75717 *
75718 * This factory knows how to concatenate itself with the existing `multi` `providers`.
75719 */
75720
75721
75722function multiViewProvidersFactoryResolver(_, tData, lView, tNode) {
75723  const factories = this.multi;
75724  let result;
75725
75726  if (this.providerFactory) {
75727    const componentCount = this.providerFactory.componentProviders;
75728    const multiProviders = getNodeInjectable(lView, lView[TVIEW], this.providerFactory.index, tNode); // Copy the section of the array which contains `multi` `providers` from the component
75729
75730    result = multiProviders.slice(0, componentCount); // Insert the `viewProvider` instances.
75731
75732    multiResolve(factories, result); // Copy the section of the array which contains `multi` `providers` from other directives
75733
75734    for (let i = componentCount; i < multiProviders.length; i++) {
75735      result.push(multiProviders[i]);
75736    }
75737  } else {
75738    result = []; // Insert the `viewProvider` instances.
75739
75740    multiResolve(factories, result);
75741  }
75742
75743  return result;
75744}
75745/**
75746 * Maps an array of factories into an array of values.
75747 */
75748
75749
75750function multiResolve(factories, result) {
75751  for (let i = 0; i < factories.length; i++) {
75752    const factory = factories[i];
75753    result.push(factory());
75754  }
75755
75756  return result;
75757}
75758/**
75759 * Creates a multi factory.
75760 */
75761
75762
75763function multiFactory(factoryFn, index, isViewProvider, isComponent, f) {
75764  const factory = new NodeInjectorFactory(factoryFn, isViewProvider, ɵɵdirectiveInject);
75765  factory.multi = [];
75766  factory.index = index;
75767  factory.componentProviders = 0;
75768  multiFactoryAdd(factory, f, isComponent && !isViewProvider);
75769  return factory;
75770}
75771/**
75772 * This feature resolves the providers of a directive (or component),
75773 * and publish them into the DI system, making it visible to others for injection.
75774 *
75775 * For example:
75776 * ```ts
75777 * class ComponentWithProviders {
75778 *   constructor(private greeter: GreeterDE) {}
75779 *
75780 *   static ɵcmp = defineComponent({
75781 *     type: ComponentWithProviders,
75782 *     selectors: [['component-with-providers']],
75783 *    factory: () => new ComponentWithProviders(directiveInject(GreeterDE as any)),
75784 *    decls: 1,
75785 *    vars: 1,
75786 *    template: function(fs: RenderFlags, ctx: ComponentWithProviders) {
75787 *      if (fs & RenderFlags.Create) {
75788 *        ɵɵtext(0);
75789 *      }
75790 *      if (fs & RenderFlags.Update) {
75791 *        ɵɵtextInterpolate(ctx.greeter.greet());
75792 *      }
75793 *    },
75794 *    features: [ɵɵProvidersFeature([GreeterDE])]
75795 *  });
75796 * }
75797 * ```
75798 *
75799 * @param definition
75800 *
75801 * @codeGenApi
75802 */
75803
75804
75805function ɵɵProvidersFeature(providers, viewProviders = []) {
75806  return definition => {
75807    definition.providersResolver = (def, processProvidersFn) => {
75808      return providersResolver(def, //
75809      processProvidersFn ? processProvidersFn(providers) : providers, //
75810      viewProviders);
75811    };
75812  };
75813}
75814/**
75815 * @license
75816 * Copyright Google LLC All Rights Reserved.
75817 *
75818 * Use of this source code is governed by an MIT-style license that can be
75819 * found in the LICENSE file at https://angular.io/license
75820 */
75821
75822/**
75823 * Represents an instance of an `NgModule` created by an `NgModuleFactory`.
75824 * Provides access to the `NgModule` instance and related objects.
75825 *
75826 * @publicApi
75827 */
75828
75829
75830class NgModuleRef$1 {}
75831/**
75832 * @publicApi
75833 *
75834 * @deprecated
75835 * This class was mostly used as a part of ViewEngine-based JIT API and is no longer needed in Ivy
75836 * JIT mode. See [JIT API changes due to ViewEngine deprecation](guide/deprecations#jit-api-changes)
75837 * for additional context. Angular provides APIs that accept NgModule classes directly (such as
75838 * [PlatformRef.bootstrapModule](api/core/PlatformRef#bootstrapModule) and
75839 * [createNgModule](api/core/createNgModule)), consider switching to those APIs instead of
75840 * using factory-based ones.
75841 */
75842
75843
75844class NgModuleFactory$1 {}
75845/**
75846 * @license
75847 * Copyright Google LLC All Rights Reserved.
75848 *
75849 * Use of this source code is governed by an MIT-style license that can be
75850 * found in the LICENSE file at https://angular.io/license
75851 */
75852
75853/**
75854 * Returns a new NgModuleRef instance based on the NgModule class and parent injector provided.
75855 *
75856 * @param ngModule NgModule class.
75857 * @param parentInjector Optional injector instance to use as a parent for the module injector. If
75858 *     not provided, `NullInjector` will be used instead.
75859 * @returns NgModuleRef that represents an NgModule instance.
75860 *
75861 * @publicApi
75862 */
75863
75864
75865function createNgModule(ngModule, parentInjector) {
75866  return new NgModuleRef(ngModule, parentInjector ?? null);
75867}
75868/**
75869 * The `createNgModule` function alias for backwards-compatibility.
75870 * Please avoid using it directly and use `createNgModule` instead.
75871 *
75872 * @deprecated Use `createNgModule` instead.
75873 */
75874
75875
75876const createNgModuleRef = createNgModule;
75877
75878class NgModuleRef extends NgModuleRef$1 {
75879  constructor(ngModuleType, _parent) {
75880    super();
75881    this._parent = _parent; // tslint:disable-next-line:require-internal-with-underscore
75882
75883    this._bootstrapComponents = [];
75884    this.destroyCbs = []; // When bootstrapping a module we have a dependency graph that looks like this:
75885    // ApplicationRef -> ComponentFactoryResolver -> NgModuleRef. The problem is that if the
75886    // module being resolved tries to inject the ComponentFactoryResolver, it'll create a
75887    // circular dependency which will result in a runtime error, because the injector doesn't
75888    // exist yet. We work around the issue by creating the ComponentFactoryResolver ourselves
75889    // and providing it, rather than letting the injector resolve it.
75890
75891    this.componentFactoryResolver = new ComponentFactoryResolver(this);
75892    const ngModuleDef = getNgModuleDef(ngModuleType);
75893    ngDevMode && assertDefined(ngModuleDef, `NgModule '${stringify(ngModuleType)}' is not a subtype of 'NgModuleType'.`);
75894    this._bootstrapComponents = maybeUnwrapFn(ngModuleDef.bootstrap);
75895    this._r3Injector = createInjectorWithoutInjectorInstances(ngModuleType, _parent, [{
75896      provide: NgModuleRef$1,
75897      useValue: this
75898    }, {
75899      provide: ComponentFactoryResolver$1,
75900      useValue: this.componentFactoryResolver
75901    }], stringify(ngModuleType), new Set(['environment'])); // We need to resolve the injector types separately from the injector creation, because
75902    // the module might be trying to use this ref in its constructor for DI which will cause a
75903    // circular error that will eventually error out, because the injector isn't created yet.
75904
75905    this._r3Injector.resolveInjectorInitializers();
75906
75907    this.instance = this._r3Injector.get(ngModuleType);
75908  }
75909
75910  get injector() {
75911    return this._r3Injector;
75912  }
75913
75914  destroy() {
75915    ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
75916    const injector = this._r3Injector;
75917    !injector.destroyed && injector.destroy();
75918    this.destroyCbs.forEach(fn => fn());
75919    this.destroyCbs = null;
75920  }
75921
75922  onDestroy(callback) {
75923    ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
75924    this.destroyCbs.push(callback);
75925  }
75926
75927}
75928
75929class NgModuleFactory extends NgModuleFactory$1 {
75930  constructor(moduleType) {
75931    super();
75932    this.moduleType = moduleType;
75933  }
75934
75935  create(parentInjector) {
75936    return new NgModuleRef(this.moduleType, parentInjector);
75937  }
75938
75939}
75940
75941class EnvironmentNgModuleRefAdapter extends NgModuleRef$1 {
75942  constructor(providers, parent, source) {
75943    super();
75944    this.componentFactoryResolver = new ComponentFactoryResolver(this);
75945    this.instance = null;
75946    const injector = new R3Injector([...providers, {
75947      provide: NgModuleRef$1,
75948      useValue: this
75949    }, {
75950      provide: ComponentFactoryResolver$1,
75951      useValue: this.componentFactoryResolver
75952    }], parent || getNullInjector(), source, new Set(['environment']));
75953    this.injector = injector;
75954    injector.resolveInjectorInitializers();
75955  }
75956
75957  destroy() {
75958    this.injector.destroy();
75959  }
75960
75961  onDestroy(callback) {
75962    this.injector.onDestroy(callback);
75963  }
75964
75965}
75966/**
75967 * Create a new environment injector.
75968 *
75969 * Learn more about environment injectors in
75970 * [this guide](guide/standalone-components#environment-injectors).
75971 *
75972 * @param providers An array of providers.
75973 * @param parent A parent environment injector.
75974 * @param debugName An optional name for this injector instance, which will be used in error
75975 *     messages.
75976 *
75977 * @publicApi
75978 * @developerPreview
75979 */
75980
75981
75982function createEnvironmentInjector(providers, parent, debugName = null) {
75983  const adapter = new EnvironmentNgModuleRefAdapter(providers, parent, debugName);
75984  return adapter.injector;
75985}
75986/**
75987 * @license
75988 * Copyright Google LLC All Rights Reserved.
75989 *
75990 * Use of this source code is governed by an MIT-style license that can be
75991 * found in the LICENSE file at https://angular.io/license
75992 */
75993
75994/**
75995 * A service used by the framework to create instances of standalone injectors. Those injectors are
75996 * created on demand in case of dynamic component instantiation and contain ambient providers
75997 * collected from the imports graph rooted at a given standalone component.
75998 */
75999
76000
76001class StandaloneService {
76002  constructor(_injector) {
76003    this._injector = _injector;
76004    this.cachedInjectors = new Map();
76005  }
76006
76007  getOrCreateStandaloneInjector(componentDef) {
76008    if (!componentDef.standalone) {
76009      return null;
76010    }
76011
76012    if (!this.cachedInjectors.has(componentDef.id)) {
76013      const providers = internalImportProvidersFrom(false, componentDef.type);
76014      const standaloneInjector = providers.length > 0 ? createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) : null;
76015      this.cachedInjectors.set(componentDef.id, standaloneInjector);
76016    }
76017
76018    return this.cachedInjectors.get(componentDef.id);
76019  }
76020
76021  ngOnDestroy() {
76022    try {
76023      for (const injector of this.cachedInjectors.values()) {
76024        if (injector !== null) {
76025          injector.destroy();
76026        }
76027      }
76028    } finally {
76029      this.cachedInjectors.clear();
76030    }
76031  }
76032
76033}
76034/** @nocollapse */
76035
76036
76037StandaloneService.ɵprov = ɵɵdefineInjectable({
76038  token: StandaloneService,
76039  providedIn: 'environment',
76040  factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector))
76041});
76042/**
76043 * A feature that acts as a setup code for the {@link StandaloneService}.
76044 *
76045 * The most important responsibility of this feature is to expose the "getStandaloneInjector"
76046 * function (an entry points to a standalone injector creation) on a component definition object. We
vendor: 5,134 bytes, lines 76047-76220
76047 * go through the features infrastructure to make sure that the standalone injector creation logic
76048 * is tree-shakable and not included in applications that don't use standalone components.
76049 *
76050 * @codeGenApi
76051 */
76052
76053function ɵɵStandaloneFeature(definition) {
76054  definition.getStandaloneInjector = parentInjector => {
76055    return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition);
76056  };
76057}
76058/**
76059 * @license
76060 * Copyright Google LLC All Rights Reserved.
76061 *
76062 * Use of this source code is governed by an MIT-style license that can be
76063 * found in the LICENSE file at https://angular.io/license
76064 */
76065
76066/**
76067 * Retrieves the component instance associated with a given DOM element.
76068 *
76069 * @usageNotes
76070 * Given the following DOM structure:
76071 *
76072 * ```html
76073 * <app-root>
76074 *   <div>
76075 *     <child-comp></child-comp>
76076 *   </div>
76077 * </app-root>
76078 * ```
76079 *
76080 * Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
76081 * associated with this DOM element.
76082 *
76083 * Calling the function on `<app-root>` will return the `MyApp` instance.
76084 *
76085 *
76086 * @param element DOM element from which the component should be retrieved.
76087 * @returns Component instance associated with the element or `null` if there
76088 *    is no component associated with it.
76089 *
76090 * @publicApi
76091 * @globalApi ng
76092 */
76093
76094
76095function getComponent(element) {
76096  ngDevMode && assertDomElement(element);
76097  const context = getLContext(element);
76098  if (context === null) return null;
76099
76100  if (context.component === undefined) {
76101    const lView = context.lView;
76102
76103    if (lView === null) {
76104      return null;
76105    }
76106
76107    context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
76108  }
76109
76110  return context.component;
76111}
76112/**
76113 * If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
76114 * view that the element is part of. Otherwise retrieves the instance of the component whose view
76115 * owns the element (in this case, the result is the same as calling `getOwningComponent`).
76116 *
76117 * @param element Element for which to get the surrounding component instance.
76118 * @returns Instance of the component that is around the element or null if the element isn't
76119 *    inside any component.
76120 *
76121 * @publicApi
76122 * @globalApi ng
76123 */
76124
76125
76126function getContext(element) {
76127  assertDomElement(element);
76128  const context = getLContext(element);
76129  const lView = context ? context.lView : null;
76130  return lView === null ? null : lView[CONTEXT];
76131}
76132/**
76133 * Retrieves the component instance whose view contains the DOM element.
76134 *
76135 * For example, if `<child-comp>` is used in the template of `<app-comp>`
76136 * (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
76137 * would return `<app-comp>`.
76138 *
76139 * @param elementOrDir DOM element, component or directive instance
76140 *    for which to retrieve the root components.
76141 * @returns Component instance whose view owns the DOM element or null if the element is not
76142 *    part of a component view.
76143 *
76144 * @publicApi
76145 * @globalApi ng
76146 */
76147
76148
76149function getOwningComponent(elementOrDir) {
76150  const context = getLContext(elementOrDir);
76151  let lView = context ? context.lView : null;
76152  if (lView === null) return null;
76153  let parent;
76154
76155  while (lView[TVIEW].type === 2
76156  /* TViewType.Embedded */
76157  && (parent = getLViewParent(lView))) {
76158    lView = parent;
76159  }
76160
76161  return lView[FLAGS] & 256
76162  /* LViewFlags.IsRoot */
76163  ? null : lView[CONTEXT];
76164}
76165/**
76166 * Retrieves all root components associated with a DOM element, directive or component instance.
76167 * Root components are those which have been bootstrapped by Angular.
76168 *
76169 * @param elementOrDir DOM element, component or directive instance
76170 *    for which to retrieve the root components.
76171 * @returns Root components associated with the target object.
76172 *
76173 * @publicApi
76174 * @globalApi ng
76175 */
76176
76177
76178function getRootComponents(elementOrDir) {
76179  const lView = readPatchedLView(elementOrDir);
76180  return lView !== null ? [getRootContext(lView)] : [];
76181}
76182/**
76183 * Retrieves an `Injector` associated with an element, component or directive instance.
76184 *
76185 * @param elementOrDir DOM element, component or directive instance for which to
76186 *    retrieve the injector.
76187 * @returns Injector associated with the element, component or directive instance.
76188 *
76189 * @publicApi
76190 * @globalApi ng
76191 */
76192
76193
76194function getInjector(elementOrDir) {
76195  const context = getLContext(elementOrDir);
76196  const lView = context ? context.lView : null;
76197  if (lView === null) return Injector.NULL;
76198  const tNode = lView[TVIEW].data[context.nodeIndex];
76199  return new NodeInjector(tNode, lView);
76200}
76201/**
76202 * Retrieve a set of injection tokens at a given DOM node.
76203 *
76204 * @param element Element for which the injection tokens should be retrieved.
76205 */
76206
76207
76208function getInjectionTokens(element) {
76209  const context = getLContext(element);
76210  const lView = context ? context.lView : null;
76211  if (lView === null) return [];
76212  const tView = lView[TVIEW];
76213  const tNode = tView.data[context.nodeIndex];
76214  const providerTokens = [];
76215  const startIndex = tNode.providerIndexes & 1048575
76216  /* TNodeProviderIndexes.ProvidersStartIndexMask */
76217  ;
76218  const endIndex = tNode.directiveEnd;
76219
76220  for (let i = startIndex; i < endIndex; i++) {
76221    let value = tView.data[i];
76222
76223    if (isDirectiveDefHack(value)) {
76224      // The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
76225      // design flaw.  We should always store same type so that we can be monomorphic. The issue
76226      // is that for Components/Directives we store the def instead the type. The correct behavior
76227      // is that we should always be storing injectable type in this location.
76228      value = value.type;
76229    }
76230
76231    providerTokens.push(value);
76232  }
76233
76234  return providerTokens;
76235}
76236/**
76237 * Retrieves directive instances associated with a given DOM node. Does not include
76238 * component instances.
76239 *
76240 * @usageNotes
76241 * Given the following DOM structure:
76242 *
76243 * ```html
76244 * <app-root>
76245 *   <button my-button></button>
76246 *   <my-comp></my-comp>
76247 * </app-root>
76248 * ```
76249 *
76250 * Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
76251 * directive that is associated with the DOM node.
76252 *
76253 * Calling `getDirectives` on `<my-comp>` will return an empty array.
76254 *
76255 * @param node DOM node for which to get the directives.
76256 * @returns Array of directives associated with the node.
76257 *
76258 * @publicApi
76259 * @globalApi ng
76260 */
76261
76262
76263function getDirectives(node) {
76264  // Skip text nodes because we can't have directives associated with them.
76265  if (node instanceof Text) {
76266    return [];
76267  }
76268
76269  const context = getLContext(node);
76270  const lView = context ? context.lView : null;
76271
76272  if (lView === null) {
76273    return [];
76274  }
76275
76276  const tView = lView[TVIEW];
76277  const nodeIndex = context.nodeIndex;
76278
76279  if (!tView?.data[nodeIndex]) {
76280    return [];
76281  }
76282
76283  if (context.directives === undefined) {
76284    context.directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
76285  } // The `directives` in this case are a named array called `LComponentView`. Clone the
76286  // result so we don't expose an internal data structure in the user's console.
76287
76288
76289  return context.directives === null ? [] : [...context.directives];
76290}
76291/**
76292 * Returns the debug (partial) metadata for a particular directive or component instance.
76293 * The function accepts an instance of a directive or component and returns the corresponding
76294 * metadata.
76295 *
76296 * @param directiveOrComponentInstance Instance of a directive or component
76297 * @returns metadata of the passed directive or component
76298 *
76299 * @publicApi
76300 * @globalApi ng
76301 */
76302
76303
76304function getDirectiveMetadata$1(directiveOrComponentInstance) {
76305  const {
76306    constructor
76307  } = directiveOrComponentInstance;
76308
76309  if (!constructor) {
76310    throw new Error('Unable to find the instance constructor');
76311  } // In case a component inherits from a directive, we may have component and directive metadata
76312  // To ensure we don't get the metadata of the directive, we want to call `getComponentDef` first.
76313
76314
76315  const componentDef = getComponentDef(constructor);
76316
76317  if (componentDef) {
76318    return {
76319      inputs: componentDef.inputs,
76320      outputs: componentDef.outputs,
76321      encapsulation: componentDef.encapsulation,
76322      changeDetection: componentDef.onPush ? ChangeDetectionStrategy.OnPush : ChangeDetectionStrategy.Default
76323    };
76324  }
76325
76326  const directiveDef = getDirectiveDef(constructor);
76327
76328  if (directiveDef) {
76329    return {
76330      inputs: directiveDef.inputs,
76331      outputs: directiveDef.outputs
76332    };
76333  }
76334
76335  return null;
76336}
76337/**
76338 * Retrieve map of local references.
76339 *
76340 * The references are retrieved as a map of local reference name to element or directive instance.
76341 *
76342 * @param target DOM element, component or directive instance for which to retrieve
76343 *    the local references.
76344 */
76345
76346
76347function getLocalRefs(target) {
76348  const context = getLContext(target);
76349  if (context === null) return {};
76350
76351  if (context.localRefs === undefined) {
76352    const lView = context.lView;
76353
76354    if (lView === null) {
76355      return {};
76356    }
76357
76358    context.localRefs = discoverLocalRefs(lView, context.nodeIndex);
76359  }
76360
76361  return context.localRefs || {};
76362}
76363/**
76364 * Retrieves the host element of a component or directive instance.
76365 * The host element is the DOM element that matched the selector of the directive.
76366 *
76367 * @param componentOrDirective Component or directive instance for which the host
76368 *     element should be retrieved.
76369 * @returns Host element of the target.
76370 *
76371 * @publicApi
76372 * @globalApi ng
76373 */
76374
76375
76376function getHostElement(componentOrDirective) {
76377  return getLContext(componentOrDirective).native;
76378}
76379/**
76380 * Retrieves the rendered text for a given component.
76381 *
76382 * This function retrieves the host element of a component and
76383 * and then returns the `textContent` for that element. This implies
76384 * that the text returned will include re-projected content of
76385 * the component as well.
76386 *
76387 * @param component The component to return the content text for.
76388 */
76389
76390
76391function getRenderedText(component) {
76392  const hostElement = getHostElement(component);
76393  return hostElement.textContent || '';
76394}
76395/**
76396 * Retrieves a list of event listeners associated with a DOM element. The list does include host
76397 * listeners, but it does not include event listeners defined outside of the Angular context
76398 * (e.g. through `addEventListener`).
76399 *
76400 * @usageNotes
76401 * Given the following DOM structure:
76402 *
76403 * ```html
76404 * <app-root>
76405 *   <div (click)="doSomething()"></div>
76406 * </app-root>
76407 * ```
76408 *
76409 * Calling `getListeners` on `<div>` will return an object that looks as follows:
76410 *
76411 * ```ts
76412 * {
76413 *   name: 'click',
76414 *   element: <div>,
76415 *   callback: () => doSomething(),
76416 *   useCapture: false
76417 * }
76418 * ```
76419 *
76420 * @param element Element for which the DOM listeners should be retrieved.
76421 * @returns Array of event listeners on the DOM element.
76422 *
76423 * @publicApi
76424 * @globalApi ng
76425 */
76426
76427
76428function getListeners(element) {
76429  ngDevMode && assertDomElement(element);
76430  const lContext = getLContext(element);
76431  const lView = lContext === null ? null : lContext.lView;
76432  if (lView === null) return [];
76433  const tView = lView[TVIEW];
76434  const lCleanup = lView[CLEANUP];
76435  const tCleanup = tView.cleanup;
76436  const listeners = [];
76437
76438  if (tCleanup && lCleanup) {
76439    for (let i = 0; i < tCleanup.length;) {
76440      const firstParam = tCleanup[i++];
76441      const secondParam = tCleanup[i++];
76442
76443      if (typeof firstParam === 'string') {
76444        const name = firstParam;
76445        const listenerElement = unwrapRNode(lView[secondParam]);
76446        const callback = lCleanup[tCleanup[i++]];
76447        const useCaptureOrIndx = tCleanup[i++]; // if useCaptureOrIndx is boolean then report it as is.
76448        // if useCaptureOrIndx is positive number then it in unsubscribe method
76449        // if useCaptureOrIndx is negative number then it is a Subscription
76450
76451        const type = typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0 ? 'dom' : 'output';
76452        const useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
76453
76454        if (element == listenerElement) {
76455          listeners.push({
76456            element,
76457            name,
76458            callback,
76459            useCapture,
76460            type
76461          });
76462        }
76463      }
76464    }
76465  }
76466
76467  listeners.sort(sortListeners);
76468  return listeners;
76469}
76470
76471function sortListeners(a, b) {
76472  if (a.name == b.name) return 0;
76473  return a.name < b.name ? -1 : 1;
76474}
76475/**
76476 * This function should not exist because it is megamorphic and only mostly correct.
76477 *
76478 * See call site for more info.
76479 */
76480
76481
76482function isDirectiveDefHack(obj) {
76483  return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
76484}
76485/**
76486 * Returns the attached `DebugNode` instance for an element in the DOM.
76487 *
76488 * @param element DOM element which is owned by an existing component's view.
76489 */
76490
76491
76492function getDebugNode$1(element) {
76493  if (ngDevMode && !(element instanceof Node)) {
76494    throw new Error('Expecting instance of DOM Element');
76495  }
76496
76497  const lContext = getLContext(element);
76498  const lView = lContext ? lContext.lView : null;
76499
76500  if (lView === null) {
76501    return null;
76502  }
76503
76504  const nodeIndex = lContext.nodeIndex;
76505
76506  if (nodeIndex !== -1) {
76507    const valueInLView = lView[nodeIndex]; // this means that value in the lView is a component with its own
76508    // data. In this situation the TNode is not accessed at the same spot.
76509
76510    const tNode = isLView(valueInLView) ? valueInLView[T_HOST] : getTNode(lView[TVIEW], nodeIndex);
76511    ngDevMode && assertEqual(tNode.index, nodeIndex, 'Expecting that TNode at index is same as index');
76512    return buildDebugNode(tNode, lView);
76513  }
76514
76515  return null;
76516}
76517/**
76518 * Retrieve the component `LView` from component/element.
76519 *
76520 * NOTE: `LView` is a private and should not be leaked outside.
76521 *       Don't export this method to `ng.*` on window.
76522 *
76523 * @param target DOM element or component instance for which to retrieve the LView.
76524 */
76525
76526
76527function getComponentLView(target) {
76528  const lContext = getLContext(target);
76529  const nodeIndx = lContext.nodeIndex;
76530  const lView = lContext.lView;
76531  ngDevMode && assertLView(lView);
76532  const componentLView = lView[nodeIndx];
76533  ngDevMode && assertLView(componentLView);
76534  return componentLView;
76535}
76536/** Asserts that a value is a DOM Element. */
76537
76538
76539function assertDomElement(value) {
76540  if (typeof Element !== 'undefined' && !(value instanceof Element)) {
76541    throw new Error('Expecting instance of DOM Element');
76542  }
76543}
76544/**
76545 * @license
76546 * Copyright Google LLC All Rights Reserved.
76547 *
76548 * Use of this source code is governed by an MIT-style license that can be
76549 * found in the LICENSE file at https://angular.io/license
76550 */
76551
76552/**
76553 * Adds decorator, constructor, and property metadata to a given type via static metadata fields
76554 * on the type.
76555 *
76556 * These metadata fields can later be read with Angular's `ReflectionCapabilities` API.
76557 *
76558 * Calls to `setClassMetadata` can be guarded by ngDevMode, resulting in the metadata assignments
76559 * being tree-shaken away during production builds.
76560 */
76561
76562
76563function setClassMetadata(type, decorators, ctorParameters, propDecorators) {
76564  return noSideEffects(() => {
76565    const clazz = type;
76566
76567    if (decorators !== null) {
76568      if (clazz.hasOwnProperty('decorators') && clazz.decorators !== undefined) {
76569        clazz.decorators.push(...decorators);
76570      } else {
76571        clazz.decorators = decorators;
76572      }
76573    }
76574
76575    if (ctorParameters !== null) {
76576      // Rather than merging, clobber the existing parameters. If other projects exist which
76577      // use tsickle-style annotations and reflect over them in the same way, this could
76578      // cause issues, but that is vanishingly unlikely.
76579      clazz.ctorParameters = ctorParameters;
76580    }
76581
76582    if (propDecorators !== null) {
76583      // The property decorator objects are merged as it is possible different fields have
76584      // different decorator types. Decorators on individual fields are not merged, as it's
76585      // also incredibly unlikely that a field will be decorated both with an Angular
76586      // decorator and a non-Angular decorator that's also been downleveled.
76587      if (clazz.hasOwnProperty('propDecorators') && clazz.propDecorators !== undefined) {
76588        clazz.propDecorators = { ...clazz.propDecorators,
76589          ...propDecorators
76590        };
76591      } else {
76592        clazz.propDecorators = propDecorators;
76593      }
76594    }
76595  });
76596}
76597/**
76598 * @license
76599 * Copyright Google LLC All Rights Reserved.
76600 *
76601 * Use of this source code is governed by an MIT-style license that can be
76602 * found in the LICENSE file at https://angular.io/license
76603 */
76604
76605/**
76606 * Bindings for pure functions are stored after regular bindings.
76607 *
76608 * |-------decls------|---------vars---------|                 |----- hostVars (dir1) ------|
76609 * ------------------------------------------------------------------------------------------
76610 * | nodes/refs/pipes | bindings | fn slots  | injector | dir1 | host bindings | host slots |
76611 * ------------------------------------------------------------------------------------------
76612 *                    ^                      ^
76613 *      TView.bindingStartIndex      TView.expandoStartIndex
76614 *
76615 * Pure function instructions are given an offset from the binding root. Adding the offset to the
76616 * binding root gives the first index where the bindings are stored. In component views, the binding
76617 * root is the bindingStartIndex. In host bindings, the binding root is the exp
vendor: 16,985 bytes, lines 76617-77072
76617andoStartIndex +
76618 * any directive instances + any hostVars in directives evaluated before it.
76619 *
76620 * See VIEW_DATA.md for more information about host binding resolution.
76621 */
76622
76623/**
76624 * If the value hasn't been saved, calls the pure function to store and return the
76625 * value. If it has been saved, returns the saved value.
76626 *
76627 * @param slotOffset the offset from binding root to the reserved slot
76628 * @param pureFn Function that returns a value
76629 * @param thisArg Optional calling context of pureFn
76630 * @returns value
76631 *
76632 * @codeGenApi
76633 */
76634
76635
76636function ɵɵpureFunction0(slotOffset, pureFn, thisArg) {
76637  const bindingIndex = getBindingRoot() + slotOffset;
76638  const lView = getLView();
76639  return lView[bindingIndex] === NO_CHANGE ? updateBinding(lView, bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) : getBinding(lView, bindingIndex);
76640}
76641/**
76642 * If the value of the provided exp has changed, calls the pure function to return
76643 * an updated value. Or if the value has not changed, returns cached value.
76644 *
76645 * @param slotOffset the offset from binding root to the reserved slot
76646 * @param pureFn Function that returns an updated value
76647 * @param exp Updated expression value
76648 * @param thisArg Optional calling context of pureFn
76649 * @returns Updated or cached value
76650 *
76651 * @codeGenApi
76652 */
76653
76654
76655function ɵɵpureFunction1(slotOffset, pureFn, exp, thisArg) {
76656  return pureFunction1Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp, thisArg);
76657}
76658/**
76659 * If the value of any provided exp has changed, calls the pure function to return
76660 * an updated value. Or if no values have changed, returns cached value.
76661 *
76662 * @param slotOffset the offset from binding root to the reserved slot
76663 * @param pureFn
76664 * @param exp1
76665 * @param exp2
76666 * @param thisArg Optional calling context of pureFn
76667 * @returns Updated or cached value
76668 *
76669 * @codeGenApi
76670 */
76671
76672
76673function ɵɵpureFunction2(slotOffset, pureFn, exp1, exp2, thisArg) {
76674  return pureFunction2Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, thisArg);
76675}
76676/**
76677 * If the value of any provided exp has changed, calls the pure function to return
76678 * an updated value. Or if no values have changed, returns cached value.
76679 *
76680 * @param slotOffset the offset from binding root to the reserved slot
76681 * @param pureFn
76682 * @param exp1
76683 * @param exp2
76684 * @param exp3
76685 * @param thisArg Optional calling context of pureFn
76686 * @returns Updated or cached value
76687 *
76688 * @codeGenApi
76689 */
76690
76691
76692function ɵɵpureFunction3(slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
76693  return pureFunction3Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, thisArg);
76694}
76695/**
76696 * If the value of any provided exp has changed, calls the pure function to return
76697 * an updated value. Or if no values have changed, returns cached value.
76698 *
76699 * @param slotOffset the offset from binding root to the reserved slot
76700 * @param pureFn
76701 * @param exp1
76702 * @param exp2
76703 * @param exp3
76704 * @param exp4
76705 * @param thisArg Optional calling context of pureFn
76706 * @returns Updated or cached value
76707 *
76708 * @codeGenApi
76709 */
76710
76711
76712function ɵɵpureFunction4(slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
76713  return pureFunction4Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg);
76714}
76715/**
76716 * If the value of any provided exp has changed, calls the pure function to return
76717 * an updated value. Or if no values have changed, returns cached value.
76718 *
76719 * @param slotOffset the offset from binding root to the reserved slot
76720 * @param pureFn
76721 * @param exp1
76722 * @param exp2
76723 * @param exp3
76724 * @param exp4
76725 * @param exp5
76726 * @param thisArg Optional calling context of pureFn
76727 * @returns Updated or cached value
76728 *
76729 * @codeGenApi
76730 */
76731
76732
76733function ɵɵpureFunction5(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, thisArg) {
76734  const bindingIndex = getBindingRoot() + slotOffset;
76735  const lView = getLView();
76736  const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
76737  return bindingUpdated(lView, bindingIndex + 4, exp5) || different ? updateBinding(lView, bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) : pureFn(exp1, exp2, exp3, exp4, exp5)) : getBinding(lView, bindingIndex + 5);
76738}
76739/**
76740 * If the value of any provided exp has changed, calls the pure function to return
76741 * an updated value. Or if no values have changed, returns cached value.
76742 *
76743 * @param slotOffset the offset from binding root to the reserved slot
76744 * @param pureFn
76745 * @param exp1
76746 * @param exp2
76747 * @param exp3
76748 * @param exp4
76749 * @param exp5
76750 * @param exp6
76751 * @param thisArg Optional calling context of pureFn
76752 * @returns Updated or cached value
76753 *
76754 * @codeGenApi
76755 */
76756
76757
76758function ɵɵpureFunction6(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, thisArg) {
76759  const bindingIndex = getBindingRoot() + slotOffset;
76760  const lView = getLView();
76761  const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
76762  return bindingUpdated2(lView, bindingIndex + 4, exp5, exp6) || different ? updateBinding(lView, bindingIndex + 6, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) : pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) : getBinding(lView, bindingIndex + 6);
76763}
76764/**
76765 * If the value of any provided exp has changed, calls the pure function to return
76766 * an updated value. Or if no values have changed, returns cached value.
76767 *
76768 * @param slotOffset the offset from binding root to the reserved slot
76769 * @param pureFn
76770 * @param exp1
76771 * @param exp2
76772 * @param exp3
76773 * @param exp4
76774 * @param exp5
76775 * @param exp6
76776 * @param exp7
76777 * @param thisArg Optional calling context of pureFn
76778 * @returns Updated or cached value
76779 *
76780 * @codeGenApi
76781 */
76782
76783
76784function ɵɵpureFunction7(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, thisArg) {
76785  const bindingIndex = getBindingRoot() + slotOffset;
76786  const lView = getLView();
76787  let different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
76788  return bindingUpdated3(lView, bindingIndex + 4, exp5, exp6, exp7) || different ? updateBinding(lView, bindingIndex + 7, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7) : pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7)) : getBinding(lView, bindingIndex + 7);
76789}
76790/**
76791 * If the value of any provided exp has changed, calls the pure function to return
76792 * an updated value. Or if no values have changed, returns cached value.
76793 *
76794 * @param slotOffset the offset from binding root to the reserved slot
76795 * @param pureFn
76796 * @param exp1
76797 * @param exp2
76798 * @param exp3
76799 * @param exp4
76800 * @param exp5
76801 * @param exp6
76802 * @param exp7
76803 * @param exp8
76804 * @param thisArg Optional calling context of pureFn
76805 * @returns Updated or cached value
76806 *
76807 * @codeGenApi
76808 */
76809
76810
76811function ɵɵpureFunction8(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, thisArg) {
76812  const bindingIndex = getBindingRoot() + slotOffset;
76813  const lView = getLView();
76814  const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
76815  return bindingUpdated4(lView, bindingIndex + 4, exp5, exp6, exp7, exp8) || different ? updateBinding(lView, bindingIndex + 8, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8) : pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8)) : getBinding(lView, bindingIndex + 8);
76816}
76817/**
76818 * pureFunction instruction that can support any number of bindings.
76819 *
76820 * If the value of any provided exp has changed, calls the pure function to return
76821 * an updated value. Or if no values have changed, returns cached value.
76822 *
76823 * @param slotOffset the offset from binding root to the reserved slot
76824 * @param pureFn A pure function that takes binding values and builds an object or array
76825 * containing those values.
76826 * @param exps An array of binding values
76827 * @param thisArg Optional calling context of pureFn
76828 * @returns Updated or cached value
76829 *
76830 * @codeGenApi
76831 */
76832
76833
76834function ɵɵpureFunctionV(slotOffset, pureFn, exps, thisArg) {
76835  return pureFunctionVInternal(getLView(), getBindingRoot(), slotOffset, pureFn, exps, thisArg);
76836}
76837/**
76838 * Results of a pure function invocation are stored in LView in a dedicated slot that is initialized
76839 * to NO_CHANGE. In rare situations a pure pipe might throw an exception on the very first
76840 * invocation and not produce any valid results. In this case LView would keep holding the NO_CHANGE
76841 * value. The NO_CHANGE is not something that we can use in expressions / bindings thus we convert
76842 * it to `undefined`.
76843 */
76844
76845
76846function getPureFunctionReturnValue(lView, returnValueIndex) {
76847  ngDevMode && assertIndexInRange(lView, returnValueIndex);
76848  const lastReturnValue = lView[returnValueIndex];
76849  return lastReturnValue === NO_CHANGE ? undefined : lastReturnValue;
76850}
76851/**
76852 * If the value of the provided exp has changed, calls the pure function to return
76853 * an updated value. Or if the value has not changed, returns cached value.
76854 *
76855 * @param lView LView in which the function is being executed.
76856 * @param bindingRoot Binding root index.
76857 * @param slotOffset the offset from binding root to the reserved slot
76858 * @param pureFn Function that returns an updated value
76859 * @param exp Updated expression value
76860 * @param thisArg Optional calling context of pureFn
76861 * @returns Updated or cached value
76862 */
76863
76864
76865function pureFunction1Internal(lView, bindingRoot, slotOffset, pureFn, exp, thisArg) {
76866  const bindingIndex = bindingRoot + slotOffset;
76867  return bindingUpdated(lView, bindingIndex, exp) ? updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) : getPureFunctionReturnValue(lView, bindingIndex + 1);
76868}
76869/**
76870 * If the value of any provided exp has changed, calls the pure function to return
76871 * an updated value. Or if no values have changed, returns cached value.
76872 *
76873 * @param lView LView in which the function is being executed.
76874 * @param bindingRoot Binding root index.
76875 * @param slotOffset the offset from binding root to the reserved slot
76876 * @param pureFn
76877 * @param exp1
76878 * @param exp2
76879 * @param thisArg Optional calling context of pureFn
76880 * @returns Updated or cached value
76881 */
76882
76883
76884function pureFunction2Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, thisArg) {
76885  const bindingIndex = bindingRoot + slotOffset;
76886  return bindingUpdated2(lView, bindingIndex, exp1, exp2) ? updateBinding(lView, bindingIndex + 2, thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) : getPureFunctionReturnValue(lView, bindingIndex + 2);
76887}
76888/**
76889 * If the value of any provided exp has changed, calls the pure function to return
76890 * an updated value. Or if no values have changed, returns cached value.
76891 *
76892 * @param lView LView in which the function is being executed.
76893 * @param bindingRoot Binding root index.
76894 * @param slotOffset the offset from binding root to the reserved slot
76895 * @param pureFn
76896 * @param exp1
76897 * @param exp2
76898 * @param exp3
76899 * @param thisArg Optional calling context of pureFn
76900 * @returns Updated or cached value
76901 */
76902
76903
76904function pureFunction3Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
76905  const bindingIndex = bindingRoot + slotOffset;
76906  return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ? updateBinding(lView, bindingIndex + 3, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) : getPureFunctionReturnValue(lView, bindingIndex + 3);
76907}
76908/**
76909 * If the value of any provided exp has changed, calls the pure function to return
76910 * an updated value. Or if no values have changed, returns cached value.
76911 *
76912 * @param lView LView in which the function is being executed.
76913 * @param bindingRoot Binding root index.
76914 * @param slotOffset the offset from binding root to the reserved slot
76915 * @param pureFn
76916 * @param exp1
76917 * @param exp2
76918 * @param exp3
76919 * @param exp4
76920 * @param thisArg Optional calling context of pureFn
76921 * @returns Updated or cached value
76922 *
76923 */
76924
76925
76926function pureFunction4Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
76927  const bindingIndex = bindingRoot + slotOffset;
76928  return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ? updateBinding(lView, bindingIndex + 4, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) : getPureFunctionReturnValue(lView, bindingIndex + 4);
76929}
76930/**
76931 * pureFunction instruction that can support any number of bindings.
76932 *
76933 * If the value of any provided exp has changed, calls the pure function to return
76934 * an updated value. Or if no values have changed, returns cached value.
76935 *
76936 * @param lView LView in which the function is being executed.
76937 * @param bindingRoot Binding root index.
76938 * @param slotOffset the offset from binding root to the reserved slot
76939 * @param pureFn A pure function that takes binding values and builds an object or array
76940 * containing those values.
76941 * @param exps An array of binding values
76942 * @param thisArg Optional calling context of pureFn
76943 * @returns Updated or cached value
76944 */
76945
76946
76947function pureFunctionVInternal(lView, bindingRoot, slotOffset, pureFn, exps, thisArg) {
76948  let bindingIndex = bindingRoot + slotOffset;
76949  let different = false;
76950
76951  for (let i = 0; i < exps.length; i++) {
76952    bindingUpdated(lView, bindingIndex++, exps[i]) && (different = true);
76953  }
76954
76955  return different ? updateBinding(lView, bindingIndex, pureFn.apply(thisArg, exps)) : getPureFunctionReturnValue(lView, bindingIndex);
76956}
76957/**
76958 * @license
76959 * Copyright Google LLC All Rights Reserved.
76960 *
76961 * Use of this source code is governed by an MIT-style license that can be
76962 * found in the LICENSE file at https://angular.io/license
76963 */
76964
76965/**
76966 * Create a pipe.
76967 *
76968 * @param index Pipe index where the pipe will be stored.
76969 * @param pipeName The name of the pipe
76970 * @returns T the instance of the pipe.
76971 *
76972 * @codeGenApi
76973 */
76974
76975
76976function ɵɵpipe(index, pipeName) {
76977  const tView = getTView();
76978  let pipeDef;
76979  const adjustedIndex = index + HEADER_OFFSET;
76980
76981  if (tView.firstCreatePass) {
76982    // The `getPipeDef` throws if a pipe with a given name is not found
76983    // (so we use non-null assertion below).
76984    pipeDef = getPipeDef(pipeName, tView.pipeRegistry);
76985    tView.data[adjustedIndex] = pipeDef;
76986
76987    if (pipeDef.onDestroy) {
76988      (tView.destroyHooks || (tView.destroyHooks = [])).push(adjustedIndex, pipeDef.onDestroy);
76989    }
76990  } else {
76991    pipeDef = tView.data[adjustedIndex];
76992  }
76993
76994  const pipeFactory = pipeDef.factory || (pipeDef.factory = getFactoryDef(pipeDef.type, true));
76995  const previousInjectImplementation = setInjectImplementation(ɵɵdirectiveInject);
76996
76997  try {
76998    // DI for pipes is supposed to behave like directives when placed on a component
76999    // host node, which means that we have to disable access to `viewProviders`.
77000    const previousIncludeViewProviders = setIncludeViewProviders(false);
77001    const pipeInstance = pipeFactory();
77002    setIncludeViewProviders(previousIncludeViewProviders);
77003    store(tView, getLView(), adjustedIndex, pipeInstance);
77004    return pipeInstance;
77005  } finally {
77006    // we have to restore the injector implementation in finally, just in case the creation of the
77007    // pipe throws an error.
77008    setInjectImplementation(previousInjectImplementation);
77009  }
77010}
77011/**
77012 * Searches the pipe registry for a pipe with the given name. If one is found,
77013 * returns the pipe. Otherwise, an error is thrown because the pipe cannot be resolved.
77014 *
77015 * @param name Name of pipe to resolve
77016 * @param registry Full list of available pipes
77017 * @returns Matching PipeDef
77018 */
77019
77020
77021function getPipeDef(name, registry) {
77022  if (registry) {
77023    for (let i = registry.length - 1; i >= 0; i--) {
77024      const pipeDef = registry[i];
77025
77026      if (name === pipeDef.name) {
77027        return pipeDef;
77028      }
77029    }
77030  }
77031
77032  if (ngDevMode) {
77033    throw new RuntimeError(-302
77034    /* RuntimeErrorCode.PIPE_NOT_FOUND */
77035    , getPipeNotFoundErrorMessage(name));
77036  }
77037}
77038/**
77039 * Generates a helpful error message for the user when a pipe is not found.
77040 *
77041 * @param name Name of the missing pipe
77042 * @returns The error message
77043 */
77044
77045
77046function getPipeNotFoundErrorMessage(name) {
77047  const lView = getLView();
77048  const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
77049  const context = declarationLView[CONTEXT];
77050  const hostIsStandalone = isHostComponentStandalone(lView);
77051  const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
77052  const verifyMessage = `Verify that it is ${hostIsStandalone ? 'included in the \'@Component.imports\' of this component' : 'declared or imported in this module'}`;
77053  const errorMessage = `The pipe '${name}' could not be found${componentInfoMessage}. ${verifyMessage}`;
77054  return errorMessage;
77055}
77056/**
77057 * Invokes a pipe with 1 arguments.
77058 *
77059 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
77060 * the pipe only when an input to the pipe changes.
77061 *
77062 * @param index Pipe index where the pipe was stored on creation.
77063 * @param slotOffset the offset in the reserved slot space
77064 * @param v1 1st argument to {@link PipeTransform#transform}.
77065 *
77066 * @codeGenApi
77067 */
77068
77069
77070function ɵɵpipeBind1(index, slotOffset, v1) {
77071  const adjustedIndex = index + HEADER_OFFSET;
77072  const lView = getLView();
77073  const pipeInstance = load(lView, adjustedIndex);
77074  return isPure(lView, adjustedIndex) ? pureFunction1Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, pipeInstance) : pipeInstance.transform(v1);
77075}
77076/**
77077 * Invokes a pipe with 2 arguments.
77078 *
77079 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
77080 * the pipe only when an input to the pipe changes.
77081 *
77082 * @param index Pipe index where the pipe was stored on creation.
77083 * @param slotOffset the offset in the reserved slot space
77084 * @param v1 1st argument to {@link PipeTransform#transform}.
77085 * @param v2 2nd argument to {@link PipeTransform#transform}.
77086 *
77087 * @codeGenApi
77088 */
77089
77090
77091function ɵɵpipeBind2(index, slotOffset, v1, v2) {
77092  const adjustedIndex = index + HEADER_OFFSET;
77093  const lView = getLView();
77094  const pipeInstance = load(lView, adjustedIndex);
77095  return isPure(lView, adjustedIndex) ? pureFunction2Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, pipeInstance) : pipeInstance.transform(v1, v2);
77096}
77097/**
77098 * Invokes a pipe with 3 arguments.
77099 *
77100 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
77101 * the pipe only when an input to the pipe changes.
77102 *
77103 * @param index Pipe index where the pipe was stored on creation.
77104 * @param slotOffset the offset in the reserved slot space
77105 * @param v1 1st argument to {@link PipeTransform#transform}.
77106 * @param v2 2nd argument to {@link PipeTransform#transform}.
77107 * @param v3 4rd argument to {@link PipeTransform#transform}.
77108 *
77109 * @codeGenApi
77110 */
77111
77112
77113function ɵɵpipeBind3(index, slotOffset, v1, v2, v3) {
77114  const adjustedIndex = index + HEADER_OFFSET;
77115  const lView = getLView();
77116  const pipeInstance = load(lView, adjustedIndex);
77117  return isPure(lView, adjustedIndex) ? pureFunction3Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, v3, pipeInstance) : pipeInstance.transform(v1, v2, v3);
77118}
77119/**
77120 * Invokes a pipe with 4 arguments.
77121 *
77122 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
77123 * the pipe only when an input to the pipe changes.
77124 *
77125 * @param index Pipe index where the pipe was stored on creation.
77126 * @param slotOffset the offset in the reserved slot space
77127 * @param v1 1st argument to {@link PipeTransform#transform}.
77128 * @param v2 2nd argument to {@link PipeTransform#transform}.
77129 * @param v3 3rd argument to {@link PipeTransform#transform}.
77130 * @param v4 4th argument to {@link PipeTransform#transform}.
77131 *
77132 * @codeGenApi
77133 */
77134
77135
77136function ɵɵpipeBind4(index, slotOffset, v1, v2, v3, v4) {
77137  const adjustedIndex = index + HEADER_OFFSET;
77138  const lView = getLView();
77139  const pipeInstance = load(lView, adjustedIndex);
77140  return isPure(lView, adjustedIndex) ? pureFunction4Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, v3, v4, pipeInstance) : pipeInstance.transform(v1, v2, v3, v4);
77141}
77142/**
77143 * Invokes a pipe with variable number of arguments.
77144 *
77145 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
77146 * the pipe only when an input to the pipe changes.
77147 *
77148 * @param index Pipe index where the pipe was stored on creation.
77149 * @param slotOffset the offset in the reserved slot space
77150 * @param values Array of arguments to pass to {@link PipeTransform#transform} method.
77151 *
77152 * @codeGenApi
77153 */
77154
77155
77156function ɵɵpipeBindV(index, slotOffset, values) {
77157  const adjustedIndex = index + HEADER_OFFSET;
77158  const lView = getLView();
77159  const pipeInstance = load(lView, adjustedIndex);
77160  return isPure(lView, adjustedIndex) ? pureFunctionVInternal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, values, pipeInstance) : pipeInstance.transform.apply(pipeInstance, values);
77161}
77162
77163function isPure(lView, index) {
77164  return lView[TVIEW].data[index].pure;
77165}
77166/**
77167 * @license
77168 * Copyright Google LLC All Rights Reserved.
77169 *
77170 * Use of this source code is governed by an MIT-style license that can be
77171 * found in the LICENSE file at https://angular.io/license
77172 */
77173
77174
77175class EventEmitter_ extends rxjs__WEBPACK_IMPORTED_MODULE_0__.Subject {
77176  constructor(isAsync = false) {
77177    super();
77178    this.__isAsync = isAsync;
77179  }
77180
77181  emit(value) {
77182    super.next(value);
77183  }
77184
77185  subscribe(observerOrNext, error, complete) {
77186    let nextFn = observerOrNext;
77187
77188    let errorFn = error || (() => null);
77189
77190    let completeFn = complete;
77191
77192    if (observerOrNext && typeof observerOrNext === 'object') {
77193      const observer = observerOrNext;
77194      nextFn = observer.next?.bind(observer);
77195      errorFn = observer.error?.bind(observer);
77196      completeFn = observer.complete?.bind(observer);
77197    }
77198
77199    if (this.__isAsync) {
77200      errorFn = _wrapInTimeout(errorFn);
77201
77202      if (nextFn) {
77203        nextFn = _wrapInTimeout(nextFn);
77204      }
77205
77206      if (completeFn) {
77207        completeFn = _wrapInTimeout(completeFn);
77208      }
77209    }
77210
77211    const sink = super.subscribe({
77212      next: nextFn,
77213      error: errorFn,
77214      complete: completeFn
77215    });
77216
77217    if (observerOrNext instanceof rxjs__WEBPACK_IMPORTED_MODULE_1__.Subscription) {
77218      observerOrNext.add(sink);
77219    }
77220
77221    return sink;
77222  }
77223
77224}
77225
77226function _wrapInTimeout(fn) {
77227  return value => {
77228    setTimeout(fn, undefined, value);
77229  };
77230}
77231/**
77232 * @publicApi
77233 */
77234
77235
77236const EventEmitter = EventEmitter_;
77237/**
77238 * @license
77239 * Copyright Google LLC All Rights Reserved.
77240 *
77241 * Use of this source code is governed by an MIT-style license that can be
77242 * found in the LICENSE file at https://angular.io/license
77243 */
77244
77245function symbolIterator() {
77246  return this._results[getSymbolIterator()]();
77247}
77248/**
77249 * An unmodifiable list of items that Angular keeps up to date when the state
77250 * of the application changes.
77251 *
77252 * The type of object that {@link ViewChildren}, {@link ContentChildren}, and {@link QueryList}
77253 * provide.
77254 *
77255 * Implements an iterable interface, therefore it can be used in both ES6
77256 * javascript `for (var i of items)` loops as well as in Angular templates with
77257 * `*ngFor="let i of myList"`.
77258 *
77259 * Changes can be observed by subscribing to the changes `Observable`.
77260 *
77261 * NOTE: In the future this class will implement an `Observable` interface.
77262 *
77263 * @usageNotes
77264 * ### Example
77265 * ```typescript
77266 * @Component({...})
77267 * class Container {
77268 *   @ViewChildren(Item) items:QueryList<Item>;
77269 * }
77270 * ```
77271 *
77272 * @publicApi
77273 */
77274
77275
77276class QueryList {
77277  /**
77278   * @param emitDistinctChangesOnly Whether `QueryList.changes` should fire only when actual change
77279   *     has occurred. Or if it should fire when query is recomputed. (recomputing could resolve in
77280   *     the same result)
77281   */
77282  constructor(_emitDistinctChangesOnly = false) {
77283    this._emitDistinctChangesOnly = _emitDistinctChangesOnly;
77284    this.dirty = true;
77285    this._results = [];
77286    this._changesDetected = false;
77287    this._changes = null;
77288    this.length = 0;
77289    this.first = undefined;
77290    this.last = undefined; // This function should be declared on the prototype, but doing so there will cause the class
77291    // declaration to have side-effects and become not tree-shakable. For this reason we do it in
77292    // the constructor.
77293    // [getSymbolIterator()](): Iterator<T> { ... }
77294
77295    const symbol = getSymbolIterator();
77296    const proto = QueryList.prototype;
77297    if (!proto[symbol]) proto[symbol] = symbolIterator;
77298  }
77299  /**
77300   * Returns `Observable` of `QueryList` notifying the subscriber of changes.
77301   */
77302
77303
77304  get changes() {
77305    return this._changes || (this._changes = new EventEmitter());
77306  }
77307  /**
77308   * Returns the QueryList entry at `index`.
77309   */
77310
77311
77312  get(index) {
77313    return this._results[index];
77314  }
77315  /**
77316   * See
77317   * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
77318   */
77319
77320
77321  map(fn) {
77322    return this._results.map(fn);
77323  }
77324  /**
77325   * See
77326   * [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
77327   */
77328
77329
77330  filter(fn) {
77331    return this._results.filter(fn);
77332  }
77333  /**
77334   * See
77335   * [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
77336   */
77337
77338
77339  find(fn) {
77340    return this._results.find(fn);
77341  }
77342  /**
77343   * See
77344   * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
77345   */
77346
77347
77348  reduce(fn, init) {
77349    return this._results.reduce(fn, init);
77350  }
77351  /**
77352   * See
77353   * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
77354   */
77355
77356
77357  forEach(fn) {
77358    this._results.forEach(fn);
77359  }
77360  /**
77361   * See
77362   * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
77363   */
77364
77365
77366  some(fn) {
77367    return this._results.some(fn);
77368  }
77369  /**
77370   * Returns a copy of the internal results list as an Array.
77371   */
77372
77373
77374  toArray() {
77375    return this._results.slice();
77376  }
77377
77378  toString() {
77379    return this._results.toString();
77380  }
77381  /**
77382   * Updates the stored data of the query list, and resets the `dirty` flag to `false`, so that
77383   * on change detection, it will not notify of changes to the queries, unless a new change
77384   * occurs.
77385   *
77386   * @param resultsTree The query results to store
77387   * @param identityAccessor Optional function for extracting stable object identity from a value
77388   *    in the array. This function is executed for each element of the query result list while
77389   *    comparing current query list with the new one (provided as a first argument of the `reset`
77390   *    function) to detect if the lists are different. If the function is not provided, elements
77391   *    are compared as is (without any pre-processing).
77392   */
77393
77394
77395  reset(resultsTree, identityAccessor) {
77396    // Cast to `QueryListInternal` so that we can mutate fields which are readonly for the usage of
77397    // QueryList (but not for QueryList itself.)
77398    const self = this;
77399    self.dirty = false;
77400    const newResultFlat = flatten(resultsTree);
77401
77402    if (this._changesDetected = !arrayEquals(self._results, newResultFlat, identityAccessor)) {
77403      self._results = newResultFlat;
77404      self.length = newResultFlat.length;
77405      self.last = newResultFlat[this.length - 1];
77406      self.first = newResultFlat[0];
77407    }
77408  }
77409  /**
77410   * Triggers a change event by emitting on the `changes` {@link EventEmitter}.
77411   */
77412
77413
77414  notifyOnChanges() {
77415    if (this._changes && (this._changesDetected || !this._emitDistinctChangesOnly)) this._changes.emit(this);
77416  }
77417  /** internal */
77418
77419
77420  setDirty() {
77421    this.dirty = true;
77422  }
77423  /** internal */
77424
77425
77426  destroy() {
77427    this.changes.complete();
77428    this.changes.unsubscribe();
77429  }
77430
77431}
77432
77433Symbol.iterator;
77434/**
77435 * @license
77436 * Copyright Google LLC All Rights Reserved.
77437 *
77438 * Use of this source code is governed by an MIT-style license that can be
77439 * found in the LICENSE file at https://angular.io/license
77440 */
77441
77442/**
77443 * Represents an embedded template that can be used to instantiate embedded views.
77444 * To instantiate embedded views based on a template, use the `ViewContainerRef`
77445 * method `createEmbeddedView()`.
77446 *
77447 * Access a `TemplateRef` instance by placing a directive on an `<ng-template>`
77448 * element (or directive prefixed with `*`). The `TemplateRef` for the embedded view
77449 * is injected into the constructor of the directive,
77450 * using the `TemplateRef` token.
77451 *
77452 * You can also use a `Query` to find a `TemplateRef` associated with
77453 * a component or a directive.
77454 *
77455 * @see `ViewContainerRef`
77456 * @see [Navigate the Component Tree with DI](guide/dependency-injection-navtree)
77457 *
77458 * @publicApi
77459 */
77460
77461class TemplateRef {}
77462/**
77463 * @internal
77464 * @nocollapse
77465 */
77466
77467
77468TemplateRef.__NG_ELEMENT_ID__ = injectTemplateRef;
77469const ViewEngineTemplateRef = TemplateRef; // TODO(alxhub): combine interface and implementation. Currently this is challenging since something
77470// in g3 depends on them being separate.
77471
77472const R3TemplateRef = class TemplateRef extends ViewEngineTemplateRef {
77473  constructor(_declarationLView, _declarationTContainer, elementRef) {
77474    super();
77475    this._declarationLView = _declarationLView;
77476    this._declarationTContainer = _declarationTContainer;
77477    this.elementRef = elementRef;
77478  }
77479
77480  createEmbeddedView(context, injector) {
77481    const embeddedTView = this._declarationTContainer.tViews;
77482    const embeddedLView = createLView(this._declarationLView, embeddedTView, context, 16
77483    /* LViewFlags.CheckAlways */
77484    , null, embeddedTView.declTNode, null, null, null, null, injector || null);
77485    const declarationLContainer = this._declarationLView[this._declarationTContainer.index];
77486    ngDevMode && assertLContainer(declarationLContainer);
77487    embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
77488    const declarationViewLQueries = this._declarationLView[QUERIES];
77489
77490    if (declarationViewLQueries !== null) {
77491      embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
77492    }
77493
77494    renderView(embeddedTView, embeddedLView, context);
77495    return new ViewRef$1(embeddedLView);
77496  }
77497
77498};
77499/**
vendor: 31,862 bytes, lines 77500-78446
77500 * Creates a TemplateRef given a node.
77501 *
77502 * @returns The TemplateRef instance to use
77503 */
77504
77505function injectTemplateRef() {
77506  return createTemplateRef(getCurrentTNode(), getLView());
77507}
77508/**
77509 * Creates a TemplateRef and stores it on the injector.
77510 *
77511 * @param hostTNode The node on which a TemplateRef is requested
77512 * @param hostLView The `LView` to which the node belongs
77513 * @returns The TemplateRef instance or null if we can't create a TemplateRef on a given node type
77514 */
77515
77516
77517function createTemplateRef(hostTNode, hostLView) {
77518  if (hostTNode.type & 4
77519  /* TNodeType.Container */
77520  ) {
77521    ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
77522    return new R3TemplateRef(hostLView, hostTNode, createElementRef(hostTNode, hostLView));
77523  }
77524
77525  return null;
77526}
77527/**
77528 * @license
77529 * Copyright Google LLC All Rights Reserved.
77530 *
77531 * Use of this source code is governed by an MIT-style license that can be
77532 * found in the LICENSE file at https://angular.io/license
77533 */
77534
77535/**
77536 * Represents a container where one or more views can be attached to a component.
77537 *
77538 * Can contain *host views* (created by instantiating a
77539 * component with the `createComponent()` method), and *embedded views*
77540 * (created by instantiating a `TemplateRef` with the `createEmbeddedView()` method).
77541 *
77542 * A view container instance can contain other view containers,
77543 * creating a [view hierarchy](guide/glossary#view-tree).
77544 *
77545 * @see `ComponentRef`
77546 * @see `EmbeddedViewRef`
77547 *
77548 * @publicApi
77549 */
77550
77551
77552class ViewContainerRef {}
77553/**
77554 * @internal
77555 * @nocollapse
77556 */
77557
77558
77559ViewContainerRef.__NG_ELEMENT_ID__ = injectViewContainerRef;
77560/**
77561 * Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
77562 * already exists, retrieves the existing ViewContainerRef.
77563 *
77564 * @returns The ViewContainerRef instance to use
77565 */
77566
77567function injectViewContainerRef() {
77568  const previousTNode = getCurrentTNode();
77569  return createContainerRef(previousTNode, getLView());
77570}
77571
77572const VE_ViewContainerRef = ViewContainerRef; // TODO(alxhub): cleaning up this indirection triggers a subtle bug in Closure in g3. Once the fix
77573// for that lands, this can be cleaned up.
77574
77575const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
77576  constructor(_lContainer, _hostTNode, _hostLView) {
77577    super();
77578    this._lContainer = _lContainer;
77579    this._hostTNode = _hostTNode;
77580    this._hostLView = _hostLView;
77581  }
77582
77583  get element() {
77584    return createElementRef(this._hostTNode, this._hostLView);
77585  }
77586
77587  get injector() {
77588    return new NodeInjector(this._hostTNode, this._hostLView);
77589  }
77590  /** @deprecated No replacement */
77591
77592
77593  get parentInjector() {
77594    const parentLocation = getParentInjectorLocation(this._hostTNode, this._hostLView);
77595
77596    if (hasParentInjector(parentLocation)) {
77597      const parentView = getParentInjectorView(parentLocation, this._hostLView);
77598      const injectorIndex = getParentInjectorIndex(parentLocation);
77599      ngDevMode && assertNodeInjector(parentView, injectorIndex);
77600      const parentTNode = parentView[TVIEW].data[injectorIndex + 8
77601      /* NodeInjectorOffset.TNODE */
77602      ];
77603      return new NodeInjector(parentTNode, parentView);
77604    } else {
77605      return new NodeInjector(null, this._hostLView);
77606    }
77607  }
77608
77609  clear() {
77610    while (this.length > 0) {
77611      this.remove(this.length - 1);
77612    }
77613  }
77614
77615  get(index) {
77616    const viewRefs = getViewRefs(this._lContainer);
77617    return viewRefs !== null && viewRefs[index] || null;
77618  }
77619
77620  get length() {
77621    return this._lContainer.length - CONTAINER_HEADER_OFFSET;
77622  }
77623
77624  createEmbeddedView(templateRef, context, indexOrOptions) {
77625    let index;
77626    let injector;
77627
77628    if (typeof indexOrOptions === 'number') {
77629      index = indexOrOptions;
77630    } else if (indexOrOptions != null) {
77631      index = indexOrOptions.index;
77632      injector = indexOrOptions.injector;
77633    }
77634
77635    const viewRef = templateRef.createEmbeddedView(context || {}, injector);
77636    this.insert(viewRef, index);
77637    return viewRef;
77638  }
77639
77640  createComponent(componentFactoryOrType, indexOrOptions, injector, projectableNodes, environmentInjector) {
77641    const isComponentFactory = componentFactoryOrType && !isType(componentFactoryOrType);
77642    let index; // This function supports 2 signatures and we need to handle options correctly for both:
77643    //   1. When first argument is a Component type. This signature also requires extra
77644    //      options to be provided as as object (more ergonomic option).
77645    //   2. First argument is a Component factory. In this case extra options are represented as
77646    //      positional arguments. This signature is less ergonomic and will be deprecated.
77647
77648    if (isComponentFactory) {
77649      if (ngDevMode) {
77650        assertEqual(typeof indexOrOptions !== 'object', true, 'It looks like Component factory was provided as the first argument ' + 'and an options object as the second argument. This combination of arguments ' + 'is incompatible. You can either change the first argument to provide Component ' + 'type or change the second argument to be a number (representing an index at ' + 'which to insert the new component\'s host view into this container)');
77651      }
77652
77653      index = indexOrOptions;
77654    } else {
77655      if (ngDevMode) {
77656        assertDefined(getComponentDef(componentFactoryOrType), `Provided Component class doesn't contain Component definition. ` + `Please check whether provided class has @Component decorator.`);
77657        assertEqual(typeof indexOrOptions !== 'number', true, 'It looks like Component type was provided as the first argument ' + 'and a number (representing an index at which to insert the new component\'s ' + 'host view into this container as the second argument. This combination of arguments ' + 'is incompatible. Please use an object as the second argument instead.');
77658      }
77659
77660      const options = indexOrOptions || {};
77661
77662      if (ngDevMode && options.environmentInjector && options.ngModuleRef) {
77663        throwError(`Cannot pass both environmentInjector and ngModuleRef options to createComponent().`);
77664      }
77665
77666      index = options.index;
77667      injector = options.injector;
77668      projectableNodes = options.projectableNodes;
77669      environmentInjector = options.environmentInjector || options.ngModuleRef;
77670    }
77671
77672    const componentFactory = isComponentFactory ? componentFactoryOrType : new ComponentFactory(getComponentDef(componentFactoryOrType));
77673    const contextInjector = injector || this.parentInjector; // If an `NgModuleRef` is not provided explicitly, try retrieving it from the DI tree.
77674
77675    if (!environmentInjector && componentFactory.ngModule == null) {
77676      // For the `ComponentFactory` case, entering this logic is very unlikely, since we expect that
77677      // an instance of a `ComponentFactory`, resolved via `ComponentFactoryResolver` would have an
77678      // `ngModule` field. This is possible in some test scenarios and potentially in some JIT-based
77679      // use-cases. For the `ComponentFactory` case we preserve backwards-compatibility and try
77680      // using a provided injector first, then fall back to the parent injector of this
77681      // `ViewContainerRef` instance.
77682      //
77683      // For the factory-less case, it's critical to establish a connection with the module
77684      // injector tree (by retrieving an instance of an `NgModuleRef` and accessing its injector),
77685      // so that a component can use DI tokens provided in MgModules. For this reason, we can not
77686      // rely on the provided injector, since it might be detached from the DI tree (for example, if
77687      // it was created via `Injector.create` without specifying a parent injector, or if an
77688      // injector is retrieved from an `NgModuleRef` created via `createNgModule` using an
77689      // NgModule outside of a module tree). Instead, we always use `ViewContainerRef`'s parent
77690      // injector, which is normally connected to the DI tree, which includes module injector
77691      // subtree.
77692      const _injector = isComponentFactory ? contextInjector : this.parentInjector; // DO NOT REFACTOR. The code here used to have a `injector.get(NgModuleRef, null) ||
77693      // undefined` expression which seems to cause internal google apps to fail. This is documented
77694      // in the following internal bug issue: go/b/142967802
77695
77696
77697      const result = _injector.get(EnvironmentInjector, null);
77698
77699      if (result) {
77700        environmentInjector = result;
77701      }
77702    }
77703
77704    const componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, environmentInjector);
77705    this.insert(componentRef.hostView, index);
77706    return componentRef;
77707  }
77708
77709  insert(viewRef, index) {
77710    const lView = viewRef._lView;
77711    const tView = lView[TVIEW];
77712
77713    if (ngDevMode && viewRef.destroyed) {
77714      throw new Error('Cannot insert a destroyed View in a ViewContainer!');
77715    }
77716
77717    if (viewAttachedToContainer(lView)) {
77718      // If view is already attached, detach it first so we clean up references appropriately.
77719      const prevIdx = this.indexOf(viewRef); // A view might be attached either to this or a different container. The `prevIdx` for
77720      // those cases will be:
77721      // equal to -1 for views attached to this ViewContainerRef
77722      // >= 0 for views attached to a different ViewContainerRef
77723
77724      if (prevIdx !== -1) {
77725        this.detach(prevIdx);
77726      } else {
77727        const prevLContainer = lView[PARENT];
77728        ngDevMode && assertEqual(isLContainer(prevLContainer), true, 'An attached view should have its PARENT point to a container.'); // We need to re-create a R3ViewContainerRef instance since those are not stored on
77729        // LView (nor anywhere else).
77730
77731        const prevVCRef = new R3ViewContainerRef(prevLContainer, prevLContainer[T_HOST], prevLContainer[PARENT]);
77732        prevVCRef.detach(prevVCRef.indexOf(viewRef));
77733      }
77734    } // Logical operation of adding `LView` to `LContainer`
77735
77736
77737    const adjustedIdx = this._adjustIndex(index);
77738
77739    const lContainer = this._lContainer;
77740    insertView(tView, lView, lContainer, adjustedIdx); // Physical operation of adding the DOM nodes.
77741
77742    const beforeNode = getBeforeNodeForView(adjustedIdx, lContainer);
77743    const renderer = lView[RENDERER];
77744    const parentRNode = nativeParentNode(renderer, lContainer[NATIVE]);
77745
77746    if (parentRNode !== null) {
77747      addViewToContainer(tView, lContainer[T_HOST], renderer, lView, parentRNode, beforeNode);
77748    }
77749
77750    viewRef.attachToViewContainerRef();
77751    addToArray(getOrCreateViewRefs(lContainer), adjustedIdx, viewRef);
77752    return viewRef;
77753  }
77754
77755  move(viewRef, newIndex) {
77756    if (ngDevMode && viewRef.destroyed) {
77757      throw new Error('Cannot move a destroyed View in a ViewContainer!');
77758    }
77759
77760    return this.insert(viewRef, newIndex);
77761  }
77762
77763  indexOf(viewRef) {
77764    const viewRefsArr = getViewRefs(this._lContainer);
77765    return viewRefsArr !== null ? viewRefsArr.indexOf(viewRef) : -1;
77766  }
77767
77768  remove(index) {
77769    const adjustedIdx = this._adjustIndex(index, -1);
77770
77771    const detachedView = detachView(this._lContainer, adjustedIdx);
77772
77773    if (detachedView) {
77774      // Before destroying the view, remove it from the container's array of `ViewRef`s.
77775      // This ensures the view container length is updated before calling
77776      // `destroyLView`, which could recursively call view container methods that
77777      // rely on an accurate container length.
77778      // (e.g. a method on this view container being called by a child directive's OnDestroy
77779      // lifecycle hook)
77780      removeFromArray(getOrCreateViewRefs(this._lContainer), adjustedIdx);
77781      destroyLView(detachedView[TVIEW], detachedView);
77782    }
77783  }
77784
77785  detach(index) {
77786    const adjustedIdx = this._adjustIndex(index, -1);
77787
77788    const view = detachView(this._lContainer, adjustedIdx);
77789    const wasDetached = view && removeFromArray(getOrCreateViewRefs(this._lContainer), adjustedIdx) != null;
77790    return wasDetached ? new ViewRef$1(view) : null;
77791  }
77792
77793  _adjustIndex(index, shift = 0) {
77794    if (index == null) {
77795      return this.length + shift;
77796    }
77797
77798    if (ngDevMode) {
77799      assertGreaterThan(index, -1, `ViewRef index must be positive, got ${index}`); // +1 because it's legal to insert at the end.
77800
77801      assertLessThan(index, this.length + 1 + shift, 'index');
77802    }
77803
77804    return index;
77805  }
77806
77807};
77808
77809function getViewRefs(lContainer) {
77810  return lContainer[VIEW_REFS];
77811}
77812
77813function getOrCreateViewRefs(lContainer) {
77814  return lContainer[VIEW_REFS] || (lContainer[VIEW_REFS] = []);
77815}
77816/**
77817 * Creates a ViewContainerRef and stores it on the injector.
77818 *
77819 * @param ViewContainerRefToken The ViewContainerRef type
77820 * @param ElementRefToken The ElementRef type
77821 * @param hostTNode The node that is requesting a ViewContainerRef
77822 * @param hostLView The view to which the node belongs
77823 * @returns The ViewContainerRef instance to use
77824 */
77825
77826
77827function createContainerRef(hostTNode, hostLView) {
77828  ngDevMode && assertTNodeType(hostTNode, 12
77829  /* TNodeType.AnyContainer */
77830  | 3
77831  /* TNodeType.AnyRNode */
77832  );
77833  let lContainer;
77834  const slotValue = hostLView[hostTNode.index];
77835
77836  if (isLContainer(slotValue)) {
77837    // If the host is a container, we don't need to create a new LContainer
77838    lContainer = slotValue;
77839  } else {
77840    let commentNode; // If the host is an element container, the native host element is guaranteed to be a
77841    // comment and we can reuse that comment as anchor element for the new LContainer.
77842    // The comment node in question is already part of the DOM structure so we don't need to append
77843    // it again.
77844
77845    if (hostTNode.type & 8
77846    /* TNodeType.ElementContainer */
77847    ) {
77848      commentNode = unwrapRNode(slotValue);
77849    } else {
77850      // If the host is a regular element, we have to insert a comment node manually which will
77851      // be used as an anchor when inserting elements. In this specific case we use low-level DOM
77852      // manipulation to insert it.
77853      const renderer = hostLView[RENDERER];
77854      ngDevMode && ngDevMode.rendererCreateComment++;
77855      commentNode = renderer.createComment(ngDevMode ? 'container' : '');
77856      const hostNative = getNativeByTNode(hostTNode, hostLView);
77857      const parentOfHostNative = nativeParentNode(renderer, hostNative);
77858      nativeInsertBefore(renderer, parentOfHostNative, commentNode, nativeNextSibling(renderer, hostNative), false);
77859    }
77860
77861    hostLView[hostTNode.index] = lContainer = createLContainer(slotValue, hostLView, commentNode, hostTNode);
77862    addToViewTree(hostLView, lContainer);
77863  }
77864
77865  return new R3ViewContainerRef(lContainer, hostTNode, hostLView);
77866}
77867/**
77868 * @license
77869 * Copyright Google LLC All Rights Reserved.
77870 *
77871 * Use of this source code is governed by an MIT-style license that can be
77872 * found in the LICENSE file at https://angular.io/license
77873 */
77874// Note: This hack is necessary so we don't erroneously get a circular dependency
77875// failure based on types.
77876
77877
77878const unusedValueExportToPlacateAjd$1 = 1;
77879/**
77880 * @license
77881 * Copyright Google LLC All Rights Reserved.
77882 *
77883 * Use of this source code is governed by an MIT-style license that can be
77884 * found in the LICENSE file at https://angular.io/license
77885 */
77886// Note: This hack is necessary so we don't erroneously get a circular dependency
77887// failure based on types.
77888
77889const unusedValueExportToPlacateAjd = 1;
77890/**
77891 * @license
77892 * Copyright Google LLC All Rights Reserved.
77893 *
77894 * Use of this source code is governed by an MIT-style license that can be
77895 * found in the LICENSE file at https://angular.io/license
77896 */
77897
77898const unusedValueToPlacateAjd = unusedValueExportToPlacateAjd$1 + unusedValueExportToPlacateAjd$6 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd;
77899
77900class LQuery_ {
77901  constructor(queryList) {
77902    this.queryList = queryList;
77903    this.matches = null;
77904  }
77905
77906  clone() {
77907    return new LQuery_(this.queryList);
77908  }
77909
77910  setDirty() {
77911    this.queryList.setDirty();
77912  }
77913
77914}
77915
77916class LQueries_ {
77917  constructor(queries = []) {
77918    this.queries = queries;
77919  }
77920
77921  createEmbeddedView(tView) {
77922    const tQueries = tView.queries;
77923
77924    if (tQueries !== null) {
77925      const noOfInheritedQueries = tView.contentQueries !== null ? tView.contentQueries[0] : tQueries.length;
77926      const viewLQueries = []; // An embedded view has queries propagated from a declaration view at the beginning of the
77927      // TQueries collection and up until a first content query declared in the embedded view. Only
77928      // propagated LQueries are created at this point (LQuery corresponding to declared content
77929      // queries will be instantiated from the content query instructions for each directive).
77930
77931      for (let i = 0; i < noOfInheritedQueries; i++) {
77932        const tQuery = tQueries.getByIndex(i);
77933        const parentLQuery = this.queries[tQuery.indexInDeclarationView];
77934        viewLQueries.push(parentLQuery.clone());
77935      }
77936
77937      return new LQueries_(viewLQueries);
77938    }
77939
77940    return null;
77941  }
77942
77943  insertView(tView) {
77944    this.dirtyQueriesWithMatches(tView);
77945  }
77946
77947  detachView(tView) {
77948    this.dirtyQueriesWithMatches(tView);
77949  }
77950
77951  dirtyQueriesWithMatches(tView) {
77952    for (let i = 0; i < this.queries.length; i++) {
77953      if (getTQuery(tView, i).matches !== null) {
77954        this.queries[i].setDirty();
77955      }
77956    }
77957  }
77958
77959}
77960
77961class TQueryMetadata_ {
77962  constructor(predicate, flags, read = null) {
77963    this.predicate = predicate;
77964    this.flags = flags;
77965    this.read = read;
77966  }
77967
77968}
77969
77970class TQueries_ {
77971  constructor(queries = []) {
77972    this.queries = queries;
77973  }
77974
77975  elementStart(tView, tNode) {
77976    ngDevMode && assertFirstCreatePass(tView, 'Queries should collect results on the first template pass only');
77977
77978    for (let i = 0; i < this.queries.length; i++) {
77979      this.queries[i].elementStart(tView, tNode);
77980    }
77981  }
77982
77983  elementEnd(tNode) {
77984    for (let i = 0; i < this.queries.length; i++) {
77985      this.queries[i].elementEnd(tNode);
77986    }
77987  }
77988
77989  embeddedTView(tNode) {
77990    let queriesForTemplateRef = null;
77991
77992    for (let i = 0; i < this.length; i++) {
77993      const childQueryIndex = queriesForTemplateRef !== null ? queriesForTemplateRef.length : 0;
77994      const tqueryClone = this.getByIndex(i).embeddedTView(tNode, childQueryIndex);
77995
77996      if (tqueryClone) {
77997        tqueryClone.indexInDeclarationView = i;
77998
77999        if (queriesForTemplateRef !== null) {
78000          queriesForTemplateRef.push(tqueryClone);
78001        } else {
78002          queriesForTemplateRef = [tqueryClone];
78003        }
78004      }
78005    }
78006
78007    return queriesForTemplateRef !== null ? new TQueries_(queriesForTemplateRef) : null;
78008  }
78009
78010  template(tView, tNode) {
78011    ngDevMode && assertFirstCreatePass(tView, 'Queries should collect results on the first template pass only');
78012
78013    for (let i = 0; i < this.queries.length; i++) {
78014      this.queries[i].template(tView, tNode);
78015    }
78016  }
78017
78018  getByIndex(index) {
78019    ngDevMode && assertIndexInRange(this.queries, index);
78020    return this.queries[index];
78021  }
78022
78023  get length() {
78024    return this.queries.length;
78025  }
78026
78027  track(tquery) {
78028    this.queries.push(tquery);
78029  }
78030
78031}
78032
78033class TQuery_ {
78034  constructor(metadata, nodeIndex = -1) {
78035    this.metadata = metadata;
78036    this.matches = null;
78037    this.indexInDeclarationView = -1;
78038    this.crossesNgTemplate = false;
78039    /**
78040     * A flag indicating if a given query still applies to nodes it is crossing. We use this flag
78041     * (alongside with _declarationNodeIndex) to know when to stop applying content queries to
78042     * elements in a template.
78043     */
78044
78045    this._appliesToNextNode = true;
78046    this._declarationNodeIndex = nodeIndex;
78047  }
78048
78049  elementStart(tView, tNode) {
78050    if (this.isApplyingToNode(tNode)) {
78051      this.matchTNode(tView, tNode);
78052    }
78053  }
78054
78055  elementEnd(tNode) {
78056    if (this._declarationNodeIndex === tNode.index) {
78057      this._appliesToNextNode = false;
78058    }
78059  }
78060
78061  template(tView, tNode) {
78062    this.elementStart(tView, tNode);
78063  }
78064
78065  embeddedTView(tNode, childQueryIndex) {
78066    if (this.isApplyingToNode(tNode)) {
78067      this.crossesNgTemplate = true; // A marker indicating a `<ng-template>` element (a placeholder for query results from
78068      // embedded views created based on this `<ng-template>`).
78069
78070      this.addMatch(-tNode.index, childQueryIndex);
78071      return new TQuery_(this.metadata);
78072    }
78073
78074    return null;
78075  }
78076
78077  isApplyingToNode(tNode) {
78078    if (this._appliesToNextNode && (this.metadata.flags & 1
78079    /* QueryFlags.descendants */
78080    ) !== 1
78081    /* QueryFlags.descendants */
78082    ) {
78083      const declarationNodeIdx = this._declarationNodeIndex;
78084      let parent = tNode.parent; // Determine if a given TNode is a "direct" child of a node on which a content query was
78085      // declared (only direct children of query's host node can match with the descendants: false
78086      // option). There are 3 main use-case / conditions to consider here:
78087      // - <needs-target><i #target></i></needs-target>: here <i #target> parent node is a query
78088      // host node;
78089      // - <needs-target><ng-template [ngIf]="true"><i #target></i></ng-template></needs-target>:
78090      // here <i #target> parent node is null;
78091      // - <needs-target><ng-container><i #target></i></ng-container></needs-target>: here we need
78092      // to go past `<ng-container>` to determine <i #target> parent node (but we shouldn't traverse
78093      // up past the query's host node!).
78094
78095      while (parent !== null && parent.type & 8
78096      /* TNodeType.ElementContainer */
78097      && parent.index !== declarationNodeIdx) {
78098        parent = parent.parent;
78099      }
78100
78101      return declarationNodeIdx === (parent !== null ? parent.index : -1);
78102    }
78103
78104    return this._appliesToNextNode;
78105  }
78106
78107  matchTNode(tView, tNode) {
78108    const predicate = this.metadata.predicate;
78109
78110    if (Array.isArray(predicate)) {
78111      for (let i = 0; i < predicate.length; i++) {
78112        const name = predicate[i];
78113        this.matchTNodeWithReadOption(tView, tNode, getIdxOfMatchingSelector(tNode, name)); // Also try matching the name to a provider since strings can be used as DI tokens too.
78114
78115        this.matchTNodeWithReadOption(tView, tNode, locateDirectiveOrProvider(tNode, tView, name, false, false));
78116      }
78117    } else {
78118      if (predicate === TemplateRef) {
78119        if (tNode.type & 4
78120        /* TNodeType.Container */
78121        ) {
78122          this.matchTNodeWithReadOption(tView, tNode, -1);
78123        }
78124      } else {
78125        this.matchTNodeWithReadOption(tView, tNode, locateDirectiveOrProvider(tNode, tView, predicate, false, false));
78126      }
78127    }
78128  }
78129
78130  matchTNodeWithReadOption(tView, tNode, nodeMatchIdx) {
78131    if (nodeMatchIdx !== null) {
78132      const read = this.metadata.read;
78133
78134      if (read !== null) {
78135        if (read === ElementRef || read === ViewContainerRef || read === TemplateRef && tNode.type & 4
78136        /* TNodeType.Container */
78137        ) {
78138          this.addMatch(tNode.index, -2);
78139        } else {
78140          const directiveOrProviderIdx = locateDirectiveOrProvider(tNode, tView, read, false, false);
78141
78142          if (directiveOrProviderIdx !== null) {
78143            this.addMatch(tNode.index, directiveOrProviderIdx);
78144          }
78145        }
78146      } else {
78147        this.addMatch(tNode.index, nodeMatchIdx);
78148      }
78149    }
78150  }
78151
78152  addMatch(tNodeIdx, matchIdx) {
78153    if (this.matches === null) {
78154      this.matches = [tNodeIdx, matchIdx];
78155    } else {
78156      this.matches.push(tNodeIdx, matchIdx);
78157    }
78158  }
78159
78160}
78161/**
78162 * Iterates over local names for a given node and returns directive index
78163 * (or -1 if a local name points to an element).
78164 *
78165 * @param tNode static data of a node to check
78166 * @param selector selector to match
78167 * @returns directive index, -1 or null if a selector didn't match any of the local names
78168 */
78169
78170
78171function getIdxOfMatchingSelector(tNode, selector) {
78172  const localNames = tNode.localNames;
78173
78174  if (localNames !== null) {
78175    for (let i = 0; i < localNames.length; i += 2) {
78176      if (localNames[i] === selector) {
78177        return localNames[i + 1];
78178      }
78179    }
78180  }
78181
78182  return null;
78183}
78184
78185function createResultByTNodeType(tNode, currentView) {
78186  if (tNode.type & (3
78187  /* TNodeType.AnyRNode */
78188  | 8
78189  /* TNodeType.ElementContainer */
78190  )) {
78191    return createElementRef(tNode, currentView);
78192  } else if (tNode.type & 4
78193  /* TNodeType.Container */
78194  ) {
78195    return createTemplateRef(tNode, currentView);
78196  }
78197
78198  return null;
78199}
78200
78201function createResultForNode(lView, tNode, matchingIdx, read) {
78202  if (matchingIdx === -1) {
78203    // if read token and / or strategy is not specified, detect it using appropriate tNode type
78204    return createResultByTNodeType(tNode, lView);
78205  } else if (matchingIdx === -2) {
78206    // read a special token from a node injector
78207    return createSpecialToken(lView, tNode, read);
78208  } else {
78209    // read a token
78210    return getNodeInjectable(lView, lView[TVIEW], matchingIdx, tNode);
78211  }
78212}
78213
78214function createSpecialToken(lView, tNode, read) {
78215  if (read === ElementRef) {
78216    return createElementRef(tNode, lView);
78217  } else if (read === TemplateRef) {
78218    return createTemplateRef(tNode, lView);
78219  } else if (read === ViewContainerRef) {
78220    ngDevMode && assertTNodeType(tNode, 3
78221    /* TNodeType.AnyRNode */
78222    | 12
78223    /* TNodeType.AnyContainer */
78224    );
78225    return createContainerRef(tNode, lView);
78226  } else {
78227    ngDevMode && throwError(`Special token to read should be one of ElementRef, TemplateRef or ViewContainerRef but got ${stringify(read)}.`);
78228  }
78229}
78230/**
78231 * A helper function that creates query results for a given view. This function is meant to do the
78232 * processing once and only once for a given view instance (a set of results for a given view
78233 * doesn't change).
78234 */
78235
78236
78237function materializeViewResults(tView, lView, tQuery, queryIndex) {
78238  const lQuery = lView[QUERIES].queries[queryIndex];
78239
78240  if (lQuery.matches === null) {
78241    const tViewData = tView.data;
78242    const tQueryMatches = tQuery.matches;
78243    const result = [];
78244
78245    for (let i = 0; i < tQueryMatches.length; i += 2) {
78246      const matchedNodeIdx = tQueryMatches[i];
78247
78248      if (matchedNodeIdx < 0) {
78249        // we at the <ng-template> marker which might have results in views created based on this
78250        // <ng-template> - those results will be in separate views though, so here we just leave
78251        // null as a placeholder
78252        result.push(null);
78253      } else {
78254        ngDevMode && assertIndexInRange(tViewData, matchedNodeIdx);
78255        const tNode = tViewData[matchedNodeIdx];
78256        result.push(createResultForNode(lView, tNode, tQueryMatches[i + 1], tQuery.metadata.read));
78257      }
78258    }
78259
78260    lQuery.matches = result;
78261  }
78262
78263  return lQuery.matches;
78264}
78265/**
78266 * A helper function that collects (already materialized) query results from a tree of views,
78267 * starting with a provided LView.
78268 */
78269
78270
78271function collectQueryResults(tView, lView, queryIndex, result) {
78272  const tQuery = tView.queries.getByIndex(queryIndex);
78273  const tQueryMatches = tQuery.matches;
78274
78275  if (tQueryMatches !== null) {
78276    const lViewResults = materializeViewResults(tView, lView, tQuery, queryIndex);
78277
78278    for (let i = 0; i < tQueryMatches.length; i += 2) {
78279      const tNodeIdx = tQueryMatches[i];
78280
78281      if (tNodeIdx > 0) {
78282        result.push(lViewResults[i / 2]);
78283      } else {
78284        const childQueryIndex = tQueryMatches[i + 1];
78285        const declarationLContainer = lView[-tNodeIdx];
78286        ngDevMode && assertLContainer(declarationLContainer); // collect matches for views inserted in this container
78287
78288        for (let i = CONTAINER_HEADER_OFFSET; i < declarationLContainer.length; i++) {
78289          const embeddedLView = declarationLContainer[i];
78290
78291          if (embeddedLView[DECLARATION_LCONTAINER] === embeddedLView[PARENT]) {
78292            collectQueryResults(embeddedLView[TVIEW], embeddedLView, childQueryIndex, result);
78293          }
78294        } // collect matches for views created from this declaration container and inserted into
78295        // different containers
78296
78297
78298        if (declarationLContainer[MOVED_VIEWS] !== null) {
78299          const embeddedLViews = declarationLContainer[MOVED_VIEWS];
78300
78301          for (let i = 0; i < embeddedLViews.length; i++) {
78302            const embeddedLView = embeddedLViews[i];
78303            collectQueryResults(embeddedLView[TVIEW], embeddedLView, childQueryIndex, result);
78304          }
78305        }
78306      }
78307    }
78308  }
78309
78310  return result;
78311}
78312/**
78313 * Refreshes a query by combining matches from all active views and removing matches from deleted
78314 * views.
78315 *
78316 * @returns `true` if a query got dirty during change detection or if this is a static query
78317 * resolving in creation mode, `false` otherwise.
78318 *
78319 * @codeGenApi
78320 */
78321
78322
78323function ɵɵqueryRefresh(queryList) {
78324  const lView = getLView();
78325  const tView = getTView();
78326  const queryIndex = getCurrentQueryIndex();
78327  setCurrentQueryIndex(queryIndex + 1);
78328  const tQuery = getTQuery(tView, queryIndex);
78329
78330  if (queryList.dirty && isCreationMode(lView) === ((tQuery.metadata.flags & 2
78331  /* QueryFlags.isStatic */
78332  ) === 2
78333  /* QueryFlags.isStatic */
78334  )) {
78335    if (tQuery.matches === null) {
78336      queryList.reset([]);
78337    } else {
78338      const result = tQuery.crossesNgTemplate ? collectQueryResults(tView, lView, queryIndex, []) : materializeViewResults(tView, lView, tQuery, queryIndex);
78339      queryList.reset(result, unwrapElementRef);
78340      queryList.notifyOnChanges();
78341    }
78342
78343    return true;
78344  }
78345
78346  return false;
78347}
78348/**
78349 * Creates new QueryList, stores the reference in LView and returns QueryList.
78350 *
78351 * @param predicate The type for which the query will search
78352 * @param flags Flags associated with the query
78353 * @param read What to save in the query
78354 *
78355 * @codeGenApi
78356 */
78357
78358
78359function ɵɵviewQuery(predicate, flags, read) {
78360  ngDevMode && assertNumber(flags, 'Expecting flags');
78361  const tView = getTView();
78362
78363  if (tView.firstCreatePass) {
78364    createTQuery(tView, new TQueryMetadata_(predicate, flags, read), -1);
78365
78366    if ((flags & 2
78367    /* QueryFlags.isStatic */
78368    ) === 2
78369    /* QueryFlags.isStatic */
78370    ) {
78371      tView.staticViewQueries = true;
78372    }
78373  }
78374
78375  createLQuery(tView, getLView(), flags);
78376}
78377/**
78378 * Registers a QueryList, associated with a content query, for later refresh (part of a view
78379 * refresh).
78380 *
78381 * @param directiveIndex Current directive index
78382 * @param predicate The type for which the query will search
78383 * @param flags Flags associated with the query
78384 * @param read What to save in the query
78385 * @returns QueryList<T>
78386 *
78387 * @codeGenApi
78388 */
78389
78390
78391function ɵɵcontentQuery(directiveIndex, predicate, flags, read) {
78392  ngDevMode && assertNumber(flags, 'Expecting flags');
78393  const tView = getTView();
78394
78395  if (tView.firstCreatePass) {
78396    const tNode = getCurrentTNode();
78397    createTQuery(tView, new TQueryMetadata_(predicate, flags, read), tNode.index);
78398    saveContentQueryAndDirectiveIndex(tView, directiveIndex);
78399
78400    if ((flags & 2
78401    /* QueryFlags.isStatic */
78402    ) === 2
78403    /* QueryFlags.isStatic */
78404    ) {
78405      tView.staticContentQueries = true;
78406    }
78407  }
78408
78409  createLQuery(tView, getLView(), flags);
78410}
78411/**
78412 * Loads a QueryList corresponding to the current view or content query.
78413 *
78414 * @codeGenApi
78415 */
78416
78417
78418function ɵɵloadQuery() {
78419  return loadQueryInternal(getLView(), getCurrentQueryIndex());
78420}
78421
78422function loadQueryInternal(lView, queryIndex) {
78423  ngDevMode && assertDefined(lView[QUERIES], 'LQueries should be defined when trying to load a query');
78424  ngDevMode && assertIndexInRange(lView[QUERIES].queries, queryIndex);
78425  return lView[QUERIES].queries[queryIndex].queryList;
78426}
78427
78428function createLQuery(tView, lView, flags) {
78429  const queryList = new QueryList((flags & 4
78430  /* QueryFlags.emitDistinctChangesOnly */
78431  ) === 4
78432  /* QueryFlags.emitDistinctChangesOnly */
78433  );
78434  storeCleanupWithContext(tView, lView, queryList, queryList.destroy);
78435  if (lView[QUERIES] === null) lView[QUERIES] = new LQueries_();
78436  lView[QUERIES].queries.push(new LQuery_(queryList));
78437}
78438
78439function createTQuery(tView, metadata, nodeIndex) {
78440  if (tView.queries === null) tView.queries = new TQueries_();
78441  tView.queries.track(new TQuery_(metadata, nodeIndex));
78442}
78443
78444function saveContentQueryAndDirectiveIndex(tView, directiveIndex) {
78445  const tViewContentQueries = tView.contentQueries || (tView.contentQueries = []);
78446  const lastSavedDirectiveIndex = tViewContentQueries.length ? tViewContentQueries[tViewContentQueries.length - 1] : 
78446-1;
78447
78448  if (directiveIndex !== lastSavedDirectiveIndex) {
78449    tViewContentQueries.push(tView.queries.length - 1, directiveIndex);
78450  }
78451}
78452
78453function getTQuery(tView, index) {
78454  ngDevMode && assertDefined(tView.queries, 'TQueries must be defined to retrieve a TQuery');
78455  return tView.queries.getByIndex(index);
78456}
78457/**
78458 * @license
78459 * Copyright Google LLC All Rights Reserved.
78460 *
78461 * Use of this source code is governed by an MIT-style license that can be
78462 * found in the LICENSE file at https://angular.io/license
78463 */
78464
78465/**
78466 * Retrieves `TemplateRef` instance from `Injector` when a local reference is placed on the
78467 * `<ng-template>` element.
78468 *
78469 * @codeGenApi
78470 */
78471
78472
78473function ɵɵtemplateRefExtractor(tNode, lView) {
78474  return createTemplateRef(tNode, lView);
78475}
78476/**
78477 * @license
78478 * Copyright Google LLC All Rights Reserved.
78479 *
78480 * Use of this source code is governed by an MIT-style license that can be
78481 * found in the LICENSE file at https://angular.io/license
78482 */
78483
78484/**
78485 * @license
78486 * Copyright Google LLC All Rights Reserved.
78487 *
78488 * Use of this source code is governed by an MIT-style license that can be
78489 * found in the LICENSE file at https://angular.io/license
78490 */
78491
78492/**
78493 * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
78494 *
78495 * This should be kept up to date with the public exports of @angular/core.
78496 */
78497
78498
78499const angularCoreEnv = (() => ({
78500  'ɵɵattribute': ɵɵattribute,
78501  'ɵɵattributeInterpolate1': ɵɵattributeInterpolate1,
78502  'ɵɵattributeInterpolate2': ɵɵattributeInterpolate2,
78503  'ɵɵattributeInterpolate3': ɵɵattributeInterpolate3,
78504  'ɵɵattributeInterpolate4': ɵɵattributeInterpolate4,
78505  'ɵɵattributeInterpolate5': ɵɵattributeInterpolate5,
78506  'ɵɵattributeInterpolate6': ɵɵattributeInterpolate6,
78507  'ɵɵattributeInterpolate7': ɵɵattributeInterpolate7,
78508  'ɵɵattributeInterpolate8': ɵɵattributeInterpolate8,
78509  'ɵɵattributeInterpolateV': ɵɵattributeInterpolateV,
78510  'ɵɵdefineComponent': ɵɵdefineComponent,
78511  'ɵɵdefineDirective': ɵɵdefineDirective,
78512  'ɵɵdefineInjectable': ɵɵdefineInjectable,
78513  'ɵɵdefineInjector': ɵɵdefineInjector,
78514  'ɵɵdefineNgModule': ɵɵdefineNgModule,
78515  'ɵɵdefinePipe': ɵɵdefinePipe,
78516  'ɵɵdirectiveInject': ɵɵdirectiveInject,
78517  'ɵɵgetInheritedFactory': ɵɵgetInheritedFactory,
78518  'ɵɵinject': ɵɵinject,
78519  'ɵɵinjectAttribute': ɵɵinjectAttribute,
78520  'ɵɵinvalidFactory': ɵɵinvalidFactory,
78521  'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
78522  'ɵɵtemplateRefExtractor': ɵɵtemplateRefExtractor,
78523  'ɵɵresetView': ɵɵresetView,
78524  'ɵɵNgOnChangesFeature': ɵɵNgOnChangesFeature,
78525  'ɵɵProvidersFeature': ɵɵProvidersFeature,
78526  'ɵɵCopyDefinitionFeature': ɵɵCopyDefinitionFeature,
78527  'ɵɵInheritDefinitionFeature': ɵɵInheritDefinitionFeature,
78528  'ɵɵStandaloneFeature': ɵɵStandaloneFeature,
78529  'ɵɵnextContext': ɵɵnextContext,
78530  'ɵɵnamespaceHTML': ɵɵnamespaceHTML,
78531  'ɵɵnamespaceMathML': ɵɵnamespaceMathML,
78532  'ɵɵnamespaceSVG': ɵɵnamespaceSVG,
78533  'ɵɵenableBindings': ɵɵenableBindings,
78534  'ɵɵdisableBindings': ɵɵdisableBindings,
78535  'ɵɵelementStart': ɵɵelementStart,
78536  'ɵɵelementEnd': ɵɵelementEnd,
78537  'ɵɵelement': ɵɵelement,
78538  'ɵɵelementContainerStart': ɵɵelementContainerStart,
78539  'ɵɵelementContainerEnd': ɵɵelementContainerEnd,
78540  'ɵɵelementContainer': ɵɵelementContainer,
78541  'ɵɵpureFunction0': ɵɵpureFunction0,
78542  'ɵɵpureFunction1': ɵɵpureFunction1,
78543  'ɵɵpureFunction2': ɵɵpureFunction2,
78544  'ɵɵpureFunction3': ɵɵpureFunction3,
78545  'ɵɵpureFunction4': ɵɵpureFunction4,
78546  'ɵɵpureFunction5': ɵɵpureFunction5,
78547  'ɵɵpureFunction6': ɵɵpureFunction6,
78548  'ɵɵpureFunction7': ɵɵpureFunction7,
78549  'ɵɵpureFunction8': ɵɵpureFunction8,
78550  'ɵɵpureFunctionV': ɵɵpureFunctionV,
78551  'ɵɵgetCurrentView': ɵɵgetCurrentView,
78552  'ɵɵrestoreView': ɵɵrestoreView,
78553  'ɵɵlistener': ɵɵlistener,
78554  'ɵɵprojection': ɵɵprojection,
78555  'ɵɵsyntheticHostProperty': ɵɵsyntheticHostProperty,
78556  'ɵɵsyntheticHostListener': ɵɵsyntheticHostListener,
78557  'ɵɵpipeBind1': ɵɵpipeBind1,
78558  'ɵɵpipeBind2': ɵɵpipeBind2,
78559  'ɵɵpipeBind3': ɵɵpipeBind3,
78560  'ɵɵpipeBind4': ɵɵpipeBind4,
78561  'ɵɵpipeBindV': ɵɵpipeBindV,
78562  'ɵɵprojectionDef': ɵɵprojectionDef,
78563  'ɵɵhostProperty': ɵɵhostProperty,
78564  'ɵɵproperty': ɵɵproperty,
78565  'ɵɵpropertyInterpolate': ɵɵpropertyInterpolate,
78566  'ɵɵpropertyInterpolate1': ɵɵpropertyInterpolate1,
78567  'ɵɵpropertyInterpolate2': ɵɵpropertyInterpolate2,
78568  'ɵɵpropertyInterpolate3': ɵɵpropertyInterpolate3,
78569  'ɵɵpropertyInterpolate4': ɵɵpropertyInterpolate4,
78570  'ɵɵpropertyInterpolate5': ɵɵpropertyInterpolate5,
78571  'ɵɵpropertyInterpolate6': ɵɵpropertyInterpolate6,
78572  'ɵɵpropertyInterpolate7': ɵɵpropertyInterpolate7,
78573  'ɵɵpropertyInterpolate8': ɵɵpropertyInterpolate8,
78574  'ɵɵpropertyInterpolateV': ɵɵpropertyInterpolateV,
78575  'ɵɵpipe': ɵɵpipe,
78576  'ɵɵqueryRefresh': ɵɵqueryRefresh,
78577  'ɵɵviewQuery': ɵɵviewQuery,
78578  'ɵɵloadQuery': ɵɵloadQuery,
78579  'ɵɵcontentQuery': ɵɵcontentQuery,
78580  'ɵɵreference': ɵɵreference,
78581  'ɵɵclassMap': ɵɵclassMap,
78582  'ɵɵclassMapInterpolate1': ɵɵclassMapInterpolate1,
78583  'ɵɵclassMapInterpolate2': ɵɵclassMapInterpolate2,
78584  'ɵɵclassMapInterpolate3': ɵɵclassMapInterpolate3,
78585  'ɵɵclassMapInterpolate4': ɵɵclassMapInterpolate4,
78586  'ɵɵclassMapInterpolate5': ɵɵclassMapInterpolate5,
78587  'ɵɵclassMapInterpolate6': ɵɵclassMapInterpolate6,
78588  'ɵɵclassMapInterpolate7': ɵɵclassMapInterpolate7,
78589  'ɵɵclassMapInterpolate8': ɵɵclassMapInterpolate8,
78590  'ɵɵclassMapInterpolateV': ɵɵclassMapInterpolateV,
78591  'ɵɵstyleMap': ɵɵstyleMap,
78592  'ɵɵstyleMapInterpolate1': ɵɵstyleMapInterpolate1,
78593  'ɵɵstyleMapInterpolate2': ɵɵstyleMapInterpolate2,
78594  'ɵɵstyleMapInterpolate3': ɵɵstyleMapInterpolate3,
78595  'ɵɵstyleMapInterpolate4': ɵɵstyleMapInterpolate4,
78596  'ɵɵstyleMapInterpolate5': ɵɵstyleMapInterpolate5,
78597  'ɵɵstyleMapInterpolate6': ɵɵstyleMapInterpolate6,
78598  'ɵɵstyleMapInterpolate7': ɵɵstyleMapInterpolate7,
78599  'ɵɵstyleMapInterpolate8': ɵɵstyleMapInterpolate8,
78600  'ɵɵstyleMapInterpolateV': ɵɵstyleMapInterpolateV,
78601  'ɵɵstyleProp': ɵɵstyleProp,
78602  'ɵɵstylePropInterpolate1': ɵɵstylePropInterpolate1,
78603  'ɵɵstylePropInterpolate2': ɵɵstylePropInterpolate2,
78604  'ɵɵstylePropInterpolate3': ɵɵstylePropInterpolate3,
78605  'ɵɵstylePropInterpolate4': ɵɵstylePropInterpolate4,
78606  'ɵɵstylePropInterpolate5': ɵɵstylePropInterpolate5,
78607  'ɵɵstylePropInterpolate6': ɵɵstylePropInterpolate6,
78608  'ɵɵstylePropInterpolate7': ɵɵstylePropInterpolate7,
78609  'ɵɵstylePropInterpolate8': ɵɵstylePropInterpolate8,
78610  'ɵɵstylePropInterpolateV': ɵɵstylePropInterpolateV,
78611  'ɵɵclassProp': ɵɵclassProp,
78612  'ɵɵadvance': ɵɵadvance,
78613  'ɵɵtemplate': ɵɵtemplate,
78614  'ɵɵtext': ɵɵtext,
78615  'ɵɵtextInterpolate': ɵɵtextInterpolate,
78616  'ɵɵtextInterpolate1': ɵɵtextInterpolate1,
78617  'ɵɵtextInterpolate2': ɵɵtextInterpolate2,
78618  'ɵɵtextInterpolate3': ɵɵtextInterpolate3,
78619  'ɵɵtextInterpolate4': ɵɵtextInterpolate4,
78620  'ɵɵtextInterpolate5': ɵɵtextInterpolate5,
78621  'ɵɵtextInterpolate6': ɵɵtextInterpolate6,
78622  'ɵɵtextInterpolate7': ɵɵtextInterpolate7,
78623  'ɵɵtextInterpolate8': ɵɵtextInterpolate8,
78624  'ɵɵtextInterpolateV': ɵɵtextInterpolateV,
78625  'ɵɵi18n': ɵɵi18n,
78626  'ɵɵi18nAttributes': ɵɵi18nAttributes,
78627  'ɵɵi18nExp': ɵɵi18nExp,
78628  'ɵɵi18nStart': ɵɵi18nStart,
78629  'ɵɵi18nEnd': ɵɵi18nEnd,
78630  'ɵɵi18nApply': ɵɵi18nApply,
78631  'ɵɵi18nPostprocess': ɵɵi18nPostprocess,
78632  'ɵɵresolveWindow': ɵɵresolveWindow,
78633  'ɵɵresolveDocument': ɵɵresolveDocument,
78634  'ɵɵresolveBody': ɵɵresolveBody,
78635  'ɵɵsetComponentScope': ɵɵsetComponentScope,
78636  'ɵɵsetNgModuleScope': ɵɵsetNgModuleScope,
78637  'ɵɵregisterNgModuleType': registerNgModuleType,
78638  'ɵɵsanitizeHtml': ɵɵsanitizeHtml,
78639  'ɵɵsanitizeStyle': ɵɵsanitizeStyle,
78640  'ɵɵsanitizeResourceUrl': ɵɵsanitizeResourceUrl,
78641  'ɵɵsanitizeScript': ɵɵsanitizeScript,
78642  'ɵɵsanitizeUrl': ɵɵsanitizeUrl,
78643  'ɵɵsanitizeUrlOrResourceUrl': ɵɵsanitizeUrlOrResourceUrl,
vendor: 42,996 bytes, lines 78644-79843
78644  'ɵɵtrustConstantHtml': ɵɵtrustConstantHtml,
78645  'ɵɵtrustConstantResourceUrl': ɵɵtrustConstantResourceUrl,
78646  'forwardRef': forwardRef,
78647  'resolveForwardRef': resolveForwardRef
78648}))();
78649
78650let jitOptions = null;
78651
78652function setJitOptions(options) {
78653  if (jitOptions !== null) {
78654    if (options.defaultEncapsulation !== jitOptions.defaultEncapsulation) {
78655      ngDevMode && console.error('Provided value for `defaultEncapsulation` can not be changed once it has been set.');
78656      return;
78657    }
78658
78659    if (options.preserveWhitespaces !== jitOptions.preserveWhitespaces) {
78660      ngDevMode && console.error('Provided value for `preserveWhitespaces` can not be changed once it has been set.');
78661      return;
78662    }
78663  }
78664
78665  jitOptions = options;
78666}
78667
78668function getJitOptions() {
78669  return jitOptions;
78670}
78671
78672function resetJitOptions() {
78673  jitOptions = null;
78674}
78675/**
78676 * @license
78677 * Copyright Google LLC All Rights Reserved.
78678 *
78679 * Use of this source code is governed by an MIT-style license that can be
78680 * found in the LICENSE file at https://angular.io/license
78681 */
78682
78683
78684function patchModuleCompilation() {// Does nothing, but exists as a target for patching.
78685}
78686/**
78687 * @license
78688 * Copyright Google LLC All Rights Reserved.
78689 *
78690 * Use of this source code is governed by an MIT-style license that can be
78691 * found in the LICENSE file at https://angular.io/license
78692 */
78693
78694
78695function isModuleWithProviders(value) {
78696  return value.ngModule !== undefined;
78697}
78698
78699function isNgModule(value) {
78700  return !!getNgModuleDef(value);
78701}
78702/**
78703 * @license
78704 * Copyright Google LLC All Rights Reserved.
78705 *
78706 * Use of this source code is governed by an MIT-style license that can be
78707 * found in the LICENSE file at https://angular.io/license
78708 */
78709
78710
78711const moduleQueue = [];
78712/**
78713 * Enqueues moduleDef to be checked later to see if scope can be set on its
78714 * component declarations.
78715 */
78716
78717function enqueueModuleForDelayedScoping(moduleType, ngModule) {
78718  moduleQueue.push({
78719    moduleType,
78720    ngModule
78721  });
78722}
78723
78724let flushingModuleQueue = false;
78725/**
78726 * Loops over queued module definitions, if a given module definition has all of its
78727 * declarations resolved, it dequeues that module definition and sets the scope on
78728 * its declarations.
78729 */
78730
78731function flushModuleScopingQueueAsMuchAsPossible() {
78732  if (!flushingModuleQueue) {
78733    flushingModuleQueue = true;
78734
78735    try {
78736      for (let i = moduleQueue.length - 1; i >= 0; i--) {
78737        const {
78738          moduleType,
78739          ngModule
78740        } = moduleQueue[i];
78741
78742        if (ngModule.declarations && ngModule.declarations.every(isResolvedDeclaration)) {
78743          // dequeue
78744          moduleQueue.splice(i, 1);
78745          setScopeOnDeclaredComponents(moduleType, ngModule);
78746        }
78747      }
78748    } finally {
78749      flushingModuleQueue = false;
78750    }
78751  }
78752}
78753/**
78754 * Returns truthy if a declaration has resolved. If the declaration happens to be
78755 * an array of declarations, it will recurse to check each declaration in that array
78756 * (which may also be arrays).
78757 */
78758
78759
78760function isResolvedDeclaration(declaration) {
78761  if (Array.isArray(declaration)) {
78762    return declaration.every(isResolvedDeclaration);
78763  }
78764
78765  return !!resolveForwardRef(declaration);
78766}
78767/**
78768 * Compiles a module in JIT mode.
78769 *
78770 * This function automatically gets called when a class has a `@NgModule` decorator.
78771 */
78772
78773
78774function compileNgModule(moduleType, ngModule = {}) {
78775  patchModuleCompilation();
78776  compileNgModuleDefs(moduleType, ngModule);
78777
78778  if (ngModule.id !== undefined) {
78779    registerNgModuleType(moduleType, ngModule.id);
78780  } // Because we don't know if all declarations have resolved yet at the moment the
78781  // NgModule decorator is executing, we're enqueueing the setting of module scope
78782  // on its declarations to be run at a later time when all declarations for the module,
78783  // including forward refs, have resolved.
78784
78785
78786  enqueueModuleForDelayedScoping(moduleType, ngModule);
78787}
78788/**
78789 * Compiles and adds the `ɵmod`, `ɵfac` and `ɵinj` properties to the module class.
78790 *
78791 * It's possible to compile a module via this API which will allow duplicate declarations in its
78792 * root.
78793 */
78794
78795
78796function compileNgModuleDefs(moduleType, ngModule, allowDuplicateDeclarationsInRoot = false) {
78797  ngDevMode && assertDefined(moduleType, 'Required value moduleType');
78798  ngDevMode && assertDefined(ngModule, 'Required value ngModule');
78799  const declarations = flatten(ngModule.declarations || EMPTY_ARRAY);
78800  let ngModuleDef = null;
78801  Object.defineProperty(moduleType, NG_MOD_DEF, {
78802    configurable: true,
78803    get: () => {
78804      if (ngModuleDef === null) {
78805        if (ngDevMode && ngModule.imports && ngModule.imports.indexOf(moduleType) > -1) {
78806          // We need to assert this immediately, because allowing it to continue will cause it to
78807          // go into an infinite loop before we've reached the point where we throw all the errors.
78808          throw new Error(`'${stringifyForError(moduleType)}' module can't import itself`);
78809        }
78810
78811        const compiler = getCompilerFacade({
78812          usage: 0
78813          /* JitCompilerUsage.Decorator */
78814          ,
78815          kind: 'NgModule',
78816          type: moduleType
78817        });
78818        ngModuleDef = compiler.compileNgModule(angularCoreEnv, `ng:///${moduleType.name}/ɵmod.js`, {
78819          type: moduleType,
78820          bootstrap: flatten(ngModule.bootstrap || EMPTY_ARRAY).map(resolveForwardRef),
78821          declarations: declarations.map(resolveForwardRef),
78822          imports: flatten(ngModule.imports || EMPTY_ARRAY).map(resolveForwardRef).map(expandModuleWithProviders),
78823          exports: flatten(ngModule.exports || EMPTY_ARRAY).map(resolveForwardRef).map(expandModuleWithProviders),
78824          schemas: ngModule.schemas ? flatten(ngModule.schemas) : null,
78825          id: ngModule.id || null
78826        }); // Set `schemas` on ngModuleDef to an empty array in JIT mode to indicate that runtime
78827        // should verify that there are no unknown elements in a template. In AOT mode, that check
78828        // happens at compile time and `schemas` information is not present on Component and Module
78829        // defs after compilation (so the check doesn't happen the second time at runtime).
78830
78831        if (!ngModuleDef.schemas) {
78832          ngModuleDef.schemas = [];
78833        }
78834      }
78835
78836      return ngModuleDef;
78837    }
78838  });
78839  let ngFactoryDef = null;
78840  Object.defineProperty(moduleType, NG_FACTORY_DEF, {
78841    get: () => {
78842      if (ngFactoryDef === null) {
78843        const compiler = getCompilerFacade({
78844          usage: 0
78845          /* JitCompilerUsage.Decorator */
78846          ,
78847          kind: 'NgModule',
78848          type: moduleType
78849        });
78850        ngFactoryDef = compiler.compileFactory(angularCoreEnv, `ng:///${moduleType.name}/ɵfac.js`, {
78851          name: moduleType.name,
78852          type: moduleType,
78853          deps: reflectDependencies(moduleType),
78854          target: compiler.FactoryTarget.NgModule,
78855          typeArgumentCount: 0
78856        });
78857      }
78858
78859      return ngFactoryDef;
78860    },
78861    // Make the property configurable in dev mode to allow overriding in tests
78862    configurable: !!ngDevMode
78863  });
78864  let ngInjectorDef = null;
78865  Object.defineProperty(moduleType, NG_INJ_DEF, {
78866    get: () => {
78867      if (ngInjectorDef === null) {
78868        ngDevMode && verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot);
78869        const meta = {
78870          name: moduleType.name,
78871          type: moduleType,
78872          providers: ngModule.providers || EMPTY_ARRAY,
78873          imports: [(ngModule.imports || EMPTY_ARRAY).map(resolveForwardRef), (ngModule.exports || EMPTY_ARRAY).map(resolveForwardRef)]
78874        };
78875        const compiler = getCompilerFacade({
78876          usage: 0
78877          /* JitCompilerUsage.Decorator */
78878          ,
78879          kind: 'NgModule',
78880          type: moduleType
78881        });
78882        ngInjectorDef = compiler.compileInjector(angularCoreEnv, `ng:///${moduleType.name}/ɵinj.js`, meta);
78883      }
78884
78885      return ngInjectorDef;
78886    },
78887    // Make the property configurable in dev mode to allow overriding in tests
78888    configurable: !!ngDevMode
78889  });
78890}
78891
78892function generateStandaloneInDeclarationsError(type, location) {
78893  const prefix = `Unexpected "${stringifyForError(type)}" found in the "declarations" array of the`;
78894  const suffix = `"${stringifyForError(type)}" is marked as standalone and can't be declared ` + 'in any NgModule - did you intend to import it instead (by adding it to the "imports" array)?';
78895  return `${prefix} ${location}, ${suffix}`;
78896}
78897
78898function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot, importingModule) {
78899  if (verifiedNgModule.get(moduleType)) return; // skip verifications of standalone components, directives, and pipes
78900
78901  if (isStandalone(moduleType)) return;
78902  verifiedNgModule.set(moduleType, true);
78903  moduleType = resolveForwardRef(moduleType);
78904  let ngModuleDef;
78905
78906  if (importingModule) {
78907    ngModuleDef = getNgModuleDef(moduleType);
78908
78909    if (!ngModuleDef) {
78910      throw new Error(`Unexpected value '${moduleType.name}' imported by the module '${importingModule.name}'. Please add an @NgModule annotation.`);
78911    }
78912  } else {
78913    ngModuleDef = getNgModuleDef(moduleType, true);
78914  }
78915
78916  const errors = [];
78917  const declarations = maybeUnwrapFn(ngModuleDef.declarations);
78918  const imports = maybeUnwrapFn(ngModuleDef.imports);
78919  flatten(imports).map(unwrapModuleWithProvidersImports).forEach(modOrStandaloneCmpt => {
78920    verifySemanticsOfNgModuleImport(modOrStandaloneCmpt, moduleType);
78921    verifySemanticsOfNgModuleDef(modOrStandaloneCmpt, false, moduleType);
78922  });
78923  const exports = maybeUnwrapFn(ngModuleDef.exports);
78924  declarations.forEach(verifyDeclarationsHaveDefinitions);
78925  declarations.forEach(verifyDirectivesHaveSelector);
78926  declarations.forEach(declarationType => verifyNotStandalone(declarationType, moduleType));
78927  const combinedDeclarations = [...declarations.map(resolveForwardRef), ...flatten(imports.map(computeCombinedExports)).map(resolveForwardRef)];
78928  exports.forEach(verifyExportsAreDeclaredOrReExported);
78929  declarations.forEach(decl => verifyDeclarationIsUnique(decl, allowDuplicateDeclarationsInRoot));
78930  declarations.forEach(verifyComponentEntryComponentsIsPartOfNgModule);
78931  const ngModule = getAnnotation(moduleType, 'NgModule');
78932
78933  if (ngModule) {
78934    ngModule.imports && flatten(ngModule.imports).map(unwrapModuleWithProvidersImports).forEach(mod => {
78935      verifySemanticsOfNgModuleImport(mod, moduleType);
78936      verifySemanticsOfNgModuleDef(mod, false, moduleType);
78937    });
78938    ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyCorrectBootstrapType);
78939    ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyComponentIsPartOfNgModule);
78940    ngModule.entryComponents && deepForEach(ngModule.entryComponents, verifyComponentIsPartOfNgModule);
78941  } // Throw Error if any errors were detected.
78942
78943
78944  if (errors.length) {
78945    throw new Error(errors.join('\n'));
78946  } ////////////////////////////////////////////////////////////////////////////////////////////////
78947
78948
78949  function verifyDeclarationsHaveDefinitions(type) {
78950    type = resolveForwardRef(type);
78951    const def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef$1(type);
78952
78953    if (!def) {
78954      errors.push(`Unexpected value '${stringifyForError(type)}' declared by the module '${stringifyForError(moduleType)}'. Please add a @Pipe/@Directive/@Component annotation.`);
78955    }
78956  }
78957
78958  function verifyDirectivesHaveSelector(type) {
78959    type = resolveForwardRef(type);
78960    const def = getDirectiveDef(type);
78961
78962    if (!getComponentDef(type) && def && def.selectors.length == 0) {
78963      errors.push(`Directive ${stringifyForError(type)} has no selector, please add it!`);
78964    }
78965  }
78966
78967  function verifyNotStandalone(type, moduleType) {
78968    type = resolveForwardRef(type);
78969    const def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef$1(type);
78970
78971    if (def?.standalone) {
78972      const location = `"${stringifyForError(moduleType)}" NgModule`;
78973      errors.push(generateStandaloneInDeclarationsError(type, location));
78974    }
78975  }
78976
78977  function verifyExportsAreDeclaredOrReExported(type) {
78978    type = resolveForwardRef(type);
78979    const kind = getComponentDef(type) && 'component' || getDirectiveDef(type) && 'directive' || getPipeDef$1(type) && 'pipe';
78980
78981    if (kind) {
78982      // only checked if we are declared as Component, Directive, or Pipe
78983      // Modules don't need to be declared or imported.
78984      if (combinedDeclarations.lastIndexOf(type) === -1) {
78985        // We are exporting something which we don't explicitly declare or import.
78986        errors.push(`Can't export ${kind} ${stringifyForError(type)} from ${stringifyForError(moduleType)} as it was neither declared nor imported!`);
78987      }
78988    }
78989  }
78990
78991  function verifyDeclarationIsUnique(type, suppressErrors) {
78992    type = resolveForwardRef(type);
78993    const existingModule = ownerNgModule.get(type);
78994
78995    if (existingModule && existingModule !== moduleType) {
78996      if (!suppressErrors) {
78997        const modules = [existingModule, moduleType].map(stringifyForError).sort();
78998        errors.push(`Type ${stringifyForError(type)} is part of the declarations of 2 modules: ${modules[0]} and ${modules[1]}! ` + `Please consider moving ${stringifyForError(type)} to a higher module that imports ${modules[0]} and ${modules[1]}. ` + `You can also create a new NgModule that exports and includes ${stringifyForError(type)} then import that NgModule in ${modules[0]} and ${modules[1]}.`);
78999      }
79000    } else {
79001      // Mark type as having owner.
79002      ownerNgModule.set(type, moduleType);
79003    }
79004  }
79005
79006  function verifyComponentIsPartOfNgModule(type) {
79007    type = resolveForwardRef(type);
79008    const existingModule = ownerNgModule.get(type);
79009
79010    if (!existingModule && !isStandalone(type)) {
79011      errors.push(`Component ${stringifyForError(type)} is not part of any NgModule or the module has not been imported into your module.`);
79012    }
79013  }
79014
79015  function verifyCorrectBootstrapType(type) {
79016    type = resolveForwardRef(type);
79017
79018    if (!getComponentDef(type)) {
79019      errors.push(`${stringifyForError(type)} cannot be used as an entry component.`);
79020    }
79021
79022    if (isStandalone(type)) {
79023      // Note: this error should be the same as the
79024      // `NGMODULE_BOOTSTRAP_IS_STANDALONE` one in AOT compiler.
79025      errors.push(`The \`${stringifyForError(type)}\` class is a standalone component, which can ` + `not be used in the \`@NgModule.bootstrap\` array. Use the \`bootstrapApplication\` ` + `function for bootstrap instead.`);
79026    }
79027  }
79028
79029  function verifyComponentEntryComponentsIsPartOfNgModule(type) {
79030    type = resolveForwardRef(type);
79031
79032    if (getComponentDef(type)) {
79033      // We know we are component
79034      const component = getAnnotation(type, 'Component');
79035
79036      if (component && component.entryComponents) {
79037        deepForEach(component.entryComponents, verifyComponentIsPartOfNgModule);
79038      }
79039    }
79040  }
79041
79042  function verifySemanticsOfNgModuleImport(type, importingModule) {
79043    type = resolveForwardRef(type);
79044    const directiveDef = getComponentDef(type) || getDirectiveDef(type);
79045
79046    if (directiveDef !== null && !directiveDef.standalone) {
79047      throw new Error(`Unexpected directive '${type.name}' imported by the module '${importingModule.name}'. Please add an @NgModule annotation.`);
79048    }
79049
79050    const pipeDef = getPipeDef$1(type);
79051
79052    if (pipeDef !== null && !pipeDef.standalone) {
79053      throw new Error(`Unexpected pipe '${type.name}' imported by the module '${importingModule.name}'. Please add an @NgModule annotation.`);
79054    }
79055  }
79056}
79057
79058function unwrapModuleWithProvidersImports(typeOrWithProviders) {
79059  typeOrWithProviders = resolveForwardRef(typeOrWithProviders);
79060  return typeOrWithProviders.ngModule || typeOrWithProviders;
79061}
79062
79063function getAnnotation(type, name) {
79064  let annotation = null;
79065  collect(type.__annotations__);
79066  collect(type.decorators);
79067  return annotation;
79068
79069  function collect(annotations) {
79070    if (annotations) {
79071      annotations.forEach(readAnnotation);
79072    }
79073  }
79074
79075  function readAnnotation(decorator) {
79076    if (!annotation) {
79077      const proto = Object.getPrototypeOf(decorator);
79078
79079      if (proto.ngMetadataName == name) {
79080        annotation = decorator;
79081      } else if (decorator.type) {
79082        const proto = Object.getPrototypeOf(decorator.type);
79083
79084        if (proto.ngMetadataName == name) {
79085          annotation = decorator.args[0];
79086        }
79087      }
79088    }
79089  }
79090}
79091/**
79092 * Keep track of compiled components. This is needed because in tests we often want to compile the
79093 * same component with more than one NgModule. This would cause an error unless we reset which
79094 * NgModule the component belongs to. We keep the list of compiled components here so that the
79095 * TestBed can reset it later.
79096 */
79097
79098
79099let ownerNgModule = new WeakMap();
79100let verifiedNgModule = new WeakMap();
79101
79102function resetCompiledComponents() {
79103  ownerNgModule = new WeakMap();
79104  verifiedNgModule = new WeakMap();
79105  moduleQueue.length = 0;
79106}
79107/**
79108 * Computes the combined declarations of explicit declarations, as well as declarations inherited by
79109 * traversing the exports of imported modules.
79110 * @param type
79111 */
79112
79113
79114function computeCombinedExports(type) {
79115  type = resolveForwardRef(type);
79116  const ngModuleDef = getNgModuleDef(type); // a standalone component, directive or pipe
79117
79118  if (ngModuleDef === null) {
79119    return [type];
79120  }
79121
79122  return [...flatten(maybeUnwrapFn(ngModuleDef.exports).map(type => {
79123    const ngModuleDef = getNgModuleDef(type);
79124
79125    if (ngModuleDef) {
79126      verifySemanticsOfNgModuleDef(type, false);
79127      return computeCombinedExports(type);
79128    } else {
79129      return type;
79130    }
79131  }))];
79132}
79133/**
79134 * Some declared components may be compiled asynchronously, and thus may not have their
79135 * ɵcmp set yet. If this is the case, then a reference to the module is written into
79136 * the `ngSelectorScope` property of the declared type.
79137 */
79138
79139
79140function setScopeOnDeclaredComponents(moduleType, ngModule) {
79141  const declarations = flatten(ngModule.declarations || EMPTY_ARRAY);
79142  const transitiveScopes = transitiveScopesFor(moduleType);
79143  declarations.forEach(declaration => {
79144    declaration = resolveForwardRef(declaration);
79145
79146    if (declaration.hasOwnProperty(NG_COMP_DEF)) {
79147      // A `ɵcmp` field exists - go ahead and patch the component directly.
79148      const component = declaration;
79149      const componentDef = getComponentDef(component);
79150      patchComponentDefWithScope(componentDef, transitiveScopes);
79151    } else if (!declaration.hasOwnProperty(NG_DIR_DEF) && !declaration.hasOwnProperty(NG_PIPE_DEF)) {
79152      // Set `ngSelectorScope` for future reference when the component compilation finishes.
79153      declaration.ngSelectorScope = moduleType;
79154    }
79155  });
79156}
79157/**
79158 * Patch the definition of a component with directives and pipes from the compilation scope of
79159 * a given module.
79160 */
79161
79162
79163function patchComponentDefWithScope(componentDef, transitiveScopes) {
79164  componentDef.directiveDefs = () => Array.from(transitiveScopes.compilation.directives).map(dir => dir.hasOwnProperty(NG_COMP_DEF) ? getComponentDef(dir) : getDirectiveDef(dir)).filter(def => !!def);
79165
79166  componentDef.pipeDefs = () => Array.from(transitiveScopes.compilation.pipes).map(pipe => getPipeDef$1(pipe));
79167
79168  componentDef.schemas = transitiveScopes.schemas; // Since we avoid Components/Directives/Pipes recompiling in case there are no overrides, we
79169  // may face a problem where previously compiled defs available to a given Component/Directive
79170  // are cached in TView and may become stale (in case any of these defs gets recompiled). In
79171  // order to avoid this problem, we force fresh TView to be created.
79172
79173  componentDef.tView = null;
79174}
79175/**
79176 * Compute the pair of transitive scopes (compilation scope and exported scope) for a given type
79177 * (either a NgModule or a standalone component / directive / pipe).
79178 */
79179
79180
79181function transitiveScopesFor(type) {
79182  if (isNgModule(type)) {
79183    return transitiveScopesForNgModule(type);
79184  } else if (isStandalone(type)) {
79185    const directiveDef = getComponentDef(type) || getDirectiveDef(type);
79186
79187    if (directiveDef !== null) {
79188      return {
79189        schemas: null,
79190        compilation: {
79191          directives: new Set(),
79192          pipes: new Set()
79193        },
79194        exported: {
79195          directives: new Set([type]),
79196          pipes: new Set()
79197        }
79198      };
79199    }
79200
79201    const pipeDef = getPipeDef$1(type);
79202
79203    if (pipeDef !== null) {
79204      return {
79205        schemas: null,
79206        compilation: {
79207          directives: new Set(),
79208          pipes: new Set()
79209        },
79210        exported: {
79211          directives: new Set(),
79212          pipes: new Set([type])
79213        }
79214      };
79215    }
79216  } // TODO: change the error message to be more user-facing and take standalone into account
79217
79218
79219  throw new Error(`${type.name} does not have a module def (ɵmod property)`);
79220}
79221/**
79222 * Compute the pair of transitive scopes (compilation scope and exported scope) for a given module.
79223 *
79224 * This operation is memoized and the result is cached on the module's definition. This function can
79225 * be called on modules with components that have not fully compiled yet, but the result should not
79226 * be used until they have.
79227 *
79228 * @param moduleType module that transitive scope should be calculated for.
79229 */
79230
79231
79232function transitiveScopesForNgModule(moduleType) {
79233  const def = getNgModuleDef(moduleType, true);
79234
79235  if (def.transitiveCompileScopes !== null) {
79236    return def.transitiveCompileScopes;
79237  }
79238
79239  const scopes = {
79240    schemas: def.schemas || null,
79241    compilation: {
79242      directives: new Set(),
79243      pipes: new Set()
79244    },
79245    exported: {
79246      directives: new Set(),
79247      pipes: new Set()
79248    }
79249  };
79250  maybeUnwrapFn(def.imports).forEach(imported => {
79251    // When this module imports another, the imported module's exported directives and pipes are
79252    // added to the compilation scope of this module.
79253    const importedScope = transitiveScopesFor(imported);
79254    importedScope.exported.directives.forEach(entry => scopes.compilation.directives.add(entry));
79255    importedScope.exported.pipes.forEach(entry => scopes.compilation.pipes.add(entry));
79256  });
79257  maybeUnwrapFn(def.declarations).forEach(declared => {
79258    const declaredWithDefs = declared;
79259
79260    if (getPipeDef$1(declaredWithDefs)) {
79261      scopes.compilation.pipes.add(declared);
79262    } else {
79263      // Either declared has a ɵcmp or ɵdir, or it's a component which hasn't
79264      // had its template compiled yet. In either case, it gets added to the compilation's
79265      // directives.
79266      scopes.compilation.directives.add(declared);
79267    }
79268  });
79269  maybeUnwrapFn(def.exports).forEach(exported => {
79270    const exportedType = exported; // Either the type is a module, a pipe, or a component/directive (which may not have a
79271    // ɵcmp as it might be compiled asynchronously).
79272
79273    if (isNgModule(exportedType)) {
79274      // When this module exports another, the exported module's exported directives and pipes are
79275      // added to both the compilation and exported scopes of this module.
79276      const exportedScope = transitiveScopesFor(exportedType);
79277      exportedScope.exported.directives.forEach(entry => {
79278        scopes.compilation.directives.add(entry);
79279        scopes.exported.directives.add(entry);
79280      });
79281      exportedScope.exported.pipes.forEach(entry => {
79282        scopes.compilation.pipes.add(entry);
79283        scopes.exported.pipes.add(entry);
79284      });
79285    } else if (getPipeDef$1(exportedType)) {
79286      scopes.exported.pipes.add(exportedType);
79287    } else {
79288      scopes.exported.directives.add(exportedType);
79289    }
79290  });
79291  def.transitiveCompileScopes = scopes;
79292  return scopes;
79293}
79294
79295function expandModuleWithProviders(value) {
79296  if (isModuleWithProviders(value)) {
79297    return value.ngModule;
79298  }
79299
79300  return value;
79301}
79302/**
79303 * @license
79304 * Copyright Google LLC All Rights Reserved.
79305 *
79306 * Use of this source code is governed by an MIT-style license that can be
79307 * found in the LICENSE file at https://angular.io/license
79308 */
79309
79310/**
79311 * Keep track of the compilation depth to avoid reentrancy issues during JIT compilation. This
79312 * matters in the following scenario:
79313 *
79314 * Consider a component 'A' that extends component 'B', both declared in module 'M'. During
79315 * the compilation of 'A' the definition of 'B' is requested to capture the inheritance chain,
79316 * potentially triggering compilation of 'B'. If this nested compilation were to trigger
79317 * `flushModuleScopingQueueAsMuchAsPossible` it may happen that module 'M' is still pending in the
79318 * queue, resulting in 'A' and 'B' to be patched with the NgModule scope. As the compilation of
79319 * 'A' is still in progress, this would introduce a circular dependency on its compilation. To avoid
79320 * this issue, the module scope queue is only flushed for compilations at the depth 0, to ensure
79321 * all compilations have finished.
79322 */
79323
79324
79325let compilationDepth = 0;
79326/**
79327 * Compile an Angular component according to its decorator metadata, and patch the resulting
79328 * component def (ɵcmp) onto the component type.
79329 *
79330 * Compilation may be asynchronous (due to the need to resolve URLs for the component template or
79331 * other resources, for example). In the event that compilation is not immediate, `compileComponent`
79332 * will enqueue resource resolution into a global queue and will fail to return the `ɵcmp`
79333 * until the global queue has been resolved with a call to `resolveComponentResources`.
79334 */
79335
79336function compileComponent(type, metadata) {
79337  // Initialize ngDevMode. This must be the first statement in compileComponent.
79338  // See the `initNgDevMode` docstring for more information.
79339  (typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode();
79340  let ngComponentDef = null; // Metadata may have resources which need to be resolved.
79341
79342  maybeQueueResolutionOfComponentResources(type, metadata); // Note that we're using the same function as `Directive`, because that's only subset of metadata
79343  // that we need to create the ngFactoryDef. We're avoiding using the component metadata
79344  // because we'd have to resolve the asynchronous templates.
79345
79346  addDirectiveFactoryDef(type, metadata);
79347  Object.defineProperty(type, NG_COMP_DEF, {
79348    get: () => {
79349      if (ngComponentDef === null) {
79350        const compiler = getCompilerFacade({
79351          usage: 0
79352          /* JitCompilerUsage.Decorator */
79353          ,
79354          kind: 'component',
79355          type: type
79356        });
79357
79358        if (componentNeedsResolution(metadata)) {
79359          const error = [`Component '${type.name}' is not resolved:`];
79360
79361          if (metadata.templateUrl) {
79362            error.push(` - templateUrl: ${metadata.templateUrl}`);
79363          }
79364
79365          if (metadata.styleUrls && metadata.styleUrls.length) {
79366            error.push(` - styleUrls: ${JSON.stringify(metadata.styleUrls)}`);
79367          }
79368
79369          error.push(`Did you run and wait for 'resolveComponentResources()'?`);
79370          throw new Error(error.join('\n'));
79371        } // This const was called `jitOptions` previously but had to be renamed to `options` because
79372        // of a bug with Terser that caused optimized JIT builds to throw a `ReferenceError`.
79373        // This bug was investigated in https://github.com/angular/angular-cli/issues/17264.
79374        // We should not rename it back until https://github.com/terser/terser/issues/615 is fixed.
79375
79376
79377        const options = getJitOptions();
79378        let preserveWhitespaces = metadata.preserveWhitespaces;
79379
79380        if (preserveWhitespaces === undefined) {
79381          if (options !== null && options.preserveWhitespaces !== undefined) {
79382            preserveWhitespaces = options.preserveWhitespaces;
79383          } else {
79384            preserveWhitespaces = false;
79385          }
79386        }
79387
79388        let encapsulation = metadata.encapsulation;
79389
79390        if (encapsulation === undefined) {
79391          if (options !== null && options.defaultEncapsulation !== undefined) {
79392            encapsulation = options.defaultEncapsulation;
79393          } else {
79394            encapsulation = ViewEncapsulation$1.Emulated;
79395          }
79396        }
79397
79398        const templateUrl = metadata.templateUrl || `ng:///${type.name}/template.html`;
79399        const meta = { ...directiveMetadata(type, metadata),
79400          typeSourceSpan: compiler.createParseSourceSpan('Component', type.name, templateUrl),
79401          template: metadata.template || '',
79402          preserveWhitespaces,
79403          styles: metadata.styles || EMPTY_ARRAY,
79404          animations: metadata.animations,
79405          // JIT components are always compiled against an empty set of `declarations`. Instead, the
79406          // `directiveDefs` and `pipeDefs` are updated at a later point:
79407          //  * for NgModule-based components, they're set when the NgModule which declares the
79408          //    component resolves in the module scoping queue
79409          //  * for standalone components, they're set just below, after `compileComponent`.
79410          declarations: [],
79411          changeDetection: metadata.changeDetection,
79412          encapsulation,
79413          interpolation: metadata.interpolation,
79414          viewProviders: metadata.viewProviders || null,
79415          isStandalone: !!metadata.standalone
79416        };
79417        compilationDepth++;
79418
79419        try {
79420          if (meta.usesInheritance) {
79421            addDirectiveDefToUndecoratedParents(type);
79422          }
79423
79424          ngComponentDef = compiler.compileComponent(angularCoreEnv, templateUrl, meta);
79425
79426          if (metadata.standalone) {
79427            // Patch the component definition for standalone components with `directiveDefs` and
79428            // `pipeDefs` functions which lazily compute the directives/pipes available in the
79429            // standalone component. Also set `dependencies` to the lazily resolved list of imports.
79430            const imports = flatten(metadata.imports || EMPTY_ARRAY);
79431            const {
79432              directiveDefs,
79433              pipeDefs
79434            } = getStandaloneDefFunctions(type, imports);
79435            ngComponentDef.directiveDefs = directiveDefs;
79436            ngComponentDef.pipeDefs = pipeDefs;
79437
79438            ngComponentDef.dependencies = () => imports.map(resolveForwardRef);
79439          }
79440        } finally {
79441          // Ensure that the compilation depth is decremented even when the compilation failed.
79442          compilationDepth--;
79443        }
79444
79445        if (compilationDepth === 0) {
79446          // When NgModule decorator executed, we enqueued the module definition such that
79447          // it would only dequeue and add itself as module scope to all of its declarations,
79448          // but only if  if all of its declarations had resolved. This call runs the check
79449          // to see if any modules that are in the queue can be dequeued and add scope to
79450          // their declarations.
79451          flushModuleScopingQueueAsMuchAsPossible();
79452        } // If component compilation is async, then the @NgModule annotation which declares the
79453        // component may execute and set an ngSelectorScope property on the component type. This
79454        // allows the component to patch itself with directiveDefs from the module after it
79455        // finishes compiling.
79456
79457
79458        if (hasSelectorScope(type)) {
79459          const scopes = transitiveScopesFor(type.ngSelectorScope);
79460          patchComponentDefWithScope(ngComponentDef, scopes);
79461        }
79462
79463        if (metadata.schemas) {
79464          if (metadata.standalone) {
79465            ngComponentDef.schemas = metadata.schemas;
79466          } else {
79467            throw new Error(`The 'schemas' was specified for the ${stringifyForError(type)} but is only valid on a component that is standalone.`);
79468          }
79469        } else if (metadata.standalone) {
79470          ngComponentDef.schemas = [];
79471        }
79472      }
79473
79474      return ngComponentDef;
79475    },
79476    // Make the property configurable in dev mode to allow overriding in tests
79477    configurable: !!ngDevMode
79478  });
79479}
79480
79481function getDependencyTypeForError(type) {
79482  if (getComponentDef(type)) return 'component';
79483  if (getDirectiveDef(type)) return 'directive';
79484  if (getPipeDef$1(type)) return 'pipe';
79485  return 'type';
79486}
79487
79488function verifyStandaloneImport(depType, importingType) {
79489  if (isForwardRef(depType)) {
79490    depType = resolveForwardRef(depType);
79491
79492    if (!depType) {
79493      throw new Error(`Expected forwardRef function, imported from "${stringifyForError(importingType)}", to return a standalone entity or NgModule but got "${stringifyForError(depType) || depType}".`);
79494    }
79495  }
79496
79497  if (getNgModuleDef(depType) == null) {
79498    const def = getComponentDef(depType) || getDirectiveDef(depType) || getPipeDef$1(depType);
79499
79500    if (def != null) {
79501      // if a component, directive or pipe is imported make sure that it is standalone
79502      if (!def.standalone) {
79503        throw new Error(`The "${stringifyForError(depType)}" ${getDependencyTypeForError(depType)}, imported from "${stringifyForError(importingType)}", is not standalone. Did you forget to add the standalone: true flag?`);
79504      }
79505    } else {
79506      // it can be either a module with provider or an unknown (not annotated) type
79507      if (isModuleWithProviders(depType)) {
79508        throw new Error(`A module with providers was imported from "${stringifyForError(importingType)}". Modules with providers are not supported in standalone components imports.`);
79509      } else {
79510        throw new Error(`The "${stringifyForError(depType)}" type, imported from "${stringifyForError(importingType)}", must be a standalone component / directive / pipe or an NgModule. Did you forget to add the required @Component / @Directive / @Pipe or @NgModule annotation?`);
79511      }
79512    }
79513  }
79514}
79515/**
79516 * Build memoized `directiveDefs` and `pipeDefs` functions for the component definition of a
79517 * standalone component, which process `imports` and filter out directives and pipes. The use of
79518 * memoized functions here allows for the delayed resolution of any `forwardRef`s present in the
79519 * component's `imports`.
79520 */
79521
79522
79523function getStandaloneDefFunctions(type, imports) {
79524  let cachedDirectiveDefs = null;
79525  let cachedPipeDefs = null;
79526
79527  const directiveDefs = () => {
79528    if (cachedDirectiveDefs === null) {
79529      // Standalone components are always able to self-reference, so include the component's own
79530      // definition in its `directiveDefs`.
79531      cachedDirectiveDefs = [getComponentDef(type)];
79532      const seen = new Set();
79533
79534      for (const rawDep of imports) {
79535        ngDevMode && verifyStandaloneImport(rawDep, type);
79536        const dep = resolveForwardRef(rawDep);
79537
79538        if (seen.has(dep)) {
79539          continue;
79540        }
79541
79542        seen.add(dep);
79543
79544        if (!!getNgModuleDef(dep)) {
79545          const scope = transitiveScopesFor(dep);
79546
79547          for (const dir of scope.exported.directives) {
79548            const def = getComponentDef(dir) || getDirectiveDef(dir);
79549
79550            if (def && !seen.has(dir)) {
79551              seen.add(dir);
79552              cachedDirectiveDefs.push(def);
79553            }
79554          }
79555        } else {
79556          const def = getComponentDef(dep) || getDirectiveDef(dep);
79557
79558          if (def) {
79559            cachedDirectiveDefs.push(def);
79560          }
79561        }
79562      }
79563    }
79564
79565    return cachedDirectiveDefs;
79566  };
79567
79568  const pipeDefs = () => {
79569    if (cachedPipeDefs === null) {
79570      cachedPipeDefs = [];
79571      const seen = new Set();
79572
79573      for (const rawDep of imports) {
79574        const dep = resolveForwardRef(rawDep);
79575
79576        if (seen.has(dep)) {
79577          continue;
79578        }
79579
79580        seen.add(dep);
79581
79582        if (!!getNgModuleDef(dep)) {
79583          const scope = transitiveScopesFor(dep);
79584
79585          for (const pipe of scope.exported.pipes) {
79586            const def = getPipeDef$1(pipe);
79587
79588            if (def && !seen.has(pipe)) {
79589              seen.add(pipe);
79590              cachedPipeDefs.push(def);
79591            }
79592          }
79593        } else {
79594          const def = getPipeDef$1(dep);
79595
79596          if (def) {
79597            cachedPipeDefs.push(def);
79598          }
79599        }
79600      }
79601    }
79602
79603    return cachedPipeDefs;
79604  };
79605
79606  return {
79607    directiveDefs,
79608    pipeDefs
79609  };
79610}
79611
79612function hasSelectorScope(component) {
79613  return component.ngSelectorScope !== undefined;
79614}
79615/**
79616 * Compile an Angular directive according to its decorator metadata, and patch the resulting
79617 * directive def onto the component type.
79618 *
79619 * In the event that compilation is not immediate, `compileDirective` will return a `Promise` which
79620 * will resolve when compilation completes and the directive becomes usable.
79621 */
79622
79623
79624function compileDirective(type, directive) {
79625  let ngDirectiveDef = null;
79626  addDirectiveFactoryDef(type, directive || {});
79627  Object.defineProperty(type, NG_DIR_DEF, {
79628    get: () => {
79629      if (ngDirectiveDef === null) {
79630        // `directive` can be null in the case of abstract directives as a base class
79631        // that use `@Directive()` with no selector. In that case, pass empty object to the
79632        // `directiveMetadata` function instead of null.
79633        const meta = getDirectiveMetadata(type, directive || {});
79634        const compiler = getCompilerFacade({
79635          usage: 0
79636          /* JitCompilerUsage.Decorator */
79637          ,
79638          kind: 'directive',
79639          type
79640        });
79641        ngDirectiveDef = compiler.compileDirective(angularCoreEnv, meta.sourceMapUrl, meta.metadata);
79642      }
79643
79644      return ngDirectiveDef;
79645    },
79646    // Make the property configurable in dev mode to allow overriding in tests
79647    configurable: !!ngDevMode
79648  });
79649}
79650
79651function getDirectiveMetadata(type, metadata) {
79652  const name = type && type.name;
79653  const sourceMapUrl = `ng:///${name}/ɵdir.js`;
79654  const compiler = getCompilerFacade({
79655    usage: 0
79656    /* JitCompilerUsage.Decorator */
79657    ,
79658    kind: 'directive',
79659    type
79660  });
79661  const facade = directiveMetadata(type, metadata);
79662  facade.typeSourceSpan = compiler.createParseSourceSpan('Directive', name, sourceMapUrl);
79663
79664  if (facade.usesInheritance) {
79665    addDirectiveDefToUndecoratedParents(type);
79666  }
79667
79668  return {
79669    metadata: facade,
79670    sourceMapUrl
79671  };
79672}
79673
79674function addDirectiveFactoryDef(type, metadata) {
79675  let ngFactoryDef = null;
79676  Object.defineProperty(type, NG_FACTORY_DEF, {
79677    get: () => {
79678      if (ngFactoryDef === null) {
79679        const meta = getDirectiveMetadata(type, metadata);
79680        const compiler = getCompilerFacade({
79681          usage: 0
79682          /* JitCompilerUsage.Decorator */
79683          ,
79684          kind: 'directive',
79685          type
79686        });
79687        ngFactoryDef = compiler.compileFactory(angularCoreEnv, `ng:///${type.name}/ɵfac.js`, {
79688          name: meta.metadata.name,
79689          type: meta.metadata.type,
79690          typeArgumentCount: 0,
79691          deps: reflectDependencies(type),
79692          target: compiler.FactoryTarget.Directive
79693        });
79694      }
79695
79696      return ngFactoryDef;
79697    },
79698    // Make the property configurable in dev mode to allow overriding in tests
79699    configurable: !!ngDevMode
79700  });
79701}
79702
79703function extendsDirectlyFromObject(type) {
79704  return Object.getPrototypeOf(type.prototype) === Object.prototype;
79705}
79706/**
79707 * Extract the `R3DirectiveMetadata` for a particular directive (either a `Directive` or a
79708 * `Component`).
79709 */
79710
79711
79712function directiveMetadata(type, metadata) {
79713  // Reflect inputs and outputs.
79714  const reflect = getReflect();
79715  const propMetadata = reflect.ownPropMetadata(type);
79716  return {
79717    name: type.name,
79718    type: type,
79719    selector: metadata.selector !== undefined ? metadata.selector : null,
79720    host: metadata.host || EMPTY_OBJ,
79721    propMetadata: propMetadata,
79722    inputs: metadata.inputs || EMPTY_ARRAY,
79723    outputs: metadata.outputs || EMPTY_ARRAY,
79724    queries: extractQueriesMetadata(type, propMetadata, isContentQuery),
79725    lifecycle: {
79726      usesOnChanges: reflect.hasLifecycleHook(type, 'ngOnChanges')
79727    },
79728    typeSourceSpan: null,
79729    usesInheritance: !extendsDirectlyFromObject(type),
79730    exportAs: extractExportAs(metadata.exportAs),
79731    providers: metadata.providers || null,
79732    viewQueries: extractQueriesMetadata(type, propMetadata, isViewQuery),
79733    isStandalone: !!metadata.standalone
79734  };
79735}
79736/**
79737 * Adds a directive definition to all parent classes of a type that don't have an Angular decorator.
79738 */
79739
79740
79741function addDirectiveDefToUndecoratedParents(type) {
79742  const objPrototype = Object.prototype;
79743  let parent = Object.getPrototypeOf(type.prototype).constructor; // Go up the prototype until we hit `Object`.
79744
79745  while (parent && parent !== objPrototype) {
79746    // Since inheritance works if the class was annotated already, we only need to add
79747    // the def if there are no annotations and the def hasn't been created already.
79748    if (!getDirectiveDef(parent) && !getComponentDef(parent) && shouldAddAbstractDirective(parent)) {
79749      compileDirective(parent, null);
79750    }
79751
79752    parent = Object.getPrototypeOf(parent);
79753  }
79754}
79755
79756function convertToR3QueryPredicate(selector) {
79757  return typeof selector === 'string' ? splitByComma(selector) : resolveForwardRef(selector);
79758}
79759
79760function convertToR3QueryMetadata(propertyName, ann) {
79761  return {
79762    propertyName: propertyName,
79763    predicate: convertToR3QueryPredicate(ann.selector),
79764    descendants: ann.descendants,
79765    first: ann.first,
79766    read: ann.read ? ann.read : null,
79767    static: !!ann.static,
79768    emitDistinctChangesOnly: !!ann.emitDistinctChangesOnly
79769  };
79770}
79771
79772function extractQueriesMetadata(type, propMetadata, isQueryAnn) {
79773  const queriesMeta = [];
79774
79775  for (const field in propMetadata) {
79776    if (propMetadata.hasOwnProperty(field)) {
79777      const annotations = propMetadata[field];
79778      annotations.forEach(ann => {
79779        if (isQueryAnn(ann)) {
79780          if (!ann.selector) {
79781            throw new Error(`Can't construct a query for the property "${field}" of ` + `"${stringifyForError(type)}" since the query selector wasn't defined.`);
79782          }
79783
79784          if (annotations.some(isInputAnnotation)) {
79785            throw new Error(`Cannot combine @Input decorators with query decorators`);
79786          }
79787
79788          queriesMeta.push(convertToR3QueryMetadata(field, ann));
79789        }
79790      });
79791    }
79792  }
79793
79794  return queriesMeta;
79795}
79796
79797function extractExportAs(exportAs) {
79798  return exportAs === undefined ? null : splitByComma(exportAs);
79799}
79800
79801function isContentQuery(value) {
79802  const name = value.ngMetadataName;
79803  return name === 'ContentChild' || name === 'ContentChildren';
79804}
79805
79806function isViewQuery(value) {
79807  const name = value.ngMetadataName;
79808  return name === 'ViewChild' || name === 'ViewChildren';
79809}
79810
79811function isInputAnnotation(value) {
79812  return value.ngMetadataName === 'Input';
79813}
79814
79815function splitByComma(value) {
79816  return value.split(',').map(piece => piece.trim());
79817}
79818
79819const LIFECYCLE_HOOKS = ['ngOnChanges', 'ngOnInit', 'ngOnDestroy', 'ngDoCheck', 'ngAfterViewInit', 'ngAfterViewChecked', 'ngAfterContentInit', 'ngAfterContentChecked'];
79820
79821function shouldAddAbstractDirective(type) {
79822  const reflect = getReflect();
79823
79824  if (LIFECYCLE_HOOKS.some(hookName => reflect.hasLifecycleHook(type, hookName))) {
79825    return true;
79826  }
79827
79828  const propMetadata = reflect.propMetadata(type);
79829
79830  for (const field in propMetadata) {
79831    const annotations = propMetadata[field];
79832
79833    for (let i = 0; i < annotations.length; i++) {
79834      const current = annotations[i];
79835      const metadataName = current.ngMetadataName;
79836
79837      if (isInputAnnotation(current) || isContentQuery(current) || isViewQuery(current) || metadataName === 'Output' || metadataName === 'HostBinding' || metadataName === 'HostListener') {
79838        return true;
79839      }
79840    }
79841  }
79842
79843  return false;
79844}
79845/**
79846 * @license
79847 * Copyright Google LLC All Rights Reserved.
79848 *
79849 * Use of this source code is governed by an MIT-style license that can be
79850 * found in the LICENSE file at https://angular.io/license
79851 */
79852
79853
79854function compilePipe(type, meta) {
79855  let ngPipeDef = null;
79856  let ngFactoryDef = null;
79857  Object.defineProperty(type, NG_FACTORY_DEF, {
79858    get: () => {
79859      if (ngFactoryDef === null) {
79860        const metadata = getPipeMetadata(type, meta);
79861        const compiler = getCompilerFacade({
79862          usage: 0
79863          /* JitCompilerUsage.Decorator */
79864          ,
79865          kind: 'pipe',
79866          type: metadata.type
79867        });
79868        ngFactoryDef = compiler.compileFactory(angularCoreEnv, `ng:///${metadata.name}/ɵfac.js`, {
79869          name: metadata.name,
79870          type: metadata.type,
79871          typeArgumentCount: 0,
79872          deps: reflectDependencies(type),
79873          target: compiler.FactoryTarget.Pipe
79874        });
79875      }
79876
79877      return ngFactoryDef;
79878    },
79879    // Make the property configurable in dev mode to allow overriding in tests
79880    configurable: !!ngDevMode
79881  });
79882  Object.defineProperty(type, NG_PIPE_DEF, {
79883    get: () => {
79884      if (ngPipeDef === null) {
79885        const metadata = getPipeMetadata(type, meta);
79886        const compiler = getCompilerFacade({
79887          usage: 0
79888          /* JitCompilerUsage.Decorator */
79889          ,
79890          kind: 'pipe',
79891          type: metadata.type
79892        });
79893        ngPipeDef = compiler.compilePipe(angularCoreEnv, `ng:///${metadata.name}/ɵpipe.js`, metadata);
79894      }
79895
79896      return ngPipeDef;
79897    },
79898    // Make the property configurable in dev mode to allow overriding in tests
79899    configurable: !!ngDevMode
79900  });
79901}
79902
79903function getPipeMetadata(type, meta) {
79904  return {
79905    type: type,
79906    name: type.name,
79907    pipeName: meta.name,
79908    pure: meta.pure !== undefined ? meta.pure : true,
79909    isStandalone: !!meta.standalone
79910  };
79911}
79912/**
79913 * @license
79914 * Copyright Google LLC All Rights Reserved.
79915 *
79916 * Use of this source code is governed by an MIT-style license that can be
79917 * found in the LICENSE file at https://angular.io/license
79918 */
79919
79920/**
79921 * Type of the Directive metadata.
79922 *
79923 * @publicApi
79924 */
79925
79926
79927const Directive = makeDecorator('Directive', (dir = {}) => dir, undefined, undefined, (type, meta) => compileDirective(type, meta));
79928/**
79929 * Component decorator and metadata.
79930 *
79931 * @Annotation
79932 * @publicApi
79933 */
79934
79935const Component = makeDecorator('Component', (c = {}) => ({
79936  changeDetection: ChangeDetectionStrategy.Default,
79937  ...c
79938}), Directive, undefined, (type, meta) => compileComponent(type, meta));
79939/**
79940 * @Annotation
79941 * @publicApi
79942 */
79943
79944const Pipe = makeDecorator('Pipe', p => ({
79945  pure: true,
79946  ...p
79947}), undefined, undefined, (type, meta) => compilePipe(type, meta));
79948/**
79949 * @Annotation
79950 * @publicApi
79951 */
79952
79953const Input = makePropDecorator('Input', bindingPropertyName => ({
79954  bindingPropertyName
79955}));
79956/**
79957 * @Annotation
79958 * @publicApi
79959 */
79960
79961const Output = makePropDecorator('Output', bindingPropertyName => ({
79962  bindingPropertyName
79963}));
79964/**
79965 * @Annotation
79966 * @publicApi
79967 */
79968
79969const HostBinding = makePropDecorator('HostBinding', hostPropertyName => ({
79970  hostPropertyName
79971}));
79972/**
79973 * Decorator that binds a DOM event to a host listener and supplies configuration metadata.
79974 * Angular invokes the supplied handler method when the host element emits the specified event,
79975 * and updates the bound element with the result.
79976 *
79977 * If the handler method returns false, applies `preventDefault` on the bound element.
79978 *
79979 * @usageNotes
79980 *
79981 * The following example declares a directive
79982 * that attaches a click listener to a button and counts clicks.
79983 *
79984 * ```ts
79985 * @Directive({selector: 'button[counting]'})
79986 * class CountClicks {
79987 *   numberOfClicks = 0;
79988 *
79989 *   @HostListener('click', ['$event.target'])
79990 *   onClick(btn) {
79991 *     console.log('button', btn, 'number of clicks:', this.numberOfClicks++);
79992 *   }
79993 * }
79994 *
79995 * @Component({
79996 *   selector: 'app',
79997 *   template: '<button counting>Increment</button>',
79998 * })
79999 * class App {}
80000 *
80001 * ```
80002 *
80003 * The following example registers another DOM event handler that listens for `Enter` key-press
80004 * events on the global `window`.
80005 * ``` ts
80006 * import { HostListener, Component } from "@angular/core";
80007 *
80008 * @Component({
80009 *   selector: 'app',
80010 *   template: `<h1>Hello, you have pressed enter {{counter}} number of times!</h1> Press enter key
80011 * to increment the counter.
80012 *   <button (click)="resetCounter()">Reset Counter</button>`
80013 * })
80014 * class AppComponent {
80015 *   counter = 0;
80016 *   @HostListener('window:keydown.enter', ['$event'])
80017 *   handleKeyDown(event: KeyboardEvent) {
80018 *     this.counter++;
80019 *   }
80020 *   resetCounter() {
80021 *     this.counter = 0;
80022 *   }
80023 * }
80024 * ```
80025 * The list of valid key names for `keydown` and `keyup` events
80026 * can be found here:
80027 * https://www.w3.org/TR/DOM-Level-3-Events-key/#named-key-attribute-values
80028 *
80029 * Note that keys can also be combined, e.g. `@HostListener('keydown.shift.a')`.
80030 *
80031 * The global target names that can be used to prefix an event name are
80032 * `document:`, `window:` and `body:`.
80033 *
80034 * @Annotation
80035 * @publicApi
80036 */
80037
80038const HostListener = makePropDecorator('HostListener', (eventName, args) => ({
80039  eventName,
80040  args
80041}));
80042/**
80043 * @license
80044 * Copyright Google LLC All Rights Reserved.
80045 *
80046 * Use of this source code is governed by an MIT-style license that can be
80047 * found in the LICENSE file at https://angular.io/license
80048 */
80049
80050/**
80051 * @Annotation
80052 * @publicApi
80053 */
80054
80055const NgModule = makeDecorator('NgModule', ngModule => ngModule, undefined, undefined,
80056/**
80057 * Decorator that marks the following class as an NgModule, and supplies
80058 * configuration metadata for it.
80059 *
80060 * * The `declarations` and `entryComponents` options configure the compiler
80061 * with information about what belongs to the NgModule.
80062 * * The `providers` options configures the NgModule's injector to provide
80063 * dependencies the NgModule members.
80064 * * The `imports` and `exports` options bring in members from other modules, and make
80065 * this module's members available to others.
80066 */
80067(type, meta) => compileNgModule(type, meta));
80068/**
80069 * @license
80070 * Copyright Google LLC All Rights Reserved.
80071 *
80072 * Use of this source code is governed by an MIT-style license that can be
80073 * found in the LICENSE file at https://angular.io/license
80074 */
80075
80076/**
80077 * @license
80078 * Copyright Google LLC All Rights Reserved.
80079 *
80080 * Use of this source code is governed by an MIT-style license that can be
80081 * found in the LICENSE file at https://angular.io/license
80082 */
80083
80084/**
80085 * @license
80086 * Copyright Google LLC All Rights Reserved.
80087 *
80088 * Use of this source code is governed by an MIT-style license that can be
80089 * found in the LICENSE file at https://angular.io/license
80090 */
80091
80092function noop(...args) {// Do nothing.
80093}
80094/**
80095 * @license
80096 * Copyright Google LLC All Rights Reserved.
80097 *
80098 * Use of this source code is governed by an MIT-style license that can be
80099 * found in the LICENSE file at https://angular.io/license
80100 */
80101
80102/**
80103 * The existence of this constant (in this particular file) informs the Angular compiler that the
80104 * current program is actually @angular/core, which needs to be compiled specially.
80105 */
80106
80107
80108const ITS_JUST_ANGULAR = true;
80109/**
80110 * A [DI token](guide/glossary#di-token "DI token definition") that you can use to provide
80111 * one or more initialization functions.
80112 *
80113 * The provided functions are injected at application startup and executed during
80114 * app initialization. If any of these functions returns a Promise or an Observable, initialization
80115 * does not complete until the Promise is resolved or the Observable is completed.
80116 *
80117 * You can, for example, create a factory function that loads language data
80118 * or an external configuration, and provide that function to the `APP_INITIALIZER` token.
80119 * The function is executed during the application bootstrap process,
80120 * and the needed data is available on startup.
80121 *
80122 * @see `ApplicationInitStatus`
80123 *
80124 * @usageNotes
80125 *
80126 * The following example illustrates how to configure a multi-provider using `APP_INITIALIZER` token
80127 * and a function returning a promise.
80128 *
80129 * ```
80130 *  function initializeApp(): Promise<any> {
80131 *    return new Promise((resolve, reject) => {
80132 *      // Do some asynchronous stuff
80133 *      resolve();
80134 *    });
80135 *  }
80136 *
80137 *  @NgModule({
80138 *   imports: [BrowserModule],
80139 *   declarations: [AppComponent],
80140 *   bootstrap: [AppComponent],
80141 *   providers: [{
80142 *     provide: APP_INITIALIZER,
80143 *     useFactory: () => initializeApp,
80144 *     multi: true
80145 *    }]
80146 *   })
80147 *  export class AppModule {}
80148 * ```
80149 *
80150 * It's also possible to configure a multi-provider using `APP_INITIALIZER` token and a function
80151 * returning an observable, see an example below. Note: the `HttpClient` in this example is used for
80152 * demo purposes to illustrate how the factory function can work with other providers available
80153 * through DI.
80154 *
80155 * ```
80156 *  function initializeAppFactory(httpClient: HttpClient): () => Observable<any> {
80157 *   return () => httpClient.get("https://someUrl.com/api/user")
80158 *     .pipe(
80159 *        tap(user => { ... })
80160 *     );
80161 *  }
80162 *
80163 *  @NgModule({
80164 *    imports: [BrowserModule, HttpClientModule],
80165 *    declarations: [AppComponent],
80166 *    bootstrap: [AppComponent],
80167 *    providers: [{
80168 *      provide: APP_INITIALIZER,
80169 *      useFactory: initializeAppFactory,
80170 *      deps: [HttpClient],
80171 *      multi: true
80172 *    }]
80173 *  })
80174 *  export class AppModule {}
80175 * ```
80176 *
80177 * @publicApi
80178 */
80179
80180const APP_INITIALIZER = new InjectionToken('Application Initializer');
80181/**
80182 * A class that reflects the state of running {@link APP_INITIALIZER} functions.
80183 *
80184 * @publicApi
80185 */
80186
80187class ApplicationInitStatus {
80188  constructor(appInits) {
80189    this.appInits = appInits;
80190    this.resolve = noop;
80191    this.reject = noop;
80192    this.initialized = false;
80193    this.done = false;
80194    this.donePromise = new Promise((res, rej) => {
80195      this.resolve = res;
80196      this.reject = rej;
80197    });
80198  }
80199  /** @internal */
80200
80201
80202  runInitializers() {
80203    if (this.initialized) {
80204      return;
80205    }
80206
80207    const asyncInitPromises = [];
80208
80209    const complete = () => {
80210      this.done = true;
80211      this.resolve();
80212    };
80213
80214    if (this.appInits) {
80215      for (let i = 0; i < this.appInits.length; i++) {
80216        const initResult = this.appInits[i]();
80217
80218        if (isPromise(initResult)) {
80219          asyncInitPromises.push(initResult);
80220        } else if (isObservable(initResult)) {
80221          const observableAsPromise = new Promise((resolve, reject) => {
80222            initResult.subscribe({
80223              complete: resolve,
80224              error: reject
80225            });
80226          });
80227          asyncInitPromises.push(observableAsPromise);
80228        }
80229      }
80230    }
80231
80232    Promise.all(asyncInitPromises).then(() => {
80233      complete();
80234    }).catch(e => {
80235      this.reject(e);
80236    });
80237
80238    if (asyncInitPromises.length === 0) {
80239      complete();
80240    }
80241
80242    this.initialized = true;
80243  }
80244
80245}
80246
80247ApplicationInitStatus.ɵfac = function ApplicationInitStatus_Factory(t) {
80248  return new (t || ApplicationInitStatus)(ɵɵinject(APP_INITIALIZER, 8));
80249};
80250
80251ApplicationInitStatus.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
80252  token: ApplicationInitStatus,
80253  factory: ApplicationInitStatus.ɵfac,
80254  providedIn: 'root'
80255});
80256
80257(function () {
80258  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ApplicationInitStatus, [{
80259    type: Injectable,
80260    args: [{
80261      providedIn: 'root'
80262    }]
80263  }], function () {
80264    return [{
80265      type: undefined,
80266      decorators: [{
80267        type: Inject,
80268        args: [APP_INITIALIZER]
80269      }, {
80270        type: Optional
80271      }]
80272    }];
80273  }, null);
80274})();
80275/**
80276 * @license
80277 * Copyright Google LLC All Rights Reserved.
80278 *
80279 * Use of this source code is governed by an MIT-style license that can be
80280 * found in the LICENSE file at https://angular.io/license
80281 */
80282
80283/**
80284 * A [DI token](guide/glossary#di-token "DI token definition") representing a unique string ID, used
80285 * primarily for prefixing application attributes and CSS styles when
80286 * {@link ViewEncapsulation#Emulated ViewEncapsulation.Emulated} is being used.
80287 *
80288 * BY default, the value is randomly generated and assigned to the application by Angular.
80289 * To provide a custom ID value, use a DI provider <!-- TODO: provider --> to configure
80290 * the root {@link Injector} that uses this token.
80291 *
80292 * @publicApi
80293 */
80294
80295
80296const APP_ID = new InjectionToken('AppId', {
80297  providedIn: 'root',
80298  factory: _appIdRandomProviderFactory
80299});
80300
80301function _appIdRandomProviderFactory() {
80302  return `${_randomChar()}${_randomChar()}${_randomChar()}`;
80303}
80304/**
80305 * Providers that generate a random `APP_ID_TOKEN`.
80306 * @publicApi
80307 */
80308
80309
80310const APP_ID_RANDOM_PROVIDER = {
80311  provide: APP_ID,
80312  useFactory: _appIdRandomProviderFactory,
80313  deps: []
80314};
80315
80316function _randomChar() {
80317  return String.fromCharCode(97 + Math.floor(Math.random() * 25));
80318}
80319/**
80320 * A function that is executed when a platform is initialized.
80321 * @publicApi
80322 */
80323
80324
80325const PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
80326/**
80327 * A token that indicates an opaque platform ID.
80328 * @publicApi
80329 */
80330
80331const PLATFORM_ID = new InjectionToken('Platform ID', {
80332  providedIn: 'platform',
80333  factory: () => 'unknown' // set a default platform name, when none set explicitly
80334
80335});
80336/**
80337 * A [DI token](guide/glossary#di-token "DI token definition") that provides a set of callbacks to
80338 * be called for every component that is bootstrapped.
80339 *
80340 * Each callback must take a `ComponentRef` instance and return nothing.
80341 *
80342 * `(componentRef: ComponentRef) => void`
80343 *
80344 * @publicApi
80345 */
80346
80347const APP_BOOTSTRAP_LISTENER = new InjectionToken('appBootstrapListener');
80348/**
80349 * A [DI token](guide/glossary#di-token "DI token definition") that indicates the root directory of
80350 * the application
80351 * @publicApi
80352 */
80353
80354const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL'); // We keep this token here, rather than the animations package, so that modules that only care
80355// about which animations module is loaded (e.g. the CDK) can retrieve it without having to
80356// include extra dependencies. See #44970 for more context.
80357
80358/**
80359 * A [DI token](guide/glossary#di-token "DI token definition") that indicates which animations
80360 * module has been loaded.
80361 * @publicApi
80362 */
80363
80364const ANIMATION_MODULE_TYPE = new InjectionToken('AnimationModuleType');
80365/**
80366 * @license
80367 * Copyright Google LLC All Rights Reserved.
80368 *
80369 * Use of this source code is governed by an MIT-style license that can be
80370 * found in the LICENSE file at https://angular.io/license
80371 */
80372
80373class Console {
80374  log(message) {
80375    // tslint:disable-next-line:no-console
80376    console.log(message);
80377  } // Note: for reporting errors use `DOM.logError()` as it is platform specific
80378
80379
80380  warn(message) {
80381    // tslint:disable-next-line:no-console
80382    console.warn(message);
80383  }
80384
80385}
80386
80387Console.ɵfac = function Console_Factory(t) {
80388  return new (t || Console)();
80389};
80390
80391Console.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
80392  token: Console,
80393  factory: Console.ɵfac,
80394  providedIn: 'platform'
80395});
80396
80397(function () {
80398  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(Console, [{
80399    type: Injectable,
80400    args: [{
80401      providedIn: 'platform'
80402    }]
80403  }], null, null);
80404})();
80405/**
80406 * @license
80407 * Copyright Google LLC All Rights Reserved.
80408 *
80409 * Use of this source code is governed by an MIT-style license that can be
80410 * found in the LICENSE file at https://angular.io/license
80411 */
80412
80413/**
80414 * Work out the locale from the potential global properties.
80415 *
80416 * * Closure Compiler: use `goog.LOCALE`.
80417 * * Ivy enabled: use `$localize.locale`
80418 */
80419
80420
80421function getGlobalLocale() {
80422  if (typeof ngI18nClosureMode !== 'undefined' && ngI18nClosureMode && typeof goog !== 'undefined' && goog.LOCALE !== 'en') {
80423    // * The default `goog.LOCALE` value is `en`, while Angular used `en-US`.
80424    // * In order to preserve backwards compatibility, we use Angular default value over
80425    //   Closure Compiler's one.
80426    return goog.LOCALE;
80427  } else {
80428    // KEEP `typeof $localize !== 'undefined' && $localize.locale` IN SYNC WITH THE LOCALIZE
80429    // COMPILE-TIME INLINER.
80430    //
80431    // * During compile time inlining of translations the expression will be replaced
80432    //   with a string literal that is the current locale. Other forms of this expression are not
80433    //   guaranteed to be replaced.
80434    //
80435    // * During runtime translation evaluation, the developer is required to set `$localize.locale`
80436    //   if required, or just to provide their own `LOCALE_ID` provider.
80437    return typeof $localize !== 'undefined' && $localize.locale || DEFAULT_LOCALE_ID;
80438  }
80439}
80440/**
80441 * Provide this token to set the locale of your application.
80442 * It is used for i18n extraction, by i18n pipes (DatePipe, I18nPluralPipe, CurrencyPipe,
80443 * DecimalPipe and PercentPipe) and by ICU expressions.
80444 *
80445 * See the [i18n guide](guide/i18n-common-locale-id) for more information.
80446 *
80447 * @usageNotes
80448 * ### Example
80449 *
80450 * ```typescript
80451 * import { LOCALE_ID } from '@angular/core';
80452 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
80453 * import { AppModule } from './app/app.module';
80454 *
80455 * platformBrowserDynamic().bootstrapModule(AppModule, {
80456 *   providers: [{provide: LOCALE_ID, useValue: 'en-US' }]
80457 * });
80458 * ```
80459 *
80460 * @publicApi
80461 */
80462
80463
80464const LOCALE_ID = new InjectionToken('LocaleId', {
80465  providedIn: 'root',
80466  factory: () => inject(LOCALE_ID, InjectFlags.Optional | InjectFlags.SkipSelf) || getGlobalLocale()
80467});
80468/**
80469 * Provide this token to set the default currency code your application uses for
80470 * CurrencyPipe when there is no currency code passed into it. This is only used by
80471 * CurrencyPipe and has no relation to locale currency. Defaults to USD if not configured.
80472 *
80473 * See the [i18n guide](guide/i18n-common-locale-id) for more information.
80474 *
80475 * <div class="alert is-helpful">
80476 *
80477 * **Deprecation notice:**
80478 *
80479 * The default currency code is currently always `USD` but this is deprecated from v9.
80480 *
80481 * **In v10 the default currency code will be taken from the current locale.**
80482 *
80483 * If you need the previous behavior then set it by creating a `DEFAULT_CURRENCY_CODE` provider in
80484 * your application `NgModule`:
80485 *
80486 * ```ts
80487 * {provide: DEFAULT_CURRENCY_CODE, useValue: 'USD'}
80488 * ```
80489 *
80490 * </div>
80491 *
80492 * @usageNotes
80493 * ### Example
80494 *
80495 * ```typescript
80496 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
80497 * import { AppModule } from './app/app.module';
80498 *
80499 * platformBrowserDynamic().bootstrapModule(AppModule, {
80500 *   providers: [{provide: DEFAULT_CURRENCY_CODE, useValue: 'EUR' }]
80501 * });
80502 * ```
80503 *
80504 * @publicApi
80505 */
80506
80507const DEFAULT_CURRENCY_CODE = new InjectionToken('DefaultCurrencyCode', {
80508  providedIn: 'root',
80509  factory: () => USD_CURRENCY_CODE
80510});
80511/**
80512 * Use this token at bootstrap to provide the content of your translation file (`xtb`,
80513 * `xlf` or `xlf2`) when you want to translate your application in another language.
80514 *
80515 * See the [i18n guide](guide/i18n-common-merge) for more information.
80516 *
80517 * @usageNotes
80518 * ### Example
80519 *
80520 * ```typescript
80521 * import { TRANSLATIONS } from '@angular/core';
80522 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
80523 * import { AppModule } from './app/app.module';
80524 *
80525 * // content of your translation file
80526 * const translations = '....';
80527 *
80528 * platformBrowserDynamic().bootstrapModule(AppModule, {
80529 *   providers: [{provide: TRANSLATIONS, useValue: translations }]
80530 * });
80531 * ```
80532 *
80533 * @publicApi
80534 */
80535
80536const TRANSLATIONS = new InjectionToken('Translations');
80537/**
80538 * Provide this token at bootstrap to set the format of your {@link TRANSLATIONS}: `xtb`,
80539 * `xlf` or `xlf2`.
80540 *
80541 * See the [i18n guide](guide/i18n-common-merge) for more information.
80542 *
80543 * @usageNotes
80544 * ### Example
80545 *
80546 * ```typescript
80547 * import { TRANSLATIONS_FORMAT } from '@angular/core';
80548 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
80549 * import { AppModule } from './app/app.module';
80550 *
80551 * platformBrowserDynamic().bootstrapModule(AppModule, {
80552 *   providers: [{provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }]
80553 * });
80554 * ```
80555 *
80556 * @publicApi
80557 */
80558
80559const TRANSLATIONS_FORMAT = new InjectionToken('TranslationsFormat');
80560/**
80561 * Use this enum at bootstrap as an option of `bootstrapModule` to define the strategy
80562 * that the compiler should use in case of missing translations:
80563 * - Error: throw if you have missing translations.
80564 * - Warning (default): show a warning in the console and/or shell.
80565 * - Ignore: do nothing.
80566 *
80567 * See the [i18n guide](guide/i18n-common-merge#report-missing-translations) for more information.
80568 *
80569 * @usageNotes
80570 * ### Example
80571 * ```typescript
80572 * import { MissingTranslationStrategy } from '@angular/core';
80573 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
80574 * import { AppModule } from './app/app.module';
80575 *
80576 * platformBrowserDynamic().bootstrapModule(AppModule, {
80577 *   missingTranslation: MissingTranslationStrategy.Error
80578 * });
80579 * ```
80580 *
80581 * @publicApi
80582 */
80583
80584var MissingTranslationStrategy;
80585
80586(function (MissingTranslationStrategy) {
80587  MissingTranslationStrategy[MissingTranslationStrategy["Error"] = 0] = "Error";
80588  MissingTranslationStrategy[MissingTranslationStrategy["Warning"] = 1] = "Warning";
80589  MissingTranslationStrategy[MissingTranslationStrategy["Ignore"] = 2] = "Ignore";
80590})(MissingTranslationStrategy || (MissingTranslationStrategy = {}));
80591/**
80592 * @license
80593 * Copyright Google LLC All Rights Reserved.
80594 *
80595 * Use of this source code is governed by an MIT-style license that can be
80596 * found in the LICENSE file at https://angular.io/license
80597 */
80598
80599/**
80600 * Combination of NgModuleFactory and ComponentFactories.
80601 *
80602 * @publicApi
80603 *
80604 * @deprecated
80605 * Ivy JIT mode doesn't require accessing this symbol.
80606 * See [JIT API changes due to ViewEngine deprecation](guide/deprecations#jit-api-changes) for
80607 * additional context.
80608 */
80609
80610
80611class ModuleWithComponentFactories {
80612  constructor(ngModuleFactory, componentFactories) {
80613    this.ngModuleFactory = ngModuleFactory;
80614    this.componentFactories = componentFactories;
80615  }
80616
80617}
80618/**
80619 * Low-level service for running the angular compiler during runtime
80620 * to create {@link ComponentFactory}s, which
80621 * can later be used to create and render a Component instance.
80622 *
80623 * Each `@NgModule` provides an own `Compiler` to its injector,
80624 * that will use the directives/pipes of the ng module for compilation
80625 * of components.
80626 *
80627 * @publicApi
80628 *
80629 * @deprecated
80630 * Ivy JIT mode doesn't require accessing this symbol.
80631 * See [JIT API changes due to ViewEngine deprecation](guide/deprecations#jit-api-changes) for
80632 * additional context.
80633 */
80634
80635
80636class Compiler {
80637  /**
80638   * Compiles the given NgModule and all of its components. All templates of the components listed
80639   * in `entryComponents` have to be inlined.
80640   */
80641  compileModuleSync(moduleType) {
80642    return new NgModuleFactory(moduleType);
80643  }
80644  /**
80645   * Compiles the given NgModule and all of its components
80646   */
80647
80648
80649  compileModuleAsync(moduleType) {
80650    return Promise.resolve(this.compileModuleSync(moduleType));
80651  }
80652  /**
80653   * Same as {@link #compileModuleSync} but also creates ComponentFactories for all components.
80654   */
80655
80656
80657  compileModuleAndAllComponentsSync(moduleType) {
80658    const ngModuleFactory = this.compileModuleSync(moduleType);
80659    const moduleDef = getNgModuleDef(moduleType);
80660    const componentFactories = maybeUnwrapFn(moduleDef.declarations).reduce((factories, declaration) => {
80661      const componentDef = getComponentDef(declaration);
80662      componentDef && factories.push(new ComponentFactory(componentDef));
80663      return factories;
80664    }, []);
80665    return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
80666  }
80667  /**
80668   * Same as {@link #compileModuleAsync} but also creates ComponentFactories for all components.
80669   */
80670
80671
80672  compileModuleAndAllComponentsAsync(moduleType) {
80673    return Promise.resolve(this.compileModuleAndAllComponentsSync(moduleType));
80674  }
80675  /**
80676   * Clears all caches.
80677   */
80678
80679
80680  clearCache() {}
80681  /**
80682   * Clears the cache for the given component/ngModule.
80683   */
80684
80685
80686  clearCacheFor(type) {}
80687  /**
80688   * Returns the id for a given NgModule, if one is defined and known to the compiler.
80689   */
80690
80691
80692  getModuleId(moduleType) {
80693    return undefined;
80694  }
80695
80696}
80697
80698Compiler.ɵfac = function Compiler_Factory(t) {
80699  return new (t || Compiler)();
80700};
80701
80702Compiler.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
80703  token: Compiler,
80704  factory: Compiler.ɵfac,
80705  providedIn: 'root'
80706});
80707
80708(function () {
80709  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(Compiler, [{
80710    type: Injectable,
80711    args: [{
80712      providedIn: 'root'
80713    }]
80714  }], null, null);
80715})();
80716/**
80717 * Token to provide CompilerOptions in the platform injector.
80718 *
80719 * @publicApi
80720 */
80721
80722
80723const COMPILER_OPTIONS = new InjectionToken('compilerOptions');
80724/**
80725 * A factory for creating a Compiler
80726 *
80727 * @publicApi
80728 *
80729 * @deprecated
80730 * Ivy JIT mode doesn't require accessing this symbol.
80731 * See [JIT API changes due to ViewEngine deprecation](guide/deprecations#jit-api-changes) for
80732 * additional context.
80733 */
80734
80735class CompilerFactory {}
80736/**
80737 * @license
80738 * Copyright Google LLC All Rights Reserved.
80739 *
80740 * Use of this source code is governed by an MIT-style license that can be
80741 * found in the LICENSE file at https://angular.io/license
80742 */
80743
80744/**
80745 * Marks a component for check (in case of OnPush components) and synchronously
80746 * performs change detection on the application this component belongs to.
80747 *
80748 * @param component Component to {@link ChangeDetectorRef#markForCheck mark for check}.
80749 *
80750 * @publicApi
80751 * @globalApi ng
80752 */
80753
80754
80755function applyChanges(component) {
80756  ngDevMode && assertDefined(component, 'component');
80757  markViewDirty(getComponentViewByInstance(component));
80758  getRootComponents(component).forEach(rootComponent => detectChanges(rootComponent));
80759}
80760/**
80761 * @license
80762 * Copyright Google LLC All Rights Reserved.
80763 *
80764 * Use of this source code is governed by an MIT-style license that can be
80765 * found in the LICENSE file at https://angular.io/license
80766 */
80767
80768/**
80769 * This file introduces series of globally accessible debug tools
80770 * to allow for the Angular debugging story to function.
80771 *
80772 * To see this in action run the following command:
80773 *
80774 *   bazel run //packages/core/test/bundling/todo:devserver
80775 *
80776 *  Then load `localhost:5432` and start using the console tools.
80777 */
80778
80779/**
80780 * This value reflects the property on the window where the dev
80781 * tools are patched (window.ng).
80782 * */
80783
80784
80785const GLOBAL_PUBLISH_EXPANDO_KEY = 'ng';
80786let _published = false;
80787/**
80788 * Publishes a collection of default debug tools onto`window.ng`.
80789 *
80790 * These functions are available globally when Angular is in development
80791 * mode and are automatically stripped away from prod mode is on.
80792 */
80793
80794function publishDefaultGlobalUtils$1() {
80795  if (!_published) {
80796    _published = true;
80797    /**
80798     * Warning: this function is *INTERNAL* and should not be relied upon in application's code.
80799     * The contract of the function might be changed in any release and/or the function can be
80800     * removed completely.
80801     */
80802
80803    publishGlobalUtil('ɵsetProfiler', setProfiler);
80804    publishGlobalUtil('getDirectiveMetadata', getDirectiveMetadata$1);
80805    publishGlobalUtil('getComponent', getComponent);
80806    publishGlobalUtil('getContext', getContext);
80807    publishGlobalUtil('getListeners', getListeners);
80808    publishGlobalUtil('getOwningComponent', getOwningComponent);
80809    publishGlobalUtil('getHostElement', getHostElement);
80810    publishGlobalUtil('getInjector', getInjector);
80811    publishGlobalUtil('getRootComponents', getRootComponents);
80812    publishGlobalUtil('getDirectives', getDirectives);
80813    publishGlobalUtil('applyChanges', applyChanges);
80814  }
80815}
80816/**
80817 * Publishes the given function to `window.ng` so that it can be
80818 * used from the browser console when an application is not in production.
80819 */
80820
80821
80822function publishGlobalUtil(name, fn) {
80823  if (typeof COMPILED === 'undefined' || !COMPILED) {
80824    // Note: we can't export `ng` when using closure enhanced optimization as:
80825    // - closure declares globals itself for minified names, which sometimes clobber our `ng` global
80826    // - we can't declare a closure extern as the namespace `ng` is already used within Google
80827    //   for typings for AngularJS (via `goog.provide('ng....')`).
80828    const w = _global;
80829    ngDevMode && assertDefined(fn, 'function not defined');
80830
80831    if (w) {
80832      let container = w[GLOBAL_PUBLISH_EXPANDO_KEY];
80833
80834      if (!container) {
80835        container = w[GLOBAL_PUBLISH_EXPANDO_KEY] = {};
80836      }
80837
80838      container[name] = fn;
80839    }
80840  }
80841}
80842/**
80843 * @license
80844 * Copyright Google LLC All Rights Reserved.
80845 *
80846 * Use of this source code is governed by an MIT-style license that can be
80847 * found in the LICENSE file at https://angular.io/license
80848 */
80849
80850
80851const promise = (() => Promise.resolve(0))();
80852
80853function scheduleMicroTask(fn) {
80854  if (typeof Zone === 'undefined') {
80855    // use promise to schedule microTask instead of use Zone
80856    promise.then(() => {
80857      fn && fn.apply(null, null);
80858    });
80859  } else {
80860    Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
80861  }
80862}
80863/**
80864 * @license
80865 * Copyright Google LLC All Rights Reserved.
80866 *
80867 * Use of this source code is governed by an MIT-style license that can be
80868 * found in the LICENSE file at https://angular.io/license
80869 */
80870
80871
80872function getNativeRequestAnimationFrame() {
80873  let nativeRequestAnimationFrame = _global['requestAnimationFrame'];
80874  let nativeCancelAnimationFrame = _global['cancelAnimationFrame'];
80875
80876  if (typeof Zone !== 'undefined' && nativeRequestAnimationFrame && nativeCancelAnimationFrame) {
80877    // use unpatched version of requestAnimationFrame(native delegate) if possible
80878    // to avoid another Change detection
80879    const unpatchedRequestAnimationFrame = nativeRequestAnimationFrame[Zone.__symbol__('OriginalDelegate')];
80880
80881    if (unpatchedRequestAnimationFrame) {
80882      nativeRequestAnimationFrame = unpatchedRequestAnimationFrame;
80883    }
80884
80885    const unpatchedCancelAnimationFrame = nativeCancelAnimationFrame[Zone.__symbol__('OriginalDelegate')];
80886
80887    if (unpatchedCancelAnimationFrame) {
80888      nativeCancelAnimationFrame = unpatchedCancelAnimationFrame;
80889    }
80890  }
80891
80892  return {
80893    nativeRequestAnimationFrame,
80894    nativeCancelAnimationFrame
80895  };
80896}
80897/**
80898 * @license
80899 * Copyright Google LLC All Rights Reserved.
80900 *
80901 * Use of this source code is governed by an MIT-style license that can be
80902 * found in the LICENSE file at https://angular.io/license
80903 */
80904
80905/**
80906 * An injectable service for executing work inside or outside of the Angular zone.
80907 *
80908 * The most common use of this service is to optimize performance when starting a work consisting of
80909 * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
80910 * Angular. Such tasks can be kicked off via {@link #runOutsideAngular} and if needed, these tasks
80911 * can reenter the Angular zone via {@link #run}.
80912 *
80913 * <!-- TODO: add/fix links to:
80914 *   - docs explaining zones and the use of zones in Angular and change-detection
80915 *   - link to runOutsideAngular/run (throughout this file!)
80916 *   -->
80917 *
80918 * @usageNotes
80919 * ### Example
80920 *
80921 * ```
80922 * import {Component, NgZone} from '@angular/core';
80923 * import {NgIf} from '@angular/common';
80924 *
80925 * @Component({
80926 *   selector: 'ng-zone-demo',
80927 *   template: `
80928 *     <h2>Demo: NgZone</h2>
80929 *
80930 *     <p>Progress: {{progress}}%</p>
80931 *     <p *ngIf="progress >= 100">Done processing {{label}} of Angular zone!</p>
80932 *
80933 *     <button (click)="processWithinAngularZone()">Process within Angular zone</button>
80934 *     <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
80935 *   `,
80936 * })
80937 * export class NgZoneDemo {
80938 *   progress: number = 0;
80939 *   label: string;
80940 *
80941 *   constructor(private _ngZone: NgZone) {}
80942 *
80943 *   // Loop inside the Angular zone
80944 *   // so the UI DOES refresh after each setTimeout cycle
80945 *   processWithinAngularZone() {
80946 *     this.label = 'inside';
80947 *     this.progress = 0;
80948 *     this._increaseProgress(() => console.log('Inside Done!'));
80949 *   }
80950 *
80951 *   // Loop outside of the Angular zone
80952 *   // so the UI DOES NOT refresh after each setTimeout cycle
80953 *   processOutsideOfAngularZone() {
80954 *     this.label = 'outside';
80955 *     this.progress = 0;
80956 *     this._ngZone.runOutsideAngular(() => {
80957 *       this._increaseProgress(() => {
80958 *         // reenter the Angular zone and display done
80959 *         this._ngZone.run(() => { console.log('Outside Done!'); });
80960 *       });
80961 *     });
80962 *   }
80963 *
80964 *   _increaseProgress(doneCallback: () => void) {
80965 *     this.progress += 1;
80966 *     console.log(`Current progress: ${this.progress}%`);
80967 *
80968 *     if (this.progress < 100) {
80969 *       window.setTimeout(() => this._increaseProgress(doneCallback), 10);
80970 *     } else {
80971 *       doneCallback();
80972 *     }
80973 *   }
80974 * }
80975 * ```
80976 *
80977 * @publicApi
80978 */
80979
80980
80981class NgZone {
80982  constructor({
80983    enableLongStackTrace = false,
80984    shouldCoalesceEventChangeDetection = false,
80985    shouldCoalesceRunChangeDetection = false
80986  }) {
80987    this.hasPendingMacrotasks = false;
80988    this.hasPendingMicrotasks = false;
80989    /**
80990     * Whether there are no outstanding microtasks or macrotasks.
80991     */
80992
80993    this.isStable = true;
80994    /**
80995     * Notifies when code enters Angular Zone. This gets fired first on VM Turn.
80996     */
80997
80998    this.onUnstable = new EventEmitter(false);
80999    /**
81000     * Notifies when there is no more microtasks enqueued in the current VM Turn.
81001     * This is a hint for Angular to do change detection, which may enqueue more microtasks.
81002     * For this reason this event can fire multiple times per VM Turn.
81003     */
81004
81005    this.onMicrotaskEmpty = new EventEmitter(false);
81006    /**
81007     * Notifies when the last `onMicrotaskEmpty` has run and there are no more microtasks, which
81008     * implies we are about to relinquish VM turn.
81009     * This event gets called just once.
81010     */
81011
81012    this.onStable = new EventEmitter(false);
81013    /**
81014     * Notifies that an error has been delivered.
81015     */
81016
81017    this.onError = new EventEmitter(false);
81018
81019    if (typeof Zone == 'undefined') {
81020      throw new RuntimeError(908
81021      /* RuntimeErrorCode.MISSING_ZONEJS */
81022      , ngDevMode && `In this configuration Angular requires Zone.js`);
81023    }
81024
81025    Zone.assertZonePatched();
81026    const self = this;
81027    self._nesting = 0;
81028    self._outer = self._inner = Zone.current;
81029
81030    if (Zone['AsyncStackTaggingZoneSpec']) {
81031      const AsyncStackTaggingZoneSpec = Zone['AsyncStackTaggingZoneSpec'];
81032      self._inner = self._inner.fork(new AsyncStackTaggingZoneSpec('Angular'));
81033    }
81034
81035    if (Zone['TaskTrackingZoneSpec']) {
81036      self._inner = self._inner.fork(new Zone['TaskTrackingZoneSpec']());
81037    }
81038
81039    if (enableLongStackTrace && Zone['longStackTraceZoneSpec']) {
81040      self._inner = self._inner.fork(Zone['longStackTraceZoneSpec']);
81041    } // if shouldCoalesceRunChangeDetection is true, all tasks including event tasks will be
81042    // coalesced, so shouldCoalesceEventChangeDetection option is not necessary and can be skipped.
81043
81044
81045    self.shouldCoalesceEventChangeDetection = !shouldCoalesceRunChangeDetection && shouldCoalesceEventChangeDetection;
81046    self.shouldCoalesceRunChangeDetection = shouldCoalesceRunChangeDetection;
81047    self.lastRequestAnimationFrameId = -1;
81048    self.nativeRequestAnimationFrame = getNativeRequestAnimationFrame().nativeRequestAnimationFrame;
81049    forkInnerZoneWithAngularBehavior(self);
81050  }
81051
81052  static isInAngularZone() {
81053    // Zone needs to be checked, because this method might be called even when NoopNgZone is used.
81054    return typeof Zone !== 'undefined' && Zone.current.get('isAngularZone') === true;
81055  }
81056
81057  static assertInAngularZone() {
81058    if (!NgZone.isInAngularZone()) {
81059      throw new RuntimeError(909
81060      /* RuntimeErrorCode.UNEXPECTED_ZONE_STATE */
81061      , ngDevMode && 'Expected to be in Angular Zone, but it is not!');
81062    }
81063  }
81064
81065  static assertNotInAngularZone() {
81066    if (NgZone.isInAngularZone()) {
81067      throw new RuntimeError(909
81068      /* RuntimeErrorCode.UNEXPECTED_ZONE_STATE */
81069      , ngDevMode && 'Expected to not be in Angular Zone, but it is!');
81070    }
81071  }
81072  /**
81073   * Executes the `fn` function synchronously within the Angular zone and returns value returned by
81074   * the function.
81075   *
81076   * Running functions via `run` allows you to reenter Angular zone from a task that was executed
81077   * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
81078   *
81079   * Any future tasks or microtasks scheduled from within this function will continue executing from
81080   * within the Angular zone.
81081   *
81082   * If a synchronous error happens it will be rethrown and not reported via `onError`.
81083   */
81084
81085
81086  run(fn, applyThis, applyArgs) {
81087    return this._inner.run(fn, applyThis, applyArgs);
81088  }
81089  /**
81090   * Executes the `fn` function synchronously within the Angular zone as a task and returns value
81091   * returned by the function.
81092   *
81093   * Running functions via `run` allows you to reenter Angular zone from a task that was executed
81094   * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
81095   *
81096   * Any future tasks or microtasks scheduled from within this function will continue executing from
81097   * within the Angular zone.
81098   *
81099   * If a synchronous error happens it will be rethrown and not reported via `onError`.
81100   */
81101
81102
81103  runTask(fn, applyThis, applyArgs, name) {
81104    const zone = this._inner;
81105    const task = zone.scheduleEventTask('NgZoneEvent: ' + name, fn, E
81105MPTY_PAYLOAD, noop, noop);
81106
81107    try {
81108      return zone.runTask(task, applyThis, applyArgs);
81109    } finally {
81110      zone.cancelTask(task);
81111    }
81112  }
81113  /**
81114   * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
81115   * rethrown.
81116   */
81117
81118
81119  runGuarded(fn, applyThis, applyArgs) {
81120    return this._inner.runGuarded(fn, applyThis, applyArgs);
81121  }
81122  /**
81123   * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
81124   * the function.
81125   *
81126   * Running functions via {@link #runOutsideAngular} allows you to escape Angular's zone and do
81127   * work that
81128   * doesn't trigger Angular change-detection or is subject to Angular's error handling.
81129   *
81130   * Any future tasks or microtasks scheduled from within this function will continue executing from
81131   * outside of the Angular zone.
81132   *
81133   * Use {@link #run} to reenter the Angular zone and do work that updates the application model.
81134   */
81135
81136
81137  runOutsideAngular(fn) {
81138    return this._outer.run(fn);
81139  }
81140
81141}
81142
81143const EMPTY_PAYLOAD = {};
81144
81145function checkStable(zone) {
81146  // TODO: @JiaLiPassion, should check zone.isCheckStableRunning to prevent
81147  // re-entry. The case is:
81148  //
81149  // @Component({...})
81150  // export class AppComponent {
81151  // constructor(private ngZone: NgZone) {
81152  //   this.ngZone.onStable.subscribe(() => {
81153  //     this.ngZone.run(() => console.log('stable'););
81154  //   });
81155  // }
81156  //
81157  // The onStable subscriber run another function inside ngZone
81158  // which causes `checkStable()` re-entry.
81159  // But this fix causes some issues in g3, so this fix will be
81160  // launched in another PR.
81161  if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) {
81162    try {
81163      zone._nesting++;
81164      zone.onMicrotaskEmpty.emit(null);
81165    } finally {
81166      zone._nesting--;
81167
81168      if (!zone.hasPendingMicrotasks) {
81169        try {
81170          zone.runOutsideAngular(() => zone.onStable.emit(null));
81171        } finally {
81172          zone.isStable = true;
81173        }
81174      }
81175    }
81176  }
81177}
81178
81179function delayChangeDetectionForEvents(zone) {
81180  /**
81181   * We also need to check _nesting here
81182   * Consider the following case with shouldCoalesceRunChangeDetection = true
81183   *
81184   * ngZone.run(() => {});
81185   * ngZone.run(() => {});
81186   *
81187   * We want the two `ngZone.run()` only trigger one change detection
81188   * when shouldCoalesceRunChangeDetection is true.
81189   * And because in this case, change detection run in async way(requestAnimationFrame),
81190   * so we also need to check the _nesting here to prevent multiple
81191   * change detections.
81192   */
81193  if (zone.isCheckStableRunning || zone.lastRequestAnimationFrameId !== -1) {
81194    return;
81195  }
81196
81197  zone.lastRequestAnimationFrameId = zone.nativeRequestAnimationFrame.call(_global, () => {
81198    // This is a work around for https://github.com/angular/angular/issues/36839.
81199    // The core issue is that when event coalescing is enabled it is possible for microtasks
81200    // to get flushed too early (As is the case with `Promise.then`) between the
81201    // coalescing eventTasks.
81202    //
81203    // To workaround this we schedule a "fake" eventTask before we process the
81204    // coalescing eventTasks. The benefit of this is that the "fake" container eventTask
81205    //  will prevent the microtasks queue from getting drained in between the coalescing
81206    // eventTask execution.
81207    if (!zone.fakeTopEventTask) {
81208      zone.fakeTopEventTask = Zone.root.scheduleEventTask('fakeTopEventTask', () => {
81209        zone.lastRequestAnimationFrameId = -1;
81210        updateMicroTaskStatus(zone);
81211        zone.isCheckStableRunning = true;
81212        checkStable(zone);
81213        zone.isCheckStableRunning = false;
81214      }, undefined, () => {}, () => {});
81215    }
81216
81217    zone.fakeTopEventTask.invoke();
81218  });
81219  updateMicroTaskStatus(zone);
81220}
81221
81222function forkInnerZoneWithAngularBehavior(zone) {
81223  const delayChangeDetectionForEventsDelegate = () => {
81224    delayChangeDetectionForEvents(zone);
81225  };
81226
81227  zone._inner = zone._inner.fork({
81228    name: 'angular',
81229    properties: {
81230      'isAngularZone': true
81231    },
81232    onInvokeTask: (delegate, current, target, task, applyThis, applyArgs) => {
vendor: 4,770 bytes, lines 81233-81384
81233      try {
81234        onEnter(zone);
81235        return delegate.invokeTask(target, task, applyThis, applyArgs);
81236      } finally {
81237        if (zone.shouldCoalesceEventChangeDetection && task.type === 'eventTask' || zone.shouldCoalesceRunChangeDetection) {
81238          delayChangeDetectionForEventsDelegate();
81239        }
81240
81241        onLeave(zone);
81242      }
81243    },
81244    onInvoke: (delegate, current, target, callback, applyThis, applyArgs, source) => {
81245      try {
81246        onEnter(zone);
81247        return delegate.invoke(target, callback, applyThis, applyArgs, source);
81248      } finally {
81249        if (zone.shouldCoalesceRunChangeDetection) {
81250          delayChangeDetectionForEventsDelegate();
81251        }
81252
81253        onLeave(zone);
81254      }
81255    },
81256    onHasTask: (delegate, current, target, hasTaskState) => {
81257      delegate.hasTask(target, hasTaskState);
81258
81259      if (current === target) {
81260        // We are only interested in hasTask events which originate from our zone
81261        // (A child hasTask event is not interesting to us)
81262        if (hasTaskState.change == 'microTask') {
81263          zone._hasPendingMicrotasks = hasTaskState.microTask;
81264          updateMicroTaskStatus(zone);
81265          checkStable(zone);
81266        } else if (hasTaskState.change == 'macroTask') {
81267          zone.hasPendingMacrotasks = hasTaskState.macroTask;
81268        }
81269      }
81270    },
81271    onHandleError: (delegate, current, target, error) => {
81272      delegate.handleError(target, error);
81273      zone.runOutsideAngular(() => zone.onError.emit(error));
81274      return false;
81275    }
81276  });
81277}
81278
81279function updateMicroTaskStatus(zone) {
81280  if (zone._hasPendingMicrotasks || (zone.shouldCoalesceEventChangeDetection || zone.shouldCoalesceRunChangeDetection) && zone.lastRequestAnimationFrameId !== -1) {
81281    zone.hasPendingMicrotasks = true;
81282  } else {
81283    zone.hasPendingMicrotasks = false;
81284  }
81285}
81286
81287function onEnter(zone) {
81288  zone._nesting++;
81289
81290  if (zone.isStable) {
81291    zone.isStable = false;
81292    zone.onUnstable.emit(null);
81293  }
81294}
81295
81296function onLeave(zone) {
81297  zone._nesting--;
81298  checkStable(zone);
81299}
81300/**
81301 * Provides a noop implementation of `NgZone` which does nothing. This zone requires explicit calls
81302 * to framework to perform rendering.
81303 */
81304
81305
81306class NoopNgZone {
81307  constructor() {
81308    this.hasPendingMicrotasks = false;
81309    this.hasPendingMacrotasks = false;
81310    this.isStable = true;
81311    this.onUnstable = new EventEmitter();
81312    this.onMicrotaskEmpty = new EventEmitter();
81313    this.onStable = new EventEmitter();
81314    this.onError = new EventEmitter();
81315  }
81316
81317  run(fn, applyThis, applyArgs) {
81318    return fn.apply(applyThis, applyArgs);
81319  }
81320
81321  runGuarded(fn, applyThis, applyArgs) {
81322    return fn.apply(applyThis, applyArgs);
81323  }
81324
81325  runOutsideAngular(fn) {
81326    return fn();
81327  }
81328
81329  runTask(fn, applyThis, applyArgs, name) {
81330    return fn.apply(applyThis, applyArgs);
81331  }
81332
81333}
81334/**
81335 * @license
81336 * Copyright Google LLC All Rights Reserved.
81337 *
81338 * Use of this source code is governed by an MIT-style license that can be
81339 * found in the LICENSE file at https://angular.io/license
81340 */
81341
81342/**
81343 * Internal injection token that can used to access an instance of a Testability class.
81344 *
81345 * This token acts as a bridge between the core bootstrap code and the `Testability` class. This is
81346 * needed to ensure that there are no direct references to the `Testability` class, so it can be
81347 * tree-shaken away (if not referenced). For the environments/setups when the `Testability` class
81348 * should be available, this token is used to add a provider that references the `Testability`
81349 * class. Otherwise, only this token is retained in a bundle, but the `Testability` class is not.
81350 */
81351
81352
81353const TESTABILITY = new InjectionToken('');
81354/**
81355 * Internal injection token to retrieve Testability getter class instance.
81356 */
81357
81358const TESTABILITY_GETTER = new InjectionToken('');
81359/**
81360 * The Testability service provides testing hooks that can be accessed from
81361 * the browser.
81362 *
81363 * Angular applications bootstrapped using an NgModule (via `@NgModule.bootstrap` field) will also
81364 * instantiate Testability by default (in both development and production modes).
81365 *
81366 * For applications bootstrapped using the `bootstrapApplication` function, Testability is not
81367 * included by default. You can include it into your applications by getting the list of necessary
81368 * providers using the `provideProtractorTestingSupport()` function and adding them into the
81369 * `options.providers` array. Example:
81370 *
81371 * ```typescript
81372 * import {provideProtractorTestingSupport} from '@angular/platform-browser';
81373 *
81374 * await bootstrapApplication(RootComponent, providers: [provideProtractorTestingSupport()]);
81375 * ```
81376 *
81377 * @publicApi
81378 */
81379
81380class Testability {
81381  constructor(_ngZone, registry, testabilityGetter) {
81382    this._ngZone = _ngZone;
81383    this.registry = registry;
81384    this._pendingCount = 0;
81385    this._isZoneStable = true;
81386    /**
81387     * Whether any work was done since the last 'whenStable' callback. This is
81388     * useful to detect if this could have potentially destabilized another
81389     * component while it is stabilizing.
81390     * @internal
81391     */
81392
81393    this._didWork = false;
81394    this._callbacks = [];
81395    this.taskTrackingZone = null; // If there was no Testability logic registered in the global scope
81396    // before, register the current testability getter as a global one.
81397
81398    if (!_testabilityGetter) {
81399      setTestabilityGetter(testabilityGetter);
81400      testabilityGetter.addToWindow(registry);
81401    }
81402
81403    this._watchAngularEvents();
81404
81405    _ngZone.run(() => {
81406      this.taskTrackingZone = typeof Zone == 'undefined' ? null : Zone.current.get('TaskTrackingZone');
81407    });
81408  }
81409
81410  _watchAngularEvents() {
81411    this._ngZone.onUnstable.subscribe({
81412      next: () => {
81413        this._didWork = true;
81414        this._isZoneStable = false;
81415      }
81416    });
81417
81418    this._ngZone.runOutsideAngular(() => {
81419      this._ngZone.onStable.subscribe({
81420        next: () => {
81421          NgZone.assertNotInAngularZone();
81422          scheduleMicroTask(() => {
81423            this._isZoneStable = true;
81424
81425            this._runCallbacksIfReady();
81426          });
81427        }
81428      });
81429    });
81430  }
81431  /**
81432   * Increases the number of pending request
81433   * @deprecated pending requests are now tracked with zones.
81434   */
81435
81436
81437  increasePendingRequestCount() {
81438    this._pendingCount += 1;
81439    this._didWork = true;
81440    return this._pendingCount;
81441  }
81442  /**
81443   * Decreases the number of pending request
81444   * @deprecated pending requests are now tracked with zones
81445   */
81446
81447
81448  decreasePendingRequestCount() {
81449    this._pendingCount -= 1;
81450
81451    if (this._pendingCount < 0) {
81452      throw new Error('pending async requests below zero');
81453    }
81454
81455    this._runCallbacksIfReady();
81456
81457    return this._pendingCount;
81458  }
81459  /**
81460   * Whether an associated application is stable
81461   */
81462
81463
81464  isStable() {
81465    return this._isZoneStable && this._pendingCount === 0 && !this._ngZone.hasPendingMacrotasks;
81466  }
81467
81468  _runCallbacksIfReady() {
81469    if (this.isStable()) {
81470      // Schedules the call backs in a new frame so that it is always async.
81471      scheduleMicroTask(() => {
81472        while (this._callbacks.length !== 0) {
81473          let cb = this._callbacks.pop();
81474
81475          clearTimeout(cb.timeoutId);
81476          cb.doneCb(this._didWork);
81477        }
81478
81479        this._didWork = false;
81480      });
81481    } else {
81482      // Still not stable, send updates.
81483      let pending = this.getPendingTasks();
81484      this._callbacks = this._callbacks.filter(cb => {
81485        if (cb.updateCb && cb.updateCb(pending)) {
81486          clearTimeout(cb.timeoutId);
81487          return false;
81488        }
81489
81490        return true;
81491      });
81492      this._didWork = true;
81493    }
81494  }
81495
81496  getPendingTasks() {
81497    if (!this.taskTrackingZone) {
81498      return [];
81499    } // Copy the tasks data so that we don't leak tasks.
81500
81501
81502    return this.taskTrackingZone.macroTasks.map(t => {
81503      return {
81504        source: t.source,
81505        // From TaskTrackingZone:
81506        // https://github.com/angular/zone.js/blob/master/lib/zone-spec/task-tracking.ts#L40
81507        creationLocation: t.creationLocation,
81508        data: t.data
81509      };
81510    });
81511  }
81512
81513  addCallback(cb, timeout, updateCb) {
81514    let timeoutId = -1;
81515
81516    if (timeout && timeout > 0) {
81517      timeoutId = setTimeout(() => {
81518        this._callbacks = this._callbacks.filter(cb => cb.timeoutId !== timeoutId);
81519        cb(this._didWork, this.getPendingTasks());
81520      }, timeout);
81521    }
81522
81523    this._callbacks.push({
81524      doneCb: cb,
81525      timeoutId: timeoutId,
81526      updateCb: updateCb
81527    });
81528  }
81529  /**
81530   * Wait for the application to be stable with a timeout. If the timeout is reached before that
81531   * happens, the callback receives a list of the macro tasks that were pending, otherwise null.
81532   *
81533   * @param doneCb The callback to invoke when Angular is stable or the timeout expires
81534   *    whichever comes first.
81535   * @param timeout Optional. The maximum time to wait for Angular to become stable. If not
81536   *    specified, whenStable() will wait forever.
81537   * @param updateCb Optional. If specified, this callback will be invoked whenever the set of
81538   *    pending macrotasks changes. If this callback returns true doneCb will not be invoked
81539   *    and no further updates will be issued.
81540   */
81541
81542
81543  whenStable(doneCb, timeout, updateCb) {
81544    if (updateCb && !this.taskTrackingZone) {
81545      throw new Error('Task tracking zone is required when passing an update callback to ' + 'whenStable(). Is "zone.js/plugins/task-tracking" loaded?');
81546    } // These arguments are 'Function' above to keep the public API simple.
81547
81548
81549    this.addCallback(doneCb, timeout, updateCb);
81550
81551    this._runCallbacksIfReady();
81552  }
81553  /**
81554   * Get the number of pending requests
81555   * @deprecated pending requests are now tracked with zones
81556   */
81557
81558
81559  getPendingRequestCount() {
81560    return this._pendingCount;
81561  }
81562  /**
81563   * Registers an application with a testability hook so that it can be tracked.
81564   * @param token token of application, root element
81565   *
81566   * @internal
81567   */
81568
81569
81570  registerApplication(token) {
81571    this.registry.registerApplication(token, this);
81572  }
81573  /**
81574   * Unregisters an application.
81575   * @param token token of application, root element
81576   *
81577   * @internal
81578   */
81579
81580
81581  unregisterApplication(token) {
81582    this.registry.unregisterApplication(token);
81583  }
81584  /**
81585   * Find providers by name
81586   * @param using The root element to search from
81587   * @param provider The name of binding variable
81588   * @param exactMatch Whether using exactMatch
81589   */
81590
81591
81592  findProviders(using, provider, exactMatch) {
81593    // TODO(juliemr): implement.
81594    return [];
81595  }
81596
81597}
81598
81599Testability.ɵfac = function Testability_Factory(t) {
81600  return new (t || Testability)(ɵɵinject(NgZone), ɵɵinject(TestabilityRegistry), ɵɵinject(TESTABILITY_GETTER));
81601};
81602
81603Testability.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
81604  token: Testability,
81605  factory: Testability.ɵfac
81606});
81607
81608(function () {
81609  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(Testability, [{
81610    type: Injectable
81611  }], function () {
81612    return [{
81613      type: NgZone
81614    }, {
81615      type: TestabilityRegistry
81616    }, {
81617      type: undefined,
81618      decorators: [{
81619        type: Inject,
81620        args: [TESTABILITY_GETTER]
81621      }]
81622    }];
81623  }, null);
81624})();
81625/**
81626 * A global registry of {@link Testability} instances for specific elements.
81627 * @publicApi
81628 */
81629
81630
81631class TestabilityRegistry {
81632  constructor() {
81633    /** @internal */
81634    this._applications = new Map();
81635  }
81636  /**
81637   * Registers an application with a testability hook so that it can be tracked
81638   * @param token token of application, root element
81639   * @param testability Testability hook
81640   */
81641
81642
81643  registerApplication(token, testability) {
81644    this._applications.set(token, testability);
81645  }
81646  /**
81647   * Unregisters an application.
81648   * @param token token of application, root element
81649   */
81650
81651
81652  unregisterApplication(token) {
81653    this._applications.delete(token);
81654  }
81655  /**
81656   * Unregisters all applications
81657   */
81658
81659
81660  unregisterAllApplications() {
81661    this._applications.clear();
81662  }
81663  /**
81664   * Get a testability hook associated with the application
81665   * @param elem root element
81666   */
81667
81668
81669  getTestability(elem) {
81670    return this._applications.get(elem) || null;
81671  }
81672  /**
81673   * Get all registered testabilities
81674   */
81675
81676
81677  getAllTestabilities() {
81678    return Array.from(this._applications.values());
81679  }
81680  /**
81681   * Get all registered applications(root elements)
81682   */
81683
81684
81685  getAllRootElements() {
81686    return Array.from(this._applications.keys());
81687  }
81688  /**
81689   * Find testability of a node in the Tree
81690   * @param elem node
81691   * @param findInAncestors whether finding testability in ancestors if testability was not found in
81692   * current node
81693   */
81694
81695
81696  findTestabilityInTree(elem, findInAncestors = true) {
81697    return _testabilityGetter?.findTestabilityInTree(this, elem, findInAncestors) ?? null;
81698  }
81699
81700}
81701
81702TestabilityRegistry.ɵfac = function TestabilityRegistry_Factory(t) {
81703  return new (t || TestabilityRegistry)();
81704};
81705
81706TestabilityRegistry.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
81707  token: TestabilityRegistry,
81708  factory: TestabilityRegistry.ɵfac,
81709  providedIn: 'platform'
81710});
81711
81712(function () {
81713  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(TestabilityRegistry, [{
81714    type: Injectable,
81715    args: [{
81716      providedIn: 'platform'
81717    }]
81718  }], null, null);
81719})();
81720/**
81721 * Set the {@link GetTestability} implementation used by the Angular testing framework.
81722 * @publicApi
81723 */
81724
81725
81726function setTestabilityGetter(getter) {
81727  _testabilityGetter = getter;
81728}
81729
81730let _testabilityGetter;
81731/**
81732 * @license
81733 * Copyright Google LLC All Rights Reserved.
81734 *
81735 * Use of this source code is governed by an MIT-style license that can be
81736 * found in the LICENSE file at https://angular.io/license
81737 */
81738
81739
81740let _platformInjector = null;
81741/**
81742 * Internal token to indicate whether having multiple bootstrapped platform should be allowed (only
81743 * one bootstrapped platform is allowed by default). This token helps to support SSR scenarios.
81744 */
81745
81746const ALLOW_MULTIPLE_PLATFORMS = new InjectionToken('AllowMultipleToken');
81747/**
81748 * Internal token that allows to register extra callbacks that should be invoked during the
81749 * `PlatformRef.destroy` operation. This token is needed to avoid a direct reference to the
81750 * `PlatformRef` class (i.e. register the callback via `PlatformRef.onDestroy`), thus making the
81751 * entire class tree-shakeable.
81752 */
81753
81754const PLATFORM_DESTROY_LISTENERS = new InjectionToken('PlatformDestroyListeners');
81755const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;
81756
81757function compileNgModuleFactory(injector, options, moduleType) {
81758  ngDevMode && assertNgModuleType(moduleType);
81759  const moduleFactory = new NgModuleFactory(moduleType); // All of the logic below is irrelevant for AOT-compiled code.
81760
81761  if (typeof ngJitMode !== 'undefined' && !ngJitMode) {
81762    return Promise.resolve(moduleFactory);
81763  }
81764
81765  const compilerOptions = injector.get(COMPILER_OPTIONS, []).concat(options); // Configure the compiler to use the provided options. This call may fail when multiple modules
81766  // are bootstrapped with incompatible options, as a component can only be compiled according to
81767  // a single set of options.
81768
81769  setJitOptions({
81770    defaultEncapsulation: _lastDefined(compilerOptions.map(opts => opts.defaultEncapsulation)),
81771    preserveWhitespaces: _lastDefined(compilerOptions.map(opts => opts.preserveWhitespaces))
81772  });
81773
81774  if (isComponentResourceResolutionQueueEmpty()) {
81775    return Promise.resolve(moduleFactory);
81776  }
81777
81778  const compilerProviders = _mergeArrays(compilerOptions.map(o => o.providers)); // In case there are no compiler providers, we just return the module factory as
81779  // there won't be any resource loader. This can happen with Ivy, because AOT compiled
81780  // modules can be still passed through "bootstrapModule". In that case we shouldn't
81781  // unnecessarily require the JIT compiler.
81782
81783
81784  if (compilerProviders.length === 0) {
81785    return Promise.resolve(moduleFactory);
81786  }
81787
81788  const compiler = getCompilerFacade({
81789    usage: 0
81790    /* JitCompilerUsage.Decorator */
81791    ,
81792    kind: 'NgModule',
81793    type: moduleType
81794  });
81795  const compilerInjector = Injector.create({
81796    providers: compilerProviders
81797  });
81798  const resourceLoader = compilerInjector.get(compiler.ResourceLoader); // The resource loader can also return a string while the "resolveComponentResources"
81799  // always expects a promise. Therefore we need to wrap the returned value in a promise.
81800
81801  return resolveComponentResources(url => Promise.resolve(resourceLoader.get(url))).then(() => moduleFactory);
81802}
81803
81804function publishDefaultGlobalUtils() {
81805  ngDevMode && publishDefaultGlobalUtils$1();
81806}
81807
81808function isBoundToModule(cf) {
81809  return cf.isBoundToModule;
81810}
81811/**
81812 * A token for third-party components that can register themselves with NgProbe.
81813 *
81814 * @publicApi
81815 */
81816
81817
81818class NgProbeToken {
81819  constructor(name, token) {
81820    this.name = name;
81821    this.token = token;
81822  }
81823
81824}
81825/**
81826 * Creates a platform.
81827 * Platforms must be created on launch using this function.
81828 *
81829 * @publicApi
81830 */
81831
81832
81833function createPlatform(injector) {
81834  if (_platformInjector && !_platformInjector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
81835    throw new RuntimeError(400
81836    /* RuntimeErrorCode.MULTIPLE_PLATFORMS */
81837    , ngDevMode && 'There can be only one platform. Destroy the previous one to create a new one.');
81838  }
81839
81840  publishDefaultGlobalUtils();
81841  _platformInjector = injector;
81842  const platform = injector.get(PlatformRef);
81843  runPlatformInitializers(injector);
81844  return platform;
81845}
81846/**
81847 * The goal of this function is to bootstrap a platform injector,
81848 * but avoid referencing `PlatformRef` class.
81849 * This function is needed for bootstrapping a Standalone Component.
81850 */
81851
81852
81853function createOrReusePlatformInjector(providers = []) {
81854  // If a platform injector already exists, it means that the platform
81855  // is already bootstrapped and no additional actions are required.
81856  if (_platformInjector) return _platformInjector; // Otherwise, setup a new platform injector and run platform initializers.
81857
81858  const injector = createPlatformInjector(providers);
81859  _platformInjector = injector;
81860  publishDefaultGlobalUtils();
81861  runPlatformInitializers(injector);
81862  return injector;
81863}
81864
81865function runPlatformInitializers(injector) {
81866  const inits = injector.get(PLATFORM_INITIALIZER, null);
81867
81868  if (inits) {
81869    inits.forEach(init => init());
81870  }
81871}
81872/**
81873 * Internal create application API that implements the core application creation logic and optional
81874 * bootstrap logic.
81875 *
81876 * Platforms (such as `platform-browser`) may require different set of application and platform
81877 * providers for an application to function correctly. As a result, platforms may use this function
81878 * internally and supply the necessary providers during the bootstrap, while exposing
81879 * platform-specific APIs as a part of their public API.
81880 *
81881 * @returns A promise that returns an `ApplicationRef` instance once resolved.
81882 */
81883
81884
81885function internalCreateApplication(config) {
81886  const {
81887    rootComponent,
81888    appProviders,
81889    platformProviders
81890  } = config;
81891
81892  if (NG_DEV_MODE && rootComponent !== undefined) {
81893    assertStandaloneComponentType(rootComponent);
81894  }
81895
81896  const platformInjector = createOrReusePlatformInjector(platformProviders);
81897  const ngZone = getNgZone('zone.js', getNgZoneOptions());
81898  return ngZone.run(() => {
81899    // Create root application injector based on a set of providers configured at the platform
81900    // bootstrap level as well as providers passed to the bootstrap call by a user.
81901    const allAppProviders = [{
81902      provide: NgZone,
81903      useValue: ngZone
81904    }
vendor: 3,812 bytes, lines 81904-82021
81904, ...(appProviders || []) //
81905    ];
81906    const envInjector = createEnvironmentInjector(allAppProviders, platformInjector, 'Environment Injector');
81907    const exceptionHandler = envInjector.get(ErrorHandler, null);
81908
81909    if (NG_DEV_MODE && !exceptionHandler) {
81910      throw new RuntimeError(402
81911      /* RuntimeErrorCode.ERROR_HANDLER_NOT_FOUND */
81912      , 'No `ErrorHandler` found in the Dependency Injection tree.');
81913    }
81914
81915    let onErrorSubscription;
81916    ngZone.runOutsideAngular(() => {
81917      onErrorSubscription = ngZone.onError.subscribe({
81918        next: error => {
81919          exceptionHandler.handleError(error);
81920        }
81921      });
81922    }); // If the whole platform is destroyed, invoke the `destroy` method
81923    // for all bootstrapped applications as well.
81924
81925    const destroyListener = () => envInjector.destroy();
81926
81927    const onPlatformDestroyListeners = platformInjector.get(PLATFORM_DESTROY_LISTENERS);
81928    onPlatformDestroyListeners.add(destroyListener);
81929    envInjector.onDestroy(() => {
81930      onErrorSubscription.unsubscribe();
81931      onPlatformDestroyListeners.delete(destroyListener);
81932    });
81933    return _callAndReportToErrorHandler(exceptionHandler, ngZone, () => {
81934      const initStatus = envInjector.get(ApplicationInitStatus);
81935      initStatus.runInitializers();
81936      return initStatus.donePromise.then(() => {
81937        const localeId = envInjector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
81938        setLocaleId(localeId || DEFAULT_LOCALE_ID);
81939        const appRef = envInjector.get(ApplicationRef);
81940
81941        if (rootComponent !== undefined) {
81942          appRef.bootstrap(rootComponent);
81943        }
81944
81945        return appRef;
81946      });
81947    });
81948  });
81949}
81950/**
81951 * Creates a factory for a platform. Can be used to provide or override `Providers` specific to
81952 * your application's runtime needs, such as `PLATFORM_INITIALIZER` and `PLATFORM_ID`.
81953 * @param parentPlatformFactory Another platform factory to modify. Allows you to compose factories
81954 * to build up configurations that might be required by different libraries or parts of the
81955 * application.
81956 * @param name Identifies the new platform factory.
81957 * @param providers A set of dependency providers for platforms created with the new factory.
81958 *
81959 * @publicApi
81960 */
81961
81962
81963function createPlatformFactory(parentPlatformFactory, name, providers = []) {
81964  const desc = `Platform: ${name}`;
81965  const marker = new InjectionToken(desc);
81966  return (extraProviders = []) => {
81967    let platform = getPlatform();
81968
81969    if (!platform || platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
81970      const platformProviders = [...providers, ...extraProviders, {
81971        provide: marker,
81972        useValue: true
81973      }];
81974
81975      if (parentPlatformFactory) {
81976        parentPlatformFactory(platformProviders);
81977      } else {
81978        createPlatform(createPlatformInjector(platformProviders, desc));
81979      }
81980    }
81981
81982    return assertPlatform(marker);
81983  };
81984}
81985/**
81986 * Checks that there is currently a platform that contains the given token as a provider.
81987 *
81988 * @publicApi
81989 */
81990
81991
81992function assertPlatform(requiredToken) {
81993  const platform = getPlatform();
81994
81995  if (!platform) {
81996    throw new RuntimeError(401
81997    /* RuntimeErrorCode.PLATFORM_NOT_FOUND */
81998    , ngDevMode && 'No platform exists!');
81999  }
82000
82001  if ((typeof ngDevMode === 'undefined' || ngDevMode) && !platform.injector.get(requiredToken, null)) {
82002    throw new RuntimeError(400
82003    /* RuntimeErrorCode.MULTIPLE_PLATFORMS */
82004    , 'A platform with a different configuration has been created. Please destroy it first.');
82005  }
82006
82007  return platform;
82008}
82009/**
82010 * Helper function to create an instance of a platform injector (that maintains the 'platform'
82011 * scope).
82012 */
82013
82014
82015function createPlatformInjector(providers = [], name) {
82016  return Injector.create({
82017    name,
82018    providers: [{
82019      provide: INJECTOR_SCOPE,
82020      useValue: 'platform'
82021    }, {
82022      provide: PLATFORM_DESTROY_LISTENERS,
82023      useValue: new Set([() => _platformInjector = null])
82024    }, ...providers]
82025  });
82026}
82027/**
82028 * Destroys the current Angular platform and all Angular applications on the page.
82029 * Destroys all modules and listeners registered with the platform.
82030 *
82031 * @publicApi
82032 */
82033
82034
82035function destroyPlatform() {
82036  getPlatform()?.destroy();
82037}
82038/**
82039 * Returns the current platform.
82040 *
82041 * @publicApi
82042 */
82043
82044
82045function getPlatform() {
82046  return _platformInjector?.get(PlatformRef) ?? null;
82047}
82048/**
82049 * The Angular platform is the entry point for Angular on a web page.
82050 * Each page has exactly one platform. Services (such as reflection) which are common
82051 * to every Angular application running on the page are bound in its scope.
82052 * A page's platform is initialized implicitly when a platform is created using a platform
82053 * factory such as `PlatformBrowser`, or explicitly by calling the `createPlatform()` function.
82054 *
82055 * @publicApi
82056 */
82057
82058
82059class PlatformRef {
82060  /** @internal */
82061  constructor(_injector) {
82062    this._injector = _injector;
82063    this._modules = [];
82064    this._destroyListeners = [];
82065    this._destroyed = false;
82066  }
82067  /**
82068   * Creates an instance of an `@NgModule` for the given platform.
82069   *
82070   * @deprecated Passing NgModule factories as the `PlatformRef.bootstrapModuleFactory` function
82071   *     argument is deprecated. Use the `PlatformRef.bootstrapModule` API instead.
82072   */
82073
82074
82075  bootstrapModuleFactory(moduleFactory, options) {
82076    // Note: We need to create the NgZone _before_ we instantiate the module,
82077    // as instantiating the module creates some providers eagerly.
82078    // So we create a mini parent injector that just contains the new NgZone and
82079    // pass that as parent to the NgModuleFactory.
82080    const ngZone = getNgZone(options?.ngZone, getNgZoneOptions(options));
82081    const providers = [{
82082      provide: NgZone,
82083      useValue: ngZone
82084    }]; // Note: Create ngZoneInjector within ngZone.run so that all of the instantiated services are
82085    // created within the Angular zone
82086    // Do not try to replace ngZone.run with ApplicationRef#run because ApplicationRef would then be
82087    // created outside of the Angular zone.
82088
82089    return ngZone.run(() => {
82090      const ngZoneInjector = Injector.create({
82091        providers: providers,
82092        parent: this.injector,
82093        name: moduleFactory.moduleType.name
82094      });
82095      const moduleRef = moduleFactory.create(ngZoneInjector);
82096      const exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
82097
82098      if (!exceptionHandler) {
82099        throw new RuntimeError(402
82100        /* RuntimeErrorCode.ERROR_HANDLER_NOT_FOUND */
82101        , ngDevMode && 'No ErrorHandler. Is platform module (BrowserModule) included?');
82102      }
82103
82104      ngZone.runOutsideAngular(() => {
82105        const subscription = ngZone.onError.subscribe({
82106          next: error => {
82107            exceptionHandler.handleError(error);
82108          }
82109        });
82110        moduleRef.onDestroy(() => {
82111          remove(this._modules, moduleRef);
82112          subscription.unsubscribe();
82113        });
82114      });
82115      return _callAndReportToErrorHandler(exceptionHandler, ngZone, () => {
82116        const initStatus = moduleRef.injector.get(ApplicationInitStatus);
82117        initStatus.runInitializers();
82118        return initStatus.donePromise.then(() => {
82119          // If the `LOCALE_ID` provider is defined at bootstrap then we set the value for ivy
82120          const localeId = moduleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
82121          setLocaleId(localeId || DEFAULT_LOCALE_ID);
82122
82123          this._moduleDoBootstrap(moduleRef);
82124
82125          return moduleRef;
82126        });
82127      });
82128    });
82129  }
82130  /**
82131   * Creates an instance of an `@NgModule` for a given platform.
82132   *
82133   * @usageNotes
82134   * ### Simple Example
82135   *
82136   * ```typescript
82137   * @NgModule({
82138   *   imports: [BrowserModule]
82139   * })
82140   * class MyModule {}
82141   *
82142   * let moduleRef = platformBrowser().bootstrapModule(MyModule);
82143   * ```
82144   *
82145   */
82146
82147
82148  bootstrapModule(moduleType, compilerOptions = []) {
82149    const options = optionsReducer({}, compilerOptions);
82150    return compileNgModuleFactory(this.injector, options, moduleType).then(moduleFactory => this.bootstrapModuleFactory(moduleFactory, options));
82151  }
82152
82153  _moduleDoBootstrap(moduleRef) {
82154    const appRef = moduleRef.injector.get(ApplicationRef);
82155
82156    if (moduleRef._bootstrapComponents.length > 0) {
82157      moduleRef._bootstrapComponents.forEach(f => appRef.bootstrap(f));
82158    } else if (moduleRef.instance.ngDoBootstrap) {
82159      moduleRef.instance.ngDoBootstrap(appRef);
82160    } else {
82161      throw new RuntimeError(403
82162      /* RuntimeErrorCode.BOOTSTRAP_COMPONENTS_NOT_FOUND */
82163      , ngDevMode && `The module ${stringify(moduleRef.instance.constructor)} was bootstrapped, ` + `but it does not declare "@NgModule.bootstrap" components nor a "ngDoBootstrap" method. ` + `Please define one of these.`);
82164    }
82165
82166    this._modules.push(moduleRef);
82167  }
82168  /**
82169   * Registers a listener to be called when the platform is destroyed.
82170   */
82171
82172
82173  onDestroy(callback) {
82174    this._destroyListeners.push(callback);
82175  }
82176  /**
82177   * Retrieves the platform {@link Injector}, which is the parent injector for
82178   * every Angular application on the page and provides singleton providers.
82179   */
82180
82181
82182  get injector() {
82183    return this._injector;
82184  }
82185  /**
82186   * Destroys the current Angular platform and all Angular applications on the page.
82187   * Destroys all modules and listeners registered with the platform.
82188   */
82189
82190
82191  destroy() {
82192    if (this._destroyed) {
82193      throw new RuntimeError(404
82194      /* RuntimeErrorCode.PLATFORM_ALREADY_DESTROYED */
82195      , ngDevMode && 'The platform has already been destroyed!');
82196    }
82197
82198    this._modules.slice().forEach(module => module.destroy());
82199
82200    this._destroyListeners.forEach(listener => listener());
82201
82202    const destroyListeners = this._injector.get(PLATFORM_DESTROY_LISTENERS, null);
82203
82204    if (destroyListeners) {
82205      destroyListeners.forEach(listener => listener());
82206      destroyListeners.clear();
82207    }
82208
82209    this._destroyed = true;
82210  }
82211  /**
82212   * Indicates whether this instance was destroyed.
82213   */
82214
82215
82216  get destroyed() {
82217    return this._destroyed;
82218  }
82219
82220}
82221
82222PlatformRef.ɵfac = function PlatformRef_Factory(t) {
82223  return new (t || PlatformRef)(ɵɵinject(Injector));
82224};
82225
82226PlatformRef.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
82227  token: PlatformRef,
82228  factory: PlatformRef.ɵfac,
82229  providedIn: 'platform'
82230});
82231
82232(function () {
82233  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PlatformRef, [{
82234    type: Injectable,
82235    args: [{
82236      providedIn: 'platform'
82237    }]
82238  }], function () {
82239    return [{
82240      type: Injector
82241    }];
82242  }, null);
82243})(); // Transforms a set of `BootstrapOptions` (supported by the NgModule-based bootstrap APIs) ->
82244// `NgZoneOptions` that are recognized by the NgZone constructor. Passing no options will result in
82245// a set of default options returned.
82246
82247
82248function getNgZoneOptions(options) {
82249  return {
82250    enableLongStackTrace: typeof ngDevMode === 'undefined' ? false : !!ngDevMode,
82251    shouldCoalesceEventChangeDetection: !!(options && options.ngZoneEventCoalescing) || false,
82252    shouldCoalesceRunChangeDetection: !!(options && options.ngZoneRunCoalescing) || false
82253  };
82254}
82255
82256function getNgZone(ngZoneToUse, options) {
82257  let ngZone;
82258
82259  if (ngZoneToUse === 'noop') {
82260    ngZone = new NoopNgZone();
82261  } else {
82262    ngZone = (ngZoneToUse === 'zone.js' ? undefined : ngZoneToUse) || new NgZone(options);
82263  }
82264
82265  return ngZone;
82266}
82267
82268function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
82269  try {
82270    const result = callback();
82271
82272    if (isPromise(result)) {
82273      return result.catch(e => {
82274        ngZone.runOutsideAngular(() => errorHandler.handleError(e)); // rethrow as the exception handler might not do it
82275
82276        throw e;
82277      });
82278    }
82279
82280    return result;
82281  } catch (e) {
82282    ngZone.runOutsideAngular(() => errorHandler.handleError(e)); // rethrow as the exception handler might not do it
82283
82284    throw e;
82285  }
82286}
82287
82288function optionsReducer(dst, objs) {
82289  if (Array.isArray(objs)) {
82290    dst = objs.reduce(optionsReducer, dst);
82291  } else {
82292    dst = { ...dst,
82293      ...objs
82294    };
82295  }
82296
82297  return dst;
82298}
82299/**
82300 * A reference to an Angular application running on a page.
82301 *
82302 * @usageNotes
82303 *
82304 * {@a is-stable-examples}
82305 * ### isStable examples and caveats
82306 *
82307 * Note two important points about `isStable`, demonstrated in the examples below:
82308 * - the application will never be stable if you start any kind
82309 * of recurrent asynchronous task when the application starts
82310 * (for example for a polling process, started with a `setInterval`, a `setTimeout`
82311 * or using RxJS operators like `interval`);
82312 * - the `isStable` Observable runs outside of the Angular zone.
82313 *
82314 * Let's imagine that you start a recurrent task
82315 * (here incrementing a counter, using RxJS `interval`),
82316 * and at the same time subscribe to `isStable`.
82317 *
82318 * ```
82319 * constructor(appRef: ApplicationRef) {
82320 *   appRef.isStable.pipe(
82321 *      filter(stable => stable)
82322 *   ).subscribe(() => console.log('App is stable now');
82323 *   interval(1000).subscribe(counter => console.log(counter));
82324 * }
82325 * ```
82326 * In this example, `isStable` will never emit `true`,
82327 * and the trace "App is stable now" will never get logged.
82328 *
82329 * If you want to execute something when the app is stable,
82330 * you have to wait for the application to be stable
82331 * before starting your polling process.
82332 *
82333 * ```
82334 * constructor(appRef: ApplicationRef) {
82335 *   appRef.isStable.pipe(
82336 *     first(stable => stable),
82337 *     tap(stable => console.log('App is stable now')),
82338 *     switchMap(() => interval(1000))
82339 *   ).subscribe(counter => console.log(counter));
82340 * }
82341 * ```
82342 * In this example, the trace "App is stable now" will be logged
82343 * and then the counter starts incrementing every second.
82344 *
82345 * Note also that this Observable runs outside of the Angular zone,
82346 * which means that the code in the subscription
82347 * to this Observable will not trigger the change detection.
82348 *
82349 * Let's imagine that instead of logging the counter value,
82350 * you update a field of your component
82351 * and display it in its template.
82352 *
82353 * ```
82354 * constructor(appRef: ApplicationRef) {
82355 *   appRef.isStable.pipe(
82356 *     first(stable => stable),
82357 *     switchMap(() => interval(1000))
82358 *   ).subscribe(counter => this.value = counter);
82359 * }
82360 * ```
82361 * As the `isStable` Observable runs outside the zone,
82362 * the `value` field will be updated properly,
82363 * but the template will not be refreshed!
82364 *
82365 * You'll have to manually trigger the change detection to update the template.
82366 *
82367 * ```
82368 * constructor(appRef: ApplicationRef, cd: ChangeDetectorRef) {
82369 *   appRef.isStable.pipe(
82370 *     first(stable => stable),
82371 *     switchMap(() => interval(1000))
82372 *   ).subscribe(counter => {
82373 *     this.value = counter;
82374 *     cd.detectChanges();
82375 *   });
82376 * }
82377 * ```
82378 *
82379 * Or make the subscription callback run inside the zone.
82380 *
82381 * ```
82382 * constructor(appRef: ApplicationRef, zone: NgZone) {
82383 *   appRef.isStable.pipe(
82384 *     first(stable => stable),
82385 *     switchMap(() => interval(1000))
82386 *   ).subscribe(counter => zone.run(() => this.value = counter));
82387 * }
82388 * ```
82389 *
82390 * @publicApi
82391 */
82392
82393
82394class ApplicationRef {
82395  /** @internal */
82396  constructor(_zone, _injector, _exceptionHandler) {
82397    this._zone = _zone;
82398    this._injector = _injector;
82399    this._exceptionHandler = _exceptionHandler;
82400    /** @internal */
82401
82402    this._bootstrapListeners = [];
82403    this._views = [];
82404    this._runningTick = false;
82405    this._stable = true;
82406    this._destroyed = false;
82407    this._destroyListeners = [];
82408    /**
82409     * Get a list of component types registered to this application.
82410     * This list is populated even before the component is created.
82411     */
82412
82413    this.componentTypes = [];
82414    /**
82415     * Get a list of components registered to this application.
82416     */
82417
82418    this.components = [];
82419    this._onMicrotaskEmptySubscription = this._zone.onMicrotaskEmpty.subscribe({
82420      next: () => {
82421        this._zone.run(() => {
82422          this.tick();
82423        });
82424      }
82425    });
82426    const isCurrentlyStable = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Observable(observer => {
82427      this._stable = this._zone.isStable && !this._zone.hasPendingMacrotasks && !this._zone.hasPendingMicrotasks;
82428
82429      this._zone.runOutsideAngular(() => {
82430        observer.next(this._stable);
82431        observer.complete();
82432      });
82433    });
82434    const isStable = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Observable(observer => {
82435      // Create the subscription to onStable outside the Angular Zone so that
82436      // the callback is run outside the Angular Zone.
82437      let stableSub;
82438
82439      this._zone.runOutsideAngular(() => {
82440        stableSub = this._zone.onStable.subscribe(() => {
82441          NgZone.assertNotInAngularZone(); // Check whether there are no pending macro/micro tasks in the next tick
82442          // to allow for NgZone to update the state.
82443
82444          scheduleMicroTask(() => {
82445            if (!this._stable && !this._zone.hasPendingMacrotasks && !this._zone.hasPendingMicrotasks) {
82446              this._stable = true;
82447              observer.next(true);
82448            }
82449          });
82450        });
82451      });
82452
82453      const unstableSub = this._zone.onUnstable.subscribe(() => {
82454        NgZone.assertInAngularZone();
82455
82456        if (this._stable) {
82457          this._stable = false;
82458
82459          this._zone.runOutsideAngular(() => {
82460            observer.next(false);
82461          });
82462        }
82463      });
82464
82465      return () => {
82466        stableSub.unsubscribe();
82467        unstableSub.unsubscribe();
82468      };
82469    });
82470    this.isStable = (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.merge)(isCurrentlyStable, isStable.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.share)()));
82471  }
82472  /**
82473   * Indicates whether this instance was destroyed.
82474   */
82475
82476
82477  get destroyed() {
82478    return this._destroyed;
82479  }
82480  /**
82481   * The `EnvironmentInjector` used to create this application.
82482   */
82483
82484
82485  get injector() {
82486    return this._injector;
82487  }
82488  /**
82489   * Bootstrap a component onto the element identified by its selector or, optionally, to a
82490   * specified element.
82491   *
82492   * @usageNotes
82493   * ### Bootstrap process
82494   *
82495   * When bootstrapping a component, Angular mounts it onto a target DOM element
82496   * and kicks off automatic change detection. The target DOM element can be
82497   * provided using the `rootSelectorOrNode` argument.
82498   *
82499   * If the target DOM element is not provided, Angular tries to find one on a page
82500   * using the `selector` of the component that is being bootstrapped
82501   * (first matched element is used).
82502   *
82503   * ### Example
82504   *
82505   * Generally, we define the component to bootstrap in the `bootstrap` array of `NgModule`,
82506   * but it requires us to know the component while writing the application code.
82507   *
82508   * Imagine a situation where we have to wait for an API call to decide about the component to
82509   * bootstrap. We can use the `ngDoBootstrap` hook of the `NgModule` and call this method to
82510   * dynamically bootstrap a component.
82511   *
82512   * {@example core/ts/platform/platform.ts region='componentSelector'}
82513   *
82514   * Optionally, a component can be mounted onto a DOM element that does not match the
82515   * selector of the bootstrapped component.
82516   *
82517   * In the following example, we are providing a CSS selector to match the target element.
82518   *
82519   * {@example core/ts/platform/platform.ts region='cssSelector'}
82520   *
82521   * While in this example, we are providing reference to a DOM node.
82522   *
82523   * {@example core/ts/platform/platform.ts region='domNode'}
82524   */
82525
82526
82527  bootstrap(componentOrFactory, rootSelectorOrNode) {
82528    NG_DEV_MODE && this.warnIfDestroyed();
82529    const isComponentFactory = componentOrFactory instanceof ComponentFactory$1;
82530
82531    const initStatus = this._injector.get(ApplicationInitStatus);
82532
82533    if (!initStatus.done) {
82534      const standalone = !isComponentFactory && isStandalone(componentOrFactory);
82535      const errorMessage = 'Cannot bootstrap as there are still asynchronous initializers running.' + (standalone ? '' : ' Bootstrap components in the `ngDoBootstrap` method of the root module.');
82536      throw new RuntimeError(405
82537      /* RuntimeErrorCode.ASYNC_INITIALIZERS_STILL_RUNNING */
82538      , NG_DEV_MODE && errorMessage);
82539    }
82540
82541    let componentFactory;
82542
82543    if (isComponentFactory) {
82544      componentFactory = componentOrFactory;
82545    } else {
82546      const resolver = this._injector.get(ComponentFactoryResolver$1);
82547
82548      componentFactory = resolver.resolveComponentFactory(componentOrFactory);
82549    }
82550
82551    this.componentTypes.push(componentFactory.componentType); // Create a factory associated with the current module if it's not bound to some other
82552
82553    const ngModule = isBoundToModule(componentFactory) ? undefined : this._injector.get(NgModuleRef$1);
82554    const selectorOrNode = rootSelectorOrNode || componentFactory.selector;
82555    const compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
82556    const nativeElement = compRef.location.nativeElement;
82557    const testability = compRef.injector.get(TESTABILITY, null);
82558    testability?.registerApplication(nativeElement);
82559    compRef.onDestroy(() => {
82560      this.detachView(compRef.hostView);
82561      remove(this.components, compRef);
82562      testability?.unregisterApplication(nativeElement);
82563    });
82564
82565    this._loadComponent(compRef);
82566
82567    if (typeof ngDevMode === 'undefined' || ngDevMode) {
82568      const _console = this._injector.get(Console);
82569
82570      _console.log(`Angular is running in development mode. Call enableProdMode() to enable production mode.`);
82571    }
82572
82573    return compRef;
82574  }
82575  /**
82576   * Invoke this method to explicitly process change detection and its side-effects.
82577   *
82578   * In development mode, `tick()` also performs a second change detection cycle to ensure that no
82579   * further changes are detected. If additional changes are picked up during this second cycle,
82580   * bindings in the app have side-effects that cannot be resolved in a single change detection
82581   * pass.
82582   * In this case, Angular throws an error, since an Angular application can only have one change
82583   * detection pass during which all change detection must complete.
82584   */
82585
82586
82587  tick() {
82588    NG_DEV_MODE && this.warnIfDestroyed();
82589
82590    if (this._runningTick) {
82591      throw new RuntimeError(101
82592      /* RuntimeErrorCode.RECURSIVE_APPLICATION_REF_TICK */
82593      , ngDevMode && 'ApplicationRef.tick is called recursively');
82594    }
82595
82596    try {
82597      this._runningTick = true;
82598
82599      for (let view of this._views) {
82600        view.detectChanges();
82601      }
82602
82603      if (typeof ngDevMode === 'undefined' || ngDevMode) {
82604        for (let view of this._views) {
82605          view.checkNoChanges();
82606        }
82607      }
82608    } catch (e) {
82609      // Attention: Don't rethrow as it could cancel subscriptions to Observables!
82610      this._zone.runOutsideAngular(() => this._exceptionHandler.handleError(e));
82611    } finally {
82612      this._runningTick = false;
82613    }
82614  }
82615  /**
82616   * Attaches a view so that it will be dirty checked.
82617   * The view will be automatically detached when it is destroyed.
82618   * This will throw if the view is already attached to a ViewContainer.
82619   */
82620
82621
82622  attachView(viewRef) {
82623    NG_DEV_MODE && this.warnIfDestroyed();
82624    const view = viewRef;
82625
82626    this._views.push(view);
82627
82628    view.attachToAppRef(this);
82629  }
82630  /**
82631   * Detaches a view from dirty checking again.
82632   */
82633
82634
82635  detachView(viewRef) {
82636    NG_DEV_MODE && this.warnIfDestroyed();
82637    const view = viewRef;
82638    remove(this._views, view);
82639    view.detachFromAppRef();
82640  }
82641
82642  _loadComponent(componentRef) {
82643    this.attachView(componentRef.hostView);
82644    this.tick();
82645    this.components.push(componentRef); // Get the listeners lazily to prevent DI cycles.
82646
82647    const listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners);
82648
82649    listeners.forEach(listener => listener(componentRef));
82650  }
82651  /** @internal */
82652
82653
82654  ngOnDestroy() {
82655    if (this._destroyed) return;
82656
82657    try {
82658      // Call all the lifecycle hooks.
82659      this._destroyListeners.forEach(listener => listener()); // Destroy all registered views.
82660
82661
82662      this._views.slice().forEach(view => view.destroy());
82663
82664      this._onMicrotaskEmptySubscription.unsubscribe();
82665    } finally {
82666      // Indicate that this instance is destroyed.
82667      this._destroyed = true; // Release all references.
82668
82669      this._views = [];
82670      this._bootstrapListeners = [];
82671      this._destroyListeners = [];
82672    }
82673  }
82674  /**
82675   * Registers a listener to be called when an instance is destroyed.
82676   *
82677   * @param callback A callback function to add as a listener.
82678   * @returns A function which unregisters a listener.
82679   *
82680   * @internal
82681   */
82682
82683
82684  onDestroy(callback) {
82685    NG_DEV_MODE && this.warnIfDestroyed();
82686
82687    this._destroyListeners.push(callback);
82688
82689    return () => remove(this._destroyListeners, callback);
82690  }
82691  /**
82692   * Destroys an Angular application represented by this `ApplicationRef`. Calling this function
82693   * will destroy the associated environment injectors as well as all the bootstrapped components
82694   * with their views.
82695   */
82696
82697
82698  destroy() {
82699    if (this._destroyed) {
82700      throw new RuntimeError(406
82701      /* RuntimeErrorCode.APPLICATION_REF_ALREADY_DESTROYED */
82702      , ngDevMode && 'This instance of the `ApplicationRef` has already been destroyed.');
82703    }
82704
82705    const injector = this._injector; // Check that this injector instance supports destroy operation.
82706
82707    if (injector.destroy && !injector.destroyed) {
82708      // Destroying an underlying injector will trigger the `ngOnDestroy` lifecycle
82709      // hook, which invokes the remaining cleanup actions.
82710      injector.destroy();
82711    }
82712  }
82713  /**
82714   * Returns the number of attached views.
82715   */
82716
82717
82718  get viewCount() {
82719    return this._views.length;
82720  }
82721
82722  warnIfDestroyed() {
82723    if (NG_DEV_MODE && this._destroyed) {
82724      console.warn(formatRuntimeError(406
82725      /* RuntimeErrorCode.APPLICATION_REF_ALREADY_DESTROYED */
82726      , 'This instance of the `ApplicationRef` has already been destroyed.'));
82727    }
82728  }
82729
82730}
82731
82732ApplicationRef.ɵfac = function ApplicationRef_Factory(t) {
82733  return new (t || ApplicationRef)(ɵɵinject(NgZone), ɵɵinject(EnvironmentInjector), ɵɵinject(ErrorHandler));
82734};
82735
82736ApplicationRef.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
82737  token: ApplicationRef,
82738  factory: ApplicationRef.ɵfac,
82739  providedIn: 'root'
82740});
82741
82742(function () {
82743  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ApplicationRef, [{
82744    type: Injectable,
82745    args: [{
82746      providedIn: 'root'
82747    }]
82748  }], function () {
82749    return [{
82750      type: NgZone
82751    }, {
82752      type: EnvironmentInjector
82753    }, {
82754      type: ErrorHandler
82755    }];
82756  }, null);
82757})();
82758
82759function remove(list, el) {
82760  const index = list.indexOf(el);
82761
82762  if (index > -1) {
82763    list.splice(index, 1);
82764  }
82765}
82766
82767function _lastDefined(args) {
82768  for (let i = args.length - 1; i >= 0; i--) {
82769    if (args[i] !== undefined) {
82770      return args[i];
82771    }
82772  }
82773
82774  return undefined;
82775}
82776
82777function _mergeArrays(parts) {
82778  const result = [];
82779  parts.forEach(part => part && result.push(...part));
82780  return result;
82781}
82782/**
82783 * @license
82784 * Copyright Google LLC All Rights Reserved.
82785 *
82786 * Use of this source code is governed by an MIT-style license that can be
82787 * found in the LICENSE file at https://angular.io/license
82788 */
82789
82790/**
82791 * This file is used to control if the default rendering pipeline should be `ViewEngine` or `Ivy`.
82792 *
82793 * For more information on how to run and debug tests with either Ivy or View Engine (legacy),
82794 * please see [BAZEL.md](./docs/BAZEL.md).
82795 */
82796
82797
82798let _devMode = true;
82799let _runModeLocked = false;
82800/**
82801 * Returns whether Angular is in development mode. After called once,
82802 * the value is locked and won't change any more.
82803 *
82804 * By default, this is true, unless a user calls `enableProdMode` before calling this.
82805 *
82806 * @publicApi
82807 */
82808
82809function isDevMode() {
82810  _runModeLocked = true;
82811  return _devMode;
82812}
82813/**
82814 * Disable Angular's development mode, which turns off assertions and other
82815 * checks within the framework.
82816 *
82817 * One important assertion this disables verifies that a change detection pass
82818 * does not result in additional changes to any bindings (also known as
82819 * unidirectional data flow).
82820 *
82821 * @publicApi
82822 */
82823
82824
82825function enableProdMode() {
82826  if (_runModeLocked) {
82827    throw new Error('Cannot enable prod mode after platform setup.');
82828  } // The below check is there so when ngDevMode is set via terser
82829  // `global['ngDevMode'] = false;` is also dropped.
82830
82831
82832  if (typeof ngDevMode === 'undefined' || ngDevMode) {
82833    _global['ngDevMode'] = false;
82834  }
82835
82836  _devMode = false;
82837}
82838/**
82839 * @license
82840 * Copyright Google LLC All Rights Reserved.
82841 *
82842 * Use of this source code is governed by an MIT-style license that can be
82843 * found in the LICENSE file at https://angular.io/license
82844 */
82845
82846/**
82847 * @license
82848 * Copyright Google LLC All Rights Reserved.
82849 *
82850 * Use of this source code is governed by an MIT-style license that can be
82851 * found in the LICENSE file at https://angular.io/license
82852 */
82853
82854/**
82855 * @license
82856 * Copyright Google LLC All Rights Reserved.
82857 *
82858 * Use of this source code is governed by an MIT-style license that can be
82859 * found in the LICENSE file at https://angular.io/license
82860 */
82861
82862/**
82863 * Returns the NgModuleFactory with the given id (specified using [@NgModule.id
82864 * field](api/core/NgModule#id)), if it exists and has been loaded. Factories for NgModules that do
82865 * not specify an `id` cannot be retrieved. Throws if an NgModule cannot be found.
82866 * @publicApi
82867 * @deprecated Use `getNgModuleById` instead.
82868 */
82869
82870
82871function getModuleFactory(id) {
82872  const type = getRegisteredNgModuleType(id);
82873  if (!type) throw noModuleError(id);
82874  return new NgModuleFactory(type);
82875}
82876/**
82877 * Returns the NgModule class with the given id (specified using [@NgModule.id
82878 * field](api/core/NgModule#id)), if it exists and has been loaded. Classes for NgModules that do
82879 * not specify an `id` cannot be retrieved. Throws if an NgModule cannot be found.
82880 * @publicApi
82881 */
82882
82883
82884function getNgModuleById(id) {
82885  const type = getRegisteredNgModuleType(id);
82886  if (!type) throw noModuleError(id);
82887  return type;
82888}
82889
82890function noModuleError(id) {
82891  return new Error(`No module with ID ${id} loaded`);
82892}
82893/**
82894 * @license
82895 * Copyright Google LLC All Rights Reserved.
82896 *
82897 * Use of this source code is governed by an MIT-style license that can be
82898 * found in the LICENSE file at https://angular.io/license
82899 */
82900
82901/**
82902 * Base class that provides change detection functionality.
82903 * A change-detection tree collects all views that are to be checked for changes.
82904 * Use the methods to add and remove views from the tree, initiate change-detection,
82905 * and explicitly mark views as _dirty_, meaning that they have changed and need to be re-rendered.
82906 *
82907 * @see [Using change detection hooks](guide/lifecycle-hooks#using-change-detection-hooks)
82908 * @see [Defining custom change detection](guide/lifecycle-hooks#defining-custom-change-detection)
82909 *
82910 * @usageNotes
82911 *
82912 * The following examples demonstrate how to modify default change-detection behavior
82913 * to perform explicit detection when needed.
82914 *
82915 * ### Use `markForCheck()` with `CheckOnce` strategy
82916 *
82917 * The following example sets the `OnPush` change-detection strategy for a component
82918 * (`CheckOnce`, rather than the default `CheckAlways`), then forces a second check
82919 * after an interval. See [live demo](https://plnkr.co/edit/GC512b?p=preview).
82920 *
82921 * <code-example path="core/ts/change_detect/change-detection.ts"
82922 * region="mark-for-check"></code-example>
82923 *
82924 * ### Detach change detector to limit how often check occurs
82925 *
82926 * The following example defines a component with a large list of read-only data
82927 * that is expected to change constantly, many times per second.
82928 * To improve performance, we want to check and update the list
82929 * less often than the changes actually occur. To do that, we detach
82930 * the component's change detector and perform an explicit local check every five seconds.
82931 *
82932 * <code-example path="core/ts/change_detect/change-detection.ts" region="detach"></code-example>
82933 *
82934 *
82935 * ### Reattaching a detached component
82936 *
82937 * The following example creates a component displaying live data.
82938 * The component detaches its change detector from the main change detector tree
82939 * when the `live` property is set to false, and reattaches it when the property
82940 * becomes true.
82941 *
82942 * <code-example path="core/ts/change_detect/change-detection.ts" region="reattach"></code-example>
82943 *
82944 * @publicApi
82945 */
82946
82947
82948class ChangeDetectorRef {}
82949/**
82950 * @internal
82951 * @nocollapse
82952 */
82953
82954
82955ChangeDetectorRef.__NG_ELEMENT_ID__ = injectChangeDetectorRef;
82956/** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
82957
82958function injectChangeDetectorRef(flags) {
82959  return createViewRef(getCurrentTNode(), getLView(), (flags & 16
82960  /* InternalInjectFlags.ForPipe */
82961  ) === 16
82962  /* InternalInjectFlags.ForPipe */
82963  );
82964}
82965/**
82966 * Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
82967 *
82968 * @param tNode The node that is requesting a ChangeDetectorRef
82969 * @param lView The view to which the node belongs
82970 * @param isPipe Whether the view is being injected into a pipe.
82971 * @returns The ChangeDetectorRef to use
82972 */
82973
82974
82975function createViewRef(tNode, lView, isPipe) {
82976  if (isComponentHost(tNode) && !isPipe) {
82977    // The LView represents the location where the component is declared.
82978    // Instead we want the LView for the component View and so we need to look it up.
82979    const componentView = getComponentLViewByIndex(tNode.index, lView); // look down
82980
82981    return new ViewRef$1(componentView, componentView);
82982  } else if (tNode.type & (3
82983  /* TNodeType.AnyRNode */
82984  | 12
82985  /* TNodeType.AnyContainer */
82986  | 32
82987  /* TNodeType.Icu */
82988  )) {
82989    // The LView represents the location where the injection is requested from.
82990    // We need to locate the containing LView (in case where the `lView` is an embedded view)
82991    const hostComponentView = lView[DECLARATION_COMPONENT_VIEW]; // look up
82992
82993    return new ViewRef$1(hostComponentView, lView);
82994  }
82995
82996  return null;
82997}
82998/**
82999 * @license
83000 * Copyright Google LLC All Rights Reserved.
83001 *
83002 * Use of this source code is governed by an MIT-style license that can be
83003 * found in the LICENSE file at https://angular.io/license
83004 */
83005
83006/**
83007 * Represents an Angular [view](guide/glossary#view "Definition").
83008 *
83009 * @see {@link ChangeDetectorRef#usage-notes Change detection usage}
83010 *
83011 * @publicApi
83012 */
83013
83014
83015class ViewRef extends ChangeDetectorRef {}
83016/**
83017 * Represents an Angular [view](guide/glossary#view) in a view container.
83018 * An [embedded view](guide/glossary#view-tree) can be referenced from a component
83019 * other than the hosting component whose template defines it, or it can be defined
83020 * independently by a `TemplateRef`.
83021 *
83022 * Properties of elements in a view can change, but the structure (number and order) of elements in
83023 * a view cannot. Change the structure of elements by inserting, moving, or
83024 * removing nested views in a view container.
83025 *
83026 * @see `ViewContainerRef`
83027 *
83028 * @usageNotes
83029 *
83030 * The following template breaks down into two separate `TemplateRef` instances,
83031 * an outer one and an inner one.
83032 *
83033 * ```
83034 * Count: {{items.length}}
83035 * <ul>
83036 *   <li *ngFor="let  item of items">{{item}}</li>
83037 * </ul>
83038 * ```
83039 *
83040 * This is the outer `TemplateRef`:
83041 *
83042 * ```
83043 * Count: {{items.length}}
83044 * <ul>
83045 *   <ng-template ngFor let-item [ngForOf]="items"></ng-template>
83046 * </ul>
83047 * ```
83048 *
83049 * This is the inner `TemplateRef`:
83050 *
83051 * ```
83052 *   <li>{{item}}</li>
83053 * ```
83054 *
83055 * The outer and inner `TemplateRef` instances are assembled into views as follows:
83056 *
83057 * ```
83058 * <!-- ViewRef: outer-0 -->
83059 * Count: 2
83060 * <ul>
83061 *   <ng-template view-container-ref></ng-template>
83062 *   <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
83063 *   <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
83064 * </ul>
83065 * <!-- /ViewRef: outer-0 -->
83066 * ```
83067 * @publicApi
83068 */
83069
83070
83071class EmbeddedViewRef extends ViewRef {}
83072/**
83073 * @license
83074 * Copyright Google LLC All Rights Reserved.
83075 *
83076 * Use of this source code is governed by an MIT-style license that can be
83077 * found in the LICENSE file at https://angular.io/license
83078 */
83079
83080/**
83081 * @license
83082 * Copyright Google LLC All Rights Reserved.
83083 *
83084 * Use of this source code is governed by an MIT-style license that can be
83085 * found in the LICENSE file at https://angular.io/license
83086 */
83087// This file exists for easily patching NgModuleFactoryLoader in g3
83088
83089
83090var ng_module_factory_loader_impl = {};
83091/**
83092 * @license
83093 * Copyright Google LLC All Rights Reserved.
83094 *
83095 * Use of this source code is governed by an MIT-style license that can be
83096 * found in the LICENSE file at https://angular.io/license
83097 */
83098
83099/**
83100 * @publicApi
83101 */
83102
83103class DebugEventListener {
83104  constructor(name, callback) {
83105    this.name = name;
83106    this.callback = callback;
83107  }
83108
83109}
83110/**
83111 * @publicApi
83112 */
83113
83114
83115function asNativeElements(debugEls) {
83116  return debugEls.map(el => el.nativeElement);
83117}
83118/**
83119 * @publicApi
83120 */
83121
83122
83123class DebugNode {
83124  constructor(nativeNode) {
83125    this.nativeNode = nativeNode;
83126  }
83127  /**
83128   * The `DebugElement` parent. Will be `null` if this is the root element.
83129   */
83130
83131
83132  get parent() {
83133    const parent = this.nativeNode.parentNode;
83134    return parent ? new DebugElement(parent) : null;
83135  }
83136  /**
83137   * The host dependency injector. For example, the root element's component instance injector.
83138   */
83139
83140
83141  get injector() {
83142    return getInjector(this.nativeNode);
83143  }
83144  /**
83145   * The element's own component instance, if it has one.
83146   */
83147
83148
83149  get componentInstance() {
83150    const nativeElement = this.nativeNode;
83151    return nativeElement && (getComponent(nativeElement) || getOwningComponent(nativeElement));
83152  }
83153  /**
83154   * An object that provides parent context for this element. Often an ancestor component instance
83155   * that governs this element.
83156   *
83157   * When an element is repeated within *ngFor, the context is an `NgForOf` whose `$implicit`
83158   * property is the value of the row instance value. For example, the `hero` in `*ngFor="let hero
83159   * of heroes"`.
83160   */
83161
83162
83163  get context() {
83164    return getComponent(this.nativeNode) || getContext(this.nativeNode);
83165  }
83166  /**
83167   * The callbacks attached to the component's @Output properties and/or the element's event
83168   * properties.
83169   */
83170
83171
83172  get listeners() {
83173    return getListeners(this.nativeNode).filter(listener => listener.type === 'dom');
83174  }
83175  /**
83176   * Dictionary of objects associated with template local variables (e.g. #foo), keyed by the local
83177   * variable name.
83178   */
83179
83180
83181  get references() {
83182    return getLocalRefs(this.nativeNode);
83183  }
83184  /**
83185   * This component's injector lookup tokens. Includes the component itself plus the tokens that the
83186   * component lists in its providers metadata.
83187   */
83188
83189
83190  get providerTokens() {
83191    return getInjectionTokens(this.nativeNode);
83192  }
83193
83194}
83195/**
83196 * @publicApi
83197 *
83198 * @see [Component testing scenarios](guide/testing-components-scenarios)
83199 * @see [Basics of testing components](guide/testing-components-basics)
83200 * @see [Testing utility APIs](guide/testing-utility-apis)
83201 */
83202
83203
83204class DebugElement extends DebugNode {
83205  constructor(nativeNode) {
83206    ngDevMode && assertDomNode(nativeNode);
83207    super(nativeNode);
83208  }
83209  /**
83210   * The underlying DOM element at the root of the component.
83211   */
83212
83213
83214  get nativeElement() {
83215    return this.nativeNode.nodeType == Node.ELEMENT_NODE ? this.nativeNode : null;
83216  }
83217  /**
83218   * The element tag name, if it is an element.
83219   */
83220
83221
83222  get name() {
83223    const context = getLContext(this.nativeNode);
83224    const lView = context ? context.lView : null;
83225
83226    if (lView !== null) {
83227      const tData = lView[TVIEW].data;
83228      const tNode = tData[context.nodeIndex];
83229      return tNode.value;
83230    } else {
83231      return this.nativeNode.nodeName;
83232    }
83233  }
83234  /**
83235   *  Gets a map of property names to property values for an element.
83236   *
83237   *  This map includes:
83238   *  - Regular property bindings (e.g. `[id]="id"`)
83239   *  - Host property bindings (e.g. `host: { '[id]': "id" }`)
83240   *  - Interpolated property bindings (e.g. `id="{{ value }}")
83241   *
83242   *  It does not include:
83243   *  - input property bindings (e.g. `[myCustomInput]="value"`)
83244   *  - attribute bindings (e.g. `[attr.role]="menu"`)
83245   */
83246
83247
83248  get properties() {
83249    const context = getLContext(this.nativeNode);
83250    const lView = context ? context.lView : null;
83251
83252    if (lView === null) {
83253      return {};
83254    }
83255
83256    const tData = lView[TVIEW].data;
83257    const tNode = tData[context.nodeIndex];
83258    const properties = {}; // Collect properties from the DOM.
83259
83260    copyDomProperties(this.nativeElement, properties); // Collect properties from the bindings. This is needed for animation renderer which has
83261    // synthetic properties which don't get reflected into the DOM.
83262
83263    collectPropertyBindings(properties, tNode, lView, tData);
83264    return properties;
83265  }
83266  /**
83267   *  A map of attribute names to attribute values for an element.
83268   */
83269
83270
83271  get attributes() {
83272    const attributes = {};
83273    const element = this.nativeElement;
83274
83275    if (!element) {
83276      return attributes;
83277    }
83278
83279    const context = getLContext(element);
83280    const lView = context ? context.lView : null;
83281
83282    if (lView === null) {
83283      return {};
83284    }
83285
83286    const tNodeAttrs = lView[TVIEW].data[context.nodeIndex].attrs;
83287    const lowercaseTNodeAttrs = []; // For debug nodes we take the element's attribute directly from the DOM since it allows us
83288    // to account for ones that weren't set via bindings (e.g. ViewEngine keeps track of the ones
83289    // that are set through `Renderer2`). The problem is that the browser will lowercase all names,
83290    // however since we have the attributes already on the TNode, we can preserve the case by going
83291    // through them once, adding them to the `attributes` map and putting their lower-cased name
83292    // into an array. Afterwards when we're going through the native DOM attributes, we can check
83293    // whether we haven't run into an attribute already through the TNode.
83294
83295    if (tNodeAttrs) {
83296      let i = 0;
83297
83298      while (i < tNodeAttrs.length) {
83299        const attrName = tNodeAttrs[i]; // Stop as soon as we hit a marker. We only care about the regular attributes. Everything
83300        // else will be handled below when we read the final attributes off the DOM.
83301
83302        if (typeof attrName !== 'string') break;
83303        const attrValue = tNodeAttrs[i + 1];
83304        attributes[attrName] = attrValue;
83305        lowercaseTNodeAttrs.push(attrName.toLowerCase());
83306        i += 2;
83307      }
83308    }
83309
83310    const eAttrs = element.attributes;
83311
83312    for (let i = 0; i < eAttrs.length; i++) {
83313      const attr = eAttrs[i];
83314      const lowercaseName = attr.name.toLowerCase(); // Make sure that we don't assign the same attribute both in its
83315      // case-sensitive form and the lower-cased one from the browser.
83316
83317      if (lowercaseTNodeAttrs.indexOf(lowercaseName) === -1) {
83318        // Save the lowercase name to align the behavior between browsers.
83319        // IE preserves the case, while all other browser convert it to lower case.
83320        attributes[lowercaseName] = attr.value;
83321      }
83322    }
83323
83324    return attributes;
83325  }
83326  /**
83327   * The inline styles of the DOM element.
83328   *
83329   * Will be `null` if there is no `style` property on the underlying DOM element.
83330   *
83331   * @see [ElementCSSInlineStyle](https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style)
83332   */
83333
83334
83335  get styles() {
83336    if (this.nativeElement && this.nativeElement.style) {
83337      return this.nativeElement.style;
83338    }
83339
83340    return {};
83341  }
83342  /**
83343   * A map containing the class names on the element as keys.
83344   *
83345   * This map is derived from the `className` property of the DOM element.
83346   *
83347   * Note: The values of this object will always be `true`. The class key will not appear in the KV
83348   * object if it does not exist on the element.
83349   *
83350   * @see [Element.className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className)
83351   */
83352
83353
83354  get classes() {
83355    const result = {};
83356    const element = this.nativeElement; // SVG elements return an `SVGAnimatedString` instead of a plain string for the `className`.
83357
83358    const className = element.className;
83359    const classes = typeof className !== 'string' ? className.baseVal.split(' ') : className.split(' ');
83360    classes.forEach(value => result[value] = true);
83361    return result;
83362  }
83363  /**
83364   * The `childNodes` of the DOM element as a `DebugNode` array.
83365   *
83366   * @see [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes)
83367   */
83368
83369
83370  get childNodes() {
83371    const childNodes = this.nativeNode.childNodes;
83372    const children = [];
83373
83374    for (let i = 0; i < childNodes.length; i++) {
83375      const element = childNodes[i];
83376      children.push(getDebugNode(element));
83377    }
83378
83379    return children;
83380  }
83381  /**
83382   * The immediate `DebugElement` children. Walk the tree by descending through `children`.
83383   */
83384
83385
83386  get children() {
83387    const nativeElement = this.nativeElement;
83388    if (!nativeElement) return [];
83389    const childNodes = nativeElement.children;
83390    const children = [];
83391
83392    for (let i = 0; i < childNodes.length; i++) {
83393      const element = childNodes[i];
83394      children.push(getDebugNode(element));
83395    }
83396
83397    return children;
83398  }
83399  /**
83400   * @returns the first `DebugElement` that matches the predicate at any depth in the subtree.
83401   */
83402
83403
83404  query(predicate) {
83405    const results = this.queryAll(predicate);
83406    return results[0] || null;
83407  }
83408  /**
83409   * @returns All `DebugElement` matches for the predicate at any depth in the subtree.
83410   */
83411
83412
83413  queryAll(predicate) {
83414    const matches = [];
83415
83416    _queryAll(this, predicate, matches, true);
83417
83418    return matches;
83419  }
83420  /**
83421   * @returns All `DebugNode` matches for the predicate at any depth in the subtree.
83422   */
83423
83424
83425  queryAllNodes(predicate) {
83426    const matches = [];
83427
83428    _queryAll(this, predicate, matches, false);
83429
83430    return matches;
83431  }
83432  /**
83433   * Triggers the event by its name if there is a corresponding listener in the element's
83434   * `listeners` collection.
83435   *
83436   * If the event lacks a listener or there's some other problem, consider
83437   * calling `nativeElement.dispatchEvent(eventObject)`.
83438   *
83439   * @param eventName The name of the event to trigger
83440   * @param eventObj The _event object_ expected by the handler
83441   *
83442   * @see [Testing components scenarios](guide/testing-components-scenarios#trigger-event-handler)
83443   */
83444
83445
83446  triggerEventHandler(eventName, eventObj) {
83447    const node = this.nativeNode;
83448    const invokedListeners = [];
83449    this.listeners.forEach(listener => {
83450      if (listener.name === eventName) {
83451        const callback = listener.callback;
83452        callback.call(node, eventObj);
83453        invokedListeners.push(callback);
83454      }
83455    }); // We need to check whether `eventListeners` exists, because it's something
83456    // that Zone.js only adds to `EventTarget` in browser environments.
83457
83458    if (typeof node.eventListeners === 'function') {
83459      // Note that in Ivy we wrap event listeners with a call to `event.preventDefault` in some
83460      // cases. We use '__ngUnwrap__' as a special token that gives us access to the actual event
83461      // listener.
83462      node.eventListeners(eventName).forEach(listener => {
83463        // In order to ensure that we can detect the special __ngUnwrap__ token described above, we
83464        // use `toString` on the listener and see if it contains the token. We use this approach to
83465        // ensure that it still worked with compiled code since it cannot remove or rename string
83466        // literals. We also considered using a special function name (i.e. if(listener.name ===
83467        // special)) but that was more cumbersome and we were also concerned the compiled code could
83468        // strip the name, turning the condition in to ("" === "") and always returning true.
83469        if (listener.toString().indexOf('__ngUnwrap__') !== -1) {
83470          const unwrappedListener = listener('__ngUnwrap__');
83471          return invokedListeners.indexOf(unwrappedListener) === -1 && unwrappedListener.call(node, eventObj);
83472        }
83473      });
83474    }
83475  }
83476
83477}
83478
83479function copyDomProperties(element, properties) {
83480  if (element) {
83481    // Skip own properties (as those are patched)
83482    let obj = Object.getPrototypeOf(element);
83483    const NodePrototype = Node.prototype;
83484
83485    while (obj !== null && obj !== NodePrototype) {
83486      const descriptors = Object.getOwnPropertyDescriptors(obj);
83487
83488      for (let key in descriptors) {
83489        if (!key.startsWith('__') && !key.startsWith('on')) {
83490          // don't include properties starting with `__` and `on`.
83491          // `__` are patched values which should not be included.
83492          // `on` are listeners which also should not be included.
83493          const value = element[key];
83494
83495          if (isPrimitiveValue(value)) {
83496            properties[key] = value;
83497          }
83498        }
83499      }
83500
83501      obj = Object.getPrototypeOf(obj);
83502    }
83503  }
83504}
83505
83506function isPrimitiveValue(value) {
83507  return typeof value === 'string' || typeof value === 'boolean' || typeof value === 'number' || value === null;
83508}
83509
83510function _queryAll(parentElement, predicate, matches, elementsOnly) {
83511  const context = getLContext(parentElement.nativeNode);
83512  const lView = context ? context.lView : null;
83513
83514  if (lView !== null) {
83515    const parentTNode = lView[TVIEW].data[context.nodeIndex];
83516
83517    _queryNodeChildren(parentTNode, lView, predicate, matches, elementsOnly, parentElement.nativeNode);
83518  } else {
83519    // If the context is null, then `parentElement` was either created with Renderer2 or native DOM
83520    // APIs.
83521    _queryNativeNodeDescendants(parentElement.nativeNode, predicate, matches, elementsOnly);
83522  }
83523}
83524/**
83525 * Recursively match the current TNode against the predicate, and goes on with the next ones.
83526 *
83527 * @param tNode the current TNode
83528 * @param lView the LView of this TNode
83529 * @param predicate the predicate to match
83530 * @param matches the list of positive matches
83531 * @param elementsOnly whether only elements should be searched
83532 * @param rootNativeNode the root native node on which predicate should not be matched
83533 */
83534
83535
83536function _queryNodeChildren(tNode, lView, predicate, matches, elementsOnly, rootNativeNode) {
83537  ngDevMode && assertTNodeForLView(tNode, lView);
83538  const nativeNode = getNativeByTNodeOrNull(tNode, lView); // For each type of TNode, specific logic is executed.
83539
83540  if (tNode.type & (3
83541  /* TNodeType.AnyRNode */
83542  | 8
83543  /* TNodeType.ElementContainer */
83544  )) {
83545    // Case 1: the TNode is an element
83546    // The native node has to be checked.
83547    _addQueryMatch(nativeNode, predicate, matches, elementsOnly, rootNativeNode);
83548
83549    if (isComponentHost(tNode)) {
83550      // If the element is the host of a component, then all nodes in its view have to be processed.
83551      // Note: the component's content (tNode.child) will be processed from the insertion points.
83552      const componentView = getComponentLViewByIndex(tNode.index, lView);
83553
83554      if (componentView && componentView[TVIEW].firstChild) {
83555        _queryNodeChildren(componentView[TVIEW].firstChild, componentView, predicate, matches, elementsOnly, rootNativeNode);
83556      }
83557    } else {
83558      if (tNode.child) {
83559        // Otherwise, its children have to be processed.
83560        _queryNodeChildren(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
83561      } // We also have to query the DOM directly in order to catch elements inserted through
83562      // Renderer2. Note that this is __not__ optimal, because we're walking similar trees multiple
83563      // times. ViewEngine could do it more efficiently, because all the insertions go through
83564      // Renderer2, however that's not the case in Ivy. This approach is being used because:
83565      // 1. Matching the ViewEngine behavior would mean potentially introducing a dependency
83566      //    from `Renderer2` to Ivy which could bring Ivy code into ViewEngine.
83567      // 2. It allows us to capture nodes that were inserted directly via the DOM.
83568
83569
83570      nativeNode && _queryNativeNodeDescendants(nativeNode, predicate, matches, elementsOnly);
83571    } // In all cases, if a dynamic container exists for this node, each view inside it has to be
83572    // processed.
83573
83574
83575    const nodeOrContainer = lView[tNode.index];
83576
83577    if (isLContainer(nodeOrContainer)) {
83578      _queryNodeChildrenInContainer(nodeOrContainer, predicate, matches, elementsOnly, rootNativeNode);
83579    }
83580  } else if (tNode.type & 4
83581  /* TNodeType.Container */
83582  ) {
83583    // Case 2: the TNode is a container
83584    // The native node has to be checked.
83585    const lContainer = lView[tNode.index];
83586
83587    _addQueryMatch(lContainer[NATIVE], predicate, matches, elementsOnly, rootNativeNode); // Each view inside the container has to be processed.
83588
83589
83590    _queryNodeChildrenInContainer(lContainer, predicate, matches, elementsOnly, rootNativeNode);
83591  } else if (tNode.type & 16
83592  /* TNodeType.Projection */
83593  ) {
83594    // Case 3: the TNode is a projection insertion point (i.e. a <ng-content>).
83595    // The nodes projected at this location all need to be processed.
83596    const componentView = lView[DECLARATION_COMPONENT_VIEW];
83597    const componentHost = componentView[T_HOST];
83598    const head = componentHost.projection[tNode.projection];
83599
83600    if (Array.isArray(head)) {
83601      for (let nativeNode of head) {
83602        _addQueryMatch(nativeNode, predicate, matches, elementsOnly, rootNativeNode);
83603      }
83604    } else if (head) {
83605      const nextLView = componentView[PARENT];
83606      const nextTNode = nextLView[TVIEW].data[head.index];
83607
83608      _queryNodeChildren(nextTNode, nextLView, predicate, matches, elementsOnly, rootNativeNode);
83609    }
83610  } else if (tNode.child) {
83611    // Case 4: the TNode is a view.
83612    _queryNodeChildren(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
83613  } // We don't want to go to the next sibling of the root node.
83614
83615
83616  if (rootNativeNode !== nativeNode) {
83617    // To determine the next node to be processed, we need to use the next or the projectionNext
83618    // link, depending on whether the current node has been projected.
83619    const nextTNode = tNode.flags & 4
83620    /* TNodeFlags.isProjected */
83621    ? tNode.projectionNext : tNode.next;
83622
83623    if (nextTNode) {
83624      _queryNodeChildren(nextTNode, lView, predicate, matches, elementsOnly, rootNativeNode);
83625    }
83626  }
83627}
83628/**
83629 * Process all TNodes in a given container.
83630 *
83631 * @param lContainer the container to be processed
83632 * @param predicate the predicate to match
83633 * @param matches the list of positive matches
83634 * @param elementsOnly whether only elements should be searched
83635 * @param rootNativeNode the root native node on which predicate should not be matched
83636 */
83637
83638
83639function _queryNodeChildrenInContainer(lContainer, predicate, matches, elementsOnly, rootNativeNode) {
83640  for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
83641    const childView = lContainer[i];
83642    const firstChild = childView[TVIEW].firstChild;
83643
83644    if (firstChild) {
83645      _queryNodeChildren(firstChild, childView, predicate, matches, elementsOnly, rootNativeNode);
83646    }
83647  }
83648}
83649/**
83650 * Match the current native node against the predicate.
83651 *
83652 * @param nativeNode the current native node
83653 * @param predicate the predicate to match
83654 * @param matches the list of positive matches
83655 * @param elementsOnly whether only elements should be searched
83656 * @param rootNativeNode the root native node on which predicate should not be matched
83657 */
83658
83659
83660function _addQueryMatch(nativeNode, predicate, matches, elementsOnly, rootNativeNode) {
83661  if (rootNativeNode !== nativeNode) {
83662    const debugNode = getDebugNode(nativeNode);
83663
83664    if (!debugNode) {
83665      return;
83666    } // Type of the "predicate and "matches" array are set based on the value of
83667    // the "elementsOnly" parameter. TypeScript is not able to properly infer these
83668    // types with generics, so we manually cast the parameters accordingly.
83669
83670
83671    if (elementsOnly && debugNode instanceof DebugElement && predicate(debugNode) && matches.indexOf(debugNode) === -1) {
83672      matches.push(debugNode);
83673    } else if (!elementsOnly && predicate(debugNode) && matches.indexOf(debugNode) === -1) {
83674      matches.push(debugNode);
83675    }
83676  }
83677}
83678/**
83679 * Match all the descendants of a DOM node against a predicate.
83680 *
83681 * @param nativeNode the current native node
83682 * @param predicate the predicate to match
83683 * @param matches the list where matches are stored
83684 * @param elementsOnly whether only elements should be searched
83685 */
83686
83687
83688function _queryNativeNodeDescendants(parentNode, predicate, matches, elementsOnly) {
83689  const nodes = parentNode.childNodes;
83690  const length = nodes.length;
83691
83692  for (let i = 0; i < length; i++) {
83693    const node = nodes[i];
83694    const debugNode = getDebugNode(node);
83695
83696    if (debugNode) {
83697      if (elementsOnly && debugNode instanceof DebugElement && predicate(debugNode) && matches.indexOf(debugNode) === -1) {
83698        matches.push(debugNode);
83699      } else if (!elementsOnly && predicate(debugNode) && matches.indexOf(debugNode) === -1) {
83700        matches.push(debugNode);
83701      }
83702
83703      _queryNativeNodeDescendants(node, predicate, matches, elementsOnly);
83704    }
83705  }
83706}
83707/**
83708 * Iterates through the property bindings for a given node and generates
83709 * a map of property names to values. This map only contains property bindings
83710 * defined in templates, not in host bindings.
83711 */
83712
83713
83714function collectPropertyBindings(properties, tNode, lView, tData) {
83715  let bindingIndexes = tNode.propertyBindings;
83716
83717  if (bindingIndexes !== null) {
83718    for (let i = 0; i < bindingIndexes.length; i++) {
83719      const bindingIndex = bindingIndexes[i];
83720      const propMetadata = tData[bindingIndex];
83721      const metadataParts = propMetadata.split(INTERPOLATION_DELIMITER);
83722      const propertyName = metadataParts[0];
83723
83724      if (metadataParts.length > 1) {
83725        let value = metadataParts[1];
83726
83727        for (let j = 1; j < metadataParts.length - 1; j++) {
83728          value += renderStringify(lView[bindingIndex + j - 1]) + metadataParts[j + 1];
83729        }
83730
83731        properties[propertyName] = value;
83732      } else {
83733        properties[propertyName] = lView[bindingIndex];
83734      }
83735    }
83736  }
83737} // Need to keep the nodes in a global Map so that multiple angular apps are supported.
83738
83739
83740const _nativeNodeToDebugNode = new Map();
83741
83742const NG_DEBUG_PROPERTY = '__ng_debug__';
83743/**
83744 * @publicApi
83745 */
83746
83747function getDebugNode(nativeNode) {
83748  if (nativeNode instanceof Node) {
83749    if (!nativeNode.hasOwnProperty(NG_DEBUG_PROPERTY)) {
83750      nativeNode[NG_DEBUG_PROPERTY] = nativeNode.nodeType == Node.ELEMENT_NODE ? new DebugElement(nativeNode) : new DebugNode(nativeNode);
83751    }
83752
83753    return nativeNode[NG_DEBUG_PROPERTY];
83754  }
83755
83756  return null;
83757} // TODO: cleanup all references to this function and remove it.
83758
83759
83760function getDebugNodeR2(_nativeNode) {
83761  return null;
83762}
83763
83764function getAllDebugNodes() {
83765  return Array.from(_nativeNodeToDebugNode.values());
83766}
83767
83768function indexDebugNode(node) {
83769  _nativeNodeToDebugNode.set(node.nativeNode, node);
83770}
83771
83772function removeDebugNodeFromIndex(node) {
83773  _nativeNodeToDebugNode.delete(node.nativeNode);
83774}
83775/**
83776 * @license
83777 * Copyright Google LLC All Rights Reserved.
83778 *
83779 * Use of this source code is governed by an MIT-style license that can be
83780 * found in the LICENSE file at https://angular.io/license
83781 */
83782
83783
83784class DefaultIterableDifferFactory {
83785  constructor() {}
83786
83787  supports(obj) {
83788    return isListLikeIterable(obj);
83789  }
83790
83791  create(trackByFn) {
83792    return new DefaultIterableDiffer(trackByFn);
83793  }
83794
83795}
83796
83797const trackByIdentity = (index, item) => item;
83798/**
83799 * @deprecated v4.0.0 - Should not be part of public API.
83800 * @publicApi
83801 */
83802
83803
83804class DefaultIterableDiffer {
83805  constructor(trackByFn) {
83806    this.length = 0; // Keeps track of the used records at any point in time (during & across `_check()` calls)
83807
83808    this._linkedRecords = null; // Keeps track of the removed records at any point in time during `_check()` calls.
83809
83810    this._unlinkedRecords = null;
83811    this._previousItHead = null;
83812    this._itHead = null;
83813    this._itTail = null;
83814    this._additionsHead = null;
83815    this._additionsTail = null;
83816    this._movesHead = null;
83817    this._movesTail = null;
83818    this._removalsHead = null;
83819    this._removalsTail = null; // Keeps track of records where custom track by is the same, but item identity has changed
83820
83821    this._identityChangesHead = null;
83822    this._identityChangesTail = null;
83823    this._trackByFn = trackByFn || trackByIdentity;
83824  }
83825
83826  forEachItem(fn) {
83827    let record;
83828
83829    for (record = this._itHead; record !== null; record = record._next) {
83830      fn(record);
83831    }
83832  }
83833
83834  forEachOperation(fn) {
83835    let nextIt = this._itHead;
83836    let nextRemove = this._removalsHead;
83837    let addRemoveOffset = 0;
83838    let moveOffsets = null;
83839
83840    while (nextIt || nextRemove) {
83841      // Figure out which is the next record to process
83842      // Order: remove, add, move
83843      const record = !nextRemove || nextIt && nextIt.currentIndex < getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ? nextIt : nextRemove;
83844      const adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets);
83845      const currentIndex = record.currentIndex; // consume the item, and adjust the addRemoveOffset and update moveDistance if necessary
83846
83847      if (record === nextRemove) {
83848        addRemoveOffset--;
83849        nextRemove = nextRemove._nextRemoved;
83850      } else {
83851        nextIt = nextIt._next;
83852
83853        if (record.previousIndex == null) {
83854          addRemoveOffset++;
83855        } else {
83856          // INVARIANT:  currentIndex < previousIndex
83857          if (!moveOffsets) moveOffsets = [];
83858          const localMovePreviousIndex = adjPreviousIndex - addRemoveOffset;
83859          const localCurrentIndex = currentIndex - addRemoveOffset;
83860
83861          if (localMovePreviousIndex != localCurrentIndex) {
83862            for (let i = 0; i < localMovePreviousIndex; i++) {
83863              const offset = i < moveOffsets.length ? moveOffsets[i] : moveOffsets[i] = 0;
83864              const index = offset + i;
83865
83866              if (localCurrentIndex <= index && index < localMovePreviousIndex) {
83867                moveOffsets[i] = offset + 1;
83868              }
83869            }
83870
83871            const previousIndex = record.previousIndex;
83872            moveOffsets[previousIndex] = localCurrentIndex - localMovePreviousIndex;
83873          }
83874        }
83875      }
83876
83877      if (adjPreviousIndex !== currentIndex) {
83878        fn(record, adjPreviousIndex, currentIndex);
83879      }
83880    }
83881  }
83882
83883  forEachPreviousItem(fn) {
83884    let record;
83885
83886    for (record = this._previousItHead; record !== null; record = record._nextPrevious) {
83887      fn(record);
83888    }
83889  }
83890
83891  forEachAddedItem(fn) {
83892    let record;
83893
83894    for (record = this._additionsHead; record !== null; record = record._nextAdded) {
83895      fn(record);
83896    }
83897  }
83898
83899  forEachMovedItem(fn) {
83900    let record;
83901
83902    for (record = this._movesHead; record !== null; record = record._nextMoved) {
83903      fn(record);
83904    }
83905  }
83906
83907  forEachRemovedItem(fn) {
83908    let record;
83909
83910    for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
83911      fn(record);
83912    }
83913  }
83914
83915  forEachIdentityChange(fn) {
83916    let record;
83917
83918    for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) {
83919      fn(record);
83920    }
83921  }
83922
83923  diff(collection) {
83924    if (collection == null) collection = [];
83925
83926    if (!isListLikeIterable(collection)) {
83927      throw new RuntimeError(900
83928      /* RuntimeErrorCode.INVALID_DIFFER_INPUT */
vendor: 5,439 bytes, lines 83929-84094
83929      , ngDevMode && `Error trying to diff '${stringify(collection)}'. Only arrays and iterables are allowed`);
83930    }
83931
83932    if (this.check(collection)) {
83933      return this;
83934    } else {
83935      return null;
83936    }
83937  }
83938
83939  onDestroy() {}
83940
83941  check(collection) {
83942    this._reset();
83943
83944    let record = this._itHead;
83945    let mayBeDirty = false;
83946    let index;
83947    let item;
83948    let itemTrackBy;
83949
83950    if (Array.isArray(collection)) {
83951      this.length = collection.length;
83952
83953      for (let index = 0; index < this.length; index++) {
83954        item = collection[index];
83955        itemTrackBy = this._trackByFn(index, item);
83956
83957        if (record === null || !Object.is(record.trackById, itemTrackBy)) {
83958          record = this._mismatch(record, item, itemTrackBy, index);
83959          mayBeDirty = true;
83960        } else {
83961          if (mayBeDirty) {
83962            // TODO(misko): can we limit this to duplicates only?
83963            record = this._verifyReinsertion(record, item, itemTrackBy, index);
83964          }
83965
83966          if (!Object.is(record.item, item)) this._addIdentityChange(record, item);
83967        }
83968
83969        record = record._next;
83970      }
83971    } else {
83972      index = 0;
83973      iterateListLike(collection, item => {
83974        itemTrackBy = this._trackByFn(index, item);
83975
83976        if (record === null || !Object.is(record.trackById, itemTrackBy)) {
83977          record = this._mismatch(record, item, itemTrackBy, index);
83978          mayBeDirty = true;
83979        } else {
83980          if (mayBeDirty) {
83981            // TODO(misko): can we limit this to duplicates only?
83982            record = this._verifyReinsertion(record, item, itemTrackBy, index);
83983          }
83984
83985          if (!Object.is(record.item, item)) this._addIdentityChange(record, item);
83986        }
83987
83988        record = record._next;
83989        index++;
83990      });
83991      this.length = index;
83992    }
83993
83994    this._truncate(record);
83995
83996    this.collection = collection;
83997    return this.isDirty;
83998  }
83999  /* CollectionChanges is considered dirty if it has any additions, moves, removals, or identity
84000   * changes.
84001   */
84002
84003
84004  get isDirty() {
84005    return this._additionsHead !== null || this._movesHead !== null || this._removalsHead !== null || this._identityChangesHead !== null;
84006  }
84007  /**
84008   * Reset the state of the change objects to show no changes. This means set previousKey to
84009   * currentKey, and clear all of the queues (additions, moves, removals).
84010   * Set the previousIndexes of moved and added items to their currentIndexes
84011   * Reset the list of additions, moves and removals
84012   *
84013   * @internal
84014   */
84015
84016
84017  _reset() {
84018    if (this.isDirty) {
84019      let record;
84020
84021      for (record = this._previousItHead = this._itHead; record !== null; record = record._next) {
84022        record._nextPrevious = record._next;
84023      }
84024
84025      for (record = this._additionsHead; record !== null; record = record._nextAdded) {
84026        record.previousIndex = record.currentIndex;
84027      }
84028
84029      this._additionsHead = this._additionsTail = null;
84030
84031      for (record = this._movesHead; record !== null; record = record._nextMoved) {
84032        record.previousIndex = record.currentIndex;
84033      }
84034
84035      this._movesHead = this._movesTail = null;
84036      this._removalsHead = this._removalsTail = null;
84037      this._identityChangesHead = this._identityChangesTail = null; // TODO(vicb): when assert gets supported
84038      // assert(!this.isDirty);
84039    }
84040  }
84041  /**
84042   * This is the core function which handles differences between collections.
84043   *
84044   * - `record` is the record which we saw at this position last time. If null then it is a new
84045   *   item.
84046   * - `item` is the current item in the collection
84047   * - `index` is the position of the item in the collection
84048   *
84049   * @internal
84050   */
84051
84052
84053  _mismatch(record, item, itemTrackBy, index) {
84054    // The previous record after which we will append the current one.
84055    let previousRecord;
84056
84057    if (record === null) {
84058      previousRecord = this._itTail;
84059    } else {
84060      previousRecord = record._prev; // Remove the record from the collection since we know it does not match the item.
84061
84062      this._remove(record);
84063    } // See if we have evicted the item, which used to be at some anterior position of _itHead list.
84064
84065
84066    record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
84067
84068    if (record !== null) {
84069      // It is an item which we have evicted earlier: reinsert it back into the list.
84070      // But first we need to check if identity changed, so we can update in view if necessary.
84071      if (!Object.is(record.item, item)) this._addIdentityChange(record, item);
84072
84073      this._reinsertAfter(record, previousRecord, index);
84074    } else {
84075      // Attempt to see if the item is at some posterior position of _itHead list.
84076      record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
84077
84078      if (record !== null) {
84079        // We have the item in _itHead at/after `index` position. We need to move it forward in the
84080        // collection.
84081        // But first we need to check if identity changed, so we can update in view if necessary.
84082        if (!Object.is(record.item, item)) this._addIdentityChange(record, item);
84083
84084        this._moveAfter(record, previousRecord, index);
84085      } else {
84086        // It is a new item: add it.
84087        record = this._addAfter(new IterableChangeRecord_(item, itemTrackBy), previousRecord, index);
84088      }
84089    }
84090
84091    return record;
84092  }
84093  /**
84094   * This check is only needed if an array contains duplicates. (Sh
84094ort circuit of nothing dirty)
84095   *
84096   * Use case: `[a, a]` => `[b, a, a]`
84097   *
84098   * If we did not have this check then the insertion of `b` would:
84099   *   1) evict first `a`
84100   *   2) insert `b` at `0` index.
84101   *   3) leave `a` at index `1` as is. <-- this is wrong!
84102   *   3) reinsert `a` at index 2. <-- this is wrong!
84103   *
84104   * The correct behavior is:
84105   *   1) evict first `a`
84106   *   2) insert `b` at `0` index.
84107   *   3) reinsert `a` at index 1.
84108   *   3) move `a` at from `1` to `2`.
84109   *
84110   *
84111   * Double check that we have not evicted a duplicate item. We need to check if the item type may
84112   * have already been removed:
84113   * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
84114   * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
84115   * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
84116   * at the end.
84117   *
84118   * @internal
84119   */
84120
84121
84122  _verifyReinsertion(record, item, itemTrackBy, index) {
84123    let reinsertRecord = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
84124
84125    if (reinsertRecord !== null) {
84126      record = this._reinsertAfter(reinsertRecord, record._prev, index);
84127    } else if (record.currentIndex != index) {
84128      record.currentIndex = index;
84129
84130      this._addToMoves(record, index);
84131    }
84132
84133    return record;
84134  }
84135  /**
84136   * Get rid of any excess {@link IterableChangeRecord_}s from the previous collection
84137   *
84138   * - `record` The first excess {@link IterableChangeRecord_}.
84139   *
84140   * @internal
84141   */
84142
84143
84144  _truncate(record) {
84145    // Anything after that needs to be removed;
84146    while (record !== null) {
84147      const nextRecord = record._next;
84148
84149      this._addToRemovals(this._unlink(record));
84150
84151      record = nextRecord;
84152    }
84153
84154    if (this._unlinkedRecords !== null) {
84155      this._unlinkedRecords.clear();
84156    }
84157
84158    if (this._additionsTail !== null) {
84159      this._additionsTail._nextAdded = null;
84160    }
84161
84162    if (this._movesTail !== null) {
84163      this._movesTail._nextMoved = null;
84164    }
84165
84166    if (this._itTail !== null) {
84167      this._itTail._next = null;
84168    }
84169
84170    if (this._removalsTail !== null) {
84171      this._removalsTail._nextRemoved = null;
84172    }
84173
84174    if (this._identityChangesTail !== null) {
84175      this._identityChangesTail._nextIdentityChange = null;
84176    }
84177  }
84178  /** @internal */
84179
84180
84181  _reinsertAfter(record, prevRecord, index) {
84182    if (this._unlinkedRecords !== null) {
84183      this._unlinkedRecords.remove(record);
84184    }
84185
84186    const prev = record._prevRemoved;
84187    const next = record._nextRemoved;
84188
84189    if (prev === null) {
84190      this._removalsHead = next;
84191    } else {
84192      prev._nextRemoved = next;
84193    }
84194
84195    if (next === null) {
84196      this._removalsTail = prev;
84197    } else {
84198      next._prevRemoved = prev;
84199    }
84200
84201    this._insertAfter(record, prevRecord, index);
84202
84203    this._addToMoves(record, index);
84204
84205    return record;
84206  }
84207  /** @internal */
84208
84209
84210  _moveAfter(record, prevRecord, index) {
84211    this._unlink(record);
84212
84213    this._insertAfter(record, prevRecord, index);
84214
84215    this._addToMoves(record, index);
84216
84217    return record;
84218  }
84219  /** @internal */
84220
84221
84222  _addAfter(record, prevRecord, index) {
84223    this._insertAfter(record, prevRecord, index);
84224
84225    if (this._additionsTail === null) {
84226      // TODO(vicb):
84227      // assert(this._additionsHead === null);
84228      this._additionsTail = this._additionsHead = record;
84229    } else {
84230      // TODO(vicb):
84231      // assert(_additionsTail._nextAdded === null);
84232      // assert(record._nextAdded === null);
84233      this._additionsTail = this._additionsTail._nextAdded = record;
84234    }
84235
84236    return record;
84237  }
84238  /** @internal */
84239
84240
84241  _insertAfter(record, prevRecord, index) {
84242    // TODO(vicb):
84243    // assert(record != prevRecord);
84244    // assert(record._next === null);
84245    // assert(record._prev === null);
84246    const next = prevRecord === null ? this._itHead : prevRecord._next; // TODO(vicb):
84247    // assert(next != record);
84248    // assert(prevRecord != record);
84249
84250    record._next = next;
84251    record._prev = prevRecord;
84252
84253    if (next === null) {
84254      this._itTail = record;
84255    } else {
84256      next._prev = record;
84257    }
84258
84259    if (prevRecord === null) {
84260      this._itHead = record;
84261    } else {
84262      prevRecord._next = record;
84263    }
84264
84265    if (this._linkedRecords === null) {
84266      this._linkedRecords = new _DuplicateMap();
84267    }
84268
84269    this._linkedRecords.put(record);
84270
84271    record.currentIndex = index;
84272    return record;
84273  }
84274  /** @internal */
84275
84276
84277  _remove(record) {
84278    return this._addToRemovals(this._unlink(record));
84279  }
84280  /** @internal */
84281
84282
84283  _unlink(record) {
84284    if (this._linkedRecords !== null) {
84285      this._linkedRecords.remove(record);
84286    }
84287
84288    const prev = record._prev;
84289    const next = record._next; // TODO(vicb):
vendor: 12,452 bytes, lines 84290-84810
84290    // assert((record._prev = null) === null);
84291    // assert((record._next = null) === null);
84292
84293    if (prev === null) {
84294      this._itHead = next;
84295    } else {
84296      prev._next = next;
84297    }
84298
84299    if (next === null) {
84300      this._itTail = prev;
84301    } else {
84302      next._prev = prev;
84303    }
84304
84305    return record;
84306  }
84307  /** @internal */
84308
84309
84310  _addToMoves(record, toIndex) {
84311    // TODO(vicb):
84312    // assert(record._nextMoved === null);
84313    if (record.previousIndex === toIndex) {
84314      return record;
84315    }
84316
84317    if (this._movesTail === null) {
84318      // TODO(vicb):
84319      // assert(_movesHead === null);
84320      this._movesTail = this._movesHead = record;
84321    } else {
84322      // TODO(vicb):
84323      // assert(_movesTail._nextMoved === null);
84324      this._movesTail = this._movesTail._nextMoved = record;
84325    }
84326
84327    return record;
84328  }
84329
84330  _addToRemovals(record) {
84331    if (this._unlinkedRecords === null) {
84332      this._unlinkedRecords = new _DuplicateMap();
84333    }
84334
84335    this._unlinkedRecords.put(record);
84336
84337    record.currentIndex = null;
84338    record._nextRemoved = null;
84339
84340    if (this._removalsTail === null) {
84341      // TODO(vicb):
84342      // assert(_removalsHead === null);
84343      this._removalsTail = this._removalsHead = record;
84344      record._prevRemoved = null;
84345    } else {
84346      // TODO(vicb):
84347      // assert(_removalsTail._nextRemoved === null);
84348      // assert(record._nextRemoved === null);
84349      record._prevRemoved = this._removalsTail;
84350      this._removalsTail = this._removalsTail._nextRemoved = record;
84351    }
84352
84353    return record;
84354  }
84355  /** @internal */
84356
84357
84358  _addIdentityChange(record, item) {
84359    record.item = item;
84360
84361    if (this._identityChangesTail === null) {
84362      this._identityChangesTail = this._identityChangesHead = record;
84363    } else {
84364      this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record;
84365    }
84366
84367    return record;
84368  }
84369
84370}
84371
84372class IterableChangeRecord_ {
84373  constructor(item, trackById) {
84374    this.item = item;
84375    this.trackById = trackById;
84376    this.currentIndex = null;
84377    this.previousIndex = null;
84378    /** @internal */
84379
84380    this._nextPrevious = null;
84381    /** @internal */
84382
84383    this._prev = null;
84384    /** @internal */
84385
84386    this._next = null;
84387    /** @internal */
84388
84389    this._prevDup = null;
84390    /** @internal */
84391
84392    this._nextDup = null;
84393    /** @internal */
84394
84395    this._prevRemoved = null;
84396    /** @internal */
84397
84398    this._nextRemoved = null;
84399    /** @internal */
84400
84401    this._nextAdded = null;
84402    /** @internal */
84403
84404    this._nextMoved = null;
84405    /** @internal */
84406
84407    this._nextIdentityChange = null;
84408  }
84409
84410} // A linked list of IterableChangeRecords with the same IterableChangeRecord_.item
84411
84412
84413class _DuplicateItemRecordList {
84414  constructor() {
84415    /** @internal */
84416    this._head = null;
84417    /** @internal */
84418
84419    this._tail = null;
84420  }
84421  /**
84422   * Append the record to the list of duplicates.
84423   *
84424   * Note: by design all records in the list of duplicates hold the same value in record.item.
84425   */
84426
84427
84428  add(record) {
84429    if (this._head === null) {
84430      this._head = this._tail = record;
84431      record._nextDup = null;
84432      record._prevDup = null;
84433    } else {
84434      // TODO(vicb):
84435      // assert(record.item ==  _head.item ||
84436      //       record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
84437      this._tail._nextDup = record;
84438      record._prevDup = this._tail;
84439      record._nextDup = null;
84440      this._tail = record;
84441    }
84442  } // Returns a IterableChangeRecord_ having IterableChangeRecord_.trackById == trackById and
84443  // IterableChangeRecord_.currentIndex >= atOrAfterIndex
84444
84445
84446  get(trackById, atOrAfterIndex) {
84447    let record;
84448
84449    for (record = this._head; record !== null; record = record._nextDup) {
84450      if ((atOrAfterIndex === null || atOrAfterIndex <= record.currentIndex) && Object.is(record.trackById, trackById)) {
84451        return record;
84452      }
84453    }
84454
84455    return null;
84456  }
84457  /**
84458   * Remove one {@link IterableChangeRecord_} from the list of duplicates.
84459   *
84460   * Returns whether the list of duplicates is empty.
84461   */
84462
84463
84464  remove(record) {
84465    // TODO(vicb):
84466    // assert(() {
84467    //  // verify that the record being removed is in the list.
84468    //  for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) {
84469    //    if (identical(cursor, record)) return true;
84470    //  }
84471    //  return false;
84472    //});
84473    const prev = record._prevDup;
84474    const next = record._nextDup;
84475
84476    if (prev === null) {
84477      this._head = next;
84478    } else {
84479      prev._nextDup = next;
84480    }
84481
84482    if (next === null) {
84483      this._tail = prev;
84484    } else {
84485      next._prevDup = prev;
84486    }
84487
84488    return this._head === null;
84489  }
84490
84491}
84492
84493class _DuplicateMap {
84494  constructor() {
84495    this.map = new Map();
84496  }
84497
84498  put(record) {
84499    const key = record.trackById;
84500    let duplicates = this.map.get(key);
84501
84502    if (!duplicates) {
84503      duplicates = new _DuplicateItemRecordList();
84504      this.map.set(key, duplicates);
84505    }
84506
84507    duplicates.add(record);
84508  }
84509  /**
84510   * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
84511   * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
84512   *
84513   * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
84514   * have any more `a`s needs to return the second `a`.
84515   */
84516
84517
84518  get(trackById, atOrAfterIndex) {
84519    const key = trackById;
84520    const recordList = this.map.get(key);
84521    return recordList ? recordList.get(trackById, atOrAfterIndex) : null;
84522  }
84523  /**
84524   * Removes a {@link IterableChangeRecord_} from the list of duplicates.
84525   *
84526   * The list of duplicates also is removed from the map if it gets empty.
84527   */
84528
84529
84530  remove(record) {
84531    const key = record.trackById;
84532    const recordList = this.map.get(key); // Remove the list of duplicates when it gets empty
84533
84534    if (recordList.remove(record)) {
84535      this.map.delete(key);
84536    }
84537
84538    return record;
84539  }
84540
84541  get isEmpty() {
84542    return this.map.size === 0;
84543  }
84544
84545  clear() {
84546    this.map.clear();
84547  }
84548
84549}
84550
84551function getPreviousIndex(item, addRemoveOffset, moveOffsets) {
84552  const previousIndex = item.previousIndex;
84553  if (previousIndex === null) return previousIndex;
84554  let moveOffset = 0;
84555
84556  if (moveOffsets && previousIndex < moveOffsets.length) {
84557    moveOffset = moveOffsets[previousIndex];
84558  }
84559
84560  return previousIndex + addRemoveOffset + moveOffset;
84561}
84562/**
84563 * @license
84564 * Copyright Google LLC All Rights Reserved.
84565 *
84566 * Use of this source code is governed by an MIT-style license that can be
84567 * found in the LICENSE file at https://angular.io/license
84568 */
84569
84570
84571class DefaultKeyValueDifferFactory {
84572  constructor() {}
84573
84574  supports(obj) {
84575    return obj instanceof Map || isJsObject(obj);
84576  }
84577
84578  create() {
84579    return new DefaultKeyValueDiffer();
84580  }
84581
84582}
84583
84584class DefaultKeyValueDiffer {
84585  constructor() {
84586    this._records = new Map();
84587    this._mapHead = null; // _appendAfter is used in the check loop
84588
84589    this._appendAfter = null;
84590    this._previousMapHead = null;
84591    this._changesHead = null;
84592    this._changesTail = null;
84593    this._additionsHead = null;
84594    this._additionsTail = null;
84595    this._removalsHead = null;
84596    this._removalsTail = null;
84597  }
84598
84599  get isDirty() {
84600    return this._additionsHead !== null || this._changesHead !== null || this._removalsHead !== null;
84601  }
84602
84603  forEachItem(fn) {
84604    let record;
84605
84606    for (record = this._mapHead; record !== null; record = record._next) {
84607      fn(record);
84608    }
84609  }
84610
84611  forEachPreviousItem(fn) {
84612    let record;
84613
84614    for (record = this._previousMapHead; record !== null; record = record._nextPrevious) {
84615      fn(record);
84616    }
84617  }
84618
84619  forEachChangedItem(fn) {
84620    let record;
84621
84622    for (record = this._changesHead; record !== null; record = record._nextChanged) {
84623      fn(record);
84624    }
84625  }
84626
84627  forEachAddedItem(fn) {
84628    let record;
84629
84630    for (record = this._additionsHead; record !== null; record = record._nextAdded) {
84631      fn(record);
84632    }
84633  }
84634
84635  forEachRemovedItem(fn) {
84636    let record;
84637
84638    for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
84639      fn(record);
84640    }
84641  }
84642
84643  diff(map) {
84644    if (!map) {
84645      map = new Map();
84646    } else if (!(map instanceof Map || isJsObject(map))) {
84647      throw new RuntimeError(900
84648      /* RuntimeErrorCode.INVALID_DIFFER_INPUT */
84649      , ngDevMode && `Error trying to diff '${stringify(map)}'. Only maps and objects are allowed`);
84650    }
84651
84652    return this.check(map) ? this : null;
84653  }
84654
84655  onDestroy() {}
84656  /**
84657   * Check the current state of the map vs the previous.
84658   * The algorithm is optimised for when the keys do no change.
84659   */
84660
84661
84662  check(map) {
84663    this._reset();
84664
84665    let insertBefore = this._mapHead;
84666    this._appendAfter = null;
84667
84668    this._forEach(map, (value, key) => {
84669      if (insertBefore && insertBefore.key === key) {
84670        this._maybeAddToChanges(insertBefore, value);
84671
84672        this._appendAfter = insertBefore;
84673        insertBefore = insertBefore._next;
84674      } else {
84675        const record = this._getOrCreateRecordForKey(key, value);
84676
84677        insertBefore = this._insertBeforeOrAppend(insertBefore, record);
84678      }
84679    }); // Items remaining at the end of the list have been deleted
84680
84681
84682    if (insertBefore) {
84683      if (insertBefore._prev) {
84684        insertBefore._prev._next = null;
84685      }
84686
84687      this._removalsHead = insertBefore;
84688
84689      for (let record = insertBefore; record !== null; record = record._nextRemoved) {
84690        if (record === this._mapHead) {
84691          this._mapHead = null;
84692        }
84693
84694        this._records.delete(record.key);
84695
84696        record._nextRemoved = record._next;
84697        record.previousValue = record.currentValue;
84698        record.currentValue = null;
84699        record._prev = null;
84700        record._next = null;
84701      }
84702    } // Make sure tails have no next records from previous runs
84703
84704
84705    if (this._changesTail) this._changesTail._nextChanged = null;
84706    if (this._additionsTail) this._additionsTail._nextAdded = null;
84707    return this.isDirty;
84708  }
84709  /**
84710   * Inserts a record before `before` or append at the end of the list when `before` is null.
84711   *
84712   * Notes:
84713   * - This method appends at `this._appendAfter`,
84714   * - This method updates `this._appendAfter`,
84715   * - The return value is the new value for the insertion pointer.
84716   */
84717
84718
84719  _insertBeforeOrAppend(before, record) {
84720    if (before) {
84721      const prev = before._prev;
84722      record._next = before;
84723      record._prev = prev;
84724      before._prev = record;
84725
84726      if (prev) {
84727        prev._next = record;
84728      }
84729
84730      if (before === this._mapHead) {
84731        this._mapHead = record;
84732      }
84733
84734      this._appendAfter = before;
84735      return before;
84736    }
84737
84738    if (this._appendAfter) {
84739      this._appendAfter._next = record;
84740      record._prev = this._appendAfter;
84741    } else {
84742      this._mapHead = record;
84743    }
84744
84745    this._appendAfter = record;
84746    return null;
84747  }
84748
84749  _getOrCreateRecordForKey(key, value) {
84750    if (this._records.has(key)) {
84751      const record = this._records.get(key);
84752
84753      this._maybeAddToChanges(record, value);
84754
84755      const prev = record._prev;
84756      const next = record._next;
84757
84758      if (prev) {
84759        prev._next = next;
84760      }
84761
84762      if (next) {
84763        next._prev = prev;
84764      }
84765
84766      record._next = null;
84767      record._prev = null;
84768      return record;
84769    }
84770
84771    const record = new KeyValueChangeRecord_(key);
84772
84773    this._records.set(key, record);
84774
84775    record.currentValue = value;
84776
84777    this._addToAdditions(record);
84778
84779    return record;
84780  }
84781  /** @internal */
84782
84783
84784  _reset() {
84785    if (this.isDirty) {
84786      let record; // let `_previousMapHead` contain the state of the map before the changes
84787
84788      this._previousMapHead = this._mapHead;
84789
84790      for (record = this._previousMapHead; record !== null; record = record._next) {
84791        record._nextPrevious = record._next;
84792      } // Update `record.previousValue` with the value of the item before the changes
84793      // We need to update all changed items (that's those which have been added and changed)
84794
84795
84796      for (record = this._changesHead; record !== null; record = record._nextChanged) {
84797        record.previousValue = record.currentValue;
84798      }
84799
84800      for (record = this._additionsHead; record != null; record = record._nextAdded) {
84801        record.previousValue = record.currentValue;
84802      }
84803
84804      this._changesHead = this._changesTail = null;
84805      this._additionsHead = this._additionsTail = null;
84806      this._removalsHead = null;
84807    }
84808  } // Add the record or a given key to the list of changes only when the value has actually changed
84809
84810
84811  _maybeAddToChanges(record, newValue) {
84812    if (!Object.is(newValue, record.currentValue)) {
84813      record.previousValue = record.currentValue;
84814      record.currentValue = newValue;
84815
84816      this._addToChanges(record);
84817    }
84818  }
84819
84820  _addToAdditions(record) {
84821    if (this._additionsHead === null) {
84822      this._additionsHead = this._additionsTail = record;
84823    } else {
84824      this._additionsTail._nextAdded = record;
84825      this._additionsTail = record;
84826    }
84827  }
84828
84829  _addToChanges(record) {
84830    if (this._changesHead === null) {
84831      this._changesHead = this._changesTail = record;
84832    } else {
84833      this._changesTail._nextChanged = record;
84834      this._changesTail = record;
84835    }
84836  }
84837  /** @internal */
84838
84839
84840  _forEach(obj, fn) {
84841    if (obj instanceof Map) {
84842      obj.forEach(fn);
84843    } else {
84844      Object.keys(obj).forEach(k => fn(obj[k], k));
84845    }
84846  }
84847
84848}
84849
84850class KeyValueChangeRecord_ {
84851  constructor(key) {
84852    this.key = key;
84853    this.previousValue = null;
84854    this.currentValue = null;
84855    /** @internal */
84856
84857    this._nextPrevious = null;
84858    /** @internal */
84859
84860    this._next = null;
84861    /** @internal */
84862
84863    this._prev = null;
84864    /** @internal */
84865
84866    this._nextAdded = null;
84867    /** @internal */
84868
84869    this._nextRemoved = null;
84870    /** @internal */
84871
84872    this._nextChanged = null;
84873  }
84874
84875}
84876/**
84877 * @license
84878 * Copyright Google LLC All Rights Reserved.
84879 *
84880 * Use of this source code is governed by an MIT-style license that can be
84881 * found in the LICENSE file at https://angular.io/license
84882 */
84883
84884
84885function defaultIterableDiffersFactory() {
84886  return new IterableDiffers([new DefaultIterableDifferFactory()]);
84887}
84888/**
84889 * A repository of different iterable diffing strategies used by NgFor, NgClass, and others.
84890 *
84891 * @publicApi
84892 */
84893
84894
84895class IterableDiffers {
84896  constructor(factories) {
84897    this.factories = factories;
84898  }
84899
84900  static create(factories, parent) {
84901    if (parent != null) {
84902      const copied = parent.factories.slice();
84903      factories = factories.concat(copied);
84904    }
84905
84906    return new IterableDiffers(factories);
84907  }
84908  /**
84909   * Takes an array of {@link IterableDifferFactory} and returns a provider used to extend the
84910   * inherited {@link IterableDiffers} instance with the provided factories and return a new
84911   * {@link IterableDiffers} instance.
84912   *
84913   * @usageNotes
84914   * ### Example
84915   *
84916   * The following example shows how to extend an existing list of factories,
84917   * which will only be applied to the injector for this component and its children.
84918   * This step is all that's required to make a new {@link IterableDiffer} available.
84919   *
84920   * ```
84921   * @Component({
84922   *   viewProviders: [
84923   *     IterableDiffers.extend([new ImmutableListDiffer()])
84924   *   ]
84925   * })
84926   * ```
84927   */
84928
84929
84930  static extend(factories) {
84931    return {
84932      provide: IterableDiffers,
84933      useFactory: parent => {
84934        // if parent is null, it means that we are in the root injector and we have just overridden
84935        // the default injection mechanism for IterableDiffers, in such a case just assume
84936        // `defaultIterableDiffersFactory`.
84937        return IterableDiffers.create(factories, parent || defaultIterableDiffersFactory());
84938      },
84939      // Dependency technically isn't optional, but we can provide a better error message this way.
84940      deps: [[IterableDiffers, new SkipSelf(), new Optional()]]
84941    };
84942  }
84943
84944  find(iterable) {
84945    const factory = this.factories.find(f => f.supports(iterable));
84946
84947    if (factory != null) {
84948      return factory;
84949    } else {
84950      throw new RuntimeError(901
84951      /* RuntimeErrorCode.NO_SUPPORTING_DIFFER_FACTORY */
84952      , ngDevMode && `Cannot find a differ supporting object '${iterable}' of type '${getTypeNameForDebugging(iterable)}'`);
84953    }
84954  }
84955
84956}
84957/** @nocollapse */
84958
84959
84960IterableDiffers.ɵprov = ɵɵdefineInjectable({
84961  token: IterableDiffers,
84962  providedIn: 'root',
84963  factory: defaultIterableDiffersFactory
84964});
84965
84966function getTypeNameForDebugging(type) {
84967  return type['name'] || typeof type;
84968}
84969/**
84970 * @license
84971 * Copyright Google LLC All Rights Reserved.
84972 *
84973 * Use of this source code is governed by an MIT-style license that can be
84974 * found in the LICENSE file at https://angular.io/license
84975 */
84976
84977
84978function defaultKeyValueDiffersFactory() {
84979  return new KeyValueDiffers([new DefaultKeyValueDifferFactory()]);
84980}
84981/**
84982 * A repository of different Map diffing strategies used by NgClass, NgStyle, and others.
84983 *
84984 * @publicApi
84985 */
84986
84987
84988class KeyValueDiffers {
84989  constructor(factories) {
84990    this.factories = factories;
84991  }
84992
84993  static create(factories, parent) {
84994    if (parent) {
84995      const copied = parent.factories.slice();
84996      factories = factories.concat(copied);
84997    }
84998
84999    return new KeyValueDiffers(factories);
85000  }
85001  /**
85002   * Takes an array of {@link KeyValueDifferFactory} and returns a provider used to extend the
85003   * inherited {@link KeyValueDiffers} instance with the provided factories and return a new
85004   * {@link KeyValueDiffers} instance.
85005   *
85006   * @usageNotes
85007   * ### Example
85008   *
85009   * The following example shows how to extend an existing list of factories,
85010   * which will only be applied to the injector for this component and its children.
85011   * This step is all that's required to make a new {@link KeyValueDiffer} available.
85012   *
85013   * ```
85014   * @Component({
85015   *   viewProviders: [
85016   *     KeyValueDiffers.extend([new ImmutableMapDiffer()])
85017   *   ]
85018   * })
85019   * ```
85020   */
85021
85022
85023  static extend(factories) {
85024    return {
85025      provide: KeyValueDiffers,
85026      useFactory: parent => {
85027        // if parent is null, it means that we are in the root injector and we have just overridden
85028        // the default injection mechanism for KeyValueDiffers, in such a case just assume
85029        // `defaultKeyValueDiffersFactory`.
85030        return KeyValueDiffers.create(factories, parent || defaultKeyValueDiffersFactory());
85031      },
85032      // Dependency technically isn't optional, but we can provide a better error message this way.
85033      deps: [[KeyValueDiffers, new SkipSelf(), new Optional()]]
85034    };
85035  }
85036
85037  find(kv) {
85038    const factory = this.factories.find(f => f.supports(kv));
85039
85040    if (factory) {
85041      return factory;
85042    }
85043
85044    throw new RuntimeError(901
85045    /* RuntimeErrorCode.NO_SUPPORTING_DIFFER_FACTORY */
85046    , ngDevMode && `Cannot find a differ supporting object '${kv}'`);
85047  }
85048
85049}
85050/** @nocollapse */
85051
85052
85053KeyValueDiffers.ɵprov = ɵɵdefineInjectable({
85054  token: KeyValueDiffers,
85055  providedIn: 'root',
85056  factory: defaultKeyValueDiffersFactory
85057});
85058/**
85059 * @license
85060 * Copyright Google LLC All Rights Reserved.
85061 *
85062 * Use of this source code is governed by an MIT-style license that can be
85063 * found in the LICENSE file at https://angular.io/license
85064 */
85065
85066/**
85067 * Structural diffing for `Object`s and `Map`s.
85068 */
85069
85070const keyValDiff = [new DefaultKeyValueDifferFactory()];
85071/**
85072 * Structural diffing for `Iterable` types such as `Array`s.
85073 */
85074
85075const iterableDiff = [new DefaultIterableDifferFactory()];
85076const defaultIterableDiffers = new IterableDiffers(iterableDiff);
85077const defaultKeyValueDiffers = new KeyValueDiffers(keyValDiff);
85078/**
85079 * @license
85080 * Copyright Google LLC All Rights Reserved.
85081 *
85082 * Use of this source code is governed by an MIT-style license that can be
85083 * found in the LICENSE file at https://angular.io/license
85084 */
85085
85086/**
85087 * @license
85088 * Copyright Google LLC All Rights Reserved.
85089 *
85090 * Use of this source code is governed by an MIT-style license that can be
85091 * found in the LICENSE file at https://angular.io/license
85092 */
85093
85094/**
85095 * This platform has to be included in any other platform
85096 *
85097 * @publicApi
85098 */
85099
85100const platformCore = createPlatformFactory(null, 'core', []);
85101/**
85102 * @license
85103 * Copyright Google LLC All Rights Reserved.
85104 *
85105 * Use of this source code is governed by an MIT-style license that can be
85106 * found in the LICENSE file at https://angular.io/license
85107 */
85108
85109/**
85110 * Re-exported by `BrowserModule`, which is included automatically in the root
85111 * `AppModule` when you create a new app with the CLI `new` command. Eagerly injects
85112 * `ApplicationRef` to instantiate it.
85113 *
85114 * @publicApi
85115 */
85116
85117class ApplicationModule {
85118  // Inject ApplicationRef to make it eager...
85119  constructor(appRef) {}
85120
85121}
85122
85123ApplicationModule.ɵfac = function ApplicationModule_Factory(t) {
85124  return new (t || ApplicationModule)(ɵɵinject(ApplicationRef));
85125};
85126
85127ApplicationModule.ɵmod = /*@__PURE__*/ɵɵdefineNgModule({
85128  type: ApplicationModule
85129});
85130ApplicationModule.ɵinj = /*@__PURE__*/ɵɵdefineInjector({});
85131
85132(function () {
85133  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ApplicationModule, [{
85134    type: NgModule
85135  }], function () {
85136    return [{
85137      type: ApplicationRef
85138    }];
85139  }, null);
85140})();
85141/**
85142 * @license
85143 * Copyright Google LLC All Rights Reserved.
85144 *
85145 * Use of this source code is governed by an MIT-style license that can be
85146 * found in the LICENSE file at https://angular.io/license
85147 */
85148
85149/** Coerces a value (typically a string) to a boolean. */
85150
85151
85152function coerceToBoolean(value) {
85153  return typeof value === 'boolean' ? value : value != null && value !== 'false';
85154}
85155/**
85156 * @license
85157 * Copyright Google LLC All Rights Reserved.
85158 *
85159 * Use of this source code is governed by an MIT-style license that can be
85160 * found in the LICENSE file at https://angular.io/license
85161 */
85162// TODO(alxhub): allows tests to compile, can be removed when tests have been updated.
85163
85164
85165const ɵivyEnabled = true;
85166/**
85167 * @license
85168 * Copyright Google LLC All Rights Reserved.
85169 *
85170 * Use of this source code is governed by an MIT-style license that can be
85171 * found in the LICENSE file at https://angular.io/license
85172 */
85173
85174/**
85175 * Compiles a partial directive declaration object into a full directive definition object.
85176 *
85177 * @codeGenApi
85178 */
85179
85180function ɵɵngDeclareDirective(decl) {
85181  const compiler = getCompilerFacade({
85182    usage: 1
85183    /* JitCompilerUsage.PartialDeclaration */
85184    ,
85185    kind: 'directive',
85186    type: decl.type
85187  });
85188  return compiler.compileDirectiveDeclaration(angularCoreEnv, `ng:///${decl.type.n
85188ame}/ɵfac.js`, decl);
85189}
85190/**
85191 * Evaluates the class metadata declaration.
85192 *
85193 * @codeGenApi
85194 */
85195
85196
85197function ɵɵngDeclareClassMetadata(decl) {
85198  setClassMetadata(decl.type, decl.decorators, decl.ctorParameters ?? null, decl.propDecorators ?? null);
85199}
85200/**
85201 * Compiles a partial component declaration object into a full component definition object.
85202 *
85203 * @codeGenApi
85204 */
85205
85206
85207function ɵɵngDeclareComponent(decl) {
85208  const compiler = getCompilerFacade({
85209    usage: 1
85210    /* JitCompilerUsage.PartialDeclaration */
85211    ,
85212    kind: 'component',
85213    type: decl.type
85214  });
85215  return compiler.compileComponentDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵcmp.js`, decl);
85216}
85217/**
85218 * Compiles a partial pipe declaration object into a full pipe definition object.
85219 *
85220 * @codeGenApi
85221 */
85222
85223
85224function ɵɵngDeclareFactory(decl) {
85225  const compiler = getCompilerFacade({
85226    usage: 1
85227    /* JitCompilerUsage.PartialDeclaration */
85228    ,
85229    kind: getFactoryKind(decl.target),
85230    type: decl.type
85231  });
85232  return compiler.compileFactoryDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵfac.js`, decl);
85233}
85234
85235function getFactoryKind(target) {
85236  switch (target) {
85237    case FactoryTarget.Directive:
85238      return 'directive';
85239
85240    case FactoryTarget.Component:
85241      return 'component';
85242
85243    case FactoryTarget.Injectable:
85244      return 'injectable';
85245
85246    case FactoryTarget.Pipe:
85247      return 'pipe';
85248
85249    case FactoryTarget.NgModule:
85250      return 'NgModule';
85251  }
85252}
85253/**
85254 * Compiles a partial injectable declaration object into a full injectable definition object.
85255 *
85256 * @codeGenApi
85257 */
85258
85259
85260function ɵɵngDeclareInjectable(decl) {
85261  const compiler = getCompilerFacade({
85262    usage: 1
85263    /* JitCompilerUsage.PartialDeclaration */
85264    ,
85265    kind: 'injectable',
85266    type: decl.type
85267  });
85268  return compiler.compileInjectableDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵprov.js`, decl);
85269}
85270/**
85271 * Compiles a partial injector declaration object into a full injector definition object.
85272 *
85273 * @codeGenApi
85274 */
85275
85276
85277function ɵɵngDeclareInjector(decl) {
85278  const compiler = getCompilerFacade({
85279    usage: 1
85280    /* JitCompilerUsage.PartialDeclaration */
85281    ,
85282    kind: 'NgModule',
85283    type: decl.type
85284  });
85285  return compiler.compileInjectorDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵinj.js`, decl);
85286}
85287/**
85288 * Compiles a partial NgModule declaration object into a full NgModule definition object.
85289 *
85290 * @codeGenApi
85291 */
85292
85293
85294function ɵɵngDeclareNgModule(decl) {
85295  const compiler = getCompilerFacade({
85296    usage: 1
85297    /* JitCompilerUsage.PartialDeclaration */
85298    ,
85299    kind: 'NgModule',
85300    type: decl.type
85301  });
85302  return compiler.compileNgModuleDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵmod.js`, decl);
85303}
85304/**
85305 * Compiles a partial pipe declaration object into a full pipe definition object.
85306 *
85307 * @codeGenApi
85308 */
85309
85310
85311function ɵɵngDeclarePipe(decl) {
85312  const compiler = getCompilerFacade({
85313    usage: 1
85314    /* JitCompilerUsage.PartialDeclaration */
85315    ,
85316    kind: 'pipe',
85317    type: decl.type
85318  });
85319  return compiler.compilePipeDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵpipe.js`, decl);
85320}
85321/**
85322 * @license
85323 * Copyright Google LLC All Rights Reserved.
85324 *
85325 * Use of this source code is governed by an MIT-style license that can be
85326 * found in the LICENSE file at https://angular.io/license
85327 */
85328// clang-format on
85329
85330/**
85331 * @license
85332 * Copyright Google LLC All Rights Reserved.
85333 *
85334 * Use of this source code is governed by an MIT-style license that can be
85335 * found in the LICENSE file at https://angular.io/license
85336 */
85337
85338/**
85339 * Creates a `ComponentRef` instance based on provided component type and a set of options.
85340 *
85341 * @usageNotes
85342 *
85343 * The example below demonstrates how the `createComponent` function can be used
85344 * to create an instance of a ComponentRef dynamically and attach it to an ApplicationRef,
85345 * so that it gets included into change detection cycles.
85346 *
85347 * Note: the example uses standalone components, but the function can also be used for
85348 * non-standalone components (declared in an NgModule) as well.
85349 *
85350 * ```typescript
85351 * @Component({
85352 *   standalone: true,
85353 *   template: `Hello {{ name }}!`
85354 * })
85355 * class HelloComponent {
85356 *   name = 'Angular';
85357 * }
85358 *
85359 * @Component({
85360 *   standalone: true,
85361 *   template: `<div id="hello-component-host"></div>`
85362 * })
85363 * class RootComponent {}
85364 *
85365 * // Bootstrap an application.
85366 * const applicationRef = await bootstrapApplication(RootComponent);
85367 *
85368 * // Locate a DOM node that would be used as a host.
85369 * const host = document.getElementById('hello-component-host');
85370 *
85371 * // Get an `EnvironmentInjector` instance from the `ApplicationRef`.
85372 * const environmentInjector = applicationRef.injector;
85373 *
85374 * // We can now create a `ComponentRef` instance.
85375 * const componentRef = createComponent(HelloComponent, {host, environmentInjector});
85376 *
85377 * // Last step is to register the newly created ref using the `ApplicationRef` instance
85378 * // to include the component view into change detection cycles.
85379 * applicationRef.attachView(componentRef.hostView);
85380 * ```
85381 *
85382 * @param component Component class reference.
85383 * @param options Set of options to use:
85384 *  * `environmentInjector`: An `EnvironmentInjector` instance to be used for the component, see
85385 * additional info about it at https://angular.io/guide/standalone-components#environment-injectors.
85386 *  * `hostElement` (optional): A DOM node that should act as a host node for the component. If not
85387 * provided, Angular creates one based on the tag name used in the component selector (and falls
85388 * back to using `div` if selector doesn't have tag name info).
85389 *  * `elementInjector` (optional): An `ElementInjector` instance, see additional info about it at
85390 * https://angular.io/guide/hierarchical-dependency-injection#elementinjector.
85391 *  * `projectableNodes` (optional): A list of DOM nodes that should be projected through
85392 *                      [`<ng-content>`](api/core/ng-content) of the new component instance.
85393 * @returns ComponentRef instance that represents a given Component.
85394 *
85395 * @publicApi
85396 */
85397
85398
85399function createComponent(component, options) {
85400  ngDevMode && assertComponentDef(component);
85401  const componentDef = getComponentDef(component);
85402  const elementInjector = options.elementInjector || getNullInjector();
85403  const factory = new ComponentFactory(componentDef);
85404  return factory.create(elementInjector, options.projectableNodes, options.hostElement, options.environmentInjector);
85405}
85406/**
85407 * Creates an object that allows to retrieve component metadata.
85408 *
85409 * @usageNotes
85410 *
85411 * The example below demonstrates how to use the function and how the fields
85412 * of the returned object map to the component metadata.
85413 *
85414 * ```typescript
85415 * @Component({
85416 *   standalone: true,
85417 *   selector: 'foo-component',
85418 *   template: `
85419 *     <ng-content></ng-content>
85420 *     <ng-content select="content-selector-a"></ng-content>
85421 *   `,
85422 * })
85423 * class FooComponent {
85424 *   @Input('inputName') inputPropName: string;
85425 *   @Output('outputName') outputPropName = new EventEmitter<void>();
85426 * }
85427 *
85428 * const mirror = reflectComponentType(FooComponent);
85429 * expect(mirror.type).toBe(FooComponent);
85430 * expect(mirror.selector).toBe('foo-component');
85431 * expect(mirror.isStandalone).toBe(true);
85432 * expect(mirror.inputs).toEqual([{propName: 'inputName', templateName: 'inputPropName'}]);
85433 * expect(mirror.outputs).toEqual([{propName: 'outputName', templateName: 'outputPropName'}]);
85434 * expect(mirror.ngContentSelectors).toEqual([
85435 *   '*',                 // first `<ng-content>` in a template, the selector defaults to `*`
85436 *   'content-selector-a' // second `<ng-content>` in a template
85437 * ]);
85438 * ```
85439 *
85440 * @param component Component class reference.
85441 * @returns An object that allows to retrieve component metadata.
85442 *
85443 * @publicApi
85444 */
85445
85446
85447function reflectComponentType(component) {
85448  const componentDef = getComponentDef(component);
85449  if (!componentDef) return null;
85450  const factory = new ComponentFactory(componentDef);
85451  return {
85452    get selector() {
85453      return factory.selector;
85454    },
85455
85456    get type() {
85457      return factory.componentType;
85458    },
85459
85460    get inputs() {
85461      return factory.inputs;
85462    },
85463
85464    get outputs() {
85465      return factory.outputs;
85466    },
85467
85468    get ngContentSelectors() {
85469      return factory.ngContentSelectors;
85470    },
85471
85472    get isStandalone() {
85473      return componentDef.standalone;
85474    }
85475
85476  };
85477}
85478/**
85479 * @license
85480 * Copyright Google LLC All Rights Reserved.
85481 *
85482 * Use of this source code is governed by an MIT-style license that can be
85483 * found in the LICENSE file at https://angular.io/license
85484 */
85485
85486
85487if (typeof ngDevMode !== 'undefined' && ngDevMode) {
85488  // This helper is to give a reasonable error message to people upgrading to v9 that have not yet
85489  // installed `@angular/localize` in their app.
85490  // tslint:disable-next-line: no-toplevel-property-access
85491  _global.$localize = _global.$localize || function () {
85492    throw new Error('It looks like your application or one of its dependencies is using i18n.\n' + 'Angular 9 introduced a global `$localize()` function that needs to be loaded.\n' + 'Please run `ng add @angular/localize` from the Angular CLI.\n' + '(For non-CLI projects, add `import \'@angular/localize/init\';` to your `polyfills.ts` file.\n' + 'For server-side rendering applications add the import to your `main.server.ts` file.)');
85493  };
85494}
85495/**
85496 * @license
85497 * Copyright Google LLC All Rights Reserved.
85498 *
85499 * Use of this source code is governed by an MIT-style license that can be
85500 * found in the LICENSE file at https://angular.io/license
85501 */
85502// This file only reexports content of the `src` folder. Keep it that way.
85503
85504/**
85505 * @license
85506 * Copyright Google LLC All Rights Reserved.
85507 *
85508 * Use of this source code is governed by an MIT-style license that can be
85509 * found in the LICENSE file at https://angular.io/license
85510 */
85511
85512/**
85513 * Generated bundle index. Do not edit.
85514 */
85515
85516
85517
85518
85519/***/ }),
85520
85521/***/ 2508:
85522/*!********************************************************!*\
85523  !*** ./node_modules/@angular/forms/fesm2020/forms.mjs ***!
85524  \********************************************************/
85525/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
85526
85527__webpack_require__.r(__webpack_exports__);
85528/* harmony export */ __webpack_require__.d(__webpack_exports__, {
85529/* harmony export */   "AbstractControl": () => (/* binding */ AbstractControl),
85530/* harmony export */   "AbstractControlDirective": () => (/* binding */ AbstractControlDirective),
85531/* harmony export */   "AbstractFormGroupDirective": () => (/* binding */ AbstractFormGroupDirective),
85532/* harmony export */   "COMPOSITION_BUFFER_MODE": () => (/* binding */ COMPOSITION_BUFFER_MODE),
85533/* harmony export */   "CheckboxControlValueAccessor": () => (/* binding */ CheckboxControlValueAccessor),
85534/* harmony export */   "CheckboxRequiredValidator": () => (/* binding */ CheckboxRequiredValidator),
85535/* harmony export */   "ControlContainer": () => (/* binding */ ControlContainer),
85536/* harmony export */   "DefaultValueAccessor": () => (/* binding */ DefaultValueAccessor),
85537/* harmony export */   "EmailValidator": () => (/* binding */ EmailValidator),
85538/* harmony export */   "FormArray": () => (/* binding */ FormArray),
85539/* harmony export */   "FormArrayName": () => (/* binding */ FormArrayName),
85540/* harmony export */   "FormBuilder": () => (/* binding */ FormBuilder),
85541/* harmony export */   "FormControl": () => (/* binding */ FormControl),
85542/* harmony export */   "FormControlDirective": () => (/* binding */ FormControlDirective),
85543/* harmony export */   "FormControlName": () => (/* binding */ FormControlName),
85544/* harmony export */   "FormGroup": () => (/* binding */ FormGroup),
85545/* harmony export */   "FormGroupDirective": () => (/* binding */ FormGroupDirective),
85546/* harmony export */   "FormGroupName": () => (/* binding */ FormGroupName),
85547/* harmony export */   "FormRecord": () => (/* binding */ FormRecord),
85548/* harmony export */   "FormsModule": () => (/* binding */ FormsModule),
85549/* harmony export */   "MaxLengthValidator": () => (/* binding */ MaxLengthValidator),
85550/* harmony export */   "MaxValidator": () => (/* binding */ MaxValidator),
85551/* harmony export */   "MinLengthValidator": () => (/* binding */ MinLengthValidator),
85552/* harmony export */   "MinValidator": () => (/* binding */ MinValidator),
85553/* harmony export */   "NG_ASYNC_VALIDATORS": () => (/* binding */ NG_ASYNC_VALIDATORS),
85554/* harmony export */   "NG_VALIDATORS": () => (/* binding */ NG_VALIDATORS),
85555/* harmony export */   "NG_VALUE_ACCESSOR": () => (/* binding */ NG_VALUE_ACCESSOR),
85556/* harmony export */   "NgControl": () => (/* binding */ NgControl),
85557/* harmony export */   "NgControlStatus": () => (/* binding */ NgControlStatus),
85558/* harmony export */   "NgControlStatusGroup": () => (/* binding */ NgControlStatusGroup),
85559/* harmony export */   "NgForm": () => (/* binding */ NgForm),
85560/* harmony export */   "NgModel": () => (/* binding */ NgModel),
85561/* harmony export */   "NgModelGroup": () => (/* binding */ NgModelGroup),
85562/* harmony export */   "NgSelectOption": () => (/* binding */ NgSelectOption),
85563/* harmony export */   "NonNullableFormBuilder": () => (/* binding */ NonNullableFormBuilder),
85564/* harmony export */   "NumberValueAccessor": () => (/* binding */ NumberValueAccessor),
85565/* harmony export */   "PatternValidator": () => (/* binding */ PatternValidator),
85566/* harmony export */   "RadioControlValueAccessor": () => (/* binding */ RadioControlValueAccessor),
85567/* harmony export */   "RangeValueAccessor": () => (/* binding */ RangeValueAccessor),
85568/* harmony export */   "ReactiveFormsModule": () => (/* binding */ ReactiveFormsModule),
85569/* harmony export */   "RequiredValidator": () => (/* binding */ RequiredValidator),
85570/* harmony export */   "SelectControlValueAccessor": () => (/* binding */ SelectControlValueAccessor),
85571/* harmony export */   "SelectMultipleControlValueAccessor": () => (/* binding */ SelectMultipleControlValueAccessor),
85572/* harmony export */   "UntypedFormArray": () => (/* binding */ UntypedFormArray),
85573/* harmony export */   "UntypedFormBuilder": () => (/* binding */ UntypedFormBuilder),
85574/* harmony export */   "UntypedFormControl": () => (/* binding */ UntypedFormControl),
85575/* harmony export */   "UntypedFormGroup": () => (/* binding */ UntypedFormGroup),
85576/* harmony export */   "VERSION": () => (/* binding */ VERSION),
85577/* harmony export */   "Validators": () => (/* binding */ Validators),
85578/* harmony export */   "ɵInternalFormsSharedModule": () => (/* binding */ ɵInternalFormsSharedModule),
85579/* harmony export */   "ɵNgNoValidate": () => (/* binding */ ɵNgNoValidate),
85580/* harmony export */   "ɵNgSelectMultipleOption": () => (/* binding */ ɵNgSelectMultipleOption)
85581/* harmony export */ });
85582/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 2560);
85583/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/common */ 4666);
85584/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 4383);
85585/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 4350);
85586/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 6942);
85587/**
85588 * @license Angular v14.2.10
85589 * (c) 2010-2022 Google LLC. https://angular.io/
85590 * License: MIT
85591 */
85592
85593
85594
85595
85596
85597/**
85598 * @license
85599 * Copyright Google LLC All Rights Reserved.
85600 *
85601 * Use of this source code is governed by an MIT-style license that can be
85602 * found in the LICENSE file at https://angular.io/license
85603 */
85604
85605/**
85606 * Base class for all ControlValueAccessor classes defined in Forms package.
85607 * Contains common logic and utility functions.
85608 *
85609 * Note: this is an *internal-only* class and should not be extended or used directly in
85610 * applications code.
85611 */
85612
85613class BaseControlValueAccessor {
85614  constructor(_renderer, _elementRef) {
85615    this._renderer = _renderer;
85616    this._elementRef = _elementRef;
85617    /**
85618     * The registered callback function called when a change or input event occurs on the input
85619     * element.
85620     * @nodoc
85621     */
85622
85623    this.onChange = _ => {};
85624    /**
85625     * The registered callback function called when a blur event occurs on the input element.
85626     * @nodoc
85627     */
85628
85629
85630    this.onTouched = () => {};
85631  }
85632  /**
85633   * Helper method that sets a property on a target element using the current Renderer
85634   * implementation.
85635   * @nodoc
85636   */
85637
85638
85639  setProperty(key, value) {
85640    this._renderer.setProperty(this._elementRef.nativeElement, key, value);
85641  }
85642  /**
85643   * Registers a function called when the control is touched.
85644   * @nodoc
85645   */
85646
85647
85648  registerOnTouched(fn) {
85649    this.onTouched = fn;
85650  }
85651  /**
85652   * Registers a function called when the control value changes.
85653   * @nodoc
85654   */
85655
85656
85657  registerOnChange(fn) {
85658    this.onChange = fn;
85659  }
85660  /**
85661   * Sets the "disabled" property on the range input element.
85662   * @nodoc
85663   */
85664
85665
85666  setDisabledState(isDisabled) {
85667    this.setProperty('disabled', isDisabled);
85668  }
85669
85670}
85671
85672BaseControlValueAccessor.ɵfac = function BaseControlValueAccessor_Factory(t) {
85673  return new (t || BaseControlValueAccessor)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef));
85674};
85675
85676BaseControlValueAccessor.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
85677  type: BaseControlValueAccessor
85678});
85679
85680(function () {
85681  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BaseControlValueAccessor, [{
85682    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive
85683  }], function () {
85684    return [{
85685      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
85686    }, {
85687      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
85688    }];
85689  }, null);
85690})();
85691/**
85692 * Base class for all built-in ControlValueAccessor classes (except DefaultValueAccessor, which is
85693 * used in case no other CVAs can be found). We use this class to distinguish between default CVA,
85694 * built-in CVAs and custom CVAs, so that Forms logic can recognize built-in CVAs and treat custom
85695 * ones with higher priority (when both built-in and custom CVAs are present).
85696 *
85697 * Note: this is an *internal-only* class and should not be extended or used directly in
85698 * applications code.
85699 */
85700
85701
85702class BuiltInControlValueAccessor extends BaseControlValueAccessor {}
85703
85704BuiltInControlValueAccessor.ɵfac = /* @__PURE__ */function () {
85705  let ɵBuiltInControlValueAccessor_BaseFactory;
85706  return function BuiltInControlValueAccessor_Factory(t) {
85707    return (ɵBuiltInControlValueAccessor_BaseFactory || (ɵBuiltInControlValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](BuiltInControlValueAccessor)))(t || BuiltInControlValueAccessor);
85708  };
85709}();
85710
85711BuiltInControlValueAccessor.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
85712  type: BuiltInControlValueAccessor,
85713  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
85714});
85715
85716(function () {
85717  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BuiltInControlValueAccessor, [{
85718    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive
85719  }], null, null);
85720})();
85721/**
85722 * Used to provide a `ControlValueAccessor` for form controls.
85723 *
85724 * See `DefaultValueAccessor` for how to implement one.
85725 *
85726 * @publicApi
85727 */
85728
85729
85730const NG_VALUE_ACCESSOR = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('NgValueAccessor');
85731/**
85732 * @license
85733 * Copyright Google LLC All Rights Reserved.
85734 *
85735 * Use of this source code is governed by an MIT-style license that can be
85736 * found in the LICENSE file at https://angular.io/license
85737 */
85738
85739const CHECKBOX_VALUE_ACCESSOR = {
85740  provide: NG_VALUE_ACCESSOR,
85741  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => CheckboxControlValueAccessor),
85742  multi: true
85743};
85744/**
85745 * @description
85746 * A `ControlValueAccessor` for writing a value and listening to changes on a checkbox input
85747 * element.
85748 *
85749 * @usageNotes
85750 *
85751 * ### Using a checkbox with a reactive form.
85752 *
85753 * The following example shows how to use a checkbox with a reactive form.
85754 *
85755 * ```ts
85756 * const rememberLoginControl = new FormControl();
85757 * ```
85758 *
85759 * ```
85760 * <input type="checkbox" [formControl]="rememberLoginControl">
85761 * ```
85762 *
85763 * @ngModule ReactiveFormsModule
85764 * @ngModule FormsModule
85765 * @publicApi
85766 */
85767
85768class CheckboxControlValueAccessor extends BuiltInControlValueAccessor {
85769  /**
85770   * Sets the "checked" property on the input element.
85771   * @nodoc
85772   */
85773  writeValue(value) {
85774    this.setProperty('checked', value);
85775  }
85776
85777}
85778
85779CheckboxControlValueAccessor.ɵfac = /* @__PURE__ */function () {
85780  let ɵCheckboxControlValueAccessor_BaseFactory;
85781  return function CheckboxControlValueAccessor_Factory(t) {
85782    return (ɵCheckboxControlValueAccessor_BaseFactory || (ɵCheckboxControlValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](CheckboxControlValueAccessor)))(t || CheckboxControlValueAccessor);
85783  };
85784}();
85785
85786CheckboxControlValueAccessor.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
85787  type: CheckboxControlValueAccessor,
85788  selectors: [["input", "type", "checkbox", "formControlName", ""], ["input", "type", "checkbox", "formControl", ""], ["input", "type", "checkbox", "ngModel", ""]],
85789  hostBindings: function CheckboxControlValueAccessor_HostBindings(rf, ctx) {
85790    if (rf & 1) {
85791      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function CheckboxControlValueAccessor_change_HostBindingHandler($event) {
85792        return ctx.onChange($event.target.checked);
85793      })("blur", function CheckboxControlValueAccessor_blur_HostBindingHandler() {
85794        return ctx.onTouched();
85795      });
85796    }
85797  },
85798  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([CHECKBOX_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
85799});
85800
85801(function () {
85802  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CheckboxControlValueAccessor, [{
85803    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
85804    args: [{
85805      selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]',
85806      host: {
85807        '(change)': 'onChange($event.target.checked)',
85808        '(blur)': 'onTouched()'
85809      },
85810      providers: [CHECKBOX_VALUE_ACCESSOR]
85811    }]
85812  }], null, null);
85813})();
85814/**
85815 * @license
85816 * Copyright Google LLC All Rights Reserved.
85817 *
85818 * Use of this source code is governed by an MIT-style license that can be
85819 * found in the LICENSE file at https://angular.io/license
85820 */
85821
85822
85823const DEFAULT_VALUE_ACCESSOR = {
85824  provide: NG_VALUE_ACCESSOR,
85825  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => DefaultValueAccessor),
85826  multi: true
85827};
85828/**
85829 * We must check whether the agent is Android because composition events
85830 * behave differently between iOS and Android.
85831 */
85832
85833function _isAndroid() {
85834  const userAgent = (0,_angular_common__WEBPACK_IMPORTED_MODULE_1__["ɵgetDOM"])() ? (0,_angular_common__WEBPACK_IMPORTED_MODULE_1__["ɵgetDOM"])().getUserAgent() : '';
85835  return /android (\d+)/.test(userAgent.toLowerCase());
85836}
85837/**
85838 * @description
85839 * Provide this token to control if form directives buffer IME input until
85840 * the "compositionend" event occurs.
85841 * @publicApi
85842 */
85843
85844
85845const COMPOSITION_BUFFER_MODE = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('
85845CompositionEventMode');
85846/**
85847 * The default `ControlValueAccessor` for writing a value and listening to changes on input
85848 * elements. The accessor is used by the `FormControlDirective`, `FormControlName`, and
85849 * `NgModel` directives.
85850 *
85851 * {@searchKeywords ngDefaultControl}
85852 *
85853 * @usageNotes
85854 *
85855 * ### Using the default value accessor
85856 *
85857 * The following example shows how to use an input element that activates the default value accessor
85858 * (in this case, a text field).
85859 *
85860 * ```ts
85861 * const firstNameControl = new FormControl();
85862 * ```
85863 *
85864 * ```
85865 * <input type="text" [formControl]="firstNameControl">
85866 * ```
85867 *
85868 * This value accessor is used by default for `<input type="text">` and `<textarea>` elements, but
85869 * you could also use it for custom components that have similar behavior and do not require special
85870 * processing. In order to attach the default value accessor to a custom element, add the
85871 * `ngDefaultControl` attribute as shown below.
85872 *
85873 * ```
85874 * <custom-input-component ngDefaultControl [(ngModel)]="value"></custom-input-component>
85875 * ```
85876 *
85877 * @ngModule ReactiveFormsModule
85878 * @ngModule FormsModule
85879 * @publicApi
85880 */
85881
85882class DefaultValueAccessor extends BaseControlValueAccessor {
85883  constructor(renderer, elementRef, _compositionMode) {
85884    super(renderer, elementRef);
85885    this._compositionMode = _compositionMode;
85886    /** Whether the user is creating a composition string (IME events). */
85887
85888    this._composing = false;
85889
85890    if (this._compositionMode == null) {
85891      this._compositionMode = !_isAndroid();
85892    }
85893  }
85894  /**
85895   * Sets the "value" property on the input element.
85896   * @nodoc
85897   */
85898
85899
85900  writeValue(value) {
85901    const normalizedValue = value == null ? '' : value;
85902    this.setProperty('value', normalizedValue);
85903  }
85904  /** @internal */
85905
85906
85907  _handleInput(value) {
85908    if (!this._compositionMode || this._compositionMode && !this._composing) {
85909      this.onChange(value);
85910    }
85911  }
85912  /** @internal */
85913
85914
85915  _compositionStart() {
85916    this._composing = true;
85917  }
85918  /** @internal */
85919
85920
85921  _compositionEnd(value) {
85922    this._composing = false;
85923    this._compositionMode && this.onChange(value);
85924  }
85925
85926}
85927
85928DefaultValueAccessor.ɵfac = function DefaultValueAccessor_Factory(t) {
85929  return new (t || DefaultValueAccessor)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](COMPOSITION_BUFFER_MODE, 8));
85930};
85931
85932DefaultValueAccessor.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
85933  type: DefaultValueAccessor,
85934  selectors: [["input", "formControlName", "", 3, "type", "checkbox"], ["textarea", "formControlName", ""], ["input", "formControl", "", 3, "type", "checkbox"], ["textarea", "formControl", ""], ["input", "ngModel", "", 3, "type", "checkbox"], ["textarea", "ngModel", ""], ["", "ngDefaultControl", ""]],
85935  hostBindings: function DefaultValueAccessor_HostBindings(rf, ctx) {
85936    if (rf & 1) {
85937      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("input", function DefaultValueAccessor_input_HostBindingHandler($event) {
85938        return ctx._handleInput($event.target.value);
85939      })("blur", function DefaultValueAccessor_blur_HostBindingHandler() {
85940        return ctx.onTouched();
85941      })("compositionstart", function DefaultValueAccessor_compositionstart_HostBindingHandler() {
85942        return ctx._compositionStart();
85943      })("compositionend", function DefaultValueAccessor_compositionend_HostBindingHandler($event) {
85944        return ctx._compositionEnd($event.target.value);
85945      });
85946    }
85947  },
85948  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([DEFAULT_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
85949});
85950
85951(function () {
85952  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DefaultValueAccessor, [{
85953    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
85954    args: [{
85955      selector: 'input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]',
85956      // TODO: vsavkin replace the above selector with the one below it once
85957      // https://github.com/angular/angular/issues/3011 is implemented
85958      // selector: '[ngModel],[formControl],[formControlName]',
85959      host: {
85960        '(input)': '$any(this)._handleInput($event.target.value)',
85961        '(blur)': 'onTouched()',
85962        '(compositionstart)': '$any(this)._compositionStart()',
85963        '(compositionend)': '$any(this)._compositionEnd($event.target.value)'
85964      },
85965      providers: [DEFAULT_VALUE_ACCESSOR]
85966    }]
85967  }], function () {
85968    return [{
85969      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
85970    }, {
85971      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
85972    }, {
85973      type: undefined,
85974      decorators: [{
85975        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
85976      }, {
85977        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
85978        args: [COMPOSITION_BUFFER_MODE]
85979      }]
85980    }];
85981  }, null);
85982})();
85983/**
85984 * @license
85985 * Copyright Google LLC All Rights Reserved.
85986 *
85987 * Use of this source code is governed by an MIT-style license that can be
85988 * found in the LICENSE file at https://angular.io/license
85989 */
85990
85991
85992const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
85993
85994function isEmptyInputValue(value) {
85995  /**
85996   * Check if the object is a string or array before evaluating the length attribute.
85997   * This avoids falsely rejecting objects that contain a custom length attribute.
85998   * For example, the object {id: 1, length: 0, width: 0} should not be returned as empty.
85999   */
86000  return value == null || (typeof value === 'string' || Array.isArray(value)) && value.length === 0;
86001}
86002
86003function hasValidLength(value) {
86004  // non-strict comparison is intentional, to check for both `null` and `undefined` values
86005  return value != null && typeof value.length === 'number';
86006}
86007/**
86008 * @description
86009 * An `InjectionToken` for registering additional synchronous validators used with
86010 * `AbstractControl`s.
86011 *
86012 * @see `NG_ASYNC_VALIDATORS`
86013 *
86014 * @usageNotes
86015 *
86016 * ### Providing a custom validator
86017 *
86018 * The following example registers a custom validator directive. Adding the validator to the
86019 * existing collection of validators requires the `multi: true` option.
86020 *
86021 * ```typescript
86022 * @Directive({
86023 *   selector: '[customValidator]',
86024 *   providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]
86025 * })
86026 * class CustomValidatorDirective implements Validator {
86027 *   validate(control: AbstractControl): ValidationErrors | null {
86028 *     return { 'custom': true };
86029 *   }
86030 * }
86031 * ```
86032 *
86033 * @publicApi
86034 */
86035
86036
86037const NG_VALIDATORS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('NgValidators');
86038/**
86039 * @description
86040 * An `InjectionToken` for registering additional asynchronous validators used with
86041 * `AbstractControl`s.
86042 *
86043 * @see `NG_VALIDATORS`
86044 *
86045 * @usageNotes
86046 *
86047 * ### Provide a custom async validator directive
86048 *
86049 * The following example implements the `AsyncValidator` interface to create an
86050 * async validator directive with a custom error key.
86051 *
86052 * ```typescript
86053 * @Directive({
86054 *   selector: '[customAsyncValidator]',
86055 *   providers: [{provide: NG_ASYNC_VALIDATORS, useExisting: CustomAsyncValidatorDirective, multi:
86056 * true}]
86057 * })
86058 * class CustomAsyncValidatorDirective implements AsyncValidator {
86059 *   validate(control: AbstractControl): Promise<ValidationErrors|null> {
86060 *     return Promise.resolve({'custom': true});
86061 *   }
86062 * }
86063 * ```
86064 *
86065 * @publicApi
86066 */
86067
86068const NG_ASYNC_VALIDATORS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('NgAsyncValidators');
86069/**
86070 * A regular expression that matches valid e-mail addresses.
86071 *
86072 * At a high level, this regexp matches e-mail addresses of the format `local-part@tld`, where:
86073 * - `local-part` consists of one or more of the allowed characters (alphanumeric and some
86074 *   punctuation symbols).
86075 * - `local-part` cannot begin or end with a period (`.`).
86076 * - `local-part` cannot be longer than 64 characters.
86077 * - `tld` consists of one or more `labels` separated by periods (`.`). For example `localhost` or
86078 *   `foo.com`.
86079 * - A `label` consists of one or more of the allowed characters (alphanumeric, dashes (`-`) and
86080 *   periods (`.`)).
86081 * - A `label` cannot begin or end with a dash (`-`) or a period (`.`).
86082 * - A `label` cannot be longer than 63 characters.
86083 * - The whole address cannot be longer than 254 characters.
86084 *
86085 * ## Implementation background
86086 *
86087 * This regexp was ported over from AngularJS (see there for git history):
86088 * https://github.com/angular/angular.js/blob/c133ef836/src/ng/directive/input.js#L27
86089 * It is based on the
86090 * [WHATWG version](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address) with
86091 * some enhancements to incorporate more RFC rules (such as rules related to domain names and the
86092 * lengths of different parts of the address). The main differences from the WHATWG version are:
86093 *   - Disallow `local-part` to begin or end with a period (`.`).
86094 *   - Disallow `local-part` length to exceed 64 characters.
86095 *   - Disallow total address length to exceed 254 characters.
86096 *
86097 * See [this commit](https://github.com/angular/angular.js/commit/f3f5cf72e) for more details.
86098 */
86099
86100const EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
86101/**
86102 * @description
86103 * Provides a set of built-in validators that can be used by form controls.
86104 *
86105 * A validator is a function that processes a `FormControl` or collection of
86106 * controls and returns an error map or null. A null map means that validation has passed.
86107 *
86108 * @see [Form Validation](/guide/form-validation)
86109 *
86110 * @publicApi
86111 */
86112
86113class Validators {
86114  /**
86115   * @description
86116   * Validator that requires the control's value to be greater than or equal to the provided number.
86117   *
86118   * @usageNotes
86119   *
86120   * ### Validate against a minimum of 3
86121   *
86122   * ```typescript
86123   * const control = new FormControl(2, Validators.min(3));
86124   *
86125   * console.log(control.errors); // {min: {min: 3, actual: 2}}
86126   * ```
86127   *
86128   * @returns A validator function that returns an error map with the
86129   * `min` property if the validation check fails, otherwise `null`.
86130   *
86131   * @see `updateValueAndValidity()`
86132   *
86133   */
86134  static min(min) {
86135    return minValidator(min);
86136  }
86137  /**
86138   * @description
86139   * Validator that requires the control's value to be less than or equal to the provided number.
86140   *
86141   * @usageNotes
86142   *
86143   * ### Validate against a maximum of 15
86144   *
86145   * ```typescript
86146   * const control = new FormControl(16, Validators.max(15));
86147   *
86148   * console.log(control.errors); // {max: {max: 15, actual: 16}}
86149   * ```
86150   *
86151   * @returns A validator function that returns an error map with the
86152   * `max` property if the validation check fails, otherwise `null`.
86153   *
86154   * @see `updateValueAndValidity()`
86155   *
86156   */
86157
86158
86159  static max(max) {
86160    return maxValidator(max);
86161  }
86162  /**
86163   * @description
86164   * Validator that requires the control have a non-empty value.
86165   *
86166   * @usageNotes
86167   *
86168   * ### Validate that the field is non-empty
86169   *
86170   * ```typescript
86171   * const control = new FormControl('', Validators.required);
86172   *
86173   * console.log(control.errors); // {required: true}
86174   * ```
86175   *
86176   * @returns An error map with the `required` property
86177   * if the validation check fails, otherwise `null`.
86178   *
86179   * @see `updateValueAndValidity()`
86180   *
86181   */
86182
86183
86184  static required(control) {
86185    return requiredValidator(control);
86186  }
86187  /**
86188   * @description
86189   * Validator that requires the control's value be true. This validator is commonly
86190   * used for required checkboxes.
86191   *
86192   * @usageNotes
86193   *
86194   * ### Validate that the field value is true
86195   *
86196   * ```typescript
86197   * const control = new FormControl('some value', Validators.requiredTrue);
86198   *
86199   * console.log(control.errors); // {required: true}
86200   * ```
86201   *
86202   * @returns An error map that contains the `required` property
86203   * set to `true` if the validation check fails, otherwise `null`.
86204   *
86205   * @see `updateValueAndValidity()`
86206   *
86207   */
86208
86209
86210  static requiredTrue(control) {
86211    return requiredTrueValidator(control);
86212  }
86213  /**
86214   * @description
86215   * Validator that requires the control's value pass an email validation test.
86216   *
86217   * Tests the value using a [regular
86218   * expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)
86219   * pattern suitable for common use cases. The pattern is based on the definition of a valid email
86220   * address in the [WHATWG HTML
86221   * specification](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address) with
86222   * some enhancements to incorporate more RFC rules (such as rules related to domain names and the
86223   * lengths of different parts of the address).
86224   *
86225   * The differences from the WHATWG version include:
86226   * - Disallow `local-part` (the part before the `@` symbol) to begin or end with a period (`.`).
86227   * - Disallow `local-part` to be longer than 64 characters.
86228   * - Disallow the whole address to be longer than 254 characters.
86229   *
86230   * If this pattern does not satisfy your business needs, you can use `Validators.pattern()` to
86231   * validate the value against a different pattern.
86232   *
86233   * @usageNotes
86234   *
86235   * ### Validate that the field matches a valid email pattern
86236   *
86237   * ```typescript
86238   * const control = new FormControl('bad@', Validators.email);
86239   *
86240   * console.log(control.errors); // {email: true}
86241   * ```
86242   *
86243   * @returns An error map with the `email` property
86244   * if the validation check fails, otherwise `null`.
86245   *
86246   * @see `updateValueAndValidity()`
86247   *
86248   */
86249
86250
86251  static email(control) {
86252    return emailValidator(control);
86253  }
86254  /**
86255   * @description
86256   * Validator that requires the length of the control's value to be greater than or equal
86257   * to the provided minimum length. This validator is also provided by default if you use the
86258   * the HTML5 `minlength` attribute. Note that the `minLength` validator is intended to be used
86259   * only for types that have a numeric `length` property, such as strings or arrays. The
86260   * `minLength` validator logic is also not invoked for values when their `length` property is 0
86261   * (for example in case of an empty string or an empty array), to support optional controls. You
86262   * can use the standard `required` validator if empty values should not be considered valid.
86263   *
86264   * @usageNotes
86265   *
86266   * ### Validate that the field has a minimum of 3 characters
86267   *
86268   * ```typescript
86269   * const control = new FormControl('ng', Validators.minLength(3));
86270   *
86271   * console.log(control.errors); // {minlength: {requiredLength: 3, actualLength: 2}}
86272   * ```
86273   *
86274   * ```html
86275   * <input minlength="5">
86276   * ```
86277   *
86278   * @returns A validator function that returns an error map with the
86279   * `minlength` property if the validation check fails, otherwise `null`.
86280   *
86281   * @see `updateValueAndValidity()`
86282   *
86283   */
86284
86285
86286  static minLength(minLength) {
86287    return minLengthValidator(minLength);
86288  }
86289  /**
86290   * @description
86291   * Validator that requires the length of the control's value to be less than or equal
86292   * to the provided maximum length. This validator is also provided by default if you use the
86293   * the HTML5 `maxlength` attribute. Note that the `maxLength` validator is intended to be used
86294   * only for types that have a numeric `length` property, such as strings or arrays.
86295   *
86296   * @usageNotes
86297   *
86298   * ### Validate that the field has maximum of 5 characters
86299   *
86300   * ```typescript
86301   * const control = new FormControl('Angular', Validators.maxLength(5));
86302   *
86303   * console.log(control.errors); // {maxlength: {requiredLength: 5, actualLength: 7}}
86304   * ```
86305   *
86306   * ```html
86307   * <input maxlength="5">
86308   * ```
86309   *
86310   * @returns A validator function that returns an error map with the
86311   * `maxlength` property if the validation check fails, otherwise `null`.
86312   *
86313   * @see `updateValueAndValidity()`
86314   *
86315   */
86316
86317
86318  static maxLength(maxLength) {
86319    return maxLengthValidator(maxLength);
86320  }
86321  /**
86322   * @description
86323   * Validator that requires the control's value to match a regex pattern. This validator is also
86324   * provided by default if you use the HTML5 `pattern` attribute.
86325   *
86326   * @usageNotes
86327   *
86328   * ### Validate that the field only contains letters or spaces
86329   *
86330   * ```typescript
86331   * const control = new FormControl('1', Validators.pattern('[a-zA-Z ]*'));
86332   *
86333   * console.log(control.errors); // {pattern: {requiredPattern: '^[a-zA-Z ]*$', actualValue: '1'}}
86334   * ```
86335   *
86336   * ```html
86337   * <input pattern="[a-zA-Z ]*">
86338   * ```
86339   *
86340   * ### Pattern matching with the global or sticky flag
86341   *
86342   * `RegExp` objects created with the `g` or `y` flags that are passed into `Validators.pattern`
86343   * can produce different results on the same input when validations are run consecutively. This is
86344   * due to how the behavior of `RegExp.prototype.test` is
86345   * specified in [ECMA-262](https://tc39.es/ecma262/#sec-regexpbuiltinexec)
86346   * (`RegExp` preserves the index of the last match when the global or sticky flag is used).
86347   * Due to this behavior, it is recommended that when using
86348   * `Validators.pattern` you **do not** pass in a `RegExp` object with either the global or sticky
86349   * flag enabled.
86350   *
86351   * ```typescript
86352   * // Not recommended (since the `g` flag is used)
86353   * const controlOne = new FormControl('1', Validators.pattern(/foo/g));
86354   *
86355   * // Good
86356   * const controlTwo = new FormControl('1', Validators.pattern(/foo/));
86357   * ```
86358   *
86359   * @param pattern A regular expression to be used as is to test the values, or a string.
86360   * If a string is passed, the `^` character is prepended and the `$` character is
86361   * appended to the provided string (if not already present), and the resulting regular
86362   * expression is used to test the values.
86363   *
86364   * @returns A validator function that returns an error map with the
86365   * `pattern` property if the validation check fails, otherwise `null`.
86366   *
vendor: 4,278 bytes, lines 86367-86525
86367   * @see `updateValueAndValidity()`
86368   *
86369   */
86370
86371
86372  static pattern(pattern) {
86373    return patternValidator(pattern);
86374  }
86375  /**
86376   * @description
86377   * Validator that performs no operation.
86378   *
86379   * @see `updateValueAndValidity()`
86380   *
86381   */
86382
86383
86384  static nullValidator(control) {
86385    return nullValidator(control);
86386  }
86387
86388  static compose(validators) {
86389    return compose(validators);
86390  }
86391  /**
86392   * @description
86393   * Compose multiple async validators into a single function that returns the union
86394   * of the individual error objects for the provided control.
86395   *
86396   * @returns A validator function that returns an error map with the
86397   * merged error objects of the async validators if the validation check fails, otherwise `null`.
86398   *
86399   * @see `updateValueAndValidity()`
86400   *
86401   */
86402
86403
86404  static composeAsync(validators) {
86405    return composeAsync(validators);
86406  }
86407
86408}
86409/**
86410 * Validator that requires the control's value to be greater than or equal to the provided number.
86411 * See `Validators.min` for additional information.
86412 */
86413
86414
86415function minValidator(min) {
86416  return control => {
86417    if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {
86418      return null; // don't validate empty values to allow optional controls
86419    }
86420
86421    const value = parseFloat(control.value); // Controls with NaN values after parsing should be treated as not having a
86422    // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
86423
86424    return !isNaN(value) && value < min ? {
86425      'min': {
86426        'min': min,
86427        'actual': control.value
86428      }
86429    } : null;
86430  };
86431}
86432/**
86433 * Validator that requires the control's value to be less than or equal to the provided number.
86434 * See `Validators.max` for additional information.
86435 */
86436
86437
86438function maxValidator(max) {
86439  return control => {
86440    if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
86441      return null; // don't validate empty values to allow optional controls
86442    }
86443
86444    const value = parseFloat(control.value); // Controls with NaN values after parsing should be treated as not having a
86445    // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
86446
86447    return !isNaN(value) && value > max ? {
86448      'max': {
86449        'max': max,
86450        'actual': control.value
86451      }
86452    } : null;
86453  };
86454}
86455/**
86456 * Validator that requires the control have a non-empty value.
86457 * See `Validators.required` for additional information.
86458 */
86459
86460
86461function requiredValidator(control) {
86462  return isEmptyInputValue(control.value) ? {
86463    'required': true
86464  } : null;
86465}
86466/**
86467 * Validator that requires the control's value be true. This validator is commonly
86468 * used for required checkboxes.
86469 * See `Validators.requiredTrue` for additional information.
86470 */
86471
86472
86473function requiredTrueValidator(control) {
86474  return control.value === true ? null : {
86475    'required': true
86476  };
86477}
86478/**
86479 * Validator that requires the control's value pass an email validation test.
86480 * See `Validators.email` for additional information.
86481 */
86482
86483
86484function emailValidator(control) {
86485  if (isEmptyInputValue(control.value)) {
86486    return null; // don't validate empty values to allow optional controls
86487  }
86488
86489  return EMAIL_REGEXP.test(control.value) ? null : {
86490    'email': true
86491  };
86492}
86493/**
86494 * Validator that requires the length of the control's value to be greater than or equal
86495 * to the provided minimum length. See `Validators.minLength` for additional information.
86496 */
86497
86498
86499function minLengthValidator(minLength) {
86500  return control => {
86501    if (isEmptyInputValue(control.value) || !hasValidLength(control.value)) {
86502      // don't validate empty values to allow optional controls
86503      // don't validate values without `length` property
86504      return null;
86505    }
86506
86507    return control.value.length < minLength ? {
86508      'minlength': {
86509        'requiredLength': minLength,
86510        'actualLength': control.value.length
86511      }
86512    } : null;
86513  };
86514}
86515/**
86516 * Validator that requires the length of the control's value to be less than or equal
86517 * to the provided maximum length. See `Validators.maxLength` for additional information.
86518 */
86519
86520
86521function maxLengthValidator(maxLength) {
86522  return control => {
86523    return hasValidLength(control.value) && control.value.length > maxLength ? {
86524      'maxlength': {
86525        'requiredLength': maxLength,
86526        'actualLength': control.value.length
86527      }
86528    } : null;
86529  };
86530}
86531/**
86532 * Validator that requires the control's value to match a regex pattern.
86533 * See `Validators.pattern` for additional information.
86534 */
86535
86536
86537function patternValidator(pattern) {
86538  if (!pattern) return nullValidator;
86539  let regex;
86540  let regexStr;
86541
86542  if (typeof pattern === 'string') {
86543    regexStr = '';
86544    if (pattern.charAt(0) !== '^') regexStr += '^';
86545    regexStr += pattern;
86546    if (pattern.charAt(pattern.length - 1) !== '$') regexStr += '$';
86547    regex = new RegExp(regexStr);
86548  } else {
86549    regexStr = pattern.toString();
86550    regex = pattern;
86551  }
86552
86553  return control => {
86554    if (isEmptyInputValue(control.value)) {
86555      return null; // don't validate empty values to allow optional controls
86556    }
86557
86558    const value = control.value;
86559    return regex.test(value) ? null : {
86560      'pattern': {
86561        'requiredPattern': regexStr,
86562        'actualValue': value
86563      }
86564    };
86565  };
86566}
86567/**
86568 * Function that has `ValidatorFn` shape, but performs no operation.
86569 */
86570
86571
86572function nullValidator(control) {
86573  return null;
86574}
86575
86576function isPresent(o) {
86577  return o != null;
86578}
86579
86580function toObservable(value) {
86581  const obs = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisPromise"])(value) ? (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.from)(value) : value;
86582
86583  if (NG_DEV_MODE$1 && !(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisObservable"])(obs)) {
86584    let errorMessage = `Expected async validator to return Promise or Observable.`; // A synchronous validator will return object or null.
86585
86586    if (typeof value === 'object') {
86587      errorMessage += ' Are you using a synchronous validator where an async validator is expected?';
86588    }
86589
86590    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](-1101
86591    /* RuntimeErrorCode.WRONG_VALIDATOR_RETURN_TYPE */
86592    , errorMessage);
86593  }
86594
86595  return obs;
86596}
86597
86598function mergeErrors(arrayOfErrors) {
86599  let res = {}; // Not using Array.reduce here due to a Chrome 80 bug
86600  // https://bugs.chromium.org/p/chromium/issues/detail?id=1049982
86601
86602  arrayOfErrors.forEach(errors => {
86603    res = errors != null ? { ...res,
86604      ...errors
86605    } : res;
86606  });
86607  return Object.keys(res).length === 0 ? null : res;
86608}
86609
86610function executeValidators(control, validators) {
86611  return validators.map(validator => validator(control));
86612}
86613
86614function isValidatorFn(validator) {
86615  return !validator.validate;
86616}
86617/**
86618 * Given the list of validators that may contain both functions as well as classes, return the list
86619 * of validator functions (convert validator classes into validator functions). This is needed to
86620 * have consistent structure in validators list before composing them.
86621 *
86622 * @param validators The set of validators that may contain validators both in plain function form
86623 *     as well as represented as a validator class.
86624 */
86625
86626
86627function normalizeValidators(validators) {
86628  return validators.map(validator => {
86629    return isValidatorFn(validator) ? validator : c => validator.validate(c);
86630  });
86631}
86632/**
86633 * Merges synchronous validators into a single validator function.
86634 * See `Validators.compose` for additional information.
86635 */
86636
86637
86638function compose(validators) {
86639  if (!validators) return null;
86640  const presentValidators = validators.filter(isPresent);
86641  if (presentValidators.length == 0) return null;
86642  return function (control) {
86643    return mergeErrors(executeValidators(control, presentValidators));
86644  };
86645}
86646/**
86647 * Accepts a list of validators of different possible shapes (`Validator` and `ValidatorFn`),
86648 * normalizes the list (converts everything to `ValidatorFn`) and merges them into a single
86649 * validator function.
86650 */
86651
86652
86653function composeValidators(validators) {
86654  return validators != null ? compose(normalizeValidators(validators)) : null;
86655}
86656/**
86657 * Merges asynchronous validators into a single validator function.
86658 * See `Validators.composeAsync` for additional information.
86659 */
86660
86661
86662function composeAsync(validators) {
86663  if (!validators) return null;
86664  const presentValidators = validators.filter(isPresent);
86665  if (presentValidators.length == 0) return null;
86666  return function (control) {
86667    const observables = executeValidators(control, presentValidators).map(toObservable);
86668    return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.forkJoin)(observables).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(mergeErrors));
86669  };
86670}
86671/**
86672 * Accepts a list of async validators of different possible shapes (`AsyncValidator` and
86673 * `AsyncValidatorFn`), normalizes the list (converts everything to `AsyncValidatorFn`) and merges
86674 * them into a single validator function.
86675 */
86676
86677
86678function composeAsyncValidators(validators) {
86679  return validators != null ? composeAsync(normalizeValidators(validators)) : null;
86680}
86681/**
86682 * Merges raw control validators with a given directive validator and returns the combined list of
86683 * validators as an array.
86684 */
86685
86686
86687function mergeValidators(controlValidators, dirValidator) {
86688  if (controlValidators === null) return [dirValidator];
86689  return Array.isArray(controlValidators) ? [...controlValidators, dirValidator] : [controlValidators, dirValidator];
86690}
86691/**
86692 * Retrieves the list of raw synchronous validators attached to a given control.
86693 */
86694
86695
86696function getControlValidators(control) {
86697  return control._rawValidators;
86698}
86699/**
86700 * Retrieves the list of raw asynchronous validators attached to a given control.
86701 */
86702
86703
86704function getControlAsyncValidators(control) {
86705  return control._rawAsyncValidators;
86706}
86707/**
86708 * Accepts a singleton validator, an array, or null, and returns an array type with the provided
86709 * validators.
86710 *
86711 * @param validators A validator, validators, or null.
86712 * @returns A validators array.
86713 */
86714
86715
86716function makeValidatorsArray(validators) {
86717  if (!validators) return [];
86718  return Array.isArray(validators) ? validators : [validators];
86719}
86720/**
86721 * Determines whether a validator or validators array has a given validator.
86722 *
86723 * @param validators The validator or validators to compare against.
86724 * @param validator The validator to check.
86725 * @returns Whether the validator is present.
86726 */
86727
86728
86729function hasValidator(validators, validator) {
86730  return Array.isArray(validators) ? validators.includes(validator) : validators === validator;
86731}
86732/**
86733 * Combines two arrays of validators into one. If duplicates are provided, only one will be added.
86734 *
86735 * @param validators The new validators.
86736 * @param currentValidators The base array of current validators.
86737 * @returns An array of validators.
86738 */
86739
86740
86741function addValidators(validators, currentValidators) {
86742  const current = makeValidatorsArray(currentValidators);
86743  const validatorsToAdd = makeValidatorsArray(validators);
86744  validatorsToAdd.forEach(v => {
86745    // Note: if there are duplicate entries in the new validators array,
86746    // only the first one would be added to the current list of validators.
86747    // Duplicate ones would be ignored since `hasValidator` would detect
86748    // the presence of a validator function and we update the current list in place.
86749    if (!hasValidator(current, v)) {
86750      current.push(v);
86751    }
86752  });
86753  return current;
86754}
86755
86756function removeValidators(validators, currentValidators) {
86757  return makeValidatorsArray(currentValidators).filter(v => !hasValidator(validators, v));
86758}
86759/**
86760 * @license
86761 * Copyright Google LLC All Rights Reserved.
86762 *
86763 * Use of this source code is governed by an MIT-style license that can be
86764 * found in the LICENSE file at https://angular.io/license
86765 */
86766
86767/**
86768 * @description
86769 * Base class for control directives.
86770 *
86771 * This class is only used internally in the `ReactiveFormsModule` and the `FormsModule`.
86772 *
86773 * @publicApi
86774 */
86775
86776
86777class AbstractControlDirective {
86778  constructor() {
86779    /**
86780     * Set of synchronous validators as they were provided while calling `setValidators` function.
86781     * @internal
86782     */
86783    this._rawValidators = [];
86784    /**
86785     * Set of asynchronous validators as they were provided while calling `setAsyncValidators`
86786     * function.
86787     * @internal
86788     */
86789
86790    this._rawAsyncValidators = [];
86791    /*
86792     * The set of callbacks to be invoked when directive instance is being destroyed.
86793     */
86794
86795    this._onDestroyCallbacks = [];
86796  }
86797  /**
86798   * @description
86799   * Reports the value of the control if it is present, otherwise null.
86800   */
86801
86802
86803  get value() {
86804    return this.control ? this.control.value : null;
86805  }
86806  /**
86807   * @description
86808   * Reports whether the control is valid. A control is considered valid if no
86809   * validation errors exist with the current value.
86810   * If the control is not present, null is returned.
86811   */
86812
86813
86814  get valid() {
86815    return this.control ? this.control.valid : null;
86816  }
86817  /**
86818   * @description
86819   * Reports whether the control is invalid, meaning that an error exists in the input value.
86820   * If the control is not present, null is returned.
86821   */
86822
86823
86824  get invalid() {
86825    return this.control ? this.control.invalid : null;
86826  }
86827  /**
86828   * @description
86829   * Reports whether a control is pending, meaning that that async validation is occurring and
86830   * errors are not yet available for the input value. If the control is not present, null is
86831   * returned.
86832   */
86833
86834
86835  get pending() {
86836    return this.control ? this.control.pending : null;
86837  }
86838  /**
86839   * @description
86840   * Reports whether the control is disabled, meaning that the control is disabled
86841   * in the UI and is exempt from validation checks and excluded from aggregate
86842   * values of ancestor controls. If the control is not present, null is returned.
86843   */
86844
86845
86846  get disabled() {
86847    return this.control ? this.control.disabled : null;
86848  }
86849  /**
86850   * @description
86851   * Reports whether the control is enabled, meaning that the control is included in ancestor
86852   * calculations of validity or value. If the control is not present, null is returned.
86853   */
86854
86855
86856  get enabled() {
86857    return this.control ? this.control.enabled : null;
86858  }
86859  /**
86860   * @description
86861   * Reports the control's validation errors. If the control is not present, null is returned.
86862   */
86863
86864
86865  get errors() {
86866    return this.control ? this.control.errors : null;
86867  }
86868  /**
86869   * @description
86870   * Reports whether the control is pristine, meaning that the user has not yet changed
86871   * the value in the UI. If the control is not present, null is returned.
86872   */
86873
86874
86875  get pristine() {
86876    return this.control ? this.control.pristine : null;
86877  }
86878  /**
86879   * @description
86880   * Reports whether the control is dirty, meaning that the user has changed
86881   * the value in the UI. If the control is not present, null is returned.
86882   */
86883
86884
86885  get dirty() {
86886    return this.control ? this.control.dirty : null;
86887  }
86888  /**
86889   * @description
86890   * Reports whether the control is touched, meaning that the user has triggered
86891   * a `blur` event on it. If the control is not present, null is returned.
86892   */
86893
86894
86895  get touched() {
86896    return this.control ? this.control.touched : null;
86897  }
86898  /**
86899   * @description
86900   * Reports the validation status of the control. Possible values include:
86901   * 'VALID', 'INVALID', 'DISABLED', and 'PENDING'.
86902   * If the control is not present, null is returned.
86903   */
86904
86905
86906  get status() {
86907    return this.control ? this.control.status : null;
86908  }
86909  /**
86910   * @description
86911   * Reports whether the control is untouched, meaning that the user has not yet triggered
86912   * a `blur` event on it. If the control is not present, null is returned.
86913   */
86914
86915
86916  get untouched() {
86917    return this.control ? this.control.untouched : null;
86918  }
86919  /**
86920   * @description
86921   * Returns a multicasting observable that emits a validation status whenever it is
86922   * calculated for the control. If the control is not present, null is returned.
86923   */
86924
86925
86926  get statusChanges() {
86927    return this.control ? this.control.statusChanges : null;
86928  }
86929  /**
86930   * @description
86931   * Returns a multicasting observable of value changes for the control that emits every time the
86932   * value of the control changes in the UI or programmatically.
86933   * If the control is not present, null is returned.
86934   */
86935
86936
86937  get valueChanges() {
86938    return this.control ? this.control.valueChanges : null;
86939  }
86940  /**
86941   * @description
86942   * Returns an array that represents the path from the top-level form to this control.
86943   * Each index is the string name of the control on that level.
86944   */
86945
86946
86947  get path() {
86948    return null;
86949  }
86950  /**
86951   * Sets synchronous validators for this directive.
86952   * @internal
86953   */
86954
86955
86956  _setValidators(validators) {
86957    this._rawValidators = validators || [];
86958    this._composedValidatorFn = composeValidators(this._rawValidators);
86959  }
86960  /**
86961   * Sets asynchronous validators for this directive.
86962   * @internal
86963   */
86964
86965
86966  _setAsyncValidators(validators) {
86967    this._rawAsyncValidators = validators || [];
86968    this._composedAsyncValidatorFn = composeAsyncValidators(this._rawAsyncValidators);
86969  }
86970  /**
86971   * @description
86972   * Synchronous validator function composed of all the synchronous validators registered with this
86973   * directive.
86974   */
86975
86976
86977  get validator() {
86978    return this._composedValidatorFn || null;
86979  }
86980  /**
86981   * @description
86982   * Asynchronous validator function composed of all the asynchronous validators registered with
86983   * this directive.
86984   */
86985
86986
86987  get asyncValidator() {
86988    return this._composedAsyncValidatorFn || null;
86989  }
86990  /**
86991   * Internal function to register callbacks that should be invoked
86992   * when directive instance is being destroyed.
86993   * @internal
86994   */
86995
86996
86997  _registerOnDestroy(fn) {
86998    this._onDestroyCallbacks.push(fn);
86999  }
87000  /**
87001   * Internal function to invoke all registered "on destroy" callbacks.
87002   * Note: calling this function also clears the list of callbacks.
87003   * @internal
87004   */
87005
87006
87007  _invokeOnDestroyCallbacks() {
87008    this._onDestroyCallbacks.forEach(fn => fn());
87009
87010    this._onDestroyCallbacks = [];
87011  }
87012  /**
87013   * @description
87014   * Resets the control with the provided value if the control is present.
87015   */
87016
87017
87018  reset(value = undefined) {
87019    if (this.control) this.control.reset(value);
87020  }
87021  /**
87022   * @description
87023   * Reports whether the control with the given path has the error specified.
87024   *
87025   * @param errorCode The code of the error to check
87026   * @param path A list of control names that designates how to move from the current control
87027   * to the control that should be queried for errors.
87028   *
87029   * @usageNotes
87030   * For example, for the following `FormGroup`:
87031   *
87032   * ```
87033   * form = new FormGroup({
87034   *   address: new FormGroup({ street: new FormControl() })
87035   * });
87036   * ```
87037   *
87038   * The path to the 'street' control from the root form would be 'address' -> 'street'.
87039   *
87040   * It can be provided to this method in one of two formats:
87041   *
87042   * 1. An array of string control names, e.g. `['address', 'street']`
87043   * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
87044   *
87045   * If no path is given, this method checks for the error on the current control.
87046   *
87047   * @returns whether the given error is present in the control at the given path.
87048   *
87049   * If the control is not present, false is returned.
87050   */
87051
87052
87053  hasError(errorCode, path) {
87054    return this.control ? this.control.hasError(errorCode, path) : false;
87055  }
87056  /**
87057   * @description
87058   * Reports error data for the control with the given path.
87059   *
87060   * @param errorCode The code of the error to check
87061   * @param path A list of control names that designates how to move from the current control
87062   * to the control that should be queried for errors.
87063   *
87064   * @usageNotes
87065   * For example, for the following `FormGroup`:
87066   *
87067   * ```
87068   * form = new FormGroup({
87069   *   address: new FormGroup({ street: new FormControl() })
87070   * });
87071   * ```
87072   *
87073   * The path to the 'street' control from the root form would be 'address' -> 'street'.
87074   *
87075   * It can be provided to this method in one of two formats:
87076   *
87077   * 1. An array of string control names, e.g. `['address', 'street']`
87078   * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
87079   *
87080   * @returns error data for that particular error. If the control or error is not present,
87081   * null is returned.
87082   */
87083
87084
87085  getError(errorCode, path) {
87086    return this.control ? this.control.getError(errorCode, path) : null;
87087  }
87088
87089}
87090/**
87091 * @license
87092 * Copyright Google LLC All Rights Reserved.
87093 *
87094 * Use of this source code is governed by an MIT-style license that can be
87095 * found in the LICENSE file at https://angular.io/license
87096 */
87097
87098/**
87099 * @description
87100 * A base class for directives that contain multiple registered instances of `NgControl`.
87101 * Only used by the forms module.
87102 *
87103 * @publicApi
87104 */
87105
87106
87107class ControlContainer extends AbstractControlDirective {
87108  /**
87109   * @description
87110   * The top-level form directive for the control.
87111   */
87112  get formDirective() {
87113    return null;
87114  }
87115  /**
87116   * @description
87117   * The path to this group.
87118   */
87119
87120
87121  get path() {
87122    return null;
87123  }
87124
87125}
87126/**
87127 * @license
87128 * Copyright Google LLC All Rights Reserved.
87129 *
87130 * Use of this source code is governed by an MIT-style license that can be
87131 * found in the LICENSE file at https://angular.io/license
87132 */
87133
87134/**
87135 * @description
87136 * A base class that all `FormControl`-based directives extend. It binds a `FormControl`
87137 * object to a DOM element.
87138 *
87139 * @publicApi
87140 */
87141
87142
87143class NgControl extends AbstractControlDirective {
87144  constructor() {
87145    super(...arguments);
87146    /**
87147     * @description
87148     * The parent form for the control.
87149     *
87150     * @internal
87151     */
87152
87153    this._parent = null;
87154    /**
87155     * @description
87156     * The name for the control
87157     */
87158
87159    this.name = null;
87160    /**
87161     * @description
87162     * The value accessor for the control
87163     */
87164
87165    this.valueAccessor = null;
87166  }
87167
87168}
87169/**
87170 * @license
87171 * Copyright Google LLC All Rights Reserved.
87172 *
87173 * Use of this source code is governed by an MIT-style license that can be
87174 * found in the LICENSE file at https://angular.io/license
87175 */
87176// DO NOT REFACTOR!
87177// Each status is represented by a separate function to make sure that
87178// advanced Closure Compiler optimizations related to property renaming
87179// can work correctly.
87180
87181
87182class AbstractControlStatus {
87183  constructor(cd) {
87184    this._cd = cd;
87185  }
87186
87187  get isTouched() {
87188    return !!this._cd?.control?.touched;
87189  }
87190
87191  get isUntouched() {
87192    return !!this._cd?.control?.untouched;
87193  }
87194
87195  get isPristine() {
87196    return !!this._cd?.control?.pristine;
87197  }
87198
87199  get isDirty() {
87200    return !!this._cd?.control?.dirty;
87201  }
87202
87203  get isValid() {
87204    return !!this._cd?.control?.valid;
87205  }
87206
87207  get isInvalid() {
87208    return !!this._cd?.control?.invalid;
87209  }
87210
87211  get isPending() {
87212    return !!this._cd?.control?.pending;
87213  }
87214
87215  get isSubmitted() {
87216    // We check for the `submitted` field from `NgForm` and `FormGroupDirective` classes, but
87217    // we avoid instanceof checks to prevent non-tree-shakable references to those types.
87218    return !!this._cd?.submitted;
87219  }
87220
87221}
87222
87223const ngControlStatusHost = {
87224  '[class.ng-untouched]': 'isUntouched',
87225  '[class.ng-touched]': 'isTouched',
87226  '[class.ng-pristine]': 'isPristine',
87227  '[class.ng-dirty]': 'isDirty',
87228  '[class.ng-valid]': 'isValid',
87229  '[class.ng-invalid]': 'isInvalid',
87230  '[class.ng-pending]': 'isPending'
87231};
87232const ngGroupStatusHost = { ...ngControlStatusHost,
87233  '[class.ng-submitted]': 'isSubmitted'
87234};
87235/**
87236 * @description
87237 * Directive automatically applied to Angular form controls that sets CSS classes
87238 * based on control status.
87239 *
87240 * @usageNotes
87241 *
87242 * ### CSS classes applied
87243 *
87244 * The following classes are applied as the properties become true:
87245 *
87246 * * ng-valid
87247 * * ng-invalid
87248 * * ng-pending
87249 * * ng-pristine
87250 * * ng-dirty
87251 * * ng-untouched
87252 * * ng-touched
87253 *
87254 * @ngModule ReactiveFormsModule
87255 * @ngModule FormsModule
87256 * @publicApi
87257 */
87258
87259class NgControlStatus extends AbstractControlStatus {
87260  constructor(cd) {
87261    super(cd);
87262  }
87263
87264}
87265
87266NgControlStatus.ɵfac = function NgControlStatus_Factory(t) {
87267  return new (t || NgControlStatus)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgControl, 2));
87268};
87269
87270NgControlStatus.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
87271  type: NgControlStatus,
87272  selectors: [["", "formControlName", ""], ["", "ngModel", ""], ["", "formControl", ""]],
87273  hostVars: 14,
87274  hostBindings: function NgControlStatus_HostBindings(rf, ctx) {
87275    if (rf & 2) {
87276      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-untouched", ctx.isUntouched)("ng-touched", ctx.isTouched)("ng-pristine", ctx.isPristine)("ng-dirty", ctx.isDirty)("ng-valid", ctx.isValid)("ng-invalid", ctx.isInvalid)("ng-pending", ctx.isPending);
87277    }
87278  },
87279  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
87280});
87281
87282(function () {
87283  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgControlStatus, [{
87284    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
87285    args: [{
87286      selector: '[formControlName],[ngModel],[formControl]',
87287      host: ngControlStatusHost
87288    }]
87289  }], function () {
87290    return [{
87291      type: NgControl,
87292      decorators: [{
87293        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
87294      }]
87295    }];
87296  }, null);
87297})();
87298/**
87299 * @description
87300 * Directive automatically applied to Angular form groups that sets CSS classes
87301 * based on control status (valid/invalid/dirty/etc). On groups, this includes the additional
87302 * class ng-submitted.
87303 *
87304 * @see `NgControlStatus`
87305 *
87306 * @ngModule ReactiveFormsModule
87307 * @ngModule FormsModule
87308 * @publicApi
87309 */
87310
87311
87312class NgControlStatusGroup extends AbstractControlStatus {
87313  constructor(cd) {
87314    super(cd);
87315  }
87316
87317}
87318
87319NgControlStatusGroup.ɵfac = function NgControlStatusGroup_Factory(t) {
87320  return new (t || NgControlStatusGroup)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 10));
87321};
87322
87323NgControlStatusGroup.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
87324  type: NgControlStatusGroup,
87325  selectors: [["", "formGroupName", ""], ["", "formArrayName", ""], ["", "ngModelGroup", ""], ["", "formGroup", ""], ["form", 3, "ngNoForm", ""], ["", "ngForm", ""]],
87326  hostVars: 16,
87327  hostBindings: function NgControlStatusGroup_HostBindings(rf, ctx) {
87328    if (rf & 2) {
87329      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-untouched", ctx.isUntouched)("ng-touched", ctx.isTouched)("ng-pristine", ctx.isPristine)("ng-dirty", ctx.isDirty)("ng-valid", ctx.isValid)("ng-invalid", ctx.isInvalid)("ng-pending", ctx.isPending)("ng-submitted", ctx.isSubmitted);
87330    }
87331  },
87332  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
87333});
87334
87335(function () {
87336  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgControlStatusGroup, [{
87337    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
87338    args: [{
87339      selector: '[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]',
87340      host: ngGroupStatusHost
87341    }]
87342  }], function () {
87343    return [{
87344      type: ControlContainer,
87345      decorators: [{
87346        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
87347      }, {
87348        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
87349      }]
87350    }];
87351  }, null);
87352})();
87353/**
87354 * @license
87355 * Copyright Google LLC All Rights Reserved.
87356 *
87357 * Use of this source code is governed by an MIT-style license that can be
87358 * found in the LICENSE file at https://angular.io/license
87359 */
87360
87361
87362const formControlNameExample = `
87363  <div [formGroup]="myGroup">
87364    <input formControlName="firstName">
87365  </div>
87366
87367  In your class:
87368
87369  this.myGroup = new FormGroup({
87370      firstName: new FormControl()
87371  });`;
87372const formGroupNameExample = `
87373  <div [formGroup]="myGroup">
87374      <div formGroupName="person">
87375        <input formControlName="firstName">
87376      </div>
87377  </div>
87378
87379  In your class:
87380
87381  this.myGroup = new FormGroup({
87382      person: new FormGroup({ firstName: new FormControl() })
87383  });`;
87384const formArrayNameExample = `
87385  <div [formGroup]="myGroup">
87386    <div formArrayName="cities">
87387      <div *ngFor="let city of cityArray.controls; index as i">
87388        <input [formControlName]="i">
87389      </div>
87390    </div>
87391  </div>
87392
87393  In your class:
87394
87395  this.cityArray = new FormArray([new FormControl('SF')]);
87396  this.myGroup = new FormGroup({
87397    cities: this.cityArray
87398  });`;
87399const ngModelGroupExample = `
87400  <form>
87401      <div ngModelGroup="person">
87402        <input [(ngModel)]="person.name" name="firstName">
87403      </div>
87404  </form>`;
87405const ngModelWithFormGroupExample = `
87406  <div [formGroup]="myGroup">
87407      <input formControlName="firstName">
87408      <input [(ngModel)]="showMoreControls" [ngModelOptions]="{standalone: true}">
87409  </div>
87410`;
87411/**
87412 * @license
87413 * Copyright Google LLC All Rights Reserved.
87414 *
87415 * Use of this source code is governed by an MIT-style license that can be
87416 * found in the LICENSE file at https://angular.io/license
87417 */
87418
87419function controlParentException() {
87420  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1050
87421  /* RuntimeErrorCode.FORM_CONTROL_NAME_MISSING_PARENT */
87422  , `formControlName must be used with a parent formGroup directive.  You'll want to add a formGroup
87423      directive and pass it an existing FormGroup instance (you can create one in your class).
87424
87425    Example:
87426
87427    ${formControlNameExample}`);
87428}
87429
87430function ngModelGroupException() {
87431  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1051
87432  /* RuntimeErrorCode.FORM_CONTROL_NAME_INSIDE_MODEL_GROUP */
87433  , `formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents
87434      that also have a "form" prefix: formGroupName, formArrayName, or formGroup.
87435
87436      Option 1:  Update the parent to be formGroupName (reactive form strategy)
87437
87438      ${formGroupNameExample}
87439
87440      Option 2: Use ngModel instead of formControlName (template-driven strategy)
87441
87442      ${ngModelGroupExample}`);
87443}
87444
87445function missingFormException() {
87446  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1052
87447  /* RuntimeErrorCode.FORM_GROUP_MISSING_INSTANCE */
87448  , `formGroup expects a FormGroup instance. Please pass one in.
87449
87450      Example:
87451
87452      ${formControlNameExample}`);
87453}
87454
87455function groupParentException() {
87456  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1053
87457  /* RuntimeErrorCode.FORM_GROUP_NAME_MISSING_PARENT */
87458  , `formGroupName must be used with a parent formGroup directive.  You'll want to add a formGroup
87459    directive and pass it an existing FormGroup instance (you can create one in your class).
87460
87461    Example:
87462
87463    ${formGroupNameExample}`);
87464}
87465
87466function arrayParentException() {
87467  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1054
87468  /* RuntimeErrorCode.FORM_ARRAY_NAME_MISSING_PARENT */
87469  , `formArrayName must be used with a parent formGroup directive.  You'll want to add a formGroup
87470      directive and pass it an existing FormGroup instance (you can create one in your class).
87471
87472      Example:
87473
87474      ${formArrayNameExample}`);
87475}
87476
87477const disabledAttrWarning = `
87478  It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true
87479  when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
87480  you. We recommend using this approach to avoid 'changed after checked' errors.
87481
87482  Example:
87483  // Specify the \`disabled\` property at control creation time:
87484  form = new FormGroup({
87485    first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
87486    last: new FormControl('Drew', Validators.required)
87487  });
87488
87489  // Controls can also be enabled/disabled after creation:
87490  form.get('first')?.enable();
87491  form.get('last')?.disable();
87492`;
87493const asyncValidatorsDroppedWithOptsWarning = `
87494  It looks like you're constructing using a FormControl with both an options argument and an
87495  async validators argument. Mixing these arguments will cause your async validators to be dropped.
87496  You should either put all your validators in the options object, or in separate validators
87497  arguments. For example:
87498
87499  // Using validators arguments
87500  fc = new FormControl(42, Validators.required, myAsyncValidator);
87501
87502  // Using AbstractControlOptions
87503  fc = new FormControl(42, {validators: Validators.required, asyncValidators: myAV});
87504
87505  // Do NOT mix them: async validators will be dropped!
87506  fc = new FormControl(42, {validators: Validators.required}, /* Oops! */ myAsyncValidator);
87507`;
87508
87509function ngModelWarning(directiveName) {
87510  return `
87511  It looks like you're using ngModel on the same form field as ${directiveName}.
87512  Support for using the ngModel input property and ngModelChange event with
87513  reactive form directives has been deprecated in Angular v6 and will be removed
87514  in a future version of Angular.
87515
87516  For more information on this, see our API docs here:
87517  https://angular.io/api/forms/${directiveName === 'formControl' ? 'FormControlDirective' : 'FormControlName'}#use-with-ngmodel
87518  `;
87519}
87520
87521function describeKey(isFormGroup, key) {
87522  return isFormGroup ? `with name: '${key}'` : `at index: ${key}`;
87523}
87524
87525function noControlsError(isFormGroup) {
87526  return `
87527    There are no form controls registered with this ${isFormGroup ? 'group' : 'array'} yet. If you're using ngModel,
87528    you may want to check next tick (e.g. use setTimeout).
87529  `;
87530}
87531
87532function missingControlError(isFormGroup, key) {
87533  return `Cannot find form control ${describeKey(isFormGroup, key)}`;
87534}
87535
87536function missingControlValueError(isFormGroup, key) {
87537  return `Must supply a value for form control ${describeKey(isFormGroup, key)}`;
87538}
87539/**
87540 * @license
87541 * Copyright Google LLC All Rights Reserved.
87542 *
87543 * Use of this source code is governed by an MIT-style license that can be
87544 * found in the LICENSE file at https://angular.io/license
87545 */
87546
87547
87548const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
87549/**
87550 * Reports that a control is valid, meaning that no errors exist in the input value.
87551 *
87552 * @see `status`
87553 */
87554
87555const VALID = 'VALID';
87556/**
87557 * Reports that a control is invalid, meaning that an error exists in the input value.
87558 *
87559 * @see `status`
87560 */
87561
87562const INVALID = 'INVALID';
87563/**
87564 * Reports that a control is pending, meaning that that async validation is occurring and
87565 * errors are not yet available for the input value.
87566 *
87567 * @see `markAsPending`
87568 * @see `status`
87569 */
87570
87571const PENDING = 'PENDING';
87572/**
87573 * Reports that a control is disabled, meaning that the control is exempt from ancestor
87574 * calculations of validity or value.
87575 *
87576 * @see `markAsDisabled`
87577 * @see `status`
87578 */
87579
87580const DISABLED = 'DISABLED';
87581/**
87582 * Gets validators from either an options object or given validators.
87583 */
87584
87585function pickValidators(validatorOrOpts) {
87586  return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.validators : validatorOrOpts) || null;
87587}
87588/**
87589 * Creates validator function by combining provided validators.
87590 */
87591
87592
87593function coerceToValidator(validator) {
87594  return Array.isArray(validator) ? composeValidators(validator) : validator || null;
87595}
87596/**
87597 * Gets async validators from either an options object or given validators.
87598 */
87599
87600
87601function pickAsyncValidators(asyncValidator, validatorOrOpts) {
87602  if (typeof ngDevMode === 'undefined' || ngDevMode) {
87603    if (isOptionsObj(validatorOrOpts) && asyncValidator) {
87604      console.warn(asyncValidatorsDroppedWithOptsWarning);
87605    }
87606  }
87607
87608  return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.asyncValidators : asyncValidator) || null;
87609}
87610/**
87611 * Creates async validator function by combining provided async validators.
87612 */
87613
87614
87615function coerceToAsyncValidator(asyncValidator) {
87616  return Array.isArray(asyncValidator) ? composeAsyncValidators(asyncValidator) : asyncValidator || null;
87617}
87618
87619function isOptionsObj(validatorOrOpts) {
87620  return validatorOrOpts != null && !Array.isArray(validatorOrOpts) && typeof validatorOrOpts === 'object';
87621}
87622
87623function assertControlPresent(parent, isGroup, key) {
87624  const controls = parent.controls;
87625  const collection = isGroup ? Object.keys(controls) : controls;
87626
87627  if (!collection.length) {
87628    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1000
87629    /* RuntimeErrorCode.NO_CONTROLS */
87630    , NG_DEV_MODE ? noControlsError(isGroup) : '');
87631  }
87632
87633  if (!controls[key]) {
87634    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1001
87635    /* RuntimeErrorCode.MISSING_CONTROL */
87636    , NG_DEV_MODE ? missingControlError(isGroup, key) : '');
87637  }
87638}
87639
87640function assertAllValuesPresent(control, isGroup, value) {
87641  control._forEachChild((_, key) => {
87642    if (value[key] === undefined) {
87643      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1002
87644      /* RuntimeErrorCode.MISSING_CONTROL_VALUE */
87645      , NG_DEV_MODE ? missingControlValueError(isGroup, key) : '');
87646    }
87647  });
87648} // clang-format on
87649
87650/**
87651 * This is the base class for `FormControl`, `FormGroup`, and `FormArray`.
87652 *
87653 * It provides some of the shared behavior that all controls and groups of controls have, like
87654 * running validators, calculating status, and resetting state. It also defines the properties
87655 * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
87656 * instantiated directly.
87657 *
87658 * The first type parameter TValue represents the value type of the control (`control.value`).
87659 * The optional type parameter TRawValue  represents the raw value type (`control.getRawValue()`).
87660 *
87661 * @see [Forms Guide](/guide/forms)
87662 * @see [Reactive Forms Guide](/guide/reactive-forms)
87663 * @see [Dynamic Forms Guide](/guide/dynamic-form)
87664 *
87665 * @publicApi
87666 */
87667
87668
87669class AbstractControl {
87670  /**
87671   * Initialize the AbstractControl instance.
87672   *
87673   * @param validators The function or array of functions that is used to determine the validity of
87674   *     this control synchronously.
87675   * @param asyncValidators The function or array of functions that is used to determine validity of
87676   *     this control asynchronously.
87677   */
87678  constructor(validators, asyncValidators) {
87679    /** @internal */
87680    this._pendingDirty = false;
87681    /**
87682     * Indicates that a control has its own pending asynchronous validation in progress.
87683     *
87684     * @internal
87685     */
87686
87687    this._hasOwnPendingAsyncValidator = false;
87688    /** @internal */
87689
87690    this._pendingTouched = false;
87691    /** @internal */
87692
87693    this._onCollectionChange = () => {};
87694
87695    this._parent = null;
87696    /**
87697     * A control is `pristine` if the user has not yet changed
87698     * the value in the UI.
87699     *
87700     * @returns True if the user has not yet changed the value in the UI; compare `dirty`.
87701     * Programmatic changes to a control's value do not mark it dirty.
87702     */
87703
87704    this.pristine = true;
87705    /**
87706     * True if the control is marked as `touched`.
87707     *
87708     * A control is marked `touched` once the user has triggered
87709     * a `blur` event on it.
87710     */
87711
87712    this.touched = false;
87713    /** @internal */
87714
87715    this._onDisabledChange = [];
87716    this._rawValidators = validators;
87717    this._rawAsyncValidators = asyncValidators;
87718    this._composedValidatorFn = coerceToValidator(this._rawValidators);
87719    this._composedAsyncValidatorFn = coerceToAsyncValidator(this._rawAsyncValidators);
87720  }
87721  /**
87722   * Returns the function that is used to determine the validity of this control synchronously.
87723   * If multiple validators have been added, this will be a single composed function.
87724   * See `Validators.compose()` for additional information.
87725   */
87726
87727
87728  get validator() {
87729    return this._composedValidatorFn;
87730  }
87731
87732  set validator(validatorFn) {
87733    this._rawValidators = this._composedValidatorFn = validatorFn;
87734  }
87735  /**
87736   * Returns the function that is used to determine the validity of this control asynchronously.
87737   * If multiple validators have been added, this will be a single composed function.
87738   * See `Validators.compose()` for additional information.
87739   */
87740
87741
87742  get asyncValidator() {
87743    return this._composedAsyncValidatorFn;
87744  }
87745
87746  set asyncValidator(asyncValidatorFn) {
87747    this._rawAsyncValidators = this._composedAsyncValidatorFn = asyncValidatorFn;
87748  }
87749  /**
87750   * The parent control.
87751   */
87752
87753
87754  get parent() {
87755    return this._parent;
87756  }
87757  /**
87758   * A control is `valid` when its `status` is `VALID`.
87759   *
87760   * @see {@link AbstractControl.status}
87761   *
87762   * @returns True if the control has passed all of its validation tests,
87763   * false otherwise.
87764   */
87765
87766
87767  get valid() {
87768    return this.status === VALID;
87769  }
87770  /**
87771   * A control is `invalid` when its `status` is `INVALID`.
87772   *
87773   * @see {@link AbstractControl.status}
87774   *
87775   * @returns True if this control has failed one or more of its validation checks,
87776   * false otherwise.
87777   */
87778
87779
87780  get invalid() {
87781    return this.status === INVALID;
87782  }
87783  /**
87784   * A control is `pending` when its `status` is `PENDING`.
87785   *
87786   * @see {@link AbstractControl.status}
87787   *
87788   * @returns True if this control is in the process of conducting a validation check,
87789   * false otherwise.
87790   */
87791
87792
87793  get pending() {
87794    return this.status == PENDING;
87795  }
87796  /**
87797   * A control is `disabled` when its `status` is `DISABLED`.
87798   *
87799   * Disabled controls are exempt from validation checks and
87800   * are not included in the aggregate value of their ancestor
87801   * controls.
87802   *
87803   * @see {@link AbstractControl.status}
87804   *
87805   * @returns True if the control is disabled, false otherwise.
87806   */
87807
87808
87809  get disabled() {
87810    return this.status === DISABLED;
87811  }
87812  /**
87813   * A control is `enabled` as long as its `status` is not `DISABLED`.
87814   *
87815   * @returns True if the control has any status other than 'DISABLED',
87816   * false if the status is 'DISABLED'.
87817   *
87818   * @see {@link AbstractControl.status}
87819   *
87820   */
87821
87822
87823  get enabled() {
87824    return this.status !== DISABLED;
87825  }
87826  /**
87827   * A control is `dirty` if the user has changed the value
87828   * in the UI.
87829   *
87830   * @returns True if the user has changed the value of this control in the UI; compare `pristine`.
87831   * Programmatic changes to a control's value do not mark it dirty.
87832   */
87833
87834
87835  get dirty() {
87836    return !this.pristine;
87837  }
87838  /**
87839   * True if the control has not been marked as touched
87840   *
87841   * A control is `untouched` if the user has not yet triggered
87842   * a `blur` event on it.
87843   */
87844
87845
87846  get untouched() {
87847    return !this.touched;
87848  }
87849  /**
87850   * Reports the update strategy of the `AbstractControl` (meaning
87851   * the event on which the control updates itself).
87852   * Possible values: `'change'` | `'blur'` | `'submit'`
87853   * Default value: `'change'`
87854   */
87855
87856
87857  get updateOn() {
87858    return this._updateOn ? this._updateOn : this.parent ? this.parent.updateOn : 'change';
87859  }
87860  /**
87861   * Sets the synchronous validators that are active on this control.  Calling
87862   * this overwrites any existing synchronous validators.
87863   *
87864   * When you add or remove a validator at run time, you must call
87865   * `updateValueAndValidity()` for the new validation to take effect.
87866   *
87867   * If you want to add a new validator without affecting existing ones, consider
87868   * using `addValidators()` method instead.
87869   */
87870
87871
87872  setValidators(validators) {
87873    this._rawValidators = validators;
87874    this._composedValidatorFn = coerceToValidator(validators);
87875  }
87876  /**
87877   * Sets the asynchronous validators that are active on this control. Calling this
87878   * overwrites any existing asynchronous validators.
87879   *
87880   * When you add or remove a validator at run time, you must call
87881   * `updateValueAndValidity()` for the new validation to take effect.
87882   *
87883   * If you want to add a new validator without affecting existing ones, consider
87884   * using `addAsyncValidators()` method instead.
87885   */
87886
87887
87888  setAsyncValidators(validators) {
87889    this._rawAsyncValidators = validators;
87890    this._composedAsyncValidatorFn = coerceToAsyncValidator(validators);
87891  }
87892  /**
87893   * Add a synchronous validator or validators to this control, without affecting other validators.
87894   *
87895   * When you add or remove a validator at run time, you must call
87896   * `updateValueAndValidity()` for the new validation to take effect.
87897   *
87898   * Adding a validator that already exists will have no effect. If duplicate validator functions
87899   * are present in the `validators` array, only the first instance would be added to a form
87900   * control.
87901   *
87902   * @param validators The new validator function or functions to add to this control.
87903   */
87904
87905
87906  addValidators(validators) {
87907    this.setValidators(addValidators(validators, this._rawValidators));
87908  }
87909  /**
87910   * Add an asynchronous validator or validators to this control, without affecting other
87911   * validators.
87912   *
87913   * When you add or remove a validator at run time, you must call
87914   * `updateValueAndValidity()` for the new validation to take effect.
87915   *
87916   * Adding a validator that already exists will have no effect.
87917   *
87918   * @param validators The new asynchronous validator function or functions to add to this control.
87919   */
87920
87921
87922  addAsyncValidators(validators) {
87923    this.setAsyncValidators(addValidators(validators, this._rawAsyncValidators));
87924  }
87925  /**
87926   * Remove a synchronous validator from this control, without affecting other validators.
87927   * Validators are compared by function reference; you must pass a reference to the exact same
87928   * validator function as the one that was originally set. If a provided validator is not found,
87929   * it is ignored.
87930   *
87931   * @usageNotes
87932   *
87933   * ### Reference to a ValidatorFn
87934   *
87935   * ```
87936   * // Reference to the RequiredValidator
87937   * const ctrl = new FormControl<string | null>('', Validators.required);
87938   * ctrl.removeValidators(Validators.required);
87939   *
87940   * // Reference to anonymous function inside MinValidator
87941   * const minValidator = Validators.min(3);
87942   * const ctrl = new FormControl<string | null>('', minValidator);
87943   * expect(ctrl.hasValidator(minValidator)).toEqual(true)
87944   * expect(ctrl.hasValidator(Validators.min(3)).toEqual(false)
87945   *
87946   * ctrl.removeValidators(minValidator);
87947   * ```
87948   *
87949   * When you add or remove a validator at run time, you must call
87950   * `updateValueAndValidity()` for the new validation to take effect.
87951   *
87952   * @param validators The validator or validators to remove.
87953   */
87954
87955
87956  removeValidators(validators) {
87957    this.setValidators(removeValidators(validators, this._rawValidators));
87958  }
87959  /**
87960   * Remove an asynchronous validator from this control, without affecting other validators.
87961   * Validators are compared by function reference; you must pass a reference to the exact same
87962   * validator function as the one that was originally set. If a provided validator is not found, it
87963   * is ignored.
87964   *
87965   * When you add or remove a validator at run time, you must call
87966   * `updateValueAndValidity()` for the new validation to take effect.
87967   *
87968   * @param validators The asynchronous validator or validators to remove.
87969   */
87970
87971
87972  removeAsyncValidators(validators) {
87973    this.setAsyncValidators(removeValidators(validators, this._rawAsyncValidators));
87974  }
87975  /**
87976   * Check whether a synchronous validator function is present on this control. The provided
87977   * validator must be a reference to the exact same function that was provided.
87978   *
87979   * @usageNotes
87980   *
87981   * ### Reference to a ValidatorFn
87982   *
87983   * ```
87984   * // Reference to the RequiredValidator
87985   * const ctrl = new FormControl<number | null>(0, Validators.required);
87986   * expect(ctrl.hasValidator(Validators.required)).toEqual(true)
87987   *
87988   * // Reference to anonymous function inside MinValidator
87989   * const minValidator = Validators.min(3);
87990   * const ctrl = new FormControl<number | null>(0, minValidator);
87991   * expect(ctrl.hasValidator(minValidator)).toEqual(true)
87992   * expect(ctrl.hasValidator(Validators.min(3)).toEqual(false)
87993   * ```
87994   *
87995   * @param validator The validator to check for presence. Compared by function reference.
87996   * @returns Whether the provided validator was found on this control.
87997   */
87998
87999
88000  hasValidator(validator) {
88001    return hasValidator(this._rawValidators, validator);
88002  }
88003  /**
88004   * Check whether an asynchronous validator function is present on this control. The provided
88005   * validator must be a reference to the exact same function that was provided.
88006   *
88007   * @param validator The asynchronous validator to check for presence. Compared by function
88008   *     reference.
88009   * @returns Whether the provided asynchronous validator was found on this control.
88010   */
88011
88012
88013  hasAsyncValidator(validator) {
88014    return hasValidator(this._rawAsyncValidators, validator);
88015  }
88016  /**
88017   * Empties out the synchronous validator list.
88018   *
88019   * When you add or remove a validator at run time, you must call
88020   * `updateValueAndValidity()` for the new validation to take effect.
88021   *
88022   */
88023
88024
88025  clearValidators() {
88026    this.validator = null;
88027  }
88028  /**
88029   * Empties out the async validator list.
88030   *
88031   * When you add or remove a validator at run time, you must call
88032   * `updateValueAndValidity()` for the new validation to take effect.
88033   *
88034   */
88035
88036
88037  clearAsyncValidators() {
88038    this.asyncValidator = null;
88039  }
88040  /**
88041   * Marks the control as `touched`. A control is touched by focus and
88042   * blur events that do not change the value.
88043   *
88044   * @see `markAsUntouched()`
88045   * @see `markAsDirty()`
88046   * @see `markAsPristine()`
88047   *
88048   * @param opts Configuration options that determine how the control propagates changes
88049   * and emits events after marking is applied.
88050   * * `onlySelf`: When true, mark only this control. When false or not supplied,
88051   * marks all direct ancestors. Default is false.
88052   */
88053
88054
88055  markAsTouched(opts = {}) {
88056    this.touched = true;
88057
88058    if (this._parent && !opts.onlySelf) {
88059      this._parent.markAsTouched(opts);
88060    }
88061  }
88062  /**
88063   * Marks the control and all its descendant controls as `touched`.
88064   * @see `markAsTouched()`
88065   */
88066
88067
88068  markAllAsTouched() {
88069    this.markAsTouched({
88070      onlySelf: true
88071    });
88072
88073    this._forEachChild(control => control.markAllAsTouched());
88074  }
88075  /**
88076   * Marks the control as `untouched`.
88077   *
88078   * If the control has any children, also marks all children as `untouched`
88079   * and recalculates the `touched` status of all parent controls.
88080   *
88081   * @see `markAsTouched()`
88082   * @see `markAsDirty()`
88083   * @see `markAsPristine()`
88084   *
88085   * @param opts Configuration options that determine how the control propagates changes
88086   * and emits events after the marking is applied.
88087   * * `onlySelf`: When true, mark only this control. When false or not supplied,
88088   * marks all direct ancestors. Default is false.
88089   */
88090
88091
88092  markAsUntouched(opts = {}) {
88093    this.touched = false;
88094    this._pendingTouched = false;
88095
88096    this._forEachChild(control => {
88097      control.markAsUntouched({
88098        onlySelf: true
88099      });
88100    });
88101
88102    if (this._parent && !opts.onlySelf) {
88103      this._parent._updateTouched(opts);
88104    }
88105  }
88106  /**
88107   * Marks the control as `dirty`. A control becomes dirty when
88108   * the control's value is changed through the UI; compare `markAsTouched`.
88109   *
88110   * @see `markAsTouched()`
88111   * @see `markAsUntouched()`
88112   * @see `markAsPristine()`
88113   *
88114   * @param opts Configuration options that determine how the control propagates changes
88115   * and emits events after marking is applied.
88116   * * `onlySelf`: When true, mark only this control. When false or not supplied,
88117   * marks all direct ancestors. Default is false.
88118   */
88119
88120
88121  markAsDirty(opts = {}) {
88122    this.pristine = false;
88123
88124    if (this._parent && !opts.onlySelf) {
88125      this._parent.markAsDirty(opts);
88126    }
88127  }
88128  /**
88129   * Marks the control as `pristine`.
88130   *
88131   * If the control has any children, marks all children as `pristine`,
88132   * and recalculates the `pristine` status of all parent
88133   * controls.
88134   *
88135   * @see `markAsTouched()`
88136   * @see `markAsUntouched()`
88137   * @see `markAsDirty()`
88138   *
88139   * @param opts Configuration options that determine how the control emits events after
88140   * marking is applied.
88141   * * `onlySelf`: When true, mark only this control. When false or not supplied,
88142   * marks all direct ancestors. Default is false.
88143   */
88144
88145
88146  markAsPristine(opts = {}) {
88147    this.pristine = true;
88148    this._pendingDirty = false;
88149
88150    this._forEachChild(control => {
88151      control.markAsPristine({
88152        onlySelf: true
88153      });
88154    });
88155
88156    if (this._parent && !opts.onlySelf) {
88157      this._parent._updatePristine(opts);
88158    }
88159  }
88160  /**
88161   * Marks the control as `pending`.
88162   *
88163   * A control is pending while the control performs async validation.
88164   *
88165   * @see {@link AbstractControl.status}
88166   *
88167   * @param opts Configuration options that determine how the control propagates changes and
88168   * emits events after marking is applied.
88169   * * `onlySelf`: When true, mark only this control. When false or not supplied,
88170   * marks all direct ancestors. Default is false.
88171   * * `emitEvent`: When true or not supplied (the default), the `statusChanges`
88172   * observable emits an event with the latest status the control is marked pending.
88173   * When false, no events are emitted.
88174   *
88175   */
88176
88177
88178  markAsPending(opts = {}) {
88179    this.status = PENDING;
88180
88181    if (opts.emitEvent !== false) {
88182      this.statusChanges.emit(this.status);
88183    }
88184
88185    if (this._parent && !opts.onlySelf) {
88186      this._parent.markAsPending(opts);
88187    }
88188  }
88189  /**
88190   * Disables the control. This means the control is exempt from validation checks and
88191   * excluded from the aggregate value of any parent. Its status is `DISABLED`.
88192   *
88193   * If the control has children, all children are also disabled.
88194   *
88195   * @see {@link AbstractControl.status}
88196   *
88197   * @param opts Configuration options that determine how the control propagates
88198   * changes and emits events after the control is disabled.
88199   * * `onlySelf`: When true, mark only this control. When false or not supplied,
88200   * marks all direct ancestors. Default is false.
88201   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
88202   * `valueChanges`
88203   * observables emit events with the latest status and value when the control is disabled.
88204   * When false, no events are emitted.
88205   */
88206
88207
88208  disable(opts = {}) {
88209    // If parent has been marked artificially dirty we don't want to re-calculate the
88210    // parent's dirtiness based on the children.
88211    const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
88212
88213    this.status = DISABLED;
88214    this.errors = null;
88215
88216    this._forEachChild(control => {
88217      control.disable({ ...opts,
88218        onlySelf: true
88219      });
88220    });
88221
88222    this._updateValue();
88223
88224    if (opts.emitEvent !== false) {
88225      this.valueChanges.emit(this.value);
88226      this.statusChanges.emit(this.status);
88227    }
88228
88229    this._updateAncestors({ ...opts,
88230      skipPristineCheck
88231    });
88232
88233    this._onDisabledChange.forEach(changeFn => changeFn(true));
88234  }
88235  /**
88236   * Enables the control. This means the control is included in validation checks and
88237   * the aggregate value of its parent. Its status recalculates based on its value and
88238   * its validators.
88239   *
88240   * By default, if the control has children, all children are enabled.
88241   *
88242   * @see {@link AbstractControl.status}
88243   *
88244   * @param opts Configure options that control how the control propagates changes and
88245   * emits events when marked as untouched
88246   * * `onlySelf`: When true, mark only this control. When false or not supplied,
88247   * marks all direct ancestors. Default is false.
88248   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
88249   * `valueChanges`
88250   * observables emit events with the latest status and value when the control is enabled.
88251   * When false, no events are emitted.
88252   */
88253
88254
88255  enable(opts = {}) {
88256    // If parent has been marked artificially dirty we don't want to re-calculate the
88257    // parent's dirtiness based on the children.
88258    const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
88259
88260    this.status = VALID;
88261
88262    this._forEachChild(control => {
88263      control.enable({ ...opts,
88264        onlySelf: true
88265      });
88266    });
88267
88268    this.updateValueAndValidity({
88269      onlySelf: true,
88270      emitEvent: opts.emitEvent
88271    });
88272
88273    this._updateAncestors({ ...opts,
88274      skipPristineCheck
88275    });
88276
88277    this._onDisabledChange.forEach(changeFn => changeFn(false));
88278  }
88279
88280  _updateAncestors(opts) {
88281    if (this._parent && !opts.onlySelf) {
88282      this._parent.updateValueAndValidity(opts);
88283
88284      if (!opts.skipPristineCheck) {
88285        this._parent._updatePristine();
88286      }
88287
88288      this._parent._updateTouched();
88289    }
88290  }
88291  /**
88292   * Sets the parent of the control
88293   *
88294   * @param parent The new parent.
88295   */
88296
88297
88298  setParent(parent) {
88299    this._parent = parent;
88300  }
88301  /**
88302   * The raw value of this control. For most control implementations, the raw value will include
88303   * disabled children.
88304   */
88305
88306
88307  getRawValue() {
88308    return this.value;
88309  }
88310  /**
88311   * Recalculates the value and validation status of the control.
88312   *
88313   * By default, it also updates the value and validity of its ancestors.
88314   *
88315   * @param opts Configuration options determine how the control propagates changes and emits events
88316   * after updates and validity checks are applied.
88317   * * `onlySelf`: When true, only update this control. When false or not supplied,
88318   * update all direct ancestors. Default is false.
88319   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
88320   * `valueChanges`
88321   * observables emit events with the latest status and value when the control is updated.
88322   * When false, no events are emitted.
88323   */
88324
88325
88326  updateValueAndValidity(opts = {}) {
88327    this._setInitialStatus();
88328
88329    this._updateValue();
88330
88331    if (this.enabled) {
88332      this._cancelExistingSubscription();
88333
88334      this.errors = this._runValidator();
88335      this.status = this._calculateStatus();
88336
88337      if (this.status === VALID || this.status === PENDING) {
88338        this._runAsyncValidator(opts.emitEvent);
88339      }
88340    }
88341
88342    if (opts.emitEvent !== false) {
88343      this.valueChanges.emit(this.value);
88344      this.statusChanges.emit(this.status);
88345    }
88346
88347    if (this._parent && !opts.onlySelf) {
88348      this._parent.updateValueAndValidity(opts);
88349    }
88350  }
88351  /** @internal */
88352
88353
88354  _updateTreeValidity(opts = {
88355    emitEvent: true
88356  }) {
88357    this._forEachChild(ctrl => ctrl._updateTreeValidity(opts));
88358
88359    this.updateValueAndValidity({
88360      onlySelf: true,
88361      emitEvent: opts.emitEvent
88362    });
88363  }
88364
88365  _setInitialStatus() {
88366    this.status = this._allControlsDisabled() ? DISABLED : VALID;
88367  }
88368
88369  _runValidator() {
88370    return this.validator ? this.validator(this) : null;
88371  }
88372
88373  _runAsyncValidator(emitEvent) {
88374    if (this.asyncValidator) {
88375      this.status = PENDING;
88376      this._hasOwnPendingAsyncValidator = true;
88377      const obs = toObservable(this.asyncValidator(this));
88378      this._asyncValidationSubscription = obs.subscribe(errors => {
88379        this._hasOwnPendingAsyncValidator = false; // This will trigger the recalculation of the validation status, which depen
88379ds on
88380        // the state of the asynchronous validation (whether it is in progress or not). So, it is
88381        // necessary that we have updated the `_hasOwnPendingAsyncValidator` boolean flag first.
88382
88383        this.setErrors(errors, {
88384          emitEvent
88385        });
88386      });
88387    }
88388  }
88389
88390  _cancelExistingSubscription() {
88391    if (this._asyncValidationSubscription) {
88392      this._asyncValidationSubscription.unsubscribe();
88393
88394      this._hasOwnPendingAsyncValidator = false;
88395    }
88396  }
88397  /**
88398   * Sets errors on a form control when running validations manually, rather than automatically.
88399   *
88400   * Calling `setErrors` also updates the validity of the parent control.
88401   *
88402   * @param opts Configuration options that determine how the control propagates
88403   * changes and emits events after the control errors are set.
88404   * * `emitEvent`: When true or not supplied (the default), the `statusChanges`
88405   * observable emits an event after the errors are set.
88406   *
88407   * @usageNotes
88408   *
88409   * ### Manually set the errors for a control
88410   *
88411   * ```
88412   * const login = new FormControl('someLogin');
88413   * login.setErrors({
88414   *   notUnique: true
88415   * });
88416   *
88417   * expect(login.valid).toEqual(false);
88418   * expect(login.errors).toEqual({ notUnique: true });
88419   *
88420   * login.setValue('someOtherLogin');
88421   *
88422   * expect(login.valid).toEqual(true);
88423   * ```
88424   */
88425
88426
88427  setErrors(errors, opts = {}) {
88428    this.errors = errors;
88429
88430    this._updateControlsErrors(opts.emitEvent !== false);
88431  }
88432  /**
88433   * Retrieves a child control given the control's name or path.
88434   *
88435   * @param path A dot-delimited string or array of string/number values that define the path to the
88436   * control. If a string is provided, passing it as a string literal will result in improved type
88437   * information. Likewise, if an array is provided, passing it `as const` will cause improved type
88438   * information to be available.
88439   *
88440   * @usageNotes
88441   * ### Retrieve a nested control
88442   *
88443   * For example, to get a `name` control nested within a `person` sub-group:
88444   *
88445   * * `this.form.get('person.name');`
88446   *
88447   * -OR-
88448   *
88449   * * `this.form.get(['person', 'name'] as const);` // `as const` gives improved typings
88450   *
88451   * ### Retrieve a control in a FormArray
88452   *
88453   * When accessing an element inside a FormArray, you can use an element index.
88454   * For example, to get a `price` control from the first element in an `items` array you can use:
88455   *
88456   * * `this.form.get('items.0.price');`
88457   *
88458   * -OR-
88459   *
88460   * * `this.form.get(['items', 0, 'price']);`
88461   */
88462
88463
88464  get(path) {
vendor: 5,312 bytes, lines 88465-88666
88465    let currPath = path;
88466    if (currPath == null) return null;
88467    if (!Array.isArray(currPath)) currPath = currPath.split('.');
88468    if (currPath.length === 0) return null;
88469    return currPath.reduce((control, name) => control && control._find(name), this);
88470  }
88471  /**
88472   * @description
88473   * Reports error data for the control with the given path.
88474   *
88475   * @param errorCode The code of the error to check
88476   * @param path A list of control names that designates how to move from the current control
88477   * to the control that should be queried for errors.
88478   *
88479   * @usageNotes
88480   * For example, for the following `FormGroup`:
88481   *
88482   * ```
88483   * form = new FormGroup({
88484   *   address: new FormGroup({ street: new FormControl() })
88485   * });
88486   * ```
88487   *
88488   * The path to the 'street' control from the root form would be 'address' -> 'street'.
88489   *
88490   * It can be provided to this method in one of two formats:
88491   *
88492   * 1. An array of string control names, e.g. `['address', 'street']`
88493   * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
88494   *
88495   * @returns error data for that particular error. If the control or error is not present,
88496   * null is returned.
88497   */
88498
88499
88500  getError(errorCode, path) {
88501    const control = path ? this.get(path) : this;
88502    return control && control.errors ? control.errors[errorCode] : null;
88503  }
88504  /**
88505   * @description
88506   * Reports whether the control with the given path has the error specified.
88507   *
88508   * @param errorCode The code of the error to check
88509   * @param path A list of control names that designates how to move from the current control
88510   * to the control that should be queried for errors.
88511   *
88512   * @usageNotes
88513   * For example, for the following `FormGroup`:
88514   *
88515   * ```
88516   * form = new FormGroup({
88517   *   address: new FormGroup({ street: new FormControl() })
88518   * });
88519   * ```
88520   *
88521   * The path to the 'street' control from the root form would be 'address' -> 'street'.
88522   *
88523   * It can be provided to this method in one of two formats:
88524   *
88525   * 1. An array of string control names, e.g. `['address', 'street']`
88526   * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
88527   *
88528   * If no path is given, this method checks for the error on the current control.
88529   *
88530   * @returns whether the given error is present in the control at the given path.
88531   *
88532   * If the control is not present, false is returned.
88533   */
88534
88535
88536  hasError(errorCode, path) {
88537    return !!this.getError(errorCode, path);
88538  }
88539  /**
88540   * Retrieves the top-level ancestor of this control.
88541   */
88542
88543
88544  get root() {
88545    let x = this;
88546
88547    while (x._parent) {
88548      x = x._parent;
88549    }
88550
88551    return x;
88552  }
88553  /** @internal */
88554
88555
88556  _updateControlsErrors(emitEvent) {
88557    this.status = this._calculateStatus();
88558
88559    if (emitEvent) {
88560      this.statusChanges.emit(this.status);
88561    }
88562
88563    if (this._parent) {
88564      this._parent._updateControlsErrors(emitEvent);
88565    }
88566  }
88567  /** @internal */
88568
88569
88570  _initObservables() {
88571    this.valueChanges = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
88572    this.statusChanges = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
88573  }
88574
88575  _calculateStatus() {
88576    if (this._allControlsDisabled()) return DISABLED;
88577    if (this.errors) return INVALID;
88578    if (this._hasOwnPendingAsyncValidator || this._anyControlsHaveStatus(PENDING)) return PENDING;
88579    if (this._anyControlsHaveStatus(INVALID)) return INVALID;
88580    return VALID;
88581  }
88582  /** @internal */
88583
88584
88585  _anyControlsHaveStatus(status) {
88586    return this._anyControls(control => control.status === status);
88587  }
88588  /** @internal */
88589
88590
88591  _anyControlsDirty() {
88592    return this._anyControls(control => control.dirty);
88593  }
88594  /** @internal */
88595
88596
88597  _anyControlsTouched() {
88598    return this._anyControls(control => control.touched);
88599  }
88600  /** @internal */
88601
88602
88603  _updatePristine(opts = {}) {
88604    this.pristine = !this._anyControlsDirty();
88605
88606    if (this._parent && !opts.onlySelf) {
88607      this._parent._updatePristine(opts);
88608    }
88609  }
88610  /** @internal */
88611
88612
88613  _updateTouched(opts = {}) {
88614    this.touched = this._anyControlsTouched();
88615
88616    if (this._parent && !opts.onlySelf) {
88617      this._parent._updateTouched(opts);
88618    }
88619  }
88620  /** @internal */
88621
88622
88623  _registerOnCollectionChange(fn) {
88624    this._onCollectionChange = fn;
88625  }
88626  /** @internal */
88627
88628
88629  _setUpdateStrategy(opts) {
88630    if (isOptionsObj(opts) && opts.updateOn != null) {
88631      this._updateOn = opts.updateOn;
88632    }
88633  }
88634  /**
88635   * Check to see if parent has been marked artificially dirty.
88636   *
88637   * @internal
88638   */
88639
88640
88641  _parentMarkedDirty(onlySelf) {
88642    const parentDirty = this._parent && this._parent.dirty;
88643    return !onlySelf && !!parentDirty && !this._parent._anyControlsDirty();
88644  }
88645  /** @internal */
88646
88647
88648  _find(name) {
88649    return null;
88650  }
88651
88652}
88653/**
88654 * @license
88655 * Copyright Google LLC All Rights Reserved.
88656 *
88657 * Use of this source code is governed by an MIT-style license that can be
88658 * found in the LICENSE file at https://angular.io/license
88659 */
88660
88661/**
88662 * Tracks the value and validity state of a group of `FormControl` instances.
88663 *
88664 * A `FormGroup` aggregates the values of each child `FormControl` into one object,
88665 * with each control name as the key.  It calculates its status by reducing the status values
88666 * of its children. For example, if one of the controls in a group is invali
88666d, the entire
88667 * group becomes invalid.
88668 *
88669 * `FormGroup` is one of the four fundamental building blocks used to define forms in Angular,
88670 * along with `FormControl`, `FormArray`, and `FormRecord`.
88671 *
88672 * When instantiating a `FormGroup`, pass in a collection of child controls as the first
88673 * argument. The key for each child registers the name for the control.
88674 *
88675 * `FormGroup` is intended for use cases where the keys are known ahead of time.
88676 * If you need to dynamically add and remove controls, use {@link FormRecord} instead.
88677 *
88678 * `FormGroup` accepts an optional type parameter `TControl`, which is an object type with inner
88679 * control types as values.
88680 *
88681 * @usageNotes
88682 *
88683 * ### Create a form group with 2 controls
88684 *
88685 * ```
88686 * const form = new FormGroup({
88687 *   first: new FormControl('Nancy', Validators.minLength(2)),
88688 *   last: new FormControl('Drew'),
88689 * });
88690 *
88691 * console.log(form.value);   // {first: 'Nancy', last; 'Drew'}
88692 * console.log(form.status);  // 'VALID'
88693 * ```
88694 *
88695 * ### The type argument, and optional controls
88696 *
88697 * `FormGroup` accepts one generic argument, which is an object c
88697ontaining its inner controls.
88698 * This type will usually be inferred automatically, but you can always specify it explicitly if you
88699 * wish.
88700 *
88701 * If you have controls that are optional (i.e. they can be removed, you can use the `?` in the
88702 * type):
88703 *
88704 * ```
88705 * const form = new FormGroup<{
88706 *   first: FormControl<string|null>,
88707 *   middle?: FormControl<string|null>, // Middle name is optional.
88708 *   last: FormControl<string|null>,
88709 * }>({
88710 *   first: new FormControl('Nancy'),
88711 *   last: new FormControl('Drew'),
88712 * });
88713 * ```
88714 *
88715 * ### Create a form group with a group-level validator
88716 *
88717 * You include group-level validators as the second arg, or group-level async
88718 * validators as the third arg. These come in handy when you want to perform validation
88719 * that considers the value of more than one child control.
88720 *
88721 * ```
88722 * const form = new FormGroup({
88723 *   password: new FormControl('', Validators.minLength(2)),
88724 *   passwordConfirm: new FormControl('', Validators.minLength(2)),
88725 * }, passwordMatchValidator);
88726 *
88727 *
88728 * function passwordMatchValidator(g: FormGroup) {
88729 *    return g.get('password').value === g.get('passwordConfirm').value
88730 *       ? null : {'mismatch': true};
88731 * }
88732 * ```
88733 *
88734 * Like `FormControl` instances, you choose to pass in
88735 * validators and async validators as part of an options object.
88736 *
88737 * ```
88738 * const form = new FormGroup({
88739 *   password: new FormControl('')
88740 *   passwordConfirm: new FormControl('')
88741 * }, { validators: passwordMatchValidator, asyncValidators: otherValidator });
88742 * ```
88743 *
88744 * ### Set the updateOn property for all controls in a form group
88745 *
88746 * The options object is used to set a default value for each child
88747 * control's `updateOn` property. If you set `updateOn` to `'blur'` at the
88748 * group level, all child controls default to 'blur', unless the child
88749 * has explicitly specified a different `updateOn` value.
88750 *
88751 * ```ts
88752 * const c = new FormGroup({
88753 *   one: new FormControl()
88754 * }, { updateOn: 'blur' });
88755 * ```
88756 *
88757 * ### Using a FormGroup with optional controls
88758 *
88759 * It is possible to have optional controls in a FormGroup. An optional control can be removed later
88760 * using `removeControl`, and can be omitted when calling `reset`. Optional controls must be
88761 * declared optional in the group's type.
88762 *
88763 * ```ts
88764 * const c = new FormGroup<{one?: FormControl<string>}>({
88765 *   one: new FormControl('')
88766 * });
88767 * ```
88768 *
88769 * Notice that `c.value.one` has type `string|null|undefined`. This is because calling `c.reset({})`
88770 * without providing the optional key `one` will cause it to become `null`.
88771 *
88772 * @publicApi
88773 */
88774
88775
88776class FormGroup extends AbstractControl {
88777  /**
88778   * Creates a new `FormGroup` instance.
88779   *
88780   * @param controls A collection of child controls. The key for each child is the name
88781   * under which it is registered.
88782   *
88783   * @param validatorOrOpts A synchronous validator function, or an array of
88784   * such functions, or an `AbstractControlOptions` object that contains validation functions
88785   * and a validation trigger.
88786   *
88787   * @param asyncValidator A single async validator or array of async validator functions
88788   *
88789   */
88790  constructor(controls, validatorOrOpts, asyncValidator) {
88791    super(pickValidators(validatorOrOpts), pickAsyncValidators(asyncValidator, validatorOrOpts));
88792    this.controls = controls;
88793
88794    this._initObservables();
88795
88796    this._setUpdateStrategy(validatorOrOpts);
88797
88798    this._setUpControls();
88799
88800    this.updateValueAndValidity({
88801      onlySelf: true,
88802      // If `asyncValidator` is present, it will trigger control status change from `PENDING` to
88803      // `VALID` or `INVALID`. The status should be broadcasted via the `statusChanges` observable,
88804      // so we set `emitEvent` to `true` to allow that during the control creation process.
88805      emitEvent: !!this.asyncValidator
88806    });
88807  }
88808
88809  registerControl(name, control) {
88810    if (this.controls[name]) return this.controls[name];
88811    this.controls[name] = control;
88812    control.setParent(this);
88813
88814    control._registerOnCollectionChange(this._onCollectionChange);
88815
88816    return control;
88817  }
88818
88819  addControl(name, control, options = {}) {
88820    this.registerControl(name, control);
vendor: 26,860 bytes, lines 88821-89606
88821    this.updateValueAndValidity({
88822      emitEvent: options.emitEvent
88823    });
88824
88825    this._onCollectionChange();
88826  }
88827  /**
88828   * Remove a control from this group. In a strongly-typed group, required controls cannot be
88829   * removed.
88830   *
88831   * This method also updates the value and validity of the control.
88832   *
88833   * @param name The control name to remove from the collection
88834   * @param options Specifies whether this FormGroup instance should emit events after a
88835   *     control is removed.
88836   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
88837   * `valueChanges` observables emit events with the latest status and value when the control is
88838   * removed. When false, no events are emitted.
88839   */
88840
88841
88842  removeControl(name, options = {}) {
88843    if (this.controls[name]) this.controls[name]._registerOnCollectionChange(() => {});
88844    delete this.controls[name];
88845    this.updateValueAndValidity({
88846      emitEvent: options.emitEvent
88847    });
88848
88849    this._onCollectionChange();
88850  }
88851
88852  setControl(name, control, options = {}) {
88853    if (this.controls[name]) this.controls[name]._registerOnCollectionChange(() => {});
88854    delete this.controls[name];
88855    if (control) this.registerControl(name, control);
88856    this.updateValueAndValidity({
88857      emitEvent: options.emitEvent
88858    });
88859
88860    this._onCollectionChange();
88861  }
88862
88863  contains(controlName) {
88864    return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled;
88865  }
88866  /**
88867   * Sets the value of the `FormGroup`. It accepts an object that matches
88868   * the structure of the group, with control names as keys.
88869   *
88870   * @usageNotes
88871   * ### Set the complete value for the form group
88872   *
88873   * ```
88874   * const form = new FormGroup({
88875   *   first: new FormControl(),
88876   *   last: new FormControl()
88877   * });
88878   *
88879   * console.log(form.value);   // {first: null, last: null}
88880   *
88881   * form.setValue({first: 'Nancy', last: 'Drew'});
88882   * console.log(form.value);   // {first: 'Nancy', last: 'Drew'}
88883   * ```
88884   *
88885   * @throws When strict checks fail, such as setting the value of a control
88886   * that doesn't exist or if you exclude a value of a control that does exist.
88887   *
88888   * @param value The new value for the control that matches the structure of the group.
88889   * @param options Configuration options that determine how the control propagates changes
88890   * and emits events after the value changes.
88891   * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity
88892   * updateValueAndValidity} method.
88893   *
88894   * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is
88895   * false.
88896   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
88897   * `valueChanges`
88898   * observables emit events with the latest status and value when the control value is updated.
88899   * When false, no events are emitted.
88900   */
88901
88902
88903  setValue(value, options = {}) {
88904    assertAllValuesPresent(this, true, value);
88905    Object.keys(value).forEach(name => {
88906      assertControlPresent(this, true, name);
88907      this.controls[name].setValue(value[name], {
88908        onlySelf: true,
88909        emitEvent: options.emitEvent
88910      });
88911    });
88912    this.updateValueAndValidity(options);
88913  }
88914  /**
88915   * Patches the value of the `FormGroup`. It accepts an object with control
88916   * names as keys, and does its best to match the values to the correct controls
88917   * in the group.
88918   *
88919   * It accepts both super-sets and sub-sets of the group without throwing an error.
88920   *
88921   * @usageNotes
88922   * ### Patch the value for a form group
88923   *
88924   * ```
88925   * const form = new FormGroup({
88926   *    first: new FormControl(),
88927   *    last: new FormControl()
88928   * });
88929   * console.log(form.value);   // {first: null, last: null}
88930   *
88931   * form.patchValue({first: 'Nancy'});
88932   * console.log(form.value);   // {first: 'Nancy', last: null}
88933   * ```
88934   *
88935   * @param value The object that matches the structure of the group.
88936   * @param options Configuration options that determine how the control propagates changes and
88937   * emits events after the value is patched.
88938   * * `onlySelf`: When true, each change only affects this control and not its parent. Default is
88939   * true.
88940   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
88941   * `valueChanges` observables emit events with the latest status and value when the control value
88942   * is updated. When false, no events are emitted. The configuration options are passed to
88943   * the {@link AbstractControl#updateValueAndValidity updateValueAndValidity} method.
88944   */
88945
88946
88947  patchValue(value, options = {}) {
88948    // Even though the `value` argument type doesn't allow `null` and `undefined` values, the
88949    // `patchValue` can be called recursively and inner data structures might have these values, so
88950    // we just ignore such cases when a field containing FormGroup instance receives `null` or
88951    // `undefined` as a value.
88952    if (value == null
88953    /* both `null` and `undefined` */
88954    ) return;
88955    Object.keys(value).forEach(name => {
88956      // The compiler cannot see through the uninstantiated conditional type of `this.controls`, so
88957      // `as any` is required.
88958      const control = this.controls[name];
88959
88960      if (control) {
88961        control.patchValue(
88962        /* Guaranteed to be present, due to the outer forEach. */
88963        value[name], {
88964          onlySelf: true,
88965          emitEvent: options.emitEvent
88966        });
88967      }
88968    });
88969    this.updateValueAndValidity(options);
88970  }
88971  /**
88972   * Resets the `FormGroup`, marks all descendants `pristine` and `untouched` and sets
88973   * the value of all descendants to their default values, or null if no defaults were provided.
88974   *
88975   * You reset to a specific form state by passing in a map of states
88976   * that matches the structure of your form, with control names as keys. The state
88977   * is a standalone value or a form state object with both a value and a disabled
88978   * status.
88979   *
88980   * @param value Resets the control with an initial value,
88981   * or an object that defines the initial value and disabled state.
88982   *
88983   * @param options Configuration options that determine how the control propagates changes
88984   * and emits events when the group is reset.
88985   * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is
88986   * false.
88987   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
88988   * `valueChanges`
88989   * observables emit events with the latest status and value when the control is reset.
88990   * When false, no events are emitted.
88991   * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity
88992   * updateValueAndValidity} method.
88993   *
88994   * @usageNotes
88995   *
88996   * ### Reset the form group values
88997   *
88998   * ```ts
88999   * const form = new FormGroup({
89000   *   first: new FormControl('first name'),
89001   *   last: new FormControl('last name')
89002   * });
89003   *
89004   * console.log(form.value);  // {first: 'first name', last: 'last name'}
89005   *
89006   * form.reset({ first: 'name', last: 'last name' });
89007   *
89008   * console.log(form.value);  // {first: 'name', last: 'last name'}
89009   * ```
89010   *
89011   * ### Reset the form group values and disabled status
89012   *
89013   * ```
89014   * const form = new FormGroup({
89015   *   first: new FormControl('first name'),
89016   *   last: new FormControl('last name')
89017   * });
89018   *
89019   * form.reset({
89020   *   first: {value: 'name', disabled: true},
89021   *   last: 'last'
89022   * });
89023   *
89024   * console.log(form.value);  // {last: 'last'}
89025   * console.log(form.get('first').status);  // 'DISABLED'
89026   * ```
89027   */
89028
89029
89030  reset(value = {}, options = {}) {
89031    this._forEachChild((control, name) => {
89032      control.reset(value[name], {
89033        onlySelf: true,
89034        emitEvent: options.emitEvent
89035      });
89036    });
89037
89038    this._updatePristine(options);
89039
89040    this._updateTouched(options);
89041
89042    this.updateValueAndValidity(options);
89043  }
89044  /**
89045   * The aggregate value of the `FormGroup`, including any disabled controls.
89046   *
89047   * Retrieves all values regardless of disabled status.
89048   */
89049
89050
89051  getRawValue() {
89052    return this._reduceChildren({}, (acc, control, name) => {
89053      acc[name] = control.getRawValue();
89054      return acc;
89055    });
89056  }
89057  /** @internal */
89058
89059
89060  _syncPendingControls() {
89061    let subtreeUpdated = this._reduceChildren(false, (updated, child) => {
89062      return child._syncPendingControls() ? true : updated;
89063    });
89064
89065    if (subtreeUpdated) this.updateValueAndValidity({
89066      onlySelf: true
89067    });
89068    return subtreeUpdated;
89069  }
89070  /** @internal */
89071
89072
89073  _forEachChild(cb) {
89074    Object.keys(this.controls).forEach(key => {
89075      // The list of controls can change (for ex. controls might be removed) while the loop
89076      // is running (as a result of invoking Forms API in `valueChanges` subscription), so we
89077      // have to null check before invoking the callback.
89078      const control = this.controls[key];
89079      control && cb(control, key);
89080    });
89081  }
89082  /** @internal */
89083
89084
89085  _setUpControls() {
89086    this._forEachChild(control => {
89087      control.setParent(this);
89088
89089      control._registerOnCollectionChange(this._onCollectionChange);
89090    });
89091  }
89092  /** @internal */
89093
89094
89095  _updateValue() {
89096    this.value = this._reduceValue();
89097  }
89098  /** @internal */
89099
89100
89101  _anyControls(condition) {
89102    for (const [controlName, control] of Object.entries(this.controls)) {
89103      if (this.contains(controlName) && condition(control)) {
89104        return true;
89105      }
89106    }
89107
89108    return false;
89109  }
89110  /** @internal */
89111
89112
89113  _reduceValue() {
89114    let acc = {};
89115    return this._reduceChildren(acc, (acc, control, name) => {
89116      if (control.enabled || this.disabled) {
89117        acc[name] = control.value;
89118      }
89119
89120      return acc;
89121    });
89122  }
89123  /** @internal */
89124
89125
89126  _reduceChildren(initValue, fn) {
89127    let res = initValue;
89128
89129    this._forEachChild((control, name) => {
89130      res = fn(res, control, name);
89131    });
89132
89133    return res;
89134  }
89135  /** @internal */
89136
89137
89138  _allControlsDisabled() {
89139    for (const controlName of Object.keys(this.controls)) {
89140      if (this.controls[controlName].enabled) {
89141        return false;
89142      }
89143    }
89144
89145    return Object.keys(this.controls).length > 0 || this.disabled;
89146  }
89147  /** @internal */
89148
89149
89150  _find(name) {
89151    return this.controls.hasOwnProperty(name) ? this.controls[name] : null;
89152  }
89153
89154}
89155
89156const UntypedFormGroup = FormGroup;
89157
89158const isFormGroup = control => control instanceof FormGroup;
89159/**
89160 * Tracks the value and validity state of a collection of `FormControl` instances, each of which has
89161 * the same value type.
89162 *
89163 * `FormRecord` is very similar to {@link FormGroup}, except it can be used with a dynamic keys,
89164 * with controls added and removed as needed.
89165 *
89166 * `FormRecord` accepts one generic argument, which describes the type of the controls it contains.
89167 *
89168 * @usageNotes
89169 *
89170 * ```
89171 * let numbers = new FormRecord({bill: new FormControl('415-123-456')});
89172 * numbers.addControl('bob', new FormControl('415-234-567'));
89173 * numbers.removeControl('bill');
89174 * ```
89175 *
89176 * @publicApi
89177 */
89178
89179
89180class FormRecord extends FormGroup {}
89181
89182const isFormRecord = control => control instanceof FormRecord;
89183/**
89184 * @license
89185 * Copyright Google LLC All Rights Reserved.
89186 *
89187 * Use of this source code is governed by an MIT-style license that can be
89188 * found in the LICENSE file at https://angular.io/license
89189 */
89190
89191
89192function controlPath(name, parent) {
89193  return [...parent.path, name];
89194}
89195/**
89196 * Links a Form control and a Form directive by setting up callbacks (such as `onChange`) on both
89197 * instances. This function is typically invoked when form directive is being initialized.
89198 *
89199 * @param control Form control instance that should be linked.
89200 * @param dir Directive that should be linked with a given control.
89201 */
89202
89203
89204function setUpControl(control, dir) {
89205  if (typeof ngDevMode === 'undefined' || ngDevMode) {
89206    if (!control) _throwError(dir, 'Cannot find control with');
89207    if (!dir.valueAccessor) _throwError(dir, 'No value accessor for form control with');
89208  }
89209
89210  setUpValidators(control, dir);
89211  dir.valueAccessor.writeValue(control.value);
89212
89213  if (control.disabled) {
89214    dir.valueAccessor.setDisabledState?.(true);
89215  }
89216
89217  setUpViewChangePipeline(control, dir);
89218  setUpModelChangePipeline(control, dir);
89219  setUpBlurPipeline(control, dir);
89220  setUpDisabledChangeHandler(control, dir);
89221}
89222/**
89223 * Reverts configuration performed by the `setUpControl` control function.
89224 * Effectively disconnects form control with a given form directive.
89225 * This function is typically invoked when corresponding form directive is being destroyed.
89226 *
89227 * @param control Form control which should be cleaned up.
89228 * @param dir Directive that should be disconnected from a given control.
89229 * @param validateControlPresenceOnChange Flag that indicates whether onChange handler should
89230 *     contain asserts to verify that it's not called once directive is destroyed. We need this flag
89231 *     to avoid potentially breaking changes caused by better control cleanup introduced in #39235.
89232 */
89233
89234
89235function cleanUpControl(control, dir, validateControlPresenceOnChange = true) {
89236  const noop = () => {
89237    if (validateControlPresenceOnChange && (typeof ngDevMode === 'undefined' || ngDevMode)) {
89238      _noControlError(dir);
89239    }
89240  }; // The `valueAccessor` field is typically defined on FromControl and FormControlName directive
89241  // instances and there is a logic in `selectValueAccessor` function that throws if it's not the
89242  // case. We still check the presence of `valueAccessor` before invoking its methods to make sure
89243  // that cleanup works correctly if app code or tests are setup to ignore the error thrown from
89244  // `selectValueAccessor`. See https://github.com/angular/angular/issues/40521.
89245
89246
89247  if (dir.valueAccessor) {
89248    dir.valueAccessor.registerOnChange(noop);
89249    dir.valueAccessor.registerOnTouched(noop);
89250  }
89251
89252  cleanUpValidators(control, dir);
89253
89254  if (control) {
89255    dir._invokeOnDestroyCallbacks();
89256
89257    control._registerOnCollectionChange(() => {});
89258  }
89259}
89260
89261function registerOnValidatorChange(validators, onChange) {
89262  validators.forEach(validator => {
89263    if (validator.registerOnValidatorChange) validator.registerOnValidatorChange(onChange);
89264  });
89265}
89266/**
89267 * Sets up disabled change handler function on a given form control if ControlValueAccessor
89268 * associated with a given directive instance supports the `setDisabledState` call.
89269 *
89270 * @param control Form control where disabled change handler should be setup.
89271 * @param dir Corresponding directive instance associated with this control.
89272 */
89273
89274
89275function setUpDisabledChangeHandler(control, dir) {
89276  if (dir.valueAccessor.setDisabledState) {
89277    const onDisabledChange = isDisabled => {
89278      dir.valueAccessor.setDisabledState(isDisabled);
89279    };
89280
89281    control.registerOnDisabledChange(onDisabledChange); // Register a callback function to cleanup disabled change handler
89282    // from a control instance when a directive is destroyed.
89283
89284    dir._registerOnDestroy(() => {
89285      control._unregisterOnDisabledChange(onDisabledChange);
89286    });
89287  }
89288}
89289/**
89290 * Sets up sync and async directive validators on provided form control.
89291 * This function merges validators from the directive into the validators of the control.
89292 *
89293 * @param control Form control where directive validators should be setup.
89294 * @param dir Directive instance that contains validators to be setup.
89295 */
89296
89297
89298function setUpValidators(control, dir) {
89299  const validators = getControlValidators(control);
89300
89301  if (dir.validator !== null) {
89302    control.setValidators(mergeValidators(validators, dir.validator));
89303  } else if (typeof validators === 'function') {
89304    // If sync validators are represented by a single validator function, we force the
89305    // `Validators.compose` call to happen by executing the `setValidators` function with
89306    // an array that contains that function. We need this to avoid possible discrepancies in
89307    // validators behavior, so sync validators are always processed by the `Validators.compose`.
89308    // Note: we should consider moving this logic inside the `setValidators` function itself, so we
89309    // have consistent behavior on AbstractControl API level. The same applies to the async
89310    // validators logic below.
89311    control.setValidators([validators]);
89312  }
89313
89314  const asyncValidators = getControlAsyncValidators(control);
89315
89316  if (dir.asyncValidator !== null) {
89317    control.setAsyncValidators(mergeValidators(asyncValidators, dir.asyncValidator));
89318  } else if (typeof asyncValidators === 'function') {
89319    control.setAsyncValidators([asyncValidators]);
89320  } // Re-run validation when validator binding changes, e.g. minlength=3 -> minlength=4
89321
89322
89323  const onValidatorChange = () => control.updateValueAndValidity();
89324
89325  registerOnValidatorChange(dir._rawValidators, onValidatorChange);
89326  registerOnValidatorChange(dir._rawAsyncValidators, onValidatorChange);
89327}
89328/**
89329 * Cleans up sync and async directive validators on provided form control.
89330 * This function reverts the setup performed by the `setUpValidators` function, i.e.
89331 * removes directive-specific validators from a given control instance.
89332 *
89333 * @param control Form control from where directive validators should be removed.
89334 * @param dir Directive instance that contains validators to be removed.
89335 * @returns true if a control was updated as a result of this action.
89336 */
89337
89338
89339function cleanUpValidators(control, dir) {
89340  let isControlUpdated = false;
89341
89342  if (control !== null) {
89343    if (dir.validator !== null) {
89344      const validators = getControlValidators(control);
89345
89346      if (Array.isArray(validators) && validators.length > 0) {
89347        // Filter out directive validator function.
89348        const updatedValidators = validators.filter(validator => validator !== dir.validator);
89349
89350        if (updatedValidators.length !== validators.length) {
89351          isControlUpdated = true;
89352          control.setValidators(updatedValidators);
89353        }
89354      }
89355    }
89356
89357    if (dir.asyncValidator !== null) {
89358      const asyncValidators = getControlAsyncValidators(control);
89359
89360      if (Array.isArray(asyncValidators) && asyncValidators.length > 0) {
89361        // Filter out directive async validator function.
89362        const updatedAsyncValidators = asyncValidators.filter(asyncValidator => asyncValidator !== dir.asyncValidator);
89363
89364        if (updatedAsyncValidators.length !== asyncValidators.length) {
89365          isControlUpdated = true;
89366          control.setAsyncValidators(updatedAsyncValidators);
89367        }
89368      }
89369    }
89370  } // Clear onValidatorChange callbacks by providing a noop function.
89371
89372
89373  const noop = () => {};
89374
89375  registerOnValidatorChange(dir._rawValidators, noop);
89376  registerOnValidatorChange(dir._rawAsyncValidators, noop);
89377  return isControlUpdated;
89378}
89379
89380function setUpViewChangePipeline(control, dir) {
89381  dir.valueAccessor.registerOnChange(newValue => {
89382    control._pendingValue = newValue;
89383    control._pendingChange = true;
89384    control._pendingDirty = true;
89385    if (control.updateOn === 'change') updateControl(control, dir);
89386  });
89387}
89388
89389function setUpBlurPipeline(control, dir) {
89390  dir.valueAccessor.registerOnTouched(() => {
89391    control._pendingTouched = true;
89392    if (control.updateOn === 'blur' && control._pendingChange) updateControl(control, dir);
89393    if (control.updateOn !== 'submit') control.markAsTouched();
89394  });
89395}
89396
89397function updateControl(control, dir) {
89398  if (control._pendingDirty) control.markAsDirty();
89399  control.setValue(control._pendingValue, {
89400    emitModelToViewChange: false
89401  });
89402  dir.viewToModelUpdate(control._pendingValue);
89403  control._pendingChange = false;
89404}
89405
89406function setUpModelChangePipeline(control, dir) {
89407  const onChange = (newValue, emitModelEvent) => {
89408    // control -> view
89409    dir.valueAccessor.writeValue(newValue); // control -> ngModel
89410
89411    if (emitModelEvent) dir.viewToModelUpdate(newValue);
89412  };
89413
89414  control.registerOnChange(onChange); // Register a callback function to cleanup onChange handler
89415  // from a control instance when a directive is destroyed.
89416
89417  dir._registerOnDestroy(() => {
89418    control._unregisterOnChange(onChange);
89419  });
89420}
89421/**
89422 * Links a FormGroup or FormArray instance and corresponding Form directive by setting up validators
89423 * present in the view.
89424 *
89425 * @param control FormGroup or FormArray instance that should be linked.
89426 * @param dir Directive that provides view validators.
89427 */
89428
89429
89430function setUpFormContainer(control, dir) {
89431  if (control == null && (typeof ngDevMode === 'undefined' || ngDevMode)) _throwError(dir, 'Cannot find control with');
89432  setUpValidators(control, dir);
89433}
89434/**
89435 * Reverts the setup performed by the `setUpFormContainer` function.
89436 *
89437 * @param control FormGroup or FormArray instance that should be cleaned up.
89438 * @param dir Directive that provided view validators.
89439 * @returns true if a control was updated as a result of this action.
89440 */
89441
89442
89443function cleanUpFormContainer(control, dir) {
89444  return cleanUpValidators(control, dir);
89445}
89446
89447function _noControlError(dir) {
89448  return _throwError(dir, 'There is no FormControl instance attached to form control element with');
89449}
89450
89451function _throwError(dir, message) {
89452  const messageEnd = _describeControlLocation(dir);
89453
89454  throw new Error(`${message} ${messageEnd}`);
89455}
89456
89457function _describeControlLocation(dir) {
89458  const path = dir.path;
89459  if (path && path.length > 1) return `path: '${path.join(' -> ')}'`;
89460  if (path?.[0]) return `name: '${path}'`;
89461  return 'unspecified name attribute';
89462}
89463
89464function _throwInvalidValueAccessorError(dir) {
89465  const loc = _describeControlLocation(dir);
89466
89467  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1200
89468  /* RuntimeErrorCode.NG_VALUE_ACCESSOR_NOT_PROVIDED */
89469  , `Value accessor was not provided as an array for form control with ${loc}. ` + `Check that the \`NG_VALUE_ACCESSOR\` token is configured as a \`multi: true\` provider.`);
89470}
89471
89472function isPropertyUpdated(changes, viewModel) {
89473  if (!changes.hasOwnProperty('model')) return false;
89474  const change = changes['model'];
89475  if (change.isFirstChange()) return true;
89476  return !Object.is(viewModel, change.currentValue);
89477}
89478
89479function isBuiltInAccessor(valueAccessor) {
89480  // Check if a given value accessor is an instance of a class that directly extends
89481  // `BuiltInControlValueAccessor` one.
89482  return Object.getPrototypeOf(valueAccessor.constructor) === BuiltInControlValueAccessor;
89483}
89484
89485function syncPendingControls(form, directives) {
89486  form._syncPendingControls();
89487
89488  directives.forEach(dir => {
89489    const control = dir.control;
89490
89491    if (control.updateOn === 'submit' && control._pendingChange) {
89492      dir.viewToModelUpdate(control._pendingValue);
89493      control._pendingChange = false;
89494    }
89495  });
89496} // TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
89497
89498
89499function selectValueAccessor(dir, valueAccessors) {
89500  if (!valueAccessors) return null;
89501  if (!Array.isArray(valueAccessors) && (typeof ngDevMode === 'undefined' || ngDevMode)) _throwInvalidValueAccessorError(dir);
89502  let defaultAccessor = undefined;
89503  let builtinAccessor = undefined;
89504  let customAccessor = undefined;
89505  valueAccessors.forEach(v => {
89506    if (v.constructor === DefaultValueAccessor) {
89507      defaultAccessor = v;
89508    } else if (isBuiltInAccessor(v)) {
89509      if (builtinAccessor && (typeof ngDevMode === 'undefined' || ngDevMode)) _throwError(dir, 'More than one built-in value accessor matches form control with');
89510      builtinAccessor = v;
89511    } else {
89512      if (customAccessor && (typeof ngDevMode === 'undefined' || ngDevMode)) _throwError(dir, 'More than one custom value accessor matches form control with');
89513      customAccessor = v;
89514    }
89515  });
89516  if (customAccessor) return customAccessor;
89517  if (builtinAccessor) return builtinAccessor;
89518  if (defaultAccessor) return defaultAccessor;
89519
89520  if (typeof ngDevMode === 'undefined' || ngDevMode) {
89521    _throwError(dir, 'No valid value accessor for form control with');
89522  }
89523
89524  return null;
89525}
89526
89527function removeListItem$1(list, el) {
89528  const index = list.indexOf(el);
89529  if (index > -1) list.splice(index, 1);
89530} // TODO(kara): remove after deprecation period
89531
89532
89533function _ngModelWarning(name, type, instance, warningConfig) {
89534  if (warningConfig === 'never') return;
89535
89536  if ((warningConfig === null || warningConfig === 'once') && !type._ngModelWarningSentOnce || warningConfig === 'always' && !instance._ngModelWarningSent) {
89537    console.warn(ngModelWarning(name));
89538    type._ngModelWarningSentOnce = true;
89539    instance._ngModelWarningSent = true;
89540  }
89541}
89542/**
89543 * @license
89544 * Copyright Google LLC All Rights Reserved.
89545 *
89546 * Use of this source code is governed by an MIT-style license that can be
89547 * found in the LICENSE file at https://angular.io/license
89548 */
89549
89550
89551const formDirectiveProvider$1 = {
89552  provide: ControlContainer,
89553  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgForm)
89554};
89555
89556const resolvedPromise$1 = (() => Promise.resolve())();
89557/**
89558 * @description
89559 * Creates a top-level `FormGroup` instance and binds it to a form
89560 * to track aggregate form value and validation status.
89561 *
89562 * As soon as you import the `FormsModule`, this directive becomes active by default on
89563 * all `<form>` tags.  You don't need to add a special selector.
89564 *
89565 * You optionally export the directive into a local template variable using `ngForm` as the key
89566 * (ex: `#myForm="ngForm"`). This is optional, but useful.  Many properties from the underlying
89567 * `FormGroup` instance are duplicated on the directive itself, so a reference to it
89568 * gives you access to the aggregate value and validity status of the form, as well as
89569 * user interaction properties like `dirty` and `touched`.
89570 *
89571 * To register child controls with the form, use `NgModel` with a `name`
89572 * attribute. You may use `NgModelGroup` to create sub-groups within the form.
89573 *
89574 * If necessary, listen to the directive's `ngSubmit` event to be notified when the user has
89575 * triggered a form submission. The `ngSubmit` event emits the original form
89576 * submission event.
89577 *
89578 * In template driven forms, all `<form>` tags are automatically tagged as `NgForm`.
89579 * To import the `FormsModule` but skip its usage in some forms,
89580 * for example, to use native HTML5 validation, add the `ngNoForm` and the `<form>`
89581 * tags won't create an `NgForm` directive. In reactive forms, using `ngNoForm` is
89582 * unnecessary because the `<form>` tags are inert. In that case, you would
89583 * refrain from using the `formGroup` directive.
89584 *
89585 * @usageNotes
89586 *
89587 * ### Listening for form submission
89588 *
89589 * The following example shows how to capture the form values from the "ngSubmit" event.
89590 *
89591 * {@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
89592 *
89593 * ### Setting the update options
89594 *
89595 * The following example shows you how to change the "updateOn" option from its default using
89596 * ngFormOptions.
89597 *
89598 * ```html
89599 * <form [ngFormOptions]="{updateOn: 'blur'}">
89600 *    <input name="one" ngModel>  <!-- this ngModel will update on blur -->
89601 * </form>
89602 * ```
89603 *
89604 * ### Native DOM validation UI
89605 *
89606 * In order to prevent the native DOM form validation UI from interfer
89606ing with Angular's form
89607 * validation, Angular automatically adds the `novalidate` attribute on any `<form>` whenever
89608 * `FormModule` or `ReactiveFormModule` are imported into the application.
89609 * If you want to explicitly enable native DOM validation UI with Angular forms, you can add the
89610 * `ngNativeValidate` attribute to the `<form>` element:
89611 *
89612 * ```html
89613 * <form ngNativeValidate>
89614 *   ...
89615 * </form>
89616 * ```
89617 *
89618 * @ngModule FormsModule
89619 * @publicApi
89620 */
89621
89622
89623class NgForm extends ControlContainer {
89624  constructor(validators, asyncValidators) {
89625    super();
89626    /**
89627     * @description
89628     * Returns whether the form submission has been triggered.
89629     */
89630
89631    this.submitted = false;
89632    this._directives = new Set();
89633    /**
89634     * @description
89635     * Event emitter for the "ngSubmit" event
89636     */
89637
89638    this.ngSubmit = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
89639    this.form = new FormGroup({}, composeValidators(validators), composeAsyncValidators(asyncValidators));
89640  }
89641  /** @nodoc */
89642
89643
89644  ngAfterViewInit() {
89645    this._setUpdateStrategy();
89646  }
89647  /**
89648   * @description
89649   * The directive instance.
89650   */
89651
89652
89653  get formDirective() {
89654    return this;
89655  }
89656  /**
89657   * @description
89658   * The internal `FormGroup` instance.
89659   */
89660
89661
89662  get control() {
89663    return this.form;
89664  }
89665  /**
89666   * @description
89667   * Returns an array representing the path to this group. Because this directive
89668   * always lives at the top level of a form, it is always an empty array.
89669   */
89670
89671
89672  get path() {
89673    return [];
89674  }
89675  /**
89676   * @description
89677   * Returns a map of the controls in this group.
89678   */
89679
89680
89681  get controls() {
89682    return this.form.controls;
89683  }
89684  /**
89685   * @description
89686   * Method that sets up the control directive in this group, re-calculates its value
89687   * and validity, and adds the instance to the internal list of directives.
89688   *
89689   * @param dir The `NgModel` directive instance.
89690   */
89691
89692
89693  addControl(dir) {
89694    resolvedPromise$1.then(() => {
89695      const container = this._findContainer(dir.path);
89696
89697      dir.control = container.registerControl(dir.name, dir.control);
89698      setUpControl(dir.control, dir);
89699      dir.control.updateValueAndValidity({
89700        emitEvent: false
89701      });
89702
89703      this._directives.add(dir);
89704    });
89705  }
89706  /**
89707   * @description
89708   * Retrieves the `FormControl` instance from the provided `NgModel` directive.
89709   *
89710   * @param dir The `NgModel` directive instance.
89711   */
89712
89713
89714  getControl(dir) {
89715    return this.form.get(dir.path);
89716  }
89717  /**
89718   * @description
89719   * Removes the `NgModel` instance from the internal list of directives
89720   *
89721   * @param dir The `NgModel` directive instance.
89722   */
89723
89724
89725  removeControl(dir) {
89726    resolvedPromise$1.then(() => {
89727      const container = this._findContainer(dir.path);
89728
89729      if (container) {
89730        container.removeControl(dir.name);
89731      }
89732
89733      this._directives.delete(dir);
89734    });
89735  }
89736  /**
89737   * @description
89738   * Adds a new `NgModelGroup` directive instance to the form.
89739   *
89740   * @param dir The `NgModelGroup` directive instance.
89741   */
89742
89743
89744  addFormGroup(dir) {
89745    resolvedPromise$1.then(() => {
89746      const container = this._findContainer(dir.path);
89747
89748      const group = new FormGroup({});
89749      setUpFormContainer(group, dir);
89750      container.registerControl(dir.name, group);
89751      group.updateValueAndValidity({
89752        emitEvent: false
89753      });
89754    });
89755  }
89756  /**
89757   * @description
89758   * Removes the `NgModelGroup` directive instance from the form.
89759   *
89760   * @param dir The `NgModelGroup` directive instance.
89761   */
89762
89763
89764  removeFormGroup(dir) {
89765    resolvedPromise$1.then(() => {
89766      const container = this._findContainer(dir.path);
89767
89768      if (container) {
89769        container.removeControl(dir.name);
89770      }
89771    });
89772  }
89773  /**
89774   * @description
89775   * Retrieves the `FormGroup` for a provided `NgModelGroup` directive instance
89776   *
89777   * @param dir The `NgModelGroup` directive instance.
89778   */
89779
89780
89781  getFormGroup(dir) {
89782    return this.form.get(dir.path);
89783  }
89784  /**
89785   * Sets the new value for the provided `NgControl` directive.
89786   *
89787   * @param dir The `NgControl` directive instance.
89788   * @param value The new value for the directive's control.
89789   */
89790
89791
89792  updateModel(dir, value) {
89793    resolvedPromise$1.then(() => {
89794      const ctrl = this.form.get(dir.path);
89795      ctrl.setValue(value);
89796    });
89797  }
89798  /**
89799   * @description
89800   * Sets the value for this `FormGroup`.
89801   *
89802   * @param value The new value
89803   */
89804
89805
89806  setValue(value) {
89807    this.control.setValue(value);
89808  }
89809  /**
89810   * @description
89811   * Method called when the "submit" event is triggered on the form.
89812   * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload.
89813   *
89814   * @param $event The "submit" event object
89815   */
89816
89817
89818  onSubmit($event) {
89819    this.submitted = true;
89820    syncPendingControls(this.form, this._directives);
89821    this.ngSubmit.emit($event); // Forms with `method="dialog"` have some special behavior
89822    // that won't reload the page and that shouldn't be prevented.
89823
89824    return $event?.target?.method === 'dialog';
89825  }
89826  /**
89827   * @description
89828   * Method called when the "reset" event is triggered on the form.
89829   */
89830
89831
89832  onReset() {
89833    this.resetForm();
89834  }
89835  /**
89836   * @description
89837   * Resets the form to an initial value and resets its submitted status.
89838   *
89839   * @param value The new value for the form.
89840   */
89841
89842
89843  resetForm(value = undefined) {
89844    this.form.reset(value);
89845    this.submitted = false;
89846  }
89847
89848  _setUpdateStrategy() {
89849    if (this.options && this.options.updateOn != null) {
89850      this.form._updateOn = this.options.updateOn;
89851    }
89852  }
89853
89854  _findContainer(path) {
89855    path.pop();
89856    return path.length ? this.form.get(path) : this.form;
89857  }
89858
89859}
89860
89861NgForm.ɵfac = function NgForm_Factory(t) {
89862  return new (t || NgForm)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10));
89863};
89864
89865NgForm.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
89866  type: NgForm,
89867  selectors: [["form", 3, "ngNoForm", "", 3, "formGroup", ""], ["ng-form"], ["", "ngForm", ""]],
89868  hostBindings: function NgForm_HostBindings(rf, ctx) {
89869    if (rf & 1) {
89870      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("submit", function NgForm_submit_HostBindingHandler($event) {
89871        return ctx.onSubmit($event);
89872      })("reset", function NgForm_reset_HostBindingHandler() {
89873        return ctx.onReset();
89874      });
89875    }
89876  },
89877  inputs: {
89878    options: ["ngFormOptions", "options"]
89879  },
89880  outputs: {
89881    ngSubmit: "ngSubmit"
89882  },
89883  exportAs: ["ngForm"],
89884  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formDirectiveProvider$1]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
89885});
89886
89887(function () {
89888  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgForm, [{
89889    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
89890    args: [{
89891      selector: 'form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]',
89892      providers: [formDirectiveProvider$1],
89893      host: {
89894        '(submit)': 'onSubmit($event)',
89895        '(reset)': 'onReset()'
89896      },
89897      outputs: ['ngSubmit'],
89898      exportAs: 'ngForm'
89899    }]
89900  }], function () {
89901    return [{
89902      type: undefined,
89903      decorators: [{
89904        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
89905      }, {
89906        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
89907      }, {
89908        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
89909        args: [NG_VALIDATORS]
89910      }]
89911    }, {
89912      type: undefined,
89913      decorators: [{
89914        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
89915      }, {
89916        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
89917      }, {
89918        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
89919        args: [NG_ASYNC_VALIDATORS]
89920      }]
89921    }];
89922  }, {
89923    options: [{
89924      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
89925      args: ['ngFormOptions']
89926    }]
89927  });
89928})();
89929/**
89930 * @license
89931 * Copyright Google LLC All Rights Reserved.
89932 *
89933 * Use of this source code is governed by an MIT-style license that can be
89934 * found in the LICENSE file at https://angular.io/license
89935 */
89936
89937
89938function removeListItem(list, el) {
89939  const index = list.indexOf(el);
89940  if (index > -1) list.splice(index, 1);
89941}
89942/**
89943 * @license
89944 * Copyright Google LLC All Rights Reserved.
89945 *
89946 * Use of this source code is governed by an MIT-style license that can be
89947 * found in the LICENSE file at https://angular.io/license
89948 */
89949
89950
89951function isFormControlState(formState) {
89952  return typeof formState === 'object' && formState !== null && Object.keys(formState).length === 2 && 'value' in formState && 'disabled' in formState;
89953}
89954
89955const FormControl = class FormControl extends AbstractControl {
89956  constructor( // formState and defaultValue will only be null if T is nullable
89957  formState = null, validatorOrOpts, asyncValidator) {
89958    super(pickValidators(validatorOrOpts), pickAsyncValidators(asyncValidator, validatorOrOpts));
89959    /** @publicApi */
89960
89961    this.defaultValue = null;
89962    /** @internal */
89963
89964    this._onChange = [];
89965    /** @internal */
89966
89967    this._pendingChange = false;
89968
89969    this._applyFormState(formState);
89970
89971    this._setUpdateStrategy(validatorOrOpts);
89972
89973    this._initObservables();
89974
89975    this.updateValueAndValidity({
89976      onlySelf: true,
89977      // If `asyncValidator` is present, it will trigger control status change from `PENDING` to
89978      // `VALID` or `INVALID`.
89979      // The status should be broadcasted via the `statusChanges` observable, so we set
89980      // `emitEvent` to `true` to allow that during the control creation process.
89981      emitEvent: !!this.asyncValidator
89982    });
89983
89984    if (isOptionsObj(validatorOrOpts) && (validatorOrOpts.nonNullable || validatorOrOpts.initialValueIsDefault)) {
89985      if (isFormControlState(formState)) {
89986        this.defaultValue = formState.value;
89987      } else {
89988        this.defaultValue = formState;
89989      }
89990    }
89991  }
89992
89993  setValue(value, options = {}) {
89994    this.value = this._pendingValue = value;
89995
89996    if (this._onChange.length && options.emitModelToViewChange !== false) {
89997      this._onChange.forEach(changeFn => changeFn(this.value, options.emitViewToModelChange !== false));
89998    }
89999
90000    this.updateValueAndValidity(options);
90001  }
90002
90003  patchValue(value, options = {}) {
90004    this.setValue(value, options);
90005  }
90006
90007  reset(formState = this.defaultValue, options = {}) {
90008    this._applyFormState(formState);
90009
90010    this.markAsPristine(options);
90011    this.markAsUntouched(options);
90012    this.setValue(this.value, options);
90013    this._pendingChange = false;
90014  }
90015  /**  @internal */
90016
90017
90018  _updateValue() {}
90019  /**  @internal */
90020
90021
90022  _anyControls(condition) {
90023    return false;
90024  }
90025  /**  @internal */
90026
90027
90028  _allControlsDisabled() {
90029    return this.disabled;
90030  }
90031
90032  registerOnChange(fn) {
90033    this._onChange.push(fn);
90034  }
90035  /** @internal */
90036
90037
90038  _unregisterOnChange(fn) {
90039    removeListItem(this._onChange, fn);
90040  }
90041
90042  registerOnDisabledChange(fn) {
90043    this._onDisabledChange.push(fn);
90044  }
90045  /** @internal */
90046
90047
90048  _unregisterOnDisabledChange(fn) {
90049    removeListItem(this._onDisabledChange, fn);
90050  }
90051  /** @internal */
90052
90053
90054  _forEachChild(cb) {}
90055  /** @internal */
90056
90057
90058  _syncPendingControls() {
90059    if (this.updateOn === 'submit') {
90060      if (this._pendingDirty) this.markAsDirty();
90061      if (this._pendingTouched) this.markAsTouched();
90062
90063      if (this._pendingChange) {
90064        this.setValue(this._pendingValue, {
90065          onlySelf: true,
90066          emitModelToViewChange: false
90067        });
90068        return true;
90069      }
90070    }
90071
90072    return false;
90073  }
90074
90075  _applyFormState(formState) {
90076    if (isFormControlState(formState)) {
90077      this.value = this._pendingValue = formState.value;
90078      formState.disabled ? this.disable({
90079        onlySelf: true,
90080        emitEvent: false
90081      }) : this.enable({
90082        onlySelf: true,
90083        emitEvent: false
90084      });
90085    } else {
90086      this.value = this._pendingValue = formState;
90087    }
90088  }
90089
90090};
90091const UntypedFormControl = FormControl;
90092
90093const isFormControl = control => control instanceof FormControl;
90094/**
90095 * @license
90096 * Copyright Google LLC All Rights Reserved.
90097 *
90098 * Use of this source code is governed by an MIT-style license that can be
90099 * found in the LICENSE file at https://angular.io/license
90100 */
90101
90102/**
90103 * @description
90104 * A base class for code shared between the `NgModelGroup` and `FormGroupName` directives.
90105 *
90106 * @publicApi
90107 */
90108
90109
90110class AbstractFormGroupDirective extends ControlContainer {
90111  /** @nodoc */
90112  ngOnInit() {
90113    this._checkParentType(); // Register the group with its parent group.
90114
90115
90116    this.formDirective.addFormGroup(this);
90117  }
90118  /** @nodoc */
90119
90120
90121  ngOnDestroy() {
90122    if (this.formDirective) {
90123      // Remove the group from its parent group.
90124      this.formDirective.removeFormGroup(this);
90125    }
90126  }
90127  /**
90128   * @description
90129   * The `FormGroup` bound to this directive.
90130   */
90131
90132
90133  get control() {
90134    return this.formDirective.getFormGroup(this);
90135  }
90136  /**
90137   * @description
90138   * The path to this group from the top-level directive.
90139   */
90140
90141
90142  get path() {
90143    return controlPath(this.name == null ? this.name : this.name.toString(), this._parent);
90144  }
90145  /**
90146   * @description
90147   * The top-level directive for this group if present, otherwise null.
90148   */
90149
90150
90151  get formDirective() {
90152    return this._parent ? this._parent.formDirective : null;
90153  }
90154  /** @internal */
90155
90156
90157  _checkParentType() {}
90158
90159}
90160
90161AbstractFormGroupDirective.ɵfac = /* @__PURE__ */function () {
90162  let ɵAbstractFormGroupDirective_BaseFactory;
90163  return function AbstractFormGroupDirective_Factory(t) {
90164    return (ɵAbstractFormGroupDirective_BaseFactory || (ɵAbstractFormGroupDirective_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](AbstractFormGroupDirective)))(t || AbstractFormGroupDirective);
90165  };
90166}();
90167
90168AbstractFormGroupDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
90169  type: AbstractFormGroupDirective,
90170  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
90171});
90172
90173(function () {
90174  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AbstractFormGroupDirective, [{
90175    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive
90176  }], null, null);
90177})();
90178/**
90179 * @license
90180 * Copyright Google LLC All Rights Reserved.
90181 *
90182 * Use of this source code is governed by an MIT-style license that can be
90183 * found in the LICENSE file at https://angular.io/license
90184 */
90185
90186
90187function modelParentException() {
90188  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1350
90189  /* RuntimeErrorCode.NGMODEL_IN_FORM_GROUP */
90190  , `
90191    ngModel cannot be used to register form controls with a parent formGroup directive.  Try using
90192    formGroup's partner directive "formControlName" instead.  Example:
90193
90194    ${formControlNameExample}
90195
90196    Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions:
90197
90198    Example:
90199
90200    ${ngModelWithFormGroupExample}`);
90201}
90202
90203function formGroupNameException() {
90204  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1351
90205  /* RuntimeErrorCode.NGMODEL_IN_FORM_GROUP_NAME */
90206  , `
90207    ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive.
90208
90209    Option 1: Use formControlName instead of ngModel (reactive strategy):
90210
90211    ${formGroupNameExample}
90212
90213    Option 2:  Update ngModel's parent be ngModelGroup (template-driven strategy):
90214
90215    ${ngModelGroupExample}`);
90216}
90217
90218function missingNameException() {
90219  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1352
90220  /* RuntimeErrorCode.NGMODEL_WITHOUT_NAME */
90221  , `If ngModel is used within a form tag, either the name attribute must be set or the form
90222    control must be defined as 'standalone' in ngModelOptions.
90223
90224    Example 1: <input [(ngModel)]="person.firstName" name="first">
90225    Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">`);
90226}
90227
90228function modelGroupParentException() {
90229  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1353
90230  /* RuntimeErrorCode.NGMODELGROUP_IN_FORM_GROUP */
90231  , `
90232    ngModelGroup cannot be used with a parent formGroup directive.
90233
90234    Option 1: Use formGroupName instead of ngModelGroup (reactive strategy):
90235
90236    ${formGroupNameExample}
90237
90238    Option 2:  Use a regular form tag instead of the formGroup directive (template-driven strategy):
90239
90240    ${ngModelGroupExample}`);
90241}
90242/**
90243 * @license
90244 * Copyright Google LLC All Rights Reserved.
90245 *
90246 * Use of this source code is governed by an MIT-style license that can be
90247 * found in the LICENSE file at https://angular.io/license
90248 */
90249
90250
90251const modelGroupProvider = {
90252  provide: ControlContainer,
90253  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgModelGroup)
90254};
90255/**
90256 * @description
90257 * Creates and binds a `FormGroup` instance to a DOM element.
90258 *
90259 * This directive can only be used as a child of `NgForm` (within `<form>` tags).
90260 *
90261 * Use this directive to validate a sub-group of your form separately from the
90262 * rest of your form, or if some values in your domain model make more sense
90263 * to consume together in a nested object.
90264 *
90265 * Provide a name for the sub-group and it will become the key
90266 * for the sub-group in the form's full value. If you need direct access, export the directive into
90267 * a local template variable using `ngModelGroup` (ex: `#myGroup="ngModelGroup"`).
90268 *
90269 * @usageNotes
90270 *
90271 * ### Consuming controls in a grouping
90272 *
90273 * The following example shows you how to combine controls together in a sub-group
90274 * of the form.
90275 *
90276 * {@example forms/ts/ngModelGroup/ng_model_group_example.ts region='Component'}
90277 *
90278 * @ngModule FormsModule
90279 * @publicApi
90280 */
90281
90282class NgModelGroup extends AbstractFormGroupDirective {
90283  constructor(parent, validators, asyncValidators) {
90284    super();
90285    this._parent = parent;
90286
90287    this._setValidators(validators);
90288
90289    this._setAsyncValidators(asyncValidators);
90290  }
90291  /** @internal */
90292
90293
90294  _checkParentType() {
90295    if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
90296      throw modelGroupParentException();
90297    }
90298  }
90299
90300}
90301
90302NgModelGroup.ɵfac = function NgModelGroup_Factory(t) {
90303  return new (t || NgModelGroup)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 5), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10));
90304};
90305
90306NgModelGroup.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
90307  type: NgModelGroup,
90308  selectors: [["", "ngModelGroup", ""]],
90309  inputs: {
90310    name: ["ngModelGroup", "name"]
90311  },
90312  exportAs: ["ngModelGroup"],
90313  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([modelGroupProvider]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
90314});
90315
90316(function () {
90317  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgModelGroup, [{
90318    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
90319    args: [{
90320      selector: '[ngModelGroup]',
90321      providers: [modelGroupProvider],
90322      exportAs: 'ngModelGroup'
90323    }]
90324  }], function () {
90325    return [{
90326      type: ControlContainer,
90327      decorators: [{
90328        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
90329      }, {
90330        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf
90331      }]
90332    }, {
90333      type: undefined,
90334      decorators: [{
90335        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
90336      }, {
90337        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
90338      }, {
90339        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
90340        args: [NG_VALIDATORS]
90341      }]
90342    }, {
90343      type: undefined,
90344      decorators: [{
90345        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
90346      }, {
90347        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
90348      }, {
90349        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
90350        args: [NG_ASYNC_VALIDATORS]
90351      }]
90352    }];
90353  }, {
90354    name: [{
90355      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
90356      args: ['ngModelGroup']
90357    }]
90358  });
90359})();
90360/**
90361 * @license
90362 * Copyright Google LLC All Rights Reserved.
90363 *
90364 * Use of this source code is governed by an MIT-style license that can be
90365 * found in the LICENSE file at https://angular.io/license
90366 */
90367
90368
90369const formControlBinding$1 = {
90370  provide: NgControl,
90371  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgModel)
90372};
90373/**
90374 * `ngModel` forces an additional change detection run when its inputs change:
90375 * E.g.:
90376 * ```
90377 * <div>{{myModel.valid}}</div>
90378 * <input [(ngModel)]="myValue" #myModel="ngModel">
90379 * ```
90380 * I.e. `ngModel` can export itself on the element and then be used in the template.
90381 * Normally, this would result in expressions before the `input` that use the exported directive
90382 * to have an old value as they have been
90383 * dirty checked before. As this is a very common case for `ngModel`, we added this second change
90384 * detection run.
90385 *
90386 * Notes:
90387 * - this is just one extra run no matter how many `ngModel`s have been changed.
90388 * - this is a general problem when using `exportAs` for directives!
90389 */
90390
90391const resolvedPromise = (() => Promise.resolve())();
90392/**
90393 * @description
90394 * Creates a `FormControl` instance from a domain model and binds it
90395 * to a form control element.
90396 *
90397 * The `FormControl` instance tracks the value, user interaction, and
90398 * validation status of the control and keeps the view synced with the model. If used
90399 * within a parent form, the directive also registers itself with the form as a child
90400 * control.
90401 *
90402 * This directive is used by itself or as part of a larger form. Use the
90403 * `ngModel` selector to activate it.
90404 *
90405 * It accepts a domain model as an optional `Input`. If you have a one-way binding
90406 * to `ngModel` with `[]` syntax, changing the domain model's value in the component
90407 * class sets the value in the view. If you have a two-way binding with `[()]` syntax
90408 * (also known as 'banana-in-a-box syntax'), the value in the UI always syncs back to
90409 * the domain model in your class.
90410 *
90411 * To inspect the properties of the associated `FormControl` (like the validity state),
90412 * export the directive into a local template variable using `ngModel` as the key (ex:
90413 * `#myVar="ngModel"`). You can then access the control using the directive's `control` property.
90414 * However, the most commonly used properties (like `valid` and `dirty`) also exist on the control
90415 * for direct access. See a full list of properties directly available in
90416 * `AbstractControlDirective`.
90417 *
90418 * @see `RadioControlValueAccessor`
90419 * @see `SelectControlValueAccessor`
90420 *
90421 * @usageNotes
90422 *
90423 * ### Using ngModel on a standalone control
90424 *
90425 * The following examples show a simple standalone control using `ngModel`:
90426 *
90427 * {@example forms/ts/simpleNgModel/simple_ng_model_example.ts region='Component'}
90428 *
90429 * When using the `ngModel` within `<form>` tags, you'll also need to supply a `name` attribute
90430 * so that the control can be registered with the parent form under that name.
90431 *
90432 * In the context of a parent form, it's often unnecessary to include one-way or two-way binding,
90433 * as the parent form syncs the value for you. You access its properties by exporting it into a
90434 * local template variable using `ngForm` such as (`#f="ngForm"`). Use the variable where
90435 * needed on form submission.
90436 *
90437 * If you do need to populate initial values into your form, using a one-way binding for
90438 * `ngModel` tends to be sufficient as long as you use the exported form's value rather
90439 * than the domain model's value on submit.
90440 *
90441 * ### Using ngModel within a form
90442 *
90443 * The following example shows controls using `ngModel` within a form:
90444 *
90445 * {@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
90446 *
90447 * ### Using a standalone ngModel within a group
90448 *
90449 * The following example shows you how to use a standalone ngModel control
90450 * within a form. This controls the display of the form, but doesn't contain form data.
90451 *
90452 * ```html
90453 * <form>
90454 *   <input name="login" ngModel placeholder="Login">
90455 *   <input type="checkbox" ngModel [ngModelOptions]="{standalone: true}"> Show more options?
90456 * </form>
90457 * <!-- form value: {login: ''} -->
90458 * ```
90459 *
90460 * ### Setting the ngModel `name` attribute through options
90461 *
90462 * The following example shows you an alternate way to set the name attribute. Here,
90463 * an attribute identified as name is used within a custom form control component. To still be able
90464 * to specify the NgModel's name, you must specify it using the `ngModelOptions` input instead.
90465 *
90466 * ```html
90467 * <form>
90468 *   <my-custom-form-control name="Nancy" ngModel [ngModelOptions]="{name: 'user'}">
90469 *   </my-custom-form-control>
90470 * </form>
90471 * <!-- form value: {user: ''} -->
90472 * ```
90473 *
90474 * @ngModule FormsModule
90475 * @publicApi
90476 */
90477
90478
90479class NgModel extends NgControl {
90480  constructor(parent, validators, asyncValidators, valueAccessors, _changeDetectorRef) {
90481    super();
90482    this._changeDetectorRef = _changeDetectorRef;
90483    this.control = new FormControl();
90484    /** @internal */
90485
90486    this._registered = false;
90487    /**
90488     * @description
90489     * Event emitter for producing the `ngModelChange` event after
90490     * the view model updates.
90491     */
90492
90493    this.update = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
90494    this._parent = parent;
90495
90496    this._setValidators(validators);
90497
90498    this._setAsyncValidators(asyncValidators);
90499
90500    this.valueAccessor = selectValueAccessor(this, valueAccessors);
90501  }
90502  /** @nodoc */
90503
90504
90505  ngOnChanges(changes) {
90506    this._checkForErrors();
90507
90508    if (!this._registered || 'name' in changes) {
90509      if (this._registered) {
90510        this._checkName();
90511
90512        if (this.formDirective) {
90513          // We can't call `formDirective.removeControl(this)`, because the `name` has already been
90514          // changed. We also can't reset the name temporarily since the logic in `removeControl`
90515          // is inside a promise and it won't run immediately. We work around it by giving it an
90516          // object with the same shape instead.
90517          const oldName = changes['name'].previousValue;
90518          this.formDirective.removeControl({
90519            name: oldName,
90520            path: this._getPath(oldName)
90521          });
90522        }
90523      }
90524
90525      this._setUpControl();
90526    }
90527
90528    if ('isDisabled' in changes) {
90529      this._updateDisabled(changes);
90530    }
90531
90532    if (isPropertyUpdated(changes, this.viewModel)) {
90533      this._updateValue(this.model);
90534
90535      this.viewModel = this.model;
90536    }
90537  }
90538  /** @nodoc */
90539
90540
90541  ngOnDestroy() {
90542    this.formDirective && this.formDirective.removeControl(this);
90543  }
90544  /**
90545   * @description
90546   * Returns an array that represents the path from the top-level form to this control.
90547   * Each index is the string name of the control on that level.
90548   */
90549
90550
90551  get path() {
90552    return this._getPath(this.name);
90553  }
90554  /**
90555   * @description
90556   * The top-level directive for this control if present, otherwise null.
90557   */
90558
90559
90560  get formDirective() {
90561    return this._parent ? this._parent.formDirective : null;
90562  }
90563  /**
90564   * @description
90565   * Sets the new value for the view model and emits an `ngModelChange` event.
90566   *
90567   * @param newValue The new value emitted by `ngModelChange`.
90568   */
90569
90570
90571  viewToModelUpdate(newValue) {
90572    this.viewModel = newValue;
90573    this.update.emit(newValue);
90574  }
90575
90576  _setUpControl() {
90577    this._setUpdateStrategy();
90578
90579    this._isStandalone() ? this._setUpStandalone() : this.formDirective.addControl(this);
90580    this._registered = true;
90581  }
90582
90583  _setUpdateStrategy() {
90584    if (this.options && this.options.updateOn != null) {
90585      this.control._updateOn = this.options.updateOn;
90586    }
90587  }
90588
90589  _isStandalone() {
90590    return !this._parent || !!(this.options && this.options.standalone);
90591  }
90592
90593  _setUpStandalone() {
90594    setUpControl(this.control, this);
90595    this.control.updateValueAndValidity({
90596      emitEvent: false
90597    });
90598  }
90599
90600  _checkForErrors() {
90601    if (!this._isStandalone()) {
90602      this._checkParentType();
90603    }
90604
90605    this._checkName();
90606  }
90607
90608  _checkParentType() {
90609    if (typeof ngDevMode === 'undefined' || ngDevMode) {
90610      if (!(this._parent instanceof NgModelGroup) && this._parent instanceof AbstractFormGroupDirective) {
90611        throw formGroupNameException();
90612      } else if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
90613        throw modelParentException();
90614      }
90615    }
90616  }
90617
90618  _checkName() {
90619    if (this.options && this.options.name) this.name = this.options.name;
90620
90621    if (!this._isStandalone() && !this.name && (typeof ngDevMode === 'undefined' || ngDevMode)) {
90622      throw missingNameException();
90623    }
90624  }
90625
90626  _updateValue(value) {
90627    resolvedPromise.then(() => {
90628      this.control.setValue(value, {
90629        emitViewToModelChange: false
90630      });
90631      this._changeDetectorRef?.markForCheck();
90632    });
90633  }
90634
90635  _updateDisabled(changes) {
90636    const disabledValue = changes['isDisabled'].currentValue; // checking for 0 to avoid breaking change
90637
90638    const isDisabled = disabledValue !== 0 && (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵcoerceToBoolean"])(disabledValue);
90639    resolvedPromise.then(() => {
90640      if (isDisabled && !this.control.disabled) {
90641        this.control.disable();
90642      } else if (!isDisabled && this.control.disabled) {
90643        this.control.enable();
90644      }
90645
90646      this._changeDetectorRef?.markForCheck();
90647    });
90648  }
90649
90650  _getPath(controlName) {
90651    return this._parent ? controlPath(controlName, this._parent) : [controlName];
90652  }
90653
90654}
90655
90656NgModel.ɵfac = function NgModel_Factory(t) {
90657  return new (t || NgModel)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 9), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALUE_ACCESSOR, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef, 8));
90658};
90659
90660NgModel.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
90661  type: NgModel,
90662  selectors: [["", "ngModel", "", 3, "formControlName", "", 3, "formControl", ""]],
90663  inputs: {
90664    name: "name",
90665    isDisabled: ["disabled", "isDisabled"],
90666    model: ["ngModel", "model"],
90667    options: ["ngModelOptions", "options"]
90668  },
90669  outputs: {
90670    update: "ngModelChange"
90671  },
90672  exportAs: ["ngModel"],
90673  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formControlBinding$1]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
90674});
90675
90676(function () {
90677  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgModel, [{
90678    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
90679    args: [{
90680      selector: '[ngModel]:not([formControlName]):not([formControl])',
90681      providers: [formControlBinding$1],
90682      exportAs: 'ngModel'
90683    }]
90684  }], function () {
90685    return [{
90686      type: ControlContainer,
90687      decorators: [{
90688        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
90689      }, {
90690        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
90691      }]
90692    }, {
90693      type: undefined,
90694      decorators: [{
90695        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
90696      }, {
90697        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
90698      }, {
90699        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
90700        args: [NG_VALIDATORS]
90701      }]
90702    }, {
90703      type: undefined,
90704      decorators: [{
90705        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
90706      }, {
90707        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
90708      }, {
90709        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
90710        args: [NG_ASYNC_VALIDATORS]
90711      }]
90712    }, {
90713      type: undefined,
90714      decorators: [{
90715        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
90716      }, {
90717        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
90718      }, {
90719        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
90720        args: [NG_VALUE_ACCESSOR]
90721      }]
90722    }, {
90723      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef,
90724      decorators: [{
90725        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
90726      }, {
90727        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
90728        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef]
90729      }]
90730    }];
90731  }, {
90732    name: [{
90733      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
90734    }],
90735    isDisabled: [{
90736      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
90737      args: ['disabled']
90738    }],
90739    model: [{
90740      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
90741      args: ['ngModel']
90742    }],
90743    options: [{
90744      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
90745      args: ['ngModelOptions']
90746    }],
90747    update: [{
90748      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
90749      args: ['ngModelChange']
90750    }]
90751  });
90752})();
90753/**
90754 * @license
90755 * Copyright Google LLC All Rights Reserved.
90756 *
90757 * Use of this source code is governed by an MIT-style license that can be
90758 * found in the LICENSE file at https://angular.io/license
90759 */
90760
90761/**
90762 * @description
90763 *
90764 * Adds `novalidate` attribute to all forms by default.
90765 *
90766 * `novalidate` is used to disable browser's native form validation.
90767 *
90768 * If you want to use native validation with Angular forms, just add `ngNativeValidate` attribute:
90769 *
90770 * ```
90771 * <form ngNativeValidate></form>
90772 * ```
90773 *
90774 * @publicApi
90775 * @ngModule ReactiveFormsModule
90776 * @ngModule FormsModule
90777 */
90778
90779
90780class ɵNgNoValidate {}
90781
90782ɵNgNoValidate.ɵfac = function ɵNgNoValidate_Factory(t) {
90783  return new (t || ɵNgNoValidate)();
90784};
90785
90786ɵNgNoValidate.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
90787  type: ɵNgNoValidate,
90788  selectors: [["form", 3, "ngNoForm", "", 3, "ngNativeValidate", ""]],
90789  hostAttrs: ["novalidate", ""]
90790});
90791
90792(function () {
90793  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ɵNgNoValidate, [{
90794    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
90795    args: [{
90796      selector: 'form:not([ngNoForm]):not([ngNativeValidate])',
90797      host: {
90798        'novalidate': ''
90799      }
90800    }]
90801  }], null, null);
90802})();
90803/**
90804 * @license
90805 * Copyright Google LLC All Rights Reserved.
90806 *
90807 * Use of this source code is governed by an MIT-style license that can be
90808 * found in the LICENSE file at https://angular.io/license
90809 */
90810
90811
90812const NUMBER_VALUE_ACCESSOR = {
90813  provide: NG_VALUE_ACCESSOR,
90814  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NumberValueAccessor),
90815  multi: true
90816};
90817/**
90818 * @description
90819 * The `ControlValueAccessor` for writing a number value and listening to number input changes.
90820 * The value accessor is used by the `FormControlDirective`, `FormControlName`, and `NgModel`
90821 * directives.
90822 *
90823 * @usageNotes
90824 *
90825 * ### Using a number input with a reactive form.
90826 *
90827 * The following example shows how to use a number input with a reactive form.
90828 *
90829 * ```ts
90830 * const totalCountControl = new FormControl();
90831 * ```
90832 *
90833 * ```
90834 * <input type="number" [formControl]="totalCountControl">
90835 * ```
90836 *
90837 * @ngModule ReactiveFormsModule
90838 * @ngModule FormsModule
90839 * @publicApi
90840 */
90841
90842class NumberValueAccessor extends BuiltInControlValueAccessor {
90843  /**
90844   * Sets the "value" property on the input element.
90845   * @nodoc
90846   */
90847  writeValue(value) {
90848    // The value needs to be normalized for IE9, otherwise it is set to 'null' when null
90849    const normalizedValue = value == null ? '' : value;
90850    this.setProperty('value', normalizedValue);
90851  }
90852  /**
90853   * Registers a function called when the control value changes.
90854   * @nodoc
90855   */
90856
90857
90858  registerOnChange(fn) {
90859    this.onChange = value => {
90860      fn(value == '' ? null : parseFloat(value));
90861    };
90862  }
90863
90864}
90865
90866NumberValueAccessor.ɵfac = /* @__PURE__ */function () {
90867  let ɵNumberValueAccessor_BaseFactory;
90868  return function NumberValueAccessor_Factory(t) {
90869    return (ɵNumberValueAccessor_BaseFactory || (ɵNumberValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NumberValueAccessor)))(t || NumberValueAccessor);
90870  };
90871}();
90872
90873NumberValueAccessor.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
90874  type: NumberValueAccessor,
90875  selectors: [["input", "type", "number", "formControlName", ""], ["input", "type", "number", "formControl", ""], ["input", "type", "number", "ngModel", ""]],
90876  hostBindings: function NumberValueAccessor_HostBindings(rf, ctx) {
90877    if (rf & 1) {
90878      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("input", function NumberValueAccessor_input_HostBindingHandler($event) {
90879        return ctx.onChange($event.target.value);
90880      })("blur", function NumberValueAccessor_blur_HostBindingHandler() {
90881        return ctx.onTouched();
90882      });
90883    }
90884  },
90885  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([NUMBER_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
90886});
90887
90888(function () {
90889  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NumberValueAccessor, [{
90890    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
90891    args: [{
90892      selector: 'input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]',
90893      host: {
90894        '(input)': 'onChange($event.target.value)',
90895        '(blur)': 'onTouched()'
90896      },
90897      providers: [NUMBER_VALUE_ACCESSOR]
90898    }]
90899  }], null, null);
90900})();
90901/**
90902 * @license
90903 * Copyright Google LLC All Rights Reserved.
90904 *
90905 * Use of this source code is governed by an MIT-style license that can be
90906 * found in the LICENSE file at https://angular.io/license
90907 */
90908
90909
90910const RADIO_VALUE_ACCESSOR = {
90911  provide: NG_VALUE_ACCESSOR,
90912  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => RadioControlValueAccessor),
90913  multi: true
90914};
90915
90916function throwNameError() {
90917  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1202
90918  /* RuntimeErrorCode.NAME_AND_FORM_CONTROL_NAME_MUST_MATCH */
90919  , `
90920      If you define both a name and a formControlName attribute on your radio button, their values
90921      must match. Ex: <input type="radio" formControlName="food" name="food">
90922    `);
90923}
90924/**
90925 * Internal-only NgModule that works as a host for the `RadioControlRegistry` tree-shakable
90926 * provider. Note: the `InternalFormsSharedModule` can not be used here directly, since it's
90927 * declared *after* the `RadioControlRegistry` class and the `providedIn` doesn't support
90928 * `forwardRef` logic.
90929 */
90930
90931
90932class RadioControlRegistryModule {}
90933
90934RadioControlRegistryModule.ɵfac = function RadioControlRegistryModule_Factory(t) {
90935  return new (t || RadioControlRegistryModule)();
90936};
90937
90938RadioControlRegistryModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
90939  type: RadioControlRegistryModule
90940});
90941RadioControlRegistryModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
90942
90943(function () {
90944  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RadioControlRegistryModule, [{
90945    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule
90946  }], null, null);
90947})();
90948/**
90949 * @description
90950 * Class used by Angular to track radio buttons. For internal use only.
90951 */
90952
90953
90954class RadioControlRegistry {
90955  constructor() {
90956    this._accessors = [];
90957  }
90958  /**
90959   * @description
90960   * Adds a control to the internal registry. For internal use only.
90961   */
90962
90963
90964  add(control, accessor) {
90965    this._accessors.push([control, accessor]);
90966  }
90967  /**
90968   * @description
90969   * Removes a control from the internal registry. For internal use only.
90970   */
90971
90972
90973  remove(accessor) {
90974    for (let i = this._accessors.length - 1; i >= 0; --i) {
90975      if (this._accessors[i][1] === accessor) {
90976        this._accessors.splice(i, 1);
90977
90978        return;
90979      }
90980    }
90981  }
90982  /**
90983   * @description
90984   * Selects a radio button. For internal use only.
90985   */
90986
90987
90988  select(accessor) {
90989    this._accessors.forEach(c => {
90990      if (this._isSameGroup(c, accessor) && c[1] !== accessor) {
90991        c[1].fireUncheck(accessor.value);
90992      }
90993    });
90994  }
90995
90996  _isSameGroup(controlPair, accessor) {
90997    if (!controlPair[0].control) return false;
90998    return controlPair[0]._parent === accessor._control._parent && controlPair[1].name === accessor.name;
90999  }
91000
91001}
91002
91003RadioControlRegistry.ɵfac = function RadioControlRegistry_Factory(t) {
91004  return new (t || RadioControlRegistry)();
91005};
91006
91007RadioControlRegistry.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
91008  token: RadioControlRegistry,
91009  factory: RadioControlRegistry.ɵfac,
91010  providedIn: RadioControlRegistryModule
91011});
91012
91013(function () {
91014  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RadioControlRegistry, [{
91015    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
91016    args: [{
91017      providedIn: RadioControlRegistryModule
91018    }]
91019  }], null, null);
91020})();
91021/**
91022 * @description
91023 * The `ControlValueAccessor` for writing radio control values and listening to radio control
91024 * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and
91025 * `NgModel` directives.
91026 *
91027 * @usageNotes
91028 *
91029 * ### Using radio buttons with reactive form directives
91030 *
91031 * The follow example shows how to use radio buttons in a reactive form. When using radio buttons in
91032 * a reactive form, radio buttons in the same group should have the same `formControlName`.
91033 * Providing a `name` attribute is optional.
91034 *
91035 * {@example forms/ts/reactiveRadioButtons/reactive_radio_button_example.ts region='Reactive'}
91036 *
91037 * @ngModule ReactiveFormsModule
91038 * @ngModule FormsModule
91039 * @publicApi
91040 */
91041
91042
91043class RadioControlValueAccessor extends BuiltInControlValueAccessor {
91044  constructor(renderer, elementRef, _registry, _injector) {
91045    super(renderer, elementRef);
91046    this._registry = _registry;
91047    this._injector = _injector;
91048    /**
91049     * The registered callback function called when a change event occurs on the input element.
91050     * Note: we declare `onChange` here (also used as host listener) as a function with no arguments
91051     * to override the `onChange` function (which expects 1 argument) in the parent
91052     * `BaseControlValueAccessor` class.
91053     * @nodoc
91054     */
91055
91056    this.onChange = () => {};
91057  }
91058  /** @nodoc */
91059
91060
91061  ngOnInit() {
91062    this._control = this._injector.get(NgControl);
91063
91064    this._checkName();
91065
91066    this._registry.add(this._control, this);
91067  }
91068  /** @nodoc */
91069
91070
91071  ngOnDestroy() {
91072    this._registry.remove(this);
91073  }
91074  /**
91075   * Sets the "checked" property value on the radio input element.
91076   * @nodoc
91077   */
91078
91079
91080  writeValue(value) {
91081    this._state = value === this.value;
91082    this.setProperty('checked', this._state);
91083  }
91084  /**
91085   * Registers a function called when the control value changes.
91086   * @nodoc
91087   */
91088
91089
91090  registerOnChange(fn) {
91091    this._fn = fn;
91092
91093    this.onChange = () => {
91094      fn(this.value);
91095
91096      this._registry.select(this);
91097    };
91098  }
91099  /**
91100   * Sets the "value" on the radio input element and unchecks it.
91101   *
91102   * @param value
91103   */
91104
91105
91106  fireUncheck(value) {
91107    this.writeValue(value);
91108  }
91109
91110  _checkName() {
91111    if (this.name && this.formControlName && this.name !== this.formControlName && (typeof ngDevMode === 'undefined' || ngDevMode)) {
91112      throwNameError();
91113    }
91114
91115    if (!this.name && this.formControlName) this.name = this.formControlName;
91116  }
91117
91118}
91119
91120RadioControlValueAccessor.ɵfac = function RadioControlValueAccessor_Factory(t) {
91121  return new (t || RadioControlValueAccessor)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](RadioControlRegistry), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector));
91122};
91123
91124RadioControlValueAccessor.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
91125  type: RadioControlValueAccessor,
91126  selectors: [["input", "type", "radio", "formControlName", ""], ["input", "type", "radio", "formControl", ""], ["input", "type", "radio", "ngModel", ""]],
91127  hostBindings: function RadioControlValueAccessor_HostBindings(rf, ctx) {
91128    if (rf & 1) {
91129      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function RadioControlValueAccessor_change_HostBindingHandler() {
91130        return ctx.onChange();
91131      })("blur", function RadioControlValueAccessor_blur_HostBindingHandler() {
91132        return ctx.onTouched();
91133      });
91134    }
91135  },
91136  inputs: {
91137    name: "name",
91138    formControlName: "formControlName",
91139    value: "value"
91140  },
91141  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([RADIO_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
91142});
91143
91144(function () {
91145  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RadioControlValueAccessor, [{
91146    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
91147    args: [{
91148      selector: 'input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]',
91149      host: {
91150        '(change)': 'onChange()',
91151        '(blur)': 'onTouched()'
91152      },
91153      providers: [RADIO_VALUE_ACCESSOR]
91154    }]
91155  }], function () {
91156    return [{
91157      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
91158    }, {
91159      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
91160    }, {
91161      type: RadioControlRegistry
91162    }, {
91163      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector
91164    }];
91165  }, {
91166    name: [{
91167      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
91168    }],
91169    formControlName: [{
91170      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
91171    }],
91172    value: [{
91173      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
91174    }]
91175  });
91176})();
91177/**
91178 * @license
91179 * Copyright Google LLC All Rights Reserved.
91180 *
91181 * Use of this source code is governed by an MIT-style license that can be
91182 * found in the LICENSE file at https://angular.io/license
91183 */
91184
91185
91186const RANGE_VALUE_ACCESSOR = {
91187  provide: NG_VALUE_ACCESSOR,
91188  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => RangeValueAccessor),
91189  multi: true
91190};
91191/**
91192 * @description
91193 * The `ControlValueAccessor` for writing a range value and listening to range input changes.
91194 * The value accessor is used by the `FormControlDirective`, `FormControlName`, and  `NgModel`
91195 * directives.
91196 *
91197 * @usageNotes
91198 *
91199 * ### Using a range input with a reactive form
91200 *
91201 * The following example shows how to use a range input with a reactive form.
91202 *
91203 * ```ts
91204 * const ageControl = new FormControl();
91205 * ```
91206 *
91207 * ```
91208 * <input type="range" [formControl]="ageControl">
91209 * ```
91210 *
91211 * @ngModule ReactiveFormsModule
91212 * @ngModule FormsModule
91213 * @publicApi
91214 */
91215
91216class RangeValueAccessor extends BuiltInControlValueAccessor {
91217  /**
91218   * Sets the "value" property on the input element.
91219   * @nodoc
91220   */
91221  writeValue(value) {
91222    this.setProperty('value', parseFloat(value));
91223  }
91224  /**
91225   * Registers a function called when the control value changes.
91226   * @nodoc
91227   */
91228
91229
91230  registerOnChange(fn) {
91231    this.onChange = value => {
91232      fn(value == '' ? null : parseFloat(value));
91233    };
91234  }
91235
91236}
91237
91238RangeValueAccessor.ɵfac = /* @__PURE__ */function () {
91239  let ɵRangeValueAccessor_BaseFactory;
91240  return function RangeValueAccessor_Factory(t) {
91241    return (ɵRangeValueAccessor_BaseFactory || (ɵRangeValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](RangeValueAccessor)))(t || RangeValueAccessor);
91242  };
91243}();
91244
91245RangeValueAccessor.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
91246  type: RangeValueAccessor,
91247  selectors: [["input", "type", "range", "formControlName", ""], ["input", "type", "range", "formControl", ""], ["input", "type", "range", "ngModel", ""]],
91248  hostBindings: function RangeValueAccessor_HostBindings(rf, ctx) {
91249    if (rf & 1) {
91250      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function RangeValueAccessor_change_HostBindingHandler($event) {
91251        return ctx.onChange($event.target.value);
91252      })("input", function RangeValueAccessor_input_HostBindingHandler($event) {
91253        return ctx.onChange($event.target.value);
91254      })("blur", function RangeValueAccessor_blur_HostBindingHandler() {
91255        return ctx.onTouched();
91256      });
91257    }
91258  },
91259  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([RANGE_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
91260});
91261
91262(function () {
91263  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RangeValueAccessor, [{
91264    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
91265    args: [{
91266      selector: 'input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]',
91267      host: {
91268        '(change)': 'onChange($event.target.value)',
91269        '(input)': 'onChange($event.target.value)',
91270        '(blur)': 'onTouched()'
91271      },
91272      providers: [RANGE_VALUE_ACCESSOR]
91273    }]
91274  }], null, null);
91275})();
91276/**
91277 * @license
91278 * Copyright Google LLC All Rights Reserved.
91279 *
91280 * Use of this source code is governed by an MIT-style license that can be
91281 * found in the LICENSE file at https://angular.io/license
91282 */
91283
91284/**
91285 * Token to provide to turn off the ngModel warning on formControl and formControlName.
91286 */
91287
91288
91289const NG_MODEL_WITH_FORM_CONTROL_WARNING = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('NgModelWithFormControlWarning');
91290const formControlBinding = {
91291  provide: NgControl,
91292  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormControlDirective)
91293};
91294/**
91295 * @description
91296 * Synchronizes a standalone `FormControl` instance to a form control element.
91297 *
91298 * Note that support for using the `ngModel` input property and `ngModelChange` event with reactive
91299 * form directives was deprecated in Angular v6 and is scheduled for removal in
91300 * a future version of Angular.
91301 * For details, see [Deprecated features](guide/deprecations#ngmodel-with-reactive-forms).
91302 *
91303 * @see [Reactive Forms Guide](guide/reactive-forms)
91304 * @see `FormControl`
91305 * @see `AbstractControl`
91306 *
91307 * @usageNotes
91308 *
91309 * The following example shows how to register a standalone control and set its value.
91310 *
91311 * {@example forms/ts/simpleFormControl/simple_form_control_example.ts region='Component'}
91312 *
91313 * @ngModule ReactiveFormsModule
91314 * @publicApi
91315 */
91316
91317class FormControlDirective extends NgControl {
91318  constructor(validators, asyncValidators, valueAccessors, _ngModelWarningConfig) {
91319    super();
91320    this._ngModelWarningConfig = _ngModelWarningConfig;
91321    /** @deprecated as of v6 */
91322
91323    this.update = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
91324    /**
91325     * @description
91326     * Instance property used to track whether an ngModel warning has been sent out for this
91327     * particular `FormControlDirective` instance. Used to support warning config of "always".
91328     *
91329     * @internal
91330     */
91331
91332    this._ngModelWarningSent = false;
91333
91334    this._setValidators(validators);
91335
91336    this._setAsyncValidators(asyncValidators);
91337
91338    this.valueAccessor = selectValueAccessor(this, valueAccessors);
91339  }
91340  /**
91341   * @description
91342   * Triggers a warning in dev mode that this input should not be used with reactive forms.
91343   */
91344
91345
91346  set isDisabled(isDisabled) {
91347    if (typeof ngDevMode === 'undefined' || ngDevMode) {
91348      console.warn(disabledAttrWarning);
91349    }
91350  }
91351  /** @nodoc */
91352
91353
91354  ngOnChanges(changes) {
91355    if (this._isControlChanged(changes)) {
91356      const previousForm = changes['form'].previousValue;
91357
91358      if (previousForm) {
91359        cleanUpControl(previousForm, this,
91360        /* validateControlPresenceOnChange */
91361        false);
91362      }
91363
91364      setUpControl(this.form, this);
91365      this.form.updateValueAndValidity({
91366        emitEvent: false
91367      });
91368    }
91369
91370    if (isPropertyUpdated(changes, this.viewModel)) {
91371      if (typeof ngDevMode === 'undefined' || ngDevMode) {
91372        _ngModelWarning('formControl', FormControlDirective, this, this._ngModelWarningConfig);
91373      }
91374
91375      this.form.setValue(this.model);
91376      this.viewModel = this.model;
91377    }
91378  }
91379  /** @nodoc */
91380
91381
91382  ngOnDestroy() {
91383    if (this.form) {
91384      cleanUpControl(this.form, this,
91385      /* validateControlPresenceOnChange */
91386      false);
91387    }
91388  }
91389  /**
91390   * @description
91391   * Returns an array that represents the path from the top-level form to this control.
91392   * Each index is the string name of the control on that level.
91393   */
91394
91395
91396  get path() {
91397    return [];
91398  }
91399  /**
91400   * @description
91401   * The `FormControl` bound to this directive.
91402   */
91403
91404
91405  get control() {
91406    return this.form;
91407  }
91408  /**
91409   * @description
91410   * Sets the new value for the view model and emits an `ngModelChange` event.
91411   *
91412   * @param newValue The new value for the view model.
91413   */
91414
91415
91416  viewToModelUpdate(newValue) {
91417    this.viewModel = newValue;
91418    this.update.emit(newValue);
91419  }
91420
91421  _isControlChanged(changes) {
91422    return changes.hasOwnProperty('form');
91423  }
91424
91425}
91426/**
91427 * @description
91428 * Static property used to track whether any ngModel warnings have been sent across
91429 * all instances of FormControlDirective. Used to support warning config of "once".
91430 *
91431 * @internal
91432 */
91433
91434
91435FormControlDirective._ngModelWarningSentOnce = false;
91436
91437FormControlDirective.ɵfac = function FormControlDirective_Factory(t) {
91438  return new (t || FormControlDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALUE_ACCESSOR, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_MODEL_WITH_FORM_CONTROL_WARNING, 8));
91439};
91440
91441FormControlDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
91442  type: FormControlDirective,
91443  selectors: [["", "formControl", ""]],
91444  inputs: {
91445    form: ["formControl", "form"],
91446    isDisabled: ["disabled", "isDisabled"],
91447    model: ["ngModel", "model"]
91448  },
91449  outputs: {
91450    update: "ngModelChange"
91451  },
91452  exportAs: ["ngForm"],
91453  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formControlBinding]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
91454});
91455
91456(function () {
91457  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormControlDirective, [{
91458    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
91459    args: [{
91460      selector: '[formControl]',
91461      providers: [formControlBinding],
91462      exportAs: 'ngForm'
91463    }]
91464  }], function () {
91465    return [{
91466      type: undefined,
91467      decorators: [{
91468        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
91469      }, {
91470        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
91471      }, {
91472        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
91473        args: [NG_VALIDATORS]
91474      }]
91475    }, {
91476      type: undefined,
91477      decorators: [{
91478        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
91479      }, {
91480        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
91481      }, {
91482        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
91483        args: [NG_ASYNC_VALIDATORS]
91484      }]
91485    }, {
91486      type: undefined,
91487      decorators: [{
91488        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
91489      }, {
91490        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
91491      }, {
91492        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
91493        args: [NG_VALUE_ACCESSOR]
91494      }]
91495    }, {
91496      type: undefined,
91497      decorators: [{
91498        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
91499      }, {
91500        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
91501        args: [NG_MODEL_WITH_FORM_CONTROL_WARNING]
91502      }]
91503    }];
91504  }, {
91505    form: [{
91506      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
91507      args: ['formControl']
91508    }],
91509    isDisabled: [{
91510      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
91511      args: ['disabled']
91512    }],
91513    model: [{
91514      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
91515      args: ['ngModel']
91516    }],
91517    update: [{
91518      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
91519      args: ['ngModelChange']
91520    }]
91521  });
91522})();
91523/**
91524 * @license
91525 * Copyright Google LLC All Rights Reserved.
91526 *
91527 * Use of this source code is governed by an MIT-style license that can be
91528 * found in the LICENSE file at https://angular.io/license
91529 */
91530
91531
91532const formDirectiveProvider = {
91533  provide: ControlContainer,
91534  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormGroupDirective)
91535};
91536/**
91537 * @description
91538 *
91539 * Binds an existing `FormGroup` or `FormRecord` to a DOM element.
91540 *
91541 * This directive accepts an existing `FormGroup` instance. It will then use this
91542 * `FormGroup` instance to match any child `FormControl`, `FormGroup`/`FormRecord`,
91543 * and `FormArray` instances to child `FormControlName`, `FormGroupName`,
91544 * and `FormArrayName` directives.
91545 *
91546 * @see [Reactive Forms Guide](guide/reactive-forms)
91547 * @see `AbstractControl`
91548 *
91549 * @usageNotes
91550 * ### Register Form Group
91551 *
91552 * The following example registers a `FormGroup` with first name and last name controls,
91553 * and listens for the *ngSubmit* event when the button is clicked.
91554 *
91555 * {@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
91556 *
91557 * @ngModule ReactiveFormsModule
91558 * @publicApi
91559 */
91560
91561class FormGroupDirective extends ControlContainer {
91562  constructor(validators, asyncValidators) {
91563    super();
91564    /**
91565     * @description
91566     * Reports whether the form submission has been triggered.
91567     */
91568
91569    this.submitted = false;
91570    /**
91571     * Callback that should be invoked when controls in FormGroup or FormArray collection change
91572     * (added or removed). This callback triggers corresponding DOM updates.
91573     */
91574
91575    this._onCollectionChange = () => this._updateDomValue();
91576    /**
91577     * @description
91578     * Tracks the list of added `FormControlName` instances
91579     */
91580
91581
91582    this.directives = [];
91583    /**
91584     * @description
91585     * Tracks the `FormGroup` bound to this directive.
91586     */
91587
91588    this.form = null;
91589    /**
91590     * @description
91591     * Emits an event when the form submission has been triggered.
91592     */
91593
91594    this.ngSubmit = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
91595
91596    this._setValidators(validators);
91597
91598    this._setAsyncValidators(asyncValidators);
91599  }
91600  /** @nodoc */
91601
91602
91603  ngOnChanges(changes) {
91604    this._checkFormPresent();
91605
91606    if (changes.hasOwnProperty('form')) {
91607      this._updateValidators();
91608
91609      this._updateDomValue();
91610
91611      this._updateRegistrations();
91612
91613      this._oldForm = this.form;
91614    }
91615  }
91616  /** @nodoc */
91617
91618
91619  ngOnDestroy() {
91620    if (this.form) {
91621      cleanUpValidators(this.form, this); // Currently the `onCollectionChange` callback is rewritten each time the
91622      // `_registerOnCollectionChange` function is invoked. The implication is that cleanup should
vendor: 4,847 bytes, lines 91623-91817
91623      // happen *only* when the `onCollectionChange` callback was set by this directive instance.
91624      // Otherwise it might cause overriding a callback of some other directive instances. We should
91625      // consider updating this logic later to make it similar to how `onChange` callbacks are
91626      // handled, see https://github.com/angular/angular/issues/39732 for additional info.
91627
91628      if (this.form._onCollectionChange === this._onCollectionChange) {
91629        this.form._registerOnCollectionChange(() => {});
91630      }
91631    }
91632  }
91633  /**
91634   * @description
91635   * Returns this directive's instance.
91636   */
91637
91638
91639  get formDirective() {
91640    return this;
91641  }
91642  /**
91643   * @description
91644   * Returns the `FormGroup` bound to this directive.
91645   */
91646
91647
91648  get control() {
91649    return this.form;
91650  }
91651  /**
91652   * @description
91653   * Returns an array representing the path to this group. Because this directive
91654   * always lives at the top level of a form, it always an empty array.
91655   */
91656
91657
91658  get path() {
91659    return [];
91660  }
91661  /**
91662   * @description
91663   * Method that sets up the control directive in this group, re-calculates its value
91664   * and validity, and adds the instance to the internal list of directives.
91665   *
91666   * @param dir The `FormControlName` directive instance.
91667   */
91668
91669
91670  addControl(dir) {
91671    const ctrl = this.form.get(dir.path);
91672    setUpControl(ctrl, dir);
91673    ctrl.updateValueAndValidity({
91674      emitEvent: false
91675    });
91676    this.directives.push(dir);
91677    return ctrl;
91678  }
91679  /**
91680   * @description
91681   * Retrieves the `FormControl` instance from the provided `FormControlName` directive
91682   *
91683   * @param dir The `FormControlName` directive instance.
91684   */
91685
91686
91687  getControl(dir) {
91688    return this.form.get(dir.path);
91689  }
91690  /**
91691   * @description
91692   * Removes the `FormControlName` instance from the internal list of directives
91693   *
91694   * @param dir The `FormControlName` directive instance.
91695   */
91696
91697
91698  removeControl(dir) {
91699    cleanUpControl(dir.control || null, dir,
91700    /* validateControlPresenceOnChange */
91701    false);
91702    removeListItem$1(this.directives, dir);
91703  }
91704  /**
91705   * Adds a new `FormGroupName` directive instance to the form.
91706   *
91707   * @param dir The `FormGroupName` directive instance.
91708   */
91709
91710
91711  addFormGroup(dir) {
91712    this._setUpFormContainer(dir);
91713  }
91714  /**
91715   * Performs the necessary cleanup when a `FormGroupName` directive instance is removed from the
91716   * view.
91717   *
91718   * @param dir The `FormGroupName` directive instance.
91719   */
91720
91721
91722  removeFormGroup(dir) {
91723    this._cleanUpFormContainer(dir);
91724  }
91725  /**
91726   * @description
91727   * Retrieves the `FormGroup` for a provided `FormGroupName` directive instance
91728   *
91729   * @param dir The `FormGroupName` directive instance.
91730   */
91731
91732
91733  getFormGroup(dir) {
91734    return this.form.get(dir.path);
91735  }
91736  /**
91737   * Performs the necessary setup when a `FormArrayName` directive instance is added to the view.
91738   *
91739   * @param dir The `FormArrayName` directive instance.
91740   */
91741
91742
91743  addFormArray(dir) {
91744    this._setUpFormContainer(dir);
91745  }
91746  /**
91747   * Performs the necessary cleanup when a `FormArrayName` directive instance is removed from the
91748   * view.
91749   *
91750   * @param dir The `FormArrayName` directive instance.
91751   */
91752
91753
91754  removeFormArray(dir) {
91755    this._cleanUpFormContainer(dir);
91756  }
91757  /**
91758   * @description
91759   * Retrieves the `FormArray` for a provided `FormArrayName` directive instance.
91760   *
91761   * @param dir The `FormArrayName` directive instance.
91762   */
91763
91764
91765  getFormArray(dir) {
91766    return this.form.get(dir.path);
91767  }
91768  /**
91769   * Sets the new value for the provided `FormControlName` directive.
91770   *
91771   * @param dir The `FormControlName` directive instance.
91772   * @param value The new value for the directive's control.
91773   */
91774
91775
91776  updateModel(dir, value) {
91777    const ctrl = this.form.get(dir.path);
91778    ctrl.setValue(value);
91779  }
91780  /**
91781   * @description
91782   * Method called with the "submit" event is triggered on the form.
91783   * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload.
91784   *
91785   * @param $event The "submit" event object
91786   */
91787
91788
91789  onSubmit($event) {
91790    this.submitted = true;
91791    syncPendingControls(this.form, this.directives);
91792    this.ngSubmit.emit($event); // Forms with `method="dialog"` have some special behavior that won't reload the page and that
91793    // shouldn't be prevented. Note that we need to null check the `event` and the `target`, because
91794    // some internal apps call this method directly with the wrong arguments.
91795
91796    return $event?.target?.method === 'dialog';
91797  }
91798  /**
91799   * @description
91800   * Method called when the "reset" event is triggered on the form.
91801   */
91802
91803
91804  onReset() {
91805    this.resetForm();
91806  }
91807  /**
91808   * @description
91809   * Resets the form to an initial value and resets its submitted status.
91810   *
91811   * @param value The new value for the form.
91812   */
91813
91814
91815  resetForm(value = undefined) {
91816    this.form.reset(value);
91817    this.submitted = false;
91818  }
91819  /** @internal */
91820
91821
91822  _updateDomValue() {
91823    this.directives.forEach(dir => {
91824      const oldCtrl = dir.control;
91825      const newCtrl = this.form.get(dir.path);
91826
91827      if (oldCtrl !== newCtrl) {
91828        // Note: the value of the `dir.control` may not be defined, for example when it's a first
91829        // `FormControl` that is added to a `FormGroup` instance (via `addControl` call).
91830        cleanUpControl(oldCtrl || null, dir); // Check whether new control at the same location inside the corresponding `FormGroup` is an
91831        // instance of `FormControl` and perform control setup only if that's the case.
91832        // Note: we don't need to clear the list of directives (`this.directives`) here, it would be
91833        // taken care of in the `removeControl` method invoked when corresponding `formControlName`
91834        // directive instance is being removed (invoked from `FormControlName.ngOnDestroy`).
91835
91836        if (isFormControl(newCtrl)) {
91837          setUpControl(newCtrl, dir);
91838          dir.control = newCtrl;
91839        }
91840      }
91841    });
91842
91843    this.form._updateTreeValidity({
91844      emitEvent: false
91845    });
91846  }
91847
91848  _setUpFormContainer(dir) {
91849    const ctrl = this.form.get(dir.path);
91850    setUpFormContainer(ctrl, dir); // NOTE: this operation looks unnecessary in case no new validators were added in
91851    // `setUpFormContainer` call. Consider updating this code to match the logic in
91852    // `_cleanUpFormContainer` function.
91853
91854    ctrl.updateValueAndValidity({
91855      emitEvent: false
91856    });
91857  }
91858
91859  _cleanUpFormContainer(dir) {
91860    if (this.form) {
91861      const ctrl = this.form.get(dir.path);
91862
91863      if (ctrl) {
91864        const isControlUpdated = cleanUpFormContainer(ctrl, dir);
91865
91866        if (isControlUpdated) {
91867          // Run validity check only in case a control was updated (i.e. view validators were
91868          // removed) as removing view validators might cause validity to change.
91869          ctrl.updateValueAndValidity({
91870            emitEvent: false
91871          });
91872        }
91873      }
91874    }
91875  }
91876
91877  _updateRegistrations() {
91878    this.form._registerOnCollectionChange(this._onCollectionChange);
91879
91880    if (this._oldForm) {
91881      this._oldForm._registerOnCollectionChange(() => {});
91882    }
91883  }
91884
91885  _updateValidators() {
91886    setUpValidators(this.form, this);
91887
91888    if (this._oldForm) {
91889      cleanUpValidators(this._oldForm, this);
91890    }
91891  }
91892
91893  _checkFormPresent() {
91894    if (!this.form && (typeof ngDevMode === 'undefined' || ngDevMode)) {
91895      throw missingFormException();
91896    }
91897  }
91898
91899}
91900
91901FormGroupDirective.ɵfac = function FormGroupDirective_Factory(t) {
91902  return new (t || FormGroupDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10));
91903};
91904
91905FormGroupDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
91906  type: FormGroupDirective,
91907  selectors: [["", "formGroup", ""]],
91908  hostBindings: function FormGroupDirective_HostBindings(rf, ctx) {
91909    if (rf & 1) {
91910      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("submit", function FormGroupDirective_submit_HostBindingHandler($event) {
91911        return ctx.onSubmit($event);
91912      })("reset", function FormGroupDirective_reset_HostBindingHandler() {
91913        return ctx.onReset();
91914      });
91915    }
91916  },
91917  inputs: {
91918    form: ["formGroup", "form"]
91919  },
91920  outputs: {
91921    ngSubmit: "ngSubmit"
91922  },
91923  exportAs: ["ngForm"],
91924  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formDirectiveProvider]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
91925});
91926
91927(function () {
91928  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormGroupDirective, [{
91929    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
91930    args: [{
91931      selector: '[formGroup]',
91932      providers: [formDirectiveProvider],
91933      host: {
91934        '(submit)': 'onSubmit($event)',
91935        '(reset)': 'onReset()'
91936      },
91937      exportAs: 'ngForm'
91938    }]
91939  }], function () {
91940    return [{
91941      type: undefined,
91942      decorators: [{
91943        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
91944      }, {
91945        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
91946      }, {
91947        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
91948        args: [NG_VALIDATORS]
91949      }]
91950    }, {
91951      type: undefined,
91952      decorators: [{
91953        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
91954      }, {
91955        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
91956      }, {
91957        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
91958        args: [NG_ASYNC_VALIDATORS]
91959      }]
91960    }];
91961  }, {
91962    form: [{
91963      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
91964      args: ['formGroup']
91965    }],
91966    ngSubmit: [{
91967      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
91968    }]
91969  });
91970})();
91971/**
91972 * @license
91973 * Copyright Google LLC All Rights Reserved.
91974 *
91975 * Use of this source code is governed by an MIT-style license that can be
91976 * found in the LICENSE file at https://angular.io/license
91977 */
91978
91979
91980const formGroupNameProvider = {
91981  provide: ControlContainer,
91982  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormGroupName)
91983};
91984/**
91985 * @description
91986 *
91987 * Syncs a nested `FormGroup` or `FormRecord` to a DOM element.
91988 *
91989 * This directive can only be used with a parent `FormGroupDirective`.
91990 *
91991 * It accepts the string name of the nested `FormGroup` or `FormRecord` to link, and
91992 * looks for a `FormGroup` or `FormRecord` registered with that name in the parent
91993 * `FormGroup` instance you passed into `FormGroupDirective`.
91994 *
91995 * Use nested form groups to validate a sub-group of a
91996 * form separately from the rest or to group the values of certain
91997 * controls into their own nested object.
91998 *
91999 * @see [Reactive Forms Guide](guide/reactive-forms)
92000 *
92001 * @usageNotes
92002 *
92003 * ### Access the group by name
92004 *
92005 * The following example uses the `AbstractControl.get` method to access the
92006 * associated `FormGroup`
92007 *
92008 * ```ts
92009 *   this.form.get('name');
92010 * ```
92011 *
92012 * ### Access individual controls in the group
92013 *
92014 * The following example uses the `AbstractControl.get` method to access
92015 * individual controls within the group using dot syntax.
92016 *
92017 * ```ts
92018 *   this.form.get('name.first');
92019 * ```
92020 *
92021 * ### Register a nested `FormGroup`.
92022 *
92023 * The following example registers a nested *name* `FormGroup` within an existing `FormGroup`,
92024 * and provides methods to retrieve the nested `FormGroup` and individual controls.
92025 *
92026 * {@example forms/ts/nestedFormGroup/nested_form_group_example.ts region='Component'}
92027 *
92028 * @ngModule ReactiveFormsModule
92029 * @publicApi
92030 */
92031
92032class FormGroupName extends AbstractFormGroupDirective {
92033  constructor(parent, validators, asyncValidators) {
92034    super();
92035    this._parent = parent;
92036
92037    this._setValidators(validators);
92038
92039    this._setAsyncValidators(asyncValidators);
92040  }
92041  /** @internal */
92042
92043
92044  _checkParentType() {
92045    if (_hasInvalidParent(this._parent) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
92046      throw groupParentException();
92047    }
92048  }
92049
92050}
92051
92052FormGroupName.ɵfac = function FormGroupName_Factory(t) {
92053  return new (t || FormGroupName)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 13), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10));
92054};
92055
92056FormGroupName.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
92057  type: FormGroupName,
92058  selectors: [["", "formGroupName", ""]],
92059  inputs: {
92060    name: ["formGroupName", "name"]
92061  },
92062  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formGroupNameProvider]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
92063});
92064
92065(function () {
92066  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormGroupName, [{
92067    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
92068    args: [{
92069      selector: '[formGroupName]',
92070      providers: [formGroupNameProvider]
92071    }]
92072  }], function () {
92073    return [{
92074      type: ControlContainer,
92075      decorators: [{
92076        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92077      }, {
92078        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
92079      }, {
92080        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf
92081      }]
92082    }, {
92083      type: undefined,
92084      decorators: [{
92085        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92086      }, {
92087        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
92088      }, {
92089        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
92090        args: [NG_VALIDATORS]
92091      }]
92092    }, {
92093      type: undefined,
92094      decorators: [{
92095        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92096      }, {
92097        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
92098      }, {
92099        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
92100        args: [NG_ASYNC_VALIDATORS]
92101      }]
92102    }];
92103  }, {
92104    name: [{
92105      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
92106      args: ['formGroupName']
92107    }]
92108  });
92109})();
92110
92111const formArrayNameProvider = {
92112  provide: ControlContainer,
92113  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormArrayName)
92114};
92115/**
92116 * @description
92117 *
92118 * Syncs a nested `FormArray` to a DOM element.
92119 *
92120 * This directive is designed to be used with a parent `FormGroupDirective` (selector:
92121 * `[formGroup]`).
92122 *
92123 * It accepts the string name of the nested `FormArray` you want to link, and
92124 * will look for a `FormArray` registered with that name in the parent
92125 * `FormGroup` instance you passed into `FormGroupDirective`.
92126 *
92127 * @see [Reactive Forms Guide](guide/reactive-forms)
92128 * @see `AbstractControl`
92129 *
92130 * @usageNotes
92131 *
92132 * ### Example
92133 *
92134 * {@example forms/ts/nestedFormArray/nested_form_array_example.ts region='Component'}
92135 *
92136 * @ngModule ReactiveFormsModule
92137 * @publicApi
92138 */
92139
92140class FormArrayName extends ControlContainer {
92141  constructor(parent, validators, asyncValidators) {
92142    super();
92143    this._parent = parent;
92144
92145    this._setValidators(validators);
92146
92147    this._setAsyncValidators(asyncValidators);
92148  }
92149  /**
92150   * A lifecycle method called when the directive's inputs are initialized. For internal use only.
92151   * @throws If the directive does not have a valid parent.
92152   * @nodoc
92153   */
92154
92155
92156  ngOnInit() {
92157    this._checkParentType();
92158
92159    this.formDirective.addFormArray(this);
92160  }
92161  /**
92162   * A lifecycle method called before the directive's instance is destroyed. For internal use only.
92163   * @nodoc
92164   */
92165
92166
92167  ngOnDestroy() {
92168    if (this.formDirective) {
92169      this.formDirective.removeFormArray(this);
92170    }
92171  }
92172  /**
92173   * @description
92174   * The `FormArray` bound to this directive.
92175   */
92176
92177
92178  get control() {
92179    return this.formDirective.getFormArray(this);
92180  }
92181  /**
92182   * @description
92183   * The top-level directive for this group if present, otherwise null.
92184   */
92185
92186
92187  get formDirective() {
92188    return this._parent ? this._parent.formDirective : null;
92189  }
92190  /**
92191   * @description
92192   * Returns an array that represents the path from the top-level form to this control.
92193   * Each index is the string name of the control on that level.
92194   */
92195
92196
92197  get path() {
92198    return controlPath(this.name == null ? this.name : this.name.toString(), this._parent);
92199  }
92200
92201  _checkParentType() {
92202    if (_hasInvalidParent(this._parent) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
92203      throw arrayParentException();
92204    }
92205  }
92206
92207}
92208
92209FormArrayName.ɵfac = function FormArrayName_Factory(t) {
92210  return new (t || FormArrayName)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 13), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10));
92211};
92212
92213FormArrayName.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
92214  type: FormArrayName,
92215  selectors: [["", "formArrayName", ""]],
92216  inputs: {
92217    name: ["formArrayName", "name"]
92218  },
92219  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formArrayNameProvider]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
92220});
92221
92222(function () {
92223  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormArrayName, [{
92224    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
92225    args: [{
92226      selector: '[formArrayName]',
92227      providers: [formArrayNameProvider]
92228    }]
92229  }], function () {
92230    return [{
92231      type: ControlContainer,
92232      decorators: [{
92233        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92234      }, {
92235        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
92236      }, {
92237        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf
92238      }]
92239    }, {
92240      type: undefined,
92241      decorators: [{
92242        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92243      }, {
92244        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
92245      }, {
92246        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
92247        args: [NG_VALIDATORS]
92248      }]
92249    }, {
92250      type: undefined,
92251      decorators: [{
92252        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92253      }, {
92254        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
92255      }, {
92256        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
92257        args: [NG_ASYNC_VALIDATORS]
92258      }]
92259    }];
92260  }, {
92261    name: [{
92262      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
92263      args: ['formArrayName']
92264    }]
92265  });
92266})();
92267
92268function _hasInvalidParent(parent) {
92269  return !(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) && !(parent instanceof FormArrayName);
92270}
92271/**
92272 * @license
92273 * Copyright Google LLC All Rights Reserved.
92274 *
92275 * Use of this source code is governed by an MIT-style license that can be
92276 * found in the LICENSE file at https://angular.io/license
92277 */
92278
92279
92280const controlNameBinding = {
92281  provide: NgControl,
92282  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormControlName)
92283};
92284/**
92285 * @description
92286 * Syncs a `FormControl` in an existing `FormGroup` to a form control
92287 * element by name.
92288 *
92289 * @see [Reactive Forms Guide](guide/reactive-forms)
92290 * @see `FormControl`
92291 * @see `AbstractControl`
92292 *
92293 * @usageNotes
92294 *
92295 * ### Register `FormControl` within a group
92296 *
92297 * The following example shows how to register multiple form controls within a form group
92298 * and set their value.
92299 *
92300 * {@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
92301 *
92302 * To see `formControlName` examples with different form control types, see:
92303 *
92304 * * Radio buttons: `RadioControlValueAccessor`
92305 * * Selects: `SelectControlValueAccessor`
92306 *
92307 * ### Use with ngModel is deprecated
92308 *
92309 * Support for using the `ngModel` input property and `ngModelChange` event with reactive
92310 * form directives has been deprecated in Angular v6 and is scheduled for removal in
92311 * a future version of Angular.
92312 *
92313 * For details, see [Deprecated features](guide/deprecations#ngmodel-with-reactive-forms).
92314 *
92315 * @ngModule ReactiveFormsModule
92316 * @publicApi
92317 */
92318
92319class FormControlName extends NgControl {
92320  constructor(parent, validators, asyncValidators, valueAccessors, _ngModelWarningConfig) {
92321    super();
92322    this._ngModelWarningConfig = _ngModelWarningConfig;
92323    this._added = false;
92324    /** @deprecated as of v6 */
92325
92326    this.update = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
92327    /**
92328     * @description
92329     * Instance property used to track whether an ngModel warning has been sent out for this
92330     * particular FormControlName instance. Used to support warning config of "always".
92331     *
92332     * @internal
92333     */
92334
92335    this._ngModelWarningSent = false;
92336    this._parent = parent;
92337
92338    this._setValidators(validators);
92339
92340    this._setAsyncValidators(asyncValidators);
92341
92342    this.valueAccessor = selectValueAccessor(this, valueAccessors);
92343  }
92344  /**
92345   * @description
92346   * Triggers a warning in dev mode that this input should not be used with reactive forms.
92347   */
92348
92349
92350  set isDisabled(isDisabled) {
92351    if (typeof ngDevMode === 'undefined' || ngDevMode) {
92352      console.warn(disabledAttrWarning);
92353    }
92354  }
92355  /** @nodoc */
92356
92357
92358  ngOnChanges(changes) {
92359    if (!this._added) this._setUpControl();
92360
92361    if (isPropertyUpdated(changes, this.viewModel)) {
92362      if (typeof ngDevMode === 'undefined' || ngDevMode) {
92363        _ngModelWarning('formControlName', FormControlName, this, this._ngModelWarningConfig);
92364      }
92365
92366      this.viewModel = this.model;
92367      this.formDirective.updateModel(this, this.model);
92368    }
92369  }
92370  /** @nodoc */
92371
92372
92373  ngOnDestroy() {
92374    if (this.formDirective) {
92375      this.formDirective.removeControl(this);
92376    }
92377  }
92378  /**
92379   * @description
92380   * Sets the new value for the view model and emits an `ngModelChange` event.
92381   *
92382   * @param newValue The new value for the view model.
92383   */
92384
92385
92386  viewToModelUpdate(newValue) {
92387    this.viewModel = newValue;
92388    this.update.emit(newValue);
92389  }
92390  /**
92391   * @description
92392   * Returns an array that represents the path from the top-level form to this control.
92393   * Each index is the string name of the control on that level.
92394   */
92395
92396
92397  get path() {
92398    return controlPath(this.name == null ? this.name : this.name.toString(), this._parent);
92399  }
92400  /**
92401   * @description
92402   * The top-level directive for this group if present, otherwise null.
92403   */
92404
92405
92406  get formDirective() {
92407    return this._parent ? this._parent.formDirective : null;
92408  }
92409
92410  _checkParentType() {
92411    if (typeof ngDevMode === 'undefined' || ngDevMode) {
92412      if (!(this._parent instanceof FormGroupName) && this._parent instanceof AbstractFormGroupDirective) {
92413        throw ngModelGroupException();
92414      } else if (!(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective) && !(this._parent instanceof FormArrayName)) {
92415        throw controlParentException();
92416      }
92417    }
92418  }
92419
92420  _setUpControl() {
92421    this._checkParentType();
92422
92423    this.control = this.formDirective.addControl(this);
92424    this._added = true;
92425  }
92426
92427}
92428/**
92429 * @description
92430 * Static property used to track whether any ngModel warnings have been sent across
92431 * all instances of FormControlName. Used to support warning config of "once".
92432 *
92433 * @internal
92434 */
92435
92436
92437FormControlName._ngModelWarningSentOnce = false;
92438
92439FormControlName.ɵfac = function FormControlName_Factory(t) {
92440  return new (t || FormControlName)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 13), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALUE_ACCESSOR, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_MODEL_WITH_FORM_CONTROL_WARNING, 8));
92441};
92442
92443FormControlName.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
92444  type: FormControlName,
92445  selectors: [["", "formControlName", ""]],
92446  inputs: {
92447    name: ["formControlName", "name"],
92448    isDisabled: ["disabled", "isDisabled"],
92449    model: ["ngModel", "model"]
92450  },
92451  outputs: {
92452    update: "ngModelChange"
92453  },
92454  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([controlNameBinding]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
92455});
92456
92457(function () {
92458  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormControlName, [{
92459    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
92460    args: [{
92461      selector: '[formControlName]',
92462      providers: [controlNameBinding]
92463    }]
92464  }], function () {
92465    return [{
92466      type: ControlContainer,
92467      decorators: [{
92468        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92469      }, {
92470        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
92471      }, {
92472        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf
92473      }]
92474    }, {
92475      type: undefined,
92476      decorators: [{
92477        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92478      }, {
92479        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
92480      }, {
92481        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
92482        args: [NG_VALIDATORS]
92483      }]
92484    }, {
92485      type: undefined,
92486      decorators: [{
92487        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92488      }, {
92489        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
92490      }, {
92491        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
92492        args: [NG_ASYNC_VALIDATORS]
92493      }]
92494    }, {
92495      type: undefined,
92496      decorators: [{
92497        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92498      }, {
92499        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
92500      }, {
92501        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
92502        args: [NG_VALUE_ACCESSOR]
92503      }]
92504    }, {
92505      type: undefined,
92506      decorators: [{
92507        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92508      }, {
92509        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
92510        args: [NG_MODEL_WITH_FORM_CONTROL_WARNING]
92511      }]
92512    }];
92513  }, {
92514    name: [{
92515      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
92516      args: ['formControlName']
92517    }],
92518    isDisabled: [{
92519      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
92520      args: ['disabled']
92521    }],
92522    model: [{
92523      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
92524      args: ['ngModel']
92525    }],
92526    update: [{
92527      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
92528      args: ['ngModelChange']
92529    }]
92530  });
92531})();
92532/**
92533 * @license
92534 * Copyright Google LLC All Rights Reserved.
92535 *
92536 * Use of this source code is governed by an MIT-style license that can be
92537 * found in the LICENSE file at https://angular.io/license
92538 */
92539
92540
92541const SELECT_VALUE_ACCESSOR = {
92542  provide: NG_VALUE_ACCESSOR,
92543  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => SelectControlValueAccessor),
92544  multi: true
92545};
92546
92547function _buildValueString$1(id, value) {
92548  if (id == null) return `${value}`;
92549  if (value && typeof value === 'object') value = 'Object';
92550  return `${id}: ${value}`.slice(0, 50);
92551}
92552
92553function _extractId$1(valueString) {
92554  return valueString.split(':')[0];
92555}
92556/**
92557 * @description
92558 * The `ControlValueAccessor` for writing select control values and listening to select control
92559 * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and
92560 * `NgModel` directives.
92561 *
92562 * @usageNotes
92563 *
92564 * ### Using select controls in a reactive form
92565 *
92566 * The following examples show how to use a select control in a reactive form.
92567 *
92568 * {@example forms/ts/reactiveSelectControl/reactive_select_control_example.ts region='Component'}
92569 *
92570 * ### Using select controls in a template-driven form
92571 *
92572 * To use a select in a template-driven form, simply add an `ngModel` and a `name`
92573 * attribute to the main `<select>` tag.
92574 *
92575 * {@example forms/ts/selectControl/select_control_example.ts region='Component'}
92576 *
92577 * ### Customizing option selection
92578 *
92579 * Angular uses object identity to select option. It's possible for the identities of items
92580 * to change while the data does not. This can happen, for example, if the items are produced
92581 * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the
92582 * second response will produce objects with different identities.
92583 *
92584 * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
92585 * `compareWith` takes a **function** which has two arguments: `option1` and `option2`.
92586 * If `compareWith` is given, Angular selects option by the return value of the function.
92587 *
92588 * ```ts
92589 * const selectedCountriesControl = new FormControl();
92590 * ```
92591 *
92592 * ```
92593 * <select [compareWith]="compareFn"  [formControl]="selectedCountriesControl">
92594 *     <option *ngFor="let country of countries" [ngValue]="country">
92595 *         {{country.name}}
92596 *     </option>
92597 * </select>
92598 *
92599 * compareFn(c1: Country, c2: Country): boolean {
92600 *     return c1 && c2 ? c1.id === c2.id : c1 === c2;
92601 * }
92602 * ```
92603 *
92604 * **Note:** We listen to the 'change' event because 'input' events aren't fired
92605 * for selects in IE, see:
92606 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event#browser_compatibility
92607 *
92608 * @ngModule ReactiveFormsModule
92609 * @ngModule FormsModule
92610 * @publicApi
92611 */
92612
92613
92614class SelectControlValueAccessor extends BuiltInControlValueAccessor {
92615  constructor() {
92616    super(...arguments);
92617    /** @internal */
92618
92619    this._optionMap = new Map();
92620    /** @internal */
92621
92622    this._idCounter = 0;
92623    this._compareWith = Object.is;
92624  }
92625  /**
92626   * @description
92627   * Tracks the option comparison algorithm for tracking identities when
92628   * checking for changes.
92629   */
92630
92631
92632  set compareWith(fn) {
92633    if (typeof fn !== 'function' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
92634      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1201
92635      /* RuntimeErrorCode.COMPAREWITH_NOT_A_FN */
92636      , `compareWith must be a function, but received ${JSON.stringify(fn)}`);
92637    }
92638
92639    this._compareWith = fn;
92640  }
92641  /**
92642   * Sets the "value" property on the select element.
92643   * @nodoc
92644   */
92645
92646
92647  writeValue(value) {
92648    this.value = value;
92649
92650    const id = this._getOptionId(value);
92651
92652    const valueString = _buildValueString$1(id, value);
92653
92654    this.setProperty('value', valueString);
92655  }
92656  /**
92657   * Registers a function called when the control value changes.
92658   * @nodoc
92659   */
92660
92661
92662  registerOnChange(fn) {
92663    this.onChange = valueString => {
92664      this.value = this._getOptionValue(valueString);
92665      fn(this.value);
92666    };
92667  }
92668  /** @internal */
92669
92670
92671  _registerOption() {
92672    return (this._idCounter++).toString();
92673  }
92674  /** @internal */
92675
92676
92677  _getOptionId(value) {
92678    for (const id of Array.from(this._optionMap.keys())) {
92679      if (this._compareWith(this._optionMap.get(id), value)) return id;
92680    }
92681
92682    return null;
92683  }
92684  /** @internal */
92685
92686
92687  _getOptionValue(valueString) {
92688    const id = _extractId$1(valueString);
92689
92690    return this._optionMap.has(id) ? this._optionMap.get(id) : valueString;
92691  }
92692
92693}
92694
92695SelectControlValueAccessor.ɵfac = /* @__PURE__ */function () {
92696  let ɵSelectControlValueAccessor_BaseFactory;
92697  return function SelectControlValueAccessor_Factory(t) {
92698    return (ɵSelectControlValueAccessor_BaseFactory || (ɵSelectControlValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](SelectControlValueAccessor)))(t || SelectControlValueAccessor);
92699  };
92700}();
92701
92702SelectControlValueAccessor.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
92703  type: SelectControlValueAccessor,
92704  selectors: [["select", "formControlName", "", 3, "multiple", ""], ["select", "formControl", "", 3, "multiple", ""], ["select", "ngModel", "", 3, "multiple", ""]],
92705  hostBindings: function SelectControlValueAccessor_HostBindings(rf, ctx) {
92706    if (rf & 1) {
92707      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function SelectControlValueAccessor_change_HostBindingHandler($event) {
92708        return ctx.onChange($event.target.value);
92709      })("blur", function SelectControlValueAccessor_blur_HostBindingHandler() {
92710        return ctx.onTouched();
92711      });
92712    }
92713  },
92714  inputs: {
92715    compareWith: "compareWith"
92716  },
92717  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([SELECT_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
92718});
92719
92720(function () {
92721  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SelectControlValueAccessor, [{
92722    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
92723    args: [{
92724      selector: 'select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]',
92725      host: {
92726        '(change)': 'onChange($event.target.value)',
92727        '(blur)': 'onTouched()'
92728      },
92729      providers: [SELECT_VALUE_ACCESSOR]
92730    }]
92731  }], null, {
92732    compareWith: [{
92733      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
92734    }]
92735  });
92736})();
92737/**
92738 * @description
92739 * Marks `<option>` as dynamic, so Angular can be notified when options change.
92740 *
92741 * @see `SelectControlValueAccessor`
92742 *
92743 * @ngModule ReactiveFormsModule
92744 * @ngModule FormsModule
92745 * @publicApi
92746 */
92747
92748
92749class NgSelectOption {
92750  constructor(_element, _renderer, _select) {
92751    this._element = _element;
92752    this._renderer = _renderer;
92753    this._select = _select;
92754    if (this._select) this.id = this._select._registerOption();
92755  }
92756  /**
92757   * @description
92758   * Tracks the value bound to the option element. Unlike the value binding,
92759   * ngValue supports binding to objects.
92760   */
92761
92762
92763  set ngValue(value) {
92764    if (this._select == null) return;
92765
92766    this._select._optionMap.set(this.id, value);
92767
92768    this._setElementValue(_buildValueString$1(this.id, value));
92769
92770    this._select.writeValue(this._select.value);
92771  }
92772  /**
92773   * @description
92774   * Tracks simple string values bound to the option element.
92775   * For objects, use the `ngValue` input binding.
92776   */
92777
92778
92779  set value(value) {
92780    this._setElementValue(value);
92781
92782    if (this._select) this._select.writeValue(this._select.value);
92783  }
92784  /** @internal */
92785
92786
92787  _setElementValue(value) {
92788    this._renderer.setProperty(this._element.nativeElement, 'value', value);
92789  }
92790  /** @nodoc */
92791
92792
92793  ngOnDestroy() {
92794    if (this._select) {
92795      this._select._optionMap.delete(this.id);
92796
92797      this._select.writeValue(this._select.value);
92798    }
92799  }
92800
92801}
92802
92803NgSelectOption.ɵfac = function NgSelectOption_Factory(t) {
92804  return new (t || NgSelectOption)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](SelectControlValueAccessor, 9));
92805};
92806
92807NgSelectOption.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
92808  type: NgSelectOption,
92809  selectors: [["option"]],
92810  inputs: {
92811    ngValue: "ngValue",
92812    value: "value"
92813  }
92814});
92815
92816(function () {
92817  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSelectOption, [{
92818    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
92819    args: [{
92820      selector: 'option'
92821    }]
92822  }], function () {
92823    return [{
92824      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
92825    }, {
92826      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
92827    }, {
92828      type: SelectControlValueAccessor,
92829      decorators: [{
92830        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
92831      }, {
92832        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
92833      }]
92834    }];
92835  }, {
92836    ngValue: [{
92837      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
92838      args: ['ngValue']
92839    }],
92840    value: [{
92841      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
92842      args: ['value']
92843    }]
92844  });
92845})();
92846/**
92847 * @license
92848 * Copyright Google LLC All Rights Reserved.
92849 *
92850 * Use of this source code is governed by an MIT-style license that can be
92851 * found in the LICENSE file at https://angular.io/license
92852 */
92853
92854
92855const SELECT_MULTIPLE_VALUE_ACCESSOR = {
92856  provide: NG_VALUE_ACCESSOR,
92857  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => SelectMultipleControlValueAccessor),
92858  multi: true
92859};
92860
92861function _buildValueString(id, value) {
92862  if (id == null) return `${value}`;
92863  if (typeof value === 'string') value = `'${value}'`;
92864  if (value && typeof value === 'object') value = 'Object';
92865  return `${id}: ${value}`.slice(0, 50);
92866}
92867
92868function _extractId(valueString) {
92869  return valueString.split(':')[0];
92870}
92871/** Mock interface for HTMLCollection */
92872
92873
92874class HTMLCollection {}
92875/**
92876 * @description
92877 * The `ControlValueAccessor` for writing multi-select control values and listening to multi-select
92878 * control changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and
92879 * `NgModel` directives.
92880 *
92881 * @see `SelectControlValueAccessor`
92882 *
92883 * @usageNotes
92884 *
92885 * ### Using a multi-select control
92886 *
92887 * The follow example shows you how to use a multi-select control with a reactive form.
92888 *
92889 * ```ts
92890 * const countryControl = new FormControl();
92891 * ```
92892 *
92893 * ```
92894 * <select multiple name="countries" [formControl]="countryControl">
92895 *   <option *ngFor="let country of countries" [ngValue]="country">
92896 *     {{ country.name }}
92897 *   </option>
92898 * </select>
92899 * ```
92900 *
92901 * ### Customizing option selection
92902 *
92903 * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
92904 * See the `SelectControlValueAccessor` for usage.
92905 *
92906 * @ngModule ReactiveFormsModule
92907 * @ngModule FormsModule
92908 * @publicApi
92909 */
92910
92911
92912class SelectMultipleControlValueAccessor extends BuiltInControlValueAccessor {
92913  constructor() {
92914    super(...arguments);
92915    /** @internal */
92916
92917    this._optionMap = new Map();
92918    /** @internal */
92919
92920    this._idCounter = 0;
92921    this._compareWith = Object.is;
92922  }
92923  /**
92924   * @description
92925   * Tracks the option comparison algorithm for tracking identities when
92926   * checking for changes.
92927   */
92928
92929
92930  set compareWith(fn) {
92931    if (typeof fn !== 'function' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
92932      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1201
92933      /* RuntimeErrorCode.COMPAREWITH_NOT_A_FN */
92934      , `compareWith must be a function, but received ${JSON.stringify(fn)}`);
92935    }
92936
92937    this._compareWith = fn;
92938  }
92939  /**
92940   * Sets the "value" property on one or of more of the select's options.
92941   * @nodoc
92942   */
92943
92944
92945  writeValue(value) {
92946    this.value = value;
92947    let optionSelectedStateSetter;
92948
92949    if (Array.isArray(value)) {
92950      // convert values to ids
92951      const ids = value.map(v => this._getOptionId(v));
92952
92953      optionSelectedStateSetter = (opt, o) => {
92954        opt._setSelected(ids.indexOf(o.toString()) > -1);
92955      };
92956    } else {
92957      optionSelectedStateSetter = (opt, o) => {
92958        opt._setSelected(false);
92959      };
92960    }
92961
92962    this._optionMap.forEach(optionSelectedStateSetter);
92963  }
92964  /**
92965   * Registers a function called when the control value changes
92966   * and writes an array of the selected options.
92967   * @nodoc
92968   */
92969
92970
92971  registerOnChange(fn) {
92972    this.onChange = element => {
92973      const selected = [];
92974      const selectedOptions = element.selectedOptions;
92975
92976      if (selectedOptions !== undefined) {
92977        const options = selectedOptions;
92978
92979        for (let i = 0; i < options.length; i++) {
92980          const opt = options[i];
92981
92982          const val = this._getOptionValue(opt.value);
92983
92984          selected.push(val);
92985        }
92986      } // Degrade to use `options` when `selectedOptions` property is not available.
92987      // Note: the `selectedOptions` is available in all supported browsers, but the Domino lib
92988      // doesn't have it currently, see https://github.com/fgnass/domino/issues/177.
92989      else {
92990        const options = element.options;
92991
92992        for (let i = 0; i < options.length; i++) {
92993          const opt = options[i];
92994
92995          if (opt.selected) {
92996            const val = this._getOptionValue(opt.value);
92997
92998            selected.push(val);
92999          }
93000        }
93001      }
93002
93003      this.value = selected;
93004      fn(selected);
93005    };
93006  }
93007  /** @internal */
93008
93009
93010  _registerOption(value) {
93011    const id = (this._idCounter++).toString();
93012
93013    this._optionMap.set(id, value);
93014
93015    return id;
93016  }
93017  /** @internal */
93018
93019
93020  _getOptionId(value) {
93021    for (const id of Array.from(this._optionMap.keys())) {
93022      if (this._compareWith(this._optionMap.get(id)._value, value)) return id;
93023    }
93024
93025    return null;
93026  }
93027  /** @internal */
93028
93029
93030  _getOptionValue(valueString) {
93031    const id = _extractId(valueString);
93032
93033    return this._optionMap.has(id) ? this._optionMap.get(id)._value : valueString;
93034  }
93035
93036}
93037
93038SelectMultipleControlValueAccessor.ɵfac = /* @__PURE__ */function () {
93039  let ɵSelectMultipleControlValueAccessor_BaseFactory;
93040  return function SelectMultipleControlValueAccessor_Factory(t) {
93041    return (ɵSelectMultipleControlValueAccessor_BaseFactory || (ɵSelectMultipleControlValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](SelectMultipleControlValueAccessor)))(t || SelectMultipleControlValueAccessor);
93042  };
93043}();
93044
93045SelectMultipleControlValueAccessor.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93046  type: SelectMultipleControlValueAccessor,
93047  selectors: [["select", "multiple", "", "formControlName", ""], ["select", "multiple", "", "formControl", ""], ["select", "multiple", "", "ngModel", ""]],
93048  hostBindings: function SelectMultipleControlValueAccessor_HostBindings(rf, ctx) {
93049    if (rf & 1) {
93050      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function SelectMultipleControlValueAccessor_change_HostBindingHandler($event) {
93051        return ctx.onChange($event.target);
93052      })("blur", function SelectMultipleControlValueAccessor_blur_HostBindingHandler() {
93053        return ctx.onTouched();
93054      });
93055    }
93056  },
93057  inputs: {
93058    compareWith: "compareWith"
93059  },
93060  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([SELECT_MULTIPLE_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
93061});
93062
93063(function () {
93064  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SelectMultipleControlValueAccessor, [{
93065    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93066    args: [{
93067      selector: 'select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]',
93068      host: {
93069        '(change)': 'onChange($event.target)',
93070        '(blur)': 'onTouched()'
93071      },
93072      providers: [SELECT_MULTIPLE_VALUE_ACCESSOR]
93073    }]
93074  }], null, {
93075    compareWith: [{
93076      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
93077    }]
93078  });
93079})();
93080/**
93081 * @description
93082 * Marks `<option>` as dynamic, so Angular can be notified when options change.
93083 *
93084 * @see `SelectMultipleControlValueAccessor`
93085 *
93086 * @ngModule ReactiveFormsModule
93087 * @ngModule FormsModule
93088 * @publicApi
93089 */
93090
93091
93092class ɵNgSelectMultipleOption {
93093  constructor(_element, _renderer, _select) {
93094    this._element = _element;
93095    this._renderer = _renderer;
93096    this._select = _select;
93097
93098    if (this._select) {
93099      this.id = this._select._registerOption(this);
93100    }
93101  }
93102  /**
93103   * @description
93104   * Tracks the value bound to the option element. Unlike the value binding,
93105   * ngValue supports binding to objects.
93106   */
93107
93108
93109  set ngValue(value) {
93110    if (this._select == null) return;
93111    this._value = value;
93112
93113    this._setElementValue(_buildValueString(this.id, value));
93114
93115    this._select.writeValue(this._select.value);
93116  }
93117  /**
93118   * @description
93119   * Tracks simple string values bound to the option element.
93120   * For objects, use the `ngValue` input binding.
93121   */
93122
93123
93124  set value(value) {
93125    if (this._select) {
93126      this._value = value;
93127
93128      this._setElementValue(_buildValueString(this.id, value));
93129
93130      this._select.writeValue(this._select.value);
93131    } else {
93132      this._setElementValue(value);
93133    }
93134  }
93135  /** @internal */
93136
93137
93138  _setElementValue(value) {
93139    this._renderer.setProperty(this._element.nativeElement, 'value', value);
93140  }
93141  /** @internal */
93142
93143
93144  _setSelected(selected) {
93145    this._renderer.setProperty(this._element.nativeElement, 'selected', selected);
93146  }
93147  /** @nodoc */
93148
93149
93150  ngOnDestroy() {
93151    if (this._select) {
93152      this._select._optionMap.delete(this.id);
93153
93154      this._select.writeValue(this._select.value);
93155    }
93156  }
93157
93158}
93159
93160ɵNgSelectMultipleOption.ɵfac = function ɵNgSelectMultipleOption_Factory(t) {
93161  return new (t || ɵNgSelectMultipleOption)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](SelectMultipleControlValueAccessor, 9));
93162};
93163
93164ɵNgSelectMultipleOption.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93165  type: ɵNgSelectMultipleOption,
93166  selectors: [["option"]],
93167  inputs: {
93168    ngValue: "ngValue",
93169    value: "value"
93170  }
93171});
93172
93173(function () {
93174  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ɵNgSelectMultipleOption, [{
93175    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93176    args: [{
93177      selector: 'option'
93178    }]
93179  }], function () {
93180    return [{
93181      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
93182    }, {
93183      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
93184    }, {
93185      type: SelectMultipleControlValueAccessor,
93186      decorators: [{
93187        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
93188      }, {
93189        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
93190      }]
93191    }];
93192  }, {
93193    ngValue: [{
93194      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
93195      args: ['ngValue']
93196    }],
93197    value: [{
93198      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
93199      args: ['value']
93200    }]
93201  });
93202})();
93203/**
93204 * @license
93205 * Copyright Google LLC All Rights Reserved.
93206 *
93207 * Use of this source code is governed by an MIT-style license that can be
93208 * found in the LICENSE file at https://angular.io/license
93209 */
93210
93211/**
93212 * Method that updates string to integer if not already a number
93213 *
93214 * @param value The value to convert to integer.
93215 * @returns value of parameter converted to number or integer.
93216 */
93217
93218
93219function toInteger(value) {
93220  return typeof value === 'number' ? value : parseInt(value, 10);
93221}
93222/**
93223 * Method that ensures that provided value is a float (and converts it to float if needed).
93224 *
93225 * @param value The value to convert to float.
93226 * @returns value of parameter converted to number or float.
93227 */
93228
93229
93230function toFloat(value) {
93231  return typeof value === 'number' ? value : parseFloat(value);
93232}
93233/**
93234 * A base class for Validator-based Directives. The class contains common logic shared across such
93235 * Directives.
93236 *
93237 * For internal use only, this class is not intended for use outside of the Forms package.
93238 */
93239
93240
93241class AbstractValidatorDirective {
93242  constructor() {
93243    this._validator = nullValidator;
93244  }
93245  /** @nodoc */
93246
93247
93248  ngOnChanges(changes) {
93249    if (this.inputName in changes) {
93250      const input = this.normalizeInput(changes[this.inputName].currentValue);
93251      this._enabled = this.enabled(input);
93252      this._validator = this._enabled ? this.createValidator(input) : nullValidator;
93253
93254      if (this._onChange) {
93255        this._onChange();
93256      }
93257    }
93258  }
93259  /** @nodoc */
93260
93261
93262  validate(control) {
93263    return this._validator(control);
93264  }
93265  /** @nodoc */
93266
93267
93268  registerOnValidatorChange(fn) {
93269    this._onChange = fn;
93270  }
93271  /**
93272   * @description
93273   * Determines whether this validator should be active or not based on an input.
93274   * Base class implementation checks whether an input is defined (if the value is different from
93275   * `null` and `undefined`). Validator classes that extend this base class can override this
93276   * function with the logic specific to a particular validator directive.
93277   */
93278
93279
93280  enabled(input) {
93281    return input != null
93282    /* both `null` and `undefined` */
93283    ;
93284  }
93285
93286}
93287
93288AbstractValidatorDirective.ɵfac = function AbstractValidatorDirective_Factory(t) {
93289  return new (t || AbstractValidatorDirective)();
93290};
93291
93292AbstractValidatorDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93293  type: AbstractValidatorDirective,
93294  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
93295});
93296
93297(function () {
93298  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AbstractValidatorDirective, [{
93299    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive
93300  }], null, null);
93301})();
93302/**
93303 * @description
93304 * Provider which adds `MaxValidator` to the `NG_VALIDATORS` multi-provider list.
93305 */
93306
93307
93308const MAX_VALIDATOR = {
93309  provide: NG_VALIDATORS,
93310  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => MaxValidator),
93311  multi: true
93312};
93313/**
93314 * A directive which installs the {@link MaxValidator} for any `formControlName`,
93315 * `formControl`, or control with `ngModel` that also has a `max` attribute.
93316 *
93317 * @see [Form Validation](guide/form-validation)
93318 *
93319 * @usageNotes
93320 *
93321 * ### Adding a max validator
93322 *
93323 * The following example shows how to add a max validator to an input attached to an
93324 * ngModel binding.
93325 *
93326 * ```html
93327 * <input type="number" ngModel max="4">
93328 * ```
93329 *
93330 * @ngModule ReactiveFormsModule
93331 * @ngModule FormsModule
93332 * @publicApi
93333 */
93334
93335class MaxValidator extends AbstractValidatorDirective {
93336  constructor() {
93337    super(...arguments);
93338    /** @internal */
93339
93340    this.inputName = 'max';
93341    /** @internal */
93342
93343    this.normalizeInput = input => toFloat(input);
93344    /** @internal */
93345
93346
93347    this.createValidator = max => maxValidator(max);
93348  }
93349
93350}
93351
93352MaxValidator.ɵfac = /* @__PURE__ */function () {
93353  let ɵMaxValidator_BaseFactory;
93354  return function MaxValidator_Factory(t) {
93355    return (ɵMaxValidator_BaseFactory || (ɵMaxValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MaxValidator)))(t || MaxValidator);
93356  };
93357}();
93358
93359MaxValidator.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93360  type: MaxValidator,
93361  selectors: [["input", "type", "number", "max", "", "formControlName", ""], ["input", "type", "number", "max", "", "formControl", ""], ["input", "type", "number", "max", "", "ngModel", ""]],
93362  hostVars: 1,
93363  hostBindings: function MaxValidator_HostBindings(rf, ctx) {
93364    if (rf & 2) {
93365      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("max", ctx._enabled ? ctx.max : null);
93366    }
93367  },
93368  inputs: {
93369    max: "max"
93370  },
93371  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([MAX_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
93372});
93373
93374(function () {
93375  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MaxValidator, [{
93376    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93377    args: [{
93378      selector: 'input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]',
93379      providers: [MAX_VALIDATOR],
93380      host: {
93381        '[attr.max]': '_enabled ? max : null'
93382      }
93383    }]
93384  }], null, {
93385    max: [{
93386      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
93387    }]
93388  });
93389})();
93390/**
93391 * @description
93392 * Provider which adds `MinValidator` to the `NG_VALIDATORS` multi-provider list.
93393 */
93394
93395
93396const MIN_VALIDATOR = {
93397  provide: NG_VALIDATORS,
93398  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => MinValidator),
93399  multi: true
93400};
93401/**
93402 * A directive which installs the {@link MinValidator} for any `formControlName`,
93403 * `formControl`, or control with `ngModel` that also has a `min` attribute.
93404 *
93405 * @see [Form Validation](guide/form-validation)
93406 *
93407 * @usageNotes
93408 *
93409 * ### Adding a min validator
93410 *
93411 * The following example shows how to add a min validator to an input attached to an
93412 * ngModel binding.
93413 *
93414 * ```html
93415 * <input type="number" ngModel min="4">
93416 * ```
93417 *
93418 * @ngModule ReactiveFormsModule
93419 * @ngModule FormsModule
93420 * @publicApi
93421 */
93422
93423class MinValidator extends AbstractValidatorDirective {
93424  constructor() {
93425    super(...arguments);
93426    /** @internal */
93427
93428    this.inputName = 'min';
93429    /** @internal */
93430
93431    this.normalizeInput = input => toFloat(input);
93432    /** @internal */
93433
93434
93435    this.createValidator = min => minValidator(min);
93436  }
93437
93438}
93439
93440MinValidator.ɵfac = /* @__PURE__ */function () {
93441  let ɵMinValidator_BaseFactory;
93442  return function MinValidator_Factory(t) {
93443    return (ɵMinValidator_BaseFactory || (ɵMinValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MinValidator)))(t || MinValidator);
93444  };
93445}();
93446
93447MinValidator.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93448  type: MinValidator,
93449  selectors: [["input", "type", "number", "min", "", "formControlName", ""], ["input", "type", "number", "min", "", "formControl", ""], ["input", "type", "number", "min", "", "ngModel", ""]],
93450  hostVars: 1,
93451  hostBindings: function MinValidator_HostBindings(rf, ctx) {
93452    if (rf & 2) {
93453      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("min", ctx._enabled ? ctx.min : null);
93454    }
93455  },
93456  inputs: {
93457    min: "min"
93458  },
93459  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([MIN_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
93460});
93461
93462(function () {
93463  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MinValidator, [{
93464    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93465    args: [{
93466      selector: 'input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]',
93467      providers: [MIN_VALIDATOR],
93468      host: {
93469        '[attr.min]': '_enabled ? min : null'
93470      }
93471    }]
93472  }], null, {
93473    min: [{
93474      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
93475    }]
93476  });
93477})();
93478/**
93479 * @description
93480 * Provider which adds `RequiredValidator` to the `NG_VALIDATORS` multi-provider list.
93481 */
93482
93483
93484const REQUIRED_VALIDATOR = {
93485  provide: NG_VALIDATORS,
93486  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => RequiredValidator),
93487  multi: true
93488};
93489/**
93490 * @description
93491 * Provider which adds `CheckboxRequiredValidator` to the `NG_VALIDATORS` multi-provider list.
93492 */
93493
93494const CHECKBOX_REQUIRED_VALIDATOR = {
93495  provide: NG_VALIDATORS,
93496  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => CheckboxRequiredValidator),
93497  multi: true
93498};
93499/**
93500 * @description
93501 * A directive that adds the `required` validator to any controls marked with the
93502 * `required` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
93503 *
93504 * @see [Form Validation](guide/form-validation)
93505 *
93506 * @usageNotes
93507 *
93508 * ### Adding a required validator using template-driven forms
93509 *
93510 * ```
93511 * <input name="fullName" ngModel required>
93512 * ```
93513 *
93514 * @ngModule FormsModule
93515 * @ngModule ReactiveFormsModule
93516 * @publicApi
93517 */
93518
93519class RequiredValidator extends AbstractValidatorDirective {
93520  constructor() {
93521    super(...arguments);
93522    /** @internal */
93523
93524    this.inputName = 'required';
93525    /** @internal */
93526
93527    this.normalizeInput = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵcoerceToBoolean"];
93528    /** @internal */
93529
93530    this.createValidator = input => requiredValidator;
93531  }
93532  /** @nodoc */
93533
93534
93535  enabled(input) {
93536    return input;
93537  }
93538
93539}
93540
93541RequiredValidator.ɵfac = /* @__PURE__ */function () {
93542  let ɵRequiredValidator_BaseFactory;
93543  return function RequiredValidator_Factory(t) {
93544    return (ɵRequiredValidator_BaseFactory || (ɵRequiredValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](RequiredValidator)))(t || RequiredValidator);
93545  };
93546}();
93547
93548RequiredValidator.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93549  type: RequiredValidator,
93550  selectors: [["", "required", "", "formControlName", "", 3, "type", "checkbox"], ["", "required", "", "formControl", "", 3, "type", "checkbox"], ["", "required", "", "ngModel", "", 3, "type", "checkbox"]],
93551  hostVars: 1,
93552  hostBindings: function RequiredValidator_HostBindings(rf, ctx) {
93553    if (rf & 2) {
93554      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("required", ctx._enabled ? "" : null);
93555    }
93556  },
93557  inputs: {
93558    required: "required"
93559  },
93560  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([REQUIRED_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
93561});
93562
93563(function () {
93564  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RequiredValidator, [{
93565    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93566    args: [{
93567      selector: ':not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]',
93568      providers: [REQUIRED_VALIDATOR],
93569      host: {
93570        '[attr.required]': '_enabled ? "" : null'
93571      }
93572    }]
93573  }], null, {
93574    required: [{
93575      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
93576    }]
93577  });
93578})();
93579/**
93580 * A Directive that adds the `required` validator to checkbox controls marked with the
93581 * `required` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
93582 *
93583 * @see [Form Validation](guide/form-validation)
93584 *
93585 * @usageNotes
93586 *
93587 * ### Adding a required checkbox validator using template-driven forms
93588 *
93589 * The following example shows how to add a checkbox required validator to an input attached to an
93590 * ngModel binding.
93591 *
93592 * ```
93593 * <input type="checkbox" name="active" ngModel required>
93594 * ```
93595 *
93596 * @publicApi
93597 * @ngModule FormsModule
93598 * @ngModule ReactiveFormsModule
93599 */
93600
93601
93602class CheckboxRequiredValidator extends RequiredValidator {
93603  constructor() {
93604    super(...arguments);
93605    /** @internal */
93606
93607    this.createValidator = input => requiredTrueValidator;
93608  }
93609
93610}
93611
93612CheckboxRequiredValidator.ɵfac = /* @__PURE__ */function () {
93613  let ɵCheckboxRequiredValidator_BaseFactory;
93614  return function CheckboxRequiredValidator_Factory(t) {
93615    return (ɵCheckboxRequiredValidator_BaseFactory || (ɵCheckboxRequiredValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](CheckboxRequiredValidator)))(t || CheckboxRequiredValidator);
93616  };
93617}();
93618
93619CheckboxRequiredValidator.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93620  type: CheckboxRequiredValidator,
93621  selectors: [["input", "type", "checkbox", "required", "", "formControlName", ""], ["input", "type", "checkbox", "required", "", "formControl", ""], ["input", "type", "checkbox", "required", "", "ngModel", ""]],
93622  hostVars: 1,
93623  hostBindings: function CheckboxRequiredValidator_HostBindings(rf, ctx) {
93624    if (rf & 2) {
93625      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("required", ctx._enabled ? "" : null);
93626    }
93627  },
93628  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([CHECKBOX_REQUIRED_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
93629});
93630
93631(function () {
93632  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CheckboxRequiredValidator, [{
93633    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93634    args: [{
93635      selector: 'input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]',
93636      providers: [CHECKBOX_REQUIRED_VALIDATOR],
93637      host: {
93638        '[attr.required]': '_enabled ? "" : null'
93639      }
93640    }]
93641  }], null, null);
93642})();
93643/**
93644 * @description
93645 * Provider which adds `EmailValidator` to the `NG_VALIDATORS` multi-provider list.
93646 */
93647
93648
93649const EMAIL_VALIDATOR = {
93650  provide: NG_VALIDATORS,
93651  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => EmailValidator),
93652  multi: true
93653};
93654/**
93655 * A directive that adds the `email` validator to controls marked with the
93656 * `email` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
93657 *
93658 * The email validation is based on the WHATWG HTML specification with some enhancements to
93659 * incorporate more RFC rules. More information can be found on the [Validators.email
93660 * page](api/forms/Validators#email).
93661 *
93662 * @see [Form Valid
93662ation](guide/form-validation)
93663 *
93664 * @usageNotes
93665 *
93666 * ### Adding an email validator
93667 *
93668 * The following example shows how to add an email validator to an input attached to an ngModel
93669 * binding.
93670 *
93671 * ```
93672 * <input type="email" name="email" ngModel email>
93673 * <input type="email" name="email" ngModel email="true">
93674 * <input type="email" name="email" ngModel [email]="true">
93675 * ```
93676 *
93677 * @publicApi
93678 * @ngModule FormsModule
93679 * @ngModule ReactiveFormsModule
93680 */
93681
93682class EmailValidator extends AbstractValidatorDirective {
93683  constructor() {
93684    super(...arguments);
93685    /** @internal */
93686
93687    this.inputName = 'email';
93688    /** @internal */
93689
93690    this.normalizeInput = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵcoerceToBoolean"];
93691    /** @internal */
93692
93693    this.createValidator = input => emailValidator;
93694  }
93695  /** @nodoc */
93696
93697
93698  enabled(input) {
93699    return input;
93700  }
93701
93702}
93703
93704EmailValidator.ɵfac = /* @__PURE__ */function () {
93705  let ɵEmailValidator_BaseFactory;
93706  return function EmailValidator_Factory(t) {
93707    return (ɵEmailValidator_BaseFactory || (ɵEmailValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](EmailValidator)))(t || EmailValidator);
93708  };
93709}();
93710
93711EmailValidator.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93712  type: EmailValidator,
93713  selectors: [["", "email", "", "formControlName", ""], ["", "email", "", "formControl", ""], ["", "email", "", "ngModel", ""]],
93714  inputs: {
93715    email: "email"
93716  },
93717  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([EMAIL_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
93718});
93719
93720(function () {
93721  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EmailValidator, [{
93722    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93723    args: [{
93724      selector: '[email][formControlName],[email][formControl],[email][ngModel]',
93725      providers: [EMAIL_VALIDATOR]
93726    }]
93727  }], null, {
93728    email: [{
93729      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
93730    }]
93731  });
93732})();
93733/**
93734 * @description
93735 * Provider which adds `MinLengthValidator` to the `NG_VALIDATORS` multi-provider list.
93736 */
93737
93738
93739const MIN_LENGTH_VALIDATOR = {
93740  provide: NG_VALIDATORS,
93741  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => MinLengthValidator),
93742  multi: true
93743};
93744/**
93745 * A directive that adds minimum length validation to controls marked with the
93746 * `minlength` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
93747 *
93748 * @see [Form Validation](guide/form-validation)
93749 *
93750 * @usageNotes
93751 *
93752 * ### Adding a minimum length validator
93753 *
93754 * The following example shows how to add a minimum length validator to an input attached to an
93755 * ngModel binding.
93756 *
93757 * ```html
93758 * <input name="firstName" ngModel minlength="4">
93759 * ```
93760 *
93761 * @ngModule ReactiveFormsModule
93762 * @ngModule FormsModule
93763 * @publicApi
93764 */
93765
93766class MinLengthValidator extends AbstractValidatorDirective {
93767  constructor() {
93768    super(...arguments);
93769    /** @internal */
93770
93771    this.inputName = 'minlength';
93772    /** @internal */
93773
93774    this.normalizeInput = input => toInteger(input);
93775    /** @internal */
93776
93777
93778    this.createValidator = minlength => minLengthValidator(minlength);
93779  }
93780
93781}
93782
93783MinLengthValidator.ɵfac = /* @__PURE__ */function () {
93784  let ɵMinLengthValidator_BaseFactory;
93785  return function MinLengthValidator_Factory(t) {
93786    return (ɵMinLengthValidator_BaseFactory || (ɵMinLengthValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MinLengthValidator)))(t || MinLengthValidator);
93787  };
93788}();
93789
93790MinLengthValidator.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93791  type: MinLengthValidator,
93792  selectors: [["", "minlength", "", "formControlName", ""], ["", "minlength", "", "formControl", ""], ["", "minlength", "", "ngModel", ""]],
93793  hostVars: 1,
93794  hostBindings: function MinLengthValidator_HostBindings(rf, ctx) {
93795    if (rf & 2) {
93796      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("minlength", ctx._enabled ? ctx.minlength : null);
93797    }
93798  },
93799  inputs: {
93800    minlength: "minlength"
93801  },
93802  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([MIN_LENGTH_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
93803});
93804
93805(function () {
93806  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MinLengthValidator, [{
93807    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93808    args: [{
93809      selector: '[minlength][formControlName],[minlength][formControl],[minlength][ngModel]',
93810      providers: [MIN_LENGTH_VALIDATOR],
93811      host: {
93812        '[attr.minlength]': '_enabled ? minlength : null'
93813      }
93814    }]
93815  }], null, {
93816    minlength: [{
93817      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
93818    }]
93819  });
93820})();
93821/**
93822 * @description
93823 * Provider which adds `MaxLengthValidator` to the `NG_VALIDATORS` multi-provider list.
93824 */
93825
93826
93827const MAX_LENGTH_VALIDATOR = {
93828  provide: NG_VALIDATORS,
93829  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => MaxLengthValidator),
93830  multi: true
93831};
93832/**
93833 * A directive that adds max length validation to controls marked with the
93834 * `maxlength` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
93835 *
93836 * @see [Form Validation](guide/form-validation)
93837 *
93838 * @usageNotes
93839 *
93840 * ### Adding a maximum length validator
93841 *
93842 * The following example shows how to add a maximum length validator to an input attached to an
93843 * ngModel binding.
93844 *
93845 * ```html
93846 * <input name="firstName" ngModel maxlength="25">
93847 * ```
93848 *
93849 * @ngModule ReactiveFormsModule
93850 * @ngModule FormsModule
93851 * @publicApi
93852 */
93853
93854class MaxLengthValidator extends AbstractValidatorDirective {
93855  constructor() {
93856    super(...arguments);
93857    /** @internal */
93858
93859    this.inputName = 'maxlength';
93860    /** @internal */
93861
93862    this.normalizeInput = input => toInteger(input);
93863    /** @internal */
93864
93865
93866    this.createValidator = maxlength => maxLengthValidator(maxlength);
93867  }
93868
93869}
93870
93871MaxLengthValidator.ɵfac = /* @__PURE__ */function () {
93872  let ɵMaxLengthValidator_BaseFactory;
93873  return function MaxLengthValidator_Factory(t) {
93874    return (ɵMaxLengthValidator_BaseFactory || (ɵMaxLengthValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MaxLengthValidator)))(t || MaxLengthValidator);
93875  };
93876}();
93877
93878MaxLengthValidator.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93879  type: MaxLengthValidator,
93880  selectors: [["", "maxlength", "", "formControlName", ""], ["", "maxlength", "", "formControl", ""], ["", "maxlength", "", "ngModel", ""]],
93881  hostVars: 1,
93882  hostBindings: function MaxLengthValidator_HostBindings(rf, ctx) {
93883    if (rf & 2) {
93884      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("maxlength", ctx._enabled ? ctx.maxlength : null);
93885    }
93886  },
93887  inputs: {
93888    maxlength: "maxlength"
93889  },
93890  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([MAX_LENGTH_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
93891});
93892
93893(function () {
93894  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MaxLengthValidator, [{
93895    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93896    args: [{
93897      selector: '[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]',
93898      providers: [MAX_LENGTH_VALIDATOR],
93899      host: {
93900        '[attr.maxlength]': '_enabled ? maxlength : null'
93901      }
93902    }]
93903  }], null, {
93904    maxlength: [{
93905      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
93906    }]
93907  });
93908})();
93909/**
93910 * @description
93911 * Provider which adds `PatternValidator` to the `NG_VALIDATORS` multi-provider list.
93912 */
93913
93914
93915const PATTERN_VALIDATOR = {
93916  provide: NG_VALIDATORS,
93917  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => PatternValidator),
93918  multi: true
93919};
93920/**
93921 * @description
93922 * A directive that adds regex pattern validation to controls marked with the
93923 * `pattern` attribute. The regex must match the entire control value.
93924 * The directive is provided with the `NG_VALIDATORS` multi-provider list.
93925 *
93926 * @see [Form Validation](guide/form-validation)
93927 *
93928 * @usageNotes
93929 *
93930 * ### Adding a pattern validator
93931 *
93932 * The following example shows how to add a pattern validator to an input attached to an
93933 * ngModel binding.
93934 *
93935 * ```html
93936 * <input name="firstName" ngModel pattern="[a-zA-Z ]*">
93937 * ```
93938 *
93939 * @ngModule ReactiveFormsModule
93940 * @ngModule FormsModule
93941 * @publicApi
93942 */
93943
93944class PatternValidator extends AbstractValidatorDirective {
93945  constructor() {
93946    super(...arguments);
93947    /** @internal */
93948
93949    this.inputName = 'pattern';
93950    /** @internal */
93951
93952    this.normalizeInput = input => input;
93953    /** @internal */
93954
93955
93956    this.createValidator = input => patternValidator(input);
93957  }
93958
93959}
93960
93961PatternValidator.ɵfac = /* @__PURE__ */function () {
93962  let ɵPatternValidator_BaseFactory;
93963  return function PatternValidator_Factory(t) {
93964    return (ɵPatternValidator_BaseFactory || (ɵPatternValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](PatternValidator)))(t || PatternValidator);
93965  };
93966}();
93967
93968PatternValidator.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
93969  type: PatternValidator,
93970  selectors: [["", "pattern", "", "formControlName", ""], ["", "pattern", "", "formControl", ""], ["", "pattern", "", "ngModel", ""]],
93971  hostVars: 1,
93972  hostBindings: function PatternValidator_HostBindings(rf, ctx) {
93973    if (rf & 2) {
93974      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("pattern", ctx._enabled ? ctx.pattern : null);
93975    }
93976  },
93977  inputs: {
93978    pattern: "pattern"
93979  },
93980  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([PATTERN_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
93981});
93982
93983(function () {
93984  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PatternValidator, [{
93985    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
93986    args: [{
93987      selector: '[pattern][formControlName],[pattern][formControl],[pattern][ngModel]',
93988      providers: [PATTERN_VALIDATOR],
93989      host: {
93990        '[attr.pattern]': '_enabled ? pattern : null'
93991      }
93992    }]
93993  }], null, {
93994    pattern: [{
93995      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
93996    }]
93997  });
93998})();
93999/**
94000 * @license
94001 * Copyright Google LLC All Rights Reserved.
94002 *
94003 * Use of this source code is governed by an MIT-style license that can be
94004 * found in the LICENSE file at https://angular.io/license
94005 */
94006
94007
94008const SHARED_FORM_DIRECTIVES = [ɵNgNoValidate, NgSelectOption, ɵNgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor, RangeValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, RadioControlValueAccessor, NgControlStatus, NgControlStatusGroup, RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, CheckboxRequiredValidator, EmailValidator, MinValidator, MaxValidator];
94009const TEMPLATE_DRIVEN_DIRECTIVES = [NgModel, NgModelGroup, NgForm];
94010const REACTIVE_DRIVEN_DIRECTIVES = [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName];
94011/**
94012 * Internal module used for sharing directives between FormsModule and ReactiveFormsModule
94013 */
94014
94015class ɵInternalFormsSharedModule {}
94016
94017ɵInternalFormsSharedModule.ɵfac = function ɵInternalFormsSharedModule_Factory(t) {
94018  return new (t || ɵInternalFormsSharedModule)();
94019};
94020
94021ɵInternalFormsSharedModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
94022  type: ɵInternalFormsSharedModule,
94023  declarations: [ɵNgNoValidate, NgSelectOption, ɵNgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor, RangeValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, RadioControlValueAccessor, NgControlStatus, NgControlStatusGroup, RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, CheckboxRequiredValidator, EmailValidator, MinValidator, MaxValidator],
94024  imports: [RadioControlRegistryModule],
94025  exports: [ɵNgNoValidate, NgSelectOption, ɵNgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor, RangeValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, RadioControlValueAccessor, NgControlStatus, NgControlStatusGroup, RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, CheckboxRequiredValidator, EmailValidator, MinValidator, MaxValidator]
94026});
94027ɵInternalFormsSharedModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
94028  imports: [RadioControlRegistryModule]
94029});
94030
94031(function () {
94032  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ɵInternalFormsSharedModule, [{
94033    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
94034    args: [{
94035      declarations: SHARED_FORM_DIRECTIVES,
94036      imports: [RadioControlRegistryModule],
94037      exports: SHARED_FORM_DIRECTIVES
94038    }]
94039  }], null, null);
94040})();
94041/**
94042 * @license
94043 * Copyright Google LLC All Rights Reserved.
94044 *
94045 * Use of this source code is governed by an MIT-style license that can be
94046 * found in the LICENSE file at https://angular.io/license
94047 */
94048
94049/**
94050 * Exports the required providers and directives for template-driven forms,
94051 * making them available for import by NgModules that import this module.
94052 *
94053 * Providers associated with this module:
94054 * * `RadioControlRegistry`
94055 *
94056 * @see [Forms Overview](/guide/forms-overview)
94057 * @see [Template-driven Forms Guide](/guide/forms)
94058 *
94059 * @publicApi
94060 */
94061
94062
94063class FormsModule {}
94064
94065FormsModule.ɵfac = function FormsModule_Factory(t) {
94066  return new (t || FormsModule)();
94067};
94068
94069FormsModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
94070  type: FormsModule,
94071  declarations: [NgModel, NgModelGroup, NgForm],
94072  exports: [ɵInternalFormsSharedModule, NgModel, NgModelGroup, NgForm]
94073});
94074FormsModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
94075  imports: [ɵInternalFormsSharedModule]
94076});
94077
94078(function () {
94079  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormsModule, [{
94080    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
94081    args: [{
94082      declarations: TEMPLATE_DRIVEN_DIRECTIVES,
94083      exports: [ɵInternalFormsSharedModule, TEMPLATE_DRIVEN_DIRECTIVES]
94084    }]
94085  }], null, null);
94086})();
94087/**
94088 * Exports the required infrastructure and directives for reactive forms,
94089 * making them available for import by NgModules that import this module.
94090 *
94091 * Providers associated with this module:
94092 * * `FormBuilder`
94093 * * `RadioControlRegistry`
94094 *
94095 * @see [Forms Overview](guide/forms-overview)
94096 * @see [Reactive Forms Guide](guide/reactive-forms)
94097 *
94098 * @publicApi
94099 */
94100
94101
94102class ReactiveFormsModule {
94103  /**
94104   * @description
94105   * Provides options for configuring the reactive forms module.
94106   *
94107   * @param opts An object of configuration options
94108   * * `warnOnNgModelWithFormControl` Configures when to emit a warning when an `ngModel`
94109   * binding is used with reactive form directives.
94110   */
94111  static withConfig(opts) {
94112    return {
94113      ngModule: ReactiveFormsModule,
94114      providers: [{
94115        provide: NG_MODEL_WITH_FORM_CONTROL_WARNING,
94116        useValue: opts.warnOnNgModelWithFormControl
94117      }]
94118    };
94119  }
94120
94121}
94122
94123ReactiveFormsModule.ɵfac = function ReactiveFormsModule_Factory(t) {
94124  return new (t || ReactiveFormsModule)();
94125};
94126
94127ReactiveFormsModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
94128  type: ReactiveFormsModule,
94129  declarations: [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName],
94130  exports: [ɵInternalFormsSharedModule, FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName]
94131});
94132ReactiveFormsModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
94133  imports: [ɵInternalFormsSharedModule]
94134});
94135
94136(function () {
94137  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ReactiveFormsModule, [{
94138    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
94139    args: [{
94140      declarations: [REACTIVE_DRIVEN_DIRECTIVES],
94141      exports: [ɵInternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES]
94142    }]
94143  }], null, null);
94144})();
94145/**
94146 * @license
94147 * Copyright Google LLC All Rights Reserved.
94148 *
94149 * Use of this source code is governed by an MIT-style license that can be
94150 * found in the LICENSE file at https://angular.io/license
94151 */
94152
94153/**
94154 * Tracks the value and validity state of an array of `FormControl`,
94155 * `FormGroup` or `FormArray` instances.
94156 *
94157 * A `FormArray` aggregates the values of each child `FormControl` into an array.
94158 * It calculates its status by reducing the status values of its children. For example, if one of
94159 * the controls in a `FormArray` is invalid, the entire array becomes invalid.
94160 *
94161 * `FormArray` accepts one generic argument, which is the type of the controls inside.
94162 * If you need a heterogenous array, use {@link UntypedFormArray}.
94163 *
94164 * `FormArray` is one of the four fundamental building blocks used to define forms in Angular,
94165 * along with `FormControl`, `FormGroup`, and `FormRecord`.
94166 *
94167 * @usageNotes
94168 *
94169 * ### Create an array of form controls
94170 *
94171 * ```
94172 * const arr = new FormArray([
94173 *   new FormControl('Nancy', Validators.minLength(2)),
94174 *   new FormControl('Drew'),
94175 * ]);
94176 *
94177 * console.log(arr.value);   // ['Nancy', 'Drew']
94178 * console.log(arr.status);  // 'VALID'
94179 * ```
94180 *
94181 * ### Create a form array with array-level validators
94182 *
94183 * You include array-level validators and async validators. These come in handy
94184 * when you want to perform validation that considers the value of more than one child
94185 * control.
94186 *
94187 * The two types of validators are passed in separately as the second and third arg
94188 * respectively, or together as part of an options object.
94189 *
94190 * ```
94191 * const arr = new FormArray([
94192 *   new FormControl('Nancy'),
94193 *   new FormControl('Drew')
94194 * ], {validators: myValidator, asyncValidators: myAsyncValidator});
94195 * ```
94196 *
94197 * ### Set the updateOn property for all controls in a form array
94198 *
94199 * The options object is used to set a default value for each child
94200 * control's `updateOn` property. If you set `updateOn` to `'blur'` at the
94201 * array level, all child controls default to 'blur', unless the child
94202 * has explicitly specified a different `updateOn` value.
94203 *
94204 * ```ts
94205 * const arr = new FormArray([
94206 *    new FormControl()
94207 * ], {updateOn: 'blur'});
94208 * ```
94209 *
94210 * ### Adding or removing controls from a form array
94211 *
94212 * To change the controls in the array, use the `push`, `insert`, `removeAt` or `clear` methods
94213 * in `FormArray` itself. These methods ensure the controls are properly tracked in the
94214 * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate
94215 * the `FormArray` directly, as that result in strange and unexpected behavior such
94216 * as broken change detection.
94217 *
94218 * @publicApi
94219 */
94220
94221
94222class FormArray extends AbstractControl {
94223  /**
94224   * Creates a new `FormArray` instance.
94225   *
94226   * @param controls An array of child controls. Each child control is given an index
94227   * where it is registered.
94228   *
94229   * @param validatorOrOpts A synchronous validator function, or an array of
94230   * such functions, or an `AbstractControlOptions` object that contains validation functions
94231   * and a validation trigger.
94232   *
94233   * @param asyncValidator A single async validator or array of async validator functions
94234   *
94235   */
94236  constructor(controls, validatorOrOpts, asyncValidator) {
94237    super(pickValidators(validatorOrOpts), pickAsyncValidators(asyncValidator, validatorOrOpts));
94238    this.controls = controls;
94239
vendor: 10,160 bytes, lines 94240-94519
94240    this._initObservables();
94241
94242    this._setUpdateStrategy(validatorOrOpts);
94243
94244    this._setUpControls();
94245
94246    this.updateValueAndValidity({
94247      onlySelf: true,
94248      // If `asyncValidator` is present, it will trigger control status change from `PENDING` to
94249      // `VALID` or `INVALID`.
94250      // The status should be broadcasted via the `statusChanges` observable, so we set `emitEvent`
94251      // to `true` to allow that during the control creation process.
94252      emitEvent: !!this.asyncValidator
94253    });
94254  }
94255  /**
94256   * Get the `AbstractControl` at the given `index` in the array.
94257   *
94258   * @param index Index in the array to retrieve the control. If `index` is negative, it will wrap
94259   *     around from the back, and if index is greatly negative (less than `-length`), the result is
94260   * undefined. This behavior is the same as `Array.at(index)`.
94261   */
94262
94263
94264  at(index) {
94265    return this.controls[this._adjustIndex(index)];
94266  }
94267  /**
94268   * Insert a new `AbstractControl` at the end of the array.
94269   *
94270   * @param control Form control to be inserted
94271   * @param options Specifies whether this FormArray instance should emit events after a new
94272   *     control is added.
94273   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
94274   * `valueChanges` observables emit events with the latest status and value when the control is
94275   * inserted. When false, no events are emitted.
94276   */
94277
94278
94279  push(control, options = {}) {
94280    this.controls.push(control);
94281
94282    this._registerControl(control);
94283
94284    this.updateValueAndValidity({
94285      emitEvent: options.emitEvent
94286    });
94287
94288    this._onCollectionChange();
94289  }
94290  /**
94291   * Insert a new `AbstractControl` at the given `index` in the array.
94292   *
94293   * @param index Index in the array to insert the control. If `index` is negative, wraps around
94294   *     from the back. If `index` is greatly negative (less than `-length`), prepends to the array.
94295   * This behavior is the same as `Array.splice(index, 0, control)`.
94296   * @param control Form control to be inserted
94297   * @param options Specifies whether this FormArray instance should emit events after a new
94298   *     control is inserted.
94299   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
94300   * `valueChanges` observables emit events with the latest status and value when the control is
94301   * inserted. When false, no events are emitted.
94302   */
94303
94304
94305  insert(index, control, options = {}) {
94306    this.controls.splice(index, 0, control);
94307
94308    this._registerControl(control);
94309
94310    this.updateValueAndValidity({
94311      emitEvent: options.emitEvent
94312    });
94313  }
94314  /**
94315   * Remove the control at the given `index` in the array.
94316   *
94317   * @param index Index in the array to remove the control.  If `index` is negative, wraps around
94318   *     from the back. If `index` is greatly negative (less than `-length`), removes the first
94319   *     element. This behavior is the same as `Array.splice(index, 1)`.
94320   * @param options Specifies whether this FormArray instance should emit events after a
94321   *     control is removed.
94322   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
94323   * `valueChanges` observables emit events with the latest status and value when the control is
94324   * removed. When false, no events are emitted.
94325   */
94326
94327
94328  removeAt(index, options = {}) {
94329    // Adjust the index, then clamp it at no less than 0 to prevent undesired underflows.
94330    let adjustedIndex = this._adjustIndex(index);
94331
94332    if (adjustedIndex < 0) adjustedIndex = 0;
94333    if (this.controls[adjustedIndex]) this.controls[adjustedIndex]._registerOnCollectionChange(() => {});
94334    this.controls.splice(adjustedIndex, 1);
94335    this.updateValueAndValidity({
94336      emitEvent: options.emitEvent
94337    });
94338  }
94339  /**
94340   * Replace an existing control.
94341   *
94342   * @param index Index in the array to replace the control. If `index` is negative, wraps around
94343   *     from the back. If `index` is greatly negative (less than `-length`), replaces the first
94344   *     element. This behavior is the same as `Array.splice(index, 1, control)`.
94345   * @param control The `AbstractControl` control to replace the existing control
94346   * @param options Specifies whether this FormArray instance should emit events after an
94347   *     existing control is replaced with a new one.
94348   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
94349   * `valueChanges` observables emit events with the latest status and value when the control is
94350   * replaced with a new one. When false, no events are emitted.
94351   */
94352
94353
94354  setControl(index, control, options = {}) {
94355    // Adjust the index, then clamp it at no less than 0 to prevent undesired underflows.
94356    let adjustedIndex = this._adjustIndex(index);
94357
94358    if (adjustedIndex < 0) adjustedIndex = 0;
94359    if (this.controls[adjustedIndex]) this.controls[adjustedIndex]._registerOnCollectionChange(() => {});
94360    this.controls.splice(adjustedIndex, 1);
94361
94362    if (control) {
94363      this.controls.splice(adjustedIndex, 0, control);
94364
94365      this._registerControl(control);
94366    }
94367
94368    this.updateValueAndValidity({
94369      emitEvent: options.emitEvent
94370    });
94371
94372    this._onCollectionChange();
94373  }
94374  /**
94375   * Length of the control array.
94376   */
94377
94378
94379  get length() {
94380    return this.controls.length;
94381  }
94382  /**
94383   * Sets the value of the `FormArray`. It accepts an array that matches
94384   * the structure of the control.
94385   *
94386   * This method performs strict checks, and throws an error if you try
94387   * to set the value of a control that doesn't exist or if you exclude the
94388   * value of a control.
94389   *
94390   * @usageNotes
94391   * ### Set the values for the controls in the form array
94392   *
94393   * ```
94394   * const arr = new FormArray([
94395   *   new FormControl(),
94396   *   new FormControl()
94397   * ]);
94398   * console.log(arr.value);   // [null, null]
94399   *
94400   * arr.setValue(['Nancy', 'Drew']);
94401   * console.log(arr.value);   // ['Nancy', 'Drew']
94402   * ```
94403   *
94404   * @param value Array of values for the controls
94405   * @param options Configure options that determine how the control propagates changes and
94406   * emits events after the value changes
94407   *
94408   * * `onlySelf`: When true, each change only affects this control, and not its parent. Default
94409   * is false.
94410   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
94411   * `valueChanges`
94412   * observables emit events with the latest status and value when the control value is updated.
94413   * When false, no events are emitted.
94414   * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity
94415   * updateValueAndValidity} method.
94416   */
94417
94418
94419  setValue(value, options = {}) {
94420    assertAllValuesPresent(this, false, value);
94421    value.forEach((newValue, index) => {
94422      assertControlPresent(this, false, index);
94423      this.at(index).setValue(newValue, {
94424        onlySelf: true,
94425        emitEvent: options.emitEvent
94426      });
94427    });
94428    this.updateValueAndValidity(options);
94429  }
94430  /**
94431   * Patches the value of the `FormArray`. It accepts an array that matches the
94432   * structure of the control, and does its best to match the values to the correct
94433   * controls in the group.
94434   *
94435   * It accepts both super-sets and sub-sets of the array without throwing an error.
94436   *
94437   * @usageNotes
94438   * ### Patch the values for controls in a form array
94439   *
94440   * ```
94441   * const arr = new FormArray([
94442   *    new FormControl(),
94443   *    new FormControl()
94444   * ]);
94445   * console.log(arr.value);   // [null, null]
94446   *
94447   * arr.patchValue(['Nancy']);
94448   * console.log(arr.value);   // ['Nancy', null]
94449   * ```
94450   *
94451   * @param value Array of latest values for the controls
94452   * @param options Configure options that determine how the control propagates changes and
94453   * emits events after the value changes
94454   *
94455   * * `onlySelf`: When true, each change only affects this control, and not its parent. Default
94456   * is false.
94457   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
94458   * `valueChanges` observables emit events with the latest status and value when the control
94459   * value is updated. When false, no events are emitted. The configuration options are passed to
94460   * the {@link AbstractControl#updateValueAndValidity updateValueAndValidity} method.
94461   */
94462
94463
94464  patchValue(value, options = {}) {
94465    // Even though the `value` argument type doesn't allow `null` and `undefined` values, the
94466    // `patchValue` can be called recursively and inner data structures might have these values,
94467    // so we just ignore such cases when a field containing FormArray instance receives `null` or
94468    // `undefined` as a value.
94469    if (value == null
94470    /* both `null` and `undefined` */
94471    ) return;
94472    value.forEach((newValue, index) => {
94473      if (this.at(index)) {
94474        this.at(index).patchValue(newValue, {
94475          onlySelf: true,
94476          emitEvent: options.emitEvent
94477        });
94478      }
94479    });
94480    this.updateValueAndValidity(options);
94481  }
94482  /**
94483   * Resets the `FormArray` and all descendants are marked `pristine` and `untouched`, and the
94484   * value of all descendants to null or null maps.
94485   *
94486   * You reset to a specific form state by passing in an array of states
94487   * that matches the structure of the control. The state is a standalone value
94488   * or a form state object with both a value and a disabled status.
94489   *
94490   * @usageNotes
94491   * ### Reset the values in a form array
94492   *
94493   * ```ts
94494   * const arr = new FormArray([
94495   *    new FormControl(),
94496   *    new FormControl()
94497   * ]);
94498   * arr.reset(['name', 'last name']);
94499   *
94500   * console.log(arr.value);  // ['name', 'last name']
94501   * ```
94502   *
94503   * ### Reset the values in a form array and the disabled status for the first control
94504   *
94505   * ```
94506   * arr.reset([
94507   *   {value: 'name', disabled: true},
94508   *   'last'
94509   * ]);
94510   *
94511   * console.log(arr.value);  // ['last']
94512   * console.log(arr.at(0).status);  // 'DISABLED'
94513   * ```
94514   *
94515   * @param value Array of values for the controls
94516   * @param options Configure options that determine how the control propagates changes and
94517   * emits events after the value changes
94518   *
94519   * * `onlySelf`: When true, each change only affects this control, and n
94519ot its parent. Default
94520   * is false.
94521   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
94522   * `valueChanges`
94523   * observables emit events with the latest status and value when the control is reset.
94524   * When false, no events are emitted.
94525   * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity
94526   * updateValueAndValidity} method.
94527   */
94528
94529
94530  reset(value = [], options = {}) {
94531    this._forEachChild((control, index) => {
94532      control.reset(value[index], {
94533        onlySelf: true,
94534        emitEvent: options.emitEvent
94535      });
94536    });
94537
94538    this._updatePristine(options);
94539
94540    this._updateTouched(options);
94541
94542    this.updateValueAndValidity(options);
94543  }
94544  /**
94545   * The aggregate value of the array, including any disabled controls.
94546   *
94547   * Reports all values regardless of disabled status.
94548   */
94549
94550
94551  getRawValue() {
94552    return this.controls.map(control => control.getRawValue());
94553  }
94554  /**
94555   * Remove all controls in the `FormArray`.
94556   *
94557   * @param options Specifies whether this FormArray instance should emit events after all
94558   *     controls are removed.
94559   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
94560   * `valueChanges` observables emit events with the latest status and value when all controls
94561   * in this FormArray instance are removed. When false, no events are emitted.
94562   *
94563   * @usageNotes
94564   * ### Remove all elements from a FormArray
94565   *
94566   * ```ts
94567   * const arr = new FormArray([
94568   *    new FormControl(),
94569   *    new FormControl()
94570   * ]);
94571   * console.log(arr.length);  // 2
94572   *
94573   * arr.clear();
94574   * console.log(arr.length);  // 0
94575   * ```
94576   *
94577   * It's a simpler and more efficient alternative to removing all elements one by one:
94578   *
94579   * ```ts
94580   * const arr = new FormArray([
94581   *    new FormControl(),
94582   *    new FormControl()
94583   * ]);
94584   *
94585   * while (arr.length) {
94586   *    arr.removeAt(0);
94587   * }
94588   * ```
94589   */
94590
94591
94592  clear(options = {}) {
94593    if (this.controls.length < 1) return;
94594
94595    this._forEachChild(control => control._registerOnCollectionChange(() => {}));
94596
94597    this.controls.splice(0);
94598    this.updateValueAndValidity({
94599      emitEvent: options.emitEvent
94600    });
94601  }
94602  /**
94603   * Adjusts a negative index by summing it with the length of the array. For very negative
94604   * indices, the result may remain negative.
94605   * @internal
94606   */
94607
94608
94609  _adjustIndex(index) {
94610    return index < 0 ? index + this.length : index;
94611  }
94612  /** @internal */
94613
94614
94615  _syncPendingControls() {
94616    let subtreeUpdated = this.controls.reduce((updated, child) => {
94617      return child._syncPendingControls() ? true : updated;
94618    }, false);
94619    if (subtreeUpdated) this.updateValueAndValidity({
94620      onlySelf: true
94621    });
94622    return subtreeUpdated;
94623  }
94624  /** @internal */
94625
94626
94627  _forEachChild(cb) {
94628    this.controls.forEach((control, index) => {
94629      cb(control, index);
94630    });
94631  }
94632  /** @internal */
94633
94634
94635  _updateValue() {
94636    this.value = this.controls.filter(control => control.enabled || this.disabled).map(control => control.value);
94637  }
94638  /** @internal */
94639
94640
94641  _anyControls(condition) {
94642    return this.controls.some(control => control.enabled && condition(control));
94643  }
94644  /** @internal */
94645
94646
94647  _setUpControls() {
94648    this._forEachChild(control => this._registerControl(control));
94649  }
94650  /** @internal */
94651
94652
94653  _allControlsDisabled() {
94654    for (const control of this.controls) {
94655      if (control.enabled) return false;
94656    }
94657
94658    return this.controls.length > 0 || this.disabled;
94659  }
94660
94661  _registerControl(control) {
94662    control.setParent(this);
94663
94664    control._registerOnCollectionChange(this._onCollectionChange);
94665  }
94666  /** @internal */
94667
94668
94669  _find(name) {
94670    return this.at(name) ?? null;
94671  }
94672
94673}
94674
94675const UntypedFormArray = FormArray;
94676
94677const isFormArray = control => control instanceof FormArray;
94678/**
94679 * @license
94680 * Copyright Google LLC All Rights Reserved.
94681 *
94682 * Use of this source code is governed by an MIT-style license that can be
94683 * found in the LICENSE file at https://angular.io/license
94684 */
94685
94686
94687function isAbstractControlOptions(options) {
94688  return !!options && (options.asyncValidators !== undefined || options.validators !== undefined || options.updateOn !== undefined);
94689} // clang-format on
94690
94691/**
94692 * @description
94693 * Creates an `AbstractControl` from a user-specified configuration.
94694 *
94695 * The `FormBuilder` provides syntactic sugar that shortens creating instances of a
94696 * `FormControl`, `FormGroup`, or `FormArray`. It reduces the amount of boilerplate needed to
94697 * build complex forms.
94698 *
94699 * @see [Reactive Forms Guide](guide/reactive-forms)
94700 *
94701 * @publicApi
94702 */
94703
94704
94705class FormBuilder {
94706  constructor() {
94707    this.useNonNullable = false;
vendor: 5,941 bytes, lines 94708-94871
94708  }
94709  /**
94710   * @description
94711   * Returns a FormBuilder in which automatically constructed @see FormControl} elements
94712   * have `{nonNullable: true}` and are non-nullable.
94713   *
94714   * **Constructing non-nullable controls**
94715   *
94716   * When constructing a control, it will be non-nullable, and will reset to its initial value.
94717   *
94718   * ```ts
94719   * let nnfb = new FormBuilder().nonNullable;
94720   * let name = nnfb.control('Alex'); // FormControl<string>
94721   * name.reset();
94722   * console.log(name); // 'Alex'
94723   * ```
94724   *
94725   * **Constructing non-nullable groups or arrays**
94726   *
94727   * When constructing a group or array, all automatically created inner controls will be
94728   * non-nullable, and will reset to their initial values.
94729   *
94730   * ```ts
94731   * let nnfb = new FormBuilder().nonNullable;
94732   * let name = nnfb.group({who: 'Alex'}); // FormGroup<{who: FormControl<string>}>
94733   * name.reset();
94734   * console.log(name); // {who: 'Alex'}
94735   * ```
94736   * **Constructing *nullable* fields on groups or arrays**
94737   *
94738   * It is still possible to have a nullable field. In particular, any `FormControl` which is
94739   * *already* constructed will not be altered. For example:
94740   *
94741   * ```ts
94742   * let nnfb = new FormBuilder().nonNullable;
94743   * // FormGroup<{who: FormControl<string|null>}>
94744   * let name = nnfb.group({who: new FormControl('Alex')});
94745   * name.reset(); console.log(name); // {who: null}
94746   * ```
94747   *
94748   * Because the inner control is constructed explicitly by the caller, the builder has
94749   * no control over how it is created, and cannot exclude the `null`.
94750   */
94751
94752
94753  get nonNullable() {
94754    const nnfb = new FormBuilder();
94755    nnfb.useNonNullable = true;
94756    return nnfb;
94757  }
94758
94759  group(controls, options = null) {
94760    const reducedControls = this._reduceControls(controls);
94761
94762    let newOptions = {};
94763
94764    if (isAbstractControlOptions(options)) {
94765      // `options` are `AbstractControlOptions`
94766      newOptions = options;
94767    } else if (options !== null) {
94768      // `options` are legacy form group options
94769      newOptions.validators = options.validator;
94770      newOptions.asyncValidators = options.asyncValidator;
94771    }
94772
94773    return new FormGroup(reducedControls, newOptions);
94774  }
94775  /**
94776   * @description
94777   * Constructs a new `FormRecord` instance. Accepts a single generic argument, which is an object
94778   * containing all the keys and corresponding inner control types.
94779   *
94780   * @param controls A collection of child controls. The key for each child is the name
94781   * under which it is registered.
94782   *
94783   * @param options Configuration options object for the `FormRecord`. The object should have the
94784   * `AbstractControlOptions` type and might contain the following fields:
94785   * * `validators`: A synchronous validator function, or an array of validator functions.
94786   * * `asyncValidators`: A single async validator or array of async validator functions.
94787   * * `updateOn`: The event upon which the control should be updated (options: 'change' | 'blur'
94788   * | submit').
94789   */
94790
94791
94792  record(controls, options = null) {
94793    const reducedControls = this._reduceControls(controls); // Cast to `any` because the inferred types are not as specific as Element.
94794
94795
94796    return new FormRecord(reducedControls, options);
94797  }
94798  /**
94799   * @description
94800   * Constructs a new `FormControl` with the given state, validators and options. Sets
94801   * `{nonNullable: true}` in the options to get a non-nullable control. Otherwise, the
94802   * control will be nullable. Accepts a single generic argument, which is the type  of the
94803   * control's value.
94804   *
94805   * @param formState Initializes the control with an initial state value, or
94806   * with an object that contains both a value and a disabled status.
94807   *
94808   * @param validatorOrOpts A synchronous validator function, or an array of
94809   * such functions, or a `FormControlOptions` object that contains
94810   * validation functions and a validation trigger.
94811   *
94812   * @param asyncValidator A single async validator or array of async validator
94813   * functions.
94814   *
94815   * @usageNotes
94816   *
94817   * ### Initialize a control as disabled
94818   *
94819   * The following example returns a control with an initial value in a disabled state.
94820   *
94821   * <code-example path="forms/ts/formBuilder/form_builder_example.ts" region="disabled-control">
94822   * </code-example>
94823   */
94824
94825
94826  control(formState, validatorOrOpts, asyncValidator) {
94827    let newOptions = {};
94828
94829    if (!this.useNonNullable) {
94830      return new FormControl(formState, validatorOrOpts, asyncValidator);
94831    }
94832
94833    if (isAbstractControlOptions(validatorOrOpts)) {
94834      // If the second argument is options, then they are copied.
94835      newOptions = validatorOrOpts;
94836    } else {
94837      // If the other arguments are validators, they are copied into an options object.
94838      newOptions.validators = validatorOrOpts;
94839      newOptions.asyncValidators = asyncValidator;
94840    }
94841
94842    return new FormControl(formState, { ...newOptions,
94843      nonNullable: true
94844    });
94845  }
94846  /**
94847   * Constructs a new `FormArray` from the given array of configurations,
94848   * validators and options. Accepts a single generic argument, which is the type of each control
94849   * inside the array.
94850   *
94851   * @param controls An array of child controls or control configs. Each child control is given an
94852   *     index when it is registered.
94853   *
94854   * @param validatorOrOpts A synchronous validator function, or an array of such functions, or an
94855   *     `AbstractControlOptions` object that contains
94856   * validation functions and a validation trigger.
94857   *
94858   * @param asyncValidator A single async validator or array of async validator functions.
94859   */
94860
94861
94862  array(controls, validatorOrOpts, asyncValidator) {
94863    const createdControls = controls.map(c => this._createControl(c)); // Cast to `any` because the inferred types are not as specific as Element.
94864
94865    return new FormArray(createdControls, validatorOrOpts, asyncValidator);
94866  }
94867  /** @internal */
94868
94869
94870  _reduceControls(controls) {
94871    const createdControls = {};
94872    Object.keys(controls).forEach(controlName => {
94873      createdControls[controlName] = this._createControl(controls[controlName]);
94874    });
94875    return createdControls;
94876  }
94877  /** @internal */
94878
94879
94880  _createControl(controls) {
94881    if (controls instanceof FormControl) {
94882      return controls;
94883    } else if (controls instanceof AbstractControl) {
94884      // A control; just return it
94885      return controls;
94886    } else if (Array.isArray(controls)) {
94887      // ControlConfig Tuple
94888      const value = controls[0];
94889      const validator = controls.length > 1 ? controls[1] : null;
94890      const asyncValidator = controls.length > 2 ? controls[2] : null;
94891      return this.control(value, validator, asyncValidator);
94892    } else {
94893      // T or FormControlState<T>
94894      return this.control(controls);
94895    }
94896  }
94897
94898}
94899
94900FormBuilder.ɵfac = function FormBuilder_Factory(t) {
94901  return new (t || FormBuilder)();
94902};
94903
94904FormBuilder.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
94905  token: FormBuilder,
94906  factory: FormBuilder.ɵfac,
94907  providedIn: ReactiveFormsModule
94908});
94909
94910(function () {
94911  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormBuilder, [{
94912    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
94913    args: [{
94914      providedIn: ReactiveFormsModule
94915    }]
94916  }], null, null);
94917})();
94918/**
94919 * @description
94920 * `NonNullableFormBuilder` is similar to {@link FormBuilder}, but automatically constructed
94921 * {@link FormControl} elements have `{nonNullable: true}` and are non-nullable.
94922 *
94923 * @publicApi
94924 */
94925
94926
94927class NonNullableFormBuilder {}
94928
94929NonNullableFormBuilder.ɵfac = function NonNullableFormBuilder_Factory(t) {
94930  return new (t || NonNullableFormBuilder)();
94931};
94932
94933NonNullableFormBuilder.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
94934  token: NonNullableFormBuilder,
94935  factory: function () {
94936    return (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(FormBuilder).nonNullable)();
94937  },
94938  providedIn: ReactiveFormsModule
94939});
94940
94941(function () {
94942  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NonNullableFormBuilder, [{
94943    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
94944    args: [{
94945      providedIn: ReactiveFormsModule,
94946      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(FormBuilder).nonNullable
94947    }]
94948  }], null, null);
94949})();
94950/**
94951 * UntypedFormBuilder is the same as @see FormBuilder, but it provides untyped controls.
94952 */
94953
94954
94955class UntypedFormBuilder extends FormBuilder {
94956  group(controlsConfig, options = null) {
94957    return super.group(controlsConfig, options);
94958  }
94959  /**
94960   * Like `FormBuilder#control`, except the resulting control is untyped.
94961   */
94962
94963
94964  control(formState, validatorOrOpts, asyncValidator) {
94965    return super.control(formState, validatorOrOpts, asyncValidator);
94966  }
94967  /**
94968   * Like `FormBuilder#array`, except the resulting array is untyped.
94969   */
94970
94971
94972  array(controlsConfig, validatorOrOpts, asyncValidator) {
94973    return super.array(controlsConfig, validatorOrOpts, asyncValidator);
94974  }
94975
94976}
94977
94978UntypedFormBuilder.ɵfac = /* @__PURE__ */function () {
94979  let ɵUntypedFormBuilder_BaseFactory;
94980  return function UntypedFormBuilder_Factory(t) {
94981    return (ɵUntypedFormBuilder_BaseFactory || (ɵUntypedFormBuilder_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](UntypedFormBuilder)))(t || UntypedFormBuilder);
94982  };
94983}();
94984
94985UntypedFormBuilder.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
94986  token: UntypedFormBuilder,
94987  factory: UntypedFormBuilder.ɵfac,
94988  providedIn: ReactiveFormsModule
94989});
94990
94991(function () {
94992  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UntypedFormBuilder, [{
94993    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
94994    args: [{
94995      providedIn: ReactiveFormsModule
94996    }]
94997  }], null, null);
94998})();
94999/**
95000 * @license
95001 * Copyright Google LLC All Rights Reserved.
95002 *
95003 * Use of this source code is governed by an MIT-style license that can be
95004 * found in the LICENSE file at https://angular.io/license
95005 */
95006
95007/**
95008 * @publicApi
95009 */
95010
95011
95012const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Version('14.2.10');
95013/**
95014 * @license
95015 * Copyright Google LLC All Rights Reserved.
95016 *
95017 * Use of this source code is governed by an MIT-style license that can be
95018 * found in the LICENSE file at https://angular.io/license
95019 */
95020
95021/**
95022 * @license
95023 * Copyright Google LLC All Rights Reserved.
95024 *
95025 * Use of this source code is governed by an MIT-style license that can be
95026 * found in the LICENSE file at https://angular.io/license
95027 */
95028// This file only reexports content of the `src` folder. Keep it that way.
95029
95030/**
95031 * @license
95032 * Copyright Google LLC All Rights Reserved.
95033 *
95034 * Use of this source code is governed by an MIT-style license that can be
95035 * found in the LICENSE file at https://angular.io/license
95036 */
95037
95038/**
95039 * Generated bundle index. Do not edit.
95040 */
95041
95042
95043
95044/***/ }),
95045
95046/***/ 6057:
95047/*!**********************************************************************************************!*\
95048  !*** ./node_modules/@angular/platform-browser-dynamic/fesm2020/platform-browser-dynamic.mjs ***!
95049  \**********************************************************************************************/
95050/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
95051
95052__webpack_require__.r(__webpack_exports__);
95053/* harmony export */ __webpack_require__.d(__webpack_exports__, {
95054/* harmony export */   "JitCompilerFactory": () => (/* binding */ JitCompilerFactory),
95055/* harmony export */   "RESOURCE_CACHE_PROVIDER": () => (/* binding */ RESOURCE_CACHE_PROVIDER),
95056/* harmony export */   "VERSION": () => (/* binding */ VERSION),
95057/* harmony export */   "platformBrowserDynamic": () => (/* binding */ platformBrowserDynamic),
95058/* harmony export */   "ɵINTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS": () => (/* binding */ INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS),
95059/* harmony export */   "ɵplatformCoreDynamic": () => (/* binding */ platformCoreDynamic)
95060/* harmony export */ });
95061/* harmony import */ var _angular_compiler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/compiler */ 8781);
95062/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 2560);
95063/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/common */ 4666);
95064/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/platform-browser */ 4497);
95065/**
95066 * @license Angular v14.2.10
95067 * (c) 2010-2022 Google LLC. https://angular.io/
95068 * License: MIT
95069 */
95070
95071
95072
95073
95074
95075/**
95076 * @license
95077 * Copyright Google LLC All Rights Reserved.
95078 *
95079 * Use of this source code is governed by an MIT-style license that can be
95080 * found in the LICENSE file at https://angular.io/license
95081 */
95082
95083const ERROR_COLLECTOR_TOKEN = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('ErrorCollector');
95084/**
95085 * A default provider for {@link PACKAGE_ROOT_URL} that maps to '/'.
95086 */
95087
95088const DEFAULT_PACKAGE_URL_PROVIDER = {
95089  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.PACKAGE_ROOT_URL,
95090  useValue: '/'
95091};
95092const COMPILER_PROVIDERS = [{
95093  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Compiler,
95094  useFactory: () => new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Compiler()
95095}];
95096/**
95097 * @publicApi
95098 *
95099 * @deprecated
95100 * Ivy JIT mode doesn't require accessing this symbol.
95101 * See [JIT API changes due to ViewEngine deprecation](guide/deprecations#jit-api-changes) for
95102 * additional context.
95103 */
95104
95105class JitCompilerFactory {
95106  /* @internal */
95107  constructor(defaultOptions) {
95108    const compilerOptions = {
95109      useJit: true,
95110      defaultEncapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.Emulated,
95111      missingTranslation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.MissingTranslationStrategy.Warning
95112    };
95113    this._defaultOptions = [compilerOptions, ...defaultOptions];
95114  }
95115
95116  createCompiler(options = []) {
95117    const opts = _mergeOptions(this._defaultOptions.concat(options));
95118
95119    const injector = _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injector.create([COMPILER_PROVIDERS, {
95120      provide: _angular_compiler__WEBPACK_IMPORTED_MODULE_0__.CompilerConfig,
95121      useFactory: () => {
95122        return new _angular_compiler__WEBPACK_IMPORTED_MODULE_0__.CompilerConfig({
95123          // let explicit values from the compiler options overwrite options
95124          // from the app providers
95125          useJit: opts.useJit,
95126          jitDevMode: (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.isDevMode)(),
95127          // let explicit values from the compiler options overwrite options
95128          // from the app providers
95129          defaultEncapsulation: opts.defaultEncapsulation,
95130          missingTranslation: opts.missingTranslation,
95131          preserveWhitespaces: opts.preserveWhitespaces
95132        });
95133      },
95134      deps: []
95135    }, opts.providers]);
95136    return injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_1__.Compiler);
95137  }
95138
95139}
95140
95141function _mergeOptions(optionsArr) {
95142  return {
95143    useJit: _lastDefined(optionsArr.map(options => options.useJit)),
95144    defaultEncapsulation: _lastDefined(optionsArr.map(options => options.defaultEncapsulation)),
95145    providers: _mergeArrays(optionsArr.map(options => options.providers)),
95146    missingTranslation: _lastDefined(optionsArr.map(options => options.missingTranslation)),
95147    preserveWhitespaces: _lastDefined(optionsArr.map(options => options.preserveWhitespaces))
95148  };
95149}
95150
95151function _lastDefined(args) {
95152  for (let i = args.length - 1; i >= 0; i--) {
95153    if (args[i] !== undefined) {
95154      return args[i];
95155    }
95156  }
95157
95158  return undefined;
95159}
95160
95161function _mergeArrays(parts) {
95162  const result = [];
95163  parts.forEach(part => part && result.push(...part));
95164  return result;
95165}
95166/**
95167 * @license
95168 * Copyright Google LLC All Rights Reserved.
95169 *
95170 * Use of this source code is governed by an MIT-style license that can be
95171 * found in the LICENSE file at https://angular.io/license
95172 */
95173
95174/**
95175 * A platform that included corePlatform and the compiler.
95176 *
95177 * @publicApi
95178 */
95179
95180
95181const platformCoreDynamic = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.createPlatformFactory)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.platformCore, 'coreDynamic', [{
95182  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.COMPILER_OPTIONS,
95183  useValue: {},
95184  multi: true
95185}, {
95186  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.CompilerFactory,
95187  useClass: JitCompilerFactory,
95188  deps: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.COMPILER_OPTIONS]
95189}]);
95190/**
95191 * @license
95192 * Copyright Google LLC All Rights Reserved.
95193 *
95194 * Use of this source code is governed by an MIT-style license that can be
95195 * found in the LICENSE file at https://angular.io/license
95196 */
95197
95198class ResourceLoaderImpl extends _angular_compiler__WEBPACK_IMPORTED_MODULE_0__.ResourceLoader {
95199  get(url) {
95200    let resolve;
95201    let reject;
95202    const promise = new Promise((res, rej) => {
95203      resolve = res;
95204      reject = rej;
95205    });
95206    const xhr = new XMLHttpRequest();
95207    xhr.open('GET', url, true);
95208    xhr.responseType = 'text';
95209
95210    xhr.onload = function () {
95211      // responseText is the old-school way of retrieving response (supported by IE8 & 9)
95212      // response/responseType properties were introduced in ResourceLoader Level2 spec (supported
95213      // by IE10)
95214      const response = xhr.response || xhr.responseText; // normalize IE9 bug (https://bugs.jquery.com/ticket/1450)
95215
95216      let status = xhr.status === 1223 ? 204 : xhr.status; // fix status code when it is 0 (0 status is undocumented).
95217      // Occurs when accessing file resources or on Android 4.1 stock browser
95218      // while retrieving files from application cache.
95219
95220      if (status === 0) {
95221        status = response ? 200 : 0;
95222      }
95223
95224      if (200 <= status && status <= 300) {
95225        resolve(response);
95226      } else {
95227        reject(`Failed to load ${url}`);
95228      }
95229    };
95230
95231    xhr.onerror = function () {
95232      reject(`Failed to load ${url}`);
95233    };
95234
95235    xhr.send();
95236    return promise;
95237  }
95238
95239}
95240
95241ResourceLoaderImpl.ɵfac = /* @__PURE__ */function () {
95242  let ɵResourceLoaderImpl_BaseFactory;
95243  return function ResourceLoaderImpl_Factory(t) {
95244    return (ɵResourceLoaderImpl_BaseFactory || (ɵResourceLoaderImpl_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵgetInheritedFactory"](ResourceLoaderImpl)))(t || ResourceLoaderImpl);
95245  };
95246}();
95247
95248ResourceLoaderImpl.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
95249  token: ResourceLoaderImpl,
95250  factory: ResourceLoaderImpl.ɵfac
95251});
95252
95253(function () {
95254  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](ResourceLoaderImpl, [{
95255    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
95256  }], null, null);
95257})();
95258/**
95259 * @license
95260 * Copyright Google LLC All Rights Reserved.
95261 *
95262 * Use of this source code is governed by an MIT-style license that can be
95263 * found in the LICENSE file at https://angular.io/license
95264 */
95265
95266/**
95267 * @publicApi
95268 */
95269
95270
95271const INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS = [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_2__["ɵINTERNAL_BROWSER_PLATFORM_PROVIDERS"], {
95272  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.COMPILER_OPTIONS,
95273  useValue: {
95274    providers: [{
95275      provide: _angular_compiler__WEBPACK_IMPORTED_MODULE_0__.ResourceLoader,
95276      useClass: ResourceLoaderImpl,
95277      deps: []
95278    }]
95279  },
95280  multi: true
95281}, {
95282  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID,
95283  useValue: _angular_common__WEBPACK_IMPORTED_MODULE_3__["ɵPLATFORM_BROWSER_ID"]
95284}];
95285/**
95286 * @license
95287 * Copyright Google LLC All Rights Reserved.
95288 *
95289 * Use of this source code is governed by an MIT-style license that can be
95290 * found in the LICENSE file at https://angular.io/license
95291 */
95292
95293/**
95294 * An implementation of ResourceLoader that uses a template cache to avoid doing an actual
95295 * ResourceLoader.
95296 *
95297 * The template cache needs to be built and loaded into window.$templateCache
95298 * via a separate mechanism.
95299 *
95300 * @publicApi
95301 *
95302 * @deprecated This was previously necessary in some cases to test AOT-compiled components with View
95303 *     Engine, but is no longer since Ivy.
95304 */
95305
95306class CachedResourceLoader extends _angular_compiler__WEBPACK_IMPORTED_MODULE_0__.Re
95306sourceLoader {
95307  constructor() {
95308    super();
95309    this._cache = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].$templateCache;
95310
95311    if (this._cache == null) {
95312      throw new Error('CachedResourceLoader: Template cache was not found in $templateCache.');
95313    }
95314  }
95315
95316  get(url) {
95317    if (this._cache.hasOwnProperty(url)) {
95318      return Promise.resolve(this._cache[url]);
95319    } else {
95320      return Promise.reject('CachedResourceLoader: Did not find cached template for ' + url);
95321    }
95322  }
95323
95324}
95325/**
95326 * @license
95327 * Copyright Google LLC All Rights Reserved.
95328 *
95329 * Use of this source code is governed by an MIT-style license that can be
95330 * found in the LICENSE file at https://angular.io/license
95331 */
95332
95333/**
95334 * @license
95335 * Copyright Google LLC All Rights Reserved.
95336 *
95337 * Use of this source code is governed by an MIT-style license that can be
95338 * found in the LICENSE file at https://angular.io/license
95339 */
95340
95341/**
95342 * @publicApi
95343 */
95344
95345
95346const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Version('14.2.10');
95347/**
95348 * @license
95349 * Copyright Google LLC All Rights Reserved.
95350 *
95351 * Use of this source code is governed by an MIT-style license that can be
95352 * found in the LICENSE file at https://angular.io/license
95353 */
95354
95355/**
95356 * @publicApi
95357 *
95358 * @deprecated This was previously necessary in some cases to test AOT-compiled components with View
95359 *     Engine, but is no longer since Ivy.
95360
95361 */
95362
95363const RESOURCE_CACHE_PROVIDER = [{
95364  provide: _angular_compiler__WEBPACK_IMPORTED_MODULE_0__.ResourceLoader,
95365  useClass: CachedResourceLoader,
95366  deps: []
95367}];
95368/**
95369 * @publicApi
95370 */
95371
95372const platformBrowserDynamic = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.createPlatformFactory)(platformCoreDynamic, 'browserDynamic', INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
95373/**
95374 * @license
95375 * Copyright Google LLC All Rights Reserved.
95376 *
95377 * Use of this source code is governed by an MIT-style license that can be
95378 * found in the LICENSE file at https://angular.io/license
95379 */
95380// This file only reexports content of the `src` folder. Keep it that way.
95381
95382/**
95383 * @license
95384 * Copyright Google LLC All Rights Reserved.
95385 *
95386 * Use of this source code is governed by an MIT-style license that can be
95387 * found in the LICENSE file at https://angular.io/license
95388 */
95389
95390/**
95391 * Generated bundle index. Do not edit.
95392 */
95393
95394
95395
95396/***/ }),
95397
95398/***/ 7146:
95399/*!************************************************************************!*\
95400  !*** ./node_modules/@angular/platform-browser/fesm2020/animations.mjs ***!
95401  \************************************************************************/
95402/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
95403
95404__webpack_require__.r(__webpack_exports__);
95405/* harmony export */ __webpack_require__.d(__webpack_exports__, {
95406/* harmony export */   "ANIMATION_MODULE_TYPE": () => (/* reexport safe */ _angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE),
95407/* harmony export */   "BrowserAnimationsModule": () => (/* binding */ BrowserAnimationsModule),
95408/* harmony export */   "NoopAnimationsModule": () => (/* binding */ NoopAnimationsModule),
95409/* harmony export */   "provideAnimations": () => (/* binding */ provideAnimations),
95410/* harmony export */   "provideNoopAnimations": () => (/* binding */ provideNoopAnimations),
95411/* harmony export */   "ɵAnimationRenderer": () => (/* binding */ AnimationRenderer),
95412/* harmony export */   "ɵAnimationRendererFactory": () => (/* binding */ AnimationRendererFactory),
95413/* harmony export */   "ɵBrowserAnimationBuilder": () => (/* binding */ BrowserAnimationBuilder),
95414/* harmony export */   "ɵBrowserAnimationFactory": () => (/* binding */ BrowserAnimationFactory),
95415/* harmony export */   "ɵInjectableAnimationEngine": () => (/* binding */ InjectableAnimationEngine)
95416/* harmony export */ });
95417/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 2560);
95418/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/platform-browser */ 4497);
95419/* harmony import */ var _angular_animations__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/animations */ 4851);
95420/* harmony import */ var _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/animations/browser */ 5787);
95421/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/common */ 4666);
95422/**
95423 * @license Angular v14.2.10
95424 * (c) 2010-2022 Google LLC. https://angular.io/
95425 * License: MIT
95426 */
95427
95428
95429
95430
95431
95432
95433
95434
95435/**
95436 * @license
95437 * Copyright Google LLC All Rights Reserved.
95438 *
95439 * Use of this source code is governed by an MIT-style license that can be
95440 * found in the LICENSE file at https://angular.io/license
95441 */
95442
95443class BrowserAnimationBuilder extends _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationBuilder {
95444  constructor(rootRenderer, doc) {
95445    super();
95446    this._nextAnimationId = 0;
95447    const typeData = {
95448      id: '0',
95449      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
95450      styles: [],
95451      data: {
95452        animation: []
95453      }
95454    };
95455    this._renderer = rootRenderer.createRenderer(doc.body, typeData);
95456  }
95457
95458  build(animation) {
95459    const id = this._nextAnimationId.toString();
95460
95461    this._nextAnimationId++;
95462    const entry = Array.isArray(animation) ? (0,_angular_animations__WEBPACK_IMPORTED_MODULE_1__.sequence)(animation) : animation;
95463    issueAnimationCommand(this._renderer, null, id, 'register', [entry]);
95464    return new BrowserAnimationFactory(id, this._renderer);
95465  }
95466
95467}
95468
95469BrowserAnimationBuilder.ɵfac = function BrowserAnimationBuilder_Factory(t) {
95470  return new (t || BrowserAnimationBuilder)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererFactory2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT));
95471};
95472
95473BrowserAnimationBuilder.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
95474  token: BrowserAnimationBuilder,
95475  factory: BrowserAnimationBuilder.ɵfac
95476});
95477
95478(function () {
95479  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BrowserAnimationBuilder, [{
95480    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
95481  }], function () {
95482    return [{
95483      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererFactory2
95484    }, {
95485      type: undefined,
95486      decorators: [{
95487        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
95488        args: [_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT]
95489      }]
95490    }];
95491  }, null);
95492})();
95493
95494class BrowserAnimationFactory extends _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationFactory {
95495  constructor(_id, _renderer) {
95496    super();
95497    this._id = _id;
95498    this._renderer = _renderer;
95499  }
95500
95501  create(element, options) {
95502    return new RendererAnimationPlayer(this._id, element, options || {}, this._renderer);
95503  }
95504
95505}
95506
95507class RendererAnimationPlayer {
95508  constructor(id, element, options, _renderer) {
95509    this.id = id;
95510    this.element = element;
95511    this._renderer = _renderer;
95512    this.parentPlayer = null;
95513    this._started = false;
95514    this.totalTime = 0;
95515
95516    this._command('create', options);
95517  }
95518
95519  _listen(eventName, callback) {
95520    return this._renderer.listen(this.element, `@@${this.id}:${eventName}`, callback);
95521  }
95522
95523  _command(command, ...args) {
95524    return issueAnimationCommand(this._renderer, this.element, this.id, command, args);
95525  }
95526
95527  onDone(fn) {
95528    this._listen('done', fn);
95529  }
95530
95531  onStart(fn) {
95532    this._listen('start', fn);
95533  }
95534
95535  onDestroy(fn) {
95536    this._listen('destroy', fn);
95537  }
95538
95539  init() {
95540    this._command('init');
95541  }
95542
95543  hasStarted() {
95544    return this._started;
95545  }
95546
95547  play() {
95548    this._command('play');
95549
95550    this._started = true;
95551  }
95552
95553  pause() {
95554    this._command('pause');
95555  }
95556
95557  restart() {
95558    this._command('restart');
95559  }
95560
95561  finish() {
95562    this._command('finish');
95563  }
95564
95565  destroy() {
95566    this._command('destroy');
95567  }
95568
95569  reset() {
95570    this._command('reset');
95571
95572    this._started = false;
95573  }
95574
95575  setPosition(p) {
95576    this._command('setPosition', p);
95577  }
95578
95579  getPosition() {
95580    return this._renderer.engine.players[+this.id]?.getPosition() ?? 0;
95581  }
95582
95583}
95584
95585function issueAnimationCommand(renderer, element, id, command, args) {
95586  return renderer.setProperty(element, `@@${id}:${command}`, args);
95587}
95588
95589const ANIMATION_PREFIX = '@';
95590const DISABLE_ANIMATIONS_FLAG = '@.disabled';
95591
95592class AnimationRendererFactory {
95593  constructor(delegate, engine, _zone) {
95594    this.delegate = delegate;
95595    this.engine = engine;
95596    this._zone = _zone;
95597    this._currentId = 0;
95598    this._microtaskId = 1;
95599    this._animationCallbacksBuffer = [];
95600    this._rendererCache = new Map();
95601    this._cdRecurDepth = 0;
95602    this.promise = Promise.resolve(0);
95603
95604    engine.onRemovalComplete = (element, delegate) => {
95605      // Note: if a component element has a leave animation, and a host leave animation,
95606      // the view engine will call `removeChild` for the parent
95607      // component renderer as well as for the child component renderer.
95608      // Therefore, we need to check if we already removed the element.
95609      const parentNode = delegate?.parentNode(element);
95610
95611      if (parentNode) {
95612        delegate.removeChild(parentNode, element);
95613      }
95614    };
95615  }
95616
95617  createRenderer(hostElement, type) {
95618    const EMPTY_NAMESPACE_ID = ''; // cache the delegates to find out which cached delegate can
95619    // be used by which cached renderer
95620
95621    const delegate = this.delegate.createRenderer(hostElement, type);
95622
95623    if (!hostElement || !type || !type.data || !type.data['animation']) {
95624      let renderer = this._rendererCache.get(delegate);
95625
95626      if (!renderer) {
95627        // Ensure that the renderer is removed from the cache on destroy
95628        // since it may contain references to detached DOM nodes.
95629        const onRendererDestroy = () => this._rendererCache.delete(delegate);
95630
95631        renderer = new BaseAnimationRenderer(EMPTY_NAMESPACE_ID, delegate, this.engine, onRendererDestroy); // only cache this result when the base renderer is used
95632
95633        this._rendererCache.set(delegate, renderer);
95634      }
95635
95636      return renderer;
95637    }
95638
95639    const componentId = type.id;
95640    const namespaceId = type.id + '-' + this._currentId;
95641    this._currentId++;
95642    this.engine.register(namespaceId, hostElement);
95643
95644    const registerTrigger = trigger => {
95645      if (Array.isArray(trigger)) {
95646        trigger.forEach(registerTrigger);
95647      } else {
95648        this.engine.registerTrigger(componentId, namespaceId, hostElement, trigger.name, trigger);
95649      }
95650    };
95651
95652    const animationTriggers = type.data['animation'];
95653    animationTriggers.forEach(registerTrigger);
95654    return new AnimationRenderer(this, namespaceId, delegate, this.engine);
95655  }
95656
95657  begin() {
95658    this._cdRecurDepth++;
95659
95660    if (this.delegate.begin) {
95661      this.delegate.begin();
95662    }
95663  }
95664
95665  _scheduleCountTask() {
95666    // always use promise to schedule microtask instead of use Zone
95667    this.promise.then(() => {
95668      this._microtaskId++;
95669    });
95670  }
95671  /** @internal */
95672
95673
95674  scheduleListenerCallback(count, fn, data) {
95675    if (count >= 0 && count < this._microtaskId) {
95676      this._zone.run(() => fn(data));
95677
95678      return;
95679    }
95680
95681    if (this._animationCallbacksBuffer.length == 0) {
95682      Promise.resolve(null).then(() => {
95683        this._zone.run(() => {
95684          this._animationCallbacksBuffer.forEach(tuple => {
95685            const [fn, data] = tuple;
95686            fn(data);
95687          });
95688
95689          this._animationCallbacksBuffer = [];
95690        });
95691      });
95692    }
95693
95694    this._animationCallbacksBuffer.push([fn, data]);
95695  }
95696
95697  end() {
95698    this._cdRecurDepth--; // this is to prevent animations from running twice when an inner
95699    // component does CD when a parent component instead has inserted it
95700
95701    if (this._cdRecurDepth == 0) {
95702      this._zone.runOutsideAngular(() => {
95703        this._scheduleCountTask();
95704
95705        this.engine.flush(this._microtaskId);
95706      });
95707    }
95708
95709    if (this.delegate.end) {
95710      this.delegate.end();
95711    }
95712  }
95713
95714  whenRenderingDone() {
95715    return this.engine.whenRenderingDone();
95716  }
95717
95718}
95719
95720AnimationRendererFactory.ɵfac = function AnimationRendererFactory_Factory(t) {
95721  return new (t || AnimationRendererFactory)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererFactory2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵAnimationEngine"]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone));
95722};
95723
95724AnimationRendererFactory.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
95725  token: AnimationRendererFactory,
95726  factory: AnimationRendererFactory.ɵfac
95727});
95728
95729(function () {
95730  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AnimationRendererFactory, [{
95731    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
95732  }], function () {
95733    return [{
95734      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererFactory2
95735    }, {
95736      type: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵAnimationEngine"]
95737    }, {
95738      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
95739    }];
95740  }, null);
95741})();
95742
95743class BaseAnimationRenderer {
95744  constructor(namespaceId, delegate, engine, _onDestroy) {
95745    this.namespaceId = namespaceId;
95746    this.delegate = delegate;
95747    this.engine = engine;
95748    this._onDestroy = _onDestroy;
95749    this.destroyNode = this.delegate.destroyNode ? n => delegate.destroyNode(n) : null;
95750  }
95751
95752  get data() {
95753    return this.delegate.data;
95754  }
95755
95756  destroy() {
95757    this.engine.destroy(this.namespaceId, this.delegate);
95758    this.delegate.destroy();
95759    this._onDestroy?.();
95760  }
95761
95762  createElement(name, namespace) {
95763    return this.delegate.createElement(name, namespace);
95764  }
95765
95766  createComment(value) {
95767    return this.delegate.createComment(value);
95768  }
95769
95770  createText(value) {
95771    return this.delegate.createText(value);
95772  }
95773
95774  appendChild(parent, newChild) {
95775    this.delegate.appendChild(parent, newChild);
95776    this.engine.onInsert(this.namespaceId, newChild, parent, false);
95777  }
95778
95779  insertBefore(parent, newChild, refChild, isMove = true) {
95780    this.delegate.insertBefore(parent, newChild, refChild); // If `isMove` true than we should animate this insert.
95781
95782    this.engine.onInsert(this.namespaceId, newChild, parent, isMove);
95783  }
95784
95785  removeChild(parent, oldChild, isHostElement) {
95786    this.engine.onRemove(this.namespaceId, oldChild, this.delegate, isHostElement);
95787  }
95788
95789  selectRootElement(selectorOrNode, preserveContent) {
95790    return this.delegate.selectRootElement(selectorOrNode, preserveContent);
95791  }
95792
95793  parentNode(node) {
95794    return this.delegate.parentNode(node);
95795  }
95796
95797  nextSibling(node) {
95798    return this.delegate.nextSibling(node);
95799  }
95800
95801  setAttribute(el, name, value, namespace) {
95802    this.delegate.setAttribute(el, name, value, namespace);
95803  }
95804
95805  removeAttribute(el, name, namespace) {
95806    this.delegate.removeAttribute(el, name, namespace);
95807  }
95808
95809  addClass(el, name) {
95810    this.delegate.addClass(el, name);
95811  }
95812
95813  removeClass(el, name) {
95814    this.delegate.removeClass(el, name);
95815  }
95816
95817  setStyle(el, style, value, flags) {
95818    this.delegate.setStyle(el, style, value, flags);
95819  }
95820
95821  removeStyle(el, style, flags) {
95822    this.delegate.removeStyle(el, style, flags);
95823  }
95824
95825  setProperty(el, name, value) {
95826    if (name.charAt(0) == ANIMATION_PREFIX && name == DISABLE_ANIMATIONS_FLAG) {
95827      this.disableAnimations(el, !!value);
95828    } else {
95829      this.delegate.setProperty(el, name, value);
95830    }
95831  }
95832
95833  setValue(node, value) {
95834    this.delegate.setValue(node, value);
95835  }
95836
95837  listen(target, eventName, callback) {
95838    return this.delegate.listen(target, eventName, callback);
95839  }
95840
95841  disableAnimations(element, value) {
95842    this.engine.disableAnimations(element, value);
95843  }
95844
95845}
95846
95847class AnimationRenderer extends BaseAnimationRenderer {
95848  constructor(factory, namespaceId, delegate, engine, onDestroy) {
95849    super(namespaceId, delegate, engine, onDestroy);
95850    this.factory = factory;
95851    this.namespaceId = namespaceId;
95852  }
95853
95854  setProperty(el, name, value) {
95855    if (name.charAt(0) == ANIMATION_PREFIX) {
95856      if (name.charAt(1) == '.' && name == DISABLE_ANIMATIONS_FLAG) {
95857        value = value === undefined ? true : !!value;
95858        this.disableAnimations(el, value);
95859      } else {
95860        this.engine.process(this.namespaceId, el, name.slice(1), value);
95861      }
95862    } else {
95863      this.delegate.setProperty(el, name, value);
95864    }
95865  }
95866
95867  listen(target, eventName, callback) {
95868    if (eventName.charAt(0) == ANIMATION_PREFIX) {
95869      const element = resolveElementFromTarget(target);
95870      let name = eventName.slice(1);
95871      let phase = ''; // @listener.phase is for trigger animation callbacks
95872      // @@listener is for animation builder callbacks
95873
95874      if (name.charAt(0) != ANIMATION_PREFIX) {
95875        [name, phase] = parseTriggerCallbackName(name);
95876      }
95877
95878      return this.engine.listen(this.namespaceId, element, name, phase, event => {
95879        const countId = event['_data'] || -1;
95880        this.factory.scheduleListenerCallback(countId, callback, event);
95881      });
95882    }
95883
95884    return this.delegate.listen(target, eventName, callback);
95885  }
95886
95887}
95888
95889function resolveElementFromTarget(target) {
95890  switch (target) {
95891    case 'body':
95892      return document.body;
95893
95894    case 'document':
95895      return document;
95896
95897    case 'window':
95898      return window;
95899
95900    default:
95901      return target;
95902  }
95903}
95904
95905function parseTriggerCallbackName(triggerName) {
95906  const dotIndex = triggerName.indexOf('.');
95907  const trigger = triggerName.substring(0, dotIndex);
95908  const phase = triggerName.slice(dotIndex + 1);
95909  return [trigger, phase];
95910}
95911/**
95912 * @license
95913 * Copyright Google LLC All Rights Reserved.
95914 *
95915 * Use of this source code is governed by an MIT-style license that can be
95916 * found in the LICENSE file at https://angular.io/license
95917 */
95918
95919
95920class InjectableAnimationEngine extends _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵAnimationEngine"] {
95921  // The `ApplicationRef` is injected here explicitly to force the dependency ordering.
95922  // Since the `ApplicationRef` should be created earlier before the `AnimationEngine`, they
95923  // both have `ngOnDestroy` hooks and `flush()` must be called after all views are destroyed.
95924  constructor(doc, driver, normalizer, appRef) {
95925    super(doc.body, driver, normalizer);
95926  }
95927
95928  ngOnDestroy() {
95929    this.flush();
95930  }
95931
95932}
95933
95934InjectableAnimationEngine.ɵfac = function InjectableAnimationEngine_Factory(t) {
95935  return new (t || InjectableAnimationEngine)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__.AnimationDriver), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵAnimationStyleNormalizer"]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ApplicationRef));
95936};
95937
95938InjectableAnimationEngine.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
95939  token: InjectableAnimationEngine,
95940  factory: InjectableAnimationEngine.ɵfac
95941});
95942
95943(function () {
95944  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](InjectableAnimationEngine, [{
95945    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
95946  }], function () {
95947    return [{
95948      type: undefined,
95949      decorators: [{
95950        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
95951        args: [_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT]
95952      }]
95953    }, {
95954      type: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__.AnimationDriver
95955    }, {
95956      type: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵAnimationStyleNormalizer"]
95957    }, {
95958      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ApplicationRef
95959    }];
95960  }, null);
95961})();
95962
95963function instantiateDefaultStyleNormalizer() {
95964  return new _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵWebAnimationsStyleNormalizer"]();
95965}
95966
95967function instantiateRendererFactory(renderer, engine, zone) {
95968  return new AnimationRendererFactory(renderer, engine, zone);
95969}
95970
95971const SHARED_ANIMATION_PROVIDERS = [{
95972  provide: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationBuilder,
95973  useClass: BrowserAnimationBuilder
95974}, {
95975  provide: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵAnimationStyleNormalizer"],
95976  useFactory: instantiateDefaultStyleNormalizer
95977}, {
95978  provide: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵAnimationEngine"],
95979  useClass: InjectableAnimationEngine
95980}, {
95981  provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererFactory2,
95982  useFactory: instantiateRendererFactory,
95983  deps: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_4__["ɵDomRendererFactory2"], _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵAnimationEngine"], _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone]
95984}];
95985/**
95986 * Separate providers from the actual module so that we can do a local modification in Google3 to
95987 * include them in the BrowserModule.
95988 */
95989
95990const BROWSER_ANIMATIONS_PROVIDERS = [{
95991  provide: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__.AnimationDriver,
95992  useFactory: () => new _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵWebAnimationsDriver"]()
95993}, {
95994  provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE,
95995  useValue: 'BrowserAnimations'
95996}, ...SHARED_ANIMATION_PROVIDERS];
95997/**
95998 * Separate providers from the actual module so that we can do a local modification in Google3 to
95999 * include them in the BrowserTestingModule.
96000 */
96001
96002const BROWSER_NOOP_ANIMATIONS_PROVIDERS = [{
96003  provide: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__.AnimationDriver,
96004  useClass: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_3__["ɵNoopAnimationDriver"]
96005}, {
96006  provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE,
96007  useValue: 'NoopAnimations'
96008}, ...SHARED_ANIMATION_PROVIDERS];
96009/**
96010 * @license
96011 * Copyright Google LLC All Rights Reserved.
96012 *
96013 * Use of this source code is governed by an MIT-style license that can be
96014 * found in the LICENSE file at https://angular.io/license
96015 */
96016
96017/**
96018 * Exports `BrowserModule` with additional [dependency-injection providers](guide/glossary#provider)
96019 * for use with animations. See [Animations](guide/animations).
96020 * @publicApi
96021 */
96022
96023class BrowserAnimationsModule {
96024  /**
96025   * Configures the module based on the specified object.
96026   *
96027   * @param config Object used to configure the behavior of the `BrowserAnimationsModule`.
96028   * @see `BrowserAnimationsModuleConfig`
96029   *
96030   * @usageNotes
96031   * When registering the `BrowserAnimationsModule`, you can use the `withConfig`
96032   * function as follows:
96033   * ```
96034   * @NgModule({
96035   *   imports: [BrowserAnimationsModule.withConfig(config)]
96036   * })
96037   * class MyNgModule {}
96038   * ```
96039   */
96040  static withConfig(config) {
96041    return {
96042      ngModule: BrowserAnimationsModule,
96043      providers: config.disableAnimations ? BROWSER_NOOP_ANIMATIONS_PROVIDERS : BROWSER_ANIMATIONS_PROVIDERS
96044    };
96045  }
96046
96047}
96048
96049BrowserAnimationsModule.ɵfac = function BrowserAnimationsModule_Factory(t) {
96050  return new (t || BrowserAnimationsModule)();
96051};
96052
96053BrowserAnimationsModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
96054  type: BrowserAnimationsModule,
96055  exports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_4__.BrowserModule]
96056});
96057BrowserAnimationsModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
96058  providers: BROWSER_ANIMATIONS_PROVIDERS,
96059  imports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_4__.BrowserModule]
96060});
96061
96062(function () {
96063  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BrowserAnimationsModule, [{
96064    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
96065    args: [{
96066      exports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_4__.BrowserModule],
96067      providers: BROWSER_ANIMATIONS_PROVIDERS
96068    }]
96069  }], null, null);
96070})();
96071/**
96072 * Returns the set of [dependency-injection providers](guide/glossary#provider)
96073 * to enable animations in an application. See [animations guide](guide/animations)
96074 * to learn more about animations in Angular.
96075 *
96076 * @usageNotes
96077 *
96078 * The function is useful when you want to enable animations in an application
96079 * bootstrapped using the `bootstrapApplication` function. In this scenario there
96080 * is no need to import the `BrowserAnimationsModule` NgModule at all, just add
96081 * providers returned by this function to the `providers` list as show below.
96082 *
96083 * ```typescript
96084 * bootstrapApplication(RootComponent, {
96085 *   providers: [
96086 *     provideAnimations()
96087 *   ]
96088 * });
96089 * ```
96090 *
96091 * @publicApi
96092 * @developerPreview
96093 */
96094
96095
96096function provideAnimations() {
96097  // Return a copy to prevent changes to the original array in case any in-place
96098  // alterations are performed to the `provideAnimations` call results in app code.
96099  return [...BROWSER_ANIMATIONS_PROVIDERS];
96100}
96101/**
96102 * A null player that must be imported to allow disabling of animations.
96103 * @publicApi
96104 */
96105
96106
96107class NoopAnimationsModule {}
96108
96109NoopAnimationsModule.ɵfac = function NoopAnimationsModule_Factory(t) {
96110  return new (t || NoopAnimationsModule)();
96111};
96112
96113NoopAnimationsModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
96114  type: NoopAnimationsModule,
96115  exports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_4__.BrowserModule]
96116});
96117NoopAnimationsModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
96118  providers: BROWSER_NOOP_ANIMATIONS_PROVIDERS,
96119  imports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_4__.BrowserModule]
96120});
96121
96122(function () {
96123  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NoopAnimationsModule, [{
96124    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
96125    args: [{
96126      exports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_4__.BrowserModule],
96127      providers: BROWSER_NOOP_ANIMATIONS_PROVIDERS
96128    }]
96129  }], null, null);
96130})();
96131/**
96132 * Returns the set of [dependency-injection providers](guide/glossary#provider)
96133 * to disable animations in an application. See [animations guide](guide/animations)
96134 * to learn more about animations in Angular.
96135 *
96136 * @usageNotes
96137 *
96138 * The function is useful when you want to bootstrap an application using
96139 * the `bootstrapApplication` function, but you need to disable animations
96140 * (for example, when running tests).
96141 *
96142 * ```typescript
96143 * bootstrapApplication(RootComponent, {
96144 *   providers: [
96145 *     provideNoopAnimations()
96146 *   ]
96147 * });
96148 * ```
96149 *
96150 * @publicApi
96151 * @developerPreview
96152 */
96153
96154
96155function provideNoopAnimations() {
96156  // Return a copy to prevent changes to the original array in case any in-place
96157  // alterations are performed to the `provideNoopAnimations` call results in app code.
96158  return [...BROWSER_NOOP_ANIMATIONS_PROVIDERS];
96159}
96160/**
96161 * @license
96162 * Copyright Google LLC All Rights Reserved.
96163 *
96164 * Use of this source code is governed by an MIT-style license that can be
96165 * found in the LICENSE file at https://angular.io/license
96166 */
96167
96168/**
96169 * @license
96170 * Copyright Google LLC All Rights Reserved.
96171 *
96172 * Use of this source code is governed by an MIT-style license that can be
96173 * found in the LICENSE file at https://angular.io/license
96174 */
96175
96176/**
96177 * @license
96178 * Copyright Google LLC All Rights Reserved.
96179 *
96180 * Use of this source code is governed by an MIT-style license that can be
96181 * found in the LICENSE file at https://angular.io/license
96182 */
96183
96184/**
96185 * @license
96186 * Copyright Google LLC All Rights Reserved.
96187 *
96188 * Use of this source code is governed by an MIT-style license that can be
96189 * found in the LICENSE file at https://angular.io/license
96190 */
96191
96192/**
96193 * Generated bundle index. Do not edit.
96194 */
96195
96196
96197
96198
96199/***/ }),
96200
96201/***/ 4497:
96202/*!******************************************************************************!*\
96203  !*** ./node_modules/@angular/platform-browser/fesm2020/platform-browser.mjs ***!
96204  \******************************************************************************/
96205/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
96206
96207__webpack_require__.r(__webpack_exports__);
96208/* harmony export */ __webpack_require__.d(__webpack_exports__, {
96209/* harmony export */   "BrowserModule": () => (/* binding */ BrowserModule),
96210/* harmony export */   "BrowserTransferStateModule": () => (/* binding */ BrowserTransferStateModule),
96211/* harmony export */   "By": () => (/* binding */ By),
96212/* harmony export */   "DomSanitizer": () => (/* binding */ DomSanitizer),
96213/* harmony export */   "EVENT_MANAGER_PLUGINS": () => (/* binding */ EVENT_MANAGER_PLUGINS),
96214/* harmony export */   "EventManager": () => (/* binding */ EventManager),
96215/* harmony export */   "HAMMER_GESTURE_CONFIG": () => (/* binding */ HAMMER_GESTURE_CONFIG),
96216/* harmony export */   "HAMMER_LOADER": () => (/* binding */ HAMMER_LOADER),
96217/* harmony export */   "HammerGestureConfig": () => (/* binding */ HammerGestureConfig),
96218/* harmony export */   "HammerModule": () => (/* binding */ HammerModule),
96219/* harmony export */   "Meta": () => (/* binding */ Meta),
96220/* harmony export */   "Title": () => (/* binding */ Title),
96221/* harmony export */   "TransferState": () => (/* binding */ TransferState),
96222/* harmony export */   "VERSION": () => (/* binding */ VERSION),
96223/* harmony export */   "bootstrapApplication": () => (/* binding */ bootstrapApplication),
96224/* harmony export */   "createApplication": () => (/* binding */ createApplication),
96225/* harmony export */   "disableDebugTools": () => (/* binding */ disableDebugTools),
96226/* harmony export */   "enableDebugTools": () => (/* binding */ enableDebugTools),
96227/* harmony export */   "makeStateKey": () => (/* binding */ makeStateKey),
96228/* harmony export */   "platformBrowser": () => (/* binding */ platformBrowser),
96229/* harmony export */   "provideProtractorTestingSupport": () => (/* binding */ provideProtractorTestingSupport),
96230/* harmony export */   "ɵBrowserDomAdapter": () => (/* binding */ BrowserDomAdapter),
96231/* harmony export */   "ɵBrowserGetTestability": () => (/* binding */ BrowserGetTestability),
96232/* harmony export */   "ɵDomEventsPlugin": () => (/* binding */ DomEventsPlugin),
96233/* harmony export */   "ɵDomRendererFactory2": () => (/* binding */ DomRendererFactory2),
96234/* harmony export */   "ɵDomSanitizerImpl": () => (/* binding */ DomSanitizerImpl),
96235/* harmony export */   "ɵDomSharedStylesHost": () => (/* binding */ DomSharedStylesHost),
96236/* harmony export */   "ɵHammerGesturesPlugin": () => (/* binding */ HammerGesturesPlugin),
96237/* harmony export */   "ɵINTERNAL_BROWSER_PLATFORM_PROVIDERS": () => (/* binding */ INTERNAL_BROWSER_PLATFORM_PROVIDERS),
96238/* harmony export */   "ɵKeyEventsPlugin": () => (/* binding */ KeyEventsPlugin),
96239/* harmony export */   "ɵNAMESPACE_URIS": () => (/* binding */ NAMESPACE_URIS),
96240/* harmony export */   "ɵSharedStylesHost": () => (/* binding */ SharedStylesHost),
96241/* harmony export */   "ɵTRANSITION_ID": () => (/* binding */ TRANSITION_ID),
96242/* harmony export */   "ɵescapeHtml": () => (/* binding */ escapeHtml),
96243/* harmony export */   "ɵflattenStyles": () => (/* binding */ flattenStyles),
96244/* harmony export */   "ɵgetDOM": () => (/* reexport safe */ _angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"]),
96245/* harmony export */   "ɵinitDomAdapter": () => (/* binding */ initDomAdapter),
96246/* harmony export */   "ɵshimContentAttribute": () => (/* binding */ shimContentAttribute),
96247/* harmony export */   "ɵshimHostAttribute": () => (/* binding */ shimHostAttribute)
96248/* harmony export */ });
96249/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/common */ 4666);
96250/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 2560);
96251/**
96252 * @license Angular v14.2.10
96253 * (c) 2010-2022 Google LLC. https://angular.io/
96254 * License: MIT
96255 */
96256
96257
96258
96259
96260/**
96261 * @license
96262 * Copyright Google LLC All Rights Reserved.
96263 *
96264 * Use of this source code is governed by an MIT-style license that can be
96265 * found in the LICENSE file at https://angular.io/license
96266 */
96267
96268/**
96269 * Provides DOM operations in any browser environment.
96270 *
96271 * @security Tread carefully! Interacting with the DOM directly is dangerous and
96272 * can introduce XSS risks.
96273 */
96274
96275class GenericBrowserDomAdapter extends _angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵDomAdapter"] {
96276  constructor() {
96277    super(...arguments);
96278    this.supportsDOMEvents = true;
96279  }
96280
96281}
96282/**
96283 * @license
96284 * Copyright Google LLC All Rights Reserved.
96285 *
96286 * Use of this source code is governed by an MIT-style license that can be
96287 * found in the LICENSE file at https://angular.io/license
96288 */
96289
96290/**
96291 * A `DomAdapter` powered by full browser DOM APIs.
96292 *
96293 * @security Tread carefully! Interacting with the DOM directly is dangerous and
96294 * can introduce XSS risks.
96295 */
96296
96297/* tslint:disable:requireParameterType no-console */
96298
96299
96300class BrowserDomAdapter extends GenericBrowserDomAdapter {
96301  static makeCurrent() {
96302    (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵsetRootDomAdapter"])(new BrowserDomAdapter());
96303  }
96304
96305  onAndCancel(el, evt, listener) {
96306    el.addEventListener(evt, listener, false); // Needed to follow Dart's subscription semantic, until fix of
96307    // https://code.google.com/p/dart/issues/detail?id=17406
96308
96309    return () => {
96310      el.removeEventListener(evt, listener, false);
96311    };
96312  }
96313
96314  dispatchEvent(el, evt) {
96315    el.dispatchEvent(evt);
96316  }
96317
96318  remove(node) {
96319    if (node.parentNode) {
96320      node.parentNode.removeChild(node);
96321    }
96322  }
96323
96324  createElement(tagName, doc) {
96325    doc = doc || this.getDefaultDocument();
96326    return doc.createElement(tagName);
96327  }
96328
96329  createHtmlDocument() {
96330    return document.implementation.createHTMLDocument('fakeTitle');
96331  }
96332
96333  getDefaultDocument() {
96334    return document;
96335  }
96336
96337  isElementNode(node) {
96338    return node.nodeType === Node.ELEMENT_NODE;
96339  }
96340
96341  isShadowRoot(node) {
96342    return node instanceof DocumentFragment;
96343  }
96344  /** @deprecated No longer being used in Ivy code. To be removed in version 14. */
96345
96346
96347  getGlobalEventTarget(doc, target) {
96348    if (target === 'window') {
96349      return window;
96350    }
96351
96352    if (target === 'document') {
96353      return doc;
96354    }
96355
96356    if (target === 'body') {
96357      return doc.body;
96358    }
96359
96360    return null;
96361  }
96362
96363  getBaseHref(doc) {
96364    const href = getBaseElementHref();
96365    return href == null ? null : relativePath(href);
96366  }
96367
96368  resetBaseElement() {
96369    baseElement = null;
96370  }
96371
96372  getUserAgent() {
96373    return window.navigator.userAgent;
96374  }
96375
96376  getCookie(name) {
96377    return (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵparseCookieValue"])(document.cookie, name);
96378  }
96379
96380}
96381
96382let baseElement = null;
96383
96384function getBaseElementHref() {
96385  baseElement = baseElement || document.querySelector('base');
96386  return baseElement ? baseElement.getAttribute('href') : null;
96387} // based on urlUtils.js in AngularJS 1
96388
96389
96390let urlParsingNode;
96391
96392function relativePath(url) {
96393  urlParsingNode = urlParsingNode || document.createElement('a');
96394  urlParsingNode.setAttribute('href', url);
96395  const pathName = urlParsingNode.pathname;
96396  return pathName.charAt(0) === '/' ? pathName : `/${pathName}`;
96397}
96398/**
96399 * @license
96400 * Copyright Google LLC All Rights Reserved.
96401 *
96402 * Use of this source code is governed by an MIT-style license that can be
96403 * found in the LICENSE file at https://angular.io/license
96404 */
96405
96406/**
96407 * An id that identifies a particular application being bootstrapped, that should
96408 * match across the client/server boundary.
96409 */
96410
96411
96412const TRANSITION_ID = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('TRANSITION_ID');
96413
96414function appInitializerFactory(transitionId, document, injector) {
96415  return () => {
96416    // Wait for all application initializers to be completed before removing the styles set by
96417    // the server.
96418    injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_1__.ApplicationInitStatus).donePromise.then(() => {
96419      const dom = (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])();
96420      const styles = document.querySelectorAll(`style[ng-transition="${transitionId}"]`);
96421
96422      for (let i = 0; i < styles.length; i++) {
96423        dom.remove(styles[i]);
96424      }
96425    });
96426  };
96427}
96428
96429const SERVER_TRANSITION_PROVIDERS = [{
96430  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_INITIALIZER,
96431  useFactory: appInitializerFactory,
96432  deps: [TRANSITION_ID, _angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT, _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injector],
96433  multi: true
96434}];
96435/**
96436 * @license
96437 * Copyright Google LLC All Rights Reserved.
96438 *
96439 * Use of this source code is governed by an MIT-style license that can be
96440 * found in the LICENSE file at https://angular.io/license
96441 */
96442
96443class BrowserGetTestability {
96444  addToWindow(registry) {
96445    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].getAngularTestability = (elem, findInAncestors = true) => {
96446      const testability = registry.findTestabilityInTree(elem, findInAncestors);
96447
96448      if (testability == null) {
96449        throw new Error('Could not find testability for element.');
96450      }
96451
96452      return testability;
96453    };
96454
96455    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].getAllAngularTestabilities = () => registry.getAllTestabilities();
96456
96457    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].getAllAngularRootElements = () => registry.getAllRootElements();
96458
96459    const whenAllStable = (callback
96460    /** TODO #9100 */
96461    ) => {
96462      const testabilities = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].getAllAngularTestabilities();
96463      let count = testabilities.length;
96464      let didWork = false;
96465
96466      const decrement = function (didWork_
96467      /** TODO #9100 */
96468      ) {
96469        didWork = didWork || didWork_;
96470        count--;
96471
96472        if (count == 0) {
96473          callback(didWork);
96474        }
96475      };
96476
96477      testabilities.forEach(function (testability
96478      /** TODO #9100 */
96479      ) {
96480        testability.whenStable(decrement);
96481      });
96482    };
96483
96484    if (!_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].frameworkStabilizers) {
96485      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].frameworkStabilizers = [];
96486    }
96487
96488    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].frameworkStabilizers.push(whenAllStable);
96489  }
96490
96491  findTestabilityInTree(registry, elem, findInAncestors) {
96492    if (elem == null) {
96493      return null;
96494    }
96495
96496    const t = registry.getTestability(elem);
96497
96498    if (t != null) {
96499      return t;
96500    } else if (!findInAncestors) {
96501      return null;
96502    }
96503
96504    if ((0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])().isShadowRoot(elem)) {
96505      return this.findTestabilityInTree(registry, elem.host, true);
96506    }
96507
96508    return this.findTestabilityInTree(registry, elem.parentElement, true);
96509  }
96510
96511}
96512/**
96513 * A factory for `HttpXhrBackend` that uses the `XMLHttpRequest` browser API.
96514 */
96515
96516
96517class BrowserXhr {
96518  build() {
96519    return new XMLHttpRequest();
96520  }
96521
96522}
96523
96524BrowserXhr.ɵfac = function BrowserXhr_Factory(t) {
96525  return new (t || BrowserXhr)();
96526};
96527
96528BrowserXhr.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
96529  token: BrowserXhr,
96530  factory: BrowserXhr.ɵfac
96531});
96532
96533(function () {
96534  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](BrowserXhr, [{
96535    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
96536  }], null, null);
96537})();
96538/**
96539 * @license
96540 * Copyright Google LLC All Rights Reserved.
96541 *
96542 * Use of this source code is governed by an MIT-style license that can be
96543 * found in the LICENSE file at https://angular.io/license
96544 */
96545
96546/**
96547 * The injection token for the event-manager plug-in service.
96548 *
96549 * @publicApi
96550 */
96551
96552
96553const EVENT_MANAGER_PLUGINS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('EventManagerPlugins');
96554/**
96555 * An injectable service that provides event management for Angular
96556 * through a browser plug-in.
96557 *
96558 * @publicApi
96559 */
96560
96561class EventManager {
96562  /**
96563   * Initializes an instance of the event-manager service.
96564   */
96565  constructor(plugins, _zone) {
96566    this._zone = _zone;
96567    this._eventNameToPlugin = new Map();
96568    plugins.forEach(p => p.manager = this);
96569    this._plugins = plugins.slice().reverse();
96570  }
96571  /**
96572   * Registers a handler for a specific element and event.
96573   *
96574   * @param element The HTML element to receive event notifications.
96575   * @param eventName The name of the event to listen for.
96576   * @param handler A function to call when the notification occurs. Receives the
96577   * event object as an argument.
96578   * @returns  A callback function that can be used to remove the handler.
96579   */
96580
96581
96582  addEventListener(element, eventName, handler) {
96583    const plugin = this._findPluginFor(eventName);
96584
96585    return plugin.addEventListener(element, eventName, handler);
96586  }
96587  /**
96588   * Registers a global handler for an event in a target view.
96589   *
96590   * @param target A target for global event notifications. One of "window", "document", or "body".
96591   * @param eventName The name of the event to listen for.
96592   * @param handler A function to call when the notification occurs. Receives the
96593   * event object as an argument.
96594   * @returns A callback function that can be used to remove the handler.
96595   * @deprecated No longer being used in Ivy code. To be removed in version 14.
96596   */
96597
96598
96599  addGlobalEventListener(target, eventName, handler) {
96600    const plugin = this._findPluginFor(eventName);
96601
96602    return plugin.addGlobalEventListener(target, eventName, handler);
96603  }
96604  /**
96605   * Retrieves the compilation zone in which event listeners are registered.
96606   */
96607
96608
96609  getZone() {
96610    return this._zone;
96611  }
96612  /** @internal */
96613
96614
96615  _findPluginFor(eventName) {
96616    const plugin = this._eventNameToPlugin.get(eventName);
96617
96618    if (plugin) {
96619      return plugin;
96620    }
96621
96622    const plugins = this._plugins;
96623
96624    for (let i = 0; i < plugins.length; i++) {
96625      const plugin = plugins[i];
96626
96627      if (plugin.supports(eventName)) {
96628        this._eventNameToPlugin.set(eventName, plugin);
96629
96630        return plugin;
96631      }
96632    }
96633
96634    throw new Error(`No event manager plugin found for event ${eventName}`);
96635  }
96636
96637}
96638
96639EventManager.ɵfac = function EventManager_Factory(t) {
96640  return new (t || EventManager)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](EVENT_MANAGER_PLUGINS), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone));
96641};
96642
96643EventManager.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
96644  token: EventManager,
96645  factory: EventManager.ɵfac
96646});
96647
96648(function () {
96649  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](EventManager, [{
96650    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
96651  }], function () {
96652    return [{
96653      type: undefined,
96654      decorators: [{
96655        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
96656        args: [EVENT_MANAGER_PLUGINS]
96657      }]
96658    }, {
96659      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
96660    }];
96661  }, null);
96662})();
96663
96664class EventManagerPlugin {
96665  constructor(_doc) {
96666    this._doc = _doc;
96667  }
96668
96669  addGlobalEventListener(element, eventName, handler) {
96670    const target = (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])().getGlobalEventTarget(this._doc, element);
96671
96672    if (!target) {
96673      throw new Error(`Unsupported event target ${target} for event ${eventName}`);
96674    }
96675
96676    return this.addEventListener(target, eventName, handler);
96677  }
96678
96679}
96680/**
96681 * @license
96682 * Copyright Google LLC All Rights Reserved.
96683 *
96684 * Use of this source code is governed by an MIT-style license that can be
96685 * found in the LICENSE file at https://angular.io/license
96686 */
96687
96688
96689class SharedStylesHost {
96690  constructor() {
96691    /** @internal */
96692    this._stylesSet = new Set();
96693  }
96694
96695  addStyles(styles) {
96696    const additions = new Set();
96697    styles.forEach(style => {
96698      if (!this._stylesSet.has(style)) {
96699        this._stylesSet.add(style);
96700
96701        additions.add(style);
96702      }
96703    });
96704    this.onStylesAdded(additions);
96705  }
96706
96707  onStylesAdded(additions) {}
96708
96709  getAllStyles() {
96710    return Array.from(this._stylesSet);
96711  }
96712
96713}
96714
96715SharedStylesHost.ɵfac = function SharedStylesHost_Factory(t) {
96716  return new (t || SharedStylesHost)();
96717};
96718
96719SharedStylesHost.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
96720  token: SharedStylesHost,
96721  factory: SharedStylesHost.ɵfac
96722});
96723
96724(function () {
96725  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](SharedStylesHost, [{
96726    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
96727  }], null, null);
96728})();
96729
96730class DomSharedStylesHost extends SharedStylesHost {
96731  constructor(_doc) {
96732    super();
96733    this._doc = _doc; // Maps all registered host nodes to a list of style nodes that have been added to the host node.
96734
96735    this._hostNodes = new Map();
96736
96737    this._hostNodes.set(_doc.head, []);
96738  }
96739
96740  _addStylesToHost(styles, host, styleNodes) {
96741    styles.forEach(style => {
96742      const styleEl = this._doc.createElement('style');
96743
96744      styleEl.textContent = style;
96745      styleNodes.push(host.appendChild(styleEl));
96746    });
96747  }
96748
96749  addHost(hostNode) {
96750    const styleNodes = [];
96751
96752    this._addStylesToHost(this._stylesSet, hostNode, styleNodes);
96753
96754    this._hostNodes.set(hostNode, styleNodes);
96755  }
96756
96757  removeHost(hostNode) {
96758    const styleNodes = this._hostNodes.get(hostNode);
96759
96760    if (styleNodes) {
96761      styleNodes.forEach(removeStyle);
96762    }
96763
96764    this._hostNodes.delete(hostNode);
96765  }
96766
96767  onStylesAdded(additions) {
96768    this._hostNodes.forEach((styleNodes, hostNode) => {
96769      this._addStylesToHost(additions, hostNode, styleNodes);
96770    });
96771  }
96772
96773  ngOnDestroy() {
96774    this._hostNodes.forEach(styleNodes => styleNodes.forEach(removeStyle));
96775  }
96776
96777}
96778
96779DomSharedStylesHost.ɵfac = function DomSharedStylesHost_Factory(t) {
96780  return new (t || DomSharedStylesHost)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
96781};
96782
96783DomSharedStylesHost.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
96784  token: DomSharedStylesHost,
96785  factory: DomSharedStylesHost.ɵfac
96786});
96787
96788(function () {
96789  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DomSharedStylesHost, [{
96790    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
96791  }], function () {
96792    return [{
96793      type: undefined,
96794      decorators: [{
96795        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
96796        args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
96797      }]
96798    }];
96799  }, null);
96800})();
96801
96802function removeStyle(styleNode) {
96803  (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])().remove(styleNode);
96804}
96805/**
96806 * @license
96807 * Copyright Google LLC All Rights Reserved.
96808 *
96809 * Use of this source code is governed by an MIT-style license that can be
96810 * found in the LICENSE file at https://angular.io/license
96811 */
96812
96813
96814const NAMESPACE_URIS = {
96815  'svg': 'http://www.w3.org/2000/svg',
96816  'xhtml': 'http://www.w3.org/1999/xhtml',
96817  'xlink': 'http://www.w3.org/1999/xlink',
96818  'xml': 'http://www.w3.org/XML/1998/namespace',
96819  'xmlns': 'http://www.w3.org/2000/xmlns/',
96820  'math': 'http://www.w3.org/1998/MathML/'
96821};
96822const COMPONENT_REGEX = /%COMP%/g;
96823const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
96824const COMPONENT_VARIABLE = '%COMP%';
96825const HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;
96826const CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;
96827
96828function shimContentAttribute(componentShortId) {
96829  return CONTENT_ATTR.replace(COMPONENT_REGEX, componentShortId);
96830}
96831
96832function shimHostAttribute(componentShortId) {
96833  return HOST_ATTR.replace(COMPONENT_REGEX, componentShortId);
96834}
96835
96836function flattenStyles(compId, styles, target) {
96837  for (let i = 0; i < styles.length; i++) {
96838    let style = styles[i];
96839
96840    if (Array.isArray(style)) {
96841      flattenStyles(compId, style, target);
96842    } else {
96843      style = style.replace(COMPONENT_REGEX, compId);
96844      target.push(style);
96845    }
96846  }
96847
96848  return target;
96849}
96850
96851function decoratePreventDefault(eventHandler) {
96852  // `DebugNode.triggerEventHandler` needs to know if the listener was created with
96853  // decoratePreventDefault or is a listener added outside the Angular context so it can handle the
96854  // two differently. In the first case, the special '__ngUnwrap__' token is passed to the unwrap
96855  // the listener (see below).
96856  return event => {
96857    // Ivy uses '__ngUnwrap__' as a special token that allows us to unwrap the function
96858    // so that it can be invoked programmatically by `DebugNode.triggerEventHandler`. The debug_node
96859    // can inspect the listener toString contents for the existence of this special token. Because
96860    // the token is a string literal, it is ensured to not be modified by compiled code.
96861    if (event === '__ngUnwrap__') {
96862      return eventHandler;
96863    }
96864
96865    const allowDefaultBehavior = eventHandler(event);
96866
96867    if (allowDefaultBehavior === false) {
96868      // TODO(tbosch): move preventDefault into event plugins...
96869      event.preventDefault();
96870      event.returnValue = false;
96871    }
96872
96873    return undefined;
96874  };
96875}
96876
96877let hasLoggedNativeEncapsulationWarning = false;
96878
96879class DomRendererFactory2 {
96880  constructor(eventManager, sharedStylesHost, appId) {
96881    this.eventManager = eventManager;
96882    this.sharedStylesHost = sharedStylesHost;
96883    this.appId = appId;
96884    this.rendererByCompId = new Map();
96885    this.defaultRenderer = new DefaultDomRenderer2(eventManager);
96886  }
96887
96888  createRenderer(element, type) {
96889    if (!element || !type) {
96890      return this.defaultRenderer;
96891    }
96892
96893    switch (type.encapsulation) {
96894      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.Emulated:
96895        {
96896          let renderer = this.rendererByCompId.get(type.id);
96897
96898          if (!renderer) {
96899            renderer = new EmulatedEncapsulationDomRenderer2(this.eventManager, this.sharedStylesHost, type, this.appId);
96900            this.rendererByCompId.set(type.id, renderer);
96901          }
96902
96903          renderer.applyToHost(element);
96904          return renderer;
96905        }
96906      // @ts-ignore TODO: Remove as part of FW-2290. TS complains about us dealing with an enum
96907      // value that is not known (but previously was the value for ViewEncapsulation.Native)
96908
96909      case 1:
96910      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.ShadowDom:
96911        // TODO(FW-2290): remove the `case 1:` fallback logic and the warning in v12.
96912        if ((typeof ngDevMode === 'undefined' || ngDevMode) && // @ts-ignore TODO: Remove as part of FW-2290. TS complains about us dealing with an
96913        // enum value that is not known (but previously was the value for
96914        // ViewEncapsulation.Native)
96915        !hasLoggedNativeEncapsulationWarning && type.encapsulation === 1) {
96916          hasLoggedNativeEncapsulationWarning = true;
96917          console.warn('ViewEncapsulation.Native is no longer supported. Falling back to ViewEncapsulation.ShadowDom. The fallback will be removed in v12.');
96918        }
96919
96920        return new ShadowDomRenderer(this.eventManager, this.sharedStylesHost, element, type);
96921
96922      default:
96923        {
96924          if (!this.rendererByCompId.has(type.id)) {
96925            const styles = flattenStyles(type.id, type.styles, []);
96926            this.sharedStylesHost.addStyles(styles);
96927            this.rendererByCompId.set(type.id, this.defaultRenderer);
96928          }
96929
96930          return this.defaultRenderer;
96931        }
96932    }
96933  }
96934
96935  begin() {}
96936
96937  end() {}
96938
96939}
96939
96940
96941DomRendererFactory2.ɵfac = function DomRendererFactory2_Factory(t) {
96942  return new (t || DomRendererFactory2)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](EventManager), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](DomSharedStylesHost), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID));
96943};
96944
96945DomRendererFactory2.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
96946  token: DomRendererFactory2,
96947  factory: DomRendererFactory2.ɵfac
96948});
96949
96950(function () {
96951  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DomRendererFactory2, [{
96952    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
96953  }], function () {
96954    return [{
96955      type: EventManager
96956    }, {
96957      type: DomSharedStylesHost
96958    }, {
96959      type: undefined,
96960      decorators: [{
96961        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
96962        args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID]
96963      }]
96964    }];
96965  }, null);
96966})();
96967
96968class DefaultDomRenderer2 {
96969  constructor(eventManager) {
96970    this.eventManager = eventManager;
96971    this.data = Object.create(null);
96972    this.destroyNode = null;
96973  }
96974
96975  destroy() {}
96976
96977  createElement(name, namespace) {
96978    if (namespace) {
96979      // TODO: `|| namespace` was added in
96980      // https://github.com/angular/angular/commit/2b9cc8503d48173492c29f5a271b61126104fbdb to
96981      // support how Ivy passed around the namespace URI rather than short name at the time. It did
96982      // not, however extend the support to other parts of the system (setAttribute, setAttribute,
96983      // and the ServerRenderer). We should decide what exactly the semantics for dealing with
96984      // namespaces should be and make it consistent.
96985      // Related issues:
96986      // https://github.com/angular/angular/issues/44028
96987      // https://github.com/angular/angular/issues/44883
96988      return document.createElementNS(NAMESPACE_URIS[namespace] || namespace, name);
96989    }
96990
96991    return document.createElement(name);
96992  }
96993
96994  createComment(value) {
96995    return document.createComment(value);
96996  }
96997
96998  createText(value) {
96999    return document.createTextNode(value);
97000  }
97001
97002  appendChild(parent, newChild) {
97003    const targetParent = isTemplateNode(parent) ? parent.content : parent;
97004    targetParent.appendChild(newChild);
97005  }
97006
97007  insertBefore(parent, newChild, refChild) {
97008    if (parent) {
97009      const targetParent = isTemplateNode(parent) ? parent.content : parent;
97010      targetParent.insertBefore(newChild, refChild);
97011    }
97012  }
97013
97014  removeChild(parent, oldChild) {
97015    if (parent) {
97016      parent.removeChild(oldChild);
97017    }
97018  }
97019
97020  selectRootElement(selectorOrNode, preserveContent) {
97021    let el = typeof selectorOrNode === 'string' ? document.querySelector(selectorOrNode) : selectorOrNode;
97022
97023    if (!el) {
97024      throw new Error(`The selector "${selectorOrNode}" did not match any elements`);
97025    }
97026
97027    if (!preserveContent) {
97028      el.textContent = '';
97029    }
97030
97031    return el;
97032  }
97033
97034  parentNode(node) {
97035    return node.parentNode;
97036  }
97037
97038  nextSibling(node) {
97039    return node.nextSibling;
97040  }
97041
97042  setAttribute(el, name, value, namespace) {
97043    if (namespace) {
97044      name = namespace + ':' + name;
97045      const namespaceUri = NAMESPACE_URIS[namespace];
97046
97047      if (namespaceUri) {
97048        el.setAttributeNS(namespaceUri, name, value);
97049      } else {
97050        el.setAttribute(name, value);
97051      }
97052    } else {
97053      el.setAttribute(name, value);
97054    }
97055  }
97056
97057  removeAttribute(el, name, namespace) {
97058    if (namespace) {
97059      const namespaceUri = NAMESPACE_URIS[namespace];
97060
97061      if (namespaceUri) {
97062        el.removeAttributeNS(namespaceUri, name);
97063      } else {
97064        el.removeAttribute(`${namespace}:${name}`);
97065      }
97066    } else {
97067      el.removeAttribute(name);
97068    }
97069  }
97070
97071  addClass(el, name) {
97072    el.classList.add(name);
97073  }
97074
97075  removeClass(el, name) {
97076    el.classList.remove(name);
97077  }
97078
97079  setStyle(el, style, value, flags) {
97080    if (flags & (_angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererStyleFlags2.DashCase | _angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererStyleFlags2.Important)) {
97081      el.style.setProperty(style, value, flags & _angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererStyleFlags2.Important ? 'important' : '');
97082    } else {
97083      el.style[style] = value;
97084    }
97085  }
97086
97087  removeStyle(el, style, flags) {
97088    if (flags & _angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererStyleFlags2.DashCase) {
97089      el.style.removeProperty(style);
97090    } else {
97091      // IE requires '' instead of null
97092      // see https://github.com/angular/angular/issues/7916
97093      el.style[style] = '';
97094    }
97095  }
97096
97097  setProperty(el, name, value) {
97098    NG_DEV_MODE$1 && checkNoSyntheticProp(name, 'property');
97099    el[name] = value;
97100  }
97101
97102  setValue(node, value) {
97103    node.nodeValue = value;
97104  }
97105
97106  listen(target, event, callback) {
97107    NG_DEV_MODE$1 && checkNoSyntheticProp(event, 'listener');
97108
97109    if (typeof target === 'string') {
97110      return this.eventManager.addGlobalEventListener(target, event, decoratePreventDefault(callback));
97111    }
97112
97113    return this.eventManager.addEventListener(target, event, decoratePreventDefault(callback));
97114  }
97115
97116}
97117
97118const AT_CHARCODE = (() => '@'.charCodeAt(0))();
97119
97120function checkNoSyntheticProp(name, nameKind) {
97121  if (name.charCodeAt(0) === AT_CHARCODE) {
97122    throw new Error(`Unexpected synthetic ${nameKind} ${name} found. Please make sure that:
97123  - Either \`BrowserAnimationsModule\` or \`NoopAnimationsModule\` are imported in your application.
97124  - 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).`);
97125  }
97126}
97127
97128function isTemplateNode(node) {
97129  return node.tagName === 'TEMPLATE' && node.content !== undefined;
97130}
97131
97132class EmulatedEncapsulationDomRenderer2 extends DefaultDomRenderer2 {
97133  constructor(eventManager, sharedStylesHost, component, appId) {
97134    super(eventManager);
97135    this.component = component;
97136    const styles = flattenStyles(appId + '-' + component.id, component.styles, []);
97137    sharedStylesHost.addStyles(styles);
97138    this.contentAttr = shimContentAttribute(appId + '-' + component.id);
97139    this.hostAttr = shimHostAttribute(appId + '-' + component.id);
97140  }
97141
97142  applyToHost(element) {
97143    super.setAttribute(element, this.hostAttr, '');
97144  }
97145
97146  createElement(parent, name) {
97147    const el = super.createElement(parent, name);
97148    super.setAttribute(el, this.contentAttr, '');
97149    return el;
97150  }
97151
97152}
97153
97154class ShadowDomRenderer extends DefaultDomRenderer2 {
97155  constructor(eventManager, sharedStylesHost, hostEl, component) {
97156    super(eventManager);
97157    this.sharedStylesHost = sharedStylesHost;
97158    this.hostEl = hostEl;
97159    this.shadowRoot = hostEl.attachShadow({
97160      mode: 'open'
97161    });
97162    this.sharedStylesHost.addHost(this.shadowRoot);
97163    const styles = flattenStyles(component.id, component.styles, []);
97164
97165    for (let i = 0; i < styles.length; i++) {
97166      const styleEl = document.createElement('style');
97167      styleEl.textContent = styles[i];
97168      this.shadowRoot.appendChild(styleEl);
97169    }
97170  }
97171
97172  nodeOrShadowRoot(node) {
97173    return node === this.hostEl ? this.shadowRoot : node;
97174  }
97175
97176  destroy() {
97177    this.sharedStylesHost.removeHost(this.shadowRoot);
97178  }
97179
97180  appendChild(parent, newChild) {
97181    return super.appendChild(this.nodeOrShadowRoot(parent), newChild);
97182  }
97183
97184  insertBefore(parent, newChild, refChild) {
97185    return super.insertBefore(this.nodeOrShadowRoot(parent), newChild, refChild);
97186  }
97187
97188  removeChild(parent, oldChild) {
97189    return super.removeChild(this.nodeOrShadowRoot(parent), oldChild);
97190  }
97191
97192  parentNode(node) {
97193    return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(node)));
97194  }
97195
97196}
97197/**
97198 * @license
97199 * Copyright Google LLC All Rights Reserved.
97200 *
97201 * Use of this source code is governed by an MIT-style license that can be
97202 * found in the LICENSE file at https://angular.io/license
97203 */
97204
97205
97206class DomEventsPlugin extends EventManagerPlugin {
97207  constructor(doc) {
97208    super(doc);
97209  } // This plugin should come last in the list of plugins, because it accepts all
97210  // events.
97211
97212
97213  supports(eventName) {
97214    return true;
97215  }
97216
97217  addEventListener(element, eventName, handler) {
97218    element.addEventListener(eventName, handler, false);
97219    return () => this.removeEventListener(element, eventName, handler);
97220  }
97221
97222  removeEventListener(target, eventName, callback) {
97223    return target.removeEventListener(eventName, callback);
97224  }
97225
97226}
97227
97228DomEventsPlugin.ɵfac = function DomEventsPlugin_Factory(t) {
97229  return new (t || DomEventsPlugin)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
97230};
97231
97232DomEventsPlugin.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
97233  token: DomEventsPlugin,
97234  factory: DomEventsPlugin.ɵfac
97235});
97236
97237(function () {
97238  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DomEventsPlugin, [{
97239    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
97240  }], function () {
97241    return [{
97242      type: undefined,
97243      decorators: [{
97244        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
97245        args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
97246      }]
97247    }];
97248  }, null);
97249})();
97250/**
97251 * @license
97252 * Copyright Google LLC All Rights Reserved.
97253 *
97254 * Use of this source code is governed by an MIT-style license that can be
97255 * found in the LICENSE file at https://angular.io/license
97256 */
97257
97258/**
97259 * Defines supported modifiers for key events.
97260 */
97261
97262
97263const MODIFIER_KEYS = ['alt', 'control', 'meta', 'shift']; // The following values are here for cross-browser compatibility and to match the W3C standard
97264// cf https://www.w3.org/TR/DOM-Level-3-Events-key/
97265
97266const _keyMap = {
97267  '\b': 'Backspace',
97268  '\t': 'Tab',
97269  '\x7F': 'Delete',
97270  '\x1B': 'Escape',
97271  'Del': 'Delete',
97272  'Esc': 'Escape',
97273  'Left': 'ArrowLeft',
97274  'Right': 'ArrowRight',
97275  'Up': 'ArrowUp',
97276  'Down': 'ArrowDown',
97277  'Menu': 'ContextMenu',
97278  'Scroll': 'ScrollLock',
97279  'Win': 'OS'
97280};
97281/**
97282 * Retrieves modifiers from key-event objects.
97283 */
97284
97285const MODIFIER_KEY_GETTERS = {
97286  'alt': event => event.altKey,
97287  'control': event => event.ctrlKey,
97288  'meta': event => event.metaKey,
97289  'shift': event => event.shiftKey
97290};
97291/**
97292 * @publicApi
97293 * A browser plug-in that provides support for handling of key events in Angular.
97294 */
97295
97296class KeyEventsPlugin extends EventManagerPlugin {
97297  /**
97298   * Initializes an instance of the browser plug-in.
97299   * @param doc The document in which key events will be detected.
97300   */
97301  constructor(doc) {
97302    super(doc);
97303  }
97304  /**
97305   * Reports whether a named key event is supported.
97306   * @param eventName The event name to query.
97307   * @return True if the named key event is supported.
97308   */
97309
97310
97311  supports(eventName) {
97312    return KeyEventsPlugin.parseEventName(eventName) != null;
97313  }
97314  /**
97315   * Registers a handler for a specific element and key event.
97316   * @param element The HTML element to receive event notifications.
97317   * @param eventName The name of the key event to listen for.
97318   * @param handler A function to call when the notification occurs. Receives the
97319   * event object as an argument.
97320   * @returns The key event that was registered.
97321   */
97322
97323
97324  addEventListener(element, eventName, handler) {
97325    const parsedEvent = KeyEventsPlugin.parseEventName(eventName);
97326    const outsideHandler = KeyEventsPlugin.eventCallback(parsedEvent['fullKey'], handler, this.manager.getZone());
97327    return this.manager.getZone().runOutsideAngular(() => {
97328      return (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])().onAndCancel(element, parsedEvent['domEventName'], outsideHandler);
97329    });
97330  }
97331  /**
97332   * Parses the user provided full keyboard event definition and normalizes it for
97333   * later internal use. It ensures the string is all lowercase, converts special
97334   * characters to a standard spelling, and orders all the values consistently.
97335   *
97336   * @param eventName The name of the key event to listen for.
97337   * @returns an object with the full, normalized string, and the dom event name
97338   * or null in the case when the event doesn't match a keyboard event.
97339   */
97340
97341
97342  static parseEventName(eventName) {
97343    const parts = eventName.toLowerCase().split('.');
97344    const domEventName = parts.shift();
97345
97346    if (parts.length === 0 || !(domEventName === 'keydown' || domEventName === 'keyup')) {
97347      return null;
97348    }
97349
97350    const key = KeyEventsPlugin._normalizeKey(parts.pop());
97351
97352    let fullKey = '';
97353    let codeIX = parts.indexOf('code');
97354
97355    if (codeIX > -1) {
97356      parts.splice(codeIX, 1);
97357      fullKey = 'code.';
97358    }
97359
97360    MODIFIER_KEYS.forEach(modifierName => {
97361      const index = parts.indexOf(modifierName);
97362
97363      if (index > -1) {
97364        parts.splice(index, 1);
97365        fullKey += modifierName + '.';
97366      }
97367    });
97368    fullKey += key;
97369
97370    if (parts.length != 0 || key.length === 0) {
97371      // returning null instead of throwing to let another plugin process the event
97372      return null;
97373    } // NOTE: Please don't rewrite this as so, as it will break JSCompiler property renaming.
97374    //       The code must remain in the `result['domEventName']` form.
97375    // return {domEventName, fullKey};
97376
97377
97378    const result = {};
97379    result['domEventName'] = domEventName;
97380    result['fullKey'] = fullKey;
97381    return result;
97382  }
97383  /**
97384   * Determines whether the actual keys pressed match the configured key code string.
97385   * The `fullKeyCode` event is normalized in the `parseEventName` method when the
97386   * event is attached to the DOM during the `addEventListener` call. This is unseen
97387   * by the end user and is normalized for internal consistency and parsing.
97388   *
97389   * @param event The keyboard event.
97390   * @param fullKeyCode The normalized user defined expected key event string
97391   * @returns boolean.
97392   */
97393
97394
97395  static matchEventFullKeyCode(event, fullKeyCode) {
97396    let keycode = _keyMap[event.key] || event.key;
97397    let key = '';
97398
97399    if (fullKeyCode.indexOf('code.') > -1) {
97400      keycode = event.code;
97401      key = 'code.';
97402    } // the keycode could be unidentified so we have to check here
97403
97404
97405    if (keycode == null || !keycode) return false;
97406    keycode = keycode.toLowerCase();
97407
97408    if (keycode === ' ') {
97409      keycode = 'space'; // for readability
97410    } else if (keycode === '.') {
97411      keycode = 'dot'; // because '.' is used as a separator in event names
97412    }
97413
97414    MODIFIER_KEYS.forEach(modifierName => {
97415      if (modifierName !== keycode) {
97416        const modifierGetter = MODIFIER_KEY_GETTERS[modifierName];
97417
97418        if (modifierGetter(event)) {
97419          key += modifierName + '.';
97420        }
97421      }
97422    });
97423    key += keycode;
97424    return key === fullKeyCode;
97425  }
97426  /**
97427   * Configures a handler callback for a key event.
97428   * @param fullKey The event name that combines all simultaneous keystrokes.
97429   * @param handler The function that responds to the key event.
97430   * @param zone The zone in which the event occurred.
97431   * @returns A callback function.
97432   */
97433
97434
97435  static eventCallback(fullKey, handler, zone) {
97436    return event => {
97437      if (KeyEventsPlugin.matchEventFullKeyCode(event, fullKey)) {
97438        zone.runGuarded(() => handler(event));
97439      }
97440    };
97441  }
97442  /** @internal */
97443
97444
97445  static _normalizeKey(keyName) {
97446    // TODO: switch to a Map if the mapping grows too much
97447    switch (keyName) {
97448      case 'esc':
97449        return 'escape';
97450
97451      default:
97452        return keyName;
97453    }
97454  }
97455
97456}
97457
97458KeyEventsPlugin.ɵfac = function KeyEventsPlugin_Factory(t) {
97459  return new (t || KeyEventsPlugin)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
97460};
97461
97462KeyEventsPlugin.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
97463  token: KeyEventsPlugin,
97464  factory: KeyEventsPlugin.ɵfac
97465});
97466
97467(function () {
97468  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](KeyEventsPlugin, [{
97469    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
97470  }], function () {
97471    return [{
97472      type: undefined,
97473      decorators: [{
97474        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
97475        args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
97476      }]
97477    }];
97478  }, null);
97479})();
97480/**
97481 * @license
97482 * Copyright Google LLC All Rights Reserved.
97483 *
97484 * Use of this source code is governed by an MIT-style license that can be
97485 * found in the LICENSE file at https://angular.io/license
97486 */
97487
97488
97489const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
97490/**
97491 * Bootstraps an instance of an Angular application and renders a standalone component as the
97492 * application's root component. More information about standalone components can be found in [this
97493 * guide](guide/standalone-components).
97494 *
97495 * @usageNotes
97496 * The root component passed into this function *must* be a standalone one (should have the
97497 * `standalone: true` flag in the `@Component` decorator config).
97498 *
97499 * ```typescript
97500 * @Component({
97501 *   standalone: true,
97502 *   template: 'Hello world!'
97503 * })
97504 * class RootComponent {}
97505 *
97506 * const appRef: ApplicationRef = await bootstrapApplication(RootComponent);
97507 * ```
97508 *
97509 * You can add the list of providers that should be available in the application injector by
97510 * specifying the `providers` field in an object passed as the second argument:
97511 *
97512 * ```typescript
97513 * await bootstrapApplication(RootComponent, {
97514 *   providers: [
97515 *     {provide: BACKEND_URL, useValue: 'https://yourdomain.com/api'}
97516 *   ]
97517 * });
97518 * ```
97519 *
97520 * The `importProvidersFrom` helper method can be used to collect all providers from any
97521 * existing NgModule (and transitively from all NgModules that it imports):
97522 *
97523 * ```typescript
97524 * await bootstrapApplication(RootComponent, {
97525 *   providers: [
97526 *     importProvidersFrom(SomeNgModule)
97527 *   ]
97528 * });
97529 * ```
97530 *
97531 * Note: the `bootstrapApplication` method doesn't include [Testability](api/core/Testability) by
97532 * default. You can add [Testability](api/core/Testability) by getting the list of necessary
97533 * providers using `provideProtractorTestingSupport()` function and adding them into the `providers`
97534 * array, for example:
97535 *
97536 * ```typescript
97537 * import {provideProtractorTestingSupport} from '@angular/platform-browser';
97538 *
97539 * await bootstrapApplication(RootComponent, {providers: [provideProtractorTestingSupport()]});
97540 * ```
97541 *
97542 * @param rootComponent A reference to a standalone component that should be rendered.
97543 * @param options Extra configuration for the bootstrap operation, see `ApplicationConfig` for
97544 *     additional info.
97545 * @returns A promise that returns an `ApplicationRef` instance once resolved.
97546 *
97547 * @publicApi
97548 * @developerPreview
97549 */
97550
97551function bootstrapApplication(rootComponent, options) {
97552  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵinternalCreateApplication"])({
97553    rootComponent,
97554    ...createProvidersConfig(options)
97555  });
97556}
97557/**
97558 * Create an instance of an Angular application without bootstrapping any components. This is useful
97559 * for the situation where one wants to decouple application environment creation (a platform and
97560 * associated injectors) from rendering components on a screen. Components can be subsequently
97561 * bootstrapped on the returned `ApplicationRef`.
97562 *
97563 * @param options Extra configuration for the application environment, see `ApplicationConfig` for
97564 *     additional info.
97565 * @returns A promise that returns an `ApplicationRef` instance once resolved.
97566 *
97567 * @publicApi
97568 * @developerPreview
97569 */
97570
97571
97572function createApplication(options) {
97573  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵinternalCreateApplication"])(createProvidersConfig(options));
97574}
97575
97576function createProvidersConfig(options) {
97577  return {
97578    appProviders: [...BROWSER_MODULE_PROVIDERS, ...(options?.providers ?? [])],
97579    platformProviders: INTERNAL_BROWSER_PLATFORM_PROVIDERS
97580  };
97581}
97582/**
97583 * Returns a set of providers required to setup [Testability](api/core/Testability) for an
97584 * application bootstrapped using the `bootstrapApplication` function. The set of providers is
97585 * needed to support testing an application with Protractor (which relies on the Testability APIs
97586 * to be present).
97587 *
97588 * @returns An array of providers required to setup Testability for an application and make it
97589 *     available for testing using Protractor.
97590 *
97591 * @developerPreview
97592 * @publicApi
97593 */
97594
97595
97596function provideProtractorTestingSupport() {
97597  // Return a copy to prevent changes to the original array in case any in-place
97598  // alterations are performed to the `provideProtractorTestingSupport` call results in app code.
97599  return [...TESTABILITY_PROVIDERS];
97600}
97601
97602function initDomAdapter() {
97603  BrowserDomAdapter.makeCurrent();
97604}
97605
97606function errorHandler() {
97607  return new _angular_core__WEBPACK_IMPORTED_MODULE_1__.ErrorHandler();
97608}
97609
97610function _document() {
97611  // Tell ivy about the global document
97612  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetDocument"])(document);
97613  return document;
97614}
97615
97616const INTERNAL_BROWSER_PLATFORM_PROVIDERS = [{
97617  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID,
97618  useValue: _angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵPLATFORM_BROWSER_ID"]
97619}, {
97620  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_INITIALIZER,
97621  useValue: initDomAdapter,
97622  multi: true
97623}, {
97624  provide: _angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT,
97625  useFactory: _document,
97626  deps: []
97627}];
97628/**
97629 * A factory function that returns a `PlatformRef` instance associated with browser service
97630 * providers.
97631 *
97632 * @publicApi
97633 */
97634
97635const platformBrowser = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.createPlatformFactory)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.platformCore, 'browser', INTERNAL_BROWSER_PLATFORM_PROVIDERS);
97636/**
97637 * Internal marker to signal whether providers from the `BrowserModule` are already present in DI.
97638 * This is needed to avoid loading `BrowserModule` providers twice. We can't rely on the
97639 * `BrowserModule` presence itself, since the standalone-based bootstrap just imports
97640 * `BrowserModule` providers without referencing the module itself.
97641 */
97642
97643const BROWSER_MODULE_PROVIDERS_MARKER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken(NG_DEV_MODE ? 'BrowserModule Providers Marker' : '');
97644const TESTABILITY_PROVIDERS = [{
97645  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵTESTABILITY_GETTER"],
97646  useClass: BrowserGetTestability,
97647  deps: []
97648}, {
97649  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵTESTABILITY"],
97650  useClass: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Testability,
97651  deps: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone, _angular_core__WEBPACK_IMPORTED_MODULE_1__.TestabilityRegistry, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵTESTABILITY_GETTER"]
97651]
97652}, {
97653  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Testability,
97654  useClass: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Testability,
97655  deps: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone, _angular_core__WEBPACK_IMPORTED_MODULE_1__.TestabilityRegistry, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵTESTABILITY_GETTER"]]
97656}];
97657const BROWSER_MODULE_PROVIDERS = [{
97658  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵINJECTOR_SCOPE"],
97659  useValue: 'root'
97660}, {
97661  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ErrorHandler,
97662  useFactory: errorHandler,
97663  deps: []
97664}, {
97665  provide: EVENT_MANAGER_PLUGINS,
97666  useClass: DomEventsPlugin,
97667  multi: true,
97668  deps: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT, _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone, _angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID]
97669}, {
97670  provide: EVENT_MANAGER_PLUGINS,
97671  useClass: KeyEventsPlugin,
97672  multi: true,
97673  deps: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
97674}, {
97675  provide: DomRendererFactory2,
97676  useClass: DomRendererFactory2,
97677  deps: [EventManager, DomSharedStylesHost, _angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID]
97678}, {
97679  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererFactory2,
97680  useExisting: DomRendererFactory2
97681}, {
97682  provide: SharedStylesHost,
97683  useExisting: DomSharedStylesHost
97684}, {
97685  provide: DomSharedStylesHost,
97686  useClass: DomSharedStylesHost,
97687  deps: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
97688}, {
97689  provide: EventManager,
97690  useClass: EventManager,
97691  deps: [EVENT_MANAGER_PLUGINS, _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone]
97692}, {
97693  provide: _angular_common__WEBPACK_IMPORTED_MODULE_0__.XhrFactory,
97694  useClass: BrowserXhr,
97695  deps: []
97696}, NG_DEV_MODE ? {
97697  provide: BROWSER_MODULE_PROVIDERS_MARKER,
97698  useValue: true
97699} : []];
97700/**
97701 * Exports required infrastructure for all Angular apps.
97702 * Included by default in all Angular apps created with the CLI
97703 * `new` command.
97704 * Re-exports `CommonModule` and `ApplicationModule`, making their
97705 * exports and providers available to all apps.
97706 *
97707 * @publicApi
97708 */
97709
97710class BrowserModule {
97711  constructor(providersAlreadyPresent) {
97712    if (NG_DEV_MODE && providersAlreadyPresent) {
97713      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.`);
97714    }
97715  }
97716  /**
97717   * Configures a browser-based app to transition from a server-rendered app, if
97718   * one is present on the page.
97719   *
97720   * @param params An object containing an identifier for the app to transition.
97721   * The ID must match between the client and server versions of the app.
97722   * @returns The reconfigured `BrowserModule` to import into the app's root `AppModule`.
97723   */
97724
97725
97726  static withServerTransition(params) {
97727    return {
97728      ngModule: BrowserModule,
97729      providers: [{
97730        provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID,
97731        useValue: params.appId
97732      }, {
97733        provide: TRANSITION_ID,
97734        useExisting: _angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID
97735      }, SERVER_TRANSITION_PROVIDERS]
97736    };
97737  }
97738
97739}
97740
97741BrowserModule.ɵfac = function BrowserModule_Factory(t) {
97742  return new (t || BrowserModule)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](BROWSER_MODULE_PROVIDERS_MARKER, 12));
97743};
97744
97745BrowserModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
97746  type: BrowserModule,
97747  exports: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.CommonModule, _angular_core__WEBPACK_IMPORTED_MODULE_1__.ApplicationModule]
97748});
97749BrowserModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({
97750  providers: [...BROWSER_MODULE_PROVIDERS, ...TESTABILITY_PROVIDERS],
97751  imports: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.CommonModule, _angular_core__WEBPACK_IMPORTED_MODULE_1__.ApplicationModule]
97752});
97753
97754(function () {
97755  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](BrowserModule, [{
97756    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
97757    args: [{
97758      providers: [...BROWSER_MODULE_PROVIDERS, ...TESTABILITY_PROVIDERS],
97759      exports: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.CommonModule, _angular_core__WEBPACK_IMPORTED_MODULE_1__.ApplicationModule]
97760    }]
97761  }], function () {
97762    return [{
97763      type: undefined,
97764      decorators: [{
97765        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
97766      }, {
97767        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.SkipSelf
97768      }, {
97769        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
97770        args: [BROWSER_MODULE_PROVIDERS_MARKER]
97771      }]
97772    }];
97773  }, null);
97774})();
97775/**
97776 * @license
97777 * Copyright Google LLC All Rights Reserved.
97778 *
97779 * Use of this source code is governed by an MIT-style license that can be
97780 * found in the LICENSE file at https://angular.io/license
97781 */
97782
97783/**
97784 * Factory to create a `Meta` service instance for the current DOM document.
97785 */
97786
97787
97788function createMeta() {
97789  return new Meta((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"])(_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
97790}
97791/**
97792 * A service for managing HTML `<meta>` tags.
97793 *
97794 * Properties of the `MetaDefinition` object match the attributes of the
97795 * HTML `<meta>` tag. These tags define document metadata that is important for
97796 * things like configuring a Content Security Policy, defining browser compatibility
97797 * and security settings, setting HTTP Headers, defining rich content for social sharing,
97798 * and Search Engine Optimization (SEO).
97799 *
97800 * To identify specific `<meta>` tags in a document, use an attribute selection
97801 * string in the format `"tag_attribute='value string'"`.
97802 * For example, an `attrSelector` value of `"name='description'"` matches a tag
97803 * whose `name` attribute has the value `"description"`.
97804 * Selectors are used with the `querySelector()` Document method,
97805 * in the format `meta[{attrSelector}]`.
97806 *
97807 * @see [HTML meta tag](https://developer.mozilla.org/docs/Web/HTML/Element/meta)
97808 * @see [Document.querySelector()](https://developer.mozilla.org/docs/Web/API/Document/querySelector)
97809 *
97810 *
97811 * @publicApi
97812 */
97813
97814
97815class Meta {
97816  constructor(_doc) {
97817    this._doc = _doc;
97818    this._dom = (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])();
97819  }
97820  /**
97821   * Retrieves or creates a specific `<meta>` tag element in the current HTML document.
97822   * In searching for an existing tag, Angular attempts to match the `name` or `property` attribute
97823   * values in the provided tag definition, and verifies that all other attribute values are equal.
97824   * If an existing element is found, it is returned and is not modified in any way.
97825   * @param tag The definition of a `<meta>` element to match or create.
97826   * @param forceCreation True to create a new element without checking whether one already exists.
97827   * @returns The existing element with the same attributes and values if found,
97828   * the new element if no match is found, or `null` if the tag parameter is not defined.
97829   */
97830
97831
97832  addTag(tag, forceCreation = false) {
97833    if (!tag) return null;
97834    return this._getOrCreateElement(tag, forceCreation);
97835  }
97836  /**
97837   * Retrieves or creates a set of `<meta>` tag elements in the current HTML document.
97838   * In searching for an existing tag, Angular attempts to match the `name` or `property` attribute
97839   * values in the provided tag definition, and verifies that all other attribute values are equal.
97840   * @param tags An array of tag definitions to match or create.
97841   * @param forceCreation True to create new elements without checking whether they already exist.
97842   * @returns The matching elements if found, or the new elements.
97843   */
97844
97845
97846  addTags(tags, forceCreation = false) {
97847    if (!tags) return [];
97848    return tags.reduce((result, tag) => {
97849      if (tag) {
97850        result.push(this._getOrCreateElement(tag, forceCreation));
97851      }
97852
97853      return result;
97854    }, []);
97855  }
97856  /**
97857   * Retrieves a `<meta>` tag element in the current HTML document.
97858   * @param attrSelector The tag attribute and value to match against, in the format
97859   * `"tag_attribute='value string'"`.
97860   * @returns The matching element, if any.
97861   */
97862
97863
97864  getTag(attrSelector) {
97865    if (!attrSelector) return null;
97866    return this._doc.querySelector(`meta[${attrSelector}]`) || null;
97867  }
97868  /**
97869   * Retrieves a set of `<meta>` tag elements in the current HTML document.
97870   * @param attrSelector The tag attribute and value to match against, in the format
97871   * `"tag_attribute='value string'"`.
97872   * @returns The matching elements, if any.
97873   */
97874
97875
97876  getTags(attrSelector) {
97877    if (!attrSelector) return [];
97878
97879    const list
97880    /*NodeList*/
97881    = this._doc.querySelectorAll(`meta[${attrSelector}]`);
97882
97883    return list ? [].slice.call(list) : [];
97884  }
97885  /**
97886   * Modifies an existing `<meta>` tag element in the current HTML document.
97887   * @param tag The tag description with which to replace the existing tag content.
97888   * @param selector A tag attribute and value to match against, to identify
97889   * an existing tag. A string in the format `"tag_attribute=`value string`"`.
97890   * If not supplied, matches a tag with the same `name` or `property` attribute value as the
97891   * replacement tag.
97892   * @return The modified element.
97893   */
97894
97895
97896  updateTag(tag, selector) {
97897    if (!tag) return null;
97898    selector = selector || this._parseSelector(tag);
97899    const meta = this.getTag(selector);
97900
97901    if (meta) {
97902      return this._setMetaElementAttributes(tag, meta);
97903    }
97904
97905    return this._getOrCreateElement(tag, true);
97906  }
97907  /**
97908   * Removes an existing `<meta>` tag element from the current HTML document.
97909   * @param attrSelector A tag attribute and value to match against, to identify
97910   * an existing tag. A string in the format `"tag_attribute=`value string`"`.
97911   */
97912
97913
97914  removeTag(attrSelector) {
97915    this.removeTagElement(this.getTag(attrSelector));
97916  }
97917  /**
97918   * Removes an existing `<meta>` tag element from the current HTML document.
97919   * @param meta The tag definition to match against to identify an existing tag.
97920   */
97921
97922
97923  removeTagElement(meta) {
97924    if (meta) {
97925      this._dom.remove(meta);
97926    }
97927  }
97928
97929  _getOrCreateElement(meta, forceCreation = false) {
97930    if (!forceCreation) {
97931      const selector = this._parseSelector(meta); // It's allowed to have multiple elements with the same name so it's not enough to
97932      // just check that element with the same name already present on the page. We also need to
97933      // check if element has tag attributes
97934
97935
97936      const elem = this.getTags(selector).filter(elem => this._containsAttributes(meta, elem))[0];
97937      if (elem !== undefined) return elem;
97938    }
97939
97940    const element = this._dom.createElement('meta');
97941
97942    this._setMetaElementAttributes(meta, element);
97943
97944    const head = this._doc.getElementsByTagName('head')[0];
97945
97946    head.appendChild(element);
97947    return element;
97948  }
97949
97950  _setMetaElementAttributes(tag, el) {
97951    Object.keys(tag).forEach(prop => el.setAttribute(this._getMetaKeyMap(prop), tag[prop]));
97952    return el;
97953  }
97954
97955  _parseSelector(tag) {
97956    const attr = tag.name ? 'name' : 'property';
97957    return `${attr}="${tag[attr]}"`;
97958  }
97959
97960  _containsAttributes(tag, elem) {
97961    return Object.keys(tag).every(key => elem.getAttribute(this._getMetaKeyMap(key)) === tag[key]);
97962  }
97963
97964  _getMetaKeyMap(prop) {
97965    return META_KEYS_MAP[prop] || prop;
97966  }
97967
97968}
97969
97970Meta.ɵfac = function Meta_Factory(t) {
97971  return new (t || Meta)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
97972};
97973
97974Meta.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
97975  token: Meta,
97976  factory: function Meta_Factory(t) {
97977    let r = null;
97978
97979    if (t) {
97980      r = new t();
97981    } else {
97982      r = createMeta();
97983    }
97984
97985    return r;
97986  },
97987  providedIn: 'root'
97988});
97989
97990(function () {
97991  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](Meta, [{
97992    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
97993    args: [{
97994      providedIn: 'root',
97995      useFactory: createMeta,
97996      deps: []
97997    }]
97998  }], function () {
97999    return [{
98000      type: undefined,
98001      decorators: [{
98002        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
98003        args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
98004      }]
98005    }];
98006  }, null);
98007})();
98008/**
98009 * Mapping for MetaDefinition properties with their correct meta attribute names
98010 */
98011
98012
98013const META_KEYS_MAP = {
98014  httpEquiv: 'http-equiv'
98015};
98016/**
98017 * @license
98018 * Copyright Google LLC All Rights Reserved.
98019 *
98020 * Use of this source code is governed by an MIT-style license that can be
98021 * found in the LICENSE file at https://angular.io/license
98022 */
98023
98024/**
98025 * Factory to create Title service.
98026 */
98027
98028function createTitle() {
98029  return new Title((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"])(_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
98030}
98031/**
98032 * A service that can be used to get and set the title of a current HTML document.
98033 *
98034 * Since an Angular application can't be bootstrapped on the entire HTML document (`<html>` tag)
98035 * it is not possible to bind to the `text` property of the `HTMLTitleElement` elements
98036 * (representing the `<title>` tag). Instead, this service can be used to set and get the current
98037 * title value.
98038 *
98039 * @publicApi
98040 */
98041
98042
98043class Title {
98044  constructor(_doc) {
98045    this._doc = _doc;
98046  }
98047  /**
98048   * Get the title of the current HTML document.
98049   */
98050
98051
98052  getTitle() {
98053    return this._doc.title;
98054  }
98055  /**
98056   * Set the title of the current HTML document.
98057   * @param newTitle
98058   */
98059
98060
98061  setTitle(newTitle) {
98062    this._doc.title = newTitle || '';
98063  }
98064
98065}
98066
98067Title.ɵfac = function Title_Factory(t) {
98068  return new (t || Title)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
98069};
98070
98071Title.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
98072  token: Title,
98073  factory: function Title_Factory(t) {
98074    let r = null;
98075
98076    if (t) {
98077      r = new t();
98078    } else {
98079      r = createTitle();
98080    }
98081
98082    return r;
98083  },
98084  providedIn: 'root'
98085});
98086
98087(function () {
98088  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](Title, [{
98089    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
98090    args: [{
98091      providedIn: 'root',
98092      useFactory: createTitle,
98093      deps: []
98094    }]
98095  }], function () {
98096    return [{
98097      type: undefined,
98098      decorators: [{
98099        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
98100        args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
98101      }]
98102    }];
98103  }, null);
98104})();
98105/**
98106 * @license
98107 * Copyright Google LLC All Rights Reserved.
98108 *
98109 * Use of this source code is governed by an MIT-style license that can be
98110 * found in the LICENSE file at https://angular.io/license
98111 */
98112
98113
98114const CAMEL_CASE_REGEXP = /([A-Z])/g;
98115const DASH_CASE_REGEXP = /-([a-z])/g;
98116
98117function camelCaseToDashCase(input) {
98118  return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
98119}
98120
98121function dashCaseToCamelCase(input) {
98122  return input.replace(DASH_CASE_REGEXP, (...m) => m[1].toUpperCase());
98123}
98124/**
98125 * Exports the value under a given `name` in the global property `ng`. For example `ng.probe` if
98126 * `name` is `'probe'`.
98127 * @param name Name under which it will be exported. Keep in mind this will be a property of the
98128 * global `ng` object.
98129 * @param value The value to export.
98130 */
98131
98132
98133function exportNgVar(name, value) {
98134  if (typeof COMPILED === 'undefined' || !COMPILED) {
98135    // Note: we can't export `ng` when using closure enhanced optimization as:
98136    // - closure declares globals itself for minified names, which sometimes clobber our `ng` global
98137    // - we can't declare a closure extern as the namespace `ng` is already used within Google
98138    //   for typings for angularJS (via `goog.provide('ng....')`).
98139    const ng = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].ng = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"].ng || {};
98140    ng[name] = value;
98141  }
98142}
98143/**
98144 * @license
98145 * Copyright Google LLC All Rights Reserved.
98146 *
98147 * Use of this source code is governed by an MIT-style license that can be
98148 * found in the LICENSE file at https://angular.io/license
98149 */
98150
98151
98152const win = typeof window !== 'undefined' && window || {};
98153/**
98154 * @license
98155 * Copyright Google LLC All Rights Reserved.
98156 *
98157 * Use of this source code is governed by an MIT-style license that can be
98158 * found in the LICENSE file at https://angular.io/license
98159 */
98160
98161class ChangeDetectionPerfRecord {
98162  constructor(msPerTick, numTicks) {
98163    this.msPerTick = msPerTick;
98164    this.numTicks = numTicks;
98165  }
98166
98167}
98168/**
98169 * Entry point for all Angular profiling-related debug tools. This object
98170 * corresponds to the `ng.profiler` in the dev console.
98171 */
98172
98173
98174class AngularProfiler {
98175  constructor(ref) {
98176    this.appRef = ref.injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_1__.ApplicationRef);
98177  } // tslint:disable:no-console
98178
98179  /**
98180   * Exercises change detection in a loop and then prints the average amount of
98181   * time in milliseconds how long a single round of change detection takes for
98182   * the current state of the UI. It runs a minimum of 5 rounds for a minimum
98183   * of 500 milliseconds.
98184   *
98185   * Optionally, a user may pass a `config` parameter containing a map of
98186   * options. Supported options are:
98187   *
98188   * `record` (boolean) - causes the profiler to record a CPU profile while
98189   * it exercises the change detector. Example:
98190   *
98191   * ```
98192   * ng.profiler.timeChangeDetection({record: true})
98193   * ```
98194   */
98195
98196
98197  timeChangeDetection(config) {
98198    const record = config && config['record'];
98199    const profileName = 'Change Detection'; // Profiler is not available in Android browsers without dev tools opened
98200
98201    const isProfilerAvailable = win.console.profile != null;
98202
98203    if (record && isProfilerAvailable) {
98204      win.console.profile(profileName);
98205    }
98206
98207    const start = performanceNow();
98208    let numTicks = 0;
98209
98210    while (numTicks < 5 || performanceNow() - start < 500) {
98211      this.appRef.tick();
98212      numTicks++;
98213    }
98214
98215    const end = performanceNow();
98216
98217    if (record && isProfilerAvailable) {
98218      win.console.profileEnd(profileName);
98219    }
98220
98221    const msPerTick = (end - start) / numTicks;
98222    win.console.log(`ran ${numTicks} change detection cycles`);
98223    win.console.log(`${msPerTick.toFixed(2)} ms per check`);
98224    return new ChangeDetectionPerfRecord(msPerTick, numTicks);
98225  }
98226
98227}
98228
98229function performanceNow() {
98230  return win.performance && win.performance.now ? win.performance.now() : new Date().getTime();
98231}
98232/**
98233 * @license
98234 * Copyright Google LLC All Rights Reserved.
98235 *
98236 * Use of this source code is governed by an MIT-style license that can be
98237 * found in the LICENSE file at https://angular.io/license
98238 */
98239
98240
98241const PROFILER_GLOBAL_NAME = 'profiler';
98242/**
98243 * Enabled Angular debug tools that are accessible via your browser's
98244 * developer console.
98245 *
98246 * Usage:
98247 *
98248 * 1. Open developer console (e.g. in Chrome Ctrl + Shift + j)
98249 * 1. Type `ng.` (usually the console will show auto-complete suggestion)
98250 * 1. Try the change detection profiler `ng.profiler.timeChangeDetection()`
98251 *    then hit Enter.
98252 *
98253 * @publicApi
98254 */
98255
98256function enableDebugTools(ref) {
98257  exportNgVar(PROFILER_GLOBAL_NAME, new AngularProfiler(ref));
98258  return ref;
98259}
98260/**
98261 * Disables Angular tools.
98262 *
98263 * @publicApi
98264 */
98265
98266
98267function disableDebugTools() {
98268  exportNgVar(PROFILER_GLOBAL_NAME, null);
98269}
98270/**
98271 * @license
98272 * Copyright Google LLC All Rights Reserved.
98273 *
98274 * Use of this source code is governed by an MIT-style license that can be
98275 * found in the LICENSE file at https://angular.io/license
98276 */
98277
98278
98279function escapeHtml(text) {
98280  const escapedText = {
98281    '&': '&a;',
98282    '"': '&q;',
98283    '\'': '&s;',
98284    '<': '&l;',
98285    '>': '&g;'
98286  };
98287  return text.replace(/[&"'<>]/g, s => escapedText[s]);
98288}
98289
98290function unescapeHtml(text) {
98291  const unescapedText = {
98292    '&a;': '&',
98293    '&q;': '"',
98294    '&s;': '\'',
98295    '&l;': '<',
98296    '&g;': '>'
98297  };
98298  return text.replace(/&[^;]+;/g, s => unescapedText[s]);
98299}
98300/**
98301 * Create a `StateKey<T>` that can be used to store value of type T with `TransferState`.
98302 *
98303 * Example:
98304 *
98305 * ```
98306 * const COUNTER_KEY = makeStateKey<number>('counter');
98307 * let value = 10;
98308 *
98309 * transferState.set(COUNTER_KEY, value);
98310 * ```
98311 *
98312 * @publicApi
98313 */
98314
98315
98316function makeStateKey(key) {
98317  return key;
98318}
98319/**
98320 * A key value store that is transferred from the application on the server side to the application
98321 * on the client side.
98322 *
98323 * The `TransferState` is available as an injectable token.
98324 * On the client, just inject this token using DI and use it, it will be lazily initialized.
98325 * On the server it's already included if `renderApplication` function is used. Otherwise, import
98326 * the `ServerTransferStateModule` module to make the `TransferState` available.
98327 *
98328 * The values in the store are serialized/deserialized using JSON.stringify/JSON.parse. So only
98329 * boolean, number, string, null and non-class objects will be serialized and deserialized in a
98330 * non-lossy manner.
98331 *
98332 * @publicApi
98333 */
98334
98335
98336class TransferState {
98337  constructor() {
98338    this.store = {};
98339    this.onSerializeCallbacks = {};
98340  }
98341  /**
98342   * Get the value corresponding to a key. Return `defaultValue` if key is not found.
98343   */
98344
98345
98346  get(key, defaultValue) {
98347    return this.store[key] !== undefined ? this.store[key] : defaultValue;
98348  }
98349  /**
98350   * Set the value corresponding to a key.
98351   */
98352
98353
98354  set(key, value) {
98355    this.store[key] = value;
98356  }
98357  /**
98358   * Remove a key from the store.
98359   */
98360
98361
98362  remove(key) {
98363    delete this.store[key];
98364  }
98365  /**
98366   * Test whether a key exists in the store.
98367   */
98368
98369
98370  hasKey(key) {
98371    return this.store.hasOwnProperty(key);
98372  }
98373  /**
98374   * Indicates whether the state is empty.
98375   */
98376
98377
98378  get isEmpty() {
98379    return Object.keys(this.store).length === 0;
98380  }
98381  /**
98382   * Register a callback to provide the value for a key when `toJson` is called.
98383   */
98384
98385
98386  onSerialize(key, callback) {
98387    this.onSerializeCallbacks[key] = callback;
98388  }
98389  /**
98390   * Serialize the current state of the store to JSON.
98391   */
98392
98393
98394  toJson() {
98395    // Call the onSerialize callbacks and put those values into the store.
98396    for (const key in this.onSerializeCallbacks) {
98397      if (this.onSerializeCallbacks.hasOwnProperty(key)) {
98398        try {
98399          this.store[key] = this.onSerializeCallbacks[key]();
98400        } catch (e) {
98401          console.warn('Exception in onSerialize callback: ', e);
98402        }
98403      }
98404    }
98405
98406    return JSON.stringify(this.store);
98407  }
98408
98409}
98410
98411TransferState.ɵfac = function TransferState_Factory(t) {
98412  return new (t || TransferState)();
98413};
98414
98415TransferState.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
98416  token: TransferState,
98417  factory: function () {
98418    return (() => {
98419      const doc = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT);
98420      const appId = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID);
98421      const state = new TransferState();
98422      state.store = retrieveTransferredState(doc, appId);
98423      return state;
98424    })();
98425  },
98426  providedIn: 'root'
98427});
98428
98429(function () {
98430  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](TransferState, [{
98431    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
98432    args: [{
98433      providedIn: 'root',
98434      useFactory: () => {
98435        const doc = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT);
98436        const appId = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID);
98437        const state = new TransferState();
98438        state.store = retrieveTransferredState(doc, appId);
98439        return state;
98440      }
98441    }]
98442  }], null, null);
98443})();
98444
98445function retrieveTransferredState(doc, appId) {
98446  // Locate the script tag with the JSON data transferred from the server.
98447  // The id of the script tag is set to the Angular appId + 'state'.
98448  const script = doc.getElementById(appId + '-state');
98449  let initialState = {};
98450
98451  if (script && script.textContent) {
98452    try {
98453      // Avoid using any here as it triggers lint errors in google3 (any is not allowed).
98454      initialState = JSON.parse(unescapeHtml(script.textContent));
98455    } catch (e) {
98456      console.warn('Exception while restoring TransferState for app ' + appId, e);
98457    }
98458  }
98459
98460  return initialState;
98461}
98462/**
98463 * NgModule to install on the client side while using the `TransferState` to transfer state from
98464 * server to client.
98465 *
98466 * @publicApi
98467 * @deprecated no longer needed, you can inject the `TransferState` in an app without providing
98468 *     this module.
98469 */
98470
98471
98472class BrowserTransferStateModule {}
98473
98474BrowserTransferStateModule.ɵfac = function BrowserTransferStateModule_Factory(t) {
98475  return new (t || BrowserTransferStateModule)();
98476};
98477
98478BrowserTransferStateModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
98479  type: BrowserTransferStateModule
98480});
98481BrowserTransferStateModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
98482
98483(function () {
98484  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](BrowserTransferStateModule, [{
98485    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
98486    args: [{}]
98487  }], null, null);
98488})();
98489/**
98490 * @license
98491 * Copyright Google LLC All Rights Reserved.
98492 *
98493 * Use of this source code is governed by an MIT-style license that can be
98494 * found in the LICENSE file at https://angular.io/license
98495 */
98496
98497/**
98498 * Predicates for use with {@link DebugElement}'s query functions.
98499 *
98500 * @publicApi
98501 */
98502
98503
98504class By {
98505  /**
98506   * Match all nodes.
98507   *
98508   * @usageNotes
98509   * ### Example
98510   *
98511   * {@example platform-browser/dom/debug/ts/by/by.ts region='by_all'}
98512   */
98513  static all() {
98514    return () => true;
98515  }
98516  /**
98517   * Match elements by the given CSS selector.
98518   *
98519   * @usageNotes
98520   * ### Example
98521   *
98522   * {@example platform-browser/dom/debug/ts/by/by.ts region='by_css'}
98523   */
98524
98525
98526  static css(selector) {
98527    return debugElement => {
98528      return debugElement.nativeElement != null ? elementMatches(debugElement.nativeElement, selector) : false;
98529    };
98530  }
98531  /**
98532   * Match nodes that have the given directive present.
98533   *
98534   * @usageNotes
98535   * ### Example
98536   *
98537   * {@example platform-browser/dom/debug/ts/by/by.ts region='by_directive'}
98538   */
98539
98540
98541  static directive(type) {
98542    return debugNode => debugNode.providerTokens.indexOf(type) !== -1;
98543  }
98544
98545}
98546
98547function elementMatches(n, selector) {
98548  if ((0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])().isElementNode(n)) {
98549    return n.matches && n.matches(selector) || n.msMatchesSelector && n.msMatchesSelector(selector) || n.webkitMatchesSelector && n.webkitMatchesSelector(selector);
98550  }
98551
98552  return false;
98553}
98554/**
98555 * @license
98556 * Copyright Google LLC All Rights Reserved.
98557 *
98558 * Use of this source code is governed by an MIT-style license that can be
98559 * found in the LICENSE file at https://angular.io/license
98560 */
98561
98562/**
98563 * Supported HammerJS recognizer event names.
98564 */
98565
98566
98567const EVENT_NAMES = {
98568  // pan
98569  'pan': true,
98570  'panstart': true,
98571  'panmove': true,
98572  'panend': true,
98573  'pancancel': true,
98574  'panleft': true,
98575  'panright': true,
98576  'panup': true,
98577  'pandown': true,
98578  // pinch
98579  'pinch': true,
98580  'pinchstart': true,
98581  'pinchmove': true,
98582  'pinchend': true,
98583  'pinchcancel': true,
98584  'pinchin': true,
98585  'pinchout': true,
98586  // press
98587  'press': true,
98588  'pressup': true,
98589  // rotate
98590  'rotate': true,
98591  'rotatestart': true,
98592  'rotatemove': true,
98593  'rotateend': true,
98594  'rotatecancel': true,
98595  // swipe
98596  'swipe': true,
98597  'swipeleft': true,
98598  'swiperight': true,
98599  'swipeup': true,
98600  'swipedown': true,
98601  // tap
98602  'tap': true,
98603  'doubletap': true
98604};
98605/**
98606 * DI token for providing [HammerJS](https://hammerjs.github.io/) support to Angular.
98607 * @see `HammerGestureConfig`
98608 *
98609 * @ngModule HammerModule
98610 * @publicApi
98611 */
98612
98613const HAMMER_GESTURE_CONFIG = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('HammerGestureConfig');
98614/**
98615 * Injection token used to provide a {@link HammerLoader} to Angular.
98616 *
98617 * @publicApi
98618 */
98619
98620const HAMMER_LOADER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('HammerLoader');
98621/**
98622 * An injectable [HammerJS Manager](https://hammerjs.github.io/api/#hammermanager)
98623 * for gesture recognition. Configures specific event recognition.
98624 * @publicApi
98625 */
98626
98627class HammerGestureConfig {
98628  constructor() {
98629    /**
98630     * A set of supported event names for gestures to be used in Angular.
98631     * Angular supports all built-in recognizers, as listed in
98632     * [HammerJS documentation](https://hammerjs.github.io/).
98633     */
98634    this.events = [];
98635    /**
98636     * Maps gesture event names to a set of configuration options
98637     * that specify overrides to the default values for specific properties.
98638     *
98639     * The key is a supported event name to be configured,
98640     * and the options object contains a set of properties, with override values
98641     * to be applied to the named recognizer event.
98642     * For example, to disable recognition of the rotate event, specify
98643     *  `{"rotate": {"enable": false}}`.
98644     *
98645     * Properties that are not present take the HammerJS default values.
98646     * For information about which properties are supported for which events,
98647     * and their allowed and default values, see
98648     * [HammerJS documentation](https://hammerjs.github.io/).
98649     *
98650     */
98651
98652    this.overrides = {};
98653  }
98654  /**
98655   * Creates a [HammerJS Manager](https://hammerjs.github.io/api/#hammermanager)
98656   * and attaches it to a given HTML element.
98657   * @param element The element that will recognize gestures.
98658   * @returns A HammerJS event-manager object.
98659   */
98660
98661
98662  buildHammer(element) {
98663    const mc = new Hammer(element, this.options);
98664    mc.get('pinch').set({
98665      enable: true
98666    });
98667    mc.get('rotate').set({
98668      enable: true
98669    });
98670
98671    for (const eventName in this.overrides) {
98672      mc.get(eventName).set(this.overrides[eventName]);
98673    }
98674
98675    return mc;
98676  }
98677
98678}
98679
98680HammerGestureConfig.ɵfac = function HammerGestureConfig_Factory(t) {
98681  return new (t || HammerGestureConfig)();
98682};
98683
98684HammerGestureConfig.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
98685  token: HammerGestureConfig,
98686  factory: HammerGestureConfig.ɵfac
98687});
98688
98689(function () {
98690  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](HammerGestureConfig, [{
98691    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
98692  }], null, null);
98693})();
98694/**
98695 * Event plugin that adds Hammer support to an application.
98696 *
98697 * @ngModule HammerModule
98698 */
98699
98700
98701class HammerGesturesPlugin extends EventManagerPlugin {
98702  constructor(doc, _config, console, loader) {
98703    super(doc);
98704    this._config = _config;
98705    this.console = console;
98706    this.loader = loader;
98707    this._loaderPromise = null;
98708  }
98709
98710  supports(eventName) {
98711    if (!EVENT_NAMES.hasOwnProperty(eventName.toLowerCase()) && !this.isCustomEvent(eventName)) {
98712      return false;
98713    }
98714
98715    if (!window.Hammer && !this.loader) {
98716      if (typeof ngDevMode === 'undefined' || ngDevMode) {
98717        this.console.warn(`The "${eventName}" event cannot be bound because Hammer.JS is not ` + `loaded and no custom loader has been specified.`);
98718      }
98719
98720      return false;
98721    }
98722
98723    return true;
98724  }
98725
98726  addEventListener(element, eventName, handler) {
98727    const zone = this.manager.getZone();
98728    eventName = eventName.toLowerCase(); // If Hammer is not present but a loader is specified, we defer adding the event listener
98729    // until Hammer is loaded.
98730
98731    if (!window.Hammer && this.loader) {
98732      this._loaderPromise = this._loaderPromise || zone.runOutsideAngular(() => this.loader()); // This `addEventListener` method returns a function to remove the added listener.
98733      // Until Hammer is loaded, the returned function needs to *cancel* the registration rather
98734      // than remove anything.
98735
98736      let cancelRegistration = false;
98737
98738      let deregister = () => {
98739        cancelRegistration = true;
98740      };
98741
98742      zone.runOutsideAngular(() => this._loaderPromise.then(() => {
98743        // If Hammer isn't actually loaded when the custom loader resolves, give up.
98744        if (!window.Hammer) {
98745          if (typeof ngDevMode === 'undefined' || ngDevMode) {
98746            this.console.warn(`The custom HAMMER_LOADER completed, but Hammer.JS is not present.`);
98747          }
98748
98749          deregister = () => {};
98750
98751          return;
98752        }
98753
98754        if (!cancelRegistration) {
98755          // Now that Hammer is loaded and the listener is being loaded for real,
98756          // the deregistration function changes from canceling registration to
98757          // removal.
98758          deregister = this.addEventListener(element, eventName, handler);
98759        }
98760      }).catch(() => {
98761        if (typeof ngDevMode === 'undefined' || ngDevMode) {
98762          this.console.warn(`The "${eventName}" event cannot be bound because the custom ` + `Hammer.JS loader failed.`);
98763        }
98764
98765        deregister = () => {};
98766      })); // Return a function that *executes* `deregister` (and not `deregister` itself) so that we
98767      // can change the behavior of `deregister` once the listener is added. Using a closure in
98768      // this way allows us to avoid any additional data structures to track listener removal.
98769
98770      return () => {
98771        deregister();
98772      };
98773    }
98774
98775    return zone.runOutsideAngular(() => {
98776      // Creating the manager bind events, must be done outside of angular
98777      const mc = this._config.buildHammer(element);
98778
98779      const callback = function (eventObj) {
98780        zone.runGuarded(function () {
98781          handler(eventObj);
98782        });
98783      };
98784
98785      mc.on(eventName, callback);
98786      return () => {
98787        mc.off(eventName, callback); // destroy mc to prevent memory leak
98788
98789        if (typeof mc.destroy === 'function') {
98790          mc.destroy();
98791        }
98792      };
98793    });
98794  }
98795
98796  isCustomEvent(eventName) {
98797    return this._config.events.indexOf(eventName) > -1;
98798  }
98799
98800}
98801
98802HammerGesturesPlugin.ɵfac = function HammerGesturesPlugin_Factory(t) {
98803  return new (t || HammerGesturesPlugin)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](HAMMER_GESTURE_CONFIG), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵConsole"]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](HAMMER_LOADER, 8));
98804};
98805
98806HammerGesturesPlugin.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
98807  token: HammerGesturesPlugin,
98808  factory: HammerGesturesPlugin.ɵfac
98809});
98810
98811(function () {
98812  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](HammerGesturesPlugin, [{
98813    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
98814  }], function () {
98815    return [{
98816      type: undefined,
98817      decorators: [{
98818        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
98819        args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
98820      }]
98821    }, {
98822      type: HammerGestureConfig,
98823      decorators: [{
98824        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
98825        args: [HAMMER_GESTURE_CONFIG]
98826      }]
98827    }, {
98828      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵConsole"]
98829    }, {
98830      type: undefined,
98831      decorators: [{
98832        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
98833      }, {
98834        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
98835        args: [HAMMER_LOADER]
98836      }]
98837    }];
98838  }, null);
98839})();
98840/**
98841 * Adds support for HammerJS.
98842 *
98843 * Import this module at the root of your application so that Angular can work with
98844 * HammerJS to detect gesture events.
98845 *
98846 * Note that applications still need to include the HammerJS script itself. This module
98847 * simply sets up the coordination layer between HammerJS and Angular's EventManager.
98848 *
98849 * @publicApi
98850 */
98851
98852
98853class HammerModule {}
98854
98855HammerModule.ɵfac = function HammerModule_Factory(t) {
98856  return new (t || HammerModule)();
98857};
98858
98859HammerModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
98860  type: HammerModule
98861});
98862HammerModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({
98863  providers: [{
98864    provide: EVENT_MANAGER_PLUGINS,
98865    useClass: HammerGesturesPlugin,
98866    multi: true,
98867    deps: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT, HAMMER_GESTURE_CONFIG, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵConsole"], [new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional(), HAMMER_LOADER]]
98868  }, {
98869    provide: HAMMER_GESTURE_CONFIG,
98870    useClass: HammerGestureConfig,
98871    deps: []
98872  }]
98873});
98874
98875(function () {
98876  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](HammerModule, [{
98877    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
98878    args: [{
98879      providers: [{
98880        provide: EVENT_MANAGER_PLUGINS,
98881        useClass: HammerGesturesPlugin,
98882        multi: true,
98883        deps: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT, HAMMER_GESTURE_CONFIG, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵConsole"], [new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional(), HAMMER_LOADER]]
98884      }, {
98885        provide: HAMMER_GESTURE_CONFIG,
98886        useClass: HammerGestureConfig,
98887        deps: []
98888      }]
98889    }]
98890  }], null, null);
98891})();
98892/**
98893 * @license
98894 * Copyright Google LLC All Rights Reserved.
98895 *
98896 * Use of this source code is governed by an MIT-style license that can be
98897 * found in the LICENSE file at https://angular.io/license
98898 */
98899
98900/**
98901 * DomSanitizer helps preventing Cross Site Scripting Security bugs (XSS) by sanitizing
98902 * values to be safe to use in the different DOM contexts.
98903 *
98904 * For example, when binding a URL in an `<a [href]="someValue">` hyperlink, `someValue` will be
98905 * sanitized so that an attacker cannot inject e.g. a `javascript:` URL that would execute code on
98906 * the website.
98907 *
98908 * In specific situations, it might be necessary to disable sanitization, for example if the
98909 * application genuinely needs to produce a `javascript:` style link with a dynamic value in it.
98910 * Users can bypass security by constructing a value with one of the `bypassSecurityTrust...`
98911 * methods, and then binding to that value from the template.
98912 *
98913 * These situations should be very rare, and extraordinary care must be taken to avoid creating a
98914 * Cross Site Scripting (XSS) security bug!
98915 *
98916 * When using `bypassSecurityTrust...`, make sure to call the method as early as possible and as
98917 * close as possible to the source of the value, to make it easy to verify no security bug is
98918 * created by its use.
98919 *
98920 * It is not required (and not recommended) to bypass security if the value is safe, e.g. a URL that
98921 * does not start with a suspicious protocol, or an HTML snippet that does not contain dangerous
98922 * code. The sanitizer leaves safe values intact.
98923 *
98924 * @security Calling any of the `bypassSecurityTrust...` APIs disables Angular's built-in
98925 * sanitization for the value passed in. Carefully check and audit all values and code paths going
98926 * into this call. Make sure any user data is appropriately escaped for this security context.
98927 * For more detail, see the [Security Guide](https://g.co/ng/security).
98928 *
98929 * @publicApi
98930 */
98931
98932
98933class DomSanitizer {}
98934
98935DomSanitizer.ɵfac = function DomSanitizer_Factory(t) {
98936  return new (t || DomSanitizer)();
98937};
98938
98939DomSanitizer.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
98940  token: DomSanitizer,
98941  factory: function DomSanitizer_Factory(t) {
98942    let r = null;
98943
98944    if (t) {
98945      r = new (t || DomSanitizer)();
98946    } else {
98947      r = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](DomSanitizerImpl);
98948    }
98949
98950    return r;
98951  },
98952  providedIn: 'root'
98953});
98954
98955(function () {
98956  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DomSanitizer, [{
98957    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
98958    args: [{
98959      providedIn: 'root',
98960      useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.forwardRef)(() => DomSanitizerImpl)
98961    }]
98962  }], null, null);
98963})();
98964
98965function domSanitizerImplFactory(injector) {
98966  return new DomSanitizerImpl(injector.get(_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
98967}
98968
98969class DomSanitizerImpl extends DomSanitizer {
98970  constructor(_doc) {
98971    super();
98972    this._doc = _doc;
98973  }
98974
98975  sanitize(ctx, value) {
98976    if (value == null) return null;
98977
98978    switch (ctx) {
98979      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.NONE:
98980        return value;
98981
98982      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.HTML:
98983        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "HTML"
98984        /* BypassType.Html */
98985        )) {
98986          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
98987        }
98988
98989        return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵ_sanitizeHtml"])(this._doc, String(value)).toString();
98990
98991      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.STYLE:
98992        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "Style"
98993        /* BypassType.Style */
98994        )) {
98995          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
98996        }
98997
98998        return value;
98999
99000      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.SCRIPT:
99001        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "Script"
99002        /* BypassType.Script */
99003        )) {
99004          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
99005        }
99006
99007        throw new Error('unsafe value used in a script context');
99008
99009      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.URL:
99010        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "URL"
99011        /* BypassType.Url */
99012        )) {
99013          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
99014        }
99015
99016        return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵ_sanitizeUrl"])(String(value));
99017
99018      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.RESOURCE_URL:
99019        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "ResourceURL"
99020        /* BypassType.ResourceUrl */
99021        )) {
99022          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
99023        }
99024
99025        throw new Error('unsafe value used in a resource URL context (see https://g.co/ng/security#xss)');
99026
99027      default:
99028        throw new Error(`Unexpected SecurityContext ${ctx} (see https://g.co/ng/security#xss)`);
99029    }
99030  }
99031
99032  bypassSecurityTrustHtml(value) {
99033    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustHtml"])(value);
99034  }
99035
99036  bypassSecurityTrustStyle(value) {
99037    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustStyle"])(value);
99038  }
99039
99040  bypassSecurityTrustScript(value) {
99041    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustScript"])(value);
99042  }
99043
99044  bypassSecurityTrustUrl(value) {
99045    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustUrl"])(value);
99046  }
99047
99048  bypassSecurityTrustResourceUrl(value) {
99049    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustResourceUrl"])(value);
99050  }
99051
99052}
99053
99054DomSanitizerImpl.ɵfac = function DomSanitizerImpl_Factory(t) {
99055  return new (t || DomSanitizerImpl)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
99056};
99057
99058DomSanitizerImpl.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
99059  token: DomSanitizerImpl,
99060  factory: function DomSanitizerImpl_Factory(t) {
99061    let r = null;
99062
99063    if (t) {
99064      r = new t();
99065    } else {
99066      r = domSanitizerImplFactory(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.Injector));
99067    }
99068
99069    return r;
99070  },
99071  providedIn: 'root'
99072});
99073
99074(function () {
99075  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DomSanitizerImpl, [{
99076    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
99077    args: [{
99078      providedIn: 'root',
99079      useFactory: domSanitizerImplFactory,
99080      deps: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.Injector]
99081    }]
99082  }], function () {
99083    return [{
99084      type: undefined,
99085      decorators: [{
99086        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
99087        args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
99088      }]
99089    }];
99090  }, null);
99091})();
99092/**
99093 * @license
99094 * Copyright Google LLC All Rights Reserved.
99095 *
99096 * Use of this source code is governed by an MIT-style license that can be
99097 * found in the LICENSE file at https://angular.io/license
99098 */
99099
99100/**
99101 * @license
99102 * Copyright Google LLC All Rights Reserved.
99103 *
99104 * Use of this source code is governed by an MIT-style license that can be
99105 * found in the LICENSE file at https://angular.io/license
99106 */
99107
99108/**
99109 * @publicApi
99110 */
99111
99112
99113const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Version('14.2.10');
99114/**
99115 * @license
99116 * Copyright Google LLC All Rights Reserved.
99117 *
99118 * Use of this source code is governed by an MIT-style license that can be
99119 * found in the LICENSE file at https://angular.io/license
99120 */
99121
99122/**
99123 * @license
99124 * Copyright Google LLC All Rights Reserved.
99125 *
99126 * Use of this source code is governed by an MIT-style license that can be
99127 * found in the LICENSE file at https://angular.io/license
99128 */
99129// This file only reexports content of the `src` folder. Keep it that way.
99130
99131/**
99132 * @license
99133 * Copyright Google LLC All Rights Reserved.
99134 *
99135 * Use of this source code is governed by an MIT-style license that can be
99136 * found in the LICENSE file at https://angular.io/license
99137 */
99138
99139/**
99140 * Generated bundle index. Do not edit.
99141 */
99142
99143
99144
99145/***/ }),
99146
99147/***/ 124:
99148/*!**********************************************************!*\
99149  !*** ./node_modules/@angular/router/fesm2020/router.mjs ***!
99150  \**********************************************************/
99151/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
99152
99153__webpack_require__.r(__webpack_exports__);
99154/* harmony export */ __webpack_require__.d(__webpack_exports__, {
99155/* harmony export */   "ActivatedRoute": () => (/* binding */ ActivatedRoute),
99156/* harmony export */   "ActivatedRouteSnapshot": () => (/* binding */ ActivatedRouteSnapshot),
99157/* harmony export */   "ActivationEnd": () => (/* binding */ ActivationEnd),
99158/* harmony export */   "ActivationStart": () => (/* binding */ ActivationStart),
99159/* harmony export */   "BaseRouteReuseStrategy": () => (/* binding */ BaseRouteReuseStrategy),
99160/* harmony export */   "ChildActivationEnd": () => (/* binding */ ChildActivationEnd),
99161/* harmony export */   "ChildActivationStart": () => (/* binding */ ChildActivationStart),
99162/* harmony export */   "ChildrenOutletContexts": () => (/* binding */ ChildrenOutletContexts),
99163/* harmony export */   "DefaultTitleStrategy": () => (/* binding */ DefaultTitleStrategy),
99164/* harmony export */   "DefaultUrlSerializer": () => (/* binding */ DefaultUrlSerializer),
99165/* harmony export */   "GuardsCheckEnd": () => (/* binding */ GuardsCheckEnd),
99166/* harmony export */   "GuardsCheckStart": () => (/* binding */ GuardsCheckStart),
99167/* harmony export */   "NavigationCancel": () => (/* binding */ NavigationCancel),
99168/* harmony export */   "NavigationEnd": () => (/* binding */ NavigationEnd),
99169/* harmony export */   "NavigationError": () => (/* binding */ NavigationError),
99170/* harmony export */   "NavigationStart": () => (/* binding */ NavigationStart),
99171/* harmony export */   "NoPreloading": () => (/* binding */ NoPreloading),
99172/* harmony export */   "OutletContext": () => (/* binding */ OutletContext),
99173/* harmony export */   "PRIMARY_OUTLET": () => (/* binding */ PRIMARY_OUTLET),
99174/* harmony export */   "PreloadAllModules": () => (/* binding */ PreloadAllModules),
99175/* harmony export */   "PreloadingStrategy": () => (/* binding */ PreloadingStrategy),
99176/* harmony export */   "ROUTER_CONFIGURATION": () => (/* binding */ ROUTER_CONFIGURATION),
99177/* harmony export */   "ROUTER_INITIALIZER": () => (/* binding */ ROUTER_INITIALIZER),
99178/* harmony export */   "ROUTES": () => (/* binding */ ROUTES),
99179/* harmony export */   "ResolveEnd": () => (/* binding */ ResolveEnd),
99180/* harmony export */   "ResolveStart": () => (/* binding */ ResolveStart),
99181/* harmony export */   "RouteConfigLoadEnd": () => (/* binding */ RouteConfigLoadEnd),
99182/* harmony export */   "RouteConfigLoadStart": () => (/* binding */ RouteConfigLoadStart),
99183/* harmony export */   "RouteReuseStrategy": () => (/* binding */ RouteReuseStrategy),
99184/* harmony export */   "Router": () => (/* binding */ Router),
99185/* harmony export */   "RouterEvent": () => (/* binding */ RouterEvent),
99186/* harmony export */   "RouterLink": () => (/* binding */ RouterLink),
99187/* harmony export */   "RouterLinkActive": () => (/* binding */ RouterLinkActive),
99188/* harmony export */   "RouterLinkWithHref": () => (/* binding */ RouterLinkWithHref),
99189/* harmony export */   "RouterModule": () => (/* binding */ RouterModule),
99190/* harmony export */   "RouterOutlet": () => (/* binding */ RouterOutlet),
99191/* harmony export */   "RouterPreloader": () => (/* binding */ RouterPreloader),
99192/* harmony export */   "RouterState": () => (/* binding */ RouterState),
99193/* harmony export */   "RouterStateSnapshot": () => (/* binding */ RouterStateSnapshot),
99194/* harmony export */   "RoutesRecognized": () => (/* binding */ RoutesRecognized),
99195/* harmony export */   "Scroll": () => (/* binding */ Scroll),
99196/* harmony export */   "TitleStrategy": () => (/* binding */ TitleStrategy),
99197/* harmony export */   "UrlHandlingStrategy": () => (/* binding */ UrlHandlingStrategy),
99198/* harmony export */   "UrlSegment": () => (/* binding */ UrlSegment),
99199/* harmony export */   "UrlSegmentGroup": () => (/* binding */ UrlSegmentGroup),
99200/* harmony export */   "UrlSerializer": () => (/* binding */ UrlSerializer),
99201/* harmony export */   "UrlTree": () => (/* binding */ UrlTree),
99202/* harmony export */   "VERSION": () => (/* binding */ VERSION),
99203/* harmony export */   "convertToParamMap": () => (/* binding */ convertToParamMap),
99204/* harmony export */   "createUrlTreeFromSnapshot": () => (/* binding */ createUrlTreeFromSnapshot),
99205/* harmony export */   "defaultUrlMatcher": () => (/* binding */ defaultUrlMatcher),
99206/* harmony export */   "provideRouter": () => (/* binding */ provideRouter),
99207/* harmony export */   "provideRoutes": () => (/* binding */ provideRoutes),
99208/* harmony export */   "withDebugTracing": () => (/* binding */ withDebugTracing),
99209/* harmony export */   "withDisabledInitialNavigation": () => (/* binding */ withDisabledInitialNavigation),
99210/* harmony export */   "withEnabledBlockingInitialNavigation": () => (/* binding */ withEnabledBlockingInitialNavigation),
99211/* harmony export */   "withInMemoryScrolling": () => (/* binding */ withInMemoryScrolling),
99212/* harmony export */   "withPreloading": () => (/* binding */ withPreloading),
99213/* harmony export */   "withRouterConfig": () => (/* binding */ withRouterConfig),
99214/* harmony exp
99214ort */   "ɵEmptyOutletComponent": () => (/* binding */ ɵEmptyOutletComponent),
99215/* harmony export */   "ɵROUTER_PROVIDERS": () => (/* binding */ ROUTER_PROVIDERS),
99216/* harmony export */   "ɵassignExtraOptionsToRouter": () => (/* binding */ assignExtraOptionsToRouter),
99217/* harmony export */   "ɵflatten": () => (/* binding */ flatten),
99218/* harmony export */   "ɵwithPreloading": () => (/* binding */ withPreloading)
99219/* harmony export */ });
99220/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 2560);
99221/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 4383);
99222/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 4139);
99223/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 4505);
99224/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 213);
99225/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs */ 9193);
99226/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! rxjs */ 5828);
99227/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! rxjs */ 2160);
99228/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! rxjs */ 6800);
99229/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! rxjs */ 6587);
99230/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! rxjs */ 2378);
99231/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! rxjs */ 6439);
99232/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! rxjs */ 4483);
99233/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! rxjs */ 2218);
99234/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! @angular/common */ 4666);
99235/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 6942);
99236/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 9095);
99237/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs/operators */ 3910);
99238/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs/operators */ 5722);
99239/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 9151);
99240/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! rxjs/operators */ 522);
99241/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! rxjs/operators */ 5670);
99242/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! rxjs/operators */ 1133);
99243/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! rxjs/operators */ 8759);
99244/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! rxjs/operators */ 7418);
99245/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! rxjs/operators */ 2647);
99246/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! rxjs/operators */ 5690);
99247/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! rxjs/operators */ 5050);
99248/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! rxjs/operators */ 9701);
99249/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! rxjs/operators */ 7760);
99250/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! rxjs/operators */ 9361);
99251/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! rxjs/operators */ 4661);
99252/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! rxjs/operators */ 8331);
99253/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! rxjs/operators */ 6675);
99254/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! @angular/platform-browser */ 4497);
99255/**
99256 * @license Angular v14.2.10
99257 * (c) 2010-2022 Google LLC. https://angular.io/
99258 * License: MIT
99259 */
99260
99261
99262
99263
99264
99265
99266
99267/**
99268 * @license
99269 * Copyright Google LLC All Rights Reserved.
99270 *
99271 * Use of this source code is governed by an MIT-style license that can be
99272 * found in the LICENSE file at https://angular.io/license
99273 */
99274
99275/**
99276 * The primary routing outlet.
99277 *
99278 * @publicApi
99279 */
99280
99281const PRIMARY_OUTLET = 'primary';
99282/**
99283 * A private symbol used to store the value of `Route.title` inside the `Route.data` if it is a
99284 * static string or `Route.resolve` if anything else. This allows us to reuse the existing route
99285 * data/resolvers to support the title feature without new instrumentation in the `Router` pipeline.
99286 */
99287
99288const RouteTitleKey = Symbol('RouteTitle');
99289
99290class ParamsAsMap {
99291  constructor(params) {
99292    this.params = params || {};
99293  }
99294
99295  has(name) {
99296    return Object.prototype.hasOwnProperty.call(this.params, name);
99297  }
99298
99299  get(name) {
99300    if (this.has(name)) {
99301      const v = this.params[name];
99302      return Array.isArray(v) ? v[0] : v;
99303    }
99304
99305    return null;
99306  }
99307
99308  getAll(name) {
99309    if (this.has(name)) {
99310      const v = this.params[name];
99311      return Array.isArray(v) ? v : [v];
99312    }
99313
99314    return [];
99315  }
99316
99317  get keys() {
99318    return Object.keys(this.params);
99319  }
99320
99321}
99322/**
99323 * Converts a `Params` instance to a `ParamMap`.
99324 * @param params The instance to convert.
99325 * @returns The new map instance.
99326 *
99327 * @publicApi
99328 */
99329
99330
99331function convertToParamMap(params) {
99332  return new ParamsAsMap(params);
99333}
99334/**
99335 * Matches the route configuration (`route`) against the actual URL (`segments`).
99336 *
99337 * When no matcher is defined on a `Route`, this is the matcher used by the Router by default.
99338 *
99339 * @param segments The remaining unmatched segments in the current navigation
99340 * @param segmentGroup The current segment group being matched
99341 * @param route The `Route` to match against.
99342 *
99343 * @see UrlMatchResult
99344 * @see Route
99345 *
99346 * @returns The resulting match information or `null` if the `route` should not match.
99347 * @publicApi
99348 */
99349
99350
99351function defaultUrlMatcher(segments, segmentGroup, route) {
99352  const parts = route.path.split('/');
99353
99354  if (parts.length > segments.length) {
99355    // The actual URL is shorter than the config, no match
99356    return null;
99357  }
99358
99359  if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || parts.length < segments.length)) {
99360    // The config is longer than the actual URL but we are looking for a full match, return null
99361    return null;
99362  }
99363
99364  const posParams = {}; // Check each config part against the actual URL
99365
99366  for (let index = 0; index < parts.length; index++) {
99367    const part = parts[index];
99368    const segment = segments[index];
99369    const isParameter = part.startsWith(':');
99370
99371    if (isParameter) {
99372      posParams[part.substring(1)] = segment;
99373    } else if (part !== segment.path) {
99374      // The actual URL part does not match the config, no match
99375      return null;
99376    }
99377  }
99378
99379  return {
99380    consumed: segments.slice(0, parts.length),
99381    posParams
99382  };
99383}
99384/**
99385 * @license
99386 * Copyright Google LLC All Rights Reserved.
99387 *
99388 * Use of this source code is governed by an MIT-style license that can be
99389 * found in the LICENSE file at https://angular.io/license
99390 */
99391
99392
99393function shallowEqualArrays(a, b) {
99394  if (a.length !== b.length) return false;
99395
99396  for (let i = 0; i < a.length; ++i) {
99397    if (!shallowEqual(a[i], b[i])) return false;
99398  }
99399
99400  return true;
99401}
99402
99403function shallowEqual(a, b) {
99404  // While `undefined` should never be possible, it would sometimes be the case in IE 11
99405  // and pre-chromium Edge. The check below accounts for this edge case.
99406  const k1 = a ? Object.keys(a) : undefined;
99407  const k2 = b ? Object.keys(b) : undefined;
99408
99409  if (!k1 || !k2 || k1.length != k2.length) {
99410    return false;
99411  }
99412
99413  let key;
99414
99415  for (let i = 0; i < k1.length; i++) {
99416    key = k1[i];
99417
99418    if (!equalArraysOrString(a[key], b[key])) {
99419      return false;
99420    }
99421  }
99422
99423  return true;
99424}
99425/**
99426 * Test equality for arrays of strings or a string.
99427 */
99428
99429
99430function equalArraysOrString(a, b) {
99431  if (Array.isArray(a) && Array.isArray(b)) {
99432    if (a.length !== b.length) return false;
99433    const aSorted = [...a].sort();
99434    const bSorted = [...b].sort();
99435    return aSorted.every((val, index) => bSorted[index] === val);
99436  } else {
99437    return a === b;
99438  }
99439}
99440/**
99441 * Flattens single-level nested arrays.
99442 */
99443
99444
99445function flatten(arr) {
99446  return Array.prototype.concat.apply([], arr);
99447}
99448/**
99449 * Return the last element of an array.
99450 */
99451
99452
99453function last(a) {
99454  return a.length > 0 ? a[a.length - 1] : null;
99455}
99456/**
99457 * Verifys all booleans in an array are `true`.
99458 */
99459
99460
99461function and(bools) {
99462  return !bools.some(v => !v);
99463}
99464
99465function forEach(map, callback) {
99466  for (const prop in map) {
99467    if (map.hasOwnProperty(prop)) {
99468      callback(map[prop], prop);
99469    }
99470  }
99471}
99472
99473function wrapIntoObservable(value) {
99474  if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisObservable"])(value)) {
99475    return value;
99476  }
99477
99478  if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisPromise"])(value)) {
99479    // Use `Promise.resolve()` to wrap promise-like instances.
99480    // Required ie when a Resolver returns a AngularJS `$q` promise to correctly trigger the
99481    // change detection.
99482    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(Promise.resolve(value));
99483  }
99484
99485  return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(value);
99486}
99487/**
99488 * @license
99489 * Copyright Google LLC All Rights Reserved.
99490 *
99491 * Use of this source code is governed by an MIT-style license that can be
99492 * found in the LICENSE file at https://angular.io/license
99493 */
99494
99495
99496const NG_DEV_MODE$9 = typeof ngDevMode === 'undefined' || ngDevMode;
99497
99498function createEmptyUrlTree() {
99499  return new UrlTree(new UrlSegmentGroup([], {}), {}, null);
99500}
99501
99502const pathCompareMap = {
99503  'exact': equalSegmentGroups,
99504  'subset': containsSegmentGroup
99505};
99506const paramCompareMap = {
99507  'exact': equalParams,
99508  'subset': containsParams,
99509  'ignored': () => true
99510};
99511
99512function containsTree(container, containee, options) {
99513  return pathCompareMap[options.paths](container.root, containee.root, options.matrixParams) && paramCompareMap[options.queryParams](container.queryParams, containee.queryParams) && !(options.fragment === 'exact' && container.fragment !== containee.fragment);
99514}
99515
99516function equalParams(container, containee) {
99517  // TODO: This does not handle array params correctly.
99518  return shallowEqual(container, containee);
99519}
99520
99521function equalSegmentGroups(container, containee, matrixParams) {
99522  if (!equalPath(container.segments, containee.segments)) return false;
99523
99524  if (!matrixParamsMatch(container.segments, containee.segments, matrixParams)) {
99525    return false;
99526  }
99527
99528  if (container.numberOfChildren !== containee.numberOfChildren) return false;
99529
99530  for (const c in containee.children) {
99531    if (!container.children[c]) return false;
99532    if (!equalSegmentGroups(container.children[c], containee.children[c], matrixParams)) return false;
99533  }
99534
99535  return true;
99536}
99537
99538function containsParams(container, containee) {
99539  return Object.keys(containee).length <= Object.keys(container).length && Object.keys(containee).every(key => equalArraysOrString(container[key], containee[key]));
99540}
99541
99542function containsSegmentGroup(container, containee, matrixParams) {
99543  return containsSegmentGroupHelper(container, containee, containee.segments, matrixParams);
99544}
99545
99546function containsSegmentGroupHelper(container, containee, containeePaths, matrixParams) {
99547  if (container.segments.length > containeePaths.length) {
99548    const current = container.segments.slice(0, containeePaths.length);
99549    if (!equalPath(current, containeePaths)) return false;
99550    if (containee.hasChildren()) return false;
99551    if (!matrixParamsMatch(current, containeePaths, matrixParams)) return false;
99552    return true;
99553  } else if (container.segments.length === containeePaths.length) {
99554    if (!equalPath(container.segments, containeePaths)) return false;
99555    if (!matrixParamsMatch(container.segments, containeePaths, matrixParams)) return false;
99556
99557    for (const c in containee.children) {
99558      if (!container.children[c]) return false;
99559
99560      if (!containsSegmentGroup(container.children[c], containee.children[c], matrixParams)) {
99561        return false;
99562      }
99563    }
99564
99565    return true;
99566  } else {
99567    const current = containeePaths.slice(0, container.segments.length);
99568    const next = containeePaths.slice(container.segments.length);
99569    if (!equalPath(container.segments, current)) return false;
99570    if (!matrixParamsMatch(container.segments, current, matrixParams)) return false;
99571    if (!container.children[PRIMARY_OUTLET]) return false;
99572    return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next, matrixParams);
99573  }
99574}
99575
99576function matrixParamsMatch(containerPaths, containeePaths, options) {
99577  return containeePaths.every((containeeSegment, i) => {
99578    return paramCompareMap[options](containerPaths[i].parameters, containeeSegment.parameters);
99579  });
99580}
99581/**
99582 * @description
99583 *
99584 * Represents the parsed URL.
99585 *
99586 * Since a router state is a tree, and the URL is nothing but a serialized state, the URL is a
99587 * serialized tree.
99588 * UrlTree is a data structure that provides a lot of affordances in dealing with URLs
99589 *
99590 * @usageNotes
99591 * ### Example
99592 *
99593 * ```
99594 * @Component({templateUrl:'template.html'})
99595 * class MyComponent {
99596 *   constructor(router: Router) {
99597 *     const tree: UrlTree =
99598 *       router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment');
99599 *     const f = tree.fragment; // return 'fragment'
99600 *     const q = tree.queryParams; // returns {debug: 'true'}
99601 *     const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
99602 *     const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33'
99603 *     g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor'
99604 *     g.children['support'].segments; // return 1 segment 'help'
99605 *   }
99606 * }
99607 * ```
99608 *
99609 * @publicApi
99610 */
99611
99612
99613class UrlTree {
99614  /** @internal */
99615  constructor(
99616  /** The root segment group of the URL tree */
99617  root,
99618  /** The query params of the URL */
99619  queryParams,
99620  /** The fragment of the URL */
99621  fragment) {
99622    this.root = root;
99623    this.queryParams = queryParams;
99624    this.fragment = fragment;
99625  }
99626
99627  get queryParamMap() {
99628    if (!this._queryParamMap) {
99629      this._queryParamMap = convertToParamMap(this.queryParams);
99630    }
99631
99632    return this._queryParamMap;
99633  }
99634  /** @docsNotRequired */
99635
99636
99637  toString() {
99638    return DEFAULT_SERIALIZER.serialize(this);
99639  }
99640
99641}
99642/**
99643 * @description
99644 *
99645 * Represents the parsed URL segment group.
99646 *
99647 * See `UrlTree` for more information.
99648 *
99649 * @publicApi
99650 */
99651
99652
99653class UrlSegmentGroup {
99654  constructor(
99655  /** The URL segments of this group. See `UrlSegment` for more information */
99656  segments,
99657  /** The list of children of this group */
99658  children) {
99659    this.segments = segments;
99660    this.children = children;
99661    /** The parent node in the url tree */
99662
99663    this.parent = null;
99664    forEach(children, (v, k) => v.parent = this);
99665  }
99666  /** Whether the segment has child segments */
99667
99668
99669  hasChildren() {
99670    return this.numberOfChildren > 0;
99671  }
99672  /** Number of child segments */
99673
99674
99675  get numberOfChildren() {
99676    return Object.keys(this.children).length;
99677  }
99678  /** @docsNotRequired */
99679
99680
99681  toString() {
99682    return serializePaths(this);
99683  }
99684
99685}
99686/**
99687 * @description
99688 *
99689 * Represents a single URL segment.
99690 *
99691 * A UrlSegment is a part of a URL between the two slashes. It contains a path and the matrix
99692 * parameters associated with the segment.
99693 *
99694 * @usageNotes
99695 * ### Example
99696 *
99697 * ```
99698 * @Component({templateUrl:'template.html'})
99699 * class MyComponent {
99700 *   constructor(router: Router) {
99701 *     const tree: UrlTree = router.parseUrl('/team;id=33');
99702 *     const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
99703 *     const s: UrlSegment[] = g.segments;
99704 *     s[0].path; // returns 'team'
99705 *     s[0].parameters; // returns {id: 33}
99706 *   }
99707 * }
99708 * ```
99709 *
99710 * @publicApi
99711 */
99712
99713
99714class UrlSegment {
99715  constructor(
99716  /** The path part of a URL segment */
99717  path,
99718  /** The matrix parameters associated with a segment */
99719  parameters) {
99720    this.path = path;
99721    this.parameters = parameters;
99722  }
99723
99724  get parameterMap() {
99725    if (!this._parameterMap) {
99726      this._parameterMap = convertToParamMap(this.parameters);
99727    }
99728
99729    return this._parameterMap;
99730  }
99731  /** @docsNotRequired */
99732
99733
99734  toString() {
99735    return serializePath(this);
99736  }
99737
99738}
99739
99740function equalSegments(as, bs) {
99741  return equalPath(as, bs) && as.every((a, i) => shallowEqual(a.parameters, bs[i].parameters));
99742}
99743
99744function equalPath(as, bs) {
99745  if (as.length !== bs.length) return false;
99746  return as.every((a, i) => a.path === bs[i].path);
99747}
99748
99749function mapChildrenIntoArray(segment, fn) {
99750  let res = [];
99751  forEach(segment.children, (child, childOutlet) => {
99752    if (childOutlet === PRIMARY_OUTLET) {
99753      res = res.concat(fn(child, childOutlet));
99754    }
99755  });
99756  forEach(segment.children, (child, childOutlet) => {
99757    if (childOutlet !== PRIMARY_OUTLET) {
99758      res = res.concat(fn(child, childOutlet));
99759    }
99760  });
99761  return res;
99762}
99763/**
99764 * @description
99765 *
99766 * Serializes and deserializes a URL string into a URL tree.
99767 *
99768 * The url serialization strategy is customizable. You can
99769 * make all URLs case insensitive by providing a custom UrlSerializer.
99770 *
99771 * See `DefaultUrlSerializer` for an example of a URL serializer.
99772 *
99773 * @publicApi
99774 */
99775
99776
99777class UrlSerializer {}
99778
99779UrlSerializer.ɵfac = function UrlSerializer_Factory(t) {
99780  return new (t || UrlSerializer)();
99781};
99782
99783UrlSerializer.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
99784  token: UrlSerializer,
99785  factory: function () {
99786    return (() => new DefaultUrlSerializer())();
99787  },
99788  providedIn: 'root'
99789});
99790
99791(function () {
99792  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UrlSerializer, [{
99793    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
99794    args: [{
99795      providedIn: 'root',
99796      useFactory: () => new DefaultUrlSerializer()
99797    }]
99798  }], null, null);
99799})();
99800/**
99801 * @description
99802 *
99803 * A default implementation of the `UrlSerializer`.
99804 *
99805 * Example URLs:
99806 *
99807 * ```
99808 * /inbox/33(popup:compose)
99809 * /inbox/33;open=true/messages/44
99810 * ```
99811 *
99812 * DefaultUrlSerializer uses parentheses to serialize secondary segments (e.g., popup:compose), the
99813 * colon syntax to specify the outlet, and the ';parameter=value' syntax (e.g., open=true) to
99814 * specify route specific parameters.
99815 *
99816 * @publicApi
99817 */
99818
99819
99820class DefaultUrlSerializer {
99821  /** Parses a url into a `UrlTree` */
99822  parse(url) {
99823    const p = new UrlParser(url);
99824    return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
99825  }
99826  /** Converts a `UrlTree` into a url */
99827
99828
99829  serialize(tree) {
99830    const segment = `/${serializeSegment(tree.root, true)}`;
99831    const query = serializeQueryParams(tree.queryParams);
99832    const fragment = typeof tree.fragment === `string` ? `#${encodeUriFragment(tree.fragment)}` : '';
99833    return `${segment}${query}${fragment}`;
99834  }
99835
99836}
99837
99838const DEFAULT_SERIALIZER = new DefaultUrlSerializer();
99839
99840function serializePaths(segment) {
99841  return segment.segments.map(p => serializePath(p)).join('/');
99842}
99843
99844function serializeSegment(segment, root) {
99845  if (!segment.hasChildren()) {
99846    return serializePaths(segment);
99847  }
99848
99849  if (root) {
99850    const primary = segment.children[PRIMARY_OUTLET] ? serializeSegment(segment.children[PRIMARY_OUTLET], false) : '';
99851    const children = [];
99852    forEach(segment.children, (v, k) => {
99853      if (k !== PRIMARY_OUTLET) {
99854        children.push(`${k}:${serializeSegment(v, false)}`);
99855      }
99856    });
99857    return children.length > 0 ? `${primary}(${children.join('//')})` : primary;
99858  } else {
99859    const children = mapChildrenIntoArray(segment, (v, k) => {
99860      if (k === PRIMARY_OUTLET) {
99861        return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
99862      }
99863
99864      return [`${k}:${serializeSegment(v, false)}`];
99865    }); // use no parenthesis if the only child is a primary outlet route
99866
99867    if (Object.keys(segment.children).length === 1 && segment.children[PRIMARY_OUTLET] != null) {
99868      return `${serializePaths(segment)}/${children[0]}`;
99869    }
99870
99871    return `${serializePaths(segment)}/(${children.join('//')})`;
99872  }
99873}
99874/**
99875 * Encodes a URI string with the default encoding. This function will only ever be called from
99876 * `encodeUriQuery` or `encodeUriSegment` as it's the base set of encodings to be used. We need
99877 * a custom encoding because encodeURIComponent is too aggressive and encodes stuff that doesn't
99878 * have to be encoded per https://url.spec.whatwg.org.
99879 */
99880
99881
99882function encodeUriString(s) {
99883  return encodeURIComponent(s).replace(/%40/g, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',');
99884}
99885/**
99886 * This function should be used to encode both keys and values in a query string key/value. In
99887 * the following URL, you need to call encodeUriQuery on "k" and "v":
99888 *
99889 * http://www.site.org/html;mk=mv?k=v#f
99890 */
99891
99892
99893function encodeUriQuery(s) {
99894  return encodeUriString(s).replace(/%3B/gi, ';');
99895}
99896/**
99897 * This function should be used to encode a URL fragment. In the following URL, you need to call
99898 * encodeUriFragment on "f":
99899 *
99900 * http://www.site.org/html;mk=mv?k=v#f
99901 */
99902
99903
99904function encodeUriFragment(s) {
99905  return encodeURI(s);
99906}
99907/**
99908 * This function should be run on any URI segment as well as the key and value in a key/value
99909 * pair for matrix params. In the following URL, you need to call encodeUriSegment on "html",
99910 * "mk", and "mv":
99911 *
99912 * http://www.site.org/html;mk=mv?k=v#f
99913 */
99914
99915
99916function encodeUriSegment(s) {
99917  return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&');
99918}
99919
99920function decode(s) {
99921  return decodeURIComponent(s);
99922} // Query keys/values should have the "+" replaced first, as "+" in a query string is " ".
99923// decodeURIComponent function will not decode "+" as a space.
99924
99925
99926function decodeQuery(s) {
99927  return decode(s.replace(/\+/g, '%20'));
99928}
99929
99930function serializePath(path) {
99931  return `${encodeUriSegment(path.path)}${serializeMatrixParams(path.parameters)}`;
99932}
99933
99934function serializeMatrixParams(params) {
99935  return Object.keys(params).map(key => `;${encodeUriSegment(key)}=${encodeUriSegment(params[key])}`).join('');
99936}
99937
99938function serializeQueryParams(params) {
99939  const strParams = Object.keys(params).map(name => {
99940    const value = params[name];
99941    return Array.isArray(value) ? value.map(v => `${encodeUriQuery(name)}=${encodeUriQuery(v)}`).join('&') : `${encodeUriQuery(name)}=${encodeUriQuery(value)}`;
99942  }).filter(s => !!s);
99943  return strParams.length ? `?${strParams.join('&')}` : '';
99944}
99945
99946const SEGMENT_RE = /^[^\/()?;=#]+/;
99947
99948function matchSegments(str) {
99949  const match = str.match(SEGMENT_RE);
99950  return match ? match[0] : '';
99951}
99952
99953const QUERY_PARAM_RE = /^[^=?&#]+/; // Return the name of the query param at the start of the string or an empty string
99954
99955function matchQueryParams(str) {
99956  const match = str.match(QUERY_PARAM_RE);
99957  return match ? match[0] : '';
99958}
99959
99960const QUERY_PARAM_VALUE_RE = /^[^&#]+/; // Return the value of the query param at the start of the string or an empty string
99961
99962function matchUrlQueryParamValue(str) {
99963  const match = str.match(QUERY_PARAM_VALUE_RE);
99964  return match ? match[0] : '';
99965}
99966
99967class UrlParser {
99968  constructor(url) {
99969    this.url = url;
99970    this.remaining = url;
99971  }
99972
99973  parseRootSegment() {
99974    this.consumeOptional('/');
99975
99976    if (this.remaining === '' || this.peekStartsWith('?') || this.peekStartsWith('#')) {
99977      return new UrlSegmentGroup([], {});
99978    } // The root segment group never has segments
99979
99980
99981    return new UrlSegmentGroup([], this.parseChildren());
99982  }
99983
99984  parseQueryParams() {
99985    const params = {};
99986
99987    if (this.consumeOptional('?')) {
99988      do {
99989        this.parseQueryParam(params);
99990      } while (this.consumeOptional('&'));
99991    }
99992
99993    return params;
99994  }
99995
99996  parseFragment() {
99997    return this.consumeOptional('#') ? decodeURIComponent(this.remaining) : null;
99998  }
99999
100000  parseChildren() {
100001    if (this.remaining === '') {
100002      return {};
100003    }
100004
100005    this.consumeOptional('/');
100006    const segments = [];
100007
100008    if (!this.peekStartsWith('(')) {
100009      segments.push(this.parseSegment());
100010    }
100011
100012    while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) {
100013      this.capture('/');
100014      segments.push(this.parseSegment());
100015    }
100016
100017    let children = {};
100018
100019    if (this.peekStartsWith('/(')) {
100020      this.capture('/');
100021      children = this.parseParens(true);
100022    }
100023
100024    let res = {};
100025
100026    if (this.peekStartsWith('(')) {
100027      res = this.parseParens(false);
100028    }
100029
100030    if (segments.length > 0 || Object.keys(children).length > 0) {
100031      res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children);
100032    }
100033
100034    return res;
100035  } // parse a segment with its matrix parameters
100036  // ie `name;k1=v1;k2`
100037
100038
100039  parseSegment() {
100040    const path = matchSegments(this.remaining);
100041
100042    if (path === '' && this.peekStartsWith(';')) {
100043      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4009
100044      /* RuntimeErrorCode.EMPTY_PATH_WITH_PARAMS */
100045      , NG_DEV_MODE$9 && `Empty path url segment cannot have parameters: '${this.remaining}'.`);
100046    }
100047
100048    this.capture(path);
100049    return new UrlSegment(decode(path), this.parseMatrixParams());
100050  }
100051
100052  parseMatrixParams() {
100053    const params = {};
100054
100055    while (this.consumeOptional(';')) {
100056      this.parseParam(params);
100057    }
100058
100059    return params;
100060  }
100061
100062  parseParam(params) {
100063    const key = matchSegments(this.remaining);
100064
100065    if (!key) {
100066      return;
100067    }
100068
100069    this.capture(key);
100070    let value = '';
100071
100072    if (this.consumeOptional('=')) {
100073      const valueMatch = matchSegments(this.remaining);
100074
100075      if (valueMatch) {
100076        value = valueMatch;
100077        this.capture(value);
100078      }
100079    }
100080
100081    params[decode(key)] = decode(value);
100082  } // Parse a single query parameter `name[=value]`
100083
100084
100085  parseQueryParam(params) {
100086    const key = matchQueryParams(this.remaining);
100087
100088    if (!key) {
100089      return;
100090    }
100091
100092    this.capture(key);
100093    let value = '';
100094
100095    if (this.consumeOptional('=')) {
100096      const valueMatch = matchUrlQueryParamValue(this.remaining);
100097
100098      if (valueMatch) {
100099        value = valueMatch;
100100        this.capture(value);
100101      }
100102    }
100103
100104    const decodedKey = decodeQuery(key);
100105    const decodedVal = decodeQuery(value);
100106
100107    if (params.hasOwnProperty(decodedKey)) {
100108      // Append to existing values
100109      let currentVal = params[decodedKey];
100110
100111      if (!Array.isArray(currentVal)) {
100112        currentVal = [currentVal];
100113        params[decodedKey] = currentVal;
100114      }
100115
100116      currentVal.push(decodedVal);
100117    } else {
100118      // Create a new value
100119      params[decodedKey] = decodedVal;
100120    }
100121  } // parse `(a/b//outlet_name:c/d)`
100122
100123
100124  parseParens(allowPrimary) {
100125    const segments = {};
100126    this.capture('(');
100127
100128    while (!this.consumeOptional(')') && this.remaining.length > 0) {
100129      const path = matchSegments(this.remaining);
100130      const next = this.remaining[path.length]; // if is is not one of these characters, then the segment was unescaped
100131      // or the group was not closed
100132
100133      if (next !== '/' && next !== ')' && next !== ';') {
100134        throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4010
100135        /* RuntimeErrorCode.UNPARSABLE_URL */
100136        , NG_DEV_MODE$9 && `Cannot parse url '${this.url}'`);
100137      }
100138
100139      let outletName = undefined;
100140
100141      if (path.indexOf(':') > -1) {
100142        outletName = path.slice(0, path.indexOf(':'));
100143        this.capture(outletName);
100144        this.capture(':');
100145      } else if (allowPrimary) {
100146        outletName = PRIMARY_OUTLET;
100147      }
100148
100149      const children = this.parseChildren();
100150      segments[outletName] = Object.keys(children).length === 1 ? children[PRIMARY_OUTLET] : new UrlSegmentGroup([], children);
100151      this.consumeOptional('//');
100152    }
100153
100154    return segments;
100155  }
100156
100157  peekStartsWith(str) {
100158    return this.remaining.startsWith(str);
100159  } // Consumes the prefix when it is present and returns whether it has been consumed
100160
100161
100162  consumeOptional(str) {
100163    if (this.peekStartsWith(str)) {
100164      this.remaining = this.remaining.substring(str.length);
100165      return true;
100166    }
100167
100168    return false;
100169  }
100170
100171  capture(str) {
100172    if (!this.consumeOptional(str)) {
100173      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4011
100174      /* RuntimeErrorCode.UNEXPECTED_VALUE_IN_URL */
100175      , NG_DEV_MODE$9 && `Expected "${str}".`);
100176    }
100177  }
100178
100179}
100180
100181function createRoot(rootCandidate) {
100182  return rootCandidate.segments.length > 0 ? new UrlSegmentGroup([], {
100183    [PRIMARY_OUTLET]: rootCandidate
100184  }) : rootCandidate;
100185}
100186/**
100187 * Recursively merges primary segment children into their parents and also drops empty children
100188 * (those which have no segments and no children themselves). The latter prevents serializing a
100189 * group into something like `/a(aux:)`, where `aux` is an empty child segment.
100190 */
100191
100192
100193function squashSegmentGroup(segmentGroup) {
100194  const newChildren = {};
100195
100196  for (const childOutlet of Object.keys(segmentGroup.children)) {
100197    const child = segmentGroup.children[childOutlet];
100198    const childCandidate = squashSegmentGroup(child); // don't add empty children
100199
100200    if (childCandidate.segments.length > 0 || childCandidate.hasChildren()) {
100201      newChildren[childOutlet] = childCandidate;
100202    }
100203  }
100204
100205  const s = new UrlSegmentGroup(segmentGroup.segments, newChildren);
100206  return mergeTrivialChildren(s);
100207}
100208/**
100209 * When possible, merges the primary outlet child into the parent `UrlSegmentGroup`.
100210 *
100211 * When a segment group has only one child which is a primary outlet, merges that child into the
100212 * parent. That is, the child segment group's segments are merged into the `s` and the child's
100213 * children become the children of `s`. Think of this like a 'squash', merging the child segment
100214 * group into the parent.
100215 */
100216
100217
100218function mergeTrivialChildren(s) {
100219  if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) {
100220    const c = s.children[PRIMARY_OUTLET];
100221    return new UrlSegmentGroup(s.segments.concat(c.segments), c.children);
100222  }
100223
100224  return s;
100225}
100226
100227function isUrlTree(v) {
100228  return v instanceof UrlTree;
100229}
100230/**
100231 * @license
100232 * Copyright Google LLC All Rights Reserved.
100233 *
100234 * Use of this source code is governed by an MIT-style license that can be
100235 * found in the LICENSE file at https://angular.io/license
100236 */
100237
100238
100239const NG_DEV_MODE$8 = typeof ngDevMode === 'undefined' || ngDevMode;
100240/**
100241 * Creates a `UrlTree` relative to an `ActivatedRouteSnapshot`.
100242 *
100243 * @publicApi
100244 *
100245 *
100246 * @param relativeTo The `ActivatedRouteSnapshot` to apply the commands to
100247 * @param commands An array of URL fragments with which to construct the new URL tree.
100248 * If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
100249 * segments, followed by the parameters for each segment.
100250 * The fragments are applied to the one provided in the `relativeTo` parameter.
100251 * @param queryParams The query parameters for the `UrlTree`. `null` if the `UrlTree` does not have
100252 *     any query parameters.
100253 * @param fragment The fragment for the `UrlTree`. `null` if the `UrlTree` does not have a fragment.
100254 *
100255 * @usageNotes
100256 *
100257 * ```
100258 * // create /team/33/user/11
100259 * createUrlTreeFromSnapshot(snapshot, ['/team', 33, 'user', 11]);
100260 *
100261 * // create /team/33;expand=true/user/11
100262 * createUrlTreeFromSnapshot(snapshot, ['/team', 33, {expand: true}, 'user', 11]);
100263 *
100264 * // you can collapse static segments like this (this works only with the first passed-in value):
100265 * createUrlTreeFromSnapshot(snapshot, ['/team/33/user', userId]);
100266 *
100267 * // If the first segment can contain slashes, and you do not want the router to split it,
100268 * // you can do the following:
100269 * createUrlTreeFromSnapshot(snapshot, [{segmentPath: '/one/two'}]);
100270 *
100271 * // create /team/33/(user/11//right:chat)
100272 * createUrlTreeFromSnapshot(snapshot, ['/team', 33, {outlets: {primary: 'user/11', right:
100273 * 'chat'}}], null, null);
100274 *
100275 * // remove the right secondary node
100276 * createUrlTreeFromSnapshot(snapshot, ['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
100277 *
100278 * // For the examples below, assume the current URL is for the `/team/33/user/11` and the
100279 * `ActivatedRouteSnapshot` points to `user/11`:
100280 *
100281 * // navigate to /team/33/user/11/details
100282 * createUrlTreeFromSnapshot(snapshot, ['details']);
100283 *
100284 * // navigate to /team/33/user/22
100285 * createUrlTreeFromSnapshot(snapshot, ['../22']);
100286 *
100287 * // navigate to /team/44/user/22
100288 * createUrlTreeFromSnapshot(snapshot, ['../../team/44/user/22']);
100289 * ```
100290 */
100291
100292function createUrlTreeFromSnapshot(relativeTo, commands, queryParams = null, fragment = null) {
100293  const relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeTo);
100294  return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, queryParams, fragment);
100295}
100296
100297function createSegmentGroupFromRoute(route) {
100298  let targetGroup;
100299
100300  function createSegmentGroupFromRouteRecursive(currentRoute) {
100301    const childOutlets = {};
100302
100303    for (const childSnapshot of currentRoute.children) {
100304      const root = createSegmentGroupFromRouteRecursive(childSnapshot);
100305      childOutlets[childSnapshot.outlet] = root;
100306    }
100307
100308    const segmentGroup = new UrlSegmentGroup(currentRoute.url, childOutlets);
100309
100310    if (currentRoute === route) {
100311      targetGroup = segmentGroup;
100312    }
100313
100314    return segmentGroup;
100315  }
100316
100317  const rootCandidate = createSegmentGroupFromRouteRecursive(route.root);
100318  const rootSegmentGroup = createRoot(rootCandidate);
100319  return targetGroup ?? rootSegmentGroup;
100320}
100321
100322function createUrlTreeFromSegmentGroup(relativeTo, commands, queryParams, fragment) {
100323  let root = relativeTo;
100324
100325  while (root.parent) {
100326    root = root.parent;
100327  } // There are no commands so the `UrlTree` goes to the same path as the one created from the
100328  // `UrlSegmentGroup`. All we need to do is update the `queryParams` and `fragment` without
100329  // applying any other logic.
100330
100331
100332  if (commands.length === 0) {
100333    return tree(root, root, root, queryParams, fragment);
100334  }
100335
100336  const nav = computeNavigation(commands);
100337
100338  if (nav.toRoot()) {
100339    return tree(root, root, new UrlSegmentGroup([], {}), queryParams, fragment);
100340  }
100341
100342  const position = findStartingPositionForTargetGroup(nav, root, relativeTo);
100343  const newSegmentGroup = position.processChildren ? updateSegmentGroupChildren(position.segmentGroup, position.index, nav.commands) : updateSegmentGroup(position.segmentGroup, position.index, nav.commands);
100344  return tree(root, position.segmentGroup, newSegmentGroup, queryParams, fragment);
100345}
100346
100347function createUrlTree(route, urlTree, commands, queryParams, fragment) {
100348  if (commands.length === 0) {
100349    return tree(urlTree.root, urlTree.root, urlTree.root, queryParams, fragment);
100350  }
100351
100352  const nav = computeNavigation(commands);
100353
100354  if (nav.toRoot()) {
100355    return tree(urlTree.root, urlTree.root, new UrlSegmentGroup([], {}), queryParams, fragment);
100356  }
100357
100358  function createTreeUsingPathIndex(lastPathIndex) {
100359    const startingPosition = findStartingPosition(nav, urlTree, route.
100359snapshot?._urlSegment, lastPathIndex);
100360    const segmentGroup = startingPosition.processChildren ? updateSegmentGroupChildren(startingPosition.segmentGroup, startingPosition.index, nav.commands) : updateSegmentGroup(startingPosition.segmentGroup, startingPosition.index, nav.commands);
100361    return tree(urlTree.root, startingPosition.segmentGroup, segmentGroup, queryParams, fragment);
100362  } // Note: The types should disallow `snapshot` from being `undefined` but due to test mocks, this
100363  // may be the case. Since we try to access it at an earlier point before the refactor to add the
100364  // warning for `relativeLinkResolution: 'legacy'`, this may cause failures in tests where it
100365  // didn't before.
100366
100367
100368  const result = createTreeUsingPathIndex(route.snapshot?._lastPathIndex); // Check if application is relying on `relativeLinkResolution: 'legacy'`
100369
100370  if (typeof ngDevMode === 'undefined' || !!ngDevMode) {
100371    const correctedResult = createTreeUsingPathIndex(route.snapshot?._correctedLastPathIndex);
100372
100373    if (correctedResult.toString() !== result.toString()) {
100374      console.warn(`relativeLinkResolution: 'legacy' is deprecated and will be removed in a future version of Angular. The link to ${result.toString()} will change to ${correctedResult.toString()} if the code is not updated before then.`);
100375    }
100376  }
100377
100378  return result;
100379}
100380
100381function isMatrixParams(command) {
100382  return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
100383}
100384/**
100385 * Determines if a given command has an `outlets` map. When we encounter a command
100386 * with an outlets k/v map, we need to apply each outlet individually to the existing segment.
100387 */
100388
100389
100390function isCommandWithOutlets(command) {
100391  return typeof command === 'object' && command != null && command.outlets;
100392}
100393
100394function tree(oldRoot, oldSegmentGroup, newSegmentGroup, queryParams, fragment) {
100395  let qp = {};
100396
100397  if (queryParams) {
100398    forEach(queryParams, (value, name) => {
100399      qp[name] = Array.isArray(value) ? value.map(v => `${v}`) : `${value}`;
100400    });
100401  }
100402
100403  let rootCandidate;
100404
100405  if (oldRoot === oldSegmentGroup) {
100406    rootCandidate = newSegmentGroup;
100407  } else {
100408    rootCandidate = replaceSegment(oldRoot, oldSegmentGroup, newSegmentGroup);
100409  }
100410
100411  const newRoot = createRoot(squashSegmentGroup(rootCandidate));
100412  return new UrlTree(newRoot, qp, fragment);
100413}
100414/**
100415 * Replaces the `oldSegment` which is located in some child of the `current` with the `newSegment`.
100416 * This also has the effect of creating new `UrlSegmentGroup` copies to update references. This
100417 * shouldn't be necessary but the fallback logic for an invalid ActivatedRoute in the creation uses
100418 * the Router's current url tree. If we don't create new segment groups, we end up modifying that
100419 * value.
100420 */
100421
100422
100423function replaceSegment(current, oldSegment, newSegment) {
100424  const children = {};
100425  forEach(current.children, (c, outletName) => {
100426    if (c === oldSegment) {
100427      children[outletName] = newSegment;
100428    } else {
100429      children[outletName] = replaceSegment(c, oldSegment, newSegment);
100430    }
100431  });
100432  return new UrlSegmentGroup(current.segments, children);
100433}
100434
100435class Navigation {
100436  constructor(isAbsolute, numberOfDoubleDots, commands) {
100437    this.isAbsolute = isAbsolute;
100438    this.numberOfDoubleDots = numberOfDoubleDots;
100439    this.commands = commands;
100440
100441    if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
100442      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4003
100443      /* RuntimeErrorCode.ROOT_SEGMENT_MATRIX_PARAMS */
100444      , NG_DEV_MODE$8 && 'Root segment cannot have matrix parameters');
100445    }
100446
100447    const cmdWithOutlet = commands.find(isCommandWithOutlets);
100448
100449    if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
100450      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4004
100451      /* RuntimeErrorCode.MISPLACED_OUTLETS_COMMAND */
100452      , NG_DEV_MODE$8 && '{outlets:{}} has to be the last command');
100453    }
100454  }
100455
100456  toRoot() {
100457    return this.isAbsolute && this.commands.length === 1 && this.commands[0] == '/';
100458  }
100459
100460}
100461/** Transforms commands to a normalized `Navigation` */
100462
100463
100464function computeNavigation(commands) {
100465  if (typeof commands[0] === 'string' && commands.length === 1 && commands[0] === '/') {
100466    return new Navigation(true, 0, commands);
100467  }
100468
100469  let numberOfDoubleDots = 0;
100470  let isAbsolute = false;
100471  const res = commands.reduce((res, cmd, cmdIdx) => {
100472    if (typeof cmd === 'object' && cmd != null) {
100473      if (cmd.outlets) {
100474        const outlets = {};
100475        forEach(cmd.outlets, (commands, name) => {
100476          outlets[name] = typeof commands === 'string' ? commands.split('/') : commands;
100477        });
100478        return [...res, {
100479          outlets
100480        }];
100481      }
100482
100483      if (cmd.segmentPath) {
100484        return [...res, cmd.segmentPath];
100485      }
100486    }
100487
100488    if (!(typeof cmd === 'string')) {
100489      return [...res, cmd];
100490    }
100491
100492    if (cmdIdx === 0) {
100493      cmd.split('/').forEach((urlPart, partIndex) => {
100494        if (partIndex == 0 && urlPart === '.') {// skip './a'
100495        } else if (partIndex == 0 && urlPart === '') {
100496          //  '/a'
100497          isAbsolute = true;
100498        } else if (urlPart === '..') {
100499          //  '../a'
100500          numberOfDoubleDots++;
100501        } else if (urlPart != '') {
100502          res.push(urlPart);
100503        }
100504      });
100505      return res;
100506    }
100507
100508    return [...res, cmd];
100509  }, []);
100510  return new Navigation(isAbsolute, numberOfDoubleDots, res);
100511}
100512
100513class Position {
100514  constructor(segmentGroup, processChildren, index) {
100515    this.segmentGroup = segmentGroup;
100516    this.processChildren = processChildren;
100517    this.index = index;
100518  }
100519
100520}
100521
100522function findStartingPositionForTargetGroup(nav, root, target) {
100523  if (nav.isAbsolute) {
100524    return new Position(root, true, 0);
100525  }
100526
100527  if (!target) {
100528    // `NaN` is used only to maintain backwards compatibility with incorrectly mocked
100529    // `ActivatedRouteSnapshot` in tests. In prior versions of this code, the position here was
100530    // determined based on an internal property that was rarely mocked, resulting in `NaN`. In
100531    // reality, this code path should _never_ be touched since `target` is not allowed to be falsey.
100532    return new Position(root, false, NaN);
100533  }
100534
100535  if (target.parent === null) {
100536    return new Position(target, true, 0);
100537  }
100538
100539  const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
100540  const index = target.segments.length - 1 + modifier;
100541  return createPositionApplyingDoubleDots(target, index, nav.numberOfDoubleDots);
100542}
100543
100544function findStartingPosition(nav, tree, segmentGroup, lastPathIndex) {
100545  if (nav.isAbsolute) {
100546    return new Position(tree.root, true, 0);
100547  }
100548
100549  if (lastPathIndex === -1) {
100550    // Pathless ActivatedRoute has _lastPathIndex === -1 but should not process children
100551    // see issue #26224, #13011, #35687
100552    // However, if the ActivatedRoute is the root we should process children like above.
100553    const processChildren = segmentGroup === tree.root;
100554    return new Position(segmentGroup, processChildren, 0);
100555  }
100556
100557  const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
100558  const index = lastPathIndex + modifier;
100559  return createPositionApplyingDoubleDots(segmentGroup, index, nav.numberOfDoubleDots);
100560}
100561
100562function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
100563  let g = group;
100564  let ci = index;
100565  let dd = numberOfDoubleDots;
100566
100567  while (dd > ci) {
100568    dd -= ci;
100569    g = g.parent;
100570
100571    if (!g) {
100572      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4005
100573      /* RuntimeErrorCode.INVALID_DOUBLE_DOTS */
100574      , NG_DEV_MODE$8 && 'Invalid number of \'../\'');
100575    }
100576
100577    ci = g.segments.length;
100578  }
100579
100580  return new Position(g, false, ci - dd);
100581}
100582
100583function getOutlets(commands) {
100584  if (isCommandWithOutlets(commands[0])) {
100585    return commands[0].outlets;
100586  }
100587
100588  return {
100589    [PRIMARY_OUTLET]: commands
100590  };
100591}
100592
100593function updateSegmentGroup(segmentGroup, startIndex, commands) {
100594  if (!segmentGroup) {
100595    segmentGroup = new UrlSegmentGroup([], {});
100596  }
100597
100598  if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
100599    return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
100600  }
100601
100602  const m = prefixedWith(segmentGroup, startIndex, commands);
100603  const slicedCommands = commands.slice(m.commandIndex);
100604
100605  if (m.match && m.pathIndex < segmentGroup.segments.length) {
100606    const g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {});
100607    g.children[PRIMARY_OUTLET] = new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children);
100608    return updateSegmentGroupChildren(g, 0, slicedCommands);
100609  } else if (m.match && slicedCommands.length === 0) {
100610    return new UrlSegmentGroup(segmentGroup.segments, {});
100611  } else if (m.match && !segmentGroup.hasChildren()) {
100612    return createNewSegmentGroup(segmentGroup, startIndex, commands);
100613  } else if (m.match) {
100614    return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands);
100615  } else {
100616    return createNewSegmentGroup(segmentGroup, startIndex, commands);
100617  }
100618}
100619
100620function updateSegmentGroupChildren(segmentGroup, startIndex, commands) {
100621  if (commands.length === 0) {
100622    return new UrlSegmentGroup(segmentGroup.segments, {});
100623  } else {
100624    const outlets = getOutlets(commands);
100625    const children = {};
100626    forEach(outlets, (commands, outlet) => {
100627      if (typeof commands === 'string') {
100628        commands = [commands];
100629      }
100630
100631      if (commands !== null) {
100632        children[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands);
100633      }
100634    });
100635    forEach(segmentGroup.children, (child, childOutlet) => {
100636      if (outlets[childOutlet] === undefined) {
100637        children[childOutlet] = child;
100638      }
100639    });
100640    return new UrlSegmentGroup(segmentGroup.segments, children);
100641  }
100642}
100643
100644function prefixedWith(segmentGroup, startIndex, commands) {
100645  let currentCommandIndex = 0;
100646  let currentPathIndex = startIndex;
100647  const noMatch = {
100648    match: false,
100649    pathIndex: 0,
100650    commandIndex: 0
100651  };
100652
100653  while (currentPathIndex < segmentGroup.segments.length) {
100654    if (currentCommandIndex >= commands.length) return noMatch;
100655    const path = segmentGroup.segments[currentPathIndex];
100656    const command = commands[currentCommandIndex]; // Do not try to consume command as part of the prefixing if it has outlets because it can
100657    // contain outlets other than the one being processed. Consuming the outlets command would
100658    // result in other outlets being ignored.
100659
100660    if (isCommandWithOutlets(command)) {
100661      break;
100662    }
100663
100664    const curr = `${command}`;
100665    const next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
100666    if (currentPathIndex > 0 && curr === undefined) break;
100667
100668    if (curr && next && typeof next === 'object' && next.outlets === undefined) {
100669      if (!compare(curr, next, path)) return noMatch;
100670      currentCommandIndex += 2;
100671    } else {
100672      if (!compare(curr, {}, path)) return noMatch;
100673      currentCommandIndex++;
100674    }
100675
100676    currentPathIndex++;
100677  }
100678
100679  return {
100680    match: true,
100681    pathIndex: currentPathIndex,
100682    commandIndex: currentCommandIndex
100683  };
100684}
100685
100686function createNewSegmentGroup(segmentGroup, startIndex, commands) {
100687  const paths = segmentGroup.segments.slice(0, startIndex);
100688  let i = 0;
100689
100690  while (i < commands.length) {
100691    const command = commands[i];
100692
100693    if (isCommandWithOutlets(command)) {
100694      const children = createNewSegmentChildren(command.outlets);
100695      return new UrlSegmentGroup(paths, children);
100696    } // if we start with an object literal, we need to reuse the path part from the segment
100697
100698
100699    if (i === 0 && isMatrixParams(commands[0])) {
100700      const p = segmentGroup.segments[startIndex];
100701      paths.push(new UrlSegment(p.path, stringify(commands[0])));
100702      i++;
100703      continue;
100704    }
100705
100706    const curr = isCommandWithOutlets(command) ? command.outlets[PRIMARY_OUTLET] : `${command}`;
100707    const next = i < commands.length - 1 ? commands[i + 1] : null;
100708
100709    if (curr && next && isMatrixParams(next)) {
100710      paths.push(new UrlSegment(curr, stringify(next)));
100711      i += 2;
100712    } else {
100713      paths.push(new UrlSegment(curr, {}));
100714      i++;
100715    }
100716  }
100717
100718  return new UrlSegmentGroup(paths, {});
100719}
100720
100721function createNewSegmentChildren(outlets) {
100722  const children = {};
100723  forEach(outlets, (commands, outlet) => {
100724    if (typeof commands === 'string') {
100725      commands = [commands];
100726    }
100727
100728    if (commands !== null) {
100729      children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands);
100730    }
100731  });
100732  return children;
100733}
100734
100735function stringify(params) {
100736  const res = {};
100737  forEach(params, (v, k) => res[k] = `${v}`);
100738  return res;
100739}
100740
100741function compare(path, params, segment) {
100742  return path == segment.path && shallowEqual(params, segment.parameters);
100743}
100744/**
100745 * @license
100746 * Copyright Google LLC All Rights Reserved.
100747 *
100748 * Use of this source code is governed by an MIT-style license that can be
100749 * found in the LICENSE file at https://angular.io/license
100750 */
100751
100752/**
100753 * Base for events the router goes through, as opposed to events tied to a specific
100754 * route. Fired one time for any given navigation.
100755 *
100756 * The following code shows how a class subscribes to router events.
100757 *
100758 * ```ts
100759 * import {Event, RouterEvent, Router} from '@angular/router';
100760 *
100761 * class MyService {
100762 *   constructor(public router: Router) {
100763 *     router.events.pipe(
100764 *        filter((e: Event): e is RouterEvent => e instanceof RouterEvent)
100765 *     ).subscribe((e: RouterEvent) => {
100766 *       // Do something
100767 *     });
100768 *   }
100769 * }
100770 * ```
100771 *
100772 * @see `Event`
100773 * @see [Router events summary](guide/router-reference#router-events)
100774 * @publicApi
100775 */
100776
100777
100778class RouterEvent {
100779  constructor(
100780  /** A unique ID that the router assigns to every router navigation. */
100781  id,
100782  /** The URL that is the destination for this navigation. */
100783  url) {
100784    this.id = id;
100785    this.url = url;
100786  }
100787
100788}
100789/**
100790 * An event triggered when a navigation starts.
100791 *
100792 * @publicApi
100793 */
100794
100795
100796class NavigationStart extends RouterEvent {
100797  constructor(
100798  /** @docsNotRequired */
100799  id,
100800  /** @docsNotRequired */
100801  url,
100802  /** @docsNotRequired */
100803  navigationTrigger = 'imperative',
100804  /** @docsNotRequired */
100805  restoredState = null) {
100806    super(id, url);
100807    this.type = 0
100808    /* EventType.NavigationStart */
100809    ;
100810    this.navigationTrigger = navigationTrigger;
100811    this.restoredState = restoredState;
100812  }
100813  /** @docsNotRequired */
100814
100815
100816  toString() {
100817    return `NavigationStart(id: ${this.id}, url: '${this.url}')`;
100818  }
100819
100820}
100821/**
100822 * An event triggered when a navigation ends successfully.
100823 *
100824 * @see `NavigationStart`
100825 * @see `NavigationCancel`
100826 * @see `NavigationError`
100827 *
100828 * @publicApi
100829 */
100830
100831
100832class NavigationEnd extends RouterEvent {
100833  constructor(
100834  /** @docsNotRequired */
100835  id,
100836  /** @docsNotRequired */
100837  url,
100838  /** @docsNotRequired */
100839  urlAfterRedirects) {
100840    super(id, url);
100841    this.urlAfterRedirects = urlAfterRedirects;
100842    this.type = 1
100843    /* EventType.NavigationEnd */
100844    ;
100845  }
100846  /** @docsNotRequired */
100847
100848
100849  toString() {
100850    return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
100851  }
100852
100853}
100854/**
100855 * An event triggered when a navigation is canceled, directly or indirectly.
100856 * This can happen for several reasons including when a route guard
100857 * returns `false` or initiates a redirect by returning a `UrlTree`.
100858 *
100859 * @see `NavigationStart`
100860 * @see `NavigationEnd`
100861 * @see `NavigationError`
100862 *
100863 * @publicApi
100864 */
100865
100866
100867class NavigationCancel extends RouterEvent {
100868  constructor(
100869  /** @docsNotRequired */
100870  id,
100871  /** @docsNotRequired */
100872  url,
100873  /**
100874   * A description of why the navigation was cancelled. For debug purposes only. Use `code`
100875   * instead for a stable cancellation reason that can be used in production.
100876   */
100877  reason,
100878  /**
100879   * A code to indicate why the navigation was canceled. This cancellation code is stable for
100880   * the reason and can be relied on whereas the `reason` string could change and should not be
100881   * used in production.
100882   */
100883  code) {
100884    super(id, url);
100885    this.reason = reason;
100886    this.code = code;
100887    this.type = 2
100888    /* EventType.NavigationCancel */
100889    ;
100890  }
100891  /** @docsNotRequired */
100892
100893
100894  toString() {
100895    return `NavigationCancel(id: ${this.id}, url: '${this.url}')`;
100896  }
100897
100898}
100899/**
100900 * An event triggered when a navigation fails due to an unexpected error.
100901 *
100902 * @see `NavigationStart`
100903 * @see `NavigationEnd`
100904 * @see `NavigationCancel`
100905 *
100906 * @publicApi
100907 */
100908
100909
100910class NavigationError extends RouterEvent {
100911  constructor(
100912  /** @docsNotRequired */
100913  id,
100914  /** @docsNotRequired */
100915  url,
100916  /** @docsNotRequired */
100917  error,
100918  /**
100919   * The target of the navigation when the error occurred.
100920   *
100921   * Note that this can be `undefined` because an error could have occurred before the
100922   * `RouterStateSnapshot` was created for the navigation.
100923   */
100924  target) {
100925    super(id, url);
100926    this.error = error;
100927    this.target = target;
100928    this.type = 3
100929    /* EventType.NavigationError */
100930    ;
100931  }
100932  /** @docsNotRequired */
100933
100934
100935  toString() {
100936    return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
100937  }
100938
100939}
100940/**
100941 * An event triggered when routes are recognized.
100942 *
100943 * @publicApi
100944 */
100945
100946
100947class RoutesRecognized extends RouterEvent {
100948  constructor(
100949  /** @docsNotRequired */
100950  id,
100951  /** @docsNotRequired */
100952  url,
100953  /** @docsNotRequired */
100954  urlAfterRedirects,
100955  /** @docsNotRequired */
100956  state) {
100957    super(id, url);
100958    this.urlAfterRedirects = urlAfterRedirects;
100959    this.state = state;
100960    this.type = 4
100961    /* EventType.RoutesRecognized */
100962    ;
100963  }
100964  /** @docsNotRequired */
100965
100966
100967  toString() {
100968    return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
100969  }
100970
100971}
100972/**
100973 * An event triggered at the start of the Guard phase of routing.
100974 *
100975 * @see `GuardsCheckEnd`
100976 *
100977 * @publicApi
100978 */
100979
100980
100981class GuardsCheckStart extends RouterEvent {
100982  constructor(
100983  /** @docsNotRequired */
100984  id,
100985  /** @docsNotRequired */
100986  url,
100987  /** @docsNotRequired */
100988  urlAfterRedirects,
100989  /** @docsNotRequired */
100990  state) {
100991    super(id, url);
100992    this.urlAfterRedirects = urlAfterRedirects;
100993    this.state = state;
100994    this.type = 7
100995    /* EventType.GuardsCheckStart */
100996    ;
100997  }
100998
100999  toString() {
101000    return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
101001  }
101002
101003}
101004/**
101005 * An event triggered at the end of the Guard phase of routing.
101006 *
101007 * @see `GuardsCheckStart`
101008 *
101009 * @publicApi
101010 */
101011
101012
101013class GuardsCheckEnd extends RouterEvent {
101014  constructor(
101015  /** @docsNotRequired */
101016  id,
101017  /** @docsNotRequired */
101018  url,
101019  /** @docsNotRequired */
101020  urlAfterRedirects,
101021  /** @docsNotRequired */
101022  state,
101023  /** @docsNotRequired */
101024  shouldActivate) {
101025    super(id, url);
101026    this.urlAfterRedirects = urlAfterRedirects;
101027    this.state = state;
101028    this.shouldActivate = shouldActivate;
101029    this.type = 8
101030    /* EventType.GuardsCheckEnd */
101031    ;
101032  }
101033
101034  toString() {
101035    return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`;
101036  }
101037
101038}
101039/**
101040 * An event triggered at the start of the Resolve phase of routing.
101041 *
101042 * Runs in the "resolve" phase whether or not there is anything to resolve.
101043 * In future, may change to only run when there are things to be resolved.
101044 *
101045 * @see `ResolveEnd`
101046 *
101047 * @publicApi
101048 */
101049
101050
101051class ResolveStart extends RouterEvent {
101052  constructor(
101053  /** @docsNotRequired */
101054  id,
101055  /** @docsNotRequired */
101056  url,
101057  /** @docsNotRequired */
101058  urlAfterRedirects,
101059  /** @docsNotRequired */
101060  state) {
101061    super(id, url);
101062    this.urlAfterRedirects = urlAfterRedirects;
101063    this.state = state;
101064    this.type = 5
101065    /* EventType.ResolveStart */
101066    ;
101067  }
101068
101069  toString() {
101070    return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
101071  }
101072
101073}
101074/**
101075 * An event triggered at the end of the Resolve phase of routing.
101076 * @see `ResolveStart`.
101077 *
101078 * @publicApi
101079 */
101080
101081
101082class ResolveEnd extends RouterEvent {
101083  constructor(
101084  /** @docsNotRequired */
101085  id,
101086  /** @docsNotRequired */
101087  url,
101088  /** @docsNotRequired */
101089  urlAfterRedirects,
101090  /** @docsNotRequired */
101091  state) {
101092    super(id, url);
101093    this.urlAfterRedirects = urlAfterRedirects;
101094    this.state = state;
101095    this.type = 6
101096    /* EventType.ResolveEnd */
101097    ;
101098  }
101099
101100  toString() {
101101    return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
101102  }
101103
101104}
101105/**
101106 * An event triggered before lazy loading a route configuration.
101107 *
101108 * @see `RouteConfigLoadEnd`
101109 *
101110 * @publicApi
101111 */
101112
101113
101114class RouteConfigLoadStart {
101115  constructor(
101116  /** @docsNotRequired */
101117  route) {
101118    this.route = route;
101119    this.type = 9
101120    /* EventType.RouteConfigLoadStart */
101121    ;
101122  }
101123
101124  toString() {
101125    return `RouteConfigLoadStart(path: ${this.route.path})`;
101126  }
101127
101128}
101129/**
101130 * An event triggered when a route has been lazy loaded.
101131 *
101132 * @see `RouteConfigLoadStart`
101133 *
101134 * @publicApi
101135 */
101136
101137
101138class RouteConfigLoadEnd {
101139  constructor(
101140  /** @docsNotRequired */
101141  route) {
101142    this.route = route;
101143    this.type = 10
101144    /* EventType.RouteConfigLoadEnd */
101145    ;
101146  }
101147
101148  toString() {
101149    return `RouteConfigLoadEnd(path: ${this.route.path})`;
101150  }
101151
101152}
101153/**
101154 * An event triggered at the start of the child-activation
101155 * part of the Resolve phase of routing.
101156 * @see  `ChildActivationEnd`
101157 * @see `ResolveStart`
101158 *
101159 * @publicApi
101160 */
101161
101162
101163class ChildActivationStart {
101164  constructor(
101165  /** @docsNotRequired */
101166  snapshot) {
101167    this.snapshot = snapshot;
101168    this.type = 11
101169    /* EventType.ChildActivationStart */
101170    ;
101171  }
101172
101173  toString() {
101174    const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
101175    return `ChildActivationStart(path: '${path}')`;
101176  }
101177
101178}
101179/**
101180 * An event triggered at the end of the child-activation part
101181 * of the Resolve phase of routing.
101182 * @see `ChildActivationStart`
101183 * @see `ResolveStart`
101184 * @publicApi
101185 */
101186
101187
101188class ChildActivationEnd {
101189  constructor(
101190  /** @docsNotRequired */
101191  snapshot) {
101192    this.snapshot = snapshot;
101193    this.type = 12
101194    /* EventType.ChildActivationEnd */
101195    ;
101196  }
101197
101198  toString() {
101199    const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
101200    return `ChildActivationEnd(path: '${path}')`;
101201  }
101202
101203}
101204/**
101205 * An event triggered at the start of the activation part
101206 * of the Resolve phase of routing.
101207 * @see `ActivationEnd`
101208 * @see `ResolveStart`
101209 *
101210 * @publicApi
101211 */
101212
101213
101214class ActivationStart {
101215  constructor(
101216  /** @docsNotRequired */
101217  snapshot) {
101218    this.snapshot = snapshot;
101219    this.type = 13
101220    /* EventType.ActivationStart */
101221    ;
101222  }
101223
101224  toString() {
101225    const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
101226    return `ActivationStart(path: '${path}')`;
101227  }
101228
101229}
101230/**
101231 * An event triggered at the end of the activation part
101232 * of the Resolve phase of routing.
101233 * @see `ActivationStart`
101234 * @see `ResolveStart`
101235 *
101236 * @publicApi
101237 */
101238
101239
101240class ActivationEnd {
101241  constructor(
101242  /** @docsNotRequired */
101243  snapshot) {
101244    this.snapshot = snapshot;
101245    this.type = 14
101246    /* EventType.ActivationEnd */
101247    ;
101248  }
101249
101250  toString() {
101251    const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
101252    return `ActivationEnd(path: '${path}')`;
101253  }
101254
101255}
101256/**
101257 * An event triggered by scrolling.
101258 *
101259 * @publicApi
101260 */
101261
101262
101263class Scroll {
101264  constructor(
101265  /** @docsNotRequired */
101266  routerEvent,
101267  /** @docsNotRequired */
101268  position,
101269  /** @docsNotRequired */
101270  anchor) {
101271    this.routerEvent = routerEvent;
101272    this.position = position;
101273    this.anchor = anchor;
101274    this.type = 15
101275    /* EventType.Scroll */
101276    ;
101277  }
101278
101279  toString() {
101280    const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null;
101281    return `Scroll(anchor: '${this.anchor}', position: '${pos}')`;
101282  }
101283
101284}
101285
101286function stringifyEvent(routerEvent) {
101287  if (!('type' in routerEvent)) {
101288    return `Unknown Router Event: ${routerEvent.constructor.name}`;
101289  }
101290
101291  switch (routerEvent.type) {
101292    case 14
101293    /* EventType.ActivationEnd */
101294    :
101295      return `ActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
101296
101297    case 13
101298    /* EventType.ActivationStart */
101299    :
101300      return `ActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
101301
101302    case 12
101303    /* EventType.ChildActivationEnd */
101304    :
101305      return `ChildActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
101306
101307    case 11
101308    /* EventType.ChildActivationStart */
101309    :
101310      return `ChildActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
101311
101312    case 8
101313    /* EventType.GuardsCheckEnd */
101314    :
101315      return `GuardsCheckEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state}, shouldActivate: ${routerEvent.shouldActivate})`;
101316
101317    case 7
101318    /* EventType.GuardsCheckStart */
101319    :
101320      return `GuardsCheckStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
101321
101322    case 2
101323    /* EventType.NavigationCancel */
101324    :
101325      return `NavigationCancel(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
101326
101327    case 1
101328    /* EventType.NavigationEnd */
101329    :
101330      return `NavigationEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}')`;
101331
101332    case 3
101333    /* EventType.NavigationError */
101334    :
101335      return `NavigationError(id: ${routerEvent.id}, url: '${routerEvent.url}', error: ${routerEvent.error})`;
101336
101337    case 0
101338    /* EventType.NavigationStart */
101339    :
101340      return `NavigationStart(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
101341
101342    case 6
101343    /* EventType.ResolveEnd */
101344    :
101345      return `ResolveEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}
101345', state: ${routerEvent.state})`;
101346
101347    case 5
101348    /* EventType.ResolveStart */
101349    :
101350      return `ResolveStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
101351
101352    case 10
101353    /* EventType.RouteConfigLoadEnd */
101354    :
101355      return `RouteConfigLoadEnd(path: ${routerEvent.route.path})`;
101356
101357    case 9
101358    /* EventType.RouteConfigLoadStart */
101359    :
101360      return `RouteConfigLoadStart(path: ${routerEvent.route.path})`;
101361
101362    case 4
101363    /* EventType.RoutesRecognized */
101364    :
101365      return `RoutesRecognized(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
101366
101367    case 15
101368    /* EventType.Scroll */
101369    :
101370      const pos = routerEvent.position ? `${routerEvent.position[0]}, ${routerEvent.position[1]}` : null;
101371      return `Scroll(anchor: '${routerEvent.anchor}', position: '${pos}')`;
101372  }
101373}
101374/**
101375 * @license
101376 * Copyright Google LLC All Rights Reserved.
101377 *
101378 * Use of this source code is governed by an MIT-style license that can be
101379 * found in the LICENSE file at https://angular.io/license
101380 */
101381
101382
101383class Tree {
101384  constructor(root) {
101385    this._root = root;
101386  }
101387
101388  get root() {
101389    return this._root.value;
101390  }
101391  /**
101392   * @internal
101393   */
101394
101395
101396  parent(t) {
101397    const p = this.pathFromRoot(t);
101398    return p.length > 1 ? p[p.length - 2] : null;
101399  }
101400  /**
101401   * @internal
101402   */
101403
101404
101405  children(t) {
101406    const n = findNode(t, this._root);
101407    return n ? n.children.map(t => t.value) : [];
101408  }
101409  /**
101410   * @internal
101411   */
101412
101413
101414  firstChild(t) {
101415    const n = findNode(t, this._root);
101416    return n && n.children.length > 0 ? n.children[0].value : null;
101417  }
101418  /**
101419   * @internal
101420   */
101421
101422
101423  siblings(t) {
101424    const p = findPath(t, this._root);
101425    if (p.length < 2) return [];
101426    const c = p[p.length - 2].children.map(c => c.value);
101427    return c.filter(cc => cc !== t);
101428  }
101429  /**
101430   * @internal
101431   */
101432
101433
101434  pathFromRoot(t) {
101435    return findPath(t, this._root).map(s => s.value);
101436  }
101437
101438} // DFS for the node matching the value
101439
101440
101441function findNode(value, node) {
101442  if (value === node.value) return node;
101443
101444  for (const child of node.children) {
101445    const node = findNode(value, child);
101446    if (node) return node;
101447  }
101448
101449  return null;
101450} // Return the path to the node with the given value using DFS
101451
101452
101453function findPath(value, node) {
101454  if (value === node.value) return [node];
101455
101456  for (const child of node.children) {
101457    const path = findPath(value, child);
101458
101459    if (path.length) {
101460      path.unshift(node);
101461      return path;
101462    }
101463  }
101464
101465  return [];
101466}
101467
101468class TreeNode {
101469  constructor(value, children) {
101470    this.value = value;
101471    this.children = children;
101472  }
101473
101474  toString() {
101475    return `TreeNode(${this.value})`;
101476  }
101477
101478} // Return the list of T indexed by outlet name
101479
101480
101481function nodeChildrenAsMap(node) {
101482  const map = {};
101483
101484  if (node) {
101485    node.children.forEach(child => map[child.value.outlet] = child);
101486  }
101487
101488  return map;
101489}
101490/**
101491 * @license
101492 * Copyright Google LLC All Rights Reserved.
101493 *
101494 * Use of this source code is governed by an MIT-style license that can be
101495 * found in the LICENSE file at https://angular.io/license
101496 */
101497
101498/**
101499 * Represents the state of the router as a tree of activated routes.
101500 *
101501 * @usageNotes
101502 *
101503 * Every node in the route tree is an `ActivatedRoute` instance
101504 * that knows about the "consumed" URL segments, the extracted parameters,
101505 * and the resolved data.
101506 * Use the `ActivatedRoute` properties to traverse the tree from any node.
101507 *
101508 * The following fragment shows how a component gets the root node
101509 * of the current state to establish its own route tree:
101510 *
101511 * ```
101512 * @Component({templateUrl:'template.html'})
101513 * class MyComponent {
101514 *   constructor(router: Router) {
101515 *     const state: RouterState = router.routerState;
101516 *     const root: ActivatedRoute = state.root;
101517 *     const child = root.firstChild;
101518 *     const id: Observable<string> = child.params.map(p => p.id);
101519 *     //...
101520 *   }
101521 * }
101522 * ```
101523 *
101524 * @see `ActivatedRoute`
101525 * @see [Getting route information](guide/router#getting-route-information)
101526 *
101527 * @publicApi
101528 */
101529
101530
101531class RouterState extends Tree {
101532  /** @internal */
101533  constructor(root,
101534  /** The current snapshot of the router state */
101535  snapshot) {
101536    super(root);
101537    this.snapshot = snapshot;
101538    setRouterState(this, root);
101539  }
101540
101541  toString() {
101542    return this.snapshot.toString();
101543  }
101544
101545}
101546
101547function createEmptyState(urlTree, rootComponent) {
101548  const snapshot = createEmptyStateSnapshot(urlTree, rootComponent);
101549  const emptyUrl = new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject([new UrlSegment('', {})]);
101550  const emptyParams = new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject({});
101551  const emptyData = new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject({});
101552  const emptyQueryParams = new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject({});
101553  const fragment = new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject('');
101554  const activated = new ActivatedRoute(emptyUrl, emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, snapshot.root);
101555  activated.snapshot = snapshot.root;
101556  return new RouterState(new TreeNode(activated, []), snapshot);
101557}
101558
101559function createEmptyStateSnapshot(urlTree, rootComponent) {
101560  const emptyParams = {};
101561  const emptyData = {};
101562  const emptyQueryParams = {};
101563  const fragment = '';
101564  const activated = new ActivatedRouteSnapshot([], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null, urlTree.root, -1, {});
101565  return new RouterStateSnapshot('', new TreeNode(activated, []));
101566}
101567/**
101568 * Provides access to information about a route associated with a component
101569 * that is loaded in an outlet.
101570 * Use to traverse the `RouterState` tree and extract information from nodes.
101571 *
101572 * The following example shows how to construct a component using information from a
101573 * currently activated route.
101574 *
101575 * Note: the observables in this class only emit when the current and previous values differ based
101576 * on shallow equality. For example, changing deeply nested properties in resolved `data` will not
101577 * cause the `ActivatedRoute.data` `Observable` to emit a new value.
101578 *
101579 * {@example router/activated-route/module.ts region="activated-route"
101580 *     header="activated-route.component.ts"}
101581 *
101582 * @see [Getting route information](guide/router#getting-route-information)
101583 *
101584 * @publicApi
101585 */
101586
101587
101588class ActivatedRoute {
101589  /** @internal */
101590  constructor(
101591  /** An observable of the URL segments matched by this route. */
101592  url,
101593  /** An observable of the matrix parameters scoped to this route. */
101594  params,
101595  /** An observable of the query parameters shared by all the routes. */
101596  queryParams,
101597  /** An observable of the URL fragment shared by all the routes. */
101598  fragment,
101599  /** An observable of the static and resolved data of this route. */
101600  data,
101601  /** The outlet name of the route, a constant. */
101602  outlet,
101603  /** The component of the route, a constant. */
101604  component, futureSnapshot) {
101605    this.url = url;
101606    this.params = params;
101607    this.queryParams = queryParams;
101608    this.fragment = fragment;
101609    this.data = data;
101610    this.outlet = outlet;
101611    this.component = component;
101612    /** An Observable of the resolved route title */
101613
101614    this.title = this.data?.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(d => d[RouteTitleKey])) ?? (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(undefined);
101615    this._futureSnapshot = futureSnapshot;
101616  }
101617  /** The configuration used to match this route. */
101618
101619
101620  get routeConfig() {
101621    return this._futureSnapshot.routeConfig;
101622  }
101623  /** The root of the router state. */
101624
101625
101626  get root() {
101627    return this._routerState.root;
101628  }
101629  /** The parent of this route in the router state tree. */
101630
101631
101632  get parent() {
101633    return this._routerState.parent(this);
101634  }
101635  /** The first child of this route in the router state tree. */
101636
101637
101638  get firstChild() {
101639    return this._routerState.firstChild(this);
101640  }
101641  /** The children of this route in the router state tree. */
101642
101643
101644  get children() {
101645    return this._routerState.children(this);
101646  }
101647  /** The path from the root of the router state tree to this route. */
101648
101649
101650  get pathFromRoot() {
101651    return this._routerState.pathFromRoot(this);
101652  }
101653  /**
101654   * An Observable that contains a map of the required and optional parameters
101655   * specific to the route.
101656   * The map supports retrieving single and multiple values from the same parameter.
101657   */
101658
101659
101660  get paramMap() {
101661    if (!this._paramMap) {
101662      this._paramMap = this.params.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(p => convertToParamMap(p)));
101663    }
101664
101665    return this._paramMap;
101666  }
101667  /**
101668   * An Observable that contains a map of the query parameters available to all routes.
101669   * The map supports retrieving single and multiple values from the query parameter.
101670   */
101671
101672
101673  get queryParamMap() {
101674    if (!this._queryParamMap) {
101675      this._queryParamMap = this.queryParams.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(p => convertToParamMap(p)));
101676    }
101677
101678    return this._queryParamMap;
101679  }
101680
101681  toString() {
101682    return this.snapshot ? this.snapshot.toString() : `Future(${this._futureSnapshot})`;
101683  }
101684
101685}
101686/**
101687 * Returns the inherited params, data, and resolve for a given route.
101688 * By default, this only inherits values up to the nearest path-less or component-less route.
101689 * @internal
101690 */
101691
101692
101693function inheritedParamsDataResolve(route, paramsInheritanceStrategy = 'emptyOnly') {
101694  const pathFromRoot = route.pathFromRoot;
101695  let inheritingStartingFrom = 0;
101696
101697  if (paramsInheritanceStrategy !== 'always') {
101698    inheritingStartingFrom = pathFromRoot.length - 1;
101699
101700    while (inheritingStartingFrom >= 1) {
101701      const current = pathFromRoot[inheritingStartingFrom];
101702      const parent = pathFromRoot[inheritingStartingFrom - 1]; // current route is an empty path => inherits its parent's params and data
101703
101704      if (current.routeConfig && current.routeConfig.path === '') {
101705        inheritingStartingFrom--; // parent is componentless => current route should inherit its params and data
101706      } else if (!parent.component) {
101707        inheritingStartingFrom--;
101708      } else {
101709        break;
101710      }
101711    }
101712  }
101713
101714  return flattenInherited(pathFromRoot.slice(inheritingStartingFrom));
101715}
101716/** @internal */
101717
101718
101719function flattenInherited(pathFromRoot) {
101720  return pathFromRoot.reduce((res, curr) => {
101721    const params = { ...res.params,
101722      ...curr.params
101723    };
101724    const data = { ...res.data,
101725      ...curr.data
101726    };
101727    const resolve = { ...curr.data,
101728      ...res.resolve,
101729      ...curr.routeConfig?.data,
101730      ...curr._resolvedData
101731    };
101732    return {
101733      params,
101734      data,
101735      resolve
101736    };
101737  }, {
101738    params: {},
101739    data: {},
101740    resolve: {}
101741  });
101742}
101743/**
101744 * @description
101745 *
101746 * Contains the information about a route associated with a component loaded in an
101747 * outlet at a particular moment in time. ActivatedRouteSnapshot can also be used to
101748 * traverse the router state tree.
101749 *
101750 * The following example initializes a component with route information extracted
101751 * from the snapshot of the root node at the time of creation.
101752 *
101753 * ```
101754 * @Component({templateUrl:'./my-component.html'})
101755 * class MyComponent {
101756 *   constructor(route: ActivatedRoute) {
101757 *     const id: string = route.snapshot.params.id;
101758 *     const url: string = route.snapshot.url.join('');
101759 *     const user = route.snapshot.data.user;
101760 *   }
101761 * }
101762 * ```
101763 *
101764 * @publicApi
101765 */
101766
101767
101768class ActivatedRouteSnapshot {
101769  /** @internal */
101770  constructor(
101771  /** The URL segments matched by this route */
101772  url,
101773  /**
101774   *  The matrix parameters scoped to this route.
101775   *
101776   *  You can compute all params (or data) in the router state or to get params outside
101777   *  of an activated component by traversing the `RouterState` tree as in the following
101778   *  example:
101779   *  ```
101780   *  collectRouteParams(router: Router) {
101781   *    let params = {};
101782   *    let stack: ActivatedRouteSnapshot[] = [router.routerState.snapshot.root];
101783   *    while (stack.length > 0) {
101784   *      const route = stack.pop()!;
101785   *      params = {...params, ...route.params};
101786   *      stack.push(...route.children);
101787   *    }
101788   *    return params;
101789   *  }
101790   *  ```
101791   */
101792  params,
101793  /** The query parameters shared by all the routes */
101794  queryParams,
101795  /** The URL fragment shared by all the routes */
101796  fragment,
101797  /** The static and resolved data of this route */
101798  data,
101799  /** The outlet name of the route */
101800  outlet,
101801  /** The component of the route */
101802  component, routeConfig, urlSegment, lastPathIndex, resolve, correctedLastPathIndex) {
101803    this.url = url;
101804    this.params = params;
101805    this.queryParams = queryParams;
101806    this.fragment = fragment;
101807    this.data = data;
101808    this.outlet = outlet;
101809    this.component = component;
101810    /** The resolved route title */
101811
101812    this.title = this.data?.[RouteTitleKey];
101813    this.routeConfig = routeConfig;
101814    this._urlSegment = urlSegment;
101815    this._lastPathIndex = lastPathIndex;
101816    this._correctedLastPathIndex = correctedLastPathIndex ?? lastPathIndex;
101817    this._resolve = resolve;
101818  }
101819  /** The root of the router state */
101820
101821
101822  get root() {
101823    return this._routerState.root;
101824  }
101825  /** The parent of this route in the router state tree */
101826
101827
101828  get parent() {
101829    return this._routerState.parent(this);
101830  }
101831  /** The first child of this route in the router state tree */
101832
101833
101834  get firstChild() {
101835    return this._routerState.firstChild(this);
101836  }
101837  /** The children of this route in the router state tree */
101838
101839
101840  get children() {
101841    return this._routerState.children(this);
101842  }
101843  /** The path from the root of the router state tree to this route */
101844
101845
101846  get pathFromRoot() {
101847    return this._routerState.pathFromRoot(this);
101848  }
101849
101850  get paramMap() {
101851    if (!this._paramMap) {
101852      this._paramMap = convertToParamMap(this.params);
101853    }
101854
101855    return this._paramMap;
101856  }
101857
101858  get queryParamMap() {
101859    if (!this._queryParamMap) {
101860      this._queryParamMap = convertToParamMap(this.queryParams);
101861    }
101862
101863    return this._queryParamMap;
101864  }
101865
101866  toString() {
101867    const url = this.url.map(segment => segment.toString()).join('/');
101868    const matched = this.routeConfig ? this.routeConfig.path : '';
101869    return `Route(url:'${url}', path:'${matched}')`;
101870  }
101871
101872}
101873/**
101874 * @description
101875 *
101876 * Represents the state of the router at a moment in time.
101877 *
101878 * This is a tree of activated route snapshots. Every node in this tree knows about
101879 * the "consumed" URL segments, the extracted parameters, and the resolved data.
101880 *
101881 * The following example shows how a component is initialized with information
101882 * from the snapshot of the root node's state at the time of creation.
101883 *
101884 * ```
101885 * @Component({templateUrl:'template.html'})
101886 * class MyComponent {
101887 *   constructor(router: Router) {
101888 *     const state: RouterState = router.routerState;
101889 *     const snapshot: RouterStateSnapshot = state.snapshot;
101890 *     const root: ActivatedRouteSnapshot = snapshot.root;
101891 *     const child = root.firstChild;
101892 *     const id: Observable<string> = child.params.map(p => p.id);
101893 *     //...
101894 *   }
101895 * }
101896 * ```
101897 *
101898 * @publicApi
101899 */
101900
101901
101902class RouterStateSnapshot extends Tree {
101903  /** @internal */
101904  constructor(
101905  /** The url from which this snapshot was created */
101906  url, root) {
101907    super(root);
101908    this.url = url;
101909    setRouterState(this, root);
101910  }
101911
101912  toString() {
101913    return serializeNode(this._root);
101914  }
101915
101916}
101917
101918function setRouterState(state, node) {
101919  node.value._routerState = state;
101920  node.children.forEach(c => setRouterState(state, c));
101921}
101922
101923function serializeNode(node) {
101924  const c = node.children.length > 0 ? ` { ${node.children.map(serializeNode).join(', ')} } ` : '';
101925  return `${node.value}${c}`;
101926}
101927/**
101928 * The expectation is that the activate route is created with the right set of parameters.
101929 * So we push new values into the observables only when they are not the initial values.
101930 * And we detect that by checking if the snapshot field is set.
101931 */
101932
101933
101934function advanceActivatedRoute(route) {
101935  if (route.snapshot) {
101936    const currentSnapshot = route.snapshot;
101937    const nextSnapshot = route._futureSnapshot;
101938    route.snapshot = nextSnapshot;
101939
101940    if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) {
101941      route.queryParams.next(nextSnapshot.queryParams);
101942    }
101943
101944    if (currentSnapshot.fragment !== nextSnapshot.fragment) {
101945      route.fragment.next(nextSnapshot.fragment);
101946    }
101947
101948    if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
101949      route.params.next(nextSnapshot.params);
101950    }
101951
101952    if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) {
101953      route.url.next(nextSnapshot.url);
101954    }
101955
101956    if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) {
101957      route.data.next(nextSnapshot.data);
101958    }
101959  } else {
101960    route.snapshot = route._futureSnapshot; // this is for resolved data
101961
101962    route.data.next(route._futureSnapshot.data);
101963  }
101964}
101965
101966function equalParamsAndUrlSegments(a, b) {
101967  const equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url);
101968  const parentsMismatch = !a.parent !== !b.parent;
101969  return equalUrlParams && !parentsMismatch && (!a.parent || equalParamsAndUrlSegments(a.parent, b.parent));
101970}
101971/**
101972 * @license
101973 * Copyright Google LLC All Rights Reserved.
101974 *
101975 * Use of this source code is governed by an MIT-style license that can be
101976 * found in the LICENSE file at https://angular.io/license
101977 */
101978
101979
101980function createRouterState(routeReuseStrategy, curr, prevState) {
101981  const root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : undefined);
101982  return new RouterState(root, curr);
101983}
101984
101985function createNode(routeReuseStrategy, curr, prevState) {
101986  // reuse an activated route that is currently displayed on the screen
101987  if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) {
101988    const value = prevState.value;
101989    value._futureSnapshot = curr.value;
101990    const children = createOrReuseChildren(routeReuseStrategy, curr, prevState);
101991    return new TreeNode(value, children);
101992  } else {
101993    if (routeReuseStrategy.shouldAttach(curr.value)) {
101994      // retrieve an activated route that is used to be displayed, but is not currently displayed
101995      const detachedRouteHandle = routeReuseStrategy.retrieve(curr.value);
101996
101997      if (detachedRouteHandle !== null) {
101998        const tree = detachedRouteHandle.route;
101999        tree.value._futureSnapshot = curr.value;
102000        tree.children = curr.children.map(c => createNode(routeReuseStrategy, c));
102001        return tree;
102002      }
102003    }
102004
102005    const value = createActivatedRoute(curr.value);
102006    const children = curr.children.map(c => createNode(routeReuseStrategy, c));
102007    return new TreeNode(value, children);
102008  }
102009}
102010
102011function createOrReuseChildren(routeReuseStrategy, curr, prevState) {
102012  return curr.children.map(child => {
102013    for (const p of prevState.children) {
102014      if (routeReuseStrategy.shouldReuseRoute(child.value, p.value.snapshot)) {
102015        return createNode(routeReuseStrategy, child, p);
102016      }
102017    }
102018
102019    return createNode(routeReuseStrategy, child);
102020  });
102021}
102022
102023function createActivatedRoute(c) {
102024  return new ActivatedRoute(new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject(c.url), new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject(c.params), new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject(c.queryParams), new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject(c.fragment), new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject(c.data), c.outlet, c.component, c);
102025}
102026/**
102027 * @license
102028 * Copyright Google LLC All Rights Reserved.
102029 *
102030 * Use of this source code is governed by an MIT-style license that can be
102031 * found in the LICENSE file at https://angular.io/license
102032 */
102033
102034
102035const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
102036
102037function redirectingNavigationError(urlSerializer, redirect) {
102038  const {
102039    redirectTo,
102040    navigationBehaviorOptions
102041  } = isUrlTree(redirect) ? {
102042    redirectTo: redirect,
102043    navigationBehaviorOptions: undefined
102044  } : redirect;
102045  const error = navigationCancelingError(ngDevMode && `Redirecting to "${urlSerializer.serialize(redirectTo)}"`, 0
102046  /* NavigationCancellationCode.Redirect */
102047  , redirect);
102048  error.url = redirectTo;
102049  error.navigationBehaviorOptions = navigationBehaviorOptions;
102050  return error;
102051}
102052
102053function navigationCancelingError(message, code, redirectUrl) {
102054  const error = new Error('NavigationCancelingError: ' + (message || ''));
102055  error[NAVIGATION_CANCELING_ERROR] = true;
102056  error.cancellationCode = code;
102057
102058  if (redirectUrl) {
102059    error.url = redirectUrl;
102060  }
102061
102062  return error;
102063}
102064
102065function isRedirectingNavigationCancelingError$1(error) {
102066  return isNavigationCancelingError$1(error) && isUrlTree(error.url);
102067}
102068
102069function isNavigationCancelingError$1(error) {
102070  return error && error[NAVIGATION_CANCELING_ERROR];
102071}
102072/**
102073 * @license
102074 * Copyright Google LLC All Rights Reserved.
102075 *
102076 * Use of this source code is governed by an MIT-style license that can be
102077 * found in the LICENSE file at https://angular.io/license
102078 */
102079
102080/**
102081 * Store contextual information about a `RouterOutlet`
102082 *
102083 * @publicApi
102084 */
102085
102086
102087class OutletContext {
102088  constructor() {
102089    this.outlet = null;
102090    this.route = null;
102091    /**
102092     * @deprecated Passing a resolver to retrieve a component factory is not required and is
102093     *     deprecated since v14.
102094     */
102095
102096    this.resolver = null;
102097    this.injector = null;
102098    this.children = new ChildrenOutletContexts();
102099    this.attachRef = null;
102100  }
102101
102102}
102103/**
102104 * Store contextual information about the children (= nested) `RouterOutlet`
102105 *
102106 * @publicApi
102107 */
102108
102109
102110class ChildrenOutletContexts {
102111  constructor() {
102112    // contexts for child outlets, by name.
102113    this.contexts = new Map();
102114  }
102115  /** Called when a `RouterOutlet` directive is instantiated */
102116
102117
102118  onChildOutletCreated(childName, outlet) {
102119    const context = this.getOrCreateContext(childName);
102120    context.outlet = outlet;
102121    this.contexts.set(childName, context);
102122  }
102123  /**
102124   * Called when a `RouterOutlet` directive is destroyed.
102125   * We need to keep the context as the outlet could be destroyed inside a NgIf and might be
102126   * re-created later.
102127   */
102128
102129
102130  onChildOutletDestroyed(childName) {
102131    const context = this.getContext(childName);
102132
102133    if (context) {
102134      context.outlet = null;
102135      context.attachRef = null;
102136    }
102137  }
102138  /**
102139   * Called when the corresponding route is deactivated during navigation.
102140   * Because the component get destroyed, all children outlet are destroyed.
102141   */
102142
102143
102144  onOutletDeactivated() {
102145    const contexts = this.contexts;
102146    this.contexts = new Map();
102147    return contexts;
102148  }
102149
102150  onOutletReAttached(contexts) {
102151    this.contexts = contexts;
102152  }
102153
102154  getOrCreateContext(childName) {
102155    let context = this.getContext(childName);
102156
102157    if (!context) {
102158      context = new OutletContext();
102159      this.contexts.set(childName, context);
102160    }
102161
102162    return context;
102163  }
102164
102165  getContext(childName) {
102166    return this.contexts.get(childName) || null;
102167  }
102168
102169}
102170
102171ChildrenOutletContexts.ɵfac = function ChildrenOutletContexts_Factory(t) {
102172  return new (t || ChildrenOutletContexts)();
102173};
102174
102175ChildrenOutletContexts.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
102176  token: ChildrenOutletContexts,
102177  factory: ChildrenOutletContexts.ɵfac,
102178  providedIn: 'root'
102179});
102180
102181(function () {
102182  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ChildrenOutletContexts, [{
102183    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
102184    args: [{
102185      providedIn: 'root'
102186    }]
102187  }], null, null);
102188})();
102189/**
102190 * @license
102191 * Copyright Google LLC All Rights Reserved.
102192 *
102193 * Use of this source code is governed by an MIT-style license that can be
102194 * found in the LICENSE file at https://angular.io/license
102195 */
102196
102197
102198const NG_DEV_MODE$7 = typeof ngDevMode === 'undefined' || ngDevMode;
102199/**
102200 * @description
102201 *
102202 * Acts as a placeholder that Angular dynamically fills based on the current router state.
102203 *
102204 * Each outlet can have a unique name, determined by the optional `name` attribute.
102205 * The name cannot be set or changed dynamically. If not set, default value is "primary".
102206 *
102207 * ```
102208 * <router-outlet></router-outlet>
102209 * <router-outlet name='left'></router-outlet>
102210 * <router-outlet name='right'></router-outlet>
102211 * ```
102212 *
102213 * Named outlets can be the targets of secondary routes.
102214 * The `Route` object for a secondary route has an `outlet` property to identify the target outlet:
102215 *
102216 * `{path: <base-path>, component: <component>, outlet: <target_outlet_name>}`
102217 *
102218 * Using named outlets and secondary routes, you can target multiple outlets in
102219 * the same `RouterLink` directive.
102220 *
102221 * The router keeps track of separate branches in a navigation tree for each named outlet and
102222 * generates a representation of that tree in the URL.
102223 * The URL for a secondary route uses the following syntax to specify both the primary and secondary
102224 * routes at the same time:
102225 *
102226 * `http://base-path/primary-route-path(outlet-name:route-path)`
102227 *
102228 * A router outlet emits an activate event when a new component is instantiated,
102229 * deactivate event when a component is destroyed.
102230 * An attached event emits when the `RouteReuseStrategy` instructs the outlet to reattach the
102231 * subtree, and the detached event emits when the `RouteReuseStrategy` instructs the outlet to
102232 * detach the subtree.
102233 *
102234 * ```
102235 * <router-outlet
102236 *   (activate)='onActivate($event)'
102237 *   (deactivate)='onDeactivate($event)'
102238 *   (attach)='onAttach($event)'
102239 *   (detach)='onDetach($event)'></router-outlet>
102240 * ```
102241 *
102242 * @see [Routing tutorial](guide/router-tutorial-toh#named-outlets "Example of a named
102243 * outlet and secondary route configuration").
102244 * @see `RouterLink`
102245 * @see `Route`
102246 * @ngModule RouterModule
102247 *
102248 * @publicApi
102249 */
102250
102251class RouterOutlet {
102252  constructor(parentContexts, location, name, changeDetector, environmentInjector) {
102253    this.parentContexts = parentContexts;
102254    this.location = location;
102255    this.changeDetector = changeDetector;
102256    this.environmentInjector = environmentInjector;
102257    this.activated = null;
102258    this._activatedRoute = null;
102259    this.activateEvents = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
102260    this.deactivateEvents = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
102261    /**
102262     * Emits an attached component instance when the `RouteReuseStrategy` instructs to re-attach a
102263     * previously detached subtree.
102264     **/
102265
102266    this.attachEvents = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
102267    /**
102268     * Emits a detached component instance when the `RouteReuseStrategy` instructs to detach the
102269     * subtree.
102270     */
102271
102272    this.detachEvents = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
102273    this.name = name || PRIMARY_OUTLET;
102274    parentContexts.onChildOutletCreated(this.name, this);
102275  }
102276  /** @nodoc */
102277
102278
102279  ngOnDestroy() {
102280    // Ensure that the registered outlet is this one before removing it on the context.
102281    if (this.parentContexts.getContext(this.name)?.outlet === this) {
102282      this.parentContexts.onChildOutletDestroyed(this.name);
102283    }
102284  }
102285  /** @nodoc */
102286
102287
102288  ngOnInit() {
102289    if (!this.activated) {
102290      // If the outlet was not instantiated at the time the route got activated 
102290we need to populate
102291      // the outlet when it is initialized (ie inside a NgIf)
102292      const context = this.parentContexts.getContext(this.name);
102293
102294      if (context && context.route) {
102295        if (context.attachRef) {
102296          // `attachRef` is populated when there is an existing component to mount
102297          this.attach(context.attachRef, context.route);
102298        } else {
102299          // otherwise the component defined in the configuration is created
102300          this.activateWith(context.route, context.injector);
102301        }
102302      }
102303    }
102304  }
102305
102306  get isActivated() {
102307    return !!this.activated;
102308  }
102309  /**
102310   * @returns The currently activated component instance.
102311   * @throws An error if the outlet is not activated.
102312   */
102313
102314
102315  get component() {
102316    if (!this.activated) throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4012
102317    /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */
102318    , NG_DEV_MODE$7 && 'Outlet is not activated');
102319    return this.activated.instance;
102320  }
102321
102322  get activatedRoute() {
102323    if (!this.activated) throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4012
102324    /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */
102325    , NG_DEV_MODE$7 && 'Outlet is not activated');
102326    return this._activatedRoute;
102327  }
102328
102329  get activatedRouteData() {
102330    if (this._activatedRoute) {
102331      return this._activatedRoute.snapshot.data;
102332    }
102333
102334    return {};
102335  }
102336  /**
102337   * Called when the `RouteReuseStrategy` instructs to detach the subtree
102338   */
102339
102340
102341  detach() {
102342    if (!this.activated) throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4012
102343    /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */
102344    , NG_DEV_MODE$7 && 'Outlet is not activated');
102345    this.location.detach();
102346    const cmp = this.activated;
102347    this.activated = null;
102348    this._activatedRoute = null;
102349    this.detachEvents.emit(cmp.instance);
102350    return cmp;
102351  }
102352  /**
102353   * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
102354   */
102355
102356
102357  attach(ref, activatedRoute) {
102358    this.activated = ref;
102359    this._activatedRoute = activatedRoute;
102360    this.location.insert(ref.hostView);
102361    this.attachEvents.emit(ref.instance);
102362  }
102363
102364  deactivate() {
102365    if (this.activated) {
102366      const c = this.component;
102367      this.activated.destroy();
102368      this.activated = null;
102369      this._activatedRoute = null;
102370      this.deactivateEvents.emit(c);
102371    }
102372  }
102373
102374  activateWith(activatedRoute, resolverOrInjector) {
102375    if (this.isActivated) {
102376      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4013
102377      /* RuntimeErrorCode.OUTLET_ALREADY_ACTIVATED */
102378      , NG_DEV_MODE$7 && 'Cannot activate an already activated outlet');
102379    }
102380
102381    this._activatedRoute = activatedRoute;
102382    const location = this.location;
102383    const snapshot = activatedRoute._futureSnapshot;
102384    const component = snapshot.component;
102385    const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
102386    const injector = new OutletInjector(activatedRoute, childContexts, location.injector);
102387
102388    if (resolverOrInjector && isComponentFactoryResolver(resolverOrInjector)) {
102389      const factory = resolverOrInjector.resolveComponentFactory(component);
102390      this.activated = location.createComponent(factory, location.length, injector);
102391    } else {
102392      const environmentInjector = resolverOrInjector ?? this.environmentInjector;
102393      this.activated = location.createComponent(component, {
102394        index: location.length,
102395        injector,
102396        environmentInjector
102397      });
102398    } // Calling `markForCheck` to make sure we will run the change detection when the
102399    // `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
102400
102401
102402    this.changeDetector.markForCheck();
102403    this.activateEvents.emit(this.activated.instance);
102404  }
102405
102406}
102407
102408RouterOutlet.ɵfac = function RouterOutlet_Factory(t) {
102409  return new (t || RouterOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ChildrenOutletContexts), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('name'), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.EnvironmentInjector));
102410};
102411
102412RouterOutlet.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
102413  type: RouterOutlet,
102414  selectors: [["router-outlet"]],
102415  outputs: {
102416    activateEvents: "activate",
102417    deactivateEvents: "deactivate",
102418    attachEvents: "attach",
102419    detachEvents: "detach"
102420  },
102421  exportAs: ["outlet"],
102422  standalone: true
102423});
102424
102425(function () {
102426  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RouterOutlet, [{
102427    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
102428    args: [{
102429      selector: 'router-outlet',
102430      exportAs: 'outlet',
102431      standalone: true
102432    }]
102433  }], function () {
102434    return [{
102435      type: ChildrenOutletContexts
102436    }, {
102437      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
102438    }, {
102439      type: undefined,
102440      decorators: [{
102441        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
102442        args: ['name']
102443      }]
102444    }, {
102445      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
102446    }, {
102447      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.EnvironmentInjector
102448    }];
102449  }, {
102450    activateEvents: [{
102451      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
102452      args: ['activate']
102453    }],
102454    deactivateEvents: [{
102455      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
102456      args: ['deactivate']
102457    }],
102458    attachEvents: [{
102459      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
102460      args: ['attach']
102461    }],
102462    detachEvents: [{
102463      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
102464      args: ['detach']
102465    }]
102466  });
102467})();
102468
102469class OutletInjector {
102470  constructor(route, childContexts, parent) {
102471    this.route = route;
102472    this.childContexts = childContexts;
102473    this.parent = parent;
102474  }
102475
102476  get(token, notFoundValue) {
102477    if (token === ActivatedRoute) {
102478      return this.route;
102479    }
102480
102481    if (token === ChildrenOutletContexts) {
102482      return this.childContexts;
102483    }
102484
102485    return this.parent.get(token, notFoundValue);
102486  }
102487
102488}
102489
102490function isComponentFactoryResolver(item) {
102491  return !!item.resolveComponentFactory;
102492}
102493/**
102494 * @license
102495 * Copyright Google LLC All Rights Reserved.
102496 *
102497 * Use of this source code is governed by an MIT-style license that can be
102498 * found in the LICENSE file at https://angular.io/license
102499 */
102500
102501/**
102502 * This component is used internally within the router to be a placeholder when an empty
102503 * router-outlet is needed. For example, with a config such as:
102504 *
102505 * `{path: 'parent', outlet: 'nav', children: [...]}`
102506 *
102507 * In order to render, there needs to be a component on this config, which will default
102508 * to this `EmptyOutletComponent`.
102509 */
102510
102511
102512class ɵEmptyOutletComponent {}
102513
102514ɵEmptyOutletComponent.ɵfac = function ɵEmptyOutletComponent_Factory(t) {
102515  return new (t || ɵEmptyOutletComponent)();
102516};
102517
102518ɵEmptyOutletComponent.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
102519  type: ɵEmptyOutletComponent,
102520  selectors: [["ng-component"]],
102521  standalone: true,
102522  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
102523  decls: 1,
102524  vars: 0,
102525  template: function ɵEmptyOutletComponent_Template(rf, ctx) {
102526    if (rf & 1) {
102527      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "router-outlet");
102528    }
102529  },
102530  dependencies: [RouterOutlet],
102531  encapsulation: 2
102532});
102533
102534(function () {
102535  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ɵEmptyOutletComponent, [{
102536    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
102537    args: [{
102538      template: `<router-outlet></router-outlet>`,
102539      imports: [RouterOutlet],
102540      standalone: true
102541    }]
102542  }], null, null);
102543})();
102544/**
102545 * @license
102546 * Copyright Google LLC All Rights Reserved.
102547 *
102548 * Use of this source code is governed by an MIT-style license that can be
102549 * found in the LICENSE file at https://angular.io/license
102550 */
102551
102552/**
102553 * Creates an `EnvironmentInjector` if the `Route` has providers and one does not already exist
102554 * and returns the injector. Otherwise, if the `Route` does not have `providers`, returns the
102555 * `currentInjector`.
102556 *
102557 * @param route The route that might have providers
102558 * @param currentInjector The parent injector of the `Route`
102559 */
102560
102561
102562function getOrCreateRouteInjectorIfNeeded(route, currentInjector) {
102563  if (route.providers && !route._injector) {
102564    route._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createEnvironmentInjector)(route.providers, currentInjector, `Route: ${route.path}`);
102565  }
102566
102567  return route._injector ?? currentInjector;
102568}
102569
102570function getLoadedRoutes(route) {
102571  return route._loadedRoutes;
102572}
102573
102574function getLoadedInjector(route) {
102575  return route._loadedInjector;
102576}
102577
102578function getLoadedComponent(route) {
102579  return route._loadedComponent;
102580}
102581
102582function getProvidersInjector(route) {
102583  return route._injector;
102584}
102585
102586function validateConfig(config, parentPath = '', requireStandaloneComponents = false) {
102587  // forEach doesn't iterate undefined values
102588  for (let i = 0; i < config.length; i++) {
102589    const route = config[i];
102590    const fullPath = getFullPath(parentPath, route);
102591    validateNode(route, fullPath, requireStandaloneComponents);
102592  }
102593}
102594
102595function assertStandalone(fullPath, component) {
102596  if (component && !(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisStandalone"])(component)) {
102597    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102598    /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102599    , `Invalid configuration of route '${fullPath}'. The component must be standalone.`);
102600  }
102601}
102602
102603function validateNode(route, fullPath, requireStandaloneComponents) {
102604  if (typeof ngDevMode === 'undefined' || ngDevMode) {
102605    if (!route) {
102606      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102607      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102608      , `
102609      Invalid configuration of route '${fullPath}': Encountered undefined route.
102610      The reason might be an extra comma.
102611
102612      Example:
102613      const routes: Routes = [
102614        { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
102615        { path: 'dashboard',  component: DashboardComponent },, << two commas
102616        { path: 'detail/:id', component: HeroDetailComponent }
102617      ];
102618    `);
102619    }
102620
102621    if (Array.isArray(route)) {
102622      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102623      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102624      , `Invalid configuration of route '${fullPath}': Array cannot be specified`);
102625    }
102626
102627    if (!route.redirectTo && !route.component && !route.loadComponent && !route.children && !route.loadChildren && route.outlet && route.outlet !== PRIMARY_OUTLET) {
102628      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102629      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102630      , `Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
102631    }
102632
102633    if (route.redirectTo && route.children) {
102634      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102635      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102636      , `Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
102637    }
102638
102639    if (route.redirectTo && route.loadChildren) {
102640      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102641      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102642      , `Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
102643    }
102644
102645    if (route.children && route.loadChildren) {
102646      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102647      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102648      , `Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
102649    }
102650
102651    if (route.redirectTo && (route.component || route.loadComponent)) {
102652      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102653      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102654      , `Invalid configuration of route '${fullPath}': redirectTo and component/loadComponent cannot be used together`);
102655    }
102656
102657    if (route.component && route.loadComponent) {
102658      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102659      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102660      , `Invalid configuration of route '${fullPath}': component and loadComponent cannot be used together`);
102661    }
102662
102663    if (route.redirectTo && route.canActivate) {
102664      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102665      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102666      , `Invalid configuration of route '${fullPath}': redirectTo and canActivate cannot be used together. Redirects happen before activation ` + `so canActivate will never be executed.`);
102667    }
102668
102669    if (route.path && route.matcher) {
102670      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102671      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102672      , `Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
102673    }
102674
102675    if (route.redirectTo === void 0 && !route.component && !route.loadComponent && !route.children && !route.loadChildren) {
102676      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102677      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102678      , `Invalid configuration of route '${fullPath}'. One of the following must be provided: component, loadComponent, redirectTo, children or loadChildren`);
102679    }
102680
102681    if (route.path === void 0 && route.matcher === void 0) {
102682      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102683      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102684      , `Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
102685    }
102686
102687    if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
102688      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102689      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102690      , `Invalid configuration of route '${fullPath}': path cannot start with a slash`);
102691    }
102692
102693    if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
102694      const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
102695      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4014
102696      /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */
102697      , `Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
102698    }
102699
102700    if (requireStandaloneComponents) {
102701      assertStandalone(fullPath, route.component);
102702    }
102703  }
102704
102705  if (route.children) {
102706    validateConfig(route.children, fullPath, requireStandaloneComponents);
102707  }
102708}
102709
102710function getFullPath(parentPath, currentRoute) {
102711  if (!currentRoute) {
102712    return parentPath;
102713  }
102714
102715  if (!parentPath && !currentRoute.path) {
102716    return '';
102717  } else if (parentPath && !currentRoute.path) {
102718    return `${parentPath}/`;
102719  } else if (!parentPath && currentRoute.path) {
102720    return currentRoute.path;
102721  } else {
102722    return `${parentPath}/${currentRoute.path}`;
102723  }
102724}
102725/**
102726 * Makes a copy of the config and adds any default required properties.
102727 */
102728
102729
102730function standardizeConfig(r) {
102731  const children = r.children && r.children.map(standardizeConfig);
102732  const c = children ? { ...r,
102733    children
102734  } : { ...r
102735  };
102736
102737  if (!c.component && !c.loadComponent && (children || c.loadChildren) && c.outlet && c.outlet !== PRIMARY_OUTLET) {
102738    c.component = ɵEmptyOutletComponent;
102739  }
102740
102741  return c;
102742}
102743/** Returns the `route.outlet` or PRIMARY_OUTLET if none exists. */
102744
102745
102746function getOutlet(route) {
102747  return route.outlet || PRIMARY_OUTLET;
102748}
102749/**
102750 * Sorts the `routes` such that the ones with an outlet matching `outletName` come first.
102751 * The order of the configs is otherwise preserved.
102752 */
102753
102754
102755function sortByMatchingOutlets(routes, outletName) {
102756  const sortedConfig = routes.filter(r => getOutlet(r) === outletName);
102757  sortedConfig.push(...routes.filter(r => getOutlet(r) !== outletName));
102758  return sortedConfig;
102759}
102760/**
102761 * Gets the first injector in the snapshot's parent tree.
102762 *
102763 * If the `Route` has a static list of providers, the returned injector will be the one created from
102764 * those. If it does not exist, the returned injector may come from the parents, which may be from a
102765 * loaded config or their static providers.
102766 *
102767 * Returns `null` if there is neither this nor any parents have a stored injector.
102768 *
102769 * Generally used for retrieving the injector to use for getting tokens for guards/resolvers and
102770 * also used for getting the correct injector to use for creating components.
102771 */
102772
102773
102774function getClosestRouteInjector(snapshot) {
102775  if (!snapshot) return null; // If the current route has its own injector, which is created from the static providers on the
102776  // route itself, we should use that. Otherwise, we start at the parent since we do not want to
102777  // include the lazy loaded injector from this route.
102778
102779  if (snapshot.routeConfig?._injector) {
102780    return snapshot.routeConfig._injector;
102781  }
102782
102783  for (let s = snapshot.parent; s; s = s.parent) {
102784    const route = s.routeConfig; // Note that the order here is important. `_loadedInjector` stored on the route with
102785    // `loadChildren: () => NgModule` so it applies to child routes with priority. The `_injector`
102786    // is created from the static providers on that parent route, so it applies to the children as
102787    // well, but only if there is no lazy loaded NgModuleRef injector.
102788
102789    if (route?._loadedInjector) return route._loadedInjector;
102790    if (route?._injector) return route._injector;
102791  }
102792
102793  return null;
102794}
102795/**
102796 * @license
102797 * Copyright Google LLC All Rights Reserved.
102798 *
102799 * Use of this source code is governed by an MIT-style license that can be
102800 * found in the LICENSE file at https://angular.io/license
102801 */
102802
102803
102804const activateRoutes = (rootContexts, routeReuseStrategy, forwardEvent) => (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(t => {
102805  new ActivateRoutes(routeReuseStrategy, t.targetRouterState, t.currentRouterState, forwardEvent).activate(rootContexts);
102806  return t;
102807});
102808
102809class ActivateRoutes {
102810  constructor(routeReuseStrategy, futureState, currState, forwardEvent) {
102811    this.routeReuseStrategy = routeReuseStrategy;
102812    this.futureState = futureState;
102813    this.currState = currState;
102814    this.forwardEvent = forwardEvent;
102815  }
102816
102817  activate(parentContexts) {
102818    const futureRoot = this.futureState._root;
102819    const currRoot = this.currState ? this.currState._root : null;
102820    this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
102821    advanceActivatedRoute(this.futureState.root);
102822    this.activateChildRoutes(futureRoot, currRoot, parentContexts);
102823  } // De-activate the child route that are not re-used for the future state
102824
102825
102826  deactivateChildRoutes(futureNode, currNode, contexts) {
102827    const children = nodeChildrenAsMap(currNode); // Recurse on the routes active in the future state to de-activate deeper children
102828
102829    futureNode.children.forEach(futureChild => {
102830      const childOutletName = futureChild.value.outlet;
102831      this.deactivateRoutes(futureChild, children[childOutletName], contexts);
102832      delete children[childOutletName];
102833    }); // De-activate the routes that will not be re-used
102834
102835    forEach(children, (v, childName) => {
102836      this.deactivateRouteAndItsChildren(v, contexts);
102837    });
102838  }
102839
102840  deactivateRoutes(futureNode, currNode, parentContext) {
102841    const future = futureNode.value;
102842    const curr = currNode ? currNode.value : null;
102843
102844    if (future === curr) {
102845      // Reusing the node, check to see if the children need to be de-activated
102846      if (future.component) {
102847        // If we have a normal route, we need to go through an outlet.
102848        const context = parentContext.getContext(future.outlet);
102849
102850        if (context) {
102851          this.deactivateChildRoutes(futureNode, currNode, context.children);
102852        }
102853      } else {
102854        // if we have a componentless route, we recurse but keep the same outlet map.
102855        this.deactivateChildRoutes(futureNode, currNode, parentContext);
102856      }
102857    } else {
102858      if (curr) {
102859        // Deactivate the current route which will not be re-used
102860        this.deactivateRouteAndItsChildren(currNode, parentContext);
102861      }
102862    }
102863  }
102864
102865  deactivateRouteAndItsChildren(route, parentContexts) {
102866    // If there is no component, the Route is never attached to an outlet (because there is no
102867    // component to attach).
102868    if (route.value.component && this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
102869      this.detachAndStoreRouteSubtree(route, parentContexts);
102870    } else {
102871      this.deactivateRouteAndOutlet(route, parentContexts);
102872    }
102873  }
102874
102875  detachAndStoreRouteSubtree(route, parentContexts) {
102876    const context = parentContexts.getContext(route.value.outlet);
102877    const contexts = context && route.value.component ? context.children : parentContexts;
102878    const children = nodeChildrenAsMap(route);
102879
102880    for (const childOutlet of Object.keys(children)) {
102881      this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
102882    }
102883
102884    if (context && context.outlet) {
102885      const componentRef = context.outlet.detach();
102886      const contexts = context.children.onOutletDeactivated();
102887      this.routeReuseStrategy.store(route.value.snapshot, {
102888        componentRef,
102889        route,
102890        contexts
102891      });
102892    }
102893  }
102894
102895  deactivateRouteAndOutlet(route, parentContexts) {
102896    const context = parentContexts.getContext(route.value.outlet); // The context could be `null` if we are on a componentless route but there may still be
102897    // children that need deactivating.
102898
102899    const contexts = context && route.value.component ? context.children : parentContexts;
102900    const children = nodeChildrenAsMap(route);
102901
102902    for (const childOutlet of Object.keys(children)) {
102903      this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
102904    }
102905
102906    if (context && context.outlet) {
102907      // Destroy the component
102908      context.outlet.deactivate(); // Destroy the contexts for all the outlets that were in the component
102909
102910      context.children.onOutletDeactivated(); // Clear the information about the attached component on the context but keep the reference to
102911      // the outlet.
102912
102913      context.attachRef = null;
102914      context.resolver = null;
102915      context.route = null;
102916    }
102917  }
102918
102919  activateChildRoutes(futureNode, currNode, contexts) {
102920    const children = nodeChildrenAsMap(currNode);
102921    futureNode.children.forEach(c => {
102922      this.activateRoutes(c, children[c.value.outlet], contexts);
102923      this.forwardEvent(new ActivationEnd(c.value.snapshot));
102924    });
102925
102926    if (futureNode.children.length) {
102927      this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
102928    }
102929  }
102930
102931  activateRoutes(futureNode, currNode, parentContexts) {
102932    const future = futureNode.value;
102933    const curr = currNode ? currNode.value : null;
102934    advanceActivatedRoute(future); // reusing the node
102935
102936    if (future === curr) {
102937      if (future.component) {
102938        // If we have a normal route, we need to go through an outlet.
102939        const context = parentContexts.getOrCreateContext(future.outlet);
102940        this.activateChildRoutes(futureNode, currNode, context.children);
102941      } else {
102942        // if we have a componentless route, we recurse but keep the same outlet map.
102943        this.activateChildRoutes(futureNode, currNode, parentContexts);
102944      }
102945    } else {
102946      if (future.component) {
102947        // if we have a normal route, we need to place the component into the outlet and recurse.
102948        const context = parentContexts.getOrCreateContext(future.outlet);
102949
102950        if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
102951          const stored = this.routeReuseStrategy.retrieve(future.snapshot);
102952          this.routeReuseStrategy.store(future.snapshot, null);
102953          context.children.onOutletReAttached(stored.contexts);
102954          context.attachRef = stored.componentRef;
102955          context.route = stored.route.value;
102956
102957          if (context.outlet) {
102958            // Attach right away when the outlet has already been instantiated
102959            // Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
102960            context.outlet.attach(stored.componentRef, stored.route.value);
102961          }
102962
102963          advanceActivatedRoute(stored.route.value);
102964          this.activateChildRoutes(futureNode, null, context.children);
102965        } else {
102966          const injector = getClosestRouteInjector(future.snapshot);
102967          const cmpFactoryResolver = injector?.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ComponentFactoryResolver) ?? null;
102968          context.attachRef = null;
102969          context.route = future;
102970          context.resolver = cmpFactoryResolver;
102971          context.injector = injector;
102972
102973          if (context.outlet) {
102974            // Activate the outlet when it has already been instantiated
102975            // Otherwise it will get activated from its `ngOnInit` when instantiated
102976            context.outlet.activateWith(future, context.injector);
102977          }
102978
102979          this.activateChildRoutes(futureNode, null, context.children);
102980        }
102981      } else {
102982        // if we have a componentless route, we recurse but keep the same outlet map.
102983        this.activateChildRoutes(futureNode, null, parentContexts);
102984      }
102985    }
102986  }
102987
102988}
102989/**
102990 * @license
102991 * Copyright Google LLC All Rights Reserved.
102992 *
102993 * Use of this source code is governed by an MIT-style license that can be
102994 * found in the LICENSE file at https://angular.io/license
102995 */
102996
102997
102998class CanActivate {
102999  constructor(path) {
103000    this.path = path;
103001    this.route = this.path[this.path.length - 1];
103002  }
103003
103004}
103005
103006class CanDeactivate {
103007  constructor(component, route) {
103008    this.component = component;
103009    this.route = route;
103010  }
103011
103012}
103013
103014function getAllRouteGuards(future, curr, parentContexts) {
103015  const futureRoot = future._root;
103016  const currRoot = curr ? curr._root : null;
103017  return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
103018}
103019
103020function getCanActivateChild(p) {
103021  const canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
103022  if (!canActivateChild || canActivateChild.length === 0) return null;
103023  return {
103024    node: p,
103025    guards: canActivateChild
103026  };
103027}
103028
103029function getTokenOrFunctionIdentity(tokenOrFunction, injector) {
103030  const NOT_FOUND = Symbol();
103031  const result = injector.get(tokenOrFunction, NOT_FOUND);
103032
103033  if (result === NOT_FOUND) {
103034    if (typeof tokenOrFunction === 'function' && !(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisInjectable"])(tokenOrFunction)) {
103035      // We think the token is just a function so return it as-is
103036      return tokenOrFunction;
103037    } else {
103038      // This will throw the not found error
103039      return injector.get(tokenOrFunction);
103040    }
103041  }
103042
103043  return result;
103044}
103045
103046function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
103047  canDeactivateChecks: [],
103048  canActivateChecks: []
103049}) {
103050  const prevChildren = nodeChildrenAsMap(currNode); // Process the children of the future route
103051
103052  futureNode.children.forEach(c => {
103053    getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks);
103054    delete prevChildren[c.value.outlet];
103055  }); // Process any children left from the current route (not active for the future route)
103056
103057  forEach(prevChildren, (v, k) => deactivateRouteAndItsChildren(v, contexts.getContext(k), checks));
103058  return checks;
103059}
103060
103061function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks = {
103062  canDeactivateChecks: [],
103063  canActivateChecks: []
103064}) {
103065  const future = futureNode.value;
103066  const curr = currNode ? currNode.value : null;
103067  const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null; // reusing the node
103068
103069  if (curr && future.routeConfig === curr.routeConfig) {
103070    const shouldRun = shouldRunGuardsAndResolvers(curr, future, future.routeConfig.runGuardsAndResolvers);
103071
103072    if (shouldRun) {
103073      checks.canActivateChecks.push(new CanActivate(futurePath));
103074    } else {
103075      // we need to set the data
103076      future.data = curr.data;
103077      future._resolvedData = curr._resolvedData;
103078    } // If we have a component, we need to go through an outlet.
103079
103080
103081    if (future.component) {
103082      getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks); // if we have a componentless route, we recurse but keep the same outlet map.
103083    } else {
103084      getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
103085    }
103086
103087    if (shouldRun && context && context.outlet && context.outlet.isActivated) {
103088      checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, curr));
103089    }
103090  } else {
103091    if (curr) {
103092      deactivateRouteAndItsChildren(currNode, context, checks);
103093    }
103094
103095    checks.canActivateChecks.push(new CanActivate(futurePath)); // If we have a component, we need to go through an outlet.
103096
103097    if (future.component) {
103098      getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks); // if we have a componentless route, we recurse but keep the same outlet map.
103099    } else {
103100      getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks);
103101    }
103102  }
103103
103104  return checks;
103105}
103106
103107function shouldRunGuardsAndResolvers(curr, future, mode) {
103108  if (typeof mode === 'function') {
103109    return mode(curr, future);
103110  }
103111
103112  switch (mode) {
103113    case 'pathParamsChange':
103114      return !equalPath(curr.url, future.url);
103115
103116    case 'pathParamsOrQueryParamsChange':
103117      return !equalPath(curr.url, future.url) || !shallowEqual(curr.queryParams, future.queryParams);
103118
103119    case 'always':
103120      return true;
103121
103122    case 'paramsOrQueryParamsChange':
103123      return !equalParamsAndUrlSegments(curr, future) || !shallowEqual(curr.queryParams, future.queryParams);
103124
103125    case 'paramsChange':
103126    default:
103127      return !equalParamsAndUrlSegments(curr, future);
103128  }
103129}
103130
103131function deactivateRouteAndItsChildren(route, context, checks) {
103132  const children = nodeChildrenAsMap(route);
103133  const r = route.value;
103134  forEach(children, (node, childName) => {
103135    if (!r.component) {
103136      deactivateRouteAndItsChildren(node, context, checks);
103137    } else if (context) {
103138      deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks);
103139    } else {
103140      deactivateRouteAndItsChildren(node, null, checks);
103141    }
103142  });
103143
103144  if (!r.component) {
103145    checks.canDeactivateChecks.push(new CanDeactivate(null, r));
103146  } else if (context && context.outlet && context.outlet.isActivated) {
103147    checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
103148  } else {
103149    checks.canDeactivateChecks.push(new CanDeactivate(null, r));
103150  }
103151}
103152/**
103153 * @license
103154 * Copyright Google LLC All Rights Reserved.
103155 *
103156 * Use of this source code is governed by an MIT-style license that can be
103157 * found in the LICENSE file at https://angular.io/license
103158 */
103159
103160/**
103161 * Simple function check, but generic so type inference will flow. Example:
103162 *
103163 * function product(a: number, b: number) {
103164 *   return a * b;
103165 * }
103166 *
103167 * if (isFunction<product>(fn)) {
103168 *   return fn(1, 2);
103169 * } else {
103170 *   throw "Must provide the `product` function";
103171 * }
103172 */
103173
103174
103175function isFunction(v) {
103176  return typeof v === 'function';
103177}
103178
103179function isBoolean(v) {
103180  return typeof v === 'boolean';
103181}
103182
103183function isCanLoad(guard) {
103184  return guard && isFunction(guard.canLoad);
103185}
103186
103187function isCanActivate(guard) {
103188  return guard && isFunction(guard.canActivate);
103189}
103190
103191function isCanActivateChild(guard) {
103192  return guard && isFunction(guard.canActivateChild);
103193}
103194
103195function isCanDeactivate(guard) {
103196  return guard && isFunction(guard.canDeactivate);
103197}
103198
103199function isCanMatch(guard) {
103200  return guard && isFunction(guard.canMatch);
103201}
103202
103203function isRedirectingNavigationCancelingError(error) {
103204  return isNavigationCancelingError(error) && isUrlTree(error.url);
103205}
103206
103207function isNavigationCancelingError(error) {
103208  return error && error[NAVIGATION_CANCELING_ERROR];
103209}
103210
103211function isEmptyError(e) {
103212  return e instanceof rxjs__WEBPACK_IMPORTED_MODULE_5__.EmptyError || e?.name === 'EmptyError';
103213}
103214/**
103215 * @license
103216 * Copyright Google LLC All Rights Reserved.
103217 *
103218 * Use of this source code is governed by an MIT-style license that can be
103219 * found in the LICENSE file at https://angular.io/license
103220 */
103221
103222
103223const INITIAL_VALUE = Symbol('INITIAL_VALUE');
103224
103225function prioritizedGuardValue() {
103226  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(obs => {
103227    return (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.combineLatest)(obs.map(o => o.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.take)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_9__.startWith)(INITIAL_VALUE)))).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(results => {
103228      for (const result of results) {
103229        if (result === true) {
103230          // If result is true, check the next one
103231          continue;
103232        } else if (result === INITIAL_VALUE) {
103233          // If guard has not finished, we need to stop processing.
103234          return INITIAL_VALUE;
103235        } else if (result === false || result instanceof UrlTree) {
103236          // Result finished and was not true. Return the result.
103237          // Note that we only allow false/UrlTree. Other values are considered invali
103237d and
103238          // ignored.
103239          return result;
103240        }
103241      } // Everything resolved to true. Return true.
103242
103243
103244      return true;
103245    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.filter)(item => item !== INITIAL_VALUE), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.take)(1));
103246  });
103247}
103248/**
103249 * @license
103250 * Copyright Google LLC All Rights Reserved.
103251 *
103252 * Use of this source code is governed by an MIT-style license that can be
103253 * found in the LICENSE file at https://angular.io/license
103254 */
103255
103256
103257function checkGuards(injector, forwardEvent) {
103258  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(t => {
103259    const {
103260      targetSnapshot,
103261      currentSnapshot,
103262      guards: {
103263        canActivateChecks,
103264        canDeactivateChecks
103265      }
103266    } = t;
103267
103268    if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
103269      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)({ ...t,
103270        guardsResult: true
103271      });
103272    }
103273
103274    return runCanDeactivateChecks(canDeactivateChecks, targetSnapshot, currentSnapshot, injector).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(canDeactivate => {
103275      return canDeactivate && isBoolean(canDeactivate) ? runCanActivateChecks(targetSnapshot, canActivateChecks, injector, forwardEvent) : (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(canDeactivate);
103276    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(guardsResult => ({ ...t,
103277      guardsResult
103278    })));
103279  });
103280}
103281
103282function runCanDeactivateChecks(checks, futureRSS, currRSS, injector) {
103283  return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(checks).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(check => runCanDeactivate(check.component, check.route, currRSS, futureRSS, injector)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.first)(result => {
103284    return result !== true;
103285  }, true));
103286}
103287
103288function runCanActivateChecks(futureSnapshot, checks, injector, forwardEvent) {
103289  return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(checks).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.concatMap)(check => {
103290    return (0,rxjs__WEBPACK_IMPORTED_MODULE_14__.concat)(fireChildActivationStart(check.route.parent, forwardEvent), fireActivationStart(check.route, forwardEvent), runCanActivateChild(futureSnapshot, check.path, injector), runCanActivate(futureSnapshot, check.route, injector));
103291  }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.first)(result => {
103292    return result !== true;
103293  }, true));
103294}
103295/**
103296 * This should fire off `ActivationStart` events for each route being activated at this
103297 * level.
103298 * In other words, if you're activating `a` and `b` below, `path` will contain the
103299 * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
103300 * return
103301 * `true` so checks continue to run.
103302 */
103303
103304
103305function fireActivationStart(snapshot, forwardEvent) {
103306  if (snapshot !== null && forwardEvent) {
103307    forwardEvent(new ActivationStart(snapshot));
103308  }
103309
103310  return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(true);
103311}
103312/**
103313 * This should fire off `ChildActivationStart` events for each route being activated at this
103314 * level.
103315 * In other words, if you're activating `a` and `b` below, `path` will contain the
103316 * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
103317 * return
103318 * `true` so checks continue to run.
103319 */
103320
103321
103322function fireChildActivationStart(snapshot, forwardEvent) {
103323  if (snapshot !== null && forwardEvent) {
103324    forwardEvent(new ChildActivationStart(snapshot));
103325  }
103326
103327  return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(true);
103328}
103329
103330function runCanActivate(futureRSS, futureARS, injector) {
103331  const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
103332  if (!canActivate || canActivate.length === 0) return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(true);
103333  const canActivateObservables = canActivate.map(canActivate => {
103334    return (0,rxjs__WEBPACK_IMPORTED_MODULE_15__.defer)(() => {
103335      const closestInjector = getClosestRouteInjector(futureARS) ?? injector;
103336      const guard = getTokenOrFunctionIdentity(canActivate, closestInjector);
103337      const guardVal = isCanActivate(guard) ? guard.canActivate(futureARS, futureRSS) : closestInjector.runInContext(() => guard(futureARS, futureRSS));
103338      return wrapIntoObservable(guardVal).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.first)());
103339    });
103340  });
103341  return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(canActivateObservables).pipe(prioritizedGuardValue());
103342}
103343
103344function runCanActivateChild(futureRSS, path, injector) {
103345  const futureARS = path[path.length - 1];
103346  const canActivateChildGuards = path.slice(0, path.length - 1).reverse().map(p => getCanActivateChild(p)).filter(_ => _ !== null);
103347  const canActivateChildGuardsMapped = canActivateChildGuards.map(d => {
103348    return (0,rxjs__WEBPACK_IMPORTED_MODULE_15__.defer)(() => {
103349      const guardsMapped = d.guards.map(canActivateChild => {
103350        const closestInjector = getClosestRouteInjector(d.node) ?? injector;
103351        const guard = getTokenOrFunctionIdentity(canActivateChild, closestInjector);
103352        const guardVal = isCanActivateChild(guard) ? guard.canActivateChild(futureARS, futureRSS) : closestInjector.runInContext(() => guard(futureARS, futureRSS));
103353        return wrapIntoObservable(guardVal).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.first)());
103354      });
103355      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(guardsMapped).pipe(prioritizedGuardValue());
103356    });
103357  });
103358  return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(canActivateChildGuardsMapped).pipe(prioritizedGuardValue());
103359}
103360
103361function runCanDeactivate(component, currARS, currRSS, futureRSS, injector) {
103362  const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
103363  if (!canDeactivate || canDeactivate.length === 0) return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(true);
103364  const canDeactivateObservables = canDeactivate.map(c => {
103365    const closestInjector = getClosestRouteInjector(currARS) ?? injector;
103366    const guard = getTokenOrFunctionIdentity(c, closestInjector);
103367    const guardVal = isCanDeactivate(guard) ? guard.canDeactivate(component, currARS, currRSS, futureRSS) : closestInjector.runInContext(() => guard(component, currARS, currRSS, futureRSS));
103368    return wrapIntoObservable(guardVal).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.first)());
103369  });
103370  return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(canDeactivateObservables).pipe(prioritizedGuardValue());
103371}
103372
103373function runCanLoadGuards(injector, route, segments, urlSerializer) {
103374  const canLoad = route.canLoad;
103375
103376  if (canLoad === undefined || canLoad.length === 0) {
103377    return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(true);
103378  }
103379
103380  const canLoadObservables = canLoad.map(injectionToken => {
103381    const guard = getTokenOrFunctionIdentity(injectionToken, injector);
103382    const guardVal = isCanLoad(guard) ? guard.canLoad(route, segments) : injector.runInContext(() => guard(route, segments));
103383    return wrapIntoObservable(guardVal);
103384  });
103385  return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(canLoadObservables).pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer));
103386}
103387
103388function redirectIfUrlTree(urlSerializer) {
103389  return (0,rxjs__WEBPACK_IMPORTED_MODULE_16__.pipe)((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(result => {
103390    if (!isUrlTree(result)) return;
103391    throw redirectingNavigationError(urlSerializer, result);
103392  }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(result => result === true));
103393}
103394
103395function runCanMatchGuards(injector, route, segments, urlSerializer) {
103396  const canMatch = route.canMatch;
103397  if (!canMatch || canMatch.length === 0) return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(true);
103398  const canMatchObservables = canMatch.map(injectionToken => {
103399    const guard = getTokenOrFunctionIdentity(injectionToken, injector);
103400    const guardVal = isCanMatch(guard) ? guard.canMatch(route, segments) : injector.runInContext(() => guard(route, segments));
103401    return wrapIntoObservable(guardVal);
103402  });
103403  return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(canMatchObservables).pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer));
103404}
103405/**
103406 * @license
103407 * Copyright Google LLC All Rights Reserved.
103408 *
103409 * Use of this source code is governed by an MIT-style license that can be
103410 * found in the LICENSE file at https://angular.io/license
103411 */
103412
103413
103414const noMatch$1 = {
103415  matched: false,
103416  consumedSegments: [],
103417  remainingSegments: [],
103418  parameters: {},
103419  positionalParamSegments: {}
103420};
103421
103422function matchWithChecks(segmentGroup, route, segments, injector, urlSerializer) {
103423  const result = match(segmentGroup, route, segments);
103424
103425  if (!result.matched) {
103426    return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(result);
103427  }
103427 // Only create the Route's `EnvironmentInjector` if it matches the attempted
103428  // navigation
103429
103430
103431  injector = getOrCreateRouteInjectorIfNeeded(route, injector);
103432  return runCanMatchGuards(injector, route, segments, urlSerializer).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(v => v === true ? result : { ...noMatch$1
103433  }));
103434}
103435
103436function match(segmentGroup, route, segments) {
103437  if (route.path === '') {
103438    if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
103439      return { ...noMatch$1
103440      };
103441    }
103442
103443    return {
103444      matched: true,
103445      consumedSegments: [],
103446      remainingSegments: segments,
103447      parameters: {},
103448      positionalParamSegments: {}
103449    };
103450  }
103451
103452  const matcher = route.matcher || defaultUrlMatcher;
103453  const res = matcher(segments, segmentGroup, route);
103454  if (!res) return { ...noMatch$1
103455  };
103456  const posParams = {};
103457  forEach(res.posParams, (v, k) => {
103458    posParams[k] = v.path;
103459  });
103460  const parameters = res.consumed.length > 0 ? { ...posParams,
103461    ...res.consumed[res.consumed.length - 1].parameters
103462  } : posParams;
103463  return {
103464    matched: true,
103465    consumedSegments: res.consumed,
103466    remainingSegments: segments.slice(res.consumed.length),
103467    // TODO(atscott): investigate combining parameters and positionalParamSegments
103468    parameters,
103469    positionalParamSegments: res.posParams ?? {}
103470  };
103471}
103472
103473function split(segmentGroup, consumedSegments, slicedSegments, config, relativeLinkResolution = 'corrected') {
103474  if (slicedSegments.length > 0 && containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
103475    const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(segmentGroup, consumedSegments, config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
103476    s._sourceSegment = segmentGroup;
103477    s._segmentIndexShift = consumedSegments.length;
103478    return {
103479      segmentGroup: s,
103480      slicedSegments: []
103481    };
103482  }
103483
103484  if (slicedSegments.length === 0 && containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
103485    const s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children, relativeLinkResolution));
103486    s._sourceSegment = segmentGroup;
103487    s._segmentIndexShift = consumedSegments.length;
103488    return {
103489      segmentGroup: s,
103490      slicedSegments
103491    };
103492  }
103493
103494  const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
103495  s._sourceSegment = segmentGroup;
103496  s._segmentIndexShift = consumedSegments.length;
103497  return {
103498    segmentGroup: s,
103499    slicedSegments
103500  };
103501}
103502
103503function addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, routes, children, relativeLinkResolution) {
103504  const res = {};
103505
103506  for (const r of routes) {
103507    if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
103508      const s = new UrlSegmentGroup([], {});
103509      s._sourceSegment = segmentGroup;
103510
103511      if (relativeLinkResolution === 'legacy') {
103512        s._segmentIndexShift = segmentGroup.segments.length;
103513
103514        if (typeof ngDevMode === 'undefined' || !!ngDevMode) {
103515          s._segmentIndexShiftCorrected = consumedSegments.length;
103516        }
103517      } else {
103518        s._segmentIndexShift = consumedSegments.length;
103519      }
103520
103521      res[getOutlet(r)] = s;
103522    }
103523  }
103524
103525  return { ...children,
103526    ...res
103527  };
103528}
103529
103530function createChildrenForEmptyPaths(segmentGroup, consumedSegments, routes, primarySegment) {
103531  const res = {};
103532  res[PRIMARY_OUTLET] = primarySegment;
103533  primarySegment._sourceSegment = segmentGroup;
103534  primarySegment._segmentIndexShift = consumedSegments.length;
103535
103536  for (const r of routes) {
103537    if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) {
103538      const s = new UrlSegmentGroup([], {});
103539      s._sourceSegment = segmentGroup;
103540      s._segmentIndexShift = consumedSegments.length;
103541      res[getOutlet(r)] = s;
103542    }
103543  }
103544
103545  return res;
103546}
103547
103548function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) {
103549  return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet(r) !== PRIMARY_OUTLET);
103550}
103551
103552function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) {
103553  return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r));
103554}
103555
103556function emptyPathMatch(segmentGroup, slicedSegments, r) {
103557  if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') {
103558    return false;
103559  }
103560
103561  return r.path === '';
103562}
103563/**
103564 * Determines if `route` is a path match for the `rawSegment`, `segments`, and `outlet` without
103565 * verifying that its children are a full match for the remainder of the `rawSegment` children as
103566 * well.
103567 */
103568
103569
103570function isImmediateMatch(route, rawSegment, segments, outlet) {
103571  // We allow matches to empty paths when the outlets differ so we can match a url like `/(b:b)` to
103572  // a config like
103573  // * `{path: '', children: [{path: 'b', outlet: 'b'}]}`
103574  // or even
103575  // * `{path: '', outlet: 'a', children: [{path: 'b', outlet: 'b'}]`
103576  //
103577  // The exception here is when the segment outlet is for the primary outlet. This would
103578  // result in a match inside the named outlet because all children there are written as primary
103579  // outlets. So we need to prevent child named outlet matches in a url like `/b` in a config like
103580  // * `{path: '', outlet: 'x' children: [{path: 'b'}]}`
103581  // This should only match if the url is `/(x:b)`.
103582  if (getOutlet(route) !== outlet && (outlet === PRIMARY_OUTLET || !emptyPathMatch(rawSegment, segments, route))) {
103583    return false;
103584  }
103585
103586  if (route.path === '**') {
103587    return true;
103588  }
103589
103590  return match(rawSegment, route, segments).matched;
103591}
103592
103593function noLeftoversInUrl(segmentGroup, segments, outlet) {
103594  return segments.length === 0 && !segmentGroup.children[outlet];
103595}
103596/**
103597 * @license
103598 * Copyright Google LLC All Rights Reserved.
103599 *
103600 * Use of this source code is governed by an MIT-style license that can be
103601 * found in the LICENSE file at https://angular.io/license
103602 */
103603
103604
103605const NG_DEV_MODE$6 = typeof ngDevMode === 'undefined' || ngDevMode;
103606
103607class NoMatch$1 {
103608  constructor(segmentGroup) {
103609    this.segmentGroup = segmentGroup || null;
103610  }
103611
103612}
103613
103614class AbsoluteRedirect {
103615  constructor(urlTree) {
103616    this.urlTree = urlTree;
103617  }
103618
103619}
103620
103621function noMatch(segmentGroup) {
103622  return (0,rxjs__WEBPACK_IMPORTED_MODULE_18__.throwError)(new NoMatch$1(segmentGroup));
103623}
103624
103625function absoluteRedirect(newTree) {
103626  return (0,rxjs__WEBPACK_IMPORTED_MODULE_18__.throwError)(new AbsoluteRedirect(newTree));
103627}
103628
103629function namedOutletsRedirect(redirectTo) {
103630  return (0,rxjs__WEBPACK_IMPORTED_MODULE_18__.throwError)(new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4000
103631  /* RuntimeErrorCode.NAMED_OUTLET_REDIRECT */
103632  , NG_DEV_MODE$6 && `Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`));
103633}
103634
103635function canLoadFails(route) {
103636  return (0,rxjs__WEBPACK_IMPORTED_MODULE_18__.throwError)(navigationCancelingError(NG_DEV_MODE$6 && `Cannot load children because the guard of the route "path: '${route.path}'" returned false`, 3
103637  /* NavigationCancellationCode.GuardRejected */
103638  ));
103639}
103640/**
103641 * Returns the `UrlTree` with the redirection applied.
103642 *
103643 * Lazy modules are loaded along the way.
103644 */
103645
103646
103647function applyRedirects$1(injector, configLoader, urlSerializer, urlTree, config) {
103648  return new ApplyRedirects(injector, configLoader, urlSerializer, urlTree, config).apply();
103649}
103650
103651class ApplyRedirects {
103652  constructor(injector, configLoader, urlSerializer, urlTree, config) {
103653    this.injector = injector;
103654    this.configLoader = configLoader;
103655    this.urlSerializer = urlSerializer;
103656    this.urlTree = urlTree;
103657    this.config = config;
103658    this.allowRedirects = true;
103659  }
103660
103661  apply() {
103662    const splitGroup = split(this.urlTree.root, [], [], this.config).segmentGroup; // TODO(atscott): creating a new segment removes the _sourceSegment _segmentIndexShift, which is
103663    // only necessary to prevent failures in tests which assert exact object matches. The `split` is
103664    // now shared between `applyRedirects` and `recognize` but only the `recognize` step needs these
103665    // properties. Before the implementations were merged, the `applyRedirects` would not assign
103666    // them. We should be able to remove this logic as a "breaking change" but should do some more
103667    // investigation into the failures first.
103668
103669    const rootSegmentGroup = new UrlSegmentGroup(splitGroup.segments, splitGroup.children);
103670    const expanded$ = this.expandSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET);
103671    const urlTrees$ = expanded$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(rootSegmentGroup => {
103672      return this.createUrlTree(squashSegmentGroup(rootSegmentGroup), this.urlTree.queryParams, this.urlTree.fragment);
103673    }));
103674    return urlTrees$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.catchError)(e => {
103675      if (e instanceof AbsoluteRedirect) {
103676        // After an absolute redirect we do not apply any more redirects!
103677        // If this implementation changes, update the documentation note in `redirectTo`.
103678        this.allowRedirects = false; // we need to run matching, so we can fetch all lazy-loaded modules
103679
103680        return this.match(e.urlTree);
103681      }
103682
103683      if (e instanceof NoMatch$1) {
103684        throw this.noMatchError(e);
103685      }
103686
103687      throw e;
103688    }));
103689  }
103690
103691  match(tree) {
103692    const expanded$ = this.expandSegmentGroup(this.injector, this.config, tree.root, PRIMARY_OUTLET);
103693    const mapped$ = expanded$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(rootSegmentGroup => {
103694      return this.createUrlTree(squashSegmentGroup(rootSegmentGroup), tree.queryParams, tree.fragment);
103695    }));
103696    return mapped$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.catchError)(e => {
103697      if (e instanceof NoMatch$1) {
103698        throw this.noMatchError(e);
103699      }
103700
103701      throw e;
103702    }));
103703  }
103704
103705  noMatchError(e) {
103706    return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4002
103707    /* RuntimeErrorCode.NO_MATCH */
103708    , NG_DEV_MODE$6 && `Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
103709  }
103710
103711  createUrlTree(rootCandidate, queryParams, fragment) {
103712    const root = createRoot(rootCandidate);
103713    return new UrlTree(root, queryParams, fragment);
103714  }
103715
103716  expandSegmentGroup(injector, routes, segmentGroup, outlet) {
103717    if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
103718      return this.expandChildren(injector, routes, segmentGroup).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(children => new UrlSegmentGroup([], children)));
103719    }
103720
103721    return this.expandSegment(injector, segmentGroup, routes, segmentGroup.segments, outlet, true);
103722  } // Recursively expand segment groups for all the child outlets
103723
103724
103725  expandChildren(injector, routes, segmentGroup) {
103726    // Expand outlets one at a time, starting with the primary outlet. We need to do it this way
103727    // because an absolute redirect from the primary outlet takes precedence.
103728    const childOutlets = [];
103729
103730    for (const child of Object.keys(segmentGroup.children)) {
103731      if (child === 'primary') {
103732        childOutlets.unshift(child);
103733      } else {
103734        childOutlets.push(child);
103735      }
103736    }
103737
103738    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(childOutlets).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.concatMap)(childOutlet => {
103739      const child = segmentGroup.children[childOutlet]; // Sort the routes so routes with outlets that match the segment appear
103740      // first, followed by routes for other outlets, which might match if they have an
103741      // empty path.
103742
103743      const sortedRoutes = sortByMatchingOutlets(routes, childOutlet);
103744      return this.expandSegmentGroup(injector, sortedRoutes, child, childOutlet).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(s => ({
103745        segment: s,
103746        outlet: childOutlet
103747      })));
103748    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.scan)((children, expandedChild) => {
103749      children[expandedChild.outlet] = expandedChild.segment;
103750      return children;
103751    }, {}), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.last)());
103752  }
103753
103754  expandSegment(injector, segmentGroup, routes, segments, outlet, allowRedirects) {
103755    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(routes).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.concatMap)(r => {
103756      const expanded$ = this.expandSegmentAgainstRoute(injector, segmentGroup, routes, r, segments, outlet, allowRedirects);
103757      return expanded$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.catchError)(e => {
103758        if (e instanceof NoMatch$1) {
103759          return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(null);
103760        }
103761
103762        throw e;
103763      }));
103764    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.first)(s => !!s), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.catchError)((e, _) => {
103765      if (isEmptyError(e)) {
103766        if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
103767          return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(new UrlSegmentGroup([], {}));
103768        }
103769
103770        return noMatch(segmentGroup);
103771      }
103772
103773      throw e;
103774    }));
103775  }
103776
103777  expandSegmentAgainstRoute(injector, segmentGroup, routes, route, paths, outlet, allowRedirects) {
103778    if (!isImmediateMatch(route, segmentGroup, paths, outlet)) {
103779      return noMatch(segmentGroup);
103780    }
103781
103782    if (route.redirectTo === undefined) {
103783      return this.matchSegmentAgainstRoute(injector, segmentGroup, route, paths, outlet);
103784    }
103785
103786    if (allowRedirects && this.allowRedirects) {
103787      return this.expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, paths, outlet);
103788    }
103789
103790    return noMatch(segmentGroup);
103791  }
103792
103793  expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
103794    if (route.path === '**') {
103795      return this.expandWildCardWithParamsAgainstRouteUsingRedirect(injector, routes, route, outlet);
103796    }
103797
103798    return this.expandRegularSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet);
103799  }
103800
103801  expandWildCardWithParamsAgainstRouteUsingRedirect(injector, routes, route, outlet) {
103802    const newTree = this.applyRedirectCommands([], route.redirectTo, {});
103803
103804    if (route.redirectTo.startsWith('/')) {
103805      return absoluteRedirect(newTree);
103806    }
103807
103808    return this.lineralizeSegments(route, newTree).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(newSegments => {
103809      const group = new UrlSegmentGroup(newSegments, {});
103810      return this.expandSegment(injector, group, routes, newSegments, outlet, false);
103811    }));
103812  }
103813
103814  expandRegularSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
103815    const {
103816      matched,
103817      consumedSegments,
103818      remainingSegments,
103819      positionalParamSegments
103820    } = match(segmentGroup, route, segments);
103821    if (!matched) return noMatch(segmentGroup);
103822    const newTree = this.applyRedirectCommands(consumedSegments, route.redirectTo, positionalParamSegments);
103823
103824    if (route.redirectTo.startsWith('/')) {
103825      return absoluteRedirect(newTree);
103826    }
103827
103828    return this.lineralizeSegments(route, newTree).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(newSegments => {
103829      return this.expandSegment(injector, segmentGroup, routes, newSegments.concat(remainingSegments), outlet, false);
103830    }));
103831  }
103832
103833  matchSegmentAgainstRoute(injector, rawSegmentGroup, route, segments, outlet) {
103834    if (route.path === '**') {
103835      // Only create the Route's `EnvironmentInjector` if it matches the attempted navigation
103836      injector = getOrCreateRouteInjectorIfNeeded(route, injector);
103837
103838      if (route.loadChildren) {
103839        const loaded$ = route._loadedRoutes ? (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)({
103840          routes: route._loadedRoutes,
103841          injector: route._loadedInjector
103842        }) : this.configLoader.loadChildren(injector, route);
103843        return loaded$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(cfg => {
103844          route._loadedRoutes = cfg.routes;
103845          route._loadedInjector = cfg.injector;
103846          return new UrlSegmentGroup(segments, {});
103847        }));
103848      }
103849
103850      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(new UrlSegmentGroup(segments, {}));
103851    }
103852
103853    return matchWithChecks(rawSegmentGroup, route, segments, injector, this.urlSerializer).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(({
103854      matched,
103855      consumedSegments,
103856      remainingSegments
103857    }) => {
103858      if (!matched) return noMatch(rawSegmentGroup); // If the route has an injector created from providers, we should start using that.
103859
103860      injector = route._injector ?? injector;
103861      const childConfig$ = this.getChildConfig(injector, route, segments);
103862      return childConfig$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(routerConfig => {
103863        const childInjector = routerConfig.injector ?? injector;
103864        const childConfig = routerConfig.routes;
103865        const {
103866          segmentGroup: splitSegmentGroup,
103867          slicedSegments
103868        } = split(rawSegmentGroup, consumedSegments, remainingSegments, childConfig); // See comment on the other call to `split` about why this is necessary.
103869
103870        const segmentGroup = new UrlSegmentGroup(splitSegmentGroup.segments, splitSegmentGroup.children);
103871
103872        if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
103873          const expanded$ = this.expandChildren(childInjector, childConfig, segmentGroup);
103874          return expanded$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(children => new UrlSegmentGroup(consumedSegments, children)));
103875        }
103876
103877        if (childConfig.length === 0 && slicedSegments.length === 0) {
103878          return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(new UrlSegmentGroup(consumedSegments, {}));
103879        }
103880
103881        const matchedOnOutlet = getOutlet(route) === outlet;
103882        const expanded$ = this.expandSegment(childInjector, segmentGroup, childConfig, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true);
103883        return expanded$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(cs => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children)));
103884      }));
103885    }));
103886  }
103887
103888  getChildConfig(injector, route, segments) {
103889    if (route.children) {
103890      // The children belong to the same module
103891      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)({
103892        routes: route.children,
103893        injector
103894      });
103895    }
103896
103897    if (route.loadChildren) {
103898      // lazy children belong to the loaded module
103899      if (route._loadedRoutes !== undefined) {
103900        return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)({
103901          routes: route._loadedRoutes,
103902          injector: route._loadedInjector
103903        });
103904      }
103905
103906      return runCanLoadGuards(injector, route, segments, this.urlSerializer).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(shouldLoadResult => {
103907        if (shouldLoadResult) {
103908          return this.configLoader.loadChildren(injector, route).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(cfg => {
103909            route._loadedRoutes = cfg.routes;
103910            route._loadedInjector = cfg.injector;
103911          }));
103912        }
103913
103914        return canLoadFails(route);
103915      }));
103916    }
103917
103918    return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)({
103919      routes: [],
103920      injector
103921    });
103922  }
103923
103924  lineralizeSegments(route, urlTree) {
103925    let res = [];
103926    let c = urlTree.root;
103927
103928    while (true) {
103929      res = res.concat(c.segments);
103930
103931      if (c.numberOfChildren === 0) {
103932        return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(res);
103933      }
103934
103935      if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
103936        return namedOutletsRedirect(route.redirectTo);
103937      }
103938
103939      c = c.children[PRIMARY_OUTLET];
103940    }
103941  }
103942
103943  applyRedirectCommands(segments, redirectTo, posParams) {
103944    return this.applyRedirectCreateUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
103945  }
103946
103947  applyRedirectCreateUrlTree(redirectTo, urlTree, segments, posParams) {
103948    const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
103949    return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
103950  }
103951
103952  createQueryParams(redirectToParams, actualParams) {
103953    const res = {};
103954    forEach(redirectToParams, (v, k) => {
103955      const copySourceValue = typeof v === 'string' && v.startsWith(':');
103956
103957      if (copySourceValue) {
103958        const sourceName = v.substring(1);
103959        res[k] = actualParams[sourceName];
103960      } else {
103961        res[k] = v;
103962      }
103963    });
103964    return res;
103965  }
103966
103967  createSegmentGroup(redirectTo, group, segments, posParams) {
103968    const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
103969    let children = {};
103970    forEach(group.children, (child, name) => {
103971      children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
103972    });
103973    return new UrlSegmentGroup(updatedSegments, children);
103974  }
103975
103976  createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
103977    return redirectToSegments.map(s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) : this.findOrReturn(s, actualSegments));
103978  }
103979
103980  findPosParam(redirectTo, redirectToUrlSegment, posParams) {
103981    const pos = posParams[redirectToUrlSegment.path.substring(1)];
103982    if (!pos) throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4001
103983    /* RuntimeErrorCode.MISSING_REDIRECT */
103984    , NG_DEV_MODE$6 && `Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
103985    return pos;
103986  }
103987
103988  findOrReturn(redirectToUrlSegment, actualSegments) {
103989    let idx = 0;
103990
103991    for (const s of actualSegments) {
103992      if (s.path === redirectToUrlSegment.path) {
103993        actualSegments.splice(idx);
103994        return s;
103995      }
103996
103997      idx++;
103998    }
103999
104000    return redirectToUrlSegment;
104001  }
104002
104003}
104004/**
104005 * @license
104006 * Copyright Google LLC All Rights Reserved.
104007 *
104008 * Use of this source code is governed by an MIT-style license that can be
104009 * found in the LICENSE file at https://angular.io/license
104010 */
104011
104012
104013function applyRedirects(environmentInjector, configLoader, urlSerializer, config) {
104014  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(t => applyRedirects$1(environmentInjector, configLoader, urlSerializer, t.extractedUrl, config).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(urlAfterRedirects => ({ ...t,
104015    urlAfterRedirects
104016  }))));
104017}
104018/**
104019 * @license
104020 * Copyright Google LLC All Rights Reserved.
104021 *
104022 * Use of this source code is governed by an MIT-style license that can be
104023 * found in the LICENSE file at https://angular.io/license
104024 */
104025
104026
104027const NG_DEV_MODE$5 = typeof ngDevMode === 'undefined' || !!ngDevMode;
104028
104029class NoMatch {}
104030
104031function newObservableError(e) {
104032  // TODO(atscott): This pattern is used throughout the router code and can be `throwError` instead.
104033  return new rxjs__WEBPACK_IMPORTED_MODULE_22__.Observable(obs => obs.error(e));
104034}
104035
104036function recognize$1(injector, rootComponentType, config, urlTree, url, urlSerializer, paramsInheritanceStrategy = 'emptyOnly', relativeLinkResolution = 'legacy') {
104037  return new Recognizer(injector, rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution, urlSerializer).recognize().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(result => {
104038    if (result === null) {
104039      return newObservableError(new NoMatch());
104040    } else {
104041      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(result);
104042    }
104043  }));
104044}
104045
104046class Recognizer {
104047  constructor(injector, rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution, urlSerializer) {
104048    this.injector = injector;
104049    this.rootComponentType = rootComponentType;
104050    this.config = config;
104051    this.urlTree = urlTree;
104052    this.url = url;
104053    this.paramsInheritanceStrategy = paramsInheritanceStrategy;
104054    this.relativeLinkResolution = relativeLinkResolution;
104055    this.urlSerializer = urlSerializer;
104056  }
104057
104058  recognize() {
104059    const rootSegmentGroup = split(this.urlTree.root, [], [], this.config.filter(c => c.redirectTo === undefined), this.relativeLinkResolution).segmentGroup;
104060    return this.processSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(children => {
104061      if (children === null) {
104062        return null;
104063      } // Use Object.freeze to prevent readers of the Router state from modifying it outside of a
104064      // navigation, resulting in the router being out of sync with the browser.
104065
104066
104067      const root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze({ ...this.urlTree.queryParams
104068      }), this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {});
104069      const rootNode = new TreeNode(root, children);
104070      const routeState = new RouterStateSnapshot(this.url, rootNode);
104071      this.inheritParamsAndData(routeState._root);
104072      return routeState;
104073    }));
104074  }
104075
104076  inheritParamsAndData(routeNode) {
104077    const route = routeNode.value;
104078    const i = inheritedParamsDataResolve(route, this.paramsInheritanceStrategy);
104079    route.params = Object.freeze(i.params);
104080    route.data = Object.freeze(i.data);
104081    routeNode.children.forEach(n => this.inheritParamsAndData(n));
104082  }
104083
104084  processSegmentGroup(injector, config, segmentGroup, outlet) {
104085    if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
104086      return this.processChildren(injector, config, segmentGroup);
104087    }
104088
104089    return this.processSegment(injector, config, segmentGroup, segmentGroup.segments, outlet);
104090  }
104091  /**
104092   * Matches every child outlet in the `segmentGroup` to a `Route` in the config. Returns `null` if
104093   * we cannot find a match for _any_ of the children.
104094   *
104095   * @param config - The `Routes` to match against
104096   * @param segmentGroup - The `UrlSegmentGroup` whose children need to be matched against the
104097   *     config.
104098   */
104099
104100
104101  processChildren(injector, config, segmentGroup) {
104102    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(Object.keys(segmentGroup.children)).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.concatMap)(childOutlet => {
104103      const child = segmentGroup.children[childOutlet]; // Sort the config so that routes with outlets that match the one being activated
104104      // appear first, followed by routes for other outlets, which might match if they have
104105      // an empty path.
104106
104107      const sortedConfig = sortByMatchingOutlets(config, childOutlet);
104108      return this.processSegmentGroup(injector, sortedConfig, child, childOutlet);
104109    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.scan)((children, outletChildren) => {
104110      if (!children || !outletChildren) return null;
104111      children.push(...outletChildren);
104112      return children;
104113    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_23__.takeWhile)(children => children !== null), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_24__.defaultIfEmpty)(null), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.last)(), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(children => {
104114      if (children === null) return null; // Because we may have matched two outlets to the same empty path segment, we can have
104115      // multiple activated results for the same outlet. We should merge the children of
104116      // these results so the final return value is only one `TreeNode` per outlet.
104117
104118      const mergedChildren = mergeEmptyPathMatches(children);
104119
104120      if (NG_DEV_MODE$5) {
104121        // This should really never happen - we are only taking the first match for each
104122        // outlet and merge the empty path matches.
104123        checkOutletNameUniqueness(mergedChildren);
104124      }
104125
104126      sortActivatedRouteSnapshots(mergedChildren);
104127      return mergedChildren;
104128    }));
104129  }
104130
104131  processSegment(injector, routes, segmentGroup, segments, outlet) {
104132    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(routes).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.concatMap)(r => {
104133      return this.processSegmentAgainstRoute(r._injector ?? injector, r, segmentGroup, segments, outlet);
104134    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.first)(x => !!x), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.catchError)(e => {
104135      if (isEmptyError(e)) {
104136        if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
104137          return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)([]);
104138        }
104139
104140        return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(null);
104141      }
104142
104143      throw e;
104144    }));
104145  }
104146
104147  processSegmentAgainstRoute(injector, route, rawSegment, segments, outlet) {
104148    if (route.redirectTo || !isImmediateMatch(route, rawSegment, segments, outlet)) return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(null);
104149    let matchResult;
104150
104151    if (route.path === '**') {
104152      const params = segments.length > 0 ? last(segments).parameters : {};
104153      const pathIndexShift = getPathIndexShift(rawSegment) + segments.length;
104154      const snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze({ ...this.urlTree.queryParams
104155      }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route), // NG_DEV_MODE is used to prevent the getCorrectedPathIndexShift function from affecting
104156      // production bundle size. This value is intended only to surface a warning to users
104157      // depending on `relativeLinkResolution: 'legacy'` in dev mode.
104158      NG_DEV_MODE$5 ? getCorrectedPathIndexShift(rawSegment) + segments.length : pathIndexShift);
104159      matchResult = (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)({
104160        snapshot,
104161        consumedSegments: [],
104162        remainingSegments: []
104163      });
104164    } else {
104165      matchResult = matchWithChecks(rawSegment, route, segments, injector, this.urlSerializer).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(({
104166        matched,
104167        consumedSegments,
104168        remainingSegments,
104169        parameters
104170      }) => {
104171        if (!matched) {
104172          return null;
104173        }
104174
104175        const pathIndexShift = getPathIndexShift(rawSegment) + consumedSegments.length;
104176        const snapshot = new ActivatedRouteSnapshot(consumedSegments, parameters, Ob
104176ject.freeze({ ...this.urlTree.queryParams
104177        }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route), NG_DEV_MODE$5 ? getCorrectedPathIndexShift(rawSegment) + consumedSegments.length : pathIndexShift);
104178        return {
104179          snapshot,
104180          consumedSegments,
104181          remainingSegments
104182        };
104183      }));
104184    }
104185
104186    return matchResult.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(result => {
104187      if (result === null) {
104188        return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(null);
104189      }
104190
104191      const {
104192        snapshot,
104193        consumedSegments,
104194        remainingSegments
104195      } = result; // If the route has an injector created from providers, we should start using that.
104196
104197      injector = route._injector ?? injector;
104198      const childInjector = route._loadedInjector ?? injector;
104199      const childConfig = getChildConfig(route);
104200      const {
104201        segmentGroup,
104202        slicedSegments
104203      } = split(rawSegment, consumedSegments, remainingSegments, // Filter out routes with redirectTo because we are trying to create activated route
104204      // snapshots and don't handle redirects here. That should have been done in
104205      // `applyRedirects`.
104206      childConfig.filter(c => c.redirectTo === undefined), this.relativeLinkResolution);
104207
104208      if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
104209        return this.processChildren(childInjector, childConfig, segmentGroup).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(children => {
104210          if (children === null) {
104211            return null;
104212          }
104213
104214          return [new TreeNode(snapshot, children)];
104215        }));
104216      }
104217
104218      if (childConfig.length === 0 && slicedSegments.length === 0) {
104219        return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)([new TreeNode(snapshot, [])]);
104220      }
104221
104222      const matchedOnOutlet = getOutlet(route) === outlet; // If we matched a config due to empty path match on a different outlet, we need to
104223      // continue passing the current outlet for the segment rather than switch to PRIMARY.
104224      // Note that we switch to primary when we have a match because outlet configs look like
104225      // this: {path: 'a', outlet: 'a', children: [
104226      //  {path: 'b', component: B},
104227      //  {path: 'c', component: C},
104228      // ]}
104229      // Notice that the children of the named outlet are configured with the primary outlet
104230
104231      return this.processSegment(childInjector, childConfig, segmentGroup, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(children => {
104232        if (children === null) {
104233          return null;
104234        }
104235
104236        return [new TreeNode(snapshot, children)];
104237      }));
104238    }));
104239  }
104240
104241}
104242
104243function sortActivatedRouteSnapshots(nodes) {
104244  nodes.sort((a, b) => {
104245    if (a.value.outlet === PRIMARY_OUTLET) return -1;
104246    if (b.value.outlet === PRIMARY_OUTLET) return 1;
104247    return a.value.outlet.localeCompare(b.value.outlet);
104248  });
104249}
104250
104251function getChildConfig(route) {
104252  if (route.children) {
104253    return route.children;
104254  }
104255
104256  if (route.loadChildren) {
104257    return route._loadedRoutes;
104258  }
104259
104260  return [];
104261}
104262
104263function hasEmptyPathConfig(node) {
104264  const config = node.value.routeConfig;
104265  return config && config.path === '' && config.redirectTo === undefined;
104266}
104267/**
104268 * Finds `TreeNode`s with matching empty path route configs and merges them into `TreeNode` with
104269 * the children from each duplicate. This is necessary because different outlets can match a
104270 * single empty path route config and the results need to then be merged.
104271 */
104272
104273
104274function mergeEmptyPathMatches(nodes) {
104275  const result = []; // The set of nodes which contain children that were merged from two duplicate empty path nodes.
104276
104277  const mergedNodes = new Set();
104278
104279  for (const node of nodes) {
104280    if (!hasEmptyPathConfig(node)) {
104281      result.push(node);
104282      continue;
104283    }
104284
104285    const duplicateEmptyPathNode = result.find(resultNode => node.value.routeConfig === resultNode.value.routeConfig);
104286
104287    if (duplicateEmptyPathNode !== undefined) {
104288      duplicateEmptyPathNode.children.push(...node.children);
104289      mergedNodes.add(duplicateEmptyPathNode);
104290    } else {
104291      result.push(node);
104292    }
104293  } // For each node which has children from multiple sources, we need to recompute a new `TreeNode`
104294  // by also merging those children. This is necessary when there are multiple empty path configs
104295  // in a row. Put another way: whenever we combine children of two nodes, we need to also check
104296  // if any of those children can be combined into a single node as well.
104297
104298
104299  for (const mergedNode of mergedNodes) {
104300    const mergedChildren = mergeEmptyPathMatches(mergedNode.children);
104301    result.push(new TreeNode(mergedNode.value, mergedChildren));
104302  }
104303
104304  return result.filter(n => !mergedNodes.has(n));
104305}
104306
104307function checkOutletNameUniqueness(nodes) {
104308  const names = {};
104309  nodes.forEach(n => {
104310    const routeWithSameOutletName = names[n.value.outlet];
104311
104312    if (routeWithSameOutletName) {
104313      const p = routeWithSameOutletName.url.map(s => s.toString()).join('/');
104314      const c = n.value.url.map(s => s.toString()).join('/');
104315      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4006
104316      /* RuntimeErrorCode.TWO_SEGMENTS_WITH_SAME_OUTLET */
104317      , NG_DEV_MODE$5 && `Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
104318    }
104319
104320    names[n.value.outlet] = n.value;
104321  });
104322}
104323
104324function getSourceSegmentGroup(segmentGroup) {
104325  let s = segmentGroup;
104326
104327  while (s._sourceSegment) {
104328    s = s._sourceSegment;
104329  }
104330
104331  return s;
104332}
104333
104334function getPathIndexShift(segmentGroup) {
104335  let s = segmentGroup;
104336  let res = s._segmentIndexShift ?? 0;
104337
104338  while (s._sourceSegment) {
104339    s = s._sourceSegment;
104340    res += s._segmentIndexShift ?? 0;
104341  }
104342
104343  return res - 1;
104344}
104345
104346function getCorrectedPathIndexShift(segmentGroup) {
104347  let s = segmentGroup;
104348  let res = s._segmentIndexShiftCorrected ?? s._segmentIndexShift ?? 0;
104349
104350  while (s._sourceSegment) {
104351    s = s._sourceSegment;
104352    res += s._segmentIndexShiftCorrected ?? s._segmentIndexShift ?? 0;
104353  }
104354
104355  return res - 1;
104356}
104357
104358function getData(route) {
104359  return route.data || {};
104360}
104361
104362function getResolve(route) {
104363  return route.resolve || {};
104364}
104365/**
104366 * @license
104367 * Copyright Google LLC All Rights Reserved.
104368 *
104369 * Use of this source code is governed by an MIT-style license that can be
104370 * found in the LICENSE file at https://angular.io/license
104371 */
104372
104373
104374function recognize(injector, rootComponentType, config, serializer, paramsInheritanceStrategy, relativeLinkResolution) {
104375  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(t => recognize$1(injector, rootComponentType, config, t.urlAfterRedirects, serializer.serialize(t.urlAfterRedirects), serializer, paramsInheritanceStrategy, relativeLinkResolution).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(targetSnapshot => ({ ...t,
104376    targetSnapshot
104377  }))));
104378}
104379/**
104380 * @license
104381 * Copyright Google LLC All Rights Reserved.
104382 *
104383 * Use of this source code is governed by an MIT-style license that can be
104384 * found in the LICENSE file at https://angular.io/license
104385 */
104386
104387
104388function resolveData(paramsInheritanceStrategy, injector) {
104389  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(t => {
104390    const {
104391      targetSnapshot,
104392      guards: {
104393        canActivateChecks
104394      }
104395    } = t;
104396
104397    if (!canActivateChecks.length) {
104398      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(t);
104399    }
104400
104401    let canActivateChecksResolved = 0;
104402    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(canActivateChecks).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.concatMap)(check => runResolve(check.route, targetSnapshot, paramsInheritanceStrategy, injector)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(() => canActivateChecksResolved++), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_25__.takeLast)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(_ => canActivateChecksResolved === canActivateChecks.length ? (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(t) : rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY));
104403  });
104404}
104405
104406function runResolve(futureARS, futureRSS, paramsInheritanceStrategy, injector) {
104407  const config = futureARS.routeConfig;
104408  const resolve = futureARS._resolve;
104409
104410  if (config?.title !== undefined && !hasStaticTitle(config)) {
104411    resolve[RouteTitleKey] = config.title;
104412  }
104413
104414  return resolveNode(resolve, futureARS, futureRSS, injector).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(resolvedData => {
104415    futureARS._resolvedData = resolvedData;
104416    futureARS.data = inheritedParamsDataResolve(futureARS, paramsInheritanceStrategy).resolve;
104417
104418    if (config && hasStaticTitle(config)) {
104419      futureARS.data[RouteTitleKey] = config.title;
104420    }
104421
104422    return null;
104423  }));
104424}
104425
104426function resolveNode(resolve, futureARS, futureRSS, injector) {
104427  const keys = getDataKeys(resolve);
104428
104429  if (keys.length === 0) {
104430    return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)({});
104431  }
104432
104433  const data = {};
104434  return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(keys).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(key => getResolver(resolve[key], futureARS, futureRSS, injector).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.first)(), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(value => {
104435    data[key] = value;
104436  }))), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_25__.takeLast)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_27__.mapTo)(data), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.catchError)(e => isEmptyError(e) ? rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY : (0,rxjs__WEBPACK_IMPORTED_MODULE_18__.throwError)(e)));
104437}
104438
104439function getDataKeys(obj) {
104440  return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
104441}
104442
104443function getResolver(injectionToken, futureARS, futureRSS, injector) {
104444  const closestInjector = getClosestRouteInjector(futureARS) ?? injector;
104445  const resolver = getTokenOrFunctionIdentity(injectionToken, closestInjector);
104446  const resolverValue = resolver.resolve ? resolver.resolve(futureARS, futureRSS) : closestInjector.runInContext(() => resolver(futureARS, futureRSS));
104447  return wrapIntoObservable(resolverValue);
104448}
104449
104450function hasStaticTitle(config) {
104451  return typeof config.title === 'string' || config.title === null;
104452}
104453/**
104454 * @license
104455 * Copyright Google LLC All Rights Reserved.
104456 *
104457 * Use of this source code is governed by an MIT-style license that can be
104458 * found in the LICENSE file at https://angular.io/license
104459 */
104460
104461/**
104462 * Perform a side effect through a switchMap for every emission on the source Observable,
104463 * but return an Observable that is identical to the source. It's essentially the same as
104464 * the `tap` operator, but if the side effectful `next` function returns an ObservableInput,
104465 * it will wait before continuing with the original value.
104466 */
104467
104468
104469function switchTap(next) {
104470  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(v => {
104471    const nextResult = next(v);
104472
104473    if (nextResult) {
104474      return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(nextResult).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(() => v));
104475    }
104476
104477    return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(v);
104478  });
104479}
104480/**
104481 * @license
104482 * Copyright Google LLC All Rights Reserved.
104483 *
104484 * Use of this source code is governed by an MIT-style license that can be
104485 * found in the LICENSE file at https://angular.io/license
104486 */
104487
104488/**
104489 * Provides a strategy for setting the page title after a router navigation.
104490 *
104491 * The built-in implementation traverses the router state snapshot and finds the deepest primary
104492 * outlet with `title` property. Given the `Routes` below, navigating to
104493 * `/base/child(popup:aux)` would result in the document title being set to "child".
104494 * ```
104495 * [
104496 *   {path: 'base', title: 'base', children: [
104497 *     {path: 'child', title: 'child'},
104498 *   ],
104499 *   {path: 'aux', outlet: 'popup', title: 'popupTitle'}
104500 * ]
104501 * ```
104502 *
104503 * This class can be used as a base class for custom title strategies. That is, you can create your
104504 * own class that extends the `TitleStrategy`. Note that in the above example, the `title`
104505 * from the named outlet is never used. However, a custom strategy might be implemented to
104506 * incorporate titles in named outlets.
104507 *
104508 * @publicApi
104509 * @see [Page title guide](guide/router#setting-the-page-title)
104510 */
104511
104512
104513class TitleStrategy {
104514  /**
104515   * @returns The `title` of the deepest primary route.
104516   */
104517  buildTitle(snapshot) {
104518    let pageTitle;
104519    let route = snapshot.root;
104520
104521    while (route !== undefined) {
104522      pageTitle = this.getResolvedTitleForRoute(route) ?? pageTitle;
104523      route = route.children.find(child => child.outlet === PRIMARY_OUTLET);
104524    }
104525
104526    return pageTitle;
104527  }
104528  /**
104529   * Given an `ActivatedRouteSnapshot`, returns the final value of the
104530   * `Route.title` property, which can either be a static string or a resolved value.
104531   */
104532
104533
104534  getResolvedTitleForRoute(snapshot) {
104535    return snapshot.data[RouteTitleKey];
104536  }
104537
104538}
104539
104540TitleStrategy.ɵfac = function TitleStrategy_Factory(t) {
104541  return new (t || TitleStrategy)();
104542};
104543
104544TitleStrategy.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
104545  token: TitleStrategy,
104546  factory: function () {
104547    return (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DefaultTitleStrategy))();
104548  },
104549  providedIn: 'root'
104550});
104551
104552(function () {
104553  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](TitleStrategy, [{
104554    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
104555    args: [{
104556      providedIn: 'root',
104557      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DefaultTitleStrategy)
104558    }]
104559  }], null, null);
104560})();
104561/**
104562 * The default `TitleStrategy` used by the router that updates the title using the `Title` service.
104563 */
104564
104565
104566class DefaultTitleStrategy extends TitleStrategy {
104567  constructor(title) {
104568    super();
104569    this.title = title;
104570  }
104571  /**
104572   * Sets the title of the browser to the given value.
104573   *
104574   * @param title The `pageTitle` from the deepest primary route.
104575   */
104576
104577
104578  updateTitle(snapshot) {
104579    const title = this.buildTitle(snapshot);
104580
104581    if (title !== undefined) {
104582      this.title.setTitle(title);
104583    }
104584  }
104585
104586}
104587
104588DefaultTitleStrategy.ɵfac = function DefaultTitleStrategy_Factory(t) {
104589  return new (t || DefaultTitleStrategy)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_platform_browser__WEBPACK_IMPORTED_MODULE_28__.Title));
104590};
104591
104592DefaultTitleStrategy.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
104593  token: DefaultTitleStrategy,
104594  factory: DefaultTitleStrategy.ɵfac,
104595  providedIn: 'root'
104596});
104597
104598(function () {
104599  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DefaultTitleStrategy, [{
104600    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
104601    args: [{
104602      providedIn: 'root'
104603    }]
104604  }], function () {
104605    return [{
104606      type: _angular_platform_browser__WEBPACK_IMPORTED_MODULE_28__.Title
104607    }];
104608  }, null);
104609})();
104610/**
104611 * @license
104612 * Copyright Google LLC All Rights Reserved.
104613 *
104614 * Use of this source code is governed by an MIT-style license that can be
104615 * found in the LICENSE file at https://angular.io/license
104616 */
104617
104618/**
104619 * Exists to aid internal migration off of the deprecated relativeLinkResolution option.
104620 */
104621
104622
104623function assignRelativeLinkResolution(router) {}
104624/**
104625 * @license
104626 * Copyright Google LLC All Rights Reserved.
104627 *
104628 * Use of this source code is governed by an MIT-style license that can be
104629 * found in the LICENSE file at https://angular.io/license
104630 */
104631
104632/**
104633 * @description
104634 *
104635 * Provides a way to customize when activated routes get reused.
104636 *
104637 * @publicApi
104638 */
104639
104640
104641class RouteReuseStrategy {}
104642/**
104643 * @description
104644 *
104645 * This base route reuse strategy only reuses routes when the matched router configs are
104646 * identical. This prevents components from being destroyed and recreated
104647 * when just the route parameters, query parameters or fragment change
104648 * (that is, the existing component is _reused_).
104649 *
104650 * This strategy does not store any routes for later reuse.
104651 *
104652 * Angular uses this strategy by default.
104653 *
104654 *
104655 * It can be used as a base class for custom route reuse strategies, i.e. you can create your own
104656 * class that extends the `BaseRouteReuseStrategy` one.
104657 * @publicApi
104658 */
104659
104660
104661class BaseRouteReuseStrategy {
104662  /**
104663   * Whether the given route should detach for later reuse.
104664   * Always returns false for `BaseRouteReuseStrategy`.
104665   * */
104666  shouldDetach(route) {
104667    return false;
104668  }
104669  /**
104670   * A no-op; the route is never stored since this strategy never detaches routes for later re-use.
104671   */
104672
104673
104674  store(route, detachedTree) {}
104675  /** Returns `false`, meaning the route (and its subtree) is never reattached */
104676
104677
104678  shouldAttach(route) {
104679    return false;
104680  }
104681  /** Returns `null` because this strategy does not store routes for later re-use. */
104682
104683
104684  retrieve(route) {
104685    return null;
104686  }
104687  /**
104688   * Determines if a route should be reused.
104689   * This strategy returns `true` when the future route config and current route config are
104690   * identical.
104691   */
104692
104693
104694  shouldReuseRoute(future, curr) {
104695    return future.routeConfig === curr.routeConfig;
104696  }
104697
104698}
104699
104700class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {}
104701/**
104702 * @license
104703 * Copyright Google LLC All Rights Reserved.
104704 *
104705 * Use of this source code is governed by an MIT-style license that can be
104706 * found in the LICENSE file at https://angular.io/license
104707 */
104708
104709
104710const NG_DEV_MODE$4 = typeof ngDevMode === 'undefined' || !!ngDevMode;
104711/**
104712 * A [DI token](guide/glossary/#di-token) for the router service.
104713 *
104714 * @publicApi
104715 */
104716
104717const ROUTER_CONFIGURATION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(NG_DEV_MODE$4 ? 'router config' : '', {
104718  providedIn: 'root',
104719  factory: () => ({})
104720});
104721/**
104722 * @license
104723 * Copyright Google LLC All Rights Reserved.
104724 *
104725 * Use of this source code is governed by an MIT-style license that can be
104726 * found in the LICENSE file at https://angular.io/license
104727 */
104728
104729const NG_DEV_MODE$3 = typeof ngDevMode === 'undefined' || !!ngDevMode;
104730/**
104731 * The [DI token](guide/glossary/#di-token) for a router configuration.
104732 *
104733 * `ROUTES` is a low level API for router configuration via depen
104733dency injection.
104734 *
104735 * We recommend that in almost all cases to use higher level APIs such as `RouterModule.forRoot()`,
104736 * `RouterModule.forChild()`, `provideRoutes`, or `Router.resetConfig()`.
104737 *
104738 * @publicApi
104739 */
104740
104741const ROUTES = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('ROUTES');
104742
104743class RouterConfigLoader {
104744  constructor(injector, compiler) {
104745    this.injector = injector;
104746    this.compiler = compiler;
104747    this.componentLoaders = new WeakMap();
104748    this.childrenLoaders = new WeakMap();
104749  }
104750
104751  loadComponent(route) {
104752    if (this.componentLoaders.get(route)) {
104753      return this.componentLoaders.get(route);
104754    } else if (route._loadedComponent) {
104755      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(route._loadedComponent);
104756    }
104757
104758    if (this.onLoadStartListener) {
104759      this.onLoadStartListener(route);
104760    }
104761
104762    const loadRunner = wrapIntoObservable(route.loadComponent()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(component => {
104763      if (this.onLoadEndListener) {
104764        this.onLoadEndListener(route);
104765      }
104766
104767      NG_DEV_MODE$3 && assertStandalone(route.path ?? '', component);
104768      route._loadedComponent = component;
104769    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_29__.finalize)(() => {
104770      this.componentLoaders.delete(route);
104771    })); // Use custom ConnectableObservable as share in runners pipe increasing the bundle size too much
104772
104773    const loader = new rxjs__WEBPACK_IMPORTED_MODULE_30__.ConnectableObservable(loadRunner, () => new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_32__.refCount)());
104774    this.componentLoaders.set(route, loader);
104775    return loader;
104776  }
104777
104778  loadChildren(parentInjector, route) {
104779    if (this.childrenLoaders.get(route)) {
104780      return this.childrenLoaders.get(route);
104781    } else if (route._loadedRoutes) {
104782      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)({
104783        routes: route._loadedRoutes,
104784        injector: route._loadedInjector
104785      });
104786    }
104787
104788    if (this.onLoadStartListener) {
104789      this.onLoadStartListener(route);
104790    }
104791
104792    const moduleFactoryOrRoutes$ = this.loadModuleFactoryOrRoutes(route.loadChildren);
104793    const loadRunner = moduleFactoryOrRoutes$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(factoryOrRoutes => {
104794      if (this.onLoadEndListener) {
104795        this.onLoadEndListener(route);
104796      } // This injector comes from the `NgModuleRef` when lazy loading an `NgModule`. There is no
104797      // injector associated with lazy loading a `Route` array.
104798
104799
104800      let injector;
104801      let rawRoutes;
104802      let requireStandaloneComponents = false;
104803
104804      if (Array.isArray(factoryOrRoutes)) {
104805        rawRoutes = factoryOrRoutes;
104806        requireStandaloneComponents = true;
104807      } else {
104808        injector = factoryOrRoutes.create(parentInjector).injector; // When loading a module that doesn't provide `RouterModule.forChild()` preloader
104809        // will get stuck in an infinite loop. The child module's Injector will look to
104810        // its parent `Injector` when it doesn't find any ROUTES so it will return routes
104811        // for it's parent module instead.
104812
104813        rawRoutes = flatten(injector.get(ROUTES, [], _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectFlags.Self | _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectFlags.Optional));
104814      }
104815
104816      const routes = rawRoutes.map(standardizeConfig);
104817      NG_DEV_MODE$3 && validateConfig(routes, route.path, requireStandaloneComponents);
104818      return {
104819        routes,
104820        injector
104821      };
104822    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_29__.finalize)(() => {
104823      this.childrenLoaders.delete(route);
104824    })); // Use custom ConnectableObservable as share in runners pipe increasing the bundle size too much
104825
104826    const loader = new rxjs__WEBPACK_IMPORTED_MODULE_30__.ConnectableObservable(loadRunner, () => new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_32__.refCount)());
104827    this.childrenLoaders.set(route, loader);
104828    return loader;
104829  }
104830
104831  loadModuleFactoryOrRoutes(loadChildren) {
104832    return wrapIntoObservable(loadChildren()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(t => {
104833      if (t instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModuleFactory || Array.isArray(t)) {
104834        return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(t);
104835      } else {
104836        return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(this.compiler.compileModuleAsync(t));
104837      }
104838    }));
104839  }
104840
104841}
104842
104843RouterConfigLoader.ɵfac = function RouterConfigLoader_Factory(t) {
104844  return new (t || RouterConfigLoader)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Compiler));
104845};
104846
104847RouterConfigLoader.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
104848  token: RouterConfigLoader,
104849  factory: RouterConfigLoader.ɵfac,
104850  providedIn: 'root'
104851});
104852
104853(function () {
104854  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RouterConfigLoader, [{
104855    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
104856    args: [{
104857      providedIn: 'root'
104858    }]
104859  }], function () {
104860    return [{
104861      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector
104862    }, {
104863      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Compiler
104864    }];
104865  }, null);
104866})();
104867/**
104868 * @license
104869 * Copyright Google LLC All Rights Reserved.
104870 *
104871 * Use of this source code is governed by an MIT-style license that can be
104872 * found in the LICENSE file at https://angular.io/license
104873 */
104874
104875/**
104876 * @description
104877 *
104878 * Provides a way to migrate AngularJS applications to Angular.
104879 *
104880 * @publicApi
104881 */
104882
104883
104884class UrlHandlingStrategy {}
104885/**
104886 * @publicApi
104887 */
104888
104889
104890class DefaultUrlHandlingStrategy {
104891  shouldProcessUrl(url) {
104892    return true;
104893  }
104894
104895  extract(url) {
104896    return url;
104897  }
104898
104899  merge(newUrlPart, wholeUrl) {
104900    return newUrlPart;
104901  }
104902
104903}
104904/**
104905 * @license
104906 * Copyright Google LLC All Rights Reserved.
104907 *
104908 * Use of this source code is governed by an MIT-style license that can be
104909 * found in the LICENSE file at https://angular.io/license
104910 */
104911
104912
104913const NG_DEV_MODE$2 = typeof ngDevMode === 'undefined' || !!ngDevMode;
104914
104915function defaultErrorHandler(error) {
104916  throw error;
104917}
104918
104919function defaultMalformedUriErrorHandler(error, urlSerializer, url) {
104920  return urlSerializer.parse('/');
104921}
104922/**
104923 * The equivalent `IsActiveMatchOptions` options for `Router.isActive` is called with `true`
104924 * (exact = true).
104925 */
104926
104927
104928const exactMatchOptions = {
104929  paths: 'exact',
104930  fragment: 'ignored',
104931  matrixParams: 'ignored',
104932  queryParams: 'exact'
104933};
104934/**
104935 * The equivalent `IsActiveMatchOptions` options for `Router.isActive` is called with `false`
104936 * (exact = false).
104937 */
104938
104939const subsetMatchOptions = {
104940  paths: 'subset',
104941  fragment: 'ignored',
104942  matrixParams: 'ignored',
104943  queryParams: 'subset'
104944};
104945
104946function assignExtraOptionsToRouter(opts, router) {
104947  if (opts.errorHandler) {
104948    router.errorHandler = opts.errorHandler;
104949  }
104950
104951  if (opts.malformedUriErrorHandler) {
104952    router.malformedUriErrorHandler = opts.malformedUriErrorHandler;
104953  }
104954
104955  if (opts.onSameUrlNavigation) {
104956    router.onSameUrlNavigation = opts.onSameUrlNavigation;
104957  }
104958
104959  if (opts.paramsInheritanceStrategy) {
104960    router.paramsInheritanceStrategy = opts.paramsInheritanceStrategy;
104961  }
104962
104963  if (opts.relativeLinkResolution) {
104964    router.relativeLinkResolution = opts.relativeLinkResolution;
104965  }
104966
104967  if (opts.urlUpdateStrategy) {
104968    router.urlUpdateStrategy = opts.urlUpdateStrategy;
104969  }
104970
104971  if (opts.canceledNavigationResolution) {
104972    router.canceledNavigationResolution = opts.canceledNavigationResolution;
104973  }
104974}
104975
104976function setupRouter() {
104977  const urlSerializer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(UrlSerializer);
104978  const contexts = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(ChildrenOutletContexts);
104979  const location = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_33__.Location);
104980  const injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
104981  const compiler = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Compiler);
104982  const config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(ROUTES, {
104983    optional: true
104984  }) ?? [];
104985  const opts = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(ROUTER_CONFIGURATION, {
104986    optional: true
104987  }) ?? {};
104988  const defaultTitleStrategy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DefaultTitleStrategy);
104989  const titleStrategy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(TitleStrategy, {
104990    optional: true
104991  });
104992  const urlHandlingStrategy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(UrlHandlingStrategy, {
104993    optional: true
104994  });
104995  const routeReuseStrategy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(RouteReuseStrategy, {
104996    optional: true
104997  });
104998  const router = new Router(null, urlSerializer, contexts, location, injector, compiler, flatten(config));
104999
105000  if (urlHandlingStrategy) {
105001    router.urlHandlingStrategy = urlHandlingStrategy;
105002  }
105003
105004  if (routeReuseStrategy) {
105005    router.routeReuseStrategy = routeReuseStrategy;
105006  }
105007
105008  router.titleStrategy = titleStrategy ?? defaultTitleStrategy;
105009  assignExtraOptionsToRouter(opts, router);
105010  assignRelativeLinkResolution(router);
105011  return router;
105012}
105013/**
105014 * @description
105015 *
105016 * A service that provides navigation among views and URL manipulation capabilities.
105017 *
105018 * @see `Route`.
105019 * @see [Routing and Navigation Guide](guide/router).
105020 *
105021 * @ngModule RouterModule
105022 *
105023 * @publicApi
105024 */
105025
105026
105027class Router {
105028  /**
105029   * Creates the router service.
105030   */
105031  // TODO: vsavkin make internal after the final is out.
105032  constructor(rootComponentType, urlSerializer, rootContexts, location, injector, compiler, config) {
105033    this.rootComponentType = rootComponentType;
105034    this.urlSerializer = urlSerializer;
105035    this.rootContexts = rootContexts;
105036    this.location = location;
105037    this.config = config;
105038    this.lastSuccessfulNavigation = null;
105039    this.currentNavigation = null;
105040    this.disposed = false;
105041    this.navigationId = 0;
105042    /**
105043     * The id of the currently active page in the router.
105044     * Updated to the transition's target id on a successful navigation.
105045     *
105046     * This is used to track what page the router last activated. When an attempted navigation fails,
105047     * the router can then use this to compute how to restore the state back to the previously active
105048     * page.
105049     */
105050
105051    this.currentPageId = 0;
105052    this.isNgZoneEnabled = false;
105053    /**
105054     * An event stream for routing events in this NgModule.
105055     */
105056
105057    this.events = new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject();
105058    /**
105059     * A handler for navigation errors in this NgModule.
105060     */
105061
105062    this.errorHandler = defaultErrorHandler;
105063    /**
105064     * A handler for errors thrown by `Router.parseUrl(url)`
105065     * when `url` contains an invalid character.
105066     * The most common case is a `%` sign
105067     * that's not encoded and is not part of a percent encoded sequence.
105068     */
105069
105070    this.malformedUriErrorHandler = defaultMalformedUriErrorHandler;
105071    /**
105072     * True if at least one navigation event has occurred,
105073     * false otherwise.
105074     */
105075
105076    this.navigated = false;
105077    this.lastSuccessfulId = -1;
105078    /**
105079     * Hook that enables you to pause navigation after the preactivation phase.
105080     * Used by `RouterModule`.
105081     *
105082     * @internal
105083     */
105084
105085    this.afterPreactivation = () => (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(void 0);
105086    /**
105087     * A strategy for extracting and merging URLs.
105088     * Used for AngularJS to Angular migrations.
105089     */
105090
105091
105092    this.urlHandlingStrategy = new DefaultUrlHandlingStrategy();
105093    /**
105094     * A strategy for re-using routes.
105095     */
105096
105097    this.routeReuseStrategy = new DefaultRouteReuseStrategy();
105098    /**
105099     * How to handle a navigation request to the current URL. One of:
105100     *
105101     * - `'ignore'` :  The router ignores the request.
105102     * - `'reload'` : The router reloads the URL. Use to implement a "refresh" feature.
105103     *
105104     * Note that this only configures whether the Route reprocesses the URL and triggers related
105105     * action and events like redirects, guards, and resolvers. By default, the router re-uses a
105106     * component instance when it re-navigates to the same component type without visiting a different
105107     * component first. This behavior is configured by the `RouteReuseStrategy`. In order to reload
105108     * routed components on same url navigation, you need to set `onSameUrlNavigation` to `'reload'`
105109     * _and_ provide a `RouteReuseStrategy` which returns `false` for `shouldReuseRoute`.
105110     */
105111
105112    this.onSameUrlNavigation = 'ignore';
105113    /**
105114     * How to merge parameters, data, resolved data, and title from parent to child
105115     * routes. One of:
105116     *
105117     * - `'emptyOnly'` : Inherit parent parameters, data, and resolved data
105118     * for path-less or component-less routes.
105119     * - `'always'` : Inherit parent parameters, data, and resolved data
105120     * for all child routes.
105121     */
105122
105123    this.paramsInheritanceStrategy = 'emptyOnly';
105124    /**
105125     * Determines when the router updates the browser URL.
105126     * By default (`"deferred"`), updates the browser URL after navigation has finished.
105127     * Set to `'eager'` to update the browser URL at the beginning of navigation.
105128     * You can choose to update early so that, if navigation fails,
105129     * you can show an error message with the URL that failed.
105130     */
105131
105132    this.urlUpdateStrategy = 'deferred';
105133    /**
105134     * Enables a bug fix that corrects relative link resolution in components with empty paths.
105135     * @see `RouterModule`
105136     *
105137     * @deprecated
105138     */
105139
105140    this.relativeLinkResolution = 'corrected';
105141    /**
105142     * Configures how the Router attempts to restore state when a navigation is cancelled.
105143     *
105144     * 'replace' - Always uses `location.replaceState` to set the browser state to the state of the
105145     * router before the navigation started. This means that if the URL of the browser is updated
105146     * _before_ the navigation is canceled, the Router will simply replace the item in history rather
105147     * than trying to restore to the previous location in the session history. This happens most
105148     * frequently with `urlUpdateStrategy: 'eager'` and navigations with the browser back/forward
105149     * buttons.
105150     *
105151     * 'computed' - Will attempt to return to the same index in the session history that corresponds
105152     * to the Angular route when the navigation gets cancelled. For example, if the browser back
105153     * button is clicked and the navigation is cancelled, the Router will trigger a forward navigation
105154     * and vice versa.
105155     *
105156     * Note: the 'computed' option is incompatible with any `UrlHandlingStrategy` which only
105157     * handles a portion of the URL because the history restoration navigates to the previous place in
105158     * the browser history rather than simply resetting a portion of the URL.
105159     *
105160     * The default value is `replace`.
105161     *
105162     */
105163
105164    this.canceledNavigationResolution = 'replace';
105165
105166    const onLoadStart = r => this.triggerEvent(new RouteConfigLoadStart(r));
105167
105168    const onLoadEnd = r => this.triggerEvent(new RouteConfigLoadEnd(r));
105169
105170    this.configLoader = injector.get(RouterConfigLoader);
105171    this.configLoader.onLoadEndListener = onLoadEnd;
105172    this.configLoader.onLoadStartListener = onLoadStart;
105173    this.ngModule = injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModuleRef);
105174    this.console = injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵConsole"]);
105175    const ngZone = injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
105176    this.isNgZoneEnabled = ngZone instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone && _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone.isInAngularZone();
105177    this.resetConfig(config);
105178    this.currentUrlTree = createEmptyUrlTree();
105179    this.rawUrlTree = this.currentUrlTree;
105180    this.browserUrlTree = this.currentUrlTree;
105181    this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
105182    this.transitions = new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject({
105183      id: 0,
105184      targetPageId: 0,
105185      currentUrlTree: this.currentUrlTree,
105186      currentRawUrl: this.currentUrlTree,
105187      extractedUrl: this.urlHandlingStrategy.extract(this.currentUrlTree),
105188      urlAfterRedirects: this.urlHandlingStrategy.extract(this.currentUrlTree),
105189      rawUrl: this.currentUrlTree,
105190      extras: {},
105191      resolve: null,
105192      reject: null,
105193      promise: Promise.resolve(true),
105194      source: 'imperative',
105195      restoredState: null,
105196      currentSnapshot: this.routerState.snapshot,
105197      targetSnapshot: null,
105198      currentRouterState: this.routerState,
105199      targetRouterState: null,
105200      guards: {
105201        canActivateChecks: [],
105202        canDeactivateChecks: []
105203      },
105204      guardsResult: null
105205    });
105206    this.navigations = this.setupNavigations(this.transitions);
105207    this.processNavigations();
105208  }
105209  /**
105210   * The ɵrouterPageId of whatever page is currently active in the browser history. This is
105211   * important for computing the target page id for new navigations because we need to ensure each
105212   * page id in the browser history is 1 more than the previous entry.
105213   */
105214
105215
105216  get browserPageId() {
105217    return this.location.getState()?.ɵrouterPageId;
105218  }
105219
105220  setupNavigations(transitions) {
105221    const eventsSubject = this.events;
105222    return transitions.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.filter)(t => t.id !== 0), // Extract URL
105223    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(t => ({ ...t,
105224      extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl)
105225    })), // Using switchMap so we cancel executing navigations when a new one comes in
105226    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(overallTransitionState => {
105227      let completed = false;
105228      let errored = false;
105229      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(overallTransitionState).pipe( // Store the Navigation object
105230      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(t => {
105231        this.currentNavigation = {
105232          id: t.id,
105233          initialUrl: t.rawUrl,
105234          extractedUrl: t.extractedUrl,
105235          trigger: t.source,
105236          extras: t.extras,
105237          previousNavigation: this.lastSuccessfulNavigation ? { ...this.lastSuccessfulNavigation,
105238            previousNavigation: null
105239          } : null
105240        };
105241      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(t => {
105242        const browserUrlTree = this.browserUrlTree.toString();
105243        const urlTransition = !this.navigated || t.extractedUrl.toString() !== browserUrlTree || // Navigations which succeed or ones which fail and are cleaned up
105244        // correctly should result in `browserUrlTree` and `currentUrlTree`
105245        // matching. If this is not the case, assume something went wrong and
105246        // try processing the URL again.
105247        browserUrlTree !== this.currentUrlTree.toString();
105248        const processCurrentUrl = (this.onSameUrlNavigation === 'reload' ? true : urlTransition) && this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
105249
105250        if (processCurrentUrl) {
105251          // If the source of the navigation is from a browser event, the URL is
105252          // already updated. We already need to sync the internal state.
105253          if (isBrowserTriggeredNavigation(t.source)) {
105254            this.browserUrlTree = t.extractedUrl;
105255          }
105256
105257          return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(t).pipe( // Fire NavigationStart event
105258          (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(t => {
105259            const transition = this.transitions.getValue();
105260            eventsSubject.next(new NavigationStart(t.id, this.serializeUrl(t.extractedUrl), t.source, t.restoredState));
105261
105262            if (transition !== this.transitions.getValue()) {
105263              return rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY;
105264            } // This delay is required to match old behavior that forced
105265            // navigation to always be async
105266
105267
105268            return Promise.resolve(t);
105269          }), // ApplyRedirects
105270          applyRedirects(this.ngModule.injector, this.configLoader, this.urlSerializer, this.config), // Update the currentNavigation
105271          // `urlAfterRedirects` is guaranteed to be set after this point
105272          (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(t => {
105273            this.currentNavigation = { ...this.currentNavigation,
105274              finalUrl: t.urlAfterRedirects
105275            };
105276            overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
105277          }), // Recognize
105278          recognize(this.ngModule.injector, this.rootComponentType, this.config, this.urlSerializer, this.paramsInheritanceStrategy, this.relativeLinkResolution), // Update URL if in `eager` update mode
105279          (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(t => {
105280            overallTransitionState.targetSnapshot = t.targetSnapshot;
105281
105282            if (this.urlUpdateStrategy === 'eager') {
105283              if (!t.extras.skipLocationChange) {
105284                const rawUrl = this.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
105285                this.setBrowserUrl(rawUrl, t);
105286              }
105287
105288              this.browserUrlTree = t.urlAfterRedirects;
105289            } // Fire RoutesRecognized
105290
105291
105292            const routesRecognized = new RoutesRecognized(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
105293            eventsSubject.next(routesRecognized);
105294          }));
105295        } else {
105296          const processPreviousUrl = urlTransition && this.rawUrlTree && this.urlHandlingStrategy.shouldProcessUrl(this.rawUrlTree);
105297          /* When the current URL shouldn't be processed, but the previous one
105298           * was, we handle this "error condition" by navigating to the
105299           * previously successful URL, but leaving the URL intact.*/
105300
105301          if (processPreviousUrl) {
105302            const {
105303              id,
105304              extractedUrl,
105305              source,
105306              restoredState,
105307              extras
105308            } = t;
105309            const navStart = new NavigationStart(id, this.serializeUrl(extractedUrl), source, restoredState);
105310            eventsSubject.next(navStart);
105311            const targetSnapshot = createEmptyState(extractedUrl, this.rootComponentType).snapshot;
105312            overallTransitionState = { ...t,
105313              targetSnapshot,
105314              urlAfterRedirects: extractedUrl,
105315              extras: { ...extras,
105316                skipLocationChange: false,
105317                replaceUrl: false
105318              }
105319            };
105320            return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(overallTransitionState);
105321          } else {
105322            /* When neither the current or previous URL can be processed, do
105323             * nothing other than update router's internal reference to the
105324             * current "settled" URL. This way the next navigation will be coming
105325             * from the current URL in the browser.
105326             */
105327            this.rawUrlTree = t.rawUrl;
105328            t.resolve(null);
105329            return rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY;
105330          }
105331        }
105332      }), // --- GUARDS ---
105333      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(t => {
105334        const guardsStart = new GuardsCheckStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
105335        this.triggerEvent(guardsStart);
105336      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(t => {
105337        overallTransitionState = { ...t,
105338          guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts)
105339        };
105340        return overallTransitionState;
105341      }), checkGuards(this.ngModule.injector, evt => this.triggerEvent(evt)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(t => {
105342        overallTransitionState.guardsResult = t.guardsResult;
105343
105344        if (isUrlTree(t.guardsResult)) {
105345          throw redirectingNavigationError(this.urlSerializer, t.guardsResult);
105346        }
105347
105348        const guardsEnd = new GuardsCheckEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
105349        this.triggerEvent(guardsEnd);
105350      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.filter)(t => {
105351        if (!t.guardsResult) {
105352          this.restoreHistory(t);
105353          this.cancelNavigationTransition(t, '', 3
105354          /* NavigationCancellationCode.GuardRejected */
105355          );
105356          return false;
105357        }
105358
105359        return true;
105360      }), // --- RESOLVE ---
105361      switchTap(t => {
105362        if (t.guards.canActivateChecks.length) {
105363          return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(t).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(t => {
105364            const resolveStart = new ResolveStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
105365            this.triggerEvent(resolveStart);
105366          }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.switchMap)(t => {
105367            let dataResolved = false;
105368            return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(t).pipe(resolveData(this.paramsInheritanceStrategy, this.ngModule.injector), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)({
105369              next: () => dataResolved = true,
105370              complete: () => {
105371                if (!dataResolved) {
105372                  this.restoreHistory(t);
105373                  this.cancelNavigationTransition(t, NG_DEV_MODE$2 ? `At least one route resolver didn't emit any value.` : '', 2
105374                  /* NavigationCancellationCode.NoDataFromResolver */
105375                  );
105376                }
105377              }
105378            }));
105379          }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(t => {
105380            const resolveEnd = new ResolveEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
105381            this.triggerEvent(resolveEnd);
105382          }));
105383        }
105384
105385        return undefined;
105386      }), // --- LOAD COMPONENTS ---
105387      switchTap(t => {
105388        const loadComponents = route => {
105389          const loaders = [];
105390
105391          if (route.routeConfig?.loadComponent && !route.routeConfig._loadedComponent) {
105392            loaders.push(this.configLoader.loadComponent(route.routeConfig).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(loadedComponent => {
105393              route.component = loadedComponent;
105394            }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(() => void 0)));
105395          }
105396
105397          for (const child of route.children) {
105398            loaders.push(...loadComponents(child));
105399          }
105400
105401          return loaders;
105402        };
105403
105404        return (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.combineLatest)(loadComponents(t.targetSnapshot.root)).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_24__.defaultIfEmpty)(), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.take)(1));
105405      }), switchTap(() => this.afterPreactivation()), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(t => {
105406        const targetRouterState = createRouterState(this.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
105407        overallTransitionState = { ...t,
105408          targetRouterState
105409        };
105410        return overallTransitionState;
105411      }),
105412      /* Once here, we are about to activate synchronously. The assumption is
105413         this will succeed, and user code may read from the Router service.
105414         Therefore before activation, we need to update router properties storing
105415         the current URL and the RouterState, as well as updated the browser URL.
105416         All this should happen *before* activating. */
105417      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)(t => {
105418        this.currentUrlTree = t.urlAfterRedirects;
105419        this.rawUrlTree = this.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
105420        this.routerState = t.targetRouterState;
105421
105422        if (this.urlUpdateStrategy === 'deferred') {
105423          if (!t.extras.skipLocationChange) {
105424            this.setBrowserUrl(this.rawUrlTree, t);
105425          }
105426
105427          this.browserUrlTree = t.urlAfterRedirects;
105428        }
105429      }), activateRoutes(this.rootContexts, this.routeReuseStrategy, evt => this.triggerEvent(evt)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.tap)({
105430        next() {
105431          completed = true;
105432        },
105433
105434        complete() {
105435          completed = true;
105436        }
105437
105438      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_29__.finalize)(() => {
105439        /* When the navigation stream finishes either through error or success,
105440         * we set the `completed` or `errored` flag. However, there are some
105441         * situations where we could get here without either of those being set.
105442         * For instance, a redirect during NavigationStart. Therefore, this is a
105443         * catch-all to make sure the NavigationCancel event is fired 
105443when a
105444         * navigation gets cancelled but not caught by other means. */
105445        if (!completed && !errored) {
105446          const cancelationReason = NG_DEV_MODE$2 ? `Navigation ID ${overallTransitionState.id} is not equal to the current navigation id ${this.navigationId}` : '';
105447          this.cancelNavigationTransition(overallTransitionState, cancelationReason, 1
105448          /* NavigationCancellationCode.SupersededByNewNavigation */
105449          );
105450        } // Only clear current navigation if it is still set to the one that
105451        // finalized.
105452
105453
105454        if (this.currentNavigation?.id === overallTransitionState.id) {
105455          this.currentNavigation = null;
105456        }
105457      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.catchError)(e => {
105458        errored = true;
105459        /* This error type is issued during Redirect, and is handled as a
105460         * cancellation rather than an error. */
105461
105462        if (isNavigationCancelingError$1(e)) {
105463          if (!isRedirectingNavigationCancelingError$1(e)) {
105464            // Set property only if we're not redirecting. If we landed on a page
105465            // and redirect to `/` route, the new navigation is going to see the
105466            // `/` isn't a change from the default currentUrlTree and won't
105467            // navigate. This is only applicable with initial navigation, so
105468            // setting `navigated` only when not redirecting resolves this
105469            // scenario.
105470            this.navigated = true;
105471            this.restoreHistory(overallTransitionState, true);
105472          }
105473
105474          const navCancel = new NavigationCancel(overallTransitionState.id, this.serializeUrl(overallTransitionState.extractedUrl), e.message, e.cancellationCode);
105475          eventsSubject.next(navCancel); // When redirecting, we need to delay resolving the navigation
105476          // promise and push it to the redirect navigation
105477
105478          if (!isRedirectingNavigationCancelingError$1(e)) {
105479            overallTransitionState.resolve(false);
105480          } else {
105481            const mergedTree = this.urlHandlingStrategy.merge(e.url, this.rawUrlTree);
105482            const extras = {
105483              skipLocationChange: overallTransitionState.extras.skipLocationChange,
105484              // The URL is already updated at this point if we have 'eager' URL
105485              // updates or if the navigation was triggered by the browser (back
105486              // button, URL bar, etc). We want to replace that item in history
105487              // if the navigation is rejected.
105488              replaceUrl: this.urlUpdateStrategy === 'eager' || isBrowserTriggeredNavigation(overallTransitionState.source)
105489            };
105490            this.scheduleNavigation(mergedTree, 'imperative', null, extras, {
105491              resolve: overallTransitionState.resolve,
105492              reject: overallTransitionState.reject,
105493              promise: overallTransitionState.promise
105494            });
105495          }
105496          /* All other errors should reset to the router's internal URL reference
105497           * to the pre-error state. */
105498
105499        } else {
105500          this.restoreHistory(overallTransitionState, true);
105501          const navError = new NavigationError(overallTransitionState.id, this.serializeUrl(overallTransitionState.extractedUrl), e, overallTransitionState.targetSnapshot ?? undefined);
105502          eventsSubject.next(navError);
105503
105504          try {
105505            overallTransitionState.resolve(this.errorHandler(e));
105506          } catch (ee) {
105507            overallTransitionState.reject(ee);
105508          }
105509        }
105510
105511        return rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY;
105512      })); // TODO(jasonaden): remove cast once g3 is on updated TypeScript
105513    }));
105514  }
105515  /**
105516   * @internal
105517   * TODO: this should be removed once the constructor of the router made internal
105518   */
105519
105520
105521  resetRootComponentType(rootComponentType) {
105522    this.rootComponentType = rootComponentType; // TODO: vsavkin router 4.0 should make the root component set to null
105523    // this will simplify the lifecycle of the router.
105524
105525    this.routerState.root.component = this.rootComponentType;
105526  }
105527
105528  setTransition(t) {
105529    this.transitions.next({ ...this.transitions.value,
105530      ...t
105531    });
105532  }
105533  /**
105534   * Sets up the location change listener and performs the initial navigation.
105535   */
105536
105537
105538  initialNavigation() {
105539    this.setUpLocationChangeListener();
105540
105541    if (this.navigationId === 0) {
105542      this.navigateByUrl(this.location.path(true), {
105543        replaceUrl: true
105544      });
105545    }
105546  }
105547  /**
105548   * Sets up the location change listener. This listener detects navigations triggered from outside
105549   * the Router (the browser back/forward buttons, for example) and schedules a corresponding Router
105550   * navigation so that the correct events, guards, etc. are triggered.
105551   */
105552
105553
105554  setUpLocationChangeListener() {
105555    // Don't need to use Zone.wrap any more, because zone.js
105556    // already patch onPopState, so location change callback will
105557    // run into ngZone
105558    if (!this.locationSubscription) {
105559      this.locationSubscription = this.location.subscribe(event => {
105560        const source = event['type'] === 'popstate' ? 'popstate' : 'hashchange';
105561
105562        if (source === 'popstate') {
105563          // The `setTimeout` was added in #12160 and is likely to support Angular/AngularJS
105564          // hybrid apps.
105565          setTimeout(() => {
105566            const extras = {
105567              replaceUrl: true
105568            }; // Navigations coming from Angular router have a navigationId state
105569            // property. When this exists, restore the state.
105570
105571            const state = event.state?.navigationId ? event.state : null;
105572
105573            if (state) {
105574              const stateCopy = { ...state
105575              };
105576              delete stateCopy.navigationId;
105577              delete stateCopy.ɵrouterPageId;
105578
105579              if (Object.keys(stateCopy).length !== 0) {
105580                extras.state = stateCopy;
105581              }
105582            }
105583
105584            const urlTree = this.parseUrl(event['url']);
105585            this.scheduleNavigation(urlTree, source, state, extras);
105586          }, 0);
105587        }
105588      });
105589    }
105590  }
105591  /** The current URL. */
105592
105593
105594  get url() {
105595    return this.serializeUrl(this.currentUrlTree);
105596  }
105597  /**
105598   * Returns the current `Navigation` object when the router is navigating,
105599   * and `null` when idle.
105600   */
105601
105602
105603  getCurrentNavigation() {
105604    return this.currentNavigation;
105605  }
105606  /** @internal */
105607
105608
105609  triggerEvent(event) {
105610    this.events.next(event);
105611  }
105612  /**
105613   * Resets the route configuration used for navigation and generating links.
105614   *
105615   * @param config The route array for the new configuration.
105616   *
105617   * @usageNotes
105618   *
105619   * ```
105620   * router.resetConfig([
105621   *  { path: 'team/:id', component: TeamCmp, children: [
105622   *    { path: 'simple', component: SimpleCmp },
105623   *    { path: 'user/:name', component: UserCmp }
105624   *  ]}
105625   * ]);
105626   * ```
105627   */
105628
105629
105630  resetConfig(config) {
105631    NG_DEV_MODE$2 && validateConfig(config);
105632    this.config = config.map(standardizeConfig);
105633    this.navigated = false;
105634    this.lastSuccessfulId = -1;
105635  }
105636  /** @nodoc */
105637
105638
105639  ngOnDestroy() {
105640    this.dispose();
105641  }
105642  /** Disposes of the router. */
105643
105644
105645  dispose() {
105646    this.transitions.complete();
105647
105648    if (this.locationSubscription) {
105649      this.locationSubscription.unsubscribe();
105650      this.locationSubscription = undefined;
105651    }
105652
105653    this.disposed = true;
105654  }
105655  /**
105656   * Appends URL segments to the current URL tree to create a new URL tree.
105657   *
105658   * @param commands An array of URL fragments with which to construct the new URL tree.
105659   * If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
105660   * segments, followed by the parameters for each segment.
105661   * The fragments are applied to the current URL tree or the one provided  in the `relativeTo`
105662   * property of the options object, if supplied.
105663   * @param navigationExtras Options that control the navigation strategy.
105664   * @returns The new URL tree.
105665   *
105666   * @usageNotes
105667   *
105668   * ```
105669   * // create /team/33/user/11
105670   * router.createUrlTree(['/team', 33, 'user', 11]);
105671   *
105672   * // create /team/33;expand=true/user/11
105673   * router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
105674   *
105675   * // you can collapse static segments like this (this works only with the first passed-in value):
105676   * router.createUrlTree(['/team/33/user', userId]);
105677   *
105678   * // If the first segment can contain slashes, and you do not want the router to split it,
105679   * // you can do the following:
105680   * router.createUrlTree([{segmentPath: '/one/two'}]);
105681   *
105682   * // create /team/33/(user/11//right:chat)
105683   * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: 'chat'}}]);
105684   *
105685   * // remove the right secondary node
105686   * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
105687   *
105688   * // assuming the current url is `/team/33/user/11` and the route points to `user/11`
105689   *
105690   * // navigate to /team/33/user/11/details
105691   * router.createUrlTree(['details'], {relativeTo: route});
105692   *
105693   * // navigate to /team/33/user/22
105694   * router.createUrlTree(['../22'], {relativeTo: route});
105695   *
105696   * // navigate to /team/44/user/22
105697   * router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
105698   *
105699   * Note that a value of `null` or `undefined` for `relativeTo` indicates that the
105700   * tree should be created relative to the root.
105701   * ```
105702   */
105703
105704
105705  createUrlTree(commands, navigationExtras = {}) {
105706    const {
105707      relativeTo,
105708      queryParams,
105709      fragment,
105710      queryParamsHandling,
105711      preserveFragment
105712    } = navigationExtras;
105713    const a = relativeTo || this.routerState.root;
105714    const f = preserveFragment ? this.currentUrlTree.fragment : fragment;
105715    let q = null;
105716
105717    switch (queryParamsHandling) {
105718      case 'merge':
105719        q = { ...this.currentUrlTree.queryParams,
105720          ...queryParams
105721        };
105722        break;
105723
105724      case 'preserve':
105725        q = this.currentUrlTree.queryParams;
105726        break;
105727
105728      default:
105729        q = queryParams || null;
105730    }
105731
105732    if (q !== null) {
105733      q = this.removeEmptyProps(q);
105734    }
105735
105736    return createUrlTree(a, this.currentUrlTree, commands, q, f ?? null);
105737  }
105738  /**
105739   * Navigates to a view using an absolute route path.
105740   *
105741   * @param url An absolute path for a defined route. The function does not apply any delta to the
105742   *     current URL.
105743   * @param extras An object containing properties that modify the navigation strategy.
105744   *
105745   * @returns A Promise that resolves to 'true' when navigation succeeds,
105746   * to 'false' when navigation fails, or is rejected on error.
105747   *
105748   * @usageNotes
105749   *
105750   * The following calls request navigation to an absolute path.
105751   *
105752   * ```
105753   * router.navigateByUrl("/team/33/user/11");
105754   *
105755   * // Navigate without updating the URL
105756   * router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
105757   * ```
105758   *
105759   * @see [Routing and Navigation guide](guide/router)
105760   *
105761   */
105762
105763
105764  navigateByUrl(url, extras = {
105765    skipLocationChange: false
105766  }) {
105767    if (typeof ngDevMode === 'undefined' || ngDevMode && this.isNgZoneEnabled && !_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone.isInAngularZone()) {
105768      this.console.warn(`Navigation triggered outside Angular zone, did 
105768you forget to call 'ngZone.run()'?`);
105769    }
105770
105771    const urlTree = isUrlTree(url) ? url : this.parseUrl(url);
105772    const mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
105773    return this.scheduleNavigation(mergedTree, 'imperative', null, extras);
105774  }
105775  /**
105776   * Navigate based on the provided array of commands and a starting point.
105777   * If no starting route is provided, the navigation is absolute.
105778   *
105779   * @param commands An array of URL fragments with which to construct the target URL.
105780   * If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
105781   * segments, followed by the parameters for each segment.
105782   * The fragments are applied to the current URL or the one provided  in the `relativeTo` property
105783   * of the options object, if supplied.
105784   * @param extras An options object that determines how the URL should be constructed or
105785   *     interpreted.
105786   *
105787   * @returns A Promise that resolves to `true` when navigation succeeds, to `false` when navigation
105788   *     fails,
105789   * or is rejected on error.
105790   *
105791   * @usageNotes
105792   *
105793   * The following calls request navigation to a dynamic route path relative to the current URL.
105794   *
105795   * ```
105796   * router.navigate(['team', 33, 'user', 11], {relativeTo: route});
105797   *
105798   * // Navigate without updating the URL, overriding the default behavior
105799   * router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
105800   * ```
105801   *
105802   * @see [Routing and Navigation guide](guide/router)
105803   *
105804   */
105805
105806
105807  navigate(commands, extras = {
105808    skipLocationChange: false
105809  }) {
105810    validateCommands(commands);
105811    return this.navigateByUrl(this.createUrlTree(commands, extras), extras);
105812  }
105813  /** Serializes a `UrlTree` into a string */
105814
105815
105816  serializeUrl(url) {
105817    return this.urlSerializer.serialize(url);
105818  }
105819  /** Parses a string into a `UrlTree` */
105820
105821
105822  parseUrl(url) {
105823    let urlTree;
105824
105825    try {
105826      urlTree = this.urlSerializer.parse(url);
105827    } catch (e) {
105828      urlTree = this.malformedUriErrorHandler(e, this.urlSerializer, url);
105829    }
105830
105831    return urlTree;
105832  }
105833
105834  isActive(url, matchOptions) {
105835    let options;
105836
105837    if (matchOptions === true) {
105838      options = { ...exactMatchOptions
105839      };
105840    } else if (matchOptions === false) {
105841      options = { ...subsetMatchOptions
105842      };
105843    } else {
105844      options = matchOptions;
105845    }
105846
105847    if (isUrlTree(url)) {
105848      return containsTree(this.currentUrlTree, url, options);
105849    }
105850
105851    const urlTree = this.parseUrl(url);
105852    return containsTree(this.currentUrlTree, urlTree, options);
105853  }
105854
105855  removeEmptyProps(params) {
105856    return Object.keys(params).reduce((result, key) => {
105857      const value = params[key];
105858
105859      if (value !== null && value !== undefined) {
105860        result[key] = value;
105861      }
105862
105863      return result;
105864    }, {});
105865  }
105866
105867  processNavigations() {
105868    this.navigations.subscribe(t => {
105869      this.navigated = true;
105870      this.lastSuccessfulId = t.id;
105871      this.currentPageId = t.targetPageId;
105872      this.events.next(new NavigationEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
105873      this.lastSuccessfulNavigation = this.currentNavigation;
105874      this.titleStrategy?.updateTitle(this.routerState.snapshot);
105875      t.resolve(true);
105876    }, e => {
105877      this.console.warn(`Unhandled Navigation Error: ${e}`);
105878    });
105879  }
105880
105881  scheduleNavigation(rawUrl, source, restoredState, extras, priorPromise) {
105882    if (this.disposed) {
105883      return Promise.resolve(false);
105884    }
105885
105886    let resolve;
105887    let reject;
105888    let promise;
105889
105890    if (priorPromise) {
105891      resolve = priorPromise.resolve;
105892      reject = priorPromise.reject;
105893      promise = priorPromise.promise;
105894    } else {
105895      promise = new Promise((res, rej) => {
105896        resolve = res;
105897        reject = rej;
105898      });
105899    }
105900
105901    const id = ++this.navigationId;
105902    let targetPageId;
105903
105904    if (this.canceledNavigationResolution === 'computed') {
105905      const isInitialPage = this.currentPageId === 0;
105906
105907      if (isInitialPage) {
105908        restoredState = this.location.getState();
105909      } // If the `ɵrouterPageId` exist in the state then `targetpageId` should have the value of
105910      // `ɵrouterPageId`. This is the case for something like a page refresh where we assign the
105911      // target id to the previously set value for that page.
105912
105913
105914      if (restoredState && restoredState.ɵrouterPageId) {
105915        targetPageId = restoredState.ɵrouterPageId;
105916      } else {
105917        // If we're replacing the URL or doing a silent navigation, we do not want to increment the
105918        // page id because we aren't pushing a new entry to history.
105919        if (extras.replaceUrl || extras.skipLocationChange) {
105920          targetPageId = this.browserPageId ?? 0;
105921        } else {
105922          targetPageId = (this.browserPageId ?? 0) + 1;
105923        }
105924      }
105925    } else {
105926      // This is unused when `canceledNavigationResolution` is not computed.
105927      targetPageId = 0;
105928    }
105929
105930    this.setTransition({
105931      id,
105932      targetPageId,
105933      source,
105934      restoredState,
105935      currentUrlTree: this.currentUrlTree,
105936      currentRawUrl: this.rawUrlTree,
105937      rawUrl,
105938      extras,
105939      resolve,
105940      reject,
105941      promise,
105942      currentSnapshot: this.routerState.snapshot,
105943      currentRouterState: this.routerState
105944    }); // Make sure that the error is propagated even though `processNavigations` catch
105945    // handler does not rethrow
105946
105947    return promise.catch(e => {
105948      return Promise.reject(e);
105949    });
105950  }
105951
105952  setBrowserUrl(url, t) {
105953    const path = this.urlSerializer.serialize(url);
105954    const state = { ...t.extras.state,
105955      ...this.generateNgRouterState(t.id, t.targetPageId)
105956    };
105957
105958    if (this.location.isCurrentPathEqualTo(path) || !!t.extras.replaceUrl) {
105959      this.location.replaceState(path, '', state);
105960    } else {
105961      this.location.go(path, '', state);
105962    }
105963  }
105964  /**
105965   * Performs the necessary rollback action to restore the browser URL to the
105966   * state before the transition.
105967   */
105968
105969
105970  restoreHistory(t, restoringFromCaughtError = false) {
105971    if (this.canceledNavigationResolution === 'computed') {
105972      const targetPagePosition = this.currentPageId - t.targetPageId; // The navigator change the location before triggered the browser event,
105973      // so we need to go back to the current url if the navigation is canceled.
105974      // Also, when navigation gets cancelled while using url update strategy eager, then we need to
105975      // go back. Because, when `urlUpdateStrategy` is `eager`; `setBrowserUrl` method is called
105976      // before any verification.
105977
105978      const browserUrlUpdateOccurred = t.source === 'popstate' || this.urlUpdateStrategy === 'eager' || this.currentUrlTree === this.currentNavigation?.finalUrl;
105979
105980      if (browserUrlUpdateOccurred && targetPagePosition !== 0) {
105981        this.location.historyGo(targetPagePosition);
105982      } else if (this.currentUrlTree === this.currentNavigation?.finalUrl && targetPagePosition === 0) {
105983        // We got to the activation stage (where currentUrlTree is set to the navigation's
105984        // finalUrl), but we weren't moving anywhere in history (skipLocationChange or replaceUrl).
105985        // We still need to reset the router state back to what it was when the navigation started.
105986        this.resetState(t); // TODO(atscott): resetting the `browserUrlTree` should really be done in `resetState`.
105987        // Investigate if this can be done by running TGP.
105988
105989        this.browserUrlTree = t.currentUrlTree;
105990        this.resetUrlToCurrentUrlTree();
105991      } else {// The browser URL and router state was not updated before the navigation cancelled so
105992        // there's no restoration needed.
105993      }
105994    } else if (this.canceledNavigationResolution === 'replace') {
105995      // TODO(atscott): It seems like we should _always_ reset the state here. It would be a no-op
105996      // for `deferred` navigations that haven't change the internal state yet because guards
105997      // reject. For 'eager' navigations, it seems like we also really should reset the state
105998      // because the navigation was cancelled. Investigate if this can be done by running TGP.
105999      if (restoringFromCaughtError) {
106000        this.resetState(t);
106001      }
106002
106003      this.resetUrlToCurrentUrlTree();
106004    }
106005  }
106006
106007  resetState(t) {
106008    this.routerState = t.currentRouterState;
106009    this.currentUrlTree = t.currentUrlTree; // Note here that we use the urlHandlingStrategy to get the reset `rawUrlTree` because it may be
106010    // configured to handle only part of the navigation URL. This means we would only want to reset
106011    // the part of the navigation handled by the Angular router rather than the whole URL. In
106012    // addition, the URLHandlingStrategy may be configured to specifically preserve parts of the URL
106013    // when merging, such as the query params so they are not lost on a refresh.
106014
106015    this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, t.rawUrl);
106016  }
106017
106018  resetUrlToCurrentUrlTree() {
106019    this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
106020  }
106021
106022  cancelNavigationTransition(t, reason, code) {
106023    const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), reason, code);
106024    this.triggerEvent(navCancel);
106025    t.resolve(false);
106026  }
106027
106028  generateNgRouterState(navigationId, routerPageId) {
106029    if (this.canceledNavigationResolution === 'computed') {
106030      return {
106031        navigationId,
106032        ɵrouterPageId: routerPageId
106033      };
106034    }
106035
106036    return {
106037      navigationId
106038    };
106039  }
106040
106041}
106042
106043Router.ɵfac = function Router_Factory(t) {
106044  _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinvalidFactory"]();
106045};
106046
106047Router.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
106048  token: Router,
106049  factory: function () {
106050    return setupRouter();
106051  },
106052  providedIn: 'root'
106053});
106054
106055(function () {
106056  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](Router, [{
106057    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
106058    args: [{
106059      providedIn: 'root',
106060      useFactory: setupRouter
106061    }]
106062  }], function () {
106063    return [{
106064      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Type
106065    }, {
106066      type: UrlSerializer
106067    }, {
106068      type: ChildrenOutletContexts
106069    }, {
106070      type: _angular_common__WEBPACK_IMPORTED_MODULE_33__.Location
106071    }, {
106072      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector
106073    }, {
106074      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Compiler
106075    }, {
106076      type: undefined
106077    }];
106078  }, null);
106079})();
106080
106081function validateCommands(commands) {
106082  for (let i = 0; i < commands.length; i++) {
106083    const cmd = commands[i];
106084
106085    if (cmd == null) {
106086      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4008
106087      /* RuntimeErrorCode.NULLISH_COMMAND */
106088      , NG_DEV_MODE$2 && `The requested path contains ${cmd} segment at index ${i}`);
106089    }
106090  }
106091}
106092
106093function isBrowserTriggeredNavigation(source) {
106094  return source !== 'imperative';
106095}
106096/**
106097 * @license
106098 * Copyright Google LLC All Rights Reserved.
106099 *
106100 * Use of this source code is governed by an MIT-style license that can be
106101 * found in the LICENSE file at https://angular.io/license
106102 */
106103
106104/**
106105 * @description
106106 *
106107 * When applied to an element in a template, makes that element a link
106108 * that initiates navigation to a route. Navigation opens one or more routed components
106109 * in one or more `<router-outlet>` locations on the page.
106110 *
106111 * Given a route configuration `[{ path: 'user/:name', component: UserCmp }]`,
106112 * the following creates a static link to the route:
106113 * `<a routerLink="/user/bob">link to user component</a>`
106114 *
106115 * You can use dynamic values to generate the link.
106116 * For a dynamic link, pass an array of path segments,
106117 * followed by the params for each segment.
106118 * For example, `['/team', teamId, 'user', userName, {details: true}]`
106119 * generates a link to `/team/11/user/bob;details=true`.
106120 *
106121 * Multiple static segments can be merged into one term and combined with dynamic segments.
106122 * For example, `['/team/11/user', userName, {details: true}]`
106123 *
106124 * The input that you provide to the link is treated as a delta to the current URL.
106125 * For instance, suppose the current URL is `/user/(box//aux:team)`.
106126 * The link `<a [routerLink]="['/user/jim']">Jim</a>` creates the URL
106127 * `/user/(jim//aux:team)`.
106128 * See {@link Router#createUrlTree createUrlTree} for more information.
106129 *
106130 * @usageNotes
106131 *
106132 * You can use absolute or relative paths in a link, set query parameters,
106133 * control how parameters are handled, and keep a history of navigation states.
106134 *
106135 * ### Relative link paths
106136 *
106137 * The first segment name can be prepended with `/`, `./`, or `../`.
106138 * * If the first segment begins with `/`, the router looks up the route from the root of the
106139 *   app.
106140 * * If the first segment begins with `./`, or doesn't begin with a slash, the router
106141 *   looks in the children of the current activated route.
106142 * * If the first segment begins with `../`, the router goes up one level in the route tree.
106143 *
106144 * ### Setting and handling query params and fragments
106145 *
106146 * The following link adds a query parameter and a fragment to the generated URL:
106147 *
106148 * ```
106149 * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education">
106150 *   link to user component
106151 * </a>
106152 * ```
106153 * By default, the directive constructs the new URL using the given query parameters.
106154 * The example generates the link: `/user/bob?debug=true#education`.
106155 *
106156 * You can instruct the directive to handle query parameters differently
106157 * by specifying the `queryParamsHandling` option in the link.
106158 * Allowed values are:
106159 *
106160 *  - `'merge'`: Merge the given `queryParams` into the current query params.
106161 *  - `'preserve'`: Preserve the current query params.
106162 *
106163 * For example:
106164 *
106165 * ```
106166 * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge">
106167 *   link to user component
106168 * </a>
106169 * ```
106170 *
106171 * See {@link UrlCreationOptions.queryParamsHandling UrlCreationOptions#queryParamsHandling}.
106172 *
106173 * ### Preserving navigation history
106174 *
106175 * You can provide a `state` value to be persisted to the browser's
106176 * [`History.state` property](https://developer.mozilla.org/en-US/docs/Web/API/History#Properties).
106177 * For example:
106178 *
106179 * ```
106180 * <a [routerLink]="['/user/bob']" [state]="{tracingId: 123}">
106181 *   link to user component
106182 * </a>
106183 * ```
106184 *
106185 * Use {@link Router.getCurrentNavigation() Router#getCurrentNavigation} to retrieve a saved
106186 * navigation-state value. For example, to capture the `tracingId` during the `NavigationStart`
106187 * event:
106188 *
106189 * ```
106190 * // Get NavigationStart events
106191 * router.events.pipe(filter(e => e instanceof NavigationStart)).subscribe(e => {
106192 *   const navigation = router.getCurrentNavigation();
106193 *   tracingService.trace({id: navigation.extras.state.tracingId});
106194 * });
106195 * ```
106196 *
106197 * @ngModule RouterModule
106198 *
106199 * @publicApi
106200 */
106201
106202
106203class RouterLink {
106204  constructor(router, route, tabIndexAttribute, renderer, el) {
106205    this.router = router;
106206    this.route = route;
106207    this.tabIndexAttribute = tabIndexAttribute;
106208    this.renderer = renderer;
106209    this.el = el;
106210    this._preserveFragment = false;
106211    this._skipLocationChange = false;
106212    this._replaceUrl = false;
106213    this.commands = null;
106214    /** @internal */
106215
106216    this.onChanges = new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject();
106217    this.setTabIndexIfNotOnNativeEl('0');
106218  }
106219  /**
106220   * Passed to {@link Router#createUrlTree Router#createUrlTree} as part of the
106221   * `UrlCreationOptions`.
106222   * @see {@link UrlCreationOptions#preserveFragment UrlCreationOptions#preserveFragment}
106223   * @see {@link Router#createUrlTree Router#createUrlTree}
106224   */
106225
106226
106227  set preserveFragment(preserveFragment) {
106228    this._preserveFragment = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵcoerceToBoolean"])(preserveFragment);
106229  }
106230
106231  get preserveFragment() {
106232    return this._preserveFragment;
106233  }
106234  /**
106235   * Passed to {@link Router#navigateByUrl Router#navigateByUrl} as part of the
106236   * `NavigationBehaviorOptions`.
106237   * @see {@link NavigationBehaviorOptions#skipLocationChange NavigationBehaviorOptions#skipLocationChange}
106238   * @see {@link Router#navigateByUrl Router#navigateByUrl}
106239   */
106240
106241
106242  set skipLocationChange(skipLocationChange) {
106243    this._skipLocationChange = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵcoerceToBoolean"])(skipLocationChange);
106244  }
106245
106246  get skipLocationChange() {
106247    return this._skipLocationChange;
106248  }
106249  /**
106250   * Passed to {@link Router#navigateByUrl Router#navigateByUrl} as part of the
106251   * `NavigationBehaviorOptions`.
106252   * @see {@link NavigationBehaviorOptions#replaceUrl NavigationBehaviorOptions#replaceUrl}
106253   * @see {@link Router#navigateByUrl Router#navigateByUrl}
106254   */
106255
106256
106257  set replaceUrl(replaceUrl) {
106258    this._replaceUrl = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵcoerceToBoolean"])(replaceUrl);
106259  }
106260
106261  get replaceUrl() {
106262    return this._replaceUrl;
106263  }
106264  /**
106265   * Modifies the tab index if there was not a tabindex attribute on the element during
106266   * instantiation.
106267   */
106268
106269
106270  setTabIndexIfNotOnNativeEl(newTabIndex) {
106271    if (this.tabIndexAttribute != null
106272    /* both `null` and `undefined` */
106273    ) {
106274      return;
106275    }
106276
106277    const renderer = this.renderer;
106278    const nativeElement = this.el.nativeElement;
106279
106280    if (newTabIndex !== null) {
106281      renderer.setAttribute(nativeElement, 'tabindex', newTabIndex);
106282    } else {
106283      renderer.removeAttribute(nativeElement, 'tabindex');
106284    }
106285  }
106286  /** @nodoc */
106287
106288
106289  ngOnChanges(changes) {
106290    // This is subscribed to by `RouterLinkActive` so that it knows to update when there are changes
106291    // to the RouterLinks it's tracking.
106292    this.onChanges.next(this);
106293  }
106294  /**
106295   * Commands to pass to {@link Router#createUrlTree Router#createUrlTree}.
106296   *   - **array**: commands to pass to {@link Router#createUrlTree Router#createUrlTree}.
106297   *   - **string**: shorthand for array of commands with just the string, i.e. `['/route']`
106298   *   - **null|undefined**: effectively disables the `routerLink`
106299   * @see {@link Router#createUrlTree Router#createUrlTree}
106300   */
106301
106302
106303  set routerLink(commands) {
106304    if (commands != null) {
106305      this.commands = Array.isArray(commands) ? commands : [commands];
106306      this.setTabIndexIfNotOnNativeEl('0');
106307    } else {
106308      this.commands = null;
106309      this.setTabIndexIfNotOnNativeEl(null);
106310    }
106311  }
106312  /** @nodoc */
106313
106314
106315  onClick() {
106316    if (this.urlTree === null) {
106317      return true;
106318    }
106319
106320    const extras = {
106321      skipLocationChange: this.skipLocationChange,
106322      replaceUrl: this.replaceUrl,
106323      state: this.state
106324    };
106325    this.router.navigateByUrl(this.urlTree, extras);
106326    return true;
106327  }
106328
106329  get urlTree() {
106330    if (this.commands === null) {
106331      return null;
106332    }
106333
106334    return this.router.createUrlTree(this.commands, {
106335      // If the `relativeTo` input is not defined, we want to use `this.route` by default.
106336      // Otherwise, we should use the value provided by the user in the input.
106337      relativeTo: this.relativeTo !== undefined ? this.relativeTo : this.route,
106338      queryParams: this.queryParams,
106339      fragment: this.fragment,
106340      queryParamsHandling: this.queryParamsHandling,
106341      preserveFragment: this.preserveFragment
106342    });
106343  }
106344
106345}
106346
106347RouterLink.ɵfac = function RouterLink_Factory(t) {
106348  return new (t || RouterLink)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](Router), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ActivatedRoute), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('tabindex'), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef));
106349};
106350
106351RouterLink.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
106352  type: RouterLink,
106353  selectors: [["", "routerLink", "", 5, "a", 5, "area"]],
106354  hostBindings: function RouterLink_HostBindings(rf, ctx) {
106355    if (rf & 1) {
106356      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function RouterLink_click_HostBindingHandler() {
106357        return ctx.onClick();
106358      });
106359    }
106360  },
106361  inputs: {
106362    queryParams: "queryParams",
106363    fragment: "fragment",
106364    queryParamsHandling: "queryParamsHandling",
106365    state: "state",
106366    relativeTo: "relativeTo",
106367    preserveFragment: "preserveFragment",
106368    skipLocationChange: "skipLocationChange",
106369    replaceUrl: "replaceUrl",
106370    routerLink: "routerLink"
106371  },
106372  standalone: true,
106373  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
106374});
106375
106376(function () {
106377  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RouterLink, [{
106378    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
106379    args: [{
106380      selector: ':not(a):not(area)[routerLink]',
106381      standalone: true
106382    }]
106383  }], function () {
106384    return [{
106385      type: Router
106386    }, {
106387      type: ActivatedRoute
106388    }, {
106389      type: undefined,
106390      decorators: [{
106391        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
106392        args: ['tabindex']
106393      }]
106394    }, {
106395      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
106396    }, {
106397      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
106398    }];
106399  }, {
106400    queryParams: [{
106401      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106402    }],
106403    fragment: [{
106404      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106405    }],
106406    queryParamsHandling: [{
106407      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106408    }],
106409    state: [{
106410      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106411    }],
106412    relativeTo: [{
106413      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106414    }],
106415    preserveFragment: [{
106416      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106417    }],
106418    skipLocationChange: [{
106419      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106420    }],
106421    replaceUrl: [{
106422      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106423    }],
106424    routerLink: [{
106425      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106426    }],
106427    onClick: [{
106428      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostListener,
106429      args: ['click']
106430    }]
106431  });
106432})();
106433/**
106434 * @description
106435 *
106436 * Lets you link to specific routes in your app.
106437 *
106438 * See `RouterLink` for more information.
106439 *
106440 * @ngModule RouterModule
106441 *
106442 * @publicApi
106443 */
106444
106445
106446class RouterLinkWithHref {
106447  constructor(router, route, locationStrategy) {
106448    this.router = router;
106449    this.route = route;
106450    this.locationStrategy = locationStrategy;
106451    this._preserveFragment = false;
106452    this._skipLocationChange = false;
106453    this._replaceUrl = false;
106454    this.commands = null; // the url displayed on the anchor element.
106455    // @HostBinding('attr.href') is used rather than @HostBinding() because it removes the
106456    // href attribute when it becomes `null`.
106457
106458    this.href = null;
106459    /** @internal */
106460
106461    this.onChanges = new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject();
106462    this.subscription = router.events.subscribe(s => {
106463      if (s instanceof NavigationEnd) {
106464        this.updateTargetUrlAndHref();
106465      }
106466    });
106467  }
106468  /**
106469   * Passed to {@link Router#createUrlTree Router#createUrlTree} as part of the
106470   * `UrlCreationOptions`.
106471   * @see {@link UrlCreationOptions#preserveFragment UrlCreationOptions#preserveFragment}
106472   * @see {@link Router#createUrlTree Router#createUrlTree}
106473   */
106474
106475
106476  set preserveFragment(preserveFragment) {
106477    this._preserveFragment = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵcoerceToBoolean"])(preserveFragment);
106478  }
106479
106480  get preserveFragment() {
106481    return this._preserveFragment;
106482  }
106483  /**
106484   * Passed to {@link Router#navigateByUrl Router#navigateByUrl} as part of the
106485   * `NavigationBehaviorOptions`.
106486   * @see {@link NavigationBehaviorOptions#skipLocationChange NavigationBehaviorOptions#skipLocationChange}
106487   * @see {@link Router#navigateByUrl Router#navigateByUrl}
106488   */
106489
106490
106491  set skipLocationChange(skipLocationChange) {
106492    this._skipLocationChange = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵcoerceToBoolean"])(skipLocationChange);
106493  }
106494
106495  get skipLocationChange() {
106496    return this._skipLocationChange;
106497  }
106498  /**
106499   * Passed to {@link Router#navigateByUrl Router#navigateByUrl} as part of the
106500   * `NavigationBehaviorOptions`.
106501   * @see {@link NavigationBehaviorOptions#replaceUrl NavigationBehaviorOptions#replaceUrl}
106502   * @see {@link Router#navigateByUrl Router#navigateByUrl}
106503   */
106504
106505
106506  set replaceUrl(replaceUrl) {
106507    this._replaceUrl = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵcoerceToBoolean"])(replaceUrl);
106508  }
106509
106510  get replaceUrl() {
106511    return this._replaceUrl;
106512  }
106513  /**
106514   * Commands to pass to {@link Router#createUrlTree Router#createUrlTree}.
106515   *   - **array**: commands to pass to {@link Router#createUrlTree Router#createUrlTree}.
106516   *   - **string**: shorthand for array of commands with just the string, i.e. `['/route']`
106517   *   - **null|undefined**: Disables the link by removing the `href`
106518   * @see {@link Router#createUrlTree Router#createUrlTree}
106519   */
106520
106521
106522  set routerLink(commands) {
106523    if (commands != null) {
106524      this.commands = Array.isArray(commands) ? commands : [commands];
106525    } else {
106526      this.commands = null;
106527    }
106528  }
106529  /** @nodoc */
106530
106531
106532  ngOnChanges(changes) {
106533    this.updateTargetUrlAndHref();
106534    this.onChanges.next(this);
106535  }
106536  /** @nodoc */
106537
106538
106539  ngOnDestroy() {
106540    this.subscription.unsubscribe();
106541  }
106542  /** @nodoc */
106543
106544
106545  onClick(button, ctrlKey, shiftKey, altKey, metaKey) {
106546    if (button !== 0 || ctrlKey || shiftKey || altKey || metaKey) {
106547      return true;
106548    }
106549
106550    if (typeof this.target === 'string' && this.target != '_self' || this.urlTree === null) {
106551      return true;
106552    }
106553
106554    const extras = {
106555      skipLocationChange: this.skipLocationChange,
106556      replaceUrl: this.replaceUrl,
106557      state: this.state
106558    };
106559    this.router.navigateByUrl(this.urlTree, extras);
106560    return false;
106561  }
106562
106563  updateTargetUrlAndHref() {
106564    this.href = this.urlTree !== null ? this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.urlTree)) : null;
106565  }
106566
106567  get urlTree() {
106568    if (this.commands === null) {
106569      return null;
106570    }
106571
106572    return this.router.createUrlTree(this.commands, {
106573      // If the `relativeTo` input is not defined, we want to use `this.route` by default.
106574      // Otherwise, we should use the value provided by the user in the input.
106575      relativeTo: this.relativeTo !== undefined ? this.relativeTo : this.route,
106576      queryParams: this.queryParams,
106577      fragment: this.fragment,
106578      queryParamsHandling: this.queryParamsHandling,
106579      preserveFragment: this.preserveFragment
106580    });
106581  }
106582
106583}
106584
106585RouterLinkWithHref.ɵfac = function RouterLinkWithHref_Factory(t) {
106586  return new (t || RouterLinkWithHref)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](Router), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ActivatedRoute), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_common__WEBPACK_IMPORTED_MODULE_33__.LocationStrategy));
106587};
106588
106589RouterLinkWithHref.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
106590  type: RouterLinkWithHref,
106591  selectors: [["a", "routerLink", ""], ["area", "routerLink", ""]],
106592  hostVars: 2,
106593  hostBindings: function RouterLinkWithHref_HostBindings(rf, ctx) {
106594    if (rf & 1) {
106595      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function RouterLinkWithHref_click_HostBindingHandler($event) {
106596        return ctx.onClick($event.button, $event.ctrlKey, $event.shiftKey, $event.altKey, $event.metaKey);
106597      });
106598    }
106599
106600    if (rf & 2) {
106601      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("target", ctx.target)("href", ctx.href, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵsanitizeUrl"]);
106602    }
106603  },
106604  inputs: {
106605    target: "target",
106606    queryParams: "queryParams",
106607    fragment: "fragment",
106608    queryParamsHandling: "queryParamsHandling",
106609    state: "state",
106610    relativeTo: "relativeTo",
106611    preserveFragment: "preserveFragment",
106612    skipLocationChange: "skipLocationChange",
106613    replaceUrl: "replaceUrl",
106614    routerLink: "routerLink"
106615  },
106616  standalone: true,
106617  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
106618});
106619
106620(function () {
106621  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RouterLinkWithHref, [{
106622    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
106623    args: [{
106624      selector: 'a[routerLink],area[routerLink]',
106625      standalone: true
106626    }]
106627  }], function () {
106628    return [{
106629      type: Router
106630    }, {
106631      type: ActivatedRoute
106632    }, {
106633      type: _angular_common__WEBPACK_IMPORTED_MODULE_33__.LocationStrategy
106634    }];
106635  }, {
106636    target: [{
106637      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
106638      args: ['attr.target']
106639    }, {
106640      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106641    }],
106642    queryParams: [{
106643      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106644    }],
106645    fragment: [{
106646      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106647    }],
106648    queryParamsHandling: [{
106649      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106650    }],
106651    state: [{
106652      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106653    }],
106654    relativeTo: [{
106655      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106656    }],
106657    href: [{
106658      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
106659      args: ['attr.href']
106660    }],
106661    preserveFragment: [{
106662      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106663    }],
106664    skipLocationChange: [{
106665      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106666    }],
106667    replaceUrl: [{
106668      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106669    }],
106670    routerLink: [{
106671      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106672    }],
106673    onClick: [{
106674      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostListener,
106675      args: ['click', ['$event.button', '$event.ctrlKey', '$event.shiftKey', '$event.altKey', '$event.metaKey']]
106676    }]
106677  });
106678})();
106679/**
106680 * @license
106681 * Copyright Google LLC All Rights Reserved.
106682 *
106683 * Use of this source code is governed by an MIT-style license that can be
106684 * found in the LICENSE file at https://angular.io/license
106685 */
106686
106687/**
106688 *
106689 * @description
106690 *
106691 * Tracks whether the linked route of an element is currently active, and allows you
106692 * to specify one or more CSS classes to add to the element when the linked route
106693 * is active.
106694 *
106695 * Use this directive to create a visual distinction for elements associated with an active route.
106696 * For example, the following code highlights the word "Bob" when the router
106697 * activates the associated route:
106698 *
106699 * ```
106700 * <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
106701 * ```
106702 *
106703 * Whenever the URL is either '/user' or '/user/bob', the "active-link" class is
106704 * added to the anchor tag. If the URL changes, the class is removed.
106705 *
106706 * You can set more than one class using a space-separated string or an array.
106707 * For example:
106708 *
106709 * ```
106710 * <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
106711 * <a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
106712 * ```
106713 *
106714 * To add the classes only when the URL matches the link exactly, add the option `exact: true`:
106715 *
106716 * ```
106717 * <a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact:
106718 * true}">Bob</a>
106719 * ```
106720 *
106721 * To directly check the `isActive` status of the link, assign the `RouterLinkActive`
106722 * instance to a template variable.
106723 * For example, the following checks the status without assigning any CSS classes:
106724 *
106725 * ```
106726 * <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive">
106727 *   Bob {{ rla.isActive ? '(already open)' : ''}}
106728 * </a>
106729 * ```
106730 *
106731 * You can apply the `RouterLinkActive` directive to an ancestor of linked elements.
106732 * For example, the following sets the active-link class on the `<div>`  parent tag
106733 * when the URL is either '/user/jim' or '/user/bob'.
106734 *
106735 * ```
106736 * <div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
106737 *   <a routerLink="/user/jim">Jim</a>
106738 *   <a routerLink="/user/bob">Bob</a>
106739 * </div>
106740 * ```
106741 *
106742 * The `RouterLinkActive` directive can also be used to set the aria-current attribute
106743 * to provide an alternative distinction for active elements to visually impaired users.
106744 *
106745 * For example, the following code adds the 'active' class to the Home Page link when it is
106746 * indeed active and in such case also sets its aria-current attribute to 'page':
106747 *
106748 * ```
106749 * <a routerLink="/" routerLinkActive="active" ariaCurrentWhenActive="page">Home Page</a>
106750 * ```
106751 *
106752 * @ngModule RouterModule
106753 *
106754 * @publicApi
106755 */
106756
106757
106758class RouterLinkActive {
106759  constructor(router, element, renderer, cdr, link, linkWithHref) {
106760    this.router = router;
106761    this.element = element;
106762    this.renderer = renderer;
106763    this.cdr = cdr;
106764    this.link = link;
106765    this.linkWithHref = linkWithHref;
106766    this.classes = [];
106767    this.isActive = false;
106768    /**
106769     * Options to configure how to determine if the router link is active.
106770     *
106771     * These options are passed to the `Router.isActive()` function.
106772     *
106773     * @see Router.isActive
106774     */
106775
106776    this.routerLinkActiveOptions = {
106777      exact: false
106778    };
106779    /**
106780     *
106781     * You can use the output `isActiveChange` to get notified each time the link becomes
106782     * active or inactive.
106783     *
106784     * Emits:
106785     * true  -> Route is active
106786     * false -> Route is inactive
106787     *
106788     * ```
106789     * <a
106790     *  routerLink="/user/bob"
106791     *  routerLinkActive="active-link"
106792     *  (isActiveChange)="this.onRouterLinkActive($event)">Bob</a>
106793     * ```
106794     */
106795
106796    this.isActiveChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
106797    this.routerEventsSubscription = router.events.subscribe(s => {
106798      if (s instanceof NavigationEnd) {
106799        this.update();
106800      }
106801    });
106802  }
106803  /** @nodoc */
106804
106805
106806  ngAfterContentInit() {
106807    // `of(null)` is used to force subscribe body to execute once immediately (like `startWith`).
106808    (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(this.links.changes, this.linksWithHrefs.changes, (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(null)).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_34__.mergeAll)()).subscribe(_ => {
106809      this.update();
106810      this.subscribeToEachLinkOnChanges();
106811    });
106812  }
106813
106814  subscribeToEachLinkOnChanges() {
106815    this.linkInputChangesSubscription?.unsubscribe();
106816    const allLinkChanges = [...this.links.toArray(), ...this.linksWithHrefs.toArray(), this.link, this.linkWithHref].filter(link => !!link).map(link => link.onChanges);
106817    this.linkInputChangesSubscription = (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(allLinkChanges).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_34__.mergeAll)()).subscribe(link => {
106818      if (this.isActive !== this.isLinkActive(this.router)(link)) {
106819        this.update();
106820      }
106821    });
106822  }
106823
106824  set routerLinkActive(data) {
106825    const classes = Array.isArray(data) ? data : data.split(' ');
106826    this.classes = classes.filter(c => !!c);
106827  }
106828  /** @nodoc */
106829
106830
106831  ngOnChanges(changes) {
106832    this.update();
106833  }
106834  /** @nodoc */
106835
106836
106837  ngOnDestroy() {
106838    this.routerEventsSubscription.unsubscribe();
106839    this.linkInputChangesSubscription?.unsubscribe();
106840  }
106841
106842  update() {
106843    if (!this.links || !this.linksWithHrefs || !this.router.navigated) return;
106844    Promise.resolve().then(() => {
106845      const hasActiveLinks = this.hasActiveLinks();
106846
106847      if (this.isActive !== hasActiveLinks) {
106848        this.isActive = hasActiveLinks;
106849        this.cdr.markForCheck();
106850        this.classes.forEach(c => {
106851          if (hasActiveLinks) {
106852            this.renderer.addClass(this.element.nativeElement, c);
106853          } else {
106854            this.renderer.removeClass(this.element.nativeElement, c);
106855          }
106856        });
106857
106858        if (hasActiveLinks && this.ariaCurrentWhenActive !== undefined) {
106859          this.renderer.setAttribute(this.element.nativeElement, 'aria-current', this.ariaCurrentWhenActive.toString());
106860        } else {
106861          this.renderer.removeAttribute(this.element.nativeElement, 'aria-current');
106862        } // Emit on isActiveChange after classes are updated
106863
106864
106865        this.isActiveChange.emit(hasActiveLinks);
106866      }
106867    });
106868  }
106869
106870  isLinkActive(router) {
106871    const options = isActiveMatchOptions(this.routerLinkActiveOptions) ? this.routerLinkActiveOptions : // While the types should disallow `undefined` here, it's possible without strict inputs
106872    this.routerLinkActiveOptions.exact || false;
106873    return link => link.urlTree ? router.isActive(link.urlTree, options) : false;
106874  }
106875
106876  hasActiveLinks() {
106877    const isActiveCheckFn = this.isLinkActive(this.router);
106878    return this.link && isActiveCheckFn(this.link) || this.linkWithHref && isActiveCheckFn(this.linkWithHref) || this.links.some(isActiveCheckFn) || this.linksWithHrefs.some(isActiveCheckFn);
106879  }
106880
106881}
106882
106883RouterLinkActive.ɵfac = function RouterLinkActive_Factory(t) {
106884  return new (t || RouterLinkActive)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](Router), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](RouterLink, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](RouterLinkWithHref, 8));
106885};
106886
106887RouterLinkActive.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
106888  type: RouterLinkActive,
106889  selectors: [["", "routerLinkActive", ""]],
106890  contentQueries: function RouterLinkActive_ContentQueries(rf, ctx, dirIndex) {
106891    if (rf & 1) {
106892      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, RouterLink, 5);
106893      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, RouterLinkWithHref, 5);
106894    }
106895
106896    if (rf & 2) {
106897      let _t;
106898
106899      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.links = _t);
106900      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.linksWithHrefs = _t);
106901    }
106902  },
106903  inputs: {
106904    routerLinkActiveOptions: "routerLinkActiveOptions",
106905    ariaCurrentWhenActive: "ariaCurrentWhenActive",
106906    routerLinkActive: "routerLinkActive"
106907  },
106908  outputs: {
106909    isActiveChange: "isActiveChange"
106910  },
106911  exportAs: ["routerLinkActive"],
106912  standalone: true,
106913  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
106914});
106915
106916(function () {
106917  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RouterLinkActive, [{
106918    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
106919    args: [{
106920      selector: '[routerLinkActive]',
106921      exportAs: 'routerLinkActive',
106922      standalone: true
106923    }]
106924  }], function () {
106925    return [{
106926      type: Router
106927    }, {
106928      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
106929    }, {
106930      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
106931    }, {
106932      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
106933    }, {
106934      type: RouterLink,
106935      decorators: [{
106936        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
106937      }]
106938    }, {
106939      type: RouterLinkWithHref,
106940      decorators: [{
106941        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
106942      }]
106943    }];
106944  }, {
106945    links: [{
106946      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
106947      args: [RouterLink, {
106948        descendants: true
106949      }]
106950    }],
106951    linksWithHrefs: [{
106952      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
106953      args: [RouterLinkWithHref, {
106954        descendants: true
106955      }]
106956    }],
106957    routerLinkActiveOptions: [{
106958      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106959    }],
106960    ariaCurrentWhenActive: [{
106961      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106962    }],
106963    isActiveChange: [{
106964      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
106965    }],
106966    routerLinkActive: [{
106967      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
106968    }]
106969  });
106970})();
106971/**
106972 * Use instead of `'paths' in options` to be compatible with property renaming
106973 */
106974
106975
106976function isActiveMatchOptions(options) {
106977  return !!options.paths;
106978}
106979/**
106980 * @license
106981 * Copyright Google LLC All Rights Reserved.
106982 *
106983 * Use of this source code is governed by an MIT-style license that can be
106984 * found in the LICENSE file at https://angular.io/license
106985 */
106986
106987/**
106988 * @description
106989 *
106990 * Provides a preloading strategy.
106991 *
106992 * @publicApi
106993 */
106994
106995
106996class PreloadingStrategy {}
106997/**
106998 * @description
106999 *
107000 * Provides a preloading strategy that preloads all modules as quickly as possible.
107001 *
107002 * ```
107003 * RouterModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules})
107004 * ```
107005 *
107006 * @publicApi
107007 */
107008
107009
107010class PreloadAllModules {
107011  preload(route, fn) {
107012    return fn().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.catchError)(() => (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(null)));
107013  }
107014
107015}
107016
107017PreloadAllModules.ɵfac = function PreloadAllModules_Factory(t) {
107018  return new (t || PreloadAllModules)();
107019};
107020
107021PreloadAllModules.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
107022  token: PreloadAllModules,
107023  factory: PreloadAllModules.ɵfac,
107024  providedIn: 'root'
107025});
107026
107027(function () {
107028  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PreloadAllModules, [{
107029    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
107030    args: [{
107031      providedIn: 'root'
107032    }]
107033  }], null, null);
107034})();
107035/**
107036 * @description
107037 *
107038 * Provides a preloading strategy that does not preload any modules.
107039 *
107040 * This strategy is enabled by default.
107041 *
107042 * @publicApi
107043 */
107044
107045
107046class NoPreloading {
107047  preload(route, fn) {
107048    return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(null);
107049  }
107050
107051}
107052
107053NoPreloading.ɵfac = function NoPreloading_Factory(t) {
107054  return new (t || NoPreloading)();
107055};
107056
107057NoPreloading.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
107058  token: NoPreloading,
107059  factory: NoPreloading.ɵfac,
107060  providedIn: 'root'
107061});
107062
107063(function () {
107064  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NoPreloading, [{
107065    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
107066    args: [{
107067      providedIn: 'root'
107068    }]
107069  }], null, null);
107070})();
107071/**
107072 * The preloader optimistically loads all router configurations to
107073 * make navigations into lazily-loaded sections of the application faster.
107074 *
107075 * The preloader runs in the background. When the router bootstraps, the preloader
107076 * starts listening to all navigation events. After every such event, the preloader
107077 * will check if any configurations can be loaded lazily.
107078 *
107079 * If a route is protected by `canLoad` guards, the preloaded will not load it.
107080 *
107081 * @publicApi
107082 */
107083
107084
107085class RouterPreloader {
107086  constructor(router, compiler, injector, preloadingStrategy, loader) {
107087    this.router = router;
107088    this.injector = injector;
107089    this.preloadingStrategy = preloadingStrategy;
107090    this.loader = loader;
107091  }
107092
107093  setUpPreloading() {
107094    this.subscription = this.router.events.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.filter)(e => e instanceof NavigationEnd), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.concatMap)(() => this.preload())).subscribe(() => {});
107095  }
107096
107097  preload() {
107098    return this.processRoutes(this.injector, this.router.config);
107099  }
107100  /** @nodoc */
107101
107102
107103  ngOnDestroy() {
107104    if (this.subscription) {
107105      this.subscription.unsubscribe();
107106    }
107107  }
107108
107109  processRoutes(injector, routes) {
107110    const res = [];
107111
107112    for (const route of routes) {
107113      if (route.providers && !route._injector) {
107114        route._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createEnvironmentInjector)(route.providers, injector, `Route: ${route.path}`);
107115      }
107116
107117      const injectorForCurrentRoute = route._injector ?? injector;
107118      const injectorForChildren = route._loadedInjector ?? injectorForCurrentRoute; // Note that `canLoad` is only checked as a condition that prevents `loadChildren` and not
107119      // `loadComponent`. `canLoad` guards only block loading of child routes by design. This
107120      // happens as a consequence of needing to descend into children for route matching immediately
107121      // while component loading is deferred until route activation. Because `canLoad` guards can
107122      // have side effects, we cannot execute them here so we instead skip preloading altogether
107123      // when present. Lastly, it remains to be decided whether `canLoad` should behave this way
107124      // at all. Code splitting and lazy loading is separate from client-side authorization checks
107125      // and should not be used as a security measure to prevent loading of code.
107126
107127      if (route.loadChildren && !route._loadedRoutes && route.canLoad === undefined || route.loadComponent && !route._loadedComponent) {
107128        res.push(this.preloadConfig(injectorForCurrentRoute, route));
107129      } else if (route.children || route._loadedRoutes) {
107130        res.push(this.processRoutes(injectorForChildren, route.children ?? route._loadedRoutes));
107131      }
107132    }
107133
107134    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)(res).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_34__.mergeAll)());
107135  }
107136
107137  preloadConfig(injector, route) {
107138    return this.preloadingStrategy.preload(route, () => {
107139      let loadedChildren$;
107140
107141      if (route.loadChildren && route.canLoad === undefined) {
107142        loadedChildren$ = this.loader.loadChildren(injector, route);
107143      } else {
107144        loadedChildren$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(null);
107145      }
107146
107147      const recursiveLoadChildren$ = loadedChildren$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(config => {
107148        if (config === null) {
107149          return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(void 0);
107150        }
107151
107152        route._loadedRoutes = config.routes;
107153        route._loadedInjector = config.injector; // If the loaded config was a module, use that as the module/module injector going
107154        // forward. Otherwise, continue using the current module/module injector.
107155
107156        return this.processRoutes(config.injector ?? injector, config.routes);
107157      }));
107158
107159      if (route.loadComponent && !route._loadedComponent) {
107160        const loadComponent$ = this.loader.loadComponent(route);
107161        return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.from)([recursiveLoadChildren$, loadComponent$]).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_34__.mergeAll)());
107162      } else {
107163        return recursiveLoadChildren$;
107164      }
107165    });
107166  }
107167
107168}
107169
107170RouterPreloader.ɵfac = function RouterPreloader_Factory(t) {
107171  return new (t || RouterPreloader)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](Router), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Compiler), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.EnvironmentInjector), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](PreloadingStrategy), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](RouterConfigLoader));
107172};
107173
107174RouterPreloader.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
107175  token: RouterPreloader,
107176  factory: RouterPreloader.ɵfac,
107177  providedIn: 'root'
107178});
107179
107180(function () {
107181  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RouterPreloader, [{
107182    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
107183    args: [{
107184      providedIn: 'root'
107185    }]
107186  }], function () {
107187    return [{
107188      type: Router
107189    }, {
107190      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Compiler
107191    }, {
107192      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.EnvironmentInjector
107193    }, {
107194      type: PreloadingStrategy
107195    }, {
107196      type: RouterConfigLoader
107197    }];
107198  }, null);
107199})();
107200/**
107201 * @license
107202 * Copyright Google LLC All Rights Reserved.
107203 *
107204 * Use of this source code is governed by an MIT-style license that can be
107205 * found in the LICENSE file at https://angular.io/license
107206 */
107207
107208
107209const ROUTER_SCROLLER = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('');
107210
107211class RouterScroller {
107212  constructor(router,
107213  /** @docsNotRequired */
107214  viewportScroller, options = {}) {
107215    this.router = router;
107216    this.viewportScroller = viewportScroller;
107217    this.options = options;
107218    this.lastId = 0;
107219    this.lastSource = 'imperative';
107220    this.restoredId = 0;
107221    this.store = {}; // Default both options to 'disabled'
107222
107223    options.scrollPositionRestoration = options.scrollPositionRestoration || 'disabled';
107224    options.anchorScrolling = options.anchorScrolling || 'disabled';
107225  }
107226
107227  init() {
107228    // we want to disable the automatic scrolling because having two places
107229    // responsible for scrolling results race conditions, especially given
107230    // that browser don't implement this behavior consistently
107231    if (this.options.scrollPositionRestoration !== 'disabled') {
107232      this.viewportScroller.setHistoryScrollRestoration('manual');
107233    }
107234
107235    this.routerEventsSubscription = this.createScrollEvents();
107236    this.scrollEventsSubscription = this.consumeScrollEvents();
107237  }
107238
107239  createScrollEvents() {
107240    return this.router.events.subscribe(e => {
107241      if (e instanceof NavigationStart) {
107242        // store the scroll position of the current stable navigations.
107243        this.store[this.lastId] = this.viewportScroller.getScrollPosition();
107244        this.lastSource = e.navigationTrigger;
107245        this.restoredId = e.restoredState ? e.restoredState.navigationId : 0;
107246      } else if (e instanceof NavigationEnd) {
107247        this.lastId = e.id;
107248        this.scheduleScrollEvent(e, this.router.parseUrl(e.urlAfterRedirects).fragment);
107249      }
107250    });
107251  }
107252
107253  consumeScrollEvents() {
107254    return this.router.events.subscribe(e => {
107255      if (!(e instanceof Scroll)) return; // a popstate event. The pop state event will always ignore anchor scrolling.
107256
107257      if (e.position) {
107258        if (this.options.scrollPositionRestoration === 'top') {
107259          this.viewportScroller.scrollToPosition([0, 0]);
107260        } else if (this.options.scrollPositionRestoration === 'enabled') {
107261          this.viewportScroller.scrollToPosition(e.position);
107262        } // imperative navigation "forward"
107263
107264      } else {
107265        if (e.anchor && this.options.anchorScrolling === 'enabled') {
107266          this.viewportScroller.scrollToAnchor(e.anchor);
107267        } else if (this.options.scrollPositionRestoration !== 'disabled') {
107268          this.viewportScroller.scrollToPosition([0, 0]);
107269        }
107270      }
107271    });
107272  }
107273
107274  scheduleScrollEvent(routerEvent, anchor) {
107275    this.router.triggerEvent(new Scroll(routerEvent, this.lastSource === 'popstate' ? this.store[this.restoredId] : null, anchor));
107276  }
107277  /** @nodoc */
107278
107279
107280  ngOnDestroy() {
107281    if (this.routerEventsSubscription) {
107282      this.routerEventsSubscription.unsubscribe();
107283    }
107284
107285    if (this.scrollEventsSubscription) {
107286      this.scrollEventsSubscription.unsubscribe();
107287    }
107288  }
107289
107290}
107291
107292RouterScroller.ɵfac = function RouterScroller_Factory(t) {
107293  _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinvalidFactory"]();
107294};
107295
107296RouterScroller.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
107297  token: RouterScroller,
107298  factory: RouterScroller.ɵfac
107299});
107300
107301(function () {
107302  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RouterScroller, [{
107303    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
107304  }], function () {
107305    return [{
107306      type: Router
107307    }, {
107308      type: _angular_common__WEBPACK_IMPORTED_MODULE_33__.ViewportScroller
107309    }, {
107310      type: undefined
107311    }];
107312  }, null);
107313})();
107314/**
107315 * @license
107316 * Copyright Google LLC All Rights Reserved.
107317 *
107318 * Use of this source code is governed by an MIT-style license that can be
107319 * found in the LICENSE file at https://angular.io/license
107320 */
107321
107322
107323const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || ngDevMode;
107324/**
107325 * Sets up providers necessary to enable `Router` functionality for the application.
107326 * Allows to configure a set of routes as well as extra features that should be enabled.
107327 *
107328 * @usageNotes
107329 *
107330 * Basic example of how you can add a Router to your application:
107331 * ```
107332 * const appRoutes: Routes = [];
107333 * bootstrapApplication(AppComponent, {
107334 *   providers: [provideRouter(appRoutes)]
107335 * });
107336 * ```
107337 *
107338 * You can also enable optional features in the Router by adding functions from the `RouterFeatures`
107339 * type:
107340 * ```
107341 * const appRoutes: Routes = [];
107342 * bootstrapApplication(AppComponent,
107343 *   {
107344 *     providers: [
107345 *       provideRouter(appRoutes,
107346 *         withDebugTracing(),
107347 *         withRouterConfig({paramsInheritanceStrategy: 'always'}))
107348 *     ]
107349 *   }
107350 * );
107351 * ```
107352 *
107353 * @see `RouterFeatures`
107354 *
107355 * @publicApi
107356 * @developerPreview
107357 * @param routes A set of `Route`s to use for the application routing table.
107358 * @param features Optional features to configure additional router behaviors.
107359 * @returns A set of providers to setup a Router.
107360 */
107361
107362function provideRouter(routes, ...features) {
107363  return [provideRoutes(routes), {
107364    provide: ActivatedRoute,
107365    useFactory: rootRoute,
107366    deps: [Router]
107367  }, {
107368    provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.APP_BOOTSTRAP_LISTENER,
107369    multi: true,
107370    useFactory: getBootstrapListener
107371  }, features.map(feature => feature.ɵproviders) // TODO: All options used by the `assignExtraOptionsToRouter` factory need to be reviewed for
107372  // how we want them to be configured. This API doesn't currently have a way to configure them
107373  // and we should decide what the _best_ way to do that is rather than just sticking with the
107374  // status quo of how it's done today.
107375  ];
107376}
107377
107378function rootRoute(router) {
107379  return router.routerState.root;
107380}
107381/**
107382 * Helper function to create an object that represents a Router feature.
107383 */
107384
107385
107386function routerFeature(kind, providers) {
107387  return {
107388    ɵkind: kind,
107389    ɵproviders: providers
107390  };
107391}
107392/**
107393 * Registers a [DI provider](guide/glossary#provider) for a set of routes.
107394 * @param routes The route configuration to provide.
107395 *
107396 * @usageNotes
107397 *
107398 * ```
107399 * @NgModule({
107400 *   providers: [provideRoutes(ROUTES)]
107401 * })
107402 * class LazyLoadedChildModule {}
107403 * ```
107404 *
107405 * @publicApi
107406 */
107407
107408
107409function provideRoutes(routes) {
107410  return [{
107411    provide: ROUTES,
107412    multi: true,
107413    useValue: routes
107414  }];
107415}
107416/**
107417 * Enables customizable scrolling behavior for router navigations.
107418 *
107419 * @usageNotes
107420 *
107421 * Basic example of how you can enable scrolling feature:
107422 * ```
107423 * const appRoutes: Routes = [];
107424 * bootstrapApplication(AppComponent,
107425 *   {
107426 *     providers: [
107427 *       provideRouter(appRoutes, withInMemoryScrolling())
107428 *     ]
107429 *   }
107430 * );
107431 * ```
107432 *
107433 * @see `provideRouter`
107434 * @see `ViewportScroller`
107435 *
107436 * @publicApi
107437 * @developerPreview
107438 * @param options Set of configuration parameters to customize scrolling behavior, see
107439 *     `InMemoryScrollingOptions` for additional information.
107440 * @returns A set of providers for use with `provideRouter`.
107441 */
107442
107443
107444function withInMemoryScrolling(options = {}) {
107445  const providers = [{
107446    provide: ROUTER_SCROLLER,
107447    useFactory: () => {
107448      const router = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(Router);
107449      const viewportScroller = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_33__.ViewportScroller);
107450      return new RouterScroller(router, viewportScroller, options);
107451    }
107452  }];
107453  return routerFeature(4
107454  /* RouterFeatureKind.InMemoryScrollingFeature */
107455  , providers);
107456}
107457
107458function getBootstrapListener() {
107459  const injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
107460  return bootstrappedComponentRef => {
107461    const ref = injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ApplicationRef);
107462
107463    if (bootstrappedComponentRef !== ref.components[0]) {
107464      return;
107465    }
107466
107467    const router = injector.get(Router);
107468    const bootstrapDone = injector.get(BOOTSTRAP_DONE);
107469
107470    if (injector.get(INITIAL_NAVIGATION) === 1
107471    /* InitialNavigation.EnabledNonBlocking */
107472    ) {
107473      router.initialNavigation();
107474    }
107475
107476    injector.get(ROUTER_PRELOADER, null, _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectFlags.Optional)?.setUpPreloading();
107477    injector.get(ROUTER_SCROLLER, null, _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectFlags.Optional)?.init();
107478    router.resetRootComponentType(ref.componentTypes[0]);
107479    bootstrapDone.next();
107480    bootstrapDone.complete();
107481  };
107482}
107483/**
107484 * A subject used to indicate that the bootstrapping phase is done. When initial navigation is
107485 * `enabledBlocking`, the first navigation waits until bootstrapping is finished before continuing
107486 * to the activation phase.
107487 */
107488
107489
107490const BOOTSTRAP_DONE = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(NG_DEV_MODE$1 ? 'bootstrap done indicator' : '', {
107491  factory: () => {
107492    return new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject();
107493  }
107494});
107495const INITIAL_NAVIGATION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(NG_DEV_MODE$1 ? 'initial navigation' : '', {
107496  providedIn: 'root',
107497  factory: () => 1
107498  /* InitialNavigation.EnabledNonBlocking */
107499
107500});
107501/**
107502 * Configures initial navigation to start before the root component is created.
107503 *
107504 * The bootstrap is blocked until the initial navigation is complete. This value is required for
107505 * [server-side rendering](guide/universal) to work.
107506 *
107507 * @usageNotes
107508 *
107509 * Basic example of how you can enable this navigation behavior:
107510 * ```
107511 * const appRoutes: Routes = [];
107512 * bootstrapApplication(AppComponent,
107513 *   {
107514 *     providers: [
107515 *       provideRouter(appRoutes, withEnabledBlockingInitialNavigation())
107516 *     ]
107517 *   }
107518 * );
107519 * ```
107520 *
107521 * @see `provideRouter`
107522 *
107523 * @publicApi
107524 * @developerPreview
107525 * @returns A set of providers for use with `provideRouter`.
107526 */
107527
107528function withEnabledBlockingInitialNavigation() {
107529  const providers = [{
107530    provide: INITIAL_NAVIGATION,
107531    useValue: 0
107532    /* InitialNavigation.EnabledBlocking */
107533
107534  }, {
107535    provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.APP_INITIALIZER,
107536    multi: true,
107537    deps: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector],
107538    useFactory: injector => {
107539      const locationInitialized = injector.get(_angular_common__WEBPACK_IMPORTED_MODULE_33__.LOCATION_INITIALIZED, Promise.resolve());
107540      let initNavigation = false;
107541      /**
107542       * Performs the given action once the router finishes its next/current navigation.
107543       *
107544       * If the navigation is canceled or errors without a redirect, the navigation is considered
107545       * complete. If the `NavigationEnd` event emits, the navigation is also considered complete.
107546       */
107547
107548      function afterNextNavigation(action) {
107549        const router = injector.get(Router);
107550        router.events.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.filter)(e => e instanceof NavigationEnd || e instanceof NavigationCancel || e instanceof NavigationError), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(e => {
107551          if (e instanceof NavigationEnd) {
107552            // Navigation assumed to succeed if we get `ActivationStart`
107553            return true;
107554          }
107555
107556          const redirecting = e instanceof NavigationCancel ? e.code === 0
107557          /* NavigationCancellationCode.Redirect */
107558          || e.code === 1
107559          /* NavigationCancellationCode.SupersededByNewNavigation */
107560          : false;
107561          return redirecting ? null : false;
107562        }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.filter)(result => result !== null), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.take)(1)).subscribe(() => {
107563          action();
107564        });
107565      }
107566
107567      return () => {
107568        return locationInitialized.then(() => {
107569          return new Promise(resolve => {
107570            const router = injector.get(Router);
107571            const bootstrapDone = injector.get(BOOTSTRAP_DONE);
107572            afterNextNavigation(() => {
107573              // Unblock APP_INITIALIZER in case the initial navigation was canceled or errored
107574              // without a redirect.
107575              resolve(true);
107576              initNavigation = true;
107577            });
107578
107579            router.afterPreactivation = () => {
107580              // Unblock APP_INITIALIZER once we get to `afterPreactivation`. At this point, we
107581              // assume activation will complete successfully (even though this is not
107582              // guaranteed).
107583              resolve(true); // only the initial navigation should be delayed until bootstrapping is done.
107584
107585              if (!initNavigation) {
107586                return bootstrapDone.closed ? (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(void 0) : bootstrapDone; // subsequent navigations should not be delayed
107587              } else {
107588                return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(void 0);
107589              }
107590            };
107591
107592            router.initialNavigation();
107593          });
107594        });
107595      };
107596    }
107597  }];
107598  return routerFeature(2
107599  /* RouterFeatureKind.EnabledBlockingInitialNavigationFeature */
107600  , providers);
107601}
107602/**
107603 * Disables initial navigation.
107604 *
107605 * Use if there is a reason to have more control over when the router starts its initial navigation
107606 * due to some complex initialization logic.
107607 *
107608 * @usageNotes
107609 *
107610 * Basic example of how you can disable initial navigation:
107611 * ```
107612 * const appRoutes: Routes = [];
107613 * bootstrapApplication(AppComponent,
107614 *   {
107615 *     providers: [
107616 *       provideRouter(appRoutes, withDisabledInitialNavigation())
107617 *     ]
107618 *   }
107619 * );
107620 * ```
107621 *
107622 * @see `provideRouter`
107623 *
107624 * @returns A set of providers for use with `provideRouter`.
107625 *
107626 * @publicApi
107627 * @developerPreview
107628 */
107629
107630
107631function withDisabledInitialNavigation() {
107632  const providers = [{
107633    provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.APP_INITIALIZER,
107634    multi: true,
107635    useFactory: () => {
107636      const router = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(Router);
107637      return () => {
107638        router.setUpLocationChangeListener();
107639      };
107640    }
107641  }, {
107642    provide: INITIAL_NAVIGATION,
107643    useValue: 2
107644    /* InitialNavigation.Disabled */
107645
107646  }];
107647  return routerFeature(3
107648  /* RouterFeatureKind.DisabledInitialNavigationFeature */
107649  , providers);
107650}
107651/**
107652 * Enables logging of all internal navigation events to the console.
107653 * Extra logging might be useful for debugging purposes to inspect Router event sequence.
107654 *
107655 * @usageNotes
107656 *
107657 * Basic example of how you can enable debug tracing:
107658 * ```
107659 * const appRoutes: Routes = [];
107660 * bootstrapApplication(AppComponent,
107661 *   {
107662 *     providers: [
107663 *       provideRouter(appRoutes, withDebugTracing())
107664 *     ]
107665 *   }
107666 * );
107667 * ```
107668 *
107669 * @see `provideRouter`
107670 *
107671 * @returns A set of providers for use with `provideRouter`.
107672 *
107673 * @publicApi
107674 * @developerPreview
107675 */
107676
107677
107678function withDebugTracing() {
107679  let providers = [];
107680
107681  if (NG_DEV_MODE$1) {
107682    providers = [{
107683      provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ENVIRONMENT_INITIALIZER,
107684      multi: true,
107685      useFactory: () => {
107686        const router = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(Router);
107687        return () => router.events.subscribe(e => {
107688          // tslint:disable:no-console
107689          console.group?.(`Router Event: ${e.constructor.name}`);
107690          console.log(stringifyEvent(e));
107691          console.log(e);
107692          console.groupEnd?.(); // tslint:enable:no-console
107693        });
107694      }
107695    }];
107696  } else {
107697    providers = [];
107698  }
107699
107700  return routerFeature(1
107701  /* RouterFeatureKind.DebugTracingFeature */
107702  , providers);
107703}
107704
107705const ROUTER_PRELOADER = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(NG_DEV_MODE$1 ? 'router preloader' : '');
107706/**
107707 * Allows to configure a preloading strategy to use. The strategy is configured by providing a
107708 * reference to a class that implements a `PreloadingStrategy`.
107709 *
107710 * @usageNotes
107711 *
107712 * Basic example of how you can configure preloading:
107713 * ```
107714 * const appRoutes: Routes = [];
107715 * bootstrapApplication(AppComponent,
107716 *   {
107717 *     providers: [
107718 *       provideRouter(appRoutes, withPreloading(PreloadAllModules))
107719 *     ]
107720 *   }
107721 * );
107722 * ```
107723 *
107724 * @see `provideRouter`
107725 *
107726 * @param preloadingStrategy A reference to a class that implements a `PreloadingStrategy` that
107727 *     should be used.
107728 * @returns A set of providers for use with `provideRouter`.
107729 *
107730 * @publicApi
107731 * @developerPreview
107732 */
107733
107734function withPreloading(preloadingStrategy) {
107735  const providers = [{
107736    provide: ROUTER_PRELOADER,
107737    useExisting: RouterPreloader
107738  }, {
107739    provide: PreloadingStrategy,
107740    useExisting: preloadingStrategy
107741  }];
107742  return routerFeature(0
107743  /* RouterFeatureKind.PreloadingFeature */
107744  , providers);
107745}
107746/**
107747 * Allows to provide extra parameters to configure Router.
107748 *
107749 * @usageNotes
107750 *
107751 * Basic example of how you can provide extra configuration options:
107752 * ```
107753 * const appRoutes: Routes = [];
107754 * bootstrapApplication(AppComponent,
107755 *   {
107756 *     providers: [
107757 *       provideRouter(appRoutes, withRouterConfig({
107758 *          onSameUrlNavigation: 'reload'
107759 *       }))
107760 *     ]
107761 *   }
107762 * );
107763 * ```
107764 *
107765 * @see `provideRouter`
107766 *
107767 * @param options A set of parameters to configure Router, see `RouterConfigOptions` for
107768 *     additional information.
107769 * @returns A set of providers for use with `provideRouter`.
107770 *
107771 * @publicApi
107772 * @developerPreview
107773 */
107774
107775
107776function withRouterConfig(options) {
107777  const providers = [{
107778    provide: ROUTER_CONFIGURATION,
107779    useValue: options
107780  }];
107781  return routerFeature(5
107782  /* RouterFeatureKind.RouterConfigurationFeature */
107783  , providers);
107784}
107785/**
107786 * @license
107787 * Copyright Google LLC All Rights Reserved.
107788 *
107789 * Use of this source code is governed by an MIT-style license that can be
107790 * found in the LICENSE file at https://angular.io/license
107791 */
107792
107793
107794const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;
107795/**
107796 * The directives defined in the `RouterModule`.
107797 */
107798
107799const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent];
107800/**
107801 * @docsNotRequired
107802 */
107803
107804const ROUTER_FORROOT_GUARD = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(NG_DEV_MODE ? 'router duplicate forRoot guard' : 'ROUTER_FORROOT_GUARD'); // TODO(atscott): All of these except `ActivatedRoute` are `providedIn: 'root'`. They are only kept
107805// here to avoid a breaking change whereby the provider order matters based on where the
107806// `RouterModule`/`RouterTestingModule` is imported. These can/should be removed as a "breaking"
107807// change in a major version.
107808
107809const ROUTER_PROVIDERS = [_angular_common__WEBPACK_IMPORTED_MODULE_33__.Location, {
107810  provide: UrlSerializer,
107811  useClass: DefaultUrlSerializer
107812}, {
107813  provide: Router,
107814  useFactory: setupRouter
107815}, ChildrenOutletContexts, {
107816  provide: ActivatedRoute,
107817  useFactory: rootRoute,
107818  deps: [Router]
107819}, RouterConfigLoader];
107820
107821function routerNgProbeToken() {
107822  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgProbeToken('Router', Router);
107823}
107824/**
107825 * @description
107826 *
107827 * Adds directives and providers for in-app navigation among views defined in an application.
107828 * Use the Angular `Router` service to declaratively specify application states and manage state
107829 * transitions.
107830 *
107831 * You can import this NgModule multiple times, once for each lazy-loaded bundle.
107832 * However, only one `Router` service can be active.
107833 * To ensure this, there are two ways to register routes when importing this module:
107834 *
107835 * * The `forRoot()` method creates an `NgModule` that contains all the directives, the given
107836 * routes, and the `Router` service itself.
107837 * * The `forChild()` method creates an `NgModule` that contains all the directives and the given
107838 * routes, but does not include the `Router` service.
107839 *
107840 * @see [Routing and Navigation guide](guide/router) for an
107841 * overview of how the `Router` service should be used.
107842 *
107843 * @publicApi
107844 */
107845
107846
107847class RouterModule {
107848  constructor(guard) {}
107849  /**
107850   * Creates and configures a module with all the router providers and directives.
107851   * Optionally sets up an application listener to perform an initial navigation.
107852   *
107853   * When registering the NgModule at the root, import as follows:
107854   *
107855   * ```
107856   * @NgModule({
107857   *   imports: [RouterModule.forRoot(ROUTES)]
107858   * })
107859   * class MyNgModule {}
107860   * ```
107861   *
107862   * @param routes An array of `Route` objects that define the navigation paths for the application.
107863   * @param config An `ExtraOptions` configuration object that controls how navigation is performed.
107864   * @return The new `NgModule`.
107865   *
107866   */
107867
107868
107869  static forRoot(routes, config) {
107870    return {
107871      ngModule: RouterModule,
107872      providers: [ROUTER_PROVIDERS, NG_DEV_MODE ? config?.enableTracing ? withDebugTracing().ɵproviders : [] : [], provideRoutes(routes), {
107873        provide: ROUTER_FORROOT_GUARD,
107874        useFactory: provideForRootGuard,
107875        deps: [[Router, new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional(), new _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf()]]
107876      }, {
107877        provide: ROUTER_CONFIGURATION,
107878        useValue: config ? config : {}
107879      }, config?.useHash ? provideHashLocationStrategy() : providePathLocationStrategy(), provideRouterScroller(), config?.preloadingStrategy ? withPreloading(config.preloadingStrategy).ɵproviders : [], {
107880        provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgProbeToken,
107881        multi: true,
107882        useFactory: routerNgProbeToken
107883      }, config?.initialNavigation ? provideInitialNavigation(config) : [], provideRouterInitializer()]
107884    };
107885  }
107886  /**
107887   * Creates a module with all the router directives and a provider registering routes,
107888   * without creating a new Router service.
107889   * When registering for submodules and lazy-loaded submodules, create the NgModule as follows:
107890   *
107891   * ```
107892   * @NgModule({
107893   *   imports: [RouterModule.forChild(ROUTES)]
107894   * })
107895   * class MyNgModule {}
107896   * ```
107897   *
107898   * @param routes An array of `Route` objects that define the navigation paths for the submodule.
107899   * @return The new NgModule.
107900   *
107901   */
107902
107903
107904  static forChild(routes) {
107905    return {
107906      ngModule: RouterModule,
107907      providers: [provideRoutes(routes)]
107908    };
107909  }
107910
107911}
107912
107913RouterModule.ɵfac = function RouterModule_Factory(t) {
107914  return new (t || RouterModule)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](ROUTER_FORROOT_GUARD, 8));
107915};
107916
107917RouterModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
107918  type: RouterModule,
107919  imports: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent],
107920  exports: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent]
107921});
107922RouterModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
107923  imports: [ɵEmptyOutletComponent]
107924});
107925
107926(function () {
107927  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RouterModule, [{
107928    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
107929    args: [{
107930      imports: ROUTER_DIRECTIVES,
107931      exports: ROUTER_DIRECTIVES
107932    }]
107933  }], function () {
107934    return [{
107935      type: undefined,
107936      decorators: [{
107937        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
107938      }, {
107939        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
107940        args: [ROUTER_FORROOT_GUARD]
107941      }]
107942    }];
107943  }, null);
107944})();
107945/**
107946 * For internal use by `RouterModule` only. Note that this differs from `withInMemoryRouterScroller`
107947 * because it reads from the `ExtraOptions` which should not be used in the standalone world.
107948 */
107949
107950
107951function provideRouterScroller() {
107952  return {
107953    provide: ROUTER_SCROLLER,
107954    useFactory: () => {
107955      const router = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(Router);
107956      const viewportScroller = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_33__.ViewportScroller);
107957      const config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(ROUTER_CONFIGURATION);
107958
107959      if (config.scrollOffset) {
107960        viewportScroller.setOffset(config.scrollOffset);
107961      }
107962
107963      return new RouterScroller(router, viewportScroller, config);
107964    }
107965  };
107966} // Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` should
107967// provide hash location directly via `{provide: LocationStrategy, useClass: HashLocationStrategy}`.
107968
107969
107970function provideHashLocationStrategy() {
107971  return {
107972    provide: _angular_common__WEBPACK_IMPORTED_MODULE_33__.LocationStrategy,
107973    useClass: _angular_common__WEBPACK_IMPORTED_MODULE_33__.HashLocationStrategy
107974  };
107975} // Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` does not
107976// need this at all because `PathLocationStrategy` is the default factory for `LocationStrategy`.
107977
107978
107979function providePathLocationStrategy() {
107980  return {
107981    provide: _angular_common__WEBPACK_IMPORTED_MODULE_33__.LocationStrategy,
107982    useClass: _angular_common__WEBPACK_IMPORTED_MODULE_33__.PathLocationStrategy
107983  };
107984}
107985
107986function provideForRootGuard(router) {
107987  if (NG_DEV_MODE && router) {
107988    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](4007
107989    /* RuntimeErrorCode.FOR_ROOT_CALLED_TWICE */
107990    , `The Router was provided more than once. This can happen if 'forRoot' is used outside of the root injector.` + ` Lazy loaded modules should use RouterModule.forChild() instead.`);
107991  }
107992
107993  return 'guarded';
107994} // Note: For internal use only with `RouterModule`. Standalone router setup with `provideRouter`
107995// users call `withXInitialNavigation` directly.
107996
107997
107998function provideInitialNavigation(config) {
107999  return [config.initialNavigation === 'disabled' ? withDisabledInitialNavigation().ɵproviders : [], config.initialNavigation === 'enabledBlocking' ? withEnabledBlockingInitialNavigation().ɵproviders : []];
108000} // TODO(atscott): This should not be in the public API
108001
108002/**
108003 * A [DI token](guide/glossary/#di-token) for the router initializer that
108004 * is called after the app is bootstrapped.
108005 *
108006 * @publicApi
108007 */
108008
108009
108010const ROUTER_INITIALIZER = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(NG_DEV_MODE ? 'Router Initializer' : '');
108011
108012function provideRouterInitializer() {
108013  return [// ROUTER_INITIALIZER token should be removed. It's public API but shouldn't be. We can just
108014  // have `getBootstrapListener` directly attached to APP_BOOTSTRAP_LISTENER.
108015  {
108016    provide: ROUTER_INITIALIZER,
108017    useFactory: getBootstrapListener
108018  }, {
108019    provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.APP_BOOTSTRAP_LISTENER,
108020    multi: true,
108021    useExisting: ROUTER_INITIALIZER
108022  }];
108023}
108024/**
108025 * @license
108026 * Copyright Google LLC All Rights Reserved.
108027 *
108028 * Use of this source code is governed by an MIT-style license that can be
108029 * found in the LICENSE file at https://angular.io/license
108030 */
108031
108032/**
108033 * @publicApi
108034 */
108035
108036
108037const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Version('14.2.10');
108038/**
108039 * @license
108040 * Copyright Google LLC All Rights Reserved.
108041 *
108042 * Use of this source code is governed by an MIT-style license that can be
108043 * found in the LICENSE file at https://angular.io/license
108044 */
108045
108046/**
108047 * @license
108048 * Copyright Google LLC All Rights Reserved.
108049 *
108050 * Use of this source code is governed by an MIT-style license that can be
108051 * found in the LICENSE file at https://angular.io/license
108052 */
108053
108054/**
108055 * @license
108056 * Copyright Google LLC All Rights Reserved.
108057 *
108058 * Use of this source code is governed by an MIT-style license that can be
108059 * found in the LICENSE file at https://angular.io/license
108060 */
108061// This file only reexports content of the `src` folder. Keep it that way.
108062
108063/**
108064 * @license
108065 * Copyright Google LLC All Rights Reserved.
108066 *
108067 * Use of this source code is governed by an MIT-style license that can be
108068 * found in the LICENSE file at https://angular.io/license
108069 */
108070
108071/**
108072 * Generated bundle index. Do not edit.
108073 */
108074
108075
108076
108077/***/ }),
108078
108079/***/ 2183:
108080/*!*********************************************************************!*\
108081  !*** ./node_modules/angular-svg-icon/fesm2020/angular-svg-icon.mjs ***!
108082  \*********************************************************************/
108083/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
108084
108085__webpack_require__.r(__webpack_exports__);
108086/* harmony export */ __webpack_require__.d(__webpack_exports__, {
108087/* harmony export */   "AngularSvgIconModule": () => (/* binding */ AngularSvgIconModule),
108088/* harmony export */   "SERVER_URL": () => (/* binding */ SERVER_URL),
108089/* harmony export */   "SVG_ICON_REGISTRY_PROVIDER": () => (/* binding */ SVG_ICON_REGISTRY_PROVIDER),
108090/* harmony export */   "SVG_ICON_REGISTRY_PROVIDER_FACTORY": () => (/* binding */ SVG_ICON_REGISTRY_PROVIDER_FACTORY),
108091/* harmony export */   "SvgHttpLoader": () => (/* binding */ SvgHttpLoader),
108092/* harmony export */   "SvgIconComponent": () => (/* binding */ SvgIconComponent),
108093/* harmony export */   "SvgIconRegistryService": () => (/* binding */ SvgIconRegistryService),
108094/* harmony export */   "SvgLoader": () => (/* binding */ SvgLoader)
108095/* harmony export */ });
108096/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 2560);
108097/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @angular/common */ 4666);
108098/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 4139);
108099/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs */ 6587);
108100/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs/operators */ 6942);
108101/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 8759);
108102/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs/operators */ 7418);
108103/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs/operators */ 4661);
108104/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs/operators */ 4514);
108105/* harmony import */ var _angular_common_http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/common/http */ 8987);
108106
108107
108108
108109
108110
108111
108112const _c0 = ["*"];
108113
108114class SvgLoader {}
108115
108116class SvgHttpLoader extends SvgLoader {
108117  constructor(http) {
108118    super();
108119    this.http = http;
108120  }
108121
108122  getSvg(url) {
108123    return this.http.get(url, {
108124      responseType: 'text'
108125    });
108126  }
108127
108128}
108129
108130SvgHttpLoader.ɵfac = function SvgHttpLoader_Factory(t) {
108131  return new (t || SvgHttpLoader)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common_http__WEBPACK_IMPORTED_MODULE_1__.HttpClient));
108132};
108133
108134SvgHttpLoader.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
108135  token: SvgHttpLoader,
108136  factory: SvgHttpLoader.ɵfac
108137});
108138
108139(function () {
108140  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SvgHt
108140tpLoader, [{
108141    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
108142  }], function () {
108143    return [{
108144      type: _angular_common_http__WEBPACK_IMPORTED_MODULE_1__.HttpClient
108145    }];
108146  }, null);
108147})();
108148
108149const SERVER_URL = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('SERVER_URL');
108150
108151class SvgIconRegistryService {
108152  constructor(loader, platformId, serverUrl, _document) {
108153    this.loader = loader;
108154    this.platformId = platformId;
108155    this.serverUrl = serverUrl;
108156    this._document = _document;
108157    this.iconsByUrl = new Map();
108158    this.iconsLoadingByUrl = new Map();
108159    this.document = this._document;
108160  }
108161  /** Add a SVG to the registry by passing a name and the SVG. */
108162
108163
108164  addSvg(name, data) {
108165    if (!this.iconsByUrl.has(name)) {
108166      const div = this.document.createElement('DIV');
108167      div.innerHTML = data;
108168      const svg = div.querySelector('svg');
108169      this.iconsByUrl.set(name, svg);
108170    }
108171  }
108172  /** Load a SVG to the registry from a URL. */
108173
108174
108175  loadSvg(url, name = url) {
108176    // not sure if there should be a possibility to use name for server usage
108177    // so overriding it for now if provided
108178    // maybe should separate functionality for url and name use-cases
108179    if (this.serverUrl && url.match(/^(http(s)?):/) === null) {
108180      url = this.serverUrl + url;
108181      name = url;
108182    }
108183
108184    if (this.iconsByUrl.has(name)) {
108185      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(this.iconsByUrl.get(name));
108186    } else if (this.iconsLoadingByUrl.has(name)) {
108187      return this.iconsLoadingByUrl.get(name);
108188    }
108189
108190    const o = this.loader.getSvg(url).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(svg => {
108191      const div = this.document.createElement('DIV');
108192      div.innerHTML = svg;
108193      return div.querySelector('svg');
108194    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.tap)(svg => this.iconsByUrl.set(name, svg)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.catchError)(err => {
108195      console.error(err);
108196      return (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.throwError)(err);
108197    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.finalize)(() => this.iconsLoadingByUrl.delete(name)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.share)());
108198    this.iconsLoadingByUrl.set(name, o);
108199    return o;
108200  }
108201  /** Get loaded SVG from registry by name. (also works by url because of blended map) */
108202
108203
108204  getSvgByName(name) {
108205    if (this.iconsByUrl.has(name)) {
108206      return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(this.iconsByUrl.get(name));
108207    } else if (this.iconsLoadingByUrl.has(name)) {
108208      return this.iconsLoadingByUrl.get(name);
108209    }
108210
108211    return (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.throwError)(`No svg with name '${name}' has been loaded`);
108212  }
108213  /** Remove a SVG from the registry by URL (or name). */
108214
108215
108216  unloadSvg(url) {
108217    if (this.iconsByUrl.has(url)) {
108218      this.iconsByUrl.delete(url);
108219    }
108220  }
108221
108222}
108223
108224SvgIconRegistryService.ɵfac = function SvgIconRegistryService_Factory(t) {
108225  return new (t || SvgIconRegistryService)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](SvgLoader), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](SERVER_URL, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_9__.DOCUMENT, 8));
108226};
108227
108228SvgIconRegistryService.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
108229  token: SvgIconRegistryService,
108230  factory: SvgIconRegistryService.ɵfac
108231});
108232
108233(function () {
108234  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SvgIconRegistryService, [{
108235    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
108236  }], function () {
108237    return [{
108238      type: SvgLoader
108239    }, {
108240      type: Object,
108241      decorators: [{
108242        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
108243        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID]
108244      }]
108245    }, {
108246      type: undefined,
108247      decorators: [{
108248        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
108249      }, {
108250        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
108251        args: [SERVER_URL]
108252      }]
108253    }, {
108254      type: undefined,
108255      decorators: [{
108256        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
108257      }, {
108258        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
108259        args: [_angular_common__WEBPACK_IMPORTED_MODULE_9__.DOCUMENT]
108260      }]
108261    }];
108262  }, null);
108263})();
108264
108265function SVG_ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry, loader, platformId, serverUrl, document) {
108266  return parentRegistry || new SvgIconRegistryService(loader, platformId, serverUrl, document);
108267}
108268
108269const SVG_ICON_REGISTRY_PROVIDER = {
108270  provide: SvgIconRegistryService,
108271  deps: [[new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional(), new _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf(), SvgIconRegistryService], SvgLoader, [_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID], [new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional(), SERVER_URL], [new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional(), _angular_common__WEBPACK_IMPORTED_MODULE_9__.DOCUMENT]],
108272  useFactory: SVG_ICON_REGISTRY_PROVIDER_FACTORY
108273};
108274
108275class SvgIconHelper {
108276  constructor() {
108277    this.loaded = false;
108278  }
108279
108280}
108281
108282class SvgIconComponent {
108283  constructor(element, differs, renderer, iconReg, cdr) {
108284    this.element = element;
108285    this.differs = differs;
108286    this.renderer = renderer;
108287    this.iconReg = iconReg;
108288    this.cdr = cdr;
108289    this.stretch = false;
108290    this.applyClass = false;
108291    /** @deprecated since 9.1.0 */
108292
108293    this.applyCss = false;
108294    this.helper = new SvgIconHelper();
108295    this._svgStyle = null;
108296  } // Adapted from ngStyle (see:  angular/packages/common/src/directives/ng_style.ts)
108297
108298
108299  set svgStyle(values) {
108300    this._svgStyle = values;
108301
108302    if (!this.helper.differ && values) {
108303      this.helper.differ = this.differs.find(values).create();
108304    }
108305  }
108306
108307  ngOnInit() {
108308    this.init();
108309  }
108310
108311  ngOnDestroy() {
108312    this.destroy();
108313  }
108314
108315  ngOnChanges(changeRecord) {
108316    const elemSvg = this.element.nativeElement.firstChild;
108317
108318    if (changeRecord.src || changeRecord.name) {
108319      if (this.helper.loaded) {
108320        this.destroy();
108321      }
108322
108323      this.init();
108324    }
108325
108326    if (changeRecord.stretch) {
108327      this.stylize();
108328    }
108329
108330    if (changeRecord.applyClass) {
108331      if (this.applyClass) {
108332        this.setClass(elemSvg, null, this.klass);
108333      } else {
108334        this.setClass(elemSvg, this.klass, null);
108335      }
108336    }
108337
108338    if (changeRecord.svgClass) {
108339      this.setClass(elemSvg, changeRecord.svgClass.previousValue, changeRecord.svgClass.currentValue);
108340    }
108341
108342    if (changeRecord.klass) {
108343      const elem = this.element.nativeElement;
108344      this.setClass(elem, changeRecord.klass.previousValue, changeRecord.klass.currentValue);
108345
108346      if (this.applyClass) {
108347        this.setClass(elemSvg, changeRecord.klass.previousValue, changeRecord.klass.currentValue);
108348      } else {
108349        this.setClass(elemSvg, changeRecord.klass.previousValue, null);
108350      }
108351    }
108352
108353    if (changeRecord.viewBox) {
108354      if (this.helper.loaded) {
108355        this.destroy();
108356      }
108357
108358      this.init();
108359    }
108360
108361    if (changeRecord.applyCss) {
108362      console.warn('applyCss deprecated since 9.1.0, will be removed in 10.0.0');
108363      console.warn('use applyClass instead');
108364    }
108365
108366    if (changeRecord.svgAriaLabel) {
108367      this.doAria(changeRecord.svgAriaLabel.currentValue);
108368    }
108369  }
108370
108371  ngDoCheck() {
108372    if (this.helper.svg && this.helper.differ) {
108373      const changes = this.helper.differ.diff(this._svgStyle);
108374
108375      if (changes) {
108376        this.applyChanges(changes);
108377      }
108378    }
108379  }
108380
108381  init() {
108382    if (this.name) {
108383      const svgObs = this.iconReg.getSvgByName(this.name);
108384
108385      if (svgObs) {
108386        this.helper.icnSub = svgObs.subscribe(svg => this.initSvg(svg));
108387      }
108388    } else if (this.src) {
108389      const svgObs = this.iconReg.loadSvg(this.src);
108390
108391      if (svgObs) {
108392        this.helper.icnSub = svgObs.subscribe(svg => this.initSvg(svg));
108393      }
108394    } else {
108395      const elem = this.element.nativeElement;
108396      elem.innerHTML = '';
108397      this.cdr.markForCheck();
108398    }
108399  }
108400
108401  initSvg(svg) {
108402    if (!this.helper.loaded && svg) {
108403      this.setSvg(svg);
108404      this.resetDiffer();
108405    }
108406  }
108407
108408  destroy() {
108409    if (this.helper.icnSub) {
108410      this.helper.icnSub.unsubscribe();
108411    }
108412
108413    this.helper = new SvgIconHelper();
108414  }
108415
108416  resetDiffer() {
108417    if (this._svgStyle && !this.helper.differ) {
108418      this.helper.differ = this.differs.find(this._svgStyle).create();
108419    }
108420  }
108421
108422  setSvg(svg) {
108423    if (!this.helper.loaded && svg) {
108424      this.helper.svg = svg;
108425      const icon = svg.cloneNode(true);
108426      const elem = this.element.nativeElement;
108427      elem.innerHTML = '';
108428      this.renderer.appendChild(elem, icon);
108429      this.helper.loaded = true;
108430      this.copyNgContentAttribute(elem, icon);
108431
108432      if (this.klass && this.applyClass) {
108433        this.setClass(elem.firstChild, null, this.klass);
108434      }
108435
108436      if (this.svgClass) {
108437        this.setClass(elem.firstChild, null, this.svgClass);
108438      }
108439
108440      if (this.viewBox) {
108441        if (this.viewBox === 'auto') {
108442          // Attempt to convert height & width to a viewBox.
108443          const w = icon.getAttribute('width');
108444          const h = icon.getAttribute('height');
108445
108446          if (h && w) {
108447            const vb = `0 0 ${w} ${h}`;
108448            this.renderer.setAttribute(icon, 'viewBox', vb);
108449            this.renderer.removeAttribute(icon, 'width');
108450            this.renderer.removeAttribute(icon, 'height');
108451          }
108452        } else if (this.viewBox !== '') {
108453          this.renderer.setAttribute(icon, 'viewBox', this.viewBox);
108454          this.renderer.removeAttribute(icon, 'width');
108455          this.renderer.removeAttribute(icon, 'height');
108456        }
108457      }
108458
108459      this.stylize(); // If there is not a svgAriaLabel and the SVG has an arial-label, then do not override
108460      // the SVG's aria-label.
108461
108462      if (!(this.svgAriaLabel === undefined && elem.firstChild.hasAttribute('aria-label'))) {
108463        this.doAria(this.svgAriaLabel || '');
108464      }
108465
108466      this.cdr.markForCheck();
108467    }
108468  }
108469
108470  copyNgContentAttribute(hostElem, icon) {
108471    const attributes = hostElem.attributes;
108472    const len = attributes.length;
108473
108474    for (let i = 0; i < len; i += 1) {
108475      const attribute = attributes.item(i);
108476
108477      if (attribute && attribute.name.startsWith('_ngcontent')) {
108478        this.setNgContentAttribute(icon, attribute.name);
108479        break;
108480      }
108481    }
108482  }
108483
108484  setNgContentAttribute(parent, attributeName) {
108485    this.renderer.setAttribute(parent, attributeName, '');
108486    const len = parent.childNodes.length;
108487
108488    for (let i = 0; i < len; i += 1) {
108489      const child = parent.childNodes[i];
108490
108491      if (child instanceof Element) {
108492        this.setNgContentAttribute(child, attributeName);
108493      }
108494    }
108495  }
108496
108497  stylize() {
108498    if (this.helper.svg) {
108499      const svg = this.element.nativeElement.firstChild;
108500
108501      if (this.stretch === true) {
108502        this.renderer.setAttribute(svg, 'preserveAspectRatio', 'none');
108503      } else if (this.stretch === false) {
108504        this.renderer.removeAttribute(svg, 'preserveAspectRatio');
108505      }
108506    }
108507  }
108508
108509  applyChanges(changes) {
108510    changes.forEachRemovedItem(record => this.setStyle(record.key, null));
108511    changes.forEachAddedItem(record => this.setStyle(record.key, record.currentValue));
108512    changes.forEachChangedItem(record => this.setStyle(record.key, record.currentValue));
108513  }
108514
108515  setStyle(nameAndUnit, value) {
108516    const [name, unit] = nameAndUnit.split('.');
108517    value = value !== null && unit ? `${value}${unit}` : value;
108518    const svg = this.element.nativeElement.firstChild;
108519
108520    if (value !== null) {
108521      this.renderer.setStyle(svg, name, value);
108522    } else {
108523      this.renderer.removeStyle(svg, name);
108524    }
108525  }
108526
108527  setClass(target, previous, current) {
108528    if (target) {
108529      if (previous) {
108530        const klasses = (Array.isArray(previous) ? previous : previous.split(' ')).filter(klass => klass);
108531
108532        for (const k of klasses) {
108533          this.renderer.removeClass(target, k);
108534        }
108535      }
108536
108537      if (current) {
108538        const klasses = (Array.isArray(current) ? current : current.split(' ')).filter(klass => klass);
108539
108540        for (const k of klasses) {
108541          this.renderer.addClass(target, k);
108542        }
108543      }
108544    }
108545  }
108546
108547  doAria(label) {
108548    const svg = this.element.nativeElement.firstChild;
108549
108550    if (svg) {
108551      if (label === '') {
108552        this.renderer.setAttribute(svg, 'aria-hidden', 'true');
108553        this.renderer.removeAttribute(svg, 'aria-label');
108554      } else {
108555        this.renderer.removeAttribute(svg, 'aria-hidden');
108556        this.renderer.setAttribute(svg, 'aria-label', label);
108557      }
108558    }
108559  }
108560
108561}
108562
108563SvgIconComponent.ɵfac = function SvgIconComponent_Factory(t) {
108564  return new (t || SvgIconComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](SvgIconRegistryService), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef));
108565};
108566
108567SvgIconComponent.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
108568  type: SvgIconComponent,
108569  selectors: [["svg-icon"]],
108570  inputs: {
108571    src: "src",
108572    name: "name",
108573    stretch: "stretch",
108574    applyClass: "applyClass",
108575    applyCss: "applyCss",
108576    svgClass: "svgClass",
108577    klass: ["class", "klass"],
108578    viewBox: "viewBox",
108579    svgAriaLabel: "svgAriaLabel",
108580    svgStyle: "svgStyle"
108581  },
108582  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]],
108583  ngContentSelectors: _c0,
108584  decls: 1,
108585  vars: 0,
108586  template: function SvgIconComponent_Template(rf, ctx) {
108587    if (rf & 1) {
108588      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
108589      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
108590    }
108591  },
108592  encapsulation: 2
108593});
108594
108595(function () {
108596  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SvgIconComponent, [{
108597    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
108598    args: [{
108599      selector: 'svg-icon',
108600      template: '<ng-content></ng-content>'
108601    }]
108602  }], function () {
108603    return [{
108604      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
108605    }, {
108606      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers
108607    }, {
108608      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
108609    }, {
108610      type: SvgIconRegistryService
108611    }, {
108612      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
108613    }];
108614  }, {
108615    src: [{
108616      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
108617    }],
108618    name: [{
108619      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
108620    }],
108621    stretch: [{
108622      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
108623    }],
108624    applyClass: [{
108625      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
108626    }],
108627    applyCss: [{
108628      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
108629    }],
108630    svgClass: [{
108631      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
108632    }],
108633    klass: [{
108634      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
108635      args: ['class']
108636    }],
108637    viewBox: [{
108638      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
108639    }],
108640    svgAriaLabel: [{
108641      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
108642    }],
108643    svgStyle: [{
108644      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
108645    }]
108646  });
108647})();
108648
108649class AngularSvgIconModule {
108650  static forRoot(config = {}) {
108651    return {
108652      ngModule: AngularSvgIconModule,
108653      providers: [SVG_ICON_REGISTRY_PROVIDER, config.loader || {
108654        provide: SvgLoader,
108655        useClass: SvgHttpLoader
108656      }]
108657    };
108658  }
108659
108660}
108661
108662AngularSvgIconModule.ɵfac = function AngularSvgIconModule_Factory(t) {
108663  return new (t || AngularSvgIconModule)();
108664};
108665
108666AngularSvgIconModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
108667  type: AngularSvgIconModule,
108668  declarations: [SvgIconComponent],
108669  imports: [_angular_common__WEBPACK_IMPORTED_MODULE_9__.CommonModule],
108670  exports: [SvgIconComponent]
108671});
108672AngularSvgIconModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
108673  imports: [_angular_common__WEBPACK_IMPORTED_MODULE_9__.CommonModule]
108674});
108675
108676(function () {
108677  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AngularSvgIconModule, [{
108678    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
108679    args: [{
108680      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_9__.CommonModule],
108681      declarations: [SvgIconComponent],
108682      exports: [SvgIconComponent]
108683    }]
108684  }], null, null);
108685})();
108686/**
108687 * Generated bundle index. Do not edit.
108688 */
108689
108690
108691
108692
108693/***/ }),
108694
108695/***/ 992:
108696/*!*****************************************************************************!*\
108697  !*** ./node_modules/ngx-google-analytics/fesm2020/ngx-google-analytics.mjs ***!
108698  \*****************************************************************************/
108699/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
108700
108701__webpack_require__.r(__webpack_exports__);
108702/* harmony export */ __webpack_require__.d(__webpack_exports__, {
108703/* harmony export */   "GaActionEnum": () => (/* binding */ GaActionEnum),
108704/* harmony export */   "GaEventCategoryDirective": () => (/* binding */ GaEventCategoryDirective),
108705/* harmony export */   "GaEventDirective": () => (/* binding */ GaEventDirective),
108706/* harmony export */   "GaEventFormInputDirective": () => (/* binding */ GaEventFormInputDirective),
108707/* harmony export */   "GoogleAnalyticsInitializer": () => (/* binding */ GoogleAnalyticsInitializer),
108708/* harmony export */   "GoogleAnalyticsRouterInitializer": () => (/* binding */ GoogleAnalyticsRouterInitializer),
108709/* harmony export */   "GoogleAnalyticsService": () => (/* binding */ GoogleAnalyticsService),
108710/* harmony export */   "NGX_DATA_LAYER": () => (/* binding */ NGX_DATA_LAYER),
108711/* harmony export */   "NGX_GOOGLE_ANALYTICS_INITIALIZER_PROVIDER": () => (/* binding */ NGX_GOOGLE_ANALYTICS_INITIALIZER_PROVIDER),
108712/* harmony export */   "NGX_GOOGLE_ANALYTICS_ROUTER_INITIALIZER_PROVIDER": () => (/* binding */ NGX_GOOGLE_ANALYTICS_ROUTER_INITIALIZER_PROVIDER),
108713/* harmony export */   "NGX_GOOGLE_ANALYTICS_ROUTING_SETTINGS_TOKEN": () => (/* binding */ NGX_GOOGLE_ANALYTICS_ROUTING_SETTINGS_TOKEN),
108714/* harmony export */   "NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN": () => (/* binding */ NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN),
108715/* harmony export */   "NGX_GTAG_FN": () => (/* binding */ NGX_GTAG_FN),
108716/* harmony export */   "NGX_WINDOW": () => (/* binding */ NGX_WINDOW),
108717/* harmony export */   "NgxGoogleAnalyticsModule": () => (/* binding */ NgxGoogleAnalyticsModule),
108718/* harmony export */   "NgxGoogleAnalyticsRouterModule": () => (/* binding */ NgxGoogleAnalyticsRouterModule),
108719/* harmony export */   "getDataLayerFn": () => (/* binding */ getDataLayerFn),
108720/* harmony export */   "getGtagFn": () => (/* binding */ getGtagFn)
108721/* harmony export */ });
108722/* harmony import */ var _github_workspace_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 1670);
108723/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 2560);
108724/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 6312);
108725/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/common */ 4666);
108726/* harmony import */ var _angular_router__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/router */ 124);
108727/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs/operators */ 9151);
108728/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 6276);
108729
108730
108731
108732
108733
108734
108735
108736
108737class GaEventCategoryDirective {
108738  constructor() {}
108739
108740}
108741
108742GaEventCategoryDirective.ɵfac = function GaEventCategoryDirective_Factory(t) {
108743  return new (t || GaEventCategoryDirective)();
108744};
108745
108746GaEventCategoryDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
108747  type: GaEventCategoryDirective,
108748  selectors: [["", "gaEvent", "", "gaCategory", ""], ["", "gaCategory", ""]],
108749  inputs: {
108750    gaCategory: "gaCategory"
108751  },
108752  exportAs: ["gaCategory"]
108753});
108754
108755(function () {
108756  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](GaEventCategoryDirective, [{
108757    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
108758    args: [{
108759      selector: `[gaEvent][gaCategory],
108760             [gaCategory]`,
108761      exportAs: 'gaCategory'
108762    }]
108763  }], function () {
108764    return [];
108765  }, {
108766    gaCategory: [{
108767      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
108768    }]
108769  });
108770})();
108771/**
108772 * Provide a Injection Token to global settings.
108773 */
108774
108775
108776const NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('ngx-google-analytics-settings', {
108777  factory: () => ({
108778    trackingCode: '',
108779    enableTracing: false
108780  })
108781});
108782/**
108783 * Provide DOM Window reference.
108784 */
108785
108786const NGX_WINDOW = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('ngx-window', {
108787  providedIn: 'root',
108788  factory: () => {
108789    const {
108790      defaultView
108791    } = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT);
108792
108793    if (!defaultView) {
108794      throw new Error('Window is not available');
108795    }
108796
108797    return defaultView;
108798  }
108799});
108800/**
108801 * Check if there is some global function called gtag on Window object, or create an empty function to doesn't brake codes...
108802 */
108803
108804function getDataLayerFn(window) {
108805  return window ? window['dataLayer'] = window['dataLayer'] || [] : null;
108806}
108807/**
108808 * Provides an injection token to access Google Analytics DataLayer Collection
108809 */
108810
108811
108812const NGX_DATA_LAYER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('ngx-data-layer', {
108813  providedIn: 'root',
108814  factory: () => getDataLayerFn((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NGX_WINDOW))
108815});
108816/**
108817 * Check if there is some global function called gtag on Window object, or create an empty function to doesn't brake codes...
108818 */
108819
108820function getGtagFn(window, dataLayer) {
108821  return window ? window['gtag'] = window['gtag'] || function () {
108822    dataLayer.push(arguments);
108823  } : null;
108824}
108825/**
108826 * Provides an injection token to access Google Analytics Gtag Function
108827 */
108828
108829
108830const NGX_GTAG_FN = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('ngx-gtag-fn', {
108831  providedIn: 'root',
108832  factory: () => getGtagFn((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NGX_WINDOW), (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NGX_DATA_LAYER))
108833});
108834
108835class GoogleAnalyticsService {
108836  constructor(settings, _document, _gtag) {
108837    this.settings = settings;
108838    this._document = _document;
108839    this._gtag = _gtag;
108840  }
108841
108842  get document() {
108843    return this._document;
108844  }
108845
108846  throw(err) {
108847    if ((this.settings.enableTracing || (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.isDevMode)()) && console && console.error) {
108848      console.error(err);
108849    }
108850  }
108851  /** @todo Change this to `Object.fromEntity()` in the future... */
108852
108853
108854  toKeyValue(map) {
108855    return map.size > 0 ? Array.from(map).reduce((obj, [key, value]) => Object.defineProperty(obj, key, {
108856      value,
108857      enumerable: true
108858    }), {}) : undefined;
108859  }
108860  /**
108861   * Call native GA Tag
108862   */
108863
108864
108865  gtag(...args) {
108866    try {
108867      this._gtag(...args.filter(x => x !== undefined));
108868    } catch (err) {
108869      this.throw(err);
108870    }
108871  }
108872  /**
108873   * Send an event trigger to GA. It is the same as call:
108874   * ```js
108875   * gtag('event', 'video_auto_play_start', {
108876   *   'event_label': 'My promotional video',
108877   *   'event_category': 'video_auto_play'
108878   * });
108879   * ```
108880   *
108881   * @param action 'video_auto_play_start'
108882   * @param category 'video_auto_play'
108883   * @param label 'My promotional video'
108884   * @param value An value to measure something
108885   * @param interaction If user interaction is performed
108886   */
108887
108888
108889  event(action, category, label, value, interaction, options) {
108890    try {
108891      const opt = new Map();
108892
108893      if (category) {
108894        opt.set('event_category', category);
108895      }
108896
108897      if (label) {
108898        opt.set('event_label', label);
108899      }
108900
108901      if (value) {
108902        opt.set('value', value);
108903      }
108904
108905      if (interaction !== undefined) {
108906        opt.set('interaction', interaction);
108907      }
108908
108909      if (options) {
108910        Object.entries(options).map(([key, value]) => opt.set(key, value));
108911      }
108912
108913      const params = this.toKeyValue(opt);
108914
108915      if (params) {
108916        this.gtag('event', action, params);
108917      } else {
108918        this.gtag('event', action);
108919      }
108920    } catch (error) {
108921      this.throw(error);
108922    }
108923  }
108924  /**
108925   * Send an page view event. This is the same as
108926   *
108927   * ```js
108928   * gtag('config', 'GA_TRACKING_ID', {
108929   *   'page_title' : 'Homepage',
108930   *   'page_path': '/home'
108931   * });
108932   * ```
108933   *
108934   * The tracking ID is injected automatically by Inject Token NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN
108935   *
108936   * @param path /home
108937   * @param title Homepage
108938   * @param location '{ page_location }'
108939   * @param options '{ ... custom dimentions }'
108940   */
108941
108942
108943  pageView(path, title, location, options) {
108944    try {
108945      const opt = new Map([['page_path', path]]);
108946
108947      if (title) {
108948        opt.set('page_title', title);
108949      }
108950
108951      if (location || this.document) {
108952        opt.set('page_location', location || this.document.location.href);
108953      }
108954
108955      if (options) {
108956        Object.entries(options).map(([key, value]) => opt.set(key, value));
108957      }
108958
108959      this.gtag('config', this.settings.trackingCode, this.toKeyValue(opt));
108960    } catch (error) {
108961      this.throw(error);
108962    }
108963  }
108964  /**
108965   * Send an event to report a App Page View. It is the same as
108966   *
108967   * ```js
108968   * gtag('event', 'screen_view', {
108969   *   'app_name': 'myAppName',
108970   *   'screen_name' : 'Home'
108971   * });
108972   *
108973   * ```
108974   *
108975   * @param screen 'screen_name'
108976   * @param appName 'app_name'
108977   * @param appId 'app_id'
108978   * @param appVersion 'app_version'
108979   * @param installerId 'app_installer_id'
108980   */
108981
108982
108983  appView(screen, appName, appId, appVersion, installerId) {
108984    try {
108985      const opt = new Map([['screen_name', screen], ['app_name', appName]]);
108986
108987      if (appId) {
108988        opt.set('app_id', appId);
108989      }
108990
108991      if (appVersion) {
108992        opt.set('app_version', appVersion);
108993      }
108994
108995      if (installerId) {
108996        opt.set('app_installer_id', installerId);
108997      }
108998
108999      this.gtag('event', 'screen_view', this.toKeyValue(opt));
109000    } catch (error) {
109001      this.throw(error);
109002    }
109003  }
109004  /**
109005   * Defines persistent values on GoogleAnalytics
109006   *
109007   * @see https://developers.google.com/analytics/devguides/collection/gtagjs/setting-values
109008   *
109009   * ```js
109010   * gtag('set', {
109011   *   'currency': 'USD',
109012   *   'country': 'US'
109013   * });
109014   * ```
109015   */
109016
109017
109018  set(...options) {
109019    try {
109020      this._gtag('set', ...options);
109021    } catch (err) {
109022      this.throw(err);
109023    }
109024  }
109025  /**
109026   * Send an event to GA to report an application error. It is the same as
109027   *
109028   * ```js
109029   * gtag('event', 'exception', {
109030   *   'description': 'error_description',
109031   *   'fatal': false   // set to true if the error is fatal
109032   * });
109033   * ```
109034   *
109035   * @param description 'error_description'
109036   * @param fatal set to true if the error is fatal
109037   */
109038
109039
109040  exception(description, fatal) {
109041    try {
109042      const opt = new Map();
109043
109044      if (description) {
109045        opt.set('description', description);
109046      }
109047
109048      if (fatal) {
109049        opt.set('fatal', fatal);
109050      }
109051
109052      const params = this.toKeyValue(opt);
109053
109054      if (params) {
109055        this.gtag('event', 'exception', this.toKeyValue(opt));
109056      } else {
109057        this.gtag('event', 'exception');
109058      }
109059    } catch (error) {
109060      this.throw(error);
109061    }
109062  }
109063
109064}
109065
109066GoogleAnalyticsService.ɵfac = function GoogleAnalyticsService_Factory(t) {
109067  return new (t || GoogleAnalyticsService)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](NGX_GTAG_FN));
109068};
109069
109070GoogleAnalyticsService.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
109071  token: GoogleAnalyticsService,
109072  factory: GoogleAnalyticsService.ɵfac,
109073  providedIn: 'root'
109074});
109075
109076(function () {
109077  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](GoogleAnalyticsService, [{
109078    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
109079    args: [{
109080      providedIn: 'root'
109081    }]
109082  }], function () {
109083    return [{
109084      type: undefined,
109085      decorators: [{
109086        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
109087        args: [NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN]
109088      }]
109089    }, {
109090      type: undefined,
109091      decorators: [{
109092        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
109093        args: [_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT]
109094      }]
109095    }, {
109096      type: undefined,
109097      decorators: [{
109098        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
109099        args: [NGX_GTAG_FN]
109100      }]
109101    }];
109102  }, null);
109103})();
109104
109105class GaEventDirective {
109106  constructor(gaCategoryDirective, gaService, settings, el) {
109107    this.gaCategoryDirective = gaCategoryDirective;
109108    this.gaService = gaService;
109109    this.settings = settings;
109110    this.el = el;
109111    this.gaBind = 'click';
109112  }
109113
109114  set gaBind(gaBind) {
109115    if (this.bindSubscription) {
109116      this.bindSubscription.unsubscribe();
109117    }
109118
109119    this._gaBind = gaBind;
109120    this.bindSubscription = (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.fromEvent)(this.el.nativeElement, gaBind).subscribe(() => this.trigger());
109121  }
109122
109123  get gaBind() {
109124    return this._gaBind;
109125  }
109126
109127  ngOnDestroy() {
109128    if (this.bindSubscription) {
109129      this.bindSubscription.unsubscribe();
109130    }
109131  }
109132
109133  trigger() {
109134    try {
109135      // Observação: não é obrigatório especificar uma categoria, uma etiqueta ou um valor. Consulte Eventos padrão do Google Analytics abaixo.
109136      // if (!this.$gaCategoryDirective) {
109137      //   throw new Error('You must provide a gaCategory attribute w/ gaEvent Directive.');
109138      // }
109139      if (!this.gaAction && !this.gaEvent) {
109140        throw new Error('You must provide a gaAction attribute to identify this event.');
109141      }
109142
109143      this.gaService.event(this.gaAction || this.gaEvent, this.gaCategoryDirective ? this.gaCategoryDirective.gaCategory : undefined, this.gaLabel || this.label, this.gaValue, this.gaInteraction);
109144    } catch (err) {
109145      this.throw(err);
109146    }
109147  }
109148
109149  throw(err) {
109150    if (((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.isDevMode)() || this.settings.enableTracing) && console && console.warn) {
109151      console.warn(err);
109152    }
109153  }
109154
109155}
109156
109157GaEventDirective.ɵfac = function GaEventDirective_Factory(t) {
109158  return new (t || GaEventDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](GaEventCategoryDirective, 8), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](GoogleAnalyticsService), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef));
109159};
109160
109161GaEventDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
109162  type: GaEventDirective,
109163  selectors: [["", "gaEvent", ""]],
109164  inputs: {
109165    gaAction: "gaAction",
109166    gaLabel: "gaLabel",
109167    label: "label",
109168    gaValue: "gaValue",
109169    gaInteraction: "gaInteraction",
109170    gaEvent: "gaEvent",
109171    gaBind: "gaBind"
109172  },
109173  exportAs: ["gaEvent"]
109174});
109175
109176(function () {
109177  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](GaEventDirective, [{
109178    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
109179    args: [{
109180      selector: `[gaEvent]`,
109181      exportAs: 'gaEvent'
109182    }]
109183  }], function () {
109184    return [{
109185      type: GaEventCategoryDirective,
109186      decorators: [{
109187        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
109188      }]
109189    }, {
109190      type: GoogleAnalyticsService
109191    }, {
109192      type: undefined,
109193      decorators: [{
109194        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
109195        args: [NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN]
109196      }]
109197    }, {
109198      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
109199    }];
109200  }, {
109201    gaAction: [{
109202      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
109203    }],
109204    gaLabel: [{
109205      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
109206    }],
109207    label: [{
109208      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
109209    }],
109210    gaValue: [{
109211      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
109212    }],
109213    gaInteraction: [{
109214      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
109215    }],
109216    gaEvent: [{
109217      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
109218    }],
109219    gaBind: [{
109220      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
109221    }]
109222  });
109223})();
109224
109225class GaEventFormInputDirective {
109226  constructor(gaEvent) {
109227    this.gaEvent = gaEvent;
109228    this.gaBind = 'focus';
109229  }
109230
109231  set gaBind(bind) {
109232    if (this.gaEvent) {
109233      this.gaEvent.gaBind = bind;
109234    }
109235  }
109236
109237}
109238
109239GaEventFormInputDirective.ɵfac = function GaEventFormInputDirective_Factory(t) {
109240  return new (t || GaEventFormInputDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](GaEventDirective, 9));
109241};
109242
109243GaEventFormInputDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
109244  type: GaEventFormInputDirective,
109245  selectors: [["input", "gaEvent", ""], ["select", "gaEvent", ""], ["textarea", "gaEvent", ""]],
109246  inputs: {
109247    gaBind: "gaBind"
109248  }
109249});
109250
109251(function () {
109252  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](GaEventFormInputDirective, [{
109253    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
109254    args: [{
109255      selector: `input[gaEvent],
109256             select[gaEvent],
109257             textarea[gaEvent]`
109258    }]
109259  }], function () {
109260    return [{
109261      type: GaEventDirective,
109262      decorators: [{
109263        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Host
109264      }, {
109265        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
109266      }]
109267    }];
109268  }, {
109269    gaBind: [{
109270      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
109271    }]
109272  });
109273})();
109274
109275var GaActionEnum;
109276
109277(function (GaActionEnum) {
109278  GaActionEnum["ADD_PAYMENT_INFO"] = "add_payment_info";
109279  GaActionEnum["ADD_TO_CART"] = "add_to_cart";
109280  GaActionEnum["ADD_TO_WISHLIST"] = "add_to_wishlist";
109281  GaActionEnum["BEGIN_CHECKOUT"] = "begin_checkout";
109282  GaActionEnum["CHECKOUT_PROGRESS"] = "checkout_progress";
109283  GaActionEnum["GENERATE_LEAD"] = "generate_lead";
109284  GaActionEnum["LOGIN"] = "login";
109285  GaActionEnum["PURCHASE"] = "purchase";
109286  GaActionEnum["REFUND"] = "refund";
109287  GaActionEnum["REMOVE_FROM_CART"] = "remove_from_cart";
109288  GaActionEnum["SEARCH"] = "search";
109289  GaActionEnum["SELECT_CONTENT"] = "select_content";
109290  GaActionEnum["SET_CHECKOUT_OPTION"] = "set_checkout_option";
109291  GaActionEnum["SHARE"] = "share";
109292  GaActionEnum["SIGN_UP"] = "sign_up";
109293  GaActionEnum["VIEW_ITEM"] = "view_item";
109294  GaActionEnum["VIEW_ITEM_LIST"] = "view_item_list";
109295  GaActionEnum["VIEW_PROMOTION"] = "view_promotion";
109296  GaActionEnum["VIEW_SEARCH_RESULT"] = "view_search_results";
109297  GaActionEnum["VIEW_SEARCH_RESULTS"] = "view_search_results";
109298})(GaActionEnum || (GaActionEnum = {}));
109299/**
109300 * Provide a DI Configuration to attach GA Initialization at Angular Startup Cycle.
109301 */
109302
109303
109304const NGX_GOOGLE_ANALYTICS_INITIALIZER_PROVIDER = {
109305  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_INITIALIZER,
109306  multi: true,
109307  useFactory: GoogleAnalyticsInitializer,
109308  deps: [NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN, NGX_GTAG_FN, _angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT]
109309};
109310/**
109311 * Create a script element on DOM and link it to Google Analytics tracking code URI.
109312 * After that, execute exactly same init process as tracking snippet code.
109313 */
109314
109315function GoogleAnalyticsInitializer(settings, gtag, document) {
109316  return /*#__PURE__*/(0,_github_workspace_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
109317    if (!settings.trackingCode) {
109318      if (!(0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.isDevMode)()) {
109319        console.error('Empty tracking code for Google Analytics. Make sure to provide one when initializing NgxGoogleAnalyticsModule.');
109320      }
109321
109322      return;
109323    }
109324
109325    if (!gtag) {
109326      if (!(0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.isDevMode)()) {
109327        console.error('Was not possible create or read gtag() fn. Make sure this module is running on a Browser w/ access to Window interface.');
109328      }
109329
109330      return;
109331    }
109332
109333    if (!document) {
109334      if (!(0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.isDevMode)()) {
109335        console.error('Was not possible to access Document interface. Make sure this module is running on a Browser w/ access do Document interface.');
109336      }
109337    } // Set default ga.js uri
109338
109339
109340    settings.uri = settings.uri || `https://www.googletagmanager.com/gtag/js?id=${settings.trackingCode}`; // these commands should run first!
109341
109342    settings.initCommands = settings?.initCommands ?? []; // assert config command
109343
109344    if (!settings.initCommands.find(x => x.command === 'config')) {
109345      settings.initCommands.unshift({
109346        command: 'config',
109347        values: [settings.trackingCode]
109348      });
109349    } // assert js command
109350
109351
109352    if (!settings.initCommands.find(x => x.command === 'js')) {
109353      settings.initCommands.unshift({
109354        command: 'js',
109355        values: [new Date()]
109356      });
109357    }
109358
109359    for (const command of settings.initCommands) {
109360      gtag(command.command, ...command.values);
109361    }
109362
109363    const s = document.createElement('script');
109364    s.async = true;
109365    s.src = settings.uri;
109366
109367    if (settings.nonce) {
109368      s.setAttribute('nonce', settings.nonce);
109369    }
109370
109371    const head = document.getElementsByTagName('head')[0];
109372    head.appendChild(s);
109373  });
109374}
109375/**
109376 * Provide a Injection Token to global settings.
109377 */
109378
109379
109380const NGX_GOOGLE_ANALYTICS_ROUTING_SETTINGS_TOKEN = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('ngx-google-analytics-routing-settings', {
109381  factory: () => ({})
109382});
109383/**
109384 * Provide a DI Configuration to attach GA Trigger to Router Events at Angular Startup Cycle.
109385 */
109386
109387const NGX_GOOGLE_ANALYTICS_ROUTER_INITIALIZER_PROVIDER = {
109388  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_BOOTSTRAP_LISTENER,
109389  multi: true,
109390  useFactory: GoogleAnalyticsRouterInitializer,
109391  deps: [NGX_GOOGLE_ANALYTICS_ROUTING_SETTINGS_TOKEN, GoogleAnalyticsService]
109392};
109393/**
109394 * Attach a listener to `NavigationEnd` Router event. So, every time Router finish the page resolution it should call `NavigationEnd` event.
109395 * We assume that NavigationEnd is the final page resolution and call GA `page_view` command.
109396 *
109397 * To avoid double binds, we also destroy the subscription when de Bootstrap Component is destroied. But, we don't know for sure
109398 * that this strategy does not cause double bind on multiple bootstrap components.
109399 *
109400 * We are using de component's injector reference to resolve Router, sou I hope there is no problem w/ double bing.
109401 *
109402 * If you have this problem, I encourage not Use NgxGoogleAnalyticsRouterModule and atach the listener on AppComponent initialization.
109403 */
109404
109405function GoogleAnalyticsRouterInitializer(settings, gaService) {
109406  return /*#__PURE__*/function () {
109407    var _ref2 = (0,_github_workspace_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (c) {
109408      const router = c.injector.get(_angular_router__WEBPACK_IMPORTED_MODULE_4__.Router);
109409      const {
109410        include = [],
109411        exclude = []
109412      } = settings ?? {};
109413      const includeRules = normalizePathRules(include);
109414      const excludeRules = normalizePathRules(exclude);
109415      const subs = router.events.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.filter)(event => event instanceof _angular_router__WEBPACK_IMPORTED_MODULE_4__.NavigationEnd), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.skip)(1), // Prevend double views on the first tigger (because GA Already send one ping on setup)
109416      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.filter)(event => includeRules.length > 0 ? includeRules.some(rule => rule.test(event.urlAfterRedirects)) : true), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.filter)(event => excludeRules.length > 0 ? !excludeRules.some(rule => rule.test(event.urlAfterRedirects)) : true)).subscribe(event => gaService.pageView(event.urlAfterRedirects, undefined)); // Cleanup
109417
109418      c.onDestroy(() => subs.unsubscribe());
109419    });
109420
109421    return function (_x) {
109422      return _ref2.apply(this, arguments);
109423    };
109424  }();
109425}
109426/** Converts all path rules from string to Regex instances */
109427
109428
109429function normalizePathRules(rules) {
109430  return rules.map(rule => rule instanceof RegExp ? rule : new RegExp(`^${rule.replace('*', '.*')}$`, 'i'));
109431}
109432/**
109433 * Install Google Analytics Tracking code on your environment and configure tracking ID.
109434 *
109435 * This module should be a dependency on the highest level module of the application, i.e. AppModule in most use cases.
109436 */
109437
109438
109439class NgxGoogleAnalyticsModule {
109440  /**
109441   * You should provide a valid Google TrackingCode. This code will be provided to the entire application by
109442   * `NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN` token. You can inject this code in you components if you like by
109443   * use the following injection code `@Inject(NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN) gaConfig: IGoogleAnalyticsSettings`
109444   *
109445   * @param trackingCode The Google Tracking Code
109446   * @param initCommands When placed, it will run any GA Commands in sequence after setup GA environment.
109447   * @param uri When placed, it will change the default js URI to the provided one.
109448   * @param enableTracing When true, trace GA tracking errors on production mode.
109449   * @param nonce When placed, nonce will be added to script tag.
109450   */
109451  static forRoot(trackingCode, initCommands = [], uri, enableTracing, nonce) {
109452    return {
109453      ngModule: NgxGoogleAnalyticsModule,
109454      providers: [{
109455        provide: NGX_GOOGLE_ANALYTICS_SETTINGS_TOKEN,
109456        useValue: {
109457          trackingCode,
109458          initCommands,
109459          uri,
109460          enableTracing,
109461          nonce
109462        }
109463      }, NGX_GOOGLE_ANALYTICS_INITIALIZER_PROVIDER]
109464    };
109465  }
109466
109467}
109468
109469NgxGoogleAnalyticsModule.ɵfac = function NgxGoogleAnalyticsModule_Factory(t) {
109470  return new (t || NgxGoogleAnalyticsModule)();
109471};
109472
109473NgxGoogleAnalyticsModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
109474  type: NgxGoogleAnalyticsModule,
109475  declarations: [GaEventDirective, GaEventCategoryDirective, GaEventFormInputDirective],
109476  exports: [GaEventDirective, GaEventCategoryDirective, GaEventFormInputDirective]
109477});
109478NgxGoogleAnalyticsModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
109479
109480(function () {
109481  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](NgxGoogleAnalyticsModule, [{
109482    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
109483    args: [{
109484      imports: [],
109485      declarations: [GaEventDirective, GaEventCategoryDirective, GaEventFormInputDirective],
109486      exports: [GaEventDirective, GaEventCategoryDirective, GaEventFormInputDirective]
109487    }]
109488  }], null, null);
109489})();
109490/**
109491 * Attach a listener to `NavigationEnd` Router event. So, every time Router finish the page resolution it should call `NavigationEnd` event.
109492 * We assume that NavigationEnd is the final page resolution and call GA `page_view` command.
109493 *
109494 * To avoid double binds, we also destroy the subscription when de Bootstrap Component is destroied. But, we don't know for sure
109495 * that this strategy does not cause double bind on multiple bootstrap components.
109496 *
109497 * We are using de component's injector reference to resolve Router, sou I hope there is no problem w/ double bing.
109498 *
109499 * If you have this problem, I encourage not Use NgxGoogleAnalyticsRouterModule and atach the listener on AppComponent initialization.
109500 *
109501 * This Module is just a sugar for:
109502 *
109503```typescript
109504constructor(private router: Router) {}
109505...
109506ngOnInit() {
109507  ...
109508  this.router
109509    .events
109510    .pipe(takeUntil(this.onDestroy$))
109511    .subscribe(event => {
109512      if (event instanceof NavigationEnd) {
109513        gaService.pageView(event.urlAfterRedirects, undefined);
109514      }
109515    });
109516```
109517 */
109518
109519
109520class NgxGoogleAnalyticsRouterModule {
109521  static forRoot(settings) {
109522    return {
109523      ngModule: NgxGoogleAnalyticsRouterModule,
109524      providers: [{
109525        provide: NGX_GOOGLE_ANALYTICS_ROUTING_SETTINGS_TOKEN,
109526        useValue: settings ?? {}
109527      }]
109528    };
109529  }
109530
109531}
109532
109533NgxGoogleAnalyticsRouterModule.ɵfac = function NgxGoogleAnalyticsRouterModule_Factory(t) {
109534  return new (t || NgxGoogleAnalyticsRouterModule)();
109535};
109536
109537NgxGoogleAnalyticsRouterModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
109538  type: NgxGoogleAnalyticsRouterModule,
109539  imports: [_angular_common__WEBPACK_IMPORTED_MODULE_2__.CommonModule, NgxGoogleAnalyticsModule]
109540});
109541NgxGoogleAnalyticsRouterModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({
109542  providers: [NGX_GOOGLE_ANALYTICS_ROUTER_INITIALIZER_PROVIDER],
109543  imports: [_angular_common__WEBPACK_IMPORTED_MODULE_2__.CommonModule, NgxGoogleAnalyticsModule]
109544});
109545
109546(function () {
109547  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](NgxGoogleAnalyticsRouterModule, [{
109548    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
109549    args: [{
109550      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_2__.CommonModule, NgxGoogleAnalyticsModule],
109551      providers: [NGX_GOOGLE_ANALYTICS_ROUTER_INITIALIZER_PROVIDER],
109552      declarations: []
109553    }]
109554  }], null, null);
109555})();
109556/*
109557 * Public API Surface of ngx-google-analytics
109558 */
109559
109560/**
109561 * Generated bundle index. Do not edit.
109562 */
109563
109564
109565
109566
109567/***/ }),
109568
109569/***/ 1670:
109570/*!*********************************************************************!*\
109571  !*** ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js ***!
109572  \*********************************************************************/
109573/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
109574
109575__webpack_require__.r(__webpack_exports__);
109576/* harmony export */ __webpack_require__.d(__webpack_exports__, {
109577/* harmony export */   "default": () => (/* binding */ _asyncToGenerator)
109578/* harmony export */ });
109579function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
109580  try {
109581    var info = gen[key](arg);
109582    var value = info.value;
109583  } catch (error) {
109584    reject(error);
109585    return;
109586  }
109587
109588  if (info.done) {
109589    resolve(value);
109590  } else {
109591    Promise.resolve(value).then(_next, _throw);
109592  }
109593}
109594
109595function _asyncToGenerator(fn) {
109596  return function () {
109597    var self = this,
109598        args = arguments;
109599    return new Promise(function (resolve, reject) {
109600      var gen = fn.apply(self, args);
109601
109602      function _next(value) {
109603        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
109604      }
109605
109606      function _throw(err) {
109607        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
109608      }
109609
109610      _next(undefined);
109611    });
109612  };
109613}
109614
109615/***/ })
109616
109617}]);
109618//# sourceMappingURL=vendor.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.