UNPKG

1.47 MBJavaScriptView Raw
1/**
2 * @license Angular v10.0.10
3 * (c) 2010-2020 Google LLC. https://angular.io/
4 * License: MIT
5 */
6
7(function (global, factory) {
8 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs'), require('rxjs/operators')) :
9 typeof define === 'function' && define.amd ? define('@angular/core', ['exports', 'rxjs', 'rxjs/operators'], factory) :
10 (global = global || self, factory((global.ng = global.ng || {}, global.ng.core = {}), global.rxjs, global.rxjs.operators));
11}(this, (function (exports, rxjs, operators) { 'use strict';
12
13 /*! *****************************************************************************
14 Copyright (c) Microsoft Corporation.
15
16 Permission to use, copy, modify, and/or distribute this software for any
17 purpose with or without fee is hereby granted.
18
19 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
20 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
21 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
22 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
23 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
24 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
25 PERFORMANCE OF THIS SOFTWARE.
26 ***************************************************************************** */
27 /* global Reflect, Promise */
28 var extendStatics = function (d, b) {
29 extendStatics = Object.setPrototypeOf ||
30 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31 function (d, b) { for (var p in b)
32 if (b.hasOwnProperty(p))
33 d[p] = b[p]; };
34 return extendStatics(d, b);
35 };
36 function __extends(d, b) {
37 extendStatics(d, b);
38 function __() { this.constructor = d; }
39 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
40 }
41 var __assign = function () {
42 __assign = Object.assign || function __assign(t) {
43 for (var s, i = 1, n = arguments.length; i < n; i++) {
44 s = arguments[i];
45 for (var p in s)
46 if (Object.prototype.hasOwnProperty.call(s, p))
47 t[p] = s[p];
48 }
49 return t;
50 };
51 return __assign.apply(this, arguments);
52 };
53 function __rest(s, e) {
54 var t = {};
55 for (var p in s)
56 if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
57 t[p] = s[p];
58 if (s != null && typeof Object.getOwnPropertySymbols === "function")
59 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
60 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
61 t[p[i]] = s[p[i]];
62 }
63 return t;
64 }
65 function __decorate(decorators, target, key, desc) {
66 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
67 if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
68 r = Reflect.decorate(decorators, target, key, desc);
69 else
70 for (var i = decorators.length - 1; i >= 0; i--)
71 if (d = decorators[i])
72 r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
73 return c > 3 && r && Object.defineProperty(target, key, r), r;
74 }
75 function __param(paramIndex, decorator) {
76 return function (target, key) { decorator(target, key, paramIndex); };
77 }
78 function __metadata(metadataKey, metadataValue) {
79 if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
80 return Reflect.metadata(metadataKey, metadataValue);
81 }
82 function __awaiter(thisArg, _arguments, P, generator) {
83 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
84 return new (P || (P = Promise))(function (resolve, reject) {
85 function fulfilled(value) { try {
86 step(generator.next(value));
87 }
88 catch (e) {
89 reject(e);
90 } }
91 function rejected(value) { try {
92 step(generator["throw"](value));
93 }
94 catch (e) {
95 reject(e);
96 } }
97 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
98 step((generator = generator.apply(thisArg, _arguments || [])).next());
99 });
100 }
101 function __generator(thisArg, body) {
102 var _ = { label: 0, sent: function () { if (t[0] & 1)
103 throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
104 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
105 function verb(n) { return function (v) { return step([n, v]); }; }
106 function step(op) {
107 if (f)
108 throw new TypeError("Generator is already executing.");
109 while (_)
110 try {
111 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)
112 return t;
113 if (y = 0, t)
114 op = [op[0] & 2, t.value];
115 switch (op[0]) {
116 case 0:
117 case 1:
118 t = op;
119 break;
120 case 4:
121 _.label++;
122 return { value: op[1], done: false };
123 case 5:
124 _.label++;
125 y = op[1];
126 op = [0];
127 continue;
128 case 7:
129 op = _.ops.pop();
130 _.trys.pop();
131 continue;
132 default:
133 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
134 _ = 0;
135 continue;
136 }
137 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
138 _.label = op[1];
139 break;
140 }
141 if (op[0] === 6 && _.label < t[1]) {
142 _.label = t[1];
143 t = op;
144 break;
145 }
146 if (t && _.label < t[2]) {
147 _.label = t[2];
148 _.ops.push(op);
149 break;
150 }
151 if (t[2])
152 _.ops.pop();
153 _.trys.pop();
154 continue;
155 }
156 op = body.call(thisArg, _);
157 }
158 catch (e) {
159 op = [6, e];
160 y = 0;
161 }
162 finally {
163 f = t = 0;
164 }
165 if (op[0] & 5)
166 throw op[1];
167 return { value: op[0] ? op[1] : void 0, done: true };
168 }
169 }
170 var __createBinding = Object.create ? (function (o, m, k, k2) {
171 if (k2 === undefined)
172 k2 = k;
173 Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
174 }) : (function (o, m, k, k2) {
175 if (k2 === undefined)
176 k2 = k;
177 o[k2] = m[k];
178 });
179 function __exportStar(m, exports) {
180 for (var p in m)
181 if (p !== "default" && !exports.hasOwnProperty(p))
182 __createBinding(exports, m, p);
183 }
184 function __values(o) {
185 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
186 if (m)
187 return m.call(o);
188 if (o && typeof o.length === "number")
189 return {
190 next: function () {
191 if (o && i >= o.length)
192 o = void 0;
193 return { value: o && o[i++], done: !o };
194 }
195 };
196 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
197 }
198 function __read(o, n) {
199 var m = typeof Symbol === "function" && o[Symbol.iterator];
200 if (!m)
201 return o;
202 var i = m.call(o), r, ar = [], e;
203 try {
204 while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
205 ar.push(r.value);
206 }
207 catch (error) {
208 e = { error: error };
209 }
210 finally {
211 try {
212 if (r && !r.done && (m = i["return"]))
213 m.call(i);
214 }
215 finally {
216 if (e)
217 throw e.error;
218 }
219 }
220 return ar;
221 }
222 function __spread() {
223 for (var ar = [], i = 0; i < arguments.length; i++)
224 ar = ar.concat(__read(arguments[i]));
225 return ar;
226 }
227 function __spreadArrays() {
228 for (var s = 0, i = 0, il = arguments.length; i < il; i++)
229 s += arguments[i].length;
230 for (var r = Array(s), k = 0, i = 0; i < il; i++)
231 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
232 r[k] = a[j];
233 return r;
234 }
235 ;
236 function __await(v) {
237 return this instanceof __await ? (this.v = v, this) : new __await(v);
238 }
239 function __asyncGenerator(thisArg, _arguments, generator) {
240 if (!Symbol.asyncIterator)
241 throw new TypeError("Symbol.asyncIterator is not defined.");
242 var g = generator.apply(thisArg, _arguments || []), i, q = [];
243 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
244 function verb(n) { if (g[n])
245 i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
246 function resume(n, v) { try {
247 step(g[n](v));
248 }
249 catch (e) {
250 settle(q[0][3], e);
251 } }
252 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
253 function fulfill(value) { resume("next", value); }
254 function reject(value) { resume("throw", value); }
255 function settle(f, v) { if (f(v), q.shift(), q.length)
256 resume(q[0][0], q[0][1]); }
257 }
258 function __asyncDelegator(o) {
259 var i, p;
260 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
261 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; }
262 }
263 function __asyncValues(o) {
264 if (!Symbol.asyncIterator)
265 throw new TypeError("Symbol.asyncIterator is not defined.");
266 var m = o[Symbol.asyncIterator], i;
267 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);
268 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); }); }; }
269 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
270 }
271 function __makeTemplateObject(cooked, raw) {
272 if (Object.defineProperty) {
273 Object.defineProperty(cooked, "raw", { value: raw });
274 }
275 else {
276 cooked.raw = raw;
277 }
278 return cooked;
279 }
280 ;
281 var __setModuleDefault = Object.create ? (function (o, v) {
282 Object.defineProperty(o, "default", { enumerable: true, value: v });
283 }) : function (o, v) {
284 o["default"] = v;
285 };
286 function __importStar(mod) {
287 if (mod && mod.__esModule)
288 return mod;
289 var result = {};
290 if (mod != null)
291 for (var k in mod)
292 if (Object.hasOwnProperty.call(mod, k))
293 __createBinding(result, mod, k);
294 __setModuleDefault(result, mod);
295 return result;
296 }
297 function __importDefault(mod) {
298 return (mod && mod.__esModule) ? mod : { default: mod };
299 }
300 function __classPrivateFieldGet(receiver, privateMap) {
301 if (!privateMap.has(receiver)) {
302 throw new TypeError("attempted to get private field on non-instance");
303 }
304 return privateMap.get(receiver);
305 }
306 function __classPrivateFieldSet(receiver, privateMap, value) {
307 if (!privateMap.has(receiver)) {
308 throw new TypeError("attempted to set private field on non-instance");
309 }
310 privateMap.set(receiver, value);
311 return value;
312 }
313
314 /**
315 * @license
316 * Copyright Google LLC All Rights Reserved.
317 *
318 * Use of this source code is governed by an MIT-style license that can be
319 * found in the LICENSE file at https://angular.io/license
320 */
321 /**
322 * Convince closure compiler that the wrapped function has no side-effects.
323 *
324 * Closure compiler always assumes that `toString` has no side-effects. We use this quirk to
325 * allow us to execute a function but have closure compiler mark the call as no-side-effects.
326 * It is important that the return value for the `noSideEffects` function be assigned
327 * to something which is retained otherwise the call to `noSideEffects` will be removed by closure
328 * compiler.
329 */
330 function noSideEffects(fn) {
331 return { toString: fn }.toString();
332 }
333
334 var ANNOTATIONS = '__annotations__';
335 var PARAMETERS = '__parameters__';
336 var PROP_METADATA = '__prop__metadata__';
337 /**
338 * @suppress {globalThis}
339 */
340 function makeDecorator(name, props, parentClass, additionalProcessing, typeFn) {
341 return noSideEffects(function () {
342 var metaCtor = makeMetadataCtor(props);
343 function DecoratorFactory() {
344 var args = [];
345 for (var _i = 0; _i < arguments.length; _i++) {
346 args[_i] = arguments[_i];
347 }
348 if (this instanceof DecoratorFactory) {
349 metaCtor.call.apply(metaCtor, __spread([this], args));
350 return this;
351 }
352 var annotationInstance = new (DecoratorFactory.bind.apply(DecoratorFactory, __spread([void 0], args)))();
353 return function TypeDecorator(cls) {
354 if (typeFn)
355 typeFn.apply(void 0, __spread([cls], args));
356 // Use of Object.defineProperty is important since it creates non-enumerable property which
357 // prevents the property is copied during subclassing.
358 var annotations = cls.hasOwnProperty(ANNOTATIONS) ?
359 cls[ANNOTATIONS] :
360 Object.defineProperty(cls, ANNOTATIONS, { value: [] })[ANNOTATIONS];
361 annotations.push(annotationInstance);
362 if (additionalProcessing)
363 additionalProcessing(cls);
364 return cls;
365 };
366 }
367 if (parentClass) {
368 DecoratorFactory.prototype = Object.create(parentClass.prototype);
369 }
370 DecoratorFactory.prototype.ngMetadataName = name;
371 DecoratorFactory.annotationCls = DecoratorFactory;
372 return DecoratorFactory;
373 });
374 }
375 function makeMetadataCtor(props) {
376 return function ctor() {
377 var args = [];
378 for (var _i = 0; _i < arguments.length; _i++) {
379 args[_i] = arguments[_i];
380 }
381 if (props) {
382 var values = props.apply(void 0, __spread(args));
383 for (var propName in values) {
384 this[propName] = values[propName];
385 }
386 }
387 };
388 }
389 function makeParamDecorator(name, props, parentClass) {
390 return noSideEffects(function () {
391 var metaCtor = makeMetadataCtor(props);
392 function ParamDecoratorFactory() {
393 var args = [];
394 for (var _i = 0; _i < arguments.length; _i++) {
395 args[_i] = arguments[_i];
396 }
397 if (this instanceof ParamDecoratorFactory) {
398 metaCtor.apply(this, args);
399 return this;
400 }
401 var annotationInstance = new (ParamDecoratorFactory.bind.apply(ParamDecoratorFactory, __spread([void 0], args)))();
402 ParamDecorator.annotation = annotationInstance;
403 return ParamDecorator;
404 function ParamDecorator(cls, unusedKey, index) {
405 // Use of Object.defineProperty is important since it creates non-enumerable property which
406 // prevents the property is copied during subclassing.
407 var parameters = cls.hasOwnProperty(PARAMETERS) ?
408 cls[PARAMETERS] :
409 Object.defineProperty(cls, PARAMETERS, { value: [] })[PARAMETERS];
410 // there might be gaps if some in between parameters do not have annotations.
411 // we pad with nulls.
412 while (parameters.length <= index) {
413 parameters.push(null);
414 }
415 (parameters[index] = parameters[index] || []).push(annotationInstance);
416 return cls;
417 }
418 }
419 if (parentClass) {
420 ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
421 }
422 ParamDecoratorFactory.prototype.ngMetadataName = name;
423 ParamDecoratorFactory.annotationCls = ParamDecoratorFactory;
424 return ParamDecoratorFactory;
425 });
426 }
427 function makePropDecorator(name, props, parentClass, additionalProcessing) {
428 return noSideEffects(function () {
429 var metaCtor = makeMetadataCtor(props);
430 function PropDecoratorFactory() {
431 var args = [];
432 for (var _i = 0; _i < arguments.length; _i++) {
433 args[_i] = arguments[_i];
434 }
435 if (this instanceof PropDecoratorFactory) {
436 metaCtor.apply(this, args);
437 return this;
438 }
439 var decoratorInstance = new (PropDecoratorFactory.bind.apply(PropDecoratorFactory, __spread([void 0], args)))();
440 function PropDecorator(target, name) {
441 var constructor = target.constructor;
442 // Use of Object.defineProperty is important because it creates a non-enumerable property
443 // which prevents the property from being copied during subclassing.
444 var meta = constructor.hasOwnProperty(PROP_METADATA) ?
445 constructor[PROP_METADATA] :
446 Object.defineProperty(constructor, PROP_METADATA, { value: {} })[PROP_METADATA];
447 meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
448 meta[name].unshift(decoratorInstance);
449 if (additionalProcessing)
450 additionalProcessing.apply(void 0, __spread([target, name], args));
451 }
452 return PropDecorator;
453 }
454 if (parentClass) {
455 PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
456 }
457 PropDecoratorFactory.prototype.ngMetadataName = name;
458 PropDecoratorFactory.annotationCls = PropDecoratorFactory;
459 return PropDecoratorFactory;
460 });
461 }
462
463 /**
464 * @license
465 * Copyright Google LLC All Rights Reserved.
466 *
467 * Use of this source code is governed by an MIT-style license that can be
468 * found in the LICENSE file at https://angular.io/license
469 */
470 var ɵ0 = function (token) { return ({ token: token }); };
471 /**
472 * Inject decorator and metadata.
473 *
474 * @Annotation
475 * @publicApi
476 */
477 var Inject = makeParamDecorator('Inject', ɵ0);
478 /**
479 * Optional decorator and metadata.
480 *
481 * @Annotation
482 * @publicApi
483 */
484 var Optional = makeParamDecorator('Optional');
485 /**
486 * Self decorator and metadata.
487 *
488 * @Annotation
489 * @publicApi
490 */
491 var Self = makeParamDecorator('Self');
492 /**
493 * `SkipSelf` decorator and metadata.
494 *
495 * @Annotation
496 * @publicApi
497 */
498 var SkipSelf = makeParamDecorator('SkipSelf');
499 /**
500 * Host decorator and metadata.
501 *
502 * @Annotation
503 * @publicApi
504 */
505 var Host = makeParamDecorator('Host');
506 var ɵ1 = function (attributeName) { return ({ attributeName: attributeName }); };
507 /**
508 * Attribute decorator and metadata.
509 *
510 * @Annotation
511 * @publicApi
512 */
513 var Attribute = makeParamDecorator('Attribute', ɵ1);
514
515 /**
516 * @license
517 * Copyright Google LLC All Rights Reserved.
518 *
519 * Use of this source code is governed by an MIT-style license that can be
520 * found in the LICENSE file at https://angular.io/license
521 */
522 (function (InjectFlags) {
523 // TODO(alxhub): make this 'const' when ngc no longer writes exports of it into ngfactory files.
524 /** Check self and check parent injector if needed */
525 InjectFlags[InjectFlags["Default"] = 0] = "Default";
526 /**
527 * Specifies that an injector should retrieve a dependency from any injector until reaching the
528 * host element of the current component. (Only used with Element Injector)
529 */
530 InjectFlags[InjectFlags["Host"] = 1] = "Host";
531 /** Don't ascend to ancestors of the node requesting injection. */
532 InjectFlags[InjectFlags["Self"] = 2] = "Self";
533 /** Skip the node that is requesting injection. */
534 InjectFlags[InjectFlags["SkipSelf"] = 4] = "SkipSelf";
535 /** Inject `defaultValue` instead if token not found. */
536 InjectFlags[InjectFlags["Optional"] = 8] = "Optional";
537 })(exports.InjectFlags || (exports.InjectFlags = {}));
538
539 /**
540 * @license
541 * Copyright Google LLC All Rights Reserved.
542 *
543 * Use of this source code is governed by an MIT-style license that can be
544 * found in the LICENSE file at https://angular.io/license
545 */
546 function getClosureSafeProperty(objWithPropertyToExtract) {
547 for (var key in objWithPropertyToExtract) {
548 if (objWithPropertyToExtract[key] === getClosureSafeProperty) {
549 return key;
550 }
551 }
552 throw Error('Could not find renamed property on target object.');
553 }
554 /**
555 * Sets properties on a target object from a source object, but only if
556 * the property doesn't already exist on the target object.
557 * @param target The target to set properties on
558 * @param source The source of the property keys and values to set
559 */
560 function fillProperties(target, source) {
561 for (var key in source) {
562 if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) {
563 target[key] = source[key];
564 }
565 }
566 }
567
568 /**
569 * @license
570 * Copyright Google LLC All Rights Reserved.
571 *
572 * Use of this source code is governed by an MIT-style license that can be
573 * found in the LICENSE file at https://angular.io/license
574 */
575 /**
576 * Construct an `InjectableDef` which defines how a token will be constructed by the DI system, and
577 * in which injectors (if any) it will be available.
578 *
579 * This should be assigned to a static `ɵprov` field on a type, which will then be an
580 * `InjectableType`.
581 *
582 * Options:
583 * * `providedIn` determines which injectors will include the injectable, by either associating it
584 * with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
585 * provided in the `'root'` injector, which will be the application-level injector in most apps.
586 * * `factory` gives the zero argument function which will create an instance of the injectable.
587 * The factory can call `inject` to access the `Injector` and request injection of dependencies.
588 *
589 * @codeGenApi
590 * @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm.
591 */
592 function ɵɵdefineInjectable(opts) {
593 return {
594 token: opts.token,
595 providedIn: opts.providedIn || null,
596 factory: opts.factory,
597 value: undefined,
598 };
599 }
600 /**
601 * @deprecated in v8, delete after v10. This API should be used only be generated code, and that
602 * code should now use ɵɵdefineInjectable instead.
603 * @publicApi
604 */
605 var defineInjectable = ɵɵdefineInjectable;
606 /**
607 * Construct an `InjectorDef` which configures an injector.
608 *
609 * This should be assigned to a static injector def (`ɵinj`) field on a type, which will then be an
610 * `InjectorType`.
611 *
612 * Options:
613 *
614 * * `factory`: an `InjectorType` is an instantiable type, so a zero argument `factory` function to
615 * create the type must be provided. If that factory function needs to inject arguments, it can
616 * use the `inject` function.
617 * * `providers`: an optional array of providers to add to the injector. Each provider must
618 * either have a factory or point to a type which has a `ɵprov` static property (the
619 * type must be an `InjectableType`).
620 * * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s
621 * whose providers will also be added to the injector. Locally provided types will override
622 * providers from imports.
623 *
624 * @codeGenApi
625 */
626 function ɵɵdefineInjector(options) {
627 return {
628 factory: options.factory,
629 providers: options.providers || [],
630 imports: options.imports || [],
631 };
632 }
633 /**
634 * Read the injectable def (`ɵprov`) for `type` in a way which is immune to accidentally reading
635 * inherited value.
636 *
637 * @param type A type which may have its own (non-inherited) `ɵprov`.
638 */
639 function getInjectableDef(type) {
640 return getOwnDefinition(type, type[NG_PROV_DEF]) ||
641 getOwnDefinition(type, type[NG_INJECTABLE_DEF]);
642 }
643 /**
644 * Return `def` only if it is defined directly on `type` and is not inherited from a base
645 * class of `type`.
646 *
647 * The function `Object.hasOwnProperty` is not sufficient to distinguish this case because in older
648 * browsers (e.g. IE10) static property inheritance is implemented by copying the properties.
649 *
650 * Instead, the definition's `token` is compared to the `type`, and if they don't match then the
651 * property was not defined directly on the type itself, and was likely inherited. The definition
652 * is only returned if the `type` matches the `def.token`.
653 */
654 function getOwnDefinition(type, def) {
655 return def && def.token === type ? def : null;
656 }
657 /**
658 * Read the injectable def (`ɵprov`) for `type` or read the `ɵprov` from one of its ancestors.
659 *
660 * @param type A type which may have `ɵprov`, via inheritance.
661 *
662 * @deprecated Will be removed in a future version of Angular, where an error will occur in the
663 * scenario if we find the `ɵprov` on an ancestor only.
664 */
665 function getInheritedInjectableDef(type) {
666 // See `jit/injectable.ts#compileInjectable` for context on NG_PROV_DEF_FALLBACK.
667 var def = type &&
668 (type[NG_PROV_DEF] || type[NG_INJECTABLE_DEF] ||
669 (type[NG_PROV_DEF_FALLBACK] && type[NG_PROV_DEF_FALLBACK]()));
670 if (def) {
671 var typeName = getTypeName(type);
672 // TODO(FW-1307): Re-add ngDevMode when closure can handle it
673 // ngDevMode &&
674 console.warn("DEPRECATED: DI is instantiating a token \"" + typeName + "\" that inherits its @Injectable decorator but does not provide one itself.\n" +
675 ("This will become an error in a future version of Angular. Please add @Injectable() to the \"" + typeName + "\" class."));
676 return def;
677 }
678 else {
679 return null;
680 }
681 }
682 /** Gets the name of a type, accounting for some cross-browser differences. */
683 function getTypeName(type) {
684 // `Function.prototype.name` behaves differently between IE and other browsers. In most browsers
685 // it'll always return the name of the function itself, no matter how many other functions it
686 // inherits from. On IE the function doesn't have its own `name` property, but it takes it from
687 // the lowest level in the prototype chain. E.g. if we have `class Foo extends Parent` most
688 // browsers will evaluate `Foo.name` to `Foo` while IE will return `Parent`. We work around
689 // the issue by converting the function to a string and parsing its name out that way via a regex.
690 if (type.hasOwnProperty('name')) {
691 return type.name;
692 }
693 var match = ('' + type).match(/^function\s*([^\s(]+)/);
694 return match === null ? '' : match[1];
695 }
696 /**
697 * Read the injector def type in a way which is immune to accidentally reading inherited value.
698 *
699 * @param type type which may have an injector def (`ɵinj`)
700 */
701 function getInjectorDef(type) {
702 return type && (type.hasOwnProperty(NG_INJ_DEF) || type.hasOwnProperty(NG_INJECTOR_DEF)) ?
703 type[NG_INJ_DEF] :
704 null;
705 }
706 var NG_PROV_DEF = getClosureSafeProperty({ ɵprov: getClosureSafeProperty });
707 var NG_INJ_DEF = getClosureSafeProperty({ ɵinj: getClosureSafeProperty });
708 // On IE10 properties defined via `defineProperty` won't be inherited by child classes,
709 // which will break inheriting the injectable definition from a grandparent through an
710 // undecorated parent class. We work around it by defining a fallback method which will be
711 // used to retrieve the definition. This should only be a problem in JIT mode, because in
712 // AOT TypeScript seems to have a workaround for static properties. When inheriting from an
713 // undecorated parent is no longer supported in v10, this can safely be removed.
714 var NG_PROV_DEF_FALLBACK = getClosureSafeProperty({ ɵprovFallback: getClosureSafeProperty });
715 // We need to keep these around so we can read off old defs if new defs are unavailable
716 var NG_INJECTABLE_DEF = getClosureSafeProperty({ ngInjectableDef: getClosureSafeProperty });
717 var NG_INJECTOR_DEF = getClosureSafeProperty({ ngInjectorDef: getClosureSafeProperty });
718
719 /**
720 * @license
721 * Copyright Google LLC All Rights Reserved.
722 *
723 * Use of this source code is governed by an MIT-style license that can be
724 * found in the LICENSE file at https://angular.io/license
725 */
726 function stringify(token) {
727 if (typeof token === 'string') {
728 return token;
729 }
730 if (Array.isArray(token)) {
731 return '[' + token.map(stringify).join(', ') + ']';
732 }
733 if (token == null) {
734 return '' + token;
735 }
736 if (token.overriddenName) {
737 return "" + token.overriddenName;
738 }
739 if (token.name) {
740 return "" + token.name;
741 }
742 var res = token.toString();
743 if (res == null) {
744 return '' + res;
745 }
746 var newLineIndex = res.indexOf('\n');
747 return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
748 }
749 /**
750 * Concatenates two strings with separator, allocating new strings only when necessary.
751 *
752 * @param before before string.
753 * @param separator separator string.
754 * @param after after string.
755 * @returns concatenated string.
756 */
757 function concatStringsWithSpace(before, after) {
758 return (before == null || before === '') ?
759 (after === null ? '' : after) :
760 ((after == null || after === '') ? before : before + ' ' + after);
761 }
762
763 /**
764 * @license
765 * Copyright Google LLC All Rights Reserved.
766 *
767 * Use of this source code is governed by an MIT-style license that can be
768 * found in the LICENSE file at https://angular.io/license
769 */
770 var __forward_ref__ = getClosureSafeProperty({ __forward_ref__: getClosureSafeProperty });
771 /**
772 * Allows to refer to references which are not yet defined.
773 *
774 * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
775 * DI is declared, but not yet defined. It is also used when the `token` which we use when creating
776 * a query is not yet defined.
777 *
778 * @usageNotes
779 * ### Example
780 * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
781 * @publicApi
782 */
783 function forwardRef(forwardRefFn) {
784 forwardRefFn.__forward_ref__ = forwardRef;
785 forwardRefFn.toString = function () {
786 return stringify(this());
787 };
788 return forwardRefFn;
789 }
790 /**
791 * Lazily retrieves the reference value from a forwardRef.
792 *
793 * Acts as the identity function when given a non-forward-ref value.
794 *
795 * @usageNotes
796 * ### Example
797 *
798 * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
799 *
800 * @see `forwardRef`
801 * @publicApi
802 */
803 function resolveForwardRef(type) {
804 return isForwardRef(type) ? type() : type;
805 }
806 /** Checks whether a function is wrapped by a `forwardRef`. */
807 function isForwardRef(fn) {
808 return typeof fn === 'function' && fn.hasOwnProperty(__forward_ref__) &&
809 fn.__forward_ref__ === forwardRef;
810 }
811
812 /**
813 * @license
814 * Copyright Google LLC All Rights Reserved.
815 *
816 * Use of this source code is governed by an MIT-style license that can be
817 * found in the LICENSE file at https://angular.io/license
818 */
819 var __globalThis = typeof globalThis !== 'undefined' && globalThis;
820 var __window = typeof window !== 'undefined' && window;
821 var __self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
822 self instanceof WorkerGlobalScope && self;
823 var __global = typeof global !== 'undefined' && global;
824 // Always use __globalThis if available, which is the spec-defined global variable across all
825 // environments, then fallback to __global first, because in Node tests both __global and
826 // __window may be defined and _global should be __global in that case.
827 var _global = __globalThis || __global || __window || __self;
828
829 /**
830 * @license
831 * Copyright Google LLC All Rights Reserved.
832 *
833 * Use of this source code is governed by an MIT-style license that can be
834 * found in the LICENSE file at https://angular.io/license
835 */
836 var R3ResolvedDependencyType;
837 (function (R3ResolvedDependencyType) {
838 R3ResolvedDependencyType[R3ResolvedDependencyType["Token"] = 0] = "Token";
839 R3ResolvedDependencyType[R3ResolvedDependencyType["Attribute"] = 1] = "Attribute";
840 R3ResolvedDependencyType[R3ResolvedDependencyType["ChangeDetectorRef"] = 2] = "ChangeDetectorRef";
841 R3ResolvedDependencyType[R3ResolvedDependencyType["Invalid"] = 3] = "Invalid";
842 })(R3ResolvedDependencyType || (R3ResolvedDependencyType = {}));
843 var R3FactoryTarget;
844 (function (R3FactoryTarget) {
845 R3FactoryTarget[R3FactoryTarget["Directive"] = 0] = "Directive";
846 R3FactoryTarget[R3FactoryTarget["Component"] = 1] = "Component";
847 R3FactoryTarget[R3FactoryTarget["Injectable"] = 2] = "Injectable";
848 R3FactoryTarget[R3FactoryTarget["Pipe"] = 3] = "Pipe";
849 R3FactoryTarget[R3FactoryTarget["NgModule"] = 4] = "NgModule";
850 })(R3FactoryTarget || (R3FactoryTarget = {}));
851 var ViewEncapsulation;
852 (function (ViewEncapsulation) {
853 ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
854 ViewEncapsulation[ViewEncapsulation["Native"] = 1] = "Native";
855 ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
856 ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
857 })(ViewEncapsulation || (ViewEncapsulation = {}));
858
859 /**
860 * @license
861 * Copyright Google LLC All Rights Reserved.
862 *
863 * Use of this source code is governed by an MIT-style license that can be
864 * found in the LICENSE file at https://angular.io/license
865 */
866 function getCompilerFacade() {
867 var globalNg = _global['ng'];
868 if (!globalNg || !globalNg.ɵcompilerFacade) {
869 throw new Error("Angular JIT compilation failed: '@angular/compiler' not loaded!\n" +
870 " - JIT compilation is discouraged for production use-cases! Consider AOT mode instead.\n" +
871 " - Did you bootstrap using '@angular/platform-browser-dynamic' or '@angular/platform-server'?\n" +
872 " - Alternatively provide the compiler with 'import \"@angular/compiler\";' before bootstrapping.");
873 }
874 return globalNg.ɵcompilerFacade;
875 }
876
877 /**
878 * @license
879 * Copyright Google LLC All Rights Reserved.
880 *
881 * Use of this source code is governed by an MIT-style license that can be
882 * found in the LICENSE file at https://angular.io/license
883 */
884 var NG_COMP_DEF = getClosureSafeProperty({ ɵcmp: getClosureSafeProperty });
885 var NG_DIR_DEF = getClosureSafeProperty({ ɵdir: getClosureSafeProperty });
886 var NG_PIPE_DEF = getClosureSafeProperty({ ɵpipe: getClosureSafeProperty });
887 var NG_MOD_DEF = getClosureSafeProperty({ ɵmod: getClosureSafeProperty });
888 var NG_LOC_ID_DEF = getClosureSafeProperty({ ɵloc: getClosureSafeProperty });
889 var NG_FACTORY_DEF = getClosureSafeProperty({ ɵfac: getClosureSafeProperty });
890 /**
891 * If a directive is diPublic, bloomAdd sets a property on the type with this constant as
892 * the key and the directive's unique ID as the value. This allows us to map directives to their
893 * bloom filter bit for DI.
894 */
895 // TODO(misko): This is wrong. The NG_ELEMENT_ID should never be minified.
896 var NG_ELEMENT_ID = getClosureSafeProperty({ __NG_ELEMENT_ID__: getClosureSafeProperty });
897
898 /**
899 * @license
900 * Copyright Google LLC All Rights Reserved.
901 *
902 * Use of this source code is governed by an MIT-style license that can be
903 * found in the LICENSE file at https://angular.io/license
904 */
905 function ngDevModeResetPerfCounters() {
906 var locationString = typeof location !== 'undefined' ? location.toString() : '';
907 var newCounters = {
908 namedConstructors: locationString.indexOf('ngDevMode=namedConstructors') != -1,
909 firstCreatePass: 0,
910 tNode: 0,
911 tView: 0,
912 rendererCreateTextNode: 0,
913 rendererSetText: 0,
914 rendererCreateElement: 0,
915 rendererAddEventListener: 0,
916 rendererSetAttribute: 0,
917 rendererRemoveAttribute: 0,
918 rendererSetProperty: 0,
919 rendererSetClassName: 0,
920 rendererAddClass: 0,
921 rendererRemoveClass: 0,
922 rendererSetStyle: 0,
923 rendererRemoveStyle: 0,
924 rendererDestroy: 0,
925 rendererDestroyNode: 0,
926 rendererMoveNode: 0,
927 rendererRemoveNode: 0,
928 rendererAppendChild: 0,
929 rendererInsertBefore: 0,
930 rendererCreateComment: 0,
931 };
932 // Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
933 var allowNgDevModeTrue = locationString.indexOf('ngDevMode=false') === -1;
934 _global['ngDevMode'] = allowNgDevModeTrue && newCounters;
935 return newCounters;
936 }
937 /**
938 * This function checks to see if the `ngDevMode` has been set. If yes,
939 * then we honor it, otherwise we default to dev mode with additional checks.
940 *
941 * The idea is that unless we are doing production build where we explicitly
942 * set `ngDevMode == false` we should be helping the developer by providing
943 * as much early warning and errors as possible.
944 *
945 * `ɵɵdefineComponent` is guaranteed to have been called before any component template functions
946 * (and thus Ivy instructions), so a single initialization there is sufficient to ensure ngDevMode
947 * is defined for the entire instruction set.
948 *
949 * When checking `ngDevMode` on toplevel, always init it before referencing it
950 * (e.g. `((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode())`), otherwise you can
951 * get a `ReferenceError` like in https://github.com/angular/angular/issues/31595.
952 *
953 * Details on possible values for `ngDevMode` can be found on its docstring.
954 *
955 * NOTE:
956 * - changes to the `ngDevMode` name must be synced with `compiler-cli/src/tooling.ts`.
957 */
958 function initNgDevMode() {
959 // The below checks are to ensure that calling `initNgDevMode` multiple times does not
960 // reset the counters.
961 // If the `ngDevMode` is not an object, then it means we have not created the perf counters
962 // yet.
963 if (typeof ngDevMode === 'undefined' || ngDevMode) {
964 if (typeof ngDevMode !== 'object') {
965 ngDevModeResetPerfCounters();
966 }
967 return !!ngDevMode;
968 }
969 return false;
970 }
971
972 /**
973 * @license
974 * Copyright Google LLC All Rights Reserved.
975 *
976 * Use of this source code is governed by an MIT-style license that can be
977 * found in the LICENSE file at https://angular.io/license
978 */
979 /**
980 * Creates a token that can be used in a DI Provider.
981 *
982 * Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
983 * runtime representation) such as when injecting an interface, callable type, array or
984 * parameterized type.
985 *
986 * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
987 * the `Injector`. This provides additional level of type safety.
988 *
989 * ```
990 * interface MyInterface {...}
991 * var myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
992 * // myInterface is inferred to be MyInterface.
993 * ```
994 *
995 * When creating an `InjectionToken`, you can optionally specify a factory function which returns
996 * (possibly by creating) a default value of the parameterized type `T`. This sets up the
997 * `InjectionToken` using this factory as a provider as if it was defined explicitly in the
998 * application's root injector. If the factory function, which takes zero arguments, needs to inject
999 * dependencies, it can do so using the `inject` function. See below for an example.
1000 *
1001 * Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
1002 * overrides the above behavior and marks the token as belonging to a particular `@NgModule`. As
1003 * mentioned above, `'root'` is the default value for `providedIn`.
1004 *
1005 * @usageNotes
1006 * ### Basic Example
1007 *
1008 * ### Plain InjectionToken
1009 *
1010 * {@example core/di/ts/injector_spec.ts region='InjectionToken'}
1011 *
1012 * ### Tree-shakable InjectionToken
1013 *
1014 * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
1015 *
1016 *
1017 * @publicApi
1018 */
1019 var InjectionToken = /** @class */ (function () {
1020 function InjectionToken(_desc, options) {
1021 this._desc = _desc;
1022 /** @internal */
1023 this.ngMetadataName = 'InjectionToken';
1024 this.ɵprov = undefined;
1025 if (typeof options == 'number') {
1026 // This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
1027 // __NG_ELEMENT_ID__ is Used by Ivy to determine bloom filter id.
1028 // We are using it to assign `-1` which is used to identify `Injector`.
1029 this.__NG_ELEMENT_ID__ = options;
1030 }
1031 else if (options !== undefined) {
1032 this.ɵprov = ɵɵdefineInjectable({
1033 token: this,
1034 providedIn: options.providedIn || 'root',
1035 factory: options.factory,
1036 });
1037 }
1038 }
1039 InjectionToken.prototype.toString = function () {
1040 return "InjectionToken " + this._desc;
1041 };
1042 return InjectionToken;
1043 }());
1044
1045 /**
1046 * @license
1047 * Copyright Google LLC All Rights Reserved.
1048 *
1049 * Use of this source code is governed by an MIT-style license that can be
1050 * found in the LICENSE file at https://angular.io/license
1051 */
1052 /**
1053 * An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.
1054 *
1055 * Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
1056 * project.
1057 *
1058 * @publicApi
1059 */
1060 var INJECTOR = new InjectionToken('INJECTOR', -1 // `-1` is used by Ivy DI system as special value to recognize it as `Injector`.
1061 );
1062 var _THROW_IF_NOT_FOUND = {};
1063 var THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
1064 var NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
1065 var NG_TOKEN_PATH = 'ngTokenPath';
1066 var NEW_LINE = /\n/gm;
1067 var NO_NEW_LINE = 'ɵ';
1068 var SOURCE = '__source';
1069 var ɵ0$1 = getClosureSafeProperty;
1070 var USE_VALUE = getClosureSafeProperty({ provide: String, useValue: ɵ0$1 });
1071 /**
1072 * Current injector value used by `inject`.
1073 * - `undefined`: it is an error to call `inject`
1074 * - `null`: `inject` can be called but there is no injector (limp-mode).
1075 * - Injector instance: Use the injector for resolution.
1076 */
1077 var _currentInjector = undefined;
1078 function setCurrentInjector(injector) {
1079 var former = _currentInjector;
1080 _currentInjector = injector;
1081 return former;
1082 }
1083 /**
1084 * Current implementation of inject.
1085 *
1086 * By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
1087 * to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
1088 * way for two reasons:
1089 * 1. `Injector` should not depend on ivy logic.
1090 * 2. To maintain tree shake-ability we don't want to bring in unnecessary code.
1091 */
1092 var _injectImplementation;
1093 /**
1094 * Sets the current inject implementation.
1095 */
1096 function setInjectImplementation(impl) {
1097 var previous = _injectImplementation;
1098 _injectImplementation = impl;
1099 return previous;
1100 }
1101 function injectInjectorOnly(token, flags) {
1102 if (flags === void 0) { flags = exports.InjectFlags.Default; }
1103 if (_currentInjector === undefined) {
1104 throw new Error("inject() must be called from an injection context");
1105 }
1106 else if (_currentInjector === null) {
1107 return injectRootLimpMode(token, undefined, flags);
1108 }
1109 else {
1110 return _currentInjector.get(token, flags & exports.InjectFlags.Optional ? null : undefined, flags);
1111 }
1112 }
1113 function ɵɵinject(token, flags) {
1114 if (flags === void 0) { flags = exports.InjectFlags.Default; }
1115 return (_injectImplementation || injectInjectorOnly)(resolveForwardRef(token), flags);
1116 }
1117 /**
1118 * Throws an error indicating that a factory function could not be generated by the compiler for a
1119 * particular class.
1120 *
1121 * This instruction allows the actual error message to be optimized away when ngDevMode is turned
1122 * off, saving bytes of generated code while still providing a good experience in dev mode.
1123 *
1124 * The name of the class is not mentioned here, but will be in the generated factory function name
1125 * and thus in the stack trace.
1126 *
1127 * @codeGenApi
1128 */
1129 function ɵɵinvalidFactoryDep(index) {
1130 var msg = ngDevMode ?
1131 "This constructor is not compatible with Angular Dependency Injection because its dependency at index " + index + " of the parameter list is invalid.\nThis can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.\n\nPlease 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." :
1132 'invalid';
1133 throw new Error(msg);
1134 }
1135 /**
1136 * Injects a token from the currently active injector.
1137 *
1138 * Must be used in the context of a factory function such as one defined for an
1139 * `InjectionToken`. Throws an error if not called from such a context.
1140 *
1141 * Within such a factory function, using this function to request injection of a dependency
1142 * is faster and more type-safe than providing an additional array of dependencies
1143 * (as has been common with `useFactory` providers).
1144 *
1145 * @param token The injection token for the dependency to be injected.
1146 * @param flags Optional flags that control how injection is executed.
1147 * The flags correspond to injection strategies that can be specified with
1148 * parameter decorators `@Host`, `@Self`, `@SkipSef`, and `@Optional`.
1149 * @returns True if injection is successful, null otherwise.
1150 *
1151 * @usageNotes
1152 *
1153 * ### Example
1154 *
1155 * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
1156 *
1157 * @publicApi
1158 */
1159 var inject = ɵɵinject;
1160 /**
1161 * Injects `root` tokens in limp mode.
1162 *
1163 * If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
1164 * `"root"`. This is known as the limp mode injection. In such case the value is stored in the
1165 * `InjectableDef`.
1166 */
1167 function injectRootLimpMode(token, notFoundValue, flags) {
1168 var injectableDef = getInjectableDef(token);
1169 if (injectableDef && injectableDef.providedIn == 'root') {
1170 return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
1171 injectableDef.value;
1172 }
1173 if (flags & exports.InjectFlags.Optional)
1174 return null;
1175 if (notFoundValue !== undefined)
1176 return notFoundValue;
1177 throw new Error("Injector: NOT_FOUND [" + stringify(token) + "]");
1178 }
1179 function injectArgs(types) {
1180 var args = [];
1181 for (var i = 0; i < types.length; i++) {
1182 var arg = resolveForwardRef(types[i]);
1183 if (Array.isArray(arg)) {
1184 if (arg.length === 0) {
1185 throw new Error('Arguments array must have arguments.');
1186 }
1187 var type = undefined;
1188 var flags = exports.InjectFlags.Default;
1189 for (var j = 0; j < arg.length; j++) {
1190 var meta = arg[j];
1191 if (meta instanceof Optional || meta.ngMetadataName === 'Optional' || meta === Optional) {
1192 flags |= exports.InjectFlags.Optional;
1193 }
1194 else if (meta instanceof SkipSelf || meta.ngMetadataName === 'SkipSelf' || meta === SkipSelf) {
1195 flags |= exports.InjectFlags.SkipSelf;
1196 }
1197 else if (meta instanceof Self || meta.ngMetadataName === 'Self' || meta === Self) {
1198 flags |= exports.InjectFlags.Self;
1199 }
1200 else if (meta instanceof Inject || meta === Inject) {
1201 type = meta.token;
1202 }
1203 else {
1204 type = meta;
1205 }
1206 }
1207 args.push(ɵɵinject(type, flags));
1208 }
1209 else {
1210 args.push(ɵɵinject(arg));
1211 }
1212 }
1213 return args;
1214 }
1215 var NullInjector = /** @class */ (function () {
1216 function NullInjector() {
1217 }
1218 NullInjector.prototype.get = function (token, notFoundValue) {
1219 if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
1220 if (notFoundValue === THROW_IF_NOT_FOUND) {
1221 // Intentionally left behind: With dev tools open the debugger will stop here. There is no
1222 // reason why correctly written application should cause this exception.
1223 // TODO(misko): uncomment the next line once `ngDevMode` works with closure.
1224 // if (ngDevMode) debugger;
1225 var error = new Error("NullInjectorError: No provider for " + stringify(token) + "!");
1226 error.name = 'NullInjectorError';
1227 throw error;
1228 }
1229 return notFoundValue;
1230 };
1231 return NullInjector;
1232 }());
1233 function catchInjectorError(e, token, injectorErrorName, source) {
1234 var tokenPath = e[NG_TEMP_TOKEN_PATH];
1235 if (token[SOURCE]) {
1236 tokenPath.unshift(token[SOURCE]);
1237 }
1238 e.message = formatError('\n' + e.message, tokenPath, injectorErrorName, source);
1239 e[NG_TOKEN_PATH] = tokenPath;
1240 e[NG_TEMP_TOKEN_PATH] = null;
1241 throw e;
1242 }
1243 function formatError(text, obj, injectorErrorName, source) {
1244 if (source === void 0) { source = null; }
1245 text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.substr(2) : text;
1246 var context = stringify(obj);
1247 if (Array.isArray(obj)) {
1248 context = obj.map(stringify).join(' -> ');
1249 }
1250 else if (typeof obj === 'object') {
1251 var parts = [];
1252 for (var key in obj) {
1253 if (obj.hasOwnProperty(key)) {
1254 var value = obj[key];
1255 parts.push(key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));
1256 }
1257 }
1258 context = "{" + parts.join(', ') + "}";
1259 }
1260 return "" + injectorErrorName + (source ? '(' + source + ')' : '') + "[" + context + "]: " + text.replace(NEW_LINE, '\n ');
1261 }
1262
1263 /**
1264 * @license
1265 * Copyright Google LLC All Rights Reserved.
1266 *
1267 * Use of this source code is governed by an MIT-style license that can be
1268 * found in the LICENSE file at https://angular.io/license
1269 */
1270 /**
1271 * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
1272 *
1273 * This should be kept up to date with the public exports of @angular/core.
1274 */
1275 var angularCoreDiEnv = {
1276 'ɵɵdefineInjectable': ɵɵdefineInjectable,
1277 'ɵɵdefineInjector': ɵɵdefineInjector,
1278 'ɵɵinject': ɵɵinject,
1279 'ɵɵgetFactoryOf': getFactoryOf,
1280 'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
1281 };
1282 function getFactoryOf(type) {
1283 var typeAny = type;
1284 if (isForwardRef(type)) {
1285 return (function () {
1286 var factory = getFactoryOf(resolveForwardRef(typeAny));
1287 return factory ? factory() : null;
1288 });
1289 }
1290 var def = getInjectableDef(typeAny) || getInjectorDef(typeAny);
1291 if (!def || def.factory === undefined) {
1292 return null;
1293 }
1294 return def.factory;
1295 }
1296
1297 /**
1298 * @license
1299 * Copyright Google LLC All Rights Reserved.
1300 *
1301 * Use of this source code is governed by an MIT-style license that can be
1302 * found in the LICENSE file at https://angular.io/license
1303 */
1304 /**
1305 * Represents an instance of an `NgModule` created by an `NgModuleFactory`.
1306 * Provides access to the `NgModule` instance and related objects.
1307 *
1308 * @publicApi
1309 */
1310 var NgModuleRef = /** @class */ (function () {
1311 function NgModuleRef() {
1312 }
1313 return NgModuleRef;
1314 }());
1315 /**
1316 * @publicApi
1317 */
1318 var NgModuleFactory = /** @class */ (function () {
1319 function NgModuleFactory() {
1320 }
1321 return NgModuleFactory;
1322 }());
1323
1324 /**
1325 * @license
1326 * Copyright Google LLC All Rights Reserved.
1327 *
1328 * Use of this source code is governed by an MIT-style license that can be
1329 * found in the LICENSE file at https://angular.io/license
1330 */
1331 function assertNumber(actual, msg) {
1332 if (!(typeof actual === 'number')) {
1333 throwError(msg, typeof actual, 'number', '===');
1334 }
1335 }
1336 function assertNumberInRange(actual, minInclusive, maxInclusive) {
1337 assertNumber(actual, 'Expected a number');
1338 assertLessThanOrEqual(actual, maxInclusive, 'Expected number to be less than or equal to');
1339 assertGreaterThanOrEqual(actual, minInclusive, 'Expected number to be greater than or equal to');
1340 }
1341 function assertString(actual, msg) {
1342 if (!(typeof actual === 'string')) {
1343 throwError(msg, actual === null ? 'null' : typeof actual, 'string', '===');
1344 }
1345 }
1346 function assertEqual(actual, expected, msg) {
1347 if (!(actual == expected)) {
1348 throwError(msg, actual, expected, '==');
1349 }
1350 }
1351 function assertNotEqual(actual, expected, msg) {
1352 if (!(actual != expected)) {
1353 throwError(msg, actual, expected, '!=');
1354 }
1355 }
1356 function assertSame(actual, expected, msg) {
1357 if (!(actual === expected)) {
1358 throwError(msg, actual, expected, '===');
1359 }
1360 }
1361 function assertNotSame(actual, expected, msg) {
1362 if (!(actual !== expected)) {
1363 throwError(msg, actual, expected, '!==');
1364 }
1365 }
1366 function assertLessThan(actual, expected, msg) {
1367 if (!(actual < expected)) {
1368 throwError(msg, actual, expected, '<');
1369 }
1370 }
1371 function assertLessThanOrEqual(actual, expected, msg) {
1372 if (!(actual <= expected)) {
1373 throwError(msg, actual, expected, '<=');
1374 }
1375 }
1376 function assertGreaterThan(actual, expected, msg) {
1377 if (!(actual > expected)) {
1378 throwError(msg, actual, expected, '>');
1379 }
1380 }
1381 function assertGreaterThanOrEqual(actual, expected, msg) {
1382 if (!(actual >= expected)) {
1383 throwError(msg, actual, expected, '>=');
1384 }
1385 }
1386 function assertNotDefined(actual, msg) {
1387 if (actual != null) {
1388 throwError(msg, actual, null, '==');
1389 }
1390 }
1391 function assertDefined(actual, msg) {
1392 if (actual == null) {
1393 throwError(msg, actual, null, '!=');
1394 }
1395 }
1396 function throwError(msg, actual, expected, comparison) {
1397 throw new Error("ASSERTION ERROR: " + msg +
1398 (comparison == null ? '' : " [Expected=> " + expected + " " + comparison + " " + actual + " <=Actual]"));
1399 }
1400 function assertDomNode(node) {
1401 // If we're in a worker, `Node` will not be defined.
1402 assertEqual((typeof Node !== 'undefined' && node instanceof Node) ||
1403 (typeof node === 'object' && node != null &&
1404 node.constructor.name === 'WebWorkerRenderNode'), true, "The provided value must be an instance of a DOM Node but got " + stringify(node));
1405 }
1406 function assertIndexInRange(arr, index) {
1407 var maxLen = arr ? arr.length : 0;
1408 assertLessThan(index, maxLen, "Index expected to be less than " + maxLen + " but got " + index);
1409 }
1410
1411 /**
1412 * @license
1413 * Copyright Google LLC All Rights Reserved.
1414 *
1415 * Use of this source code is governed by an MIT-style license that can be
1416 * found in the LICENSE file at https://angular.io/license
1417 */
1418 /**
1419 * Equivalent to ES6 spread, add each item to an array.
1420 *
1421 * @param items The items to add
1422 * @param arr The array to which you want to add the items
1423 */
1424 function addAllToArray(items, arr) {
1425 for (var i = 0; i < items.length; i++) {
1426 arr.push(items[i]);
1427 }
1428 }
1429 /**
1430 * Flattens an array.
1431 */
1432 function flatten(list, dst) {
1433 if (dst === undefined)
1434 dst = list;
1435 for (var i = 0; i < list.length; i++) {
1436 var item = list[i];
1437 if (Array.isArray(item)) {
1438 // we need to inline it.
1439 if (dst === list) {
1440 // Our assumption that the list was already flat was wrong and
1441 // we need to clone flat since we need to write to it.
1442 dst = list.slice(0, i);
1443 }
1444 flatten(item, dst);
1445 }
1446 else if (dst !== list) {
1447 dst.push(item);
1448 }
1449 }
1450 return dst;
1451 }
1452 function deepForEach(input, fn) {
1453 input.forEach(function (value) { return Array.isArray(value) ? deepForEach(value, fn) : fn(value); });
1454 }
1455 function addToArray(arr, index, value) {
1456 // perf: array.push is faster than array.splice!
1457 if (index >= arr.length) {
1458 arr.push(value);
1459 }
1460 else {
1461 arr.splice(index, 0, value);
1462 }
1463 }
1464 function removeFromArray(arr, index) {
1465 // perf: array.pop is faster than array.splice!
1466 if (index >= arr.length - 1) {
1467 return arr.pop();
1468 }
1469 else {
1470 return arr.splice(index, 1)[0];
1471 }
1472 }
1473 function newArray(size, value) {
1474 var list = [];
1475 for (var i = 0; i < size; i++) {
1476 list.push(value);
1477 }
1478 return list;
1479 }
1480 /**
1481 * Remove item from array (Same as `Array.splice()` but faster.)
1482 *
1483 * `Array.splice()` is not as fast because it has to allocate an array for the elements which were
1484 * removed. This causes memory pressure and slows down code when most of the time we don't
1485 * care about the deleted items array.
1486 *
1487 * https://jsperf.com/fast-array-splice (About 20x faster)
1488 *
1489 * @param array Array to splice
1490 * @param index Index of element in array to remove.
1491 * @param count Number of items to remove.
1492 */
1493 function arraySplice(array, index, count) {
1494 var length = array.length - count;
1495 while (index < length) {
1496 array[index] = array[index + count];
1497 index++;
1498 }
1499 while (count--) {
1500 array.pop(); // shrink the array
1501 }
1502 }
1503 /**
1504 * Same as `Array.splice(index, 0, value)` but faster.
1505 *
1506 * `Array.splice()` is not fast because it has to allocate an array for the elements which were
1507 * removed. This causes memory pressure and slows down code when most of the time we don't
1508 * care about the deleted items array.
1509 *
1510 * @param array Array to splice.
1511 * @param index Index in array where the `value` should be added.
1512 * @param value Value to add to array.
1513 */
1514 function arrayInsert(array, index, value) {
1515 ngDevMode && assertLessThanOrEqual(index, array.length, 'Can\'t insert past array end.');
1516 var end = array.length;
1517 while (end > index) {
1518 var previousEnd = end - 1;
1519 array[end] = array[previousEnd];
1520 end = previousEnd;
1521 }
1522 array[index] = value;
1523 }
1524 /**
1525 * Same as `Array.splice2(index, 0, value1, value2)` but faster.
1526 *
1527 * `Array.splice()` is not fast because it has to allocate an array for the elements which were
1528 * removed. This causes memory pressure and slows down code when most of the time we don't
1529 * care about the deleted items array.
1530 *
1531 * @param array Array to splice.
1532 * @param index Index in array where the `value` should be added.
1533 * @param value1 Value to add to array.
1534 * @param value2 Value to add to array.
1535 */
1536 function arrayInsert2(array, index, value1, value2) {
1537 ngDevMode && assertLessThanOrEqual(index, array.length, 'Can\'t insert past array end.');
1538 var end = array.length;
1539 if (end == index) {
1540 // inserting at the end.
1541 array.push(value1, value2);
1542 }
1543 else if (end === 1) {
1544 // corner case when we have less items in array than we have items to insert.
1545 array.push(value2, array[0]);
1546 array[0] = value1;
1547 }
1548 else {
1549 end--;
1550 array.push(array[end - 1], array[end]);
1551 while (end > index) {
1552 var previousEnd = end - 2;
1553 array[end] = array[previousEnd];
1554 end--;
1555 }
1556 array[index] = value1;
1557 array[index + 1] = value2;
1558 }
1559 }
1560 /**
1561 * Insert a `value` into an `array` so that the array remains sorted.
1562 *
1563 * NOTE:
1564 * - Duplicates are not allowed, and are ignored.
1565 * - This uses binary search algorithm for fast inserts.
1566 *
1567 * @param array A sorted array to insert into.
1568 * @param value The value to insert.
1569 * @returns index of the inserted value.
1570 */
1571 function arrayInsertSorted(array, value) {
1572 var index = arrayIndexOfSorted(array, value);
1573 if (index < 0) {
1574 // if we did not find it insert it.
1575 index = ~index;
1576 arrayInsert(array, index, value);
1577 }
1578 return index;
1579 }
1580 /**
1581 * Remove `value` from a sorted `array`.
1582 *
1583 * NOTE:
1584 * - This uses binary search algorithm for fast removals.
1585 *
1586 * @param array A sorted array to remove from.
1587 * @param value The value to remove.
1588 * @returns index of the removed value.
1589 * - positive index if value found and removed.
1590 * - negative index if value not found. (`~index` to get the value where it should have been
1591 * inserted)
1592 */
1593 function arrayRemoveSorted(array, value) {
1594 var index = arrayIndexOfSorted(array, value);
1595 if (index >= 0) {
1596 arraySplice(array, index, 1);
1597 }
1598 return index;
1599 }
1600 /**
1601 * Get an index of an `value` in a sorted `array`.
1602 *
1603 * NOTE:
1604 * - This uses binary search algorithm for fast removals.
1605 *
1606 * @param array A sorted array to binary search.
1607 * @param value The value to look for.
1608 * @returns index of the value.
1609 * - positive index if value found.
1610 * - negative index if value not found. (`~index` to get the value where it should have been
1611 * located)
1612 */
1613 function arrayIndexOfSorted(array, value) {
1614 return _arrayIndexOfSorted(array, value, 0);
1615 }
1616 /**
1617 * Set a `value` for a `key`.
1618 *
1619 * @param keyValueArray to modify.
1620 * @param key The key to locate or create.
1621 * @param value The value to set for a `key`.
1622 * @returns index (always even) of where the value vas set.
1623 */
1624 function keyValueArraySet(keyValueArray, key, value) {
1625 var index = keyValueArrayIndexOf(keyValueArray, key);
1626 if (index >= 0) {
1627 // if we found it set it.
1628 keyValueArray[index | 1] = value;
1629 }
1630 else {
1631 index = ~index;
1632 arrayInsert2(keyValueArray, index, key, value);
1633 }
1634 return index;
1635 }
1636 /**
1637 * Retrieve a `value` for a `key` (on `undefined` if not found.)
1638 *
1639 * @param keyValueArray to search.
1640 * @param key The key to locate.
1641 * @return The `value` stored at the `key` location or `undefined if not found.
1642 */
1643 function keyValueArrayGet(keyValueArray, key) {
1644 var index = keyValueArrayIndexOf(keyValueArray, key);
1645 if (index >= 0) {
1646 // if we found it retrieve it.
1647 return keyValueArray[index | 1];
1648 }
1649 return undefined;
1650 }
1651 /**
1652 * Retrieve a `key` index value in the array or `-1` if not found.
1653 *
1654 * @param keyValueArray to search.
1655 * @param key The key to locate.
1656 * @returns index of where the key is (or should have been.)
1657 * - positive (even) index if key found.
1658 * - negative index if key not found. (`~index` (even) to get the index where it should have
1659 * been inserted.)
1660 */
1661 function keyValueArrayIndexOf(keyValueArray, key) {
1662 return _arrayIndexOfSorted(keyValueArray, key, 1);
1663 }
1664 /**
1665 * Delete a `key` (and `value`) from the `KeyValueArray`.
1666 *
1667 * @param keyValueArray to modify.
1668 * @param key The key to locate or delete (if exist).
1669 * @returns index of where the key was (or should have been.)
1670 * - positive (even) index if key found and deleted.
1671 * - negative index if key not found. (`~index` (even) to get the index where it should have
1672 * been.)
1673 */
1674 function keyValueArrayDelete(keyValueArray, key) {
1675 var index = keyValueArrayIndexOf(keyValueArray, key);
1676 if (index >= 0) {
1677 // if we found it remove it.
1678 arraySplice(keyValueArray, index, 2);
1679 }
1680 return index;
1681 }
1682 /**
1683 * INTERNAL: Get an index of an `value` in a sorted `array` by grouping search by `shift`.
1684 *
1685 * NOTE:
1686 * - This uses binary search algorithm for fast removals.
1687 *
1688 * @param array A sorted array to binary search.
1689 * @param value The value to look for.
1690 * @param shift grouping shift.
1691 * - `0` means look at every location
1692 * - `1` means only look at every other (even) location (the odd locations are to be ignored as
1693 * they are values.)
1694 * @returns index of the value.
1695 * - positive index if value found.
1696 * - negative index if value not found. (`~index` to get the value where it should have been
1697 * inserted)
1698 */
1699 function _arrayIndexOfSorted(array, value, shift) {
1700 ngDevMode && assertEqual(Array.isArray(array), true, 'Expecting an array');
1701 var start = 0;
1702 var end = array.length >> shift;
1703 while (end !== start) {
1704 var middle = start + ((end - start) >> 1); // find the middle.
1705 var current = array[middle << shift];
1706 if (value === current) {
1707 return (middle << shift);
1708 }
1709 else if (current > value) {
1710 end = middle;
1711 }
1712 else {
1713 start = middle + 1; // We already searched middle so make it non-inclusive by adding 1
1714 }
1715 }
1716 return ~(end << shift);
1717 }
1718
1719 /**
1720 * @license
1721 * Copyright Google LLC All Rights Reserved.
1722 *
1723 * Use of this source code is governed by an MIT-style license that can be
1724 * found in the LICENSE file at https://angular.io/license
1725 */
1726 (function (ChangeDetectionStrategy) {
1727 /**
1728 * Use the `CheckOnce` strategy, meaning that automatic change detection is deactivated
1729 * until reactivated by setting the strategy to `Default` (`CheckAlways`).
1730 * Change detection can still be explicitly invoked.
1731 * This strategy applies to all child directives and cannot be overridden.
1732 */
1733 ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
1734 /**
1735 * Use the default `CheckAlways` strategy, in which change detection is automatic until
1736 * explicitly deactivated.
1737 */
1738 ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
1739 })(exports.ChangeDetectionStrategy || (exports.ChangeDetectionStrategy = {}));
1740 (function (ChangeDetectorStatus) {
1741 /**
1742 * A state in which, after calling `detectChanges()`, the change detector
1743 * state becomes `Checked`, and must be explicitly invoked or reactivated.
1744 */
1745 ChangeDetectorStatus[ChangeDetectorStatus["CheckOnce"] = 0] = "CheckOnce";
1746 /**
1747 * A state in which change detection is skipped until the change detector mode
1748 * becomes `CheckOnce`.
1749 */
1750 ChangeDetectorStatus[ChangeDetectorStatus["Checked"] = 1] = "Checked";
1751 /**
1752 * A state in which change detection continues automatically until explicitly
1753 * deactivated.
1754 */
1755 ChangeDetectorStatus[ChangeDetectorStatus["CheckAlways"] = 2] = "CheckAlways";
1756 /**
1757 * A state in which a change detector sub tree is not a part of the main tree and
1758 * should be skipped.
1759 */
1760 ChangeDetectorStatus[ChangeDetectorStatus["Detached"] = 3] = "Detached";
1761 /**
1762 * Indicates that the change detector encountered an error checking a binding
1763 * or calling a directive lifecycle method and is now in an inconsistent state. Change
1764 * detectors in this state do not detect changes.
1765 */
1766 ChangeDetectorStatus[ChangeDetectorStatus["Errored"] = 4] = "Errored";
1767 /**
1768 * Indicates that the change detector has been destroyed.
1769 */
1770 ChangeDetectorStatus[ChangeDetectorStatus["Destroyed"] = 5] = "Destroyed";
1771 })(exports.ɵChangeDetectorStatus || (exports.ɵChangeDetectorStatus = {}));
1772 /**
1773 * Reports whether a given strategy is currently the default for change detection.
1774 * @param changeDetectionStrategy The strategy to check.
1775 * @returns True if the given strategy is the current default, false otherwise.
1776 * @see `ChangeDetectorStatus`
1777 * @see `ChangeDetectorRef`
1778 */
1779 function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
1780 return changeDetectionStrategy == null ||
1781 changeDetectionStrategy === exports.ChangeDetectionStrategy.Default;
1782 }
1783
1784 /**
1785 * @license
1786 * Copyright Google LLC All Rights Reserved.
1787 *
1788 * Use of this source code is governed by an MIT-style license that can be
1789 * found in the LICENSE file at https://angular.io/license
1790 */
1791 (function (ViewEncapsulation) {
1792 /**
1793 * Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
1794 * Element and pre-processing the style rules provided via {@link Component#styles styles} or
1795 * {@link Component#styleUrls styleUrls}, and adding the new Host Element attribute to all
1796 * selectors.
1797 *
1798 * This is the default option.
1799 */
1800 ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
1801 /**
1802 * @deprecated v6.1.0 - use {ViewEncapsulation.ShadowDom} instead.
1803 * Use the native encapsulation mechanism of the renderer.
1804 *
1805 * For the DOM this means using the deprecated [Shadow DOM
1806 * v0](https://w3c.github.io/webcomponents/spec/shadow/) and
1807 * creating a ShadowRoot for Component's Host Element.
1808 */
1809 ViewEncapsulation[ViewEncapsulation["Native"] = 1] = "Native";
1810 /**
1811 * Don't provide any template or style encapsulation.
1812 */
1813 ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
1814 /**
1815 * Use Shadow DOM to encapsulate styles.
1816 *
1817 * For the DOM this means using modern [Shadow
1818 * DOM](https://w3c.github.io/webcomponents/spec/shadow/) and
1819 * creating a ShadowRoot for Component's Host Element.
1820 */
1821 ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
1822 })(exports.ViewEncapsulation || (exports.ViewEncapsulation = {}));
1823
1824 /**
1825 * @license
1826 * Copyright Google LLC All Rights Reserved.
1827 *
1828 * Use of this source code is governed by an MIT-style license that can be
1829 * found in the LICENSE file at https://angular.io/license
1830 */
1831 /**
1832 * This file contains reuseable "empty" symbols that can be used as default return values
1833 * in different parts of the rendering code. Because the same symbols are returned, this
1834 * allows for identity checks against these values to be consistently used by the framework
1835 * code.
1836 */
1837 var EMPTY_OBJ = {};
1838 var EMPTY_ARRAY = [];
1839 // freezing the values prevents any code from accidentally inserting new values in
1840 if ((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode()) {
1841 // These property accesses can be ignored because ngDevMode will be set to false
1842 // when optimizing code and the whole if statement will be dropped.
1843 // tslint:disable-next-line:no-toplevel-property-access
1844 Object.freeze(EMPTY_OBJ);
1845 // tslint:disable-next-line:no-toplevel-property-access
1846 Object.freeze(EMPTY_ARRAY);
1847 }
1848
1849 /**
1850 * @license
1851 * Copyright Google LLC All Rights Reserved.
1852 *
1853 * Use of this source code is governed by an MIT-style license that can be
1854 * found in the LICENSE file at https://angular.io/license
1855 */
1856 var _renderCompCount = 0;
1857 /**
1858 * Create a component definition object.
1859 *
1860 *
1861 * # Example
1862 * ```
1863 * class MyDirective {
1864 * // Generated by Angular Template Compiler
1865 * // [Symbol] syntax will not be supported by TypeScript until v2.7
1866 * static ɵcmp = defineComponent({
1867 * ...
1868 * });
1869 * }
1870 * ```
1871 * @codeGenApi
1872 */
1873 function ɵɵdefineComponent(componentDefinition) {
1874 return noSideEffects(function () {
1875 // Initialize ngDevMode. This must be the first statement in ɵɵdefineComponent.
1876 // See the `initNgDevMode` docstring for more information.
1877 (typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode();
1878 var type = componentDefinition.type;
1879 var typePrototype = type.prototype;
1880 var declaredInputs = {};
1881 var def = {
1882 type: type,
1883 providersResolver: null,
1884 decls: componentDefinition.decls,
1885 vars: componentDefinition.vars,
1886 factory: null,
1887 template: componentDefinition.template || null,
1888 consts: componentDefinition.consts || null,
1889 ngContentSelectors: componentDefinition.ngContentSelectors,
1890 hostBindings: componentDefinition.hostBindings || null,
1891 hostVars: componentDefinition.hostVars || 0,
1892 hostAttrs: componentDefinition.hostAttrs || null,
1893 contentQueries: componentDefinition.contentQueries || null,
1894 declaredInputs: declaredInputs,
1895 inputs: null,
1896 outputs: null,
1897 exportAs: componentDefinition.exportAs || null,
1898 onPush: componentDefinition.changeDetection === exports.ChangeDetectionStrategy.OnPush,
1899 directiveDefs: null,
1900 pipeDefs: null,
1901 selectors: componentDefinition.selectors || EMPTY_ARRAY,
1902 viewQuery: componentDefinition.viewQuery || null,
1903 features: componentDefinition.features || null,
1904 data: componentDefinition.data || {},
1905 // TODO(misko): convert ViewEncapsulation into const enum so that it can be used
1906 // directly in the next line. Also `None` should be 0 not 2.
1907 encapsulation: componentDefinition.encapsulation || exports.ViewEncapsulation.Emulated,
1908 id: 'c',
1909 styles: componentDefinition.styles || EMPTY_ARRAY,
1910 _: null,
1911 setInput: null,
1912 schemas: componentDefinition.schemas || null,
1913 tView: null,
1914 };
1915 var directiveTypes = componentDefinition.directives;
1916 var feature = componentDefinition.features;
1917 var pipeTypes = componentDefinition.pipes;
1918 def.id += _renderCompCount++;
1919 def.inputs = invertObject(componentDefinition.inputs, declaredInputs),
1920 def.outputs = invertObject(componentDefinition.outputs),
1921 feature && feature.forEach(function (fn) { return fn(def); });
1922 def.directiveDefs = directiveTypes ?
1923 function () { return (typeof directiveTypes === 'function' ? directiveTypes() : directiveTypes)
1924 .map(extractDirectiveDef); } :
1925 null;
1926 def.pipeDefs = pipeTypes ?
1927 function () { return (typeof pipeTypes === 'function' ? pipeTypes() : pipeTypes).map(extractPipeDef); } :
1928 null;
1929 return def;
1930 });
1931 }
1932 /**
1933 * @codeGenApi
1934 */
1935 function ɵɵsetComponentScope(type, directives, pipes) {
1936 var def = type.ɵcmp;
1937 def.directiveDefs = function () { return directives.map(extractDirectiveDef); };
1938 def.pipeDefs = function () { return pipes.map(extractPipeDef); };
1939 }
1940 function extractDirectiveDef(type) {
1941 var def = getComponentDef(type) || getDirectiveDef(type);
1942 if (ngDevMode && !def) {
1943 throw new Error("'" + type.name + "' is neither 'ComponentType' or 'DirectiveType'.");
1944 }
1945 return def;
1946 }
1947 function extractPipeDef(type) {
1948 var def = getPipeDef(type);
1949 if (ngDevMode && !def) {
1950 throw new Error("'" + type.name + "' is not a 'PipeType'.");
1951 }
1952 return def;
1953 }
1954 var autoRegisterModuleById = {};
1955 /**
1956 * @codeGenApi
1957 */
1958 function ɵɵdefineNgModule(def) {
1959 var res = {
1960 type: def.type,
1961 bootstrap: def.bootstrap || EMPTY_ARRAY,
1962 declarations: def.declarations || EMPTY_ARRAY,
1963 imports: def.imports || EMPTY_ARRAY,
1964 exports: def.exports || EMPTY_ARRAY,
1965 transitiveCompileScopes: null,
1966 schemas: def.schemas || null,
1967 id: def.id || null,
1968 };
1969 if (def.id != null) {
1970 noSideEffects(function () {
1971 autoRegisterModuleById[def.id] = def.type;
1972 });
1973 }
1974 return res;
1975 }
1976 /**
1977 * Adds the module metadata that is necessary to compute the module's transitive scope to an
1978 * existing module definition.
1979 *
1980 * Scope metadata of modules is not used in production builds, so calls to this function can be
1981 * marked pure to tree-shake it from the bundle, allowing for all referenced declarations
1982 * to become eligible for tree-shaking as well.
1983 *
1984 * @codeGenApi
1985 */
1986 function ɵɵsetNgModuleScope(type, scope) {
1987 return noSideEffects(function () {
1988 var ngModuleDef = getNgModuleDef(type, true);
1989 ngModuleDef.declarations = scope.declarations || EMPTY_ARRAY;
1990 ngModuleDef.imports = scope.imports || EMPTY_ARRAY;
1991 ngModuleDef.exports = scope.exports || EMPTY_ARRAY;
1992 });
1993 }
1994 /**
1995 * Inverts an inputs or outputs lookup such that the keys, which were the
1996 * minified keys, are part of the values, and the values are parsed so that
1997 * the publicName of the property is the new key
1998 *
1999 * e.g. for
2000 *
2001 * ```
2002 * class Comp {
2003 * @Input()
2004 * propName1: string;
2005 *
2006 * @Input('publicName2')
2007 * declaredPropName2: number;
2008 * }
2009 * ```
2010 *
2011 * will be serialized as
2012 *
2013 * ```
2014 * {
2015 * propName1: 'propName1',
2016 * declaredPropName2: ['publicName2', 'declaredPropName2'],
2017 * }
2018 * ```
2019 *
2020 * which is than translated by the minifier as:
2021 *
2022 * ```
2023 * {
2024 * minifiedPropName1: 'propName1',
2025 * minifiedPropName2: ['publicName2', 'declaredPropName2'],
2026 * }
2027 * ```
2028 *
2029 * becomes: (public name => minifiedName)
2030 *
2031 * ```
2032 * {
2033 * 'propName1': 'minifiedPropName1',
2034 * 'publicName2': 'minifiedPropName2',
2035 * }
2036 * ```
2037 *
2038 * Optionally the function can take `secondary` which will result in: (public name => declared name)
2039 *
2040 * ```
2041 * {
2042 * 'propName1': 'propName1',
2043 * 'publicName2': 'declaredPropName2',
2044 * }
2045 * ```
2046 *
2047
2048 */
2049 function invertObject(obj, secondary) {
2050 if (obj == null)
2051 return EMPTY_OBJ;
2052 var newLookup = {};
2053 for (var minifiedKey in obj) {
2054 if (obj.hasOwnProperty(minifiedKey)) {
2055 var publicName = obj[minifiedKey];
2056 var declaredName = publicName;
2057 if (Array.isArray(publicName)) {
2058 declaredName = publicName[1];
2059 publicName = publicName[0];
2060 }
2061 newLookup[publicName] = minifiedKey;
2062 if (secondary) {
2063 (secondary[publicName] = declaredName);
2064 }
2065 }
2066 }
2067 return newLookup;
2068 }
2069 /**
2070 * Create a directive definition object.
2071 *
2072 * # Example
2073 * ```ts
2074 * class MyDirective {
2075 * // Generated by Angular Template Compiler
2076 * // [Symbol] syntax will not be supported by TypeScript until v2.7
2077 * static ɵdir = ɵɵdefineDirective({
2078 * ...
2079 * });
2080 * }
2081 * ```
2082 *
2083 * @codeGenApi
2084 */
2085 var ɵɵdefineDirective = ɵɵdefineComponent;
2086 /**
2087 * Create a pipe definition object.
2088 *
2089 * # Example
2090 * ```
2091 * class MyPipe implements PipeTransform {
2092 * // Generated by Angular Template Compiler
2093 * static ɵpipe = definePipe({
2094 * ...
2095 * });
2096 * }
2097 * ```
2098 * @param pipeDef Pipe definition generated by the compiler
2099 *
2100 * @codeGenApi
2101 */
2102 function ɵɵdefinePipe(pipeDef) {
2103 return {
2104 type: pipeDef.type,
2105 name: pipeDef.name,
2106 factory: null,
2107 pure: pipeDef.pure !== false,
2108 onDestroy: pipeDef.type.prototype.ngOnDestroy || null
2109 };
2110 }
2111 /**
2112 * The following getter methods retrieve the definition form the type. Currently the retrieval
2113 * honors inheritance, but in the future we may change the rule to require that definitions are
2114 * explicit. This would require some sort of migration strategy.
2115 */
2116 function getComponentDef(type) {
2117 return type[NG_COMP_DEF] || null;
2118 }
2119 function getDirectiveDef(type) {
2120 return type[NG_DIR_DEF] || null;
2121 }
2122 function getPipeDef(type) {
2123 return type[NG_PIPE_DEF] || null;
2124 }
2125 function getFactoryDef(type, throwNotFound) {
2126 var hasFactoryDef = type.hasOwnProperty(NG_FACTORY_DEF);
2127 if (!hasFactoryDef && throwNotFound === true && ngDevMode) {
2128 throw new Error("Type " + stringify(type) + " does not have '\u0275fac' property.");
2129 }
2130 return hasFactoryDef ? type[NG_FACTORY_DEF] : null;
2131 }
2132 function getNgModuleDef(type, throwNotFound) {
2133 var ngModuleDef = type[NG_MOD_DEF] || null;
2134 if (!ngModuleDef && throwNotFound === true) {
2135 throw new Error("Type " + stringify(type) + " does not have '\u0275mod' property.");
2136 }
2137 return ngModuleDef;
2138 }
2139 function getNgLocaleIdDef(type) {
2140 return type[NG_LOC_ID_DEF] || null;
2141 }
2142
2143 /**
2144 * Special location which allows easy identification of type. If we have an array which was
2145 * retrieved from the `LView` and that array has `true` at `TYPE` location, we know it is
2146 * `LContainer`.
2147 */
2148 var TYPE = 1;
2149 /**
2150 * Below are constants for LContainer indices to help us look up LContainer members
2151 * without having to remember the specific indices.
2152 * Uglify will inline these when minifying so there shouldn't be a cost.
2153 */
2154 /**
2155 * Flag to signify that this `LContainer` may have transplanted views which need to be change
2156 * detected. (see: `LView[DECLARATION_COMPONENT_VIEW])`.
2157 *
2158 * This flag, once set, is never unset for the `LContainer`. This means that when unset we can skip
2159 * a lot of work in `refreshEmbeddedViews`. But when set we still need to verify
2160 * that the `MOVED_VIEWS` are transplanted and on-push.
2161 */
2162 var HAS_TRANSPLANTED_VIEWS = 2;
2163 // PARENT, NEXT, TRANSPLANTED_VIEWS_TO_REFRESH are indices 3, 4, and 5
2164 // As we already have these constants in LView, we don't need to re-create them.
2165 // T_HOST is index 6
2166 // We already have this constants in LView, we don't need to re-create it.
2167 var NATIVE = 7;
2168 var VIEW_REFS = 8;
2169 var MOVED_VIEWS = 9;
2170 /**
2171 * Size of LContainer's header. Represents the index after which all views in the
2172 * container will be inserted. We need to keep a record of current views so we know
2173 * which views are already in the DOM (and don't need to be re-added) and so we can
2174 * remove views from the DOM when they are no longer required.
2175 */
2176 var CONTAINER_HEADER_OFFSET = 10;
2177 // Note: This hack is necessary so we don't erroneously get a circular dependency
2178 // failure based on types.
2179 var unusedValueExportToPlacateAjd = 1;
2180
2181 /**
2182 * @license
2183 * Copyright Google LLC All Rights Reserved.
2184 *
2185 * Use of this source code is governed by an MIT-style license that can be
2186 * found in the LICENSE file at https://angular.io/license
2187 */
2188 // Below are constants for LView indices to help us look up LView members
2189 // without having to remember the specific indices.
2190 // Uglify will inline these when minifying so there shouldn't be a cost.
2191 var HOST = 0;
2192 var TVIEW = 1;
2193 var FLAGS = 2;
2194 var PARENT = 3;
2195 var NEXT = 4;
2196 var TRANSPLANTED_VIEWS_TO_REFRESH = 5;
2197 var T_HOST = 6;
2198 var CLEANUP = 7;
2199 var CONTEXT = 8;
2200 var INJECTOR$1 = 9;
2201 var RENDERER_FACTORY = 10;
2202 var RENDERER = 11;
2203 var SANITIZER = 12;
2204 var CHILD_HEAD = 13;
2205 var CHILD_TAIL = 14;
2206 var DECLARATION_VIEW = 15;
2207 var DECLARATION_COMPONENT_VIEW = 16;
2208 var DECLARATION_LCONTAINER = 17;
2209 var PREORDER_HOOK_FLAGS = 18;
2210 var QUERIES = 19;
2211 /** Size of LView's header. Necessary to adjust for it when setting slots. */
2212 var HEADER_OFFSET = 20;
2213 // Note: This hack is necessary so we don't erroneously get a circular dependency
2214 // failure based on types.
2215 var unusedValueExportToPlacateAjd$1 = 1;
2216
2217 /**
2218 * @license
2219 * Copyright Google LLC All Rights Reserved.
2220 *
2221 * Use of this source code is governed by an MIT-style license that can be
2222 * found in the LICENSE file at https://angular.io/license
2223 */
2224 /**
2225 * True if `value` is `LView`.
2226 * @param value wrapped value of `RNode`, `LView`, `LContainer`
2227 */
2228 function isLView(value) {
2229 return Array.isArray(value) && typeof value[TYPE] === 'object';
2230 }
2231 /**
2232 * True if `value` is `LContainer`.
2233 * @param value wrapped value of `RNode`, `LView`, `LContainer`
2234 */
2235 function isLContainer(value) {
2236 return Array.isArray(value) && value[TYPE] === true;
2237 }
2238 function isContentQueryHost(tNode) {
2239 return (tNode.flags & 8 /* hasContentQuery */) !== 0;
2240 }
2241 function isComponentHost(tNode) {
2242 return (tNode.flags & 2 /* isComponentHost */) === 2 /* isComponentHost */;
2243 }
2244 function isDirectiveHost(tNode) {
2245 return (tNode.flags & 1 /* isDirectiveHost */) === 1 /* isDirectiveHost */;
2246 }
2247 function isComponentDef(def) {
2248 return def.template !== null;
2249 }
2250 function isRootView(target) {
2251 return (target[FLAGS] & 512 /* IsRoot */) !== 0;
2252 }
2253
2254 /**
2255 * @license
2256 * Copyright Google LLC All Rights Reserved.
2257 *
2258 * Use of this source code is governed by an MIT-style license that can be
2259 * found in the LICENSE file at https://angular.io/license
2260 */
2261 // [Assert functions do not constraint type when they are guarded by a truthy
2262 // expression.](https://github.com/microsoft/TypeScript/issues/37295)
2263 function assertTNodeForLView(tNode, lView) {
2264 tNode.hasOwnProperty('tView_') &&
2265 assertEqual(tNode.tView_, lView[TVIEW], 'This TNode does not belong to this LView.');
2266 }
2267 function assertComponentType(actual, msg) {
2268 if (msg === void 0) { msg = 'Type passed in is not ComponentType, it does not have \'ɵcmp\' property.'; }
2269 if (!getComponentDef(actual)) {
2270 throwError(msg);
2271 }
2272 }
2273 function assertNgModuleType(actual, msg) {
2274 if (msg === void 0) { msg = 'Type passed in is not NgModuleType, it does not have \'ɵmod\' property.'; }
2275 if (!getNgModuleDef(actual)) {
2276 throwError(msg);
2277 }
2278 }
2279 function assertPreviousIsParent(isParent) {
2280 assertEqual(isParent, true, 'previousOrParentTNode should be a parent');
2281 }
2282 function assertHasParent(tNode) {
2283 assertDefined(tNode, 'previousOrParentTNode should exist!');
2284 assertDefined(tNode.parent, 'previousOrParentTNode should have a parent');
2285 }
2286 function assertDataNext(lView, index, arr) {
2287 if (arr == null)
2288 arr = lView;
2289 assertEqual(arr.length, index, "index " + index + " expected to be at the end of arr (length " + arr.length + ")");
2290 }
2291 function assertLContainer(value) {
2292 assertDefined(value, 'LContainer must be defined');
2293 assertEqual(isLContainer(value), true, 'Expecting LContainer');
2294 }
2295 function assertLViewOrUndefined(value) {
2296 value && assertEqual(isLView(value), true, 'Expecting LView or undefined or null');
2297 }
2298 function assertLView(value) {
2299 assertDefined(value, 'LView must be defined');
2300 assertEqual(isLView(value), true, 'Expecting LView');
2301 }
2302 function assertFirstCreatePass(tView, errMessage) {
2303 assertEqual(tView.firstCreatePass, true, errMessage || 'Should only be called in first create pass.');
2304 }
2305 function assertFirstUpdatePass(tView, errMessage) {
2306 assertEqual(tView.firstUpdatePass, true, errMessage || 'Should only be called in first update pass.');
2307 }
2308 /**
2309 * This is a basic sanity check that an object is probably a directive def. DirectiveDef is
2310 * an interface, so we can't do a direct instanceof check.
2311 */
2312 function assertDirectiveDef(obj) {
2313 if (obj.type === undefined || obj.selectors == undefined || obj.inputs === undefined) {
2314 throwError("Expected a DirectiveDef/ComponentDef and this object does not seem to have the expected shape.");
2315 }
2316 }
2317
2318 /**
2319 * @license
2320 * Copyright Google LLC All Rights Reserved.
2321 *
2322 * Use of this source code is governed by an MIT-style license that can be
2323 * found in the LICENSE file at https://angular.io/license
2324 */
2325 /**
2326 * Represents a basic change from a previous to a new value for a single
2327 * property on a directive instance. Passed as a value in a
2328 * {@link SimpleChanges} object to the `ngOnChanges` hook.
2329 *
2330 * @see `OnChanges`
2331 *
2332 * @publicApi
2333 */
2334 var SimpleChange = /** @class */ (function () {
2335 function SimpleChange(previousValue, currentValue, firstChange) {
2336 this.previousValue = previousValue;
2337 this.currentValue = currentValue;
2338 this.firstChange = firstChange;
2339 }
2340 /**
2341 * Check whether the new value is the first value assigned.
2342 */
2343 SimpleChange.prototype.isFirstChange = function () {
2344 return this.firstChange;
2345 };
2346 return SimpleChange;
2347 }());
2348
2349 /**
2350 * @license
2351 * Copyright Google LLC All Rights Reserved.
2352 *
2353 * Use of this source code is governed by an MIT-style license that can be
2354 * found in the LICENSE file at https://angular.io/license
2355 */
2356 /**
2357 * The NgOnChangesFeature decorates a component with support for the ngOnChanges
2358 * lifecycle hook, so it should be included in any component that implements
2359 * that hook.
2360 *
2361 * If the component or directive uses inheritance, the NgOnChangesFeature MUST
2362 * be included as a feature AFTER {@link InheritDefinitionFeature}, otherwise
2363 * inherited properties will not be propagated to the ngOnChanges lifecycle
2364 * hook.
2365 *
2366 * Example usage:
2367 *
2368 * ```
2369 * static ɵcmp = defineComponent({
2370 * ...
2371 * inputs: {name: 'publicName'},
2372 * features: [NgOnChangesFeature]
2373 * });
2374 * ```
2375 *
2376 * @codeGenApi
2377 */
2378 function ɵɵNgOnChangesFeature() {
2379 return NgOnChangesFeatureImpl;
2380 }
2381 function NgOnChangesFeatureImpl(definition) {
2382 if (definition.type.prototype.ngOnChanges) {
2383 definition.setInput = ngOnChangesSetInput;
2384 }
2385 return rememberChangeHistoryAndInvokeOnChangesHook;
2386 }
2387 // This option ensures that the ngOnChanges lifecycle hook will be inherited
2388 // from superclasses (in InheritDefinitionFeature).
2389 /** @nocollapse */
2390 // tslint:disable-next-line:no-toplevel-property-access
2391 ɵɵNgOnChangesFeature.ngInherit = true;
2392 /**
2393 * This is a synthetic lifecycle hook which gets inserted into `TView.preOrderHooks` to simulate
2394 * `ngOnChanges`.
2395 *
2396 * The hook reads the `NgSimpleChangesStore` data from the component instance and if changes are
2397 * found it invokes `ngOnChanges` on the component instance.
2398 *
2399 * @param this Component instance. Because this function gets inserted into `TView.preOrderHooks`,
2400 * it is guaranteed to be called with component instance.
2401 */
2402 function rememberChangeHistoryAndInvokeOnChangesHook() {
2403 var simpleChangesStore = getSimpleChangesStore(this);
2404 var current = simpleChangesStore === null || simpleChangesStore === void 0 ? void 0 : simpleChangesStore.current;
2405 if (current) {
2406 var previous = simpleChangesStore.previous;
2407 if (previous === EMPTY_OBJ) {
2408 simpleChangesStore.previous = current;
2409 }
2410 else {
2411 // New changes are copied to the previous store, so that we don't lose history for inputs
2412 // which were not changed this time
2413 for (var key in current) {
2414 previous[key] = current[key];
2415 }
2416 }
2417 simpleChangesStore.current = null;
2418 this.ngOnChanges(current);
2419 }
2420 }
2421 function ngOnChangesSetInput(instance, value, publicName, privateName) {
2422 var simpleChangesStore = getSimpleChangesStore(instance) ||
2423 setSimpleChangesStore(instance, { previous: EMPTY_OBJ, current: null });
2424 var current = simpleChangesStore.current || (simpleChangesStore.current = {});
2425 var previous = simpleChangesStore.previous;
2426 var declaredName = this.declaredInputs[publicName];
2427 var previousChange = previous[declaredName];
2428 current[declaredName] = new SimpleChange(previousChange && previousChange.currentValue, value, previous === EMPTY_OBJ);
2429 instance[privateName] = value;
2430 }
2431 var SIMPLE_CHANGES_STORE = '__ngSimpleChanges__';
2432 function getSimpleChangesStore(instance) {
2433 return instance[SIMPLE_CHANGES_STORE] || null;
2434 }
2435 function setSimpleChangesStore(instance, store) {
2436 return instance[SIMPLE_CHANGES_STORE] = store;
2437 }
2438
2439 /**
2440 * @license
2441 * Copyright Google LLC All Rights Reserved.
2442 *
2443 * Use of this source code is governed by an MIT-style license that can be
2444 * found in the LICENSE file at https://angular.io/license
2445 */
2446 var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
2447 var MATH_ML_NAMESPACE = 'http://www.w3.org/1998/MathML/';
2448
2449 /**
2450 * @license
2451 * Copyright Google LLC All Rights Reserved.
2452 *
2453 * Use of this source code is governed by an MIT-style license that can be
2454 * found in the LICENSE file at https://angular.io/license
2455 */
2456 /**
2457 * This property will be monkey-patched on elements, components and directives
2458 */
2459 var MONKEY_PATCH_KEY_NAME = '__ngContext__';
2460
2461 /**
2462 * @license
2463 * Copyright Google LLC All Rights Reserved.
2464 *
2465 * Use of this source code is governed by an MIT-style license that can be
2466 * found in the LICENSE file at https://angular.io/license
2467 */
2468 /**
2469 * Most of the use of `document` in Angular is from within the DI system so it is possible to simply
2470 * inject the `DOCUMENT` token and are done.
2471 *
2472 * Ivy is special because it does not rely upon the DI and must get hold of the document some other
2473 * way.
2474 *
2475 * The solution is to define `getDocument()` and `setDocument()` top-level functions for ivy.
2476 * Wherever ivy needs the global document, it calls `getDocument()` instead.
2477 *
2478 * When running ivy outside of a browser environment, it is necessary to call `setDocument()` to
2479 * tell ivy what the global `document` is.
2480 *
2481 * Angular does this for us in each of the standard platforms (`Browser`, `Server`, and `WebWorker`)
2482 * by calling `setDocument()` when providing the `DOCUMENT` token.
2483 */
2484 var DOCUMENT = undefined;
2485 /**
2486 * Tell ivy what the `document` is for this platform.
2487 *
2488 * It is only necessary to call this if the current platform is not a browser.
2489 *
2490 * @param document The object representing the global `document` in this environment.
2491 */
2492 function setDocument(document) {
2493 DOCUMENT = document;
2494 }
2495 /**
2496 * Access the object that represents the `document` for this platform.
2497 *
2498 * Ivy calls this whenever it needs to access the `document` object.
2499 * For example to create the renderer or to do sanitization.
2500 */
2501 function getDocument() {
2502 if (DOCUMENT !== undefined) {
2503 return DOCUMENT;
2504 }
2505 else if (typeof document !== 'undefined') {
2506 return document;
2507 }
2508 // No "document" can be found. This should only happen if we are running ivy outside Angular and
2509 // the current platform is not a browser. Since this is not a supported scenario at the moment
2510 // this should not happen in Angular apps.
2511 // Once we support running ivy outside of Angular we will need to publish `setDocument()` as a
2512 // public API. Meanwhile we just return `undefined` and let the application fail.
2513 return undefined;
2514 }
2515
2516 /**
2517 * @license
2518 * Copyright Google LLC All Rights Reserved.
2519 *
2520 * Use of this source code is governed by an MIT-style license that can be
2521 * found in the LICENSE file at https://angular.io/license
2522 */
2523 // TODO: cleanup once the code is merged in angular/angular
2524 var RendererStyleFlags3;
2525 (function (RendererStyleFlags3) {
2526 RendererStyleFlags3[RendererStyleFlags3["Important"] = 1] = "Important";
2527 RendererStyleFlags3[RendererStyleFlags3["DashCase"] = 2] = "DashCase";
2528 })(RendererStyleFlags3 || (RendererStyleFlags3 = {}));
2529 /** Returns whether the `renderer` is a `ProceduralRenderer3` */
2530 function isProceduralRenderer(renderer) {
2531 return !!(renderer.listen);
2532 }
2533 var ɵ0$2 = function (hostElement, rendererType) {
2534 return getDocument();
2535 };
2536 var domRendererFactory3 = {
2537 createRenderer: ɵ0$2
2538 };
2539 // Note: This hack is necessary so we don't erroneously get a circular dependency
2540 // failure based on types.
2541 var unusedValueExportToPlacateAjd$2 = 1;
2542
2543 /**
2544 * @license
2545 * Copyright Google LLC All Rights Reserved.
2546 *
2547 * Use of this source code is governed by an MIT-style license that can be
2548 * found in the LICENSE file at https://angular.io/license
2549 */
2550 /**
2551 * For efficiency reasons we often put several different data types (`RNode`, `LView`, `LContainer`)
2552 * in same location in `LView`. This is because we don't want to pre-allocate space for it
2553 * because the storage is sparse. This file contains utilities for dealing with such data types.
2554 *
2555 * How do we know what is stored at a given location in `LView`.
2556 * - `Array.isArray(value) === false` => `RNode` (The normal storage value)
2557 * - `Array.isArray(value) === true` => then the `value[0]` represents the wrapped value.
2558 * - `typeof value[TYPE] === 'object'` => `LView`
2559 * - This happens when we have a component at a given location
2560 * - `typeof value[TYPE] === true` => `LContainer`
2561 * - This happens when we have `LContainer` binding at a given location.
2562 *
2563 *
2564 * NOTE: it is assumed that `Array.isArray` and `typeof` operations are very efficient.
2565 */
2566 /**
2567 * Returns `RNode`.
2568 * @param value wrapped value of `RNode`, `LView`, `LContainer`
2569 */
2570 function unwrapRNode(value) {
2571 while (Array.isArray(value)) {
2572 value = value[HOST];
2573 }
2574 return value;
2575 }
2576 /**
2577 * Returns `LView` or `null` if not found.
2578 * @param value wrapped value of `RNode`, `LView`, `LContainer`
2579 */
2580 function unwrapLView(value) {
2581 while (Array.isArray(value)) {
2582 // This check is same as `isLView()` but we don't call at as we don't want to call
2583 // `Array.isArray()` twice and give JITer more work for inlining.
2584 if (typeof value[TYPE] === 'object')
2585 return value;
2586 value = value[HOST];
2587 }
2588 return null;
2589 }
2590 /**
2591 * Returns `LContainer` or `null` if not found.
2592 * @param value wrapped value of `RNode`, `LView`, `LContainer`
2593 */
2594 function unwrapLContainer(value) {
2595 while (Array.isArray(value)) {
2596 // This check is same as `isLContainer()` but we don't call at as we don't want to call
2597 // `Array.isArray()` twice and give JITer more work for inlining.
2598 if (value[TYPE] === true)
2599 return value;
2600 value = value[HOST];
2601 }
2602 return null;
2603 }
2604 /**
2605 * Retrieves an element value from the provided `viewData`, by unwrapping
2606 * from any containers, component views, or style contexts.
2607 */
2608 function getNativeByIndex(index, lView) {
2609 return unwrapRNode(lView[index + HEADER_OFFSET]);
2610 }
2611 /**
2612 * Retrieve an `RNode` for a given `TNode` and `LView`.
2613 *
2614 * This function guarantees in dev mode to retrieve a non-null `RNode`.
2615 *
2616 * @param tNode
2617 * @param lView
2618 */
2619 function getNativeByTNode(tNode, lView) {
2620 ngDevMode && assertTNodeForLView(tNode, lView);
2621 ngDevMode && assertIndexInRange(lView, tNode.index);
2622 var node = unwrapRNode(lView[tNode.index]);
2623 ngDevMode && !isProceduralRenderer(lView[RENDERER]) && assertDomNode(node);
2624 return node;
2625 }
2626 /**
2627 * Retrieve an `RNode` or `null` for a given `TNode` and `LView`.
2628 *
2629 * Some `TNode`s don't have associated `RNode`s. For example `Projection`
2630 *
2631 * @param tNode
2632 * @param lView
2633 */
2634 function getNativeByTNodeOrNull(tNode, lView) {
2635 var index = tNode.index;
2636 if (index !== -1) {
2637 ngDevMode && assertTNodeForLView(tNode, lView);
2638 var node = unwrapRNode(lView[index]);
2639 ngDevMode && node !== null && !isProceduralRenderer(lView[RENDERER]) && assertDomNode(node);
2640 return node;
2641 }
2642 return null;
2643 }
2644 function getTNode(tView, index) {
2645 ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');
2646 ngDevMode && assertLessThan(index, tView.data.length, 'wrong index for TNode');
2647 return tView.data[index + HEADER_OFFSET];
2648 }
2649 /** Retrieves a value from any `LView` or `TData`. */
2650 function load(view, index) {
2651 ngDevMode && assertIndexInRange(view, index + HEADER_OFFSET);
2652 return view[index + HEADER_OFFSET];
2653 }
2654 function getComponentLViewByIndex(nodeIndex, hostView) {
2655 // Could be an LView or an LContainer. If LContainer, unwrap to find LView.
2656 ngDevMode && assertIndexInRange(hostView, nodeIndex);
2657 var slotValue = hostView[nodeIndex];
2658 var lView = isLView(slotValue) ? slotValue : slotValue[HOST];
2659 return lView;
2660 }
2661 /**
2662 * Returns the monkey-patch value data present on the target (which could be
2663 * a component, directive or a DOM node).
2664 */
2665 function readPatchedData(target) {
2666 ngDevMode && assertDefined(target, 'Target expected');
2667 return target[MONKEY_PATCH_KEY_NAME] || null;
2668 }
2669 function readPatchedLView(target) {
2670 var value = readPatchedData(target);
2671 if (value) {
2672 return Array.isArray(value) ? value : value.lView;
2673 }
2674 return null;
2675 }
2676 /** Checks whether a given view is in creation mode */
2677 function isCreationMode(view) {
2678 return (view[FLAGS] & 4 /* CreationMode */) === 4 /* CreationMode */;
2679 }
2680 /**
2681 * Returns a boolean for whether the view is attached to the change detection tree.
2682 *
2683 * Note: This determines whether a view should be checked, not whether it's inserted
2684 * into a container. For that, you'll want `viewAttachedToContainer` below.
2685 */
2686 function viewAttachedToChangeDetector(view) {
2687 return (view[FLAGS] & 128 /* Attached */) === 128 /* Attached */;
2688 }
2689 /** Returns a boolean for whether the view is attached to a container. */
2690 function viewAttachedToContainer(view) {
2691 return isLContainer(view[PARENT]);
2692 }
2693 /** Returns a constant from `TConstants` instance. */
2694 function getConstant(consts, index) {
2695 return consts === null || index == null ? null : consts[index];
2696 }
2697 /**
2698 * Resets the pre-order hook flags of the view.
2699 * @param lView the LView on which the flags are reset
2700 */
2701 function resetPreOrderHookFlags(lView) {
2702 lView[PREORDER_HOOK_FLAGS] = 0;
2703 }
2704 /**
2705 * Updates the `TRANSPLANTED_VIEWS_TO_REFRESH` counter on the `LContainer` as well as the parents
2706 * whose
2707 * 1. counter goes from 0 to 1, indicating that there is a new child that has a view to refresh
2708 * or
2709 * 2. counter goes from 1 to 0, indicating there are no more descendant views to refresh
2710 */
2711 function updateTransplantedViewCount(lContainer, amount) {
2712 lContainer[TRANSPLANTED_VIEWS_TO_REFRESH] += amount;
2713 var viewOrContainer = lContainer;
2714 var parent = lContainer[PARENT];
2715 while (parent !== null &&
2716 ((amount === 1 && viewOrContainer[TRANSPLANTED_VIEWS_TO_REFRESH] === 1) ||
2717 (amount === -1 && viewOrContainer[TRANSPLANTED_VIEWS_TO_REFRESH] === 0))) {
2718 parent[TRANSPLANTED_VIEWS_TO_REFRESH] += amount;
2719 viewOrContainer = parent;
2720 parent = parent[PARENT];
2721 }
2722 }
2723
2724 /**
2725 * @license
2726 * Copyright Google LLC All Rights Reserved.
2727 *
2728 * Use of this source code is governed by an MIT-style license that can be
2729 * found in the LICENSE file at https://angular.io/license
2730 */
2731 var instructionState = {
2732 lFrame: createLFrame(null),
2733 bindingsEnabled: true,
2734 checkNoChangesMode: false,
2735 };
2736 function getElementDepthCount() {
2737 return instructionState.lFrame.elementDepthCount;
2738 }
2739 function increaseElementDepthCount() {
2740 instructionState.lFrame.elementDepthCount++;
2741 }
2742 function decreaseElementDepthCount() {
2743 instructionState.lFrame.elementDepthCount--;
2744 }
2745 function getBindingsEnabled() {
2746 return instructionState.bindingsEnabled;
2747 }
2748 /**
2749 * Enables directive matching on elements.
2750 *
2751 * * Example:
2752 * ```
2753 * <my-comp my-directive>
2754 * Should match component / directive.
2755 * </my-comp>
2756 * <div ngNonBindable>
2757 * <!-- ɵɵdisableBindings() -->
2758 * <my-comp my-directive>
2759 * Should not match component / directive because we are in ngNonBindable.
2760 * </my-comp>
2761 * <!-- ɵɵenableBindings() -->
2762 * </div>
2763 * ```
2764 *
2765 * @codeGenApi
2766 */
2767 function ɵɵenableBindings() {
2768 instructionState.bindingsEnabled = true;
2769 }
2770 /**
2771 * Disables directive matching on element.
2772 *
2773 * * Example:
2774 * ```
2775 * <my-comp my-directive>
2776 * Should match component / directive.
2777 * </my-comp>
2778 * <div ngNonBindable>
2779 * <!-- ɵɵdisableBindings() -->
2780 * <my-comp my-directive>
2781 * Should not match component / directive because we are in ngNonBindable.
2782 * </my-comp>
2783 * <!-- ɵɵenableBindings() -->
2784 * </div>
2785 * ```
2786 *
2787 * @codeGenApi
2788 */
2789 function ɵɵdisableBindings() {
2790 instructionState.bindingsEnabled = false;
2791 }
2792 /**
2793 * Return the current `LView`.
2794 */
2795 function getLView() {
2796 return instructionState.lFrame.lView;
2797 }
2798 /**
2799 * Return the current `TView`.
2800 */
2801 function getTView() {
2802 return instructionState.lFrame.tView;
2803 }
2804 /**
2805 * Restores `contextViewData` to the given OpaqueViewState instance.
2806 *
2807 * Used in conjunction with the getCurrentView() instruction to save a snapshot
2808 * of the current view and restore it when listeners are invoked. This allows
2809 * walking the declaration view tree in listeners to get vars from parent views.
2810 *
2811 * @param viewToRestore The OpaqueViewState instance to restore.
2812 *
2813 * @codeGenApi
2814 */
2815 function ɵɵrestoreView(viewToRestore) {
2816 instructionState.lFrame.contextLView = viewToRestore;
2817 }
2818 function getPreviousOrParentTNode() {
2819 return instructionState.lFrame.previousOrParentTNode;
2820 }
2821 function setPreviousOrParentTNode(tNode, isParent) {
2822 instructionState.lFrame.previousOrParentTNode = tNode;
2823 instructionState.lFrame.isParent = isParent;
2824 }
2825 function getIsParent() {
2826 return instructionState.lFrame.isParent;
2827 }
2828 function setIsNotParent() {
2829 instructionState.lFrame.isParent = false;
2830 }
2831 function setIsParent() {
2832 instructionState.lFrame.isParent = true;
2833 }
2834 function getContextLView() {
2835 return instructionState.lFrame.contextLView;
2836 }
2837 function getCheckNoChangesMode() {
2838 // TODO(misko): remove this from the LView since it is ngDevMode=true mode only.
2839 return instructionState.checkNoChangesMode;
2840 }
2841 function setCheckNoChangesMode(mode) {
2842 instructionState.checkNoChangesMode = mode;
2843 }
2844 // top level variables should not be exported for performance reasons (PERF_NOTES.md)
2845 function getBindingRoot() {
2846 var lFrame = instructionState.lFrame;
2847 var index = lFrame.bindingRootIndex;
2848 if (index === -1) {
2849 index = lFrame.bindingRootIndex = lFrame.tView.bindingStartIndex;
2850 }
2851 return index;
2852 }
2853 function getBindingIndex() {
2854 return instructionState.lFrame.bindingIndex;
2855 }
2856 function setBindingIndex(value) {
2857 return instructionState.lFrame.bindingIndex = value;
2858 }
2859 function nextBindingIndex() {
2860 return instructionState.lFrame.bindingIndex++;
2861 }
2862 function incrementBindingIndex(count) {
2863 var lFrame = instructionState.lFrame;
2864 var index = lFrame.bindingIndex;
2865 lFrame.bindingIndex = lFrame.bindingIndex + count;
2866 return index;
2867 }
2868 /**
2869 * Set a new binding root index so that host template functions can execute.
2870 *
2871 * Bindings inside the host template are 0 index. But because we don't know ahead of time
2872 * how many host bindings we have we can't pre-compute them. For this reason they are all
2873 * 0 index and we just shift the root so that they match next available location in the LView.
2874 *
2875 * @param bindingRootIndex Root index for `hostBindings`
2876 * @param currentDirectiveIndex `TData[currentDirectiveIndex]` will point to the current directive
2877 * whose `hostBindings` are being processed.
2878 */
2879 function setBindingRootForHostBindings(bindingRootIndex, currentDirectiveIndex) {
2880 var lFrame = instructionState.lFrame;
2881 lFrame.bindingIndex = lFrame.bindingRootIndex = bindingRootIndex;
2882 setCurrentDirectiveIndex(currentDirectiveIndex);
2883 }
2884 /**
2885 * When host binding is executing this points to the directive index.
2886 * `TView.data[getCurrentDirectiveIndex()]` is `DirectiveDef`
2887 * `LView[getCurrentDirectiveIndex()]` is directive instance.
2888 */
2889 function getCurrentDirectiveIndex() {
2890 return instructionState.lFrame.currentDirectiveIndex;
2891 }
2892 /**
2893 * Sets an index of a directive whose `hostBindings` are being processed.
2894 *
2895 * @param currentDirectiveIndex `TData` index where current directive instance can be found.
2896 */
2897 function setCurrentDirectiveIndex(currentDirectiveIndex) {
2898 instructionState.lFrame.currentDirectiveIndex = currentDirectiveIndex;
2899 }
2900 /**
2901 * Retrieve the current `DirectiveDef` which is active when `hostBindings` instruction is being
2902 * executed.
2903 *
2904 * @param tData Current `TData` where the `DirectiveDef` will be looked up at.
2905 */
2906 function getCurrentDirectiveDef(tData) {
2907 var currentDirectiveIndex = instructionState.lFrame.currentDirectiveIndex;
2908 return currentDirectiveIndex === -1 ? null : tData[currentDirectiveIndex];
2909 }
2910 function getCurrentQueryIndex() {
2911 return instructionState.lFrame.currentQueryIndex;
2912 }
2913 function setCurrentQueryIndex(value) {
2914 instructionState.lFrame.currentQueryIndex = value;
2915 }
2916 /**
2917 * This is a light weight version of the `enterView` which is needed by the DI system.
2918 * @param newView
2919 * @param tNode
2920 */
2921 function enterDI(newView, tNode) {
2922 ngDevMode && assertLViewOrUndefined(newView);
2923 var newLFrame = allocLFrame();
2924 instructionState.lFrame = newLFrame;
2925 newLFrame.previousOrParentTNode = tNode;
2926 newLFrame.lView = newView;
2927 }
2928 /**
2929 * Swap the current lView with a new lView.
2930 *
2931 * For performance reasons we store the lView in the top level of the module.
2932 * This way we minimize the number of properties to read. Whenever a new view
2933 * is entered we have to store the lView for later, and when the view is
2934 * exited the state has to be restored
2935 *
2936 * @param newView New lView to become active
2937 * @param tNode Element to which the View is a child of
2938 * @returns the previously active lView;
2939 */
2940 function enterView(newView, tNode) {
2941 ngDevMode && assertLViewOrUndefined(newView);
2942 var newLFrame = allocLFrame();
2943 if (ngDevMode) {
2944 assertEqual(newLFrame.isParent, true, 'Expected clean LFrame');
2945 assertEqual(newLFrame.lView, null, 'Expected clean LFrame');
2946 assertEqual(newLFrame.tView, null, 'Expected clean LFrame');
2947 assertEqual(newLFrame.selectedIndex, 0, 'Expected clean LFrame');
2948 assertEqual(newLFrame.elementDepthCount, 0, 'Expected clean LFrame');
2949 assertEqual(newLFrame.currentDirectiveIndex, -1, 'Expected clean LFrame');
2950 assertEqual(newLFrame.currentNamespace, null, 'Expected clean LFrame');
2951 assertEqual(newLFrame.bindingRootIndex, -1, 'Expected clean LFrame');
2952 assertEqual(newLFrame.currentQueryIndex, 0, 'Expected clean LFrame');
2953 }
2954 var tView = newView[TVIEW];
2955 instructionState.lFrame = newLFrame;
2956 newLFrame.previousOrParentTNode = tNode;
2957 newLFrame.lView = newView;
2958 newLFrame.tView = tView;
2959 newLFrame.contextLView = newView;
2960 newLFrame.bindingIndex = tView.bindingStartIndex;
2961 }
2962 /**
2963 * Allocates next free LFrame. This function tries to reuse the `LFrame`s to lower memory pressure.
2964 */
2965 function allocLFrame() {
2966 var currentLFrame = instructionState.lFrame;
2967 var childLFrame = currentLFrame === null ? null : currentLFrame.child;
2968 var newLFrame = childLFrame === null ? createLFrame(currentLFrame) : childLFrame;
2969 return newLFrame;
2970 }
2971 function createLFrame(parent) {
2972 var lFrame = {
2973 previousOrParentTNode: null,
2974 isParent: true,
2975 lView: null,
2976 tView: null,
2977 selectedIndex: 0,
2978 contextLView: null,
2979 elementDepthCount: 0,
2980 currentNamespace: null,
2981 currentDirectiveIndex: -1,
2982 bindingRootIndex: -1,
2983 bindingIndex: -1,
2984 currentQueryIndex: 0,
2985 parent: parent,
2986 child: null,
2987 };
2988 parent !== null && (parent.child = lFrame); // link the new LFrame for reuse.
2989 return lFrame;
2990 }
2991 /**
2992 * A lightweight version of leave which is used with DI.
2993 *
2994 * This function only resets `previousOrParentTNode` and `LView` as those are the only properties
2995 * used with DI (`enterDI()`).
2996 *
2997 * NOTE: This function is reexported as `leaveDI`. However `leaveDI` has return type of `void` where
2998 * as `leaveViewLight` has `LFrame`. This is so that `leaveViewLight` can be used in `leaveView`.
2999 */
3000 function leaveViewLight() {
3001 var oldLFrame = instructionState.lFrame;
3002 instructionState.lFrame = oldLFrame.parent;
3003 oldLFrame.previousOrParentTNode = null;
3004 oldLFrame.lView = null;
3005 return oldLFrame;
3006 }
3007 /**
3008 * This is a lightweight version of the `leaveView` which is needed by the DI system.
3009 *
3010 * NOTE: this function is an alias so that we can change the type of the function to have `void`
3011 * return type.
3012 */
3013 var leaveDI = leaveViewLight;
3014 /**
3015 * Leave the current `LView`
3016 *
3017 * This pops the `LFrame` with the associated `LView` from the stack.
3018 *
3019 * IMPORTANT: We must zero out the `LFrame` values here otherwise they will be retained. This is
3020 * because for performance reasons we don't release `LFrame` but rather keep it for next use.
3021 */
3022 function leaveView() {
3023 var oldLFrame = leaveViewLight();
3024 oldLFrame.isParent = true;
3025 oldLFrame.tView = null;
3026 oldLFrame.selectedIndex = 0;
3027 oldLFrame.contextLView = null;
3028 oldLFrame.elementDepthCount = 0;
3029 oldLFrame.currentDirectiveIndex = -1;
3030 oldLFrame.currentNamespace = null;
3031 oldLFrame.bindingRootIndex = -1;
3032 oldLFrame.bindingIndex = -1;
3033 oldLFrame.currentQueryIndex = 0;
3034 }
3035 function nextContextImpl(level) {
3036 var contextLView = instructionState.lFrame.contextLView =
3037 walkUpViews(level, instructionState.lFrame.contextLView);
3038 return contextLView[CONTEXT];
3039 }
3040 function walkUpViews(nestingLevel, currentView) {
3041 while (nestingLevel > 0) {
3042 ngDevMode &&
3043 assertDefined(currentView[DECLARATION_VIEW], 'Declaration view should be defined if nesting level is greater than 0.');
3044 currentView = currentView[DECLARATION_VIEW];
3045 nestingLevel--;
3046 }
3047 return currentView;
3048 }
3049 /**
3050 * Gets the currently selected element index.
3051 *
3052 * Used with {@link property} instruction (and more in the future) to identify the index in the
3053 * current `LView` to act on.
3054 */
3055 function getSelectedIndex() {
3056 return instructionState.lFrame.selectedIndex;
3057 }
3058 /**
3059 * Sets the most recent index passed to {@link select}
3060 *
3061 * Used with {@link property} instruction (and more in the future) to identify the index in the
3062 * current `LView` to act on.
3063 *
3064 * (Note that if an "exit function" was set earlier (via `setElementExitFn()`) then that will be
3065 * run if and when the provided `index` value is different from the current selected index value.)
3066 */
3067 function setSelectedIndex(index) {
3068 instructionState.lFrame.selectedIndex = index;
3069 }
3070 /**
3071 * Gets the `tNode` that represents currently selected element.
3072 */
3073 function getSelectedTNode() {
3074 var lFrame = instructionState.lFrame;
3075 return getTNode(lFrame.tView, lFrame.selectedIndex);
3076 }
3077 /**
3078 * Sets the namespace used to create elements to `'http://www.w3.org/2000/svg'` in global state.
3079 *
3080 * @codeGenApi
3081 */
3082 function ɵɵnamespaceSVG() {
3083 instructionState.lFrame.currentNamespace = SVG_NAMESPACE;
3084 }
3085 /**
3086 * Sets the namespace used to create elements to `'http://www.w3.org/1998/MathML/'` in global state.
3087 *
3088 * @codeGenApi
3089 */
3090 function ɵɵnamespaceMathML() {
3091 instructionState.lFrame.currentNamespace = MATH_ML_NAMESPACE;
3092 }
3093 /**
3094 * Sets the namespace used to create elements to `null`, which forces element creation to use
3095 * `createElement` rather than `createElementNS`.
3096 *
3097 * @codeGenApi
3098 */
3099 function ɵɵnamespaceHTML() {
3100 namespaceHTMLInternal();
3101 }
3102 /**
3103 * Sets the namespace used to create elements to `null`, which forces element creation to use
3104 * `createElement` rather than `createElementNS`.
3105 */
3106 function namespaceHTMLInternal() {
3107 instructionState.lFrame.currentNamespace = null;
3108 }
3109 function getNamespace() {
3110 return instructionState.lFrame.currentNamespace;
3111 }
3112
3113 /**
3114 * @license
3115 * Copyright Google LLC All Rights Reserved.
3116 *
3117 * Use of this source code is governed by an MIT-style license that can be
3118 * found in the LICENSE file at https://angular.io/license
3119 */
3120 /**
3121 * Adds all directive lifecycle hooks from the given `DirectiveDef` to the given `TView`.
3122 *
3123 * Must be run *only* on the first template pass.
3124 *
3125 * Sets up the pre-order hooks on the provided `tView`,
3126 * see {@link HookData} for details about the data structure.
3127 *
3128 * @param directiveIndex The index of the directive in LView
3129 * @param directiveDef The definition containing the hooks to setup in tView
3130 * @param tView The current TView
3131 */
3132 function registerPreOrderHooks(directiveIndex, directiveDef, tView) {
3133 ngDevMode && assertFirstCreatePass(tView);
3134 var _a = directiveDef.type.prototype, ngOnChanges = _a.ngOnChanges, ngOnInit = _a.ngOnInit, ngDoCheck = _a.ngDoCheck;
3135 if (ngOnChanges) {
3136 var wrappedOnChanges = NgOnChangesFeatureImpl(directiveDef);
3137 (tView.preOrderHooks || (tView.preOrderHooks = [])).push(directiveIndex, wrappedOnChanges);
3138 (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = []))
3139 .push(directiveIndex, wrappedOnChanges);
3140 }
3141 if (ngOnInit) {
3142 (tView.preOrderHooks || (tView.preOrderHooks = [])).push(0 - directiveIndex, ngOnInit);
3143 }
3144 if (ngDoCheck) {
3145 (tView.preOrderHooks || (tView.preOrderHooks = [])).push(directiveIndex, ngDoCheck);
3146 (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(directiveIndex, ngDoCheck);
3147 }
3148 }
3149 /**
3150 *
3151 * Loops through the directives on the provided `tNode` and queues hooks to be
3152 * run that are not initialization hooks.
3153 *
3154 * Should be executed during `elementEnd()` and similar to
3155 * preserve hook execution order. Content, view, and destroy hooks for projected
3156 * components and directives must be called *before* their hosts.
3157 *
3158 * Sets up the content, view, and destroy hooks on the provided `tView`,
3159 * see {@link HookData} for details about the data structure.
3160 *
3161 * NOTE: This does not set up `onChanges`, `onInit` or `doCheck`, those are set up
3162 * separately at `elementStart`.
3163 *
3164 * @param tView The current TView
3165 * @param tNode The TNode whose directives are to be searched for hooks to queue
3166 */
3167 function registerPostOrderHooks(tView, tNode) {
3168 ngDevMode && assertFirstCreatePass(tView);
3169 // It's necessary to loop through the directives at elementEnd() (rather than processing in
3170 // directiveCreate) so we can preserve the current hook order. Content, view, and destroy
3171 // hooks for projected components and directives must be called *before* their hosts.
3172 for (var i = tNode.directiveStart, end = tNode.directiveEnd; i < end; i++) {
3173 var directiveDef = tView.data[i];
3174 var lifecycleHooks = directiveDef.type.prototype;
3175 var ngAfterContentInit = lifecycleHooks.ngAfterContentInit, ngAfterContentChecked = lifecycleHooks.ngAfterContentChecked, ngAfterViewInit = lifecycleHooks.ngAfterViewInit, ngAfterViewChecked = lifecycleHooks.ngAfterViewChecked, ngOnDestroy = lifecycleHooks.ngOnDestroy;
3176 if (ngAfterContentInit) {
3177 (tView.contentHooks || (tView.contentHooks = [])).push(-i, ngAfterContentInit);
3178 }
3179 if (ngAfterContentChecked) {
3180 (tView.contentHooks || (tView.contentHooks = [])).push(i, ngAfterContentChecked);
3181 (tView.contentCheckHooks || (tView.contentCheckHooks = [])).push(i, ngAfterContentChecked);
3182 }
3183 if (ngAfterViewInit) {
3184 (tView.viewHooks || (tView.viewHooks = [])).push(-i, ngAfterViewInit);
3185 }
3186 if (ngAfterViewChecked) {
3187 (tView.viewHooks || (tView.viewHooks = [])).push(i, ngAfterViewChecked);
3188 (tView.viewCheckHooks || (tView.viewCheckHooks = [])).push(i, ngAfterViewChecked);
3189 }
3190 if (ngOnDestroy != null) {
3191 (tView.destroyHooks || (tView.destroyHooks = [])).push(i, ngOnDestroy);
3192 }
3193 }
3194 }
3195 /**
3196 * Executing hooks requires complex logic as we need to deal with 2 constraints.
3197 *
3198 * 1. Init hooks (ngOnInit, ngAfterContentInit, ngAfterViewInit) must all be executed once and only
3199 * once, across many change detection cycles. This must be true even if some hooks throw, or if
3200 * some recursively trigger a change detection cycle.
3201 * To solve that, it is required to track the state of the execution of these init hooks.
3202 * This is done by storing and maintaining flags in the view: the {@link InitPhaseState},
3203 * and the index within that phase. They can be seen as a cursor in the following structure:
3204 * [[onInit1, onInit2], [afterContentInit1], [afterViewInit1, afterViewInit2, afterViewInit3]]
3205 * They are are stored as flags in LView[FLAGS].
3206 *
3207 * 2. Pre-order hooks can be executed in batches, because of the select instruction.
3208 * To be able to pause and resume their execution, we also need some state about the hook's array
3209 * that is being processed:
3210 * - the index of the next hook to be executed
3211 * - the number of init hooks already found in the processed part of the array
3212 * They are are stored as flags in LView[PREORDER_HOOK_FLAGS].
3213 */
3214 /**
3215 * Executes pre-order check hooks ( OnChanges, DoChanges) given a view where all the init hooks were
3216 * executed once. This is a light version of executeInitAndCheckPreOrderHooks where we can skip read
3217 * / write of the init-hooks related flags.
3218 * @param lView The LView where hooks are defined
3219 * @param hooks Hooks to be run
3220 * @param nodeIndex 3 cases depending on the value:
3221 * - undefined: all hooks from the array should be executed (post-order case)
3222 * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
3223 * flushing the remaining hooks)
3224 * - number: execute hooks only from the saved index until that node index exclusive (pre-order
3225 * case, when executing select(number))
3226 */
3227 function executeCheckHooks(lView, hooks, nodeIndex) {
3228 callHooks(lView, hooks, 3 /* InitPhaseCompleted */, nodeIndex);
3229 }
3230 /**
3231 * Executes post-order init and check hooks (one of AfterContentInit, AfterContentChecked,
3232 * AfterViewInit, AfterViewChecked) given a view where there are pending init hooks to be executed.
3233 * @param lView The LView where hooks are defined
3234 * @param hooks Hooks to be run
3235 * @param initPhase A phase for which hooks should be run
3236 * @param nodeIndex 3 cases depending on the value:
3237 * - undefined: all hooks from the array should be executed (post-order case)
3238 * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
3239 * flushing the remaining hooks)
3240 * - number: execute hooks only from the saved index until that node index exclusive (pre-order
3241 * case, when executing select(number))
3242 */
3243 function executeInitAndCheckHooks(lView, hooks, initPhase, nodeIndex) {
3244 ngDevMode &&
3245 assertNotEqual(initPhase, 3 /* InitPhaseCompleted */, 'Init pre-order hooks should not be called more than once');
3246 if ((lView[FLAGS] & 3 /* InitPhaseStateMask */) === initPhase) {
3247 callHooks(lView, hooks, initPhase, nodeIndex);
3248 }
3249 }
3250 function incrementInitPhaseFlags(lView, initPhase) {
3251 ngDevMode &&
3252 assertNotEqual(initPhase, 3 /* InitPhaseCompleted */, 'Init hooks phase should not be incremented after all init hooks have been run.');
3253 var flags = lView[FLAGS];
3254 if ((flags & 3 /* InitPhaseStateMask */) === initPhase) {
3255 flags &= 2047 /* IndexWithinInitPhaseReset */;
3256 flags += 1 /* InitPhaseStateIncrementer */;
3257 lView[FLAGS] = flags;
3258 }
3259 }
3260 /**
3261 * Calls lifecycle hooks with their contexts, skipping init hooks if it's not
3262 * the first LView pass
3263 *
3264 * @param currentView The current view
3265 * @param arr The array in which the hooks are found
3266 * @param initPhaseState the current state of the init phase
3267 * @param currentNodeIndex 3 cases depending on the value:
3268 * - undefined: all hooks from the array should be executed (post-order case)
3269 * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
3270 * flushing the remaining hooks)
3271 * - number: execute hooks only from the saved index until that node index exclusive (pre-order
3272 * case, when executing select(number))
3273 */
3274 function callHooks(currentView, arr, initPhase, currentNodeIndex) {
3275 ngDevMode &&
3276 assertEqual(getCheckNoChangesMode(), false, 'Hooks should never be run in the check no changes mode.');
3277 var startIndex = currentNodeIndex !== undefined ?
3278 (currentView[PREORDER_HOOK_FLAGS] & 65535 /* IndexOfTheNextPreOrderHookMaskMask */) :
3279 0;
3280 var nodeIndexLimit = currentNodeIndex != null ? currentNodeIndex : -1;
3281 var lastNodeIndexFound = 0;
3282 for (var i = startIndex; i < arr.length; i++) {
3283 var hook = arr[i + 1];
3284 if (typeof hook === 'number') {
3285 lastNodeIndexFound = arr[i];
3286 if (currentNodeIndex != null && lastNodeIndexFound >= currentNodeIndex) {
3287 break;
3288 }
3289 }
3290 else {
3291 var isInitHook = arr[i] < 0;
3292 if (isInitHook)
3293 currentView[PREORDER_HOOK_FLAGS] += 65536 /* NumberOfInitHooksCalledIncrementer */;
3294 if (lastNodeIndexFound < nodeIndexLimit || nodeIndexLimit == -1) {
3295 callHook(currentView, initPhase, arr, i);
3296 currentView[PREORDER_HOOK_FLAGS] =
3297 (currentView[PREORDER_HOOK_FLAGS] & 4294901760 /* NumberOfInitHooksCalledMask */) + i +
3298 2;
3299 }
3300 i++;
3301 }
3302 }
3303 }
3304 /**
3305 * Execute one hook against the current `LView`.
3306 *
3307 * @param currentView The current view
3308 * @param initPhaseState the current state of the init phase
3309 * @param arr The array in which the hooks are found
3310 * @param i The current index within the hook data array
3311 */
3312 function callHook(currentView, initPhase, arr, i) {
3313 var isInitHook = arr[i] < 0;
3314 var hook = arr[i + 1];
3315 var directiveIndex = isInitHook ? -arr[i] : arr[i];
3316 var directive = currentView[directiveIndex];
3317 if (isInitHook) {
3318 var indexWithintInitPhase = currentView[FLAGS] >> 11 /* IndexWithinInitPhaseShift */;
3319 // The init phase state must be always checked here as it may have been recursively
3320 // updated
3321 if (indexWithintInitPhase <
3322 (currentView[PREORDER_HOOK_FLAGS] >> 16 /* NumberOfInitHooksCalledShift */) &&
3323 (currentView[FLAGS] & 3 /* InitPhaseStateMask */) === initPhase) {
3324 currentView[FLAGS] += 2048 /* IndexWithinInitPhaseIncrementer */;
3325 hook.call(directive);
3326 }
3327 }
3328 else {
3329 hook.call(directive);
3330 }
3331 }
3332
3333 /**
3334 * @license
3335 * Copyright Google LLC All Rights Reserved.
3336 *
3337 * Use of this source code is governed by an MIT-style license that can be
3338 * found in the LICENSE file at https://angular.io/license
3339 */
3340 var TNODE = 8;
3341 var PARENT_INJECTOR = 8;
3342 var INJECTOR_BLOOM_PARENT_SIZE = 9;
3343 var NO_PARENT_INJECTOR = -1;
3344 /**
3345 * Each injector is saved in 9 contiguous slots in `LView` and 9 contiguous slots in
3346 * `TView.data`. This allows us to store information about the current node's tokens (which
3347 * can be shared in `TView`) as well as the tokens of its ancestor nodes (which cannot be
3348 * shared, so they live in `LView`).
3349 *
3350 * Each of these slots (aside from the last slot) contains a bloom filter. This bloom filter
3351 * determines whether a directive is available on the associated node or not. This prevents us
3352 * from searching the directives array at this level unless it's probable the directive is in it.
3353 *
3354 * See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters.
3355 *
3356 * Because all injectors have been flattened into `LView` and `TViewData`, they cannot typed
3357 * using interfaces as they were previously. The start index of each `LInjector` and `TInjector`
3358 * will differ based on where it is flattened into the main array, so it's not possible to know
3359 * the indices ahead of time and save their types here. The interfaces are still included here
3360 * for documentation purposes.
3361 *
3362 * export interface LInjector extends Array<any> {
3363 *
3364 * // Cumulative bloom for directive IDs 0-31 (IDs are % BLOOM_SIZE)
3365 * [0]: number;
3366 *
3367 * // Cumulative bloom for directive IDs 32-63
3368 * [1]: number;
3369 *
3370 * // Cumulative bloom for directive IDs 64-95
3371 * [2]: number;
3372 *
3373 * // Cumulative bloom for directive IDs 96-127
3374 * [3]: number;
3375 *
3376 * // Cumulative bloom for directive IDs 128-159
3377 * [4]: number;
3378 *
3379 * // Cumulative bloom for directive IDs 160 - 191
3380 * [5]: number;
3381 *
3382 * // Cumulative bloom for directive IDs 192 - 223
3383 * [6]: number;
3384 *
3385 * // Cumulative bloom for directive IDs 224 - 255
3386 * [7]: number;
3387 *
3388 * // We need to store a reference to the injector's parent so DI can keep looking up
3389 * // the injector tree until it finds the dependency it's looking for.
3390 * [PARENT_INJECTOR]: number;
3391 * }
3392 *
3393 * export interface TInjector extends Array<any> {
3394 *
3395 * // Shared node bloom for directive IDs 0-31 (IDs are % BLOOM_SIZE)
3396 * [0]: number;
3397 *
3398 * // Shared node bloom for directive IDs 32-63
3399 * [1]: number;
3400 *
3401 * // Shared node bloom for directive IDs 64-95
3402 * [2]: number;
3403 *
3404 * // Shared node bloom for directive IDs 96-127
3405 * [3]: number;
3406 *
3407 * // Shared node bloom for directive IDs 128-159
3408 * [4]: number;
3409 *
3410 * // Shared node bloom for directive IDs 160 - 191
3411 * [5]: number;
3412 *
3413 * // Shared node bloom for directive IDs 192 - 223
3414 * [6]: number;
3415 *
3416 * // Shared node bloom for directive IDs 224 - 255
3417 * [7]: number;
3418 *
3419 * // Necessary to find directive indices for a particular node.
3420 * [TNODE]: TElementNode|TElementContainerNode|TContainerNode;
3421 * }
3422 */
3423 /**
3424 * Factory for creating instances of injectors in the NodeInjector.
3425 *
3426 * This factory is complicated by the fact that it can resolve `multi` factories as well.
3427 *
3428 * NOTE: Some of the fields are optional which means that this class has two hidden classes.
3429 * - One without `multi` support (most common)
3430 * - One with `multi` values, (rare).
3431 *
3432 * Since VMs can cache up to 4 inline hidden classes this is OK.
3433 *
3434 * - Single factory: Only `resolving` and `factory` is defined.
3435 * - `providers` factory: `componentProviders` is a number and `index = -1`.
3436 * - `viewProviders` factory: `componentProviders` is a number and `index` points to `providers`.
3437 */
3438 var NodeInjectorFactory = /** @class */ (function () {
3439 function NodeInjectorFactory(
3440 /**
3441 * Factory to invoke in order to create a new instance.
3442 */
3443 factory,
3444 /**
3445 * Set to `true` if the token is declared in `viewProviders` (or if it is component).
3446 */
3447 isViewProvider, injectImplementation) {
3448 this.factory = factory;
3449 /**
3450 * Marker set to true during factory invocation to see if we get into recursive loop.
3451 * Recursive loop causes an error to be displayed.
3452 */
3453 this.resolving = false;
3454 this.canSeeViewProviders = isViewProvider;
3455 this.injectImpl = injectImplementation;
3456 }
3457 return NodeInjectorFactory;
3458 }());
3459 function isFactory(obj) {
3460 return obj instanceof NodeInjectorFactory;
3461 }
3462 // Note: This hack is necessary so we don't erroneously get a circular dependency
3463 // failure based on types.
3464 var unusedValueExportToPlacateAjd$3 = 1;
3465
3466 /**
3467 * @license
3468 * Copyright Google LLC All Rights Reserved.
3469 *
3470 * Use of this source code is governed by an MIT-style license that can be
3471 * found in the LICENSE file at https://angular.io/license
3472 */
3473 function assertNodeType(tNode, type) {
3474 assertDefined(tNode, 'should be called with a TNode');
3475 assertEqual(tNode.type, type, "should be a " + typeName(type));
3476 }
3477 function assertNodeOfPossibleTypes(tNode, types, message) {
3478 assertDefined(tNode, 'should be called with a TNode');
3479 var found = types.some(function (type) { return tNode.type === type; });
3480 assertEqual(found, true, message !== null && message !== void 0 ? message : "Should be one of " + types.map(typeName).join(', ') + " but got " + typeName(tNode.type));
3481 }
3482 function assertNodeNotOfTypes(tNode, types, message) {
3483 assertDefined(tNode, 'should be called with a TNode');
3484 var found = types.some(function (type) { return tNode.type === type; });
3485 assertEqual(found, false, message !== null && message !== void 0 ? message : "Should not be one of " + types.map(typeName).join(', ') + " but got " + typeName(tNode.type));
3486 }
3487 function typeName(type) {
3488 if (type == 1 /* Projection */)
3489 return 'Projection';
3490 if (type == 0 /* Container */)
3491 return 'Container';
3492 if (type == 5 /* IcuContainer */)
3493 return 'IcuContainer';
3494 if (type == 2 /* View */)
3495 return 'View';
3496 if (type == 3 /* Element */)
3497 return 'Element';
3498 if (type == 4 /* ElementContainer */)
3499 return 'ElementContainer';
3500 return '<unknown>';
3501 }
3502
3503 /**
3504 * Assigns all attribute values to the provided element via the inferred renderer.
3505 *
3506 * This function accepts two forms of attribute entries:
3507 *
3508 * default: (key, value):
3509 * attrs = [key1, value1, key2, value2]
3510 *
3511 * namespaced: (NAMESPACE_MARKER, uri, name, value)
3512 * attrs = [NAMESPACE_MARKER, uri, name, value, NAMESPACE_MARKER, uri, name, value]
3513 *
3514 * The `attrs` array can contain a mix of both the default and namespaced entries.
3515 * The "default" values are set without a marker, but if the function comes across
3516 * a marker value then it will attempt to set a namespaced value. If the marker is
3517 * not of a namespaced value then the function will quit and return the index value
3518 * where it stopped during the iteration of the attrs array.
3519 *
3520 * See [AttributeMarker] to understand what the namespace marker value is.
3521 *
3522 * Note that this instruction does not support assigning style and class values to
3523 * an element. See `elementStart` and `elementHostAttrs` to learn how styling values
3524 * are applied to an element.
3525 * @param renderer The renderer to be used
3526 * @param native The element that the attributes will be assigned to
3527 * @param attrs The attribute array of values that will be assigned to the element
3528 * @returns the index value that was last accessed in the attributes array
3529 */
3530 function setUpAttributes(renderer, native, attrs) {
3531 var isProc = isProceduralRenderer(renderer);
3532 var i = 0;
3533 while (i < attrs.length) {
3534 var value = attrs[i];
3535 if (typeof value === 'number') {
3536 // only namespaces are supported. Other value types (such as style/class
3537 // entries) are not supported in this function.
3538 if (value !== 0 /* NamespaceURI */) {
3539 break;
3540 }
3541 // we just landed on the marker value ... therefore
3542 // we should skip to the next entry
3543 i++;
3544 var namespaceURI = attrs[i++];
3545 var attrName = attrs[i++];
3546 var attrVal = attrs[i++];
3547 ngDevMode && ngDevMode.rendererSetAttribute++;
3548 isProc ?
3549 renderer.setAttribute(native, attrName, attrVal, namespaceURI) :
3550 native.setAttributeNS(namespaceURI, attrName, attrVal);
3551 }
3552 else {
3553 // attrName is string;
3554 var attrName = value;
3555 var attrVal = attrs[++i];
3556 // Standard attributes
3557 ngDevMode && ngDevMode.rendererSetAttribute++;
3558 if (isAnimationProp(attrName)) {
3559 if (isProc) {
3560 renderer.setProperty(native, attrName, attrVal);
3561 }
3562 }
3563 else {
3564 isProc ?
3565 renderer.setAttribute(native, attrName, attrVal) :
3566 native.setAttribute(attrName, attrVal);
3567 }
3568 i++;
3569 }
3570 }
3571 // another piece of code may iterate over the same attributes array. Therefore
3572 // it may be helpful to return the exact spot where the attributes array exited
3573 // whether by running into an unsupported marker or if all the static values were
3574 // iterated over.
3575 return i;
3576 }
3577 /**
3578 * Test whether the given value is a marker that indicates that the following
3579 * attribute values in a `TAttributes` array are only the names of attributes,
3580 * and not name-value pairs.
3581 * @param marker The attribute marker to test.
3582 * @returns true if the marker is a "name-only" marker (e.g. `Bindings`, `Template` or `I18n`).
3583 */
3584 function isNameOnlyAttributeMarker(marker) {
3585 return marker === 3 /* Bindings */ || marker === 4 /* Template */ ||
3586 marker === 6 /* I18n */;
3587 }
3588 function isAnimationProp(name) {
3589 // Perf note: accessing charCodeAt to check for the first character of a string is faster as
3590 // compared to accessing a character at index 0 (ex. name[0]). The main reason for this is that
3591 // charCodeAt doesn't allocate memory to return a substring.
3592 return name.charCodeAt(0) === 64 /* AT_SIGN */;
3593 }
3594 /**
3595 * Merges `src` `TAttributes` into `dst` `TAttributes` removing any duplicates in the process.
3596 *
3597 * This merge function keeps the order of attrs same.
3598 *
3599 * @param dst Location of where the merged `TAttributes` should end up.
3600 * @param src `TAttributes` which should be appended to `dst`
3601 */
3602 function mergeHostAttrs(dst, src) {
3603 if (src === null || src.length === 0) {
3604 // do nothing
3605 }
3606 else if (dst === null || dst.length === 0) {
3607 // We have source, but dst is empty, just make a copy.
3608 dst = src.slice();
3609 }
3610 else {
3611 var srcMarker = -1 /* ImplicitAttributes */;
3612 for (var i = 0; i < src.length; i++) {
3613 var item = src[i];
3614 if (typeof item === 'number') {
3615 srcMarker = item;
3616 }
3617 else {
3618 if (srcMarker === 0 /* NamespaceURI */) {
3619 // Case where we need to consume `key1`, `key2`, `value` items.
3620 }
3621 else if (srcMarker === -1 /* ImplicitAttributes */ ||
3622 srcMarker === 2 /* Styles */) {
3623 // Case where we have to consume `key1` and `value` only.
3624 mergeHostAttribute(dst, srcMarker, item, null, src[++i]);
3625 }
3626 else {
3627 // Case where we have to consume `key1` only.
3628 mergeHostAttribute(dst, srcMarker, item, null, null);
3629 }
3630 }
3631 }
3632 }
3633 return dst;
3634 }
3635 /**
3636 * Append `key`/`value` to existing `TAttributes` taking region marker and duplicates into account.
3637 *
3638 * @param dst `TAttributes` to append to.
3639 * @param marker Region where the `key`/`value` should be added.
3640 * @param key1 Key to add to `TAttributes`
3641 * @param key2 Key to add to `TAttributes` (in case of `AttributeMarker.NamespaceURI`)
3642 * @param value Value to add or to overwrite to `TAttributes` Only used if `marker` is not Class.
3643 */
3644 function mergeHostAttribute(dst, marker, key1, key2, value) {
3645 var i = 0;
3646 // Assume that new markers will be inserted at the end.
3647 var markerInsertPosition = dst.length;
3648 // scan until correct type.
3649 if (marker === -1 /* ImplicitAttributes */) {
3650 markerInsertPosition = -1;
3651 }
3652 else {
3653 while (i < dst.length) {
3654 var dstValue = dst[i++];
3655 if (typeof dstValue === 'number') {
3656 if (dstValue === marker) {
3657 markerInsertPosition = -1;
3658 break;
3659 }
3660 else if (dstValue > marker) {
3661 // We need to save this as we want the markers to be inserted in specific order.
3662 markerInsertPosition = i - 1;
3663 break;
3664 }
3665 }
3666 }
3667 }
3668 // search until you find place of insertion
3669 while (i < dst.length) {
3670 var item = dst[i];
3671 if (typeof item === 'number') {
3672 // since `i` started as the index after the marker, we did not find it if we are at the next
3673 // marker
3674 break;
3675 }
3676 else if (item === key1) {
3677 // We already have same token
3678 if (key2 === null) {
3679 if (value !== null) {
3680 dst[i + 1] = value;
3681 }
3682 return;
3683 }
3684 else if (key2 === dst[i + 1]) {
3685 dst[i + 2] = value;
3686 return;
3687 }
3688 }
3689 // Increment counter.
3690 i++;
3691 if (key2 !== null)
3692 i++;
3693 if (value !== null)
3694 i++;
3695 }
3696 // insert at location.
3697 if (markerInsertPosition !== -1) {
3698 dst.splice(markerInsertPosition, 0, marker);
3699 i = markerInsertPosition + 1;
3700 }
3701 dst.splice(i++, 0, key1);
3702 if (key2 !== null) {
3703 dst.splice(i++, 0, key2);
3704 }
3705 if (value !== null) {
3706 dst.splice(i++, 0, value);
3707 }
3708 }
3709
3710 /**
3711 * @license
3712 * Copyright Google LLC All Rights Reserved.
3713 *
3714 * Use of this source code is governed by an MIT-style license that can be
3715 * found in the LICENSE file at https://angular.io/license
3716 */
3717 /// Parent Injector Utils ///////////////////////////////////////////////////////////////
3718 function hasParentInjector(parentLocation) {
3719 return parentLocation !== NO_PARENT_INJECTOR;
3720 }
3721 function getParentInjectorIndex(parentLocation) {
3722 return parentLocation & 32767 /* InjectorIndexMask */;
3723 }
3724 function getParentInjectorViewOffset(parentLocation) {
3725 return parentLocation >> 16 /* ViewOffsetShift */;
3726 }
3727 /**
3728 * Unwraps a parent injector location number to find the view offset from the current injector,
3729 * then walks up the declaration view tree until the view is found that contains the parent
3730 * injector.
3731 *
3732 * @param location The location of the parent injector, which contains the view offset
3733 * @param startView The LView instance from which to start walking up the view tree
3734 * @returns The LView instance that contains the parent injector
3735 */
3736 function getParentInjectorView(location, startView) {
3737 var viewOffset = getParentInjectorViewOffset(location);
3738 var parentView = startView;
3739 // For most cases, the parent injector can be found on the host node (e.g. for component
3740 // or container), but we must keep the loop here to support the rarer case of deeply nested
3741 // <ng-template> tags or inline views, where the parent injector might live many views
3742 // above the child injector.
3743 while (viewOffset > 0) {
3744 parentView = parentView[DECLARATION_VIEW];
3745 viewOffset--;
3746 }
3747 return parentView;
3748 }
3749
3750 /**
3751 * @license
3752 * Copyright Google LLC All Rights Reserved.
3753 *
3754 * Use of this source code is governed by an MIT-style license that can be
3755 * found in the LICENSE file at https://angular.io/license
3756 */
3757 /**
3758 * Used for stringify render output in Ivy.
3759 * Important! This function is very performance-sensitive and we should
3760 * be extra careful not to introduce megamorphic reads in it.
3761 */
3762 function renderStringify(value) {
3763 if (typeof value === 'string')
3764 return value;
3765 if (value == null)
3766 return '';
3767 return '' + value;
3768 }
3769 /**
3770 * Used to stringify a value so that it can be displayed in an error message.
3771 * Important! This function contains a megamorphic read and should only be
3772 * used for error messages.
3773 */
3774 function stringifyForError(value) {
3775 if (typeof value === 'function')
3776 return value.name || value.toString();
3777 if (typeof value === 'object' && value != null && typeof value.type === 'function') {
3778 return value.type.name || value.type.toString();
3779 }
3780 return renderStringify(value);
3781 }
3782 var ɵ0$3 = function () { return (typeof requestAnimationFrame !== 'undefined' &&
3783 requestAnimationFrame || // browser only
3784 setTimeout // everything else
3785 )
3786 .bind(_global); };
3787 var defaultScheduler = (ɵ0$3)();
3788 /**
3789 *
3790 * @codeGenApi
3791 */
3792 function ɵɵresolveWindow(element) {
3793 return { name: 'window', target: element.ownerDocument.defaultView };
3794 }
3795 /**
3796 *
3797 * @codeGenApi
3798 */
3799 function ɵɵresolveDocument(element) {
3800 return { name: 'document', target: element.ownerDocument };
3801 }
3802 /**
3803 *
3804 * @codeGenApi
3805 */
3806 function ɵɵresolveBody(element) {
3807 return { name: 'body', target: element.ownerDocument.body };
3808 }
3809 /**
3810 * The special delimiter we use to separate property names, prefixes, and suffixes
3811 * in property binding metadata. See storeBindingMetadata().
3812 *
3813 * We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
3814 * because it is a very uncommon character that is unlikely to be part of a user's
3815 * property names or interpolation strings. If it is in fact used in a property
3816 * binding, DebugElement.properties will not return the correct value for that
3817 * binding. However, there should be no runtime effect for real applications.
3818 *
3819 * This character is typically rendered as a question mark inside of a diamond.
3820 * See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
3821 *
3822 */
3823 var INTERPOLATION_DELIMITER = "\uFFFD";
3824 /**
3825 * Unwrap a value which might be behind a closure (for forward declaration reasons).
3826 */
3827 function maybeUnwrapFn(value) {
3828 if (value instanceof Function) {
3829 return value();
3830 }
3831 else {
3832 return value;
3833 }
3834 }
3835
3836 /**
3837 * @license
3838 * Copyright Google LLC All Rights Reserved.
3839 *
3840 * Use of this source code is governed by an MIT-style license that can be
3841 * found in the LICENSE file at https://angular.io/license
3842 */
3843 /**
3844 * Defines if the call to `inject` should include `viewProviders` in its resolution.
3845 *
3846 * This is set to true when we try to instantiate a component. This value is reset in
3847 * `getNodeInjectable` to a value which matches the declaration location of the token about to be
3848 * instantiated. This is done so that if we are injecting a token which was declared outside of
3849 * `viewProviders` we don't accidentally pull `viewProviders` in.
3850 *
3851 * Example:
3852 *
3853 * ```
3854 * @Injectable()
3855 * class MyService {
3856 * constructor(public value: String) {}
3857 * }
3858 *
3859 * @Component({
3860 * providers: [
3861 * MyService,
3862 * {provide: String, value: 'providers' }
3863 * ]
3864 * viewProviders: [
3865 * {provide: String, value: 'viewProviders'}
3866 * ]
3867 * })
3868 * class MyComponent {
3869 * constructor(myService: MyService, value: String) {
3870 * // We expect that Component can see into `viewProviders`.
3871 * expect(value).toEqual('viewProviders');
3872 * // `MyService` was not declared in `viewProviders` hence it can't see it.
3873 * expect(myService.value).toEqual('providers');
3874 * }
3875 * }
3876 *
3877 * ```
3878 */
3879 var includeViewProviders = true;
3880 function setIncludeViewProviders(v) {
3881 var oldValue = includeViewProviders;
3882 includeViewProviders = v;
3883 return oldValue;
3884 }
3885 /**
3886 * The number of slots in each bloom filter (used by DI). The larger this number, the fewer
3887 * directives that will share slots, and thus, the fewer false positives when checking for
3888 * the existence of a directive.
3889 */
3890 var BLOOM_SIZE = 256;
3891 var BLOOM_MASK = BLOOM_SIZE - 1;
3892 /** Counter used to generate unique IDs for directives. */
3893 var nextNgElementId = 0;
3894 /**
3895 * Registers this directive as present in its node's injector by flipping the directive's
3896 * corresponding bit in the injector's bloom filter.
3897 *
3898 * @param injectorIndex The index of the node injector where this token should be registered
3899 * @param tView The TView for the injector's bloom filters
3900 * @param type The directive token to register
3901 */
3902 function bloomAdd(injectorIndex, tView, type) {
3903 ngDevMode && assertEqual(tView.firstCreatePass, true, 'expected firstCreatePass to be true');
3904 var id;
3905 if (typeof type === 'string') {
3906 id = type.charCodeAt(0) || 0;
3907 }
3908 else if (type.hasOwnProperty(NG_ELEMENT_ID)) {
3909 id = type[NG_ELEMENT_ID];
3910 }
3911 // Set a unique ID on the directive type, so if something tries to inject the directive,
3912 // we can easily retrieve the ID and hash it into the bloom bit that should be checked.
3913 if (id == null) {
3914 id = type[NG_ELEMENT_ID] = nextNgElementId++;
3915 }
3916 // We only have BLOOM_SIZE (256) slots in our bloom filter (8 buckets * 32 bits each),
3917 // so all unique IDs must be modulo-ed into a number from 0 - 255 to fit into the filter.
3918 var bloomBit = id & BLOOM_MASK;
3919 // Create a mask that targets the specific bit associated with the directive.
3920 // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
3921 // to bit positions 0 - 31 in a 32 bit integer.
3922 var mask = 1 << bloomBit;
3923 // Use the raw bloomBit number to determine which bloom filter bucket we should check
3924 // e.g: bf0 = [0 - 31], bf1 = [32 - 63], bf2 = [64 - 95], bf3 = [96 - 127], etc
3925 var b7 = bloomBit & 0x80;
3926 var b6 = bloomBit & 0x40;
3927 var b5 = bloomBit & 0x20;
3928 var tData = tView.data;
3929 if (b7) {
3930 b6 ? (b5 ? (tData[injectorIndex + 7] |= mask) : (tData[injectorIndex + 6] |= mask)) :
3931 (b5 ? (tData[injectorIndex + 5] |= mask) : (tData[injectorIndex + 4] |= mask));
3932 }
3933 else {
3934 b6 ? (b5 ? (tData[injectorIndex + 3] |= mask) : (tData[injectorIndex + 2] |= mask)) :
3935 (b5 ? (tData[injectorIndex + 1] |= mask) : (tData[injectorIndex] |= mask));
3936 }
3937 }
3938 /**
3939 * Creates (or gets an existing) injector for a given element or container.
3940 *
3941 * @param tNode for which an injector should be retrieved / created.
3942 * @param hostView View where the node is stored
3943 * @returns Node injector
3944 */
3945 function getOrCreateNodeInjectorForNode(tNode, hostView) {
3946 var existingInjectorIndex = getInjectorIndex(tNode, hostView);
3947 if (existingInjectorIndex !== -1) {
3948 return existingInjectorIndex;
3949 }
3950 var tView = hostView[TVIEW];
3951 if (tView.firstCreatePass) {
3952 tNode.injectorIndex = hostView.length;
3953 insertBloom(tView.data, tNode); // foundation for node bloom
3954 insertBloom(hostView, null); // foundation for cumulative bloom
3955 insertBloom(tView.blueprint, null);
3956 }
3957 var parentLoc = getParentInjectorLocation(tNode, hostView);
3958 var injectorIndex = tNode.injectorIndex;
3959 // If a parent injector can't be found, its location is set to -1.
3960 // In that case, we don't need to set up a cumulative bloom
3961 if (hasParentInjector(parentLoc)) {
3962 var parentIndex = getParentInjectorIndex(parentLoc);
3963 var parentLView = getParentInjectorView(parentLoc, hostView);
3964 var parentData = parentLView[TVIEW].data;
3965 // Creates a cumulative bloom filter that merges the parent's bloom filter
3966 // and its own cumulative bloom (which contains tokens for all ancestors)
3967 for (var i = 0; i < 8; i++) {
3968 hostView[injectorIndex + i] = parentLView[parentIndex + i] | parentData[parentIndex + i];
3969 }
3970 }
3971 hostView[injectorIndex + PARENT_INJECTOR] = parentLoc;
3972 return injectorIndex;
3973 }
3974 function insertBloom(arr, footer) {
3975 arr.push(0, 0, 0, 0, 0, 0, 0, 0, footer);
3976 }
3977 function getInjectorIndex(tNode, hostView) {
3978 if (tNode.injectorIndex === -1 ||
3979 // If the injector index is the same as its parent's injector index, then the index has been
3980 // copied down from the parent node. No injector has been created yet on this node.
3981 (tNode.parent && tNode.parent.injectorIndex === tNode.injectorIndex) ||
3982 // After the first template pass, the injector index might exist but the parent values
3983 // might not have been calculated yet for this instance
3984 hostView[tNode.injectorIndex + PARENT_INJECTOR] == null) {
3985 return -1;
3986 }
3987 else {
3988 return tNode.injectorIndex;
3989 }
3990 }
3991 /**
3992 * Finds the index of the parent injector, with a view offset if applicable. Used to set the
3993 * parent injector initially.
3994 *
3995 * Returns a combination of number of `ViewData` we have to go up and index in that `Viewdata`
3996 */
3997 function getParentInjectorLocation(tNode, view) {
3998 if (tNode.parent && tNode.parent.injectorIndex !== -1) {
3999 return tNode.parent.injectorIndex; // ViewOffset is 0
4000 }
4001 // For most cases, the parent injector index can be found on the host node (e.g. for component
4002 // or container), so this loop will be skipped, but we must keep the loop here to support
4003 // the rarer case of deeply nested <ng-template> tags or inline views.
4004 var hostTNode = view[T_HOST];
4005 var viewOffset = 1;
4006 while (hostTNode && hostTNode.injectorIndex === -1) {
4007 view = view[DECLARATION_VIEW];
4008 hostTNode = view ? view[T_HOST] : null;
4009 viewOffset++;
4010 }
4011 return hostTNode ?
4012 hostTNode.injectorIndex | (viewOffset << 16 /* ViewOffsetShift */) :
4013 -1;
4014 }
4015 /**
4016 * Makes a type or an injection token public to the DI system by adding it to an
4017 * injector's bloom filter.
4018 *
4019 * @param di The node injector in which a directive will be added
4020 * @param token The type or the injection token to be made public
4021 */
4022 function diPublicInInjector(injectorIndex, tView, token) {
4023 bloomAdd(injectorIndex, tView, token);
4024 }
4025 /**
4026 * Inject static attribute value into directive constructor.
4027 *
4028 * This method is used with `factory` functions which are generated as part of
4029 * `defineDirective` or `defineComponent`. The method retrieves the static value
4030 * of an attribute. (Dynamic attributes are not supported since they are not resolved
4031 * at the time of injection and can change over time.)
4032 *
4033 * # Example
4034 * Given:
4035 * ```
4036 * @Component(...)
4037 * class MyComponent {
4038 * constructor(@Attribute('title') title: string) { ... }
4039 * }
4040 * ```
4041 * When instantiated with
4042 * ```
4043 * <my-component title="Hello"></my-component>
4044 * ```
4045 *
4046 * Then factory method generated is:
4047 * ```
4048 * MyComponent.ɵcmp = defineComponent({
4049 * factory: () => new MyComponent(injectAttribute('title'))
4050 * ...
4051 * })
4052 * ```
4053 *
4054 * @publicApi
4055 */
4056 function injectAttributeImpl(tNode, attrNameToInject) {
4057 ngDevMode &&
4058 assertNodeOfPossibleTypes(tNode, [0 /* Container */, 3 /* Element */, 4 /* ElementContainer */]);
4059 ngDevMode && assertDefined(tNode, 'expecting tNode');
4060 if (attrNameToInject === 'class') {
4061 return tNode.classes;
4062 }
4063 if (attrNameToInject === 'style') {
4064 return tNode.styles;
4065 }
4066 var attrs = tNode.attrs;
4067 if (attrs) {
4068 var attrsLength = attrs.length;
4069 var i = 0;
4070 while (i < attrsLength) {
4071 var value = attrs[i];
4072 // If we hit a `Bindings` or `Template` marker then we are done.
4073 if (isNameOnlyAttributeMarker(value))
4074 break;
4075 // Skip namespaced attributes
4076 if (value === 0 /* NamespaceURI */) {
4077 // we skip the next two values
4078 // as namespaced attributes looks like
4079 // [..., AttributeMarker.NamespaceURI, 'http://someuri.com/test', 'test:exist',
4080 // 'existValue', ...]
4081 i = i + 2;
4082 }
4083 else if (typeof value === 'number') {
4084 // Skip to the first value of the marked attribute.
4085 i++;
4086 while (i < attrsLength && typeof attrs[i] === 'string') {
4087 i++;
4088 }
4089 }
4090 else if (value === attrNameToInject) {
4091 return attrs[i + 1];
4092 }
4093 else {
4094 i = i + 2;
4095 }
4096 }
4097 }
4098 return null;
4099 }
4100 /**
4101 * Returns the value associated to the given token from the NodeInjectors => ModuleInjector.
4102 *
4103 * Look for the injector providing the token by walking up the node injector tree and then
4104 * the module injector tree.
4105 *
4106 * This function patches `token` with `__NG_ELEMENT_ID__` which contains the id for the bloom
4107 * filter. Negative values are reserved for special objects.
4108 * - `-1` is reserved for injecting `Injector` (implemented by `NodeInjector`)
4109 *
4110 * @param tNode The Node where the search for the injector should start
4111 * @param lView The `LView` that contains the `tNode`
4112 * @param token The token to look for
4113 * @param flags Injection flags
4114 * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
4115 * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
4116 */
4117 function getOrCreateInjectable(tNode, lView, token, flags, notFoundValue) {
4118 if (flags === void 0) { flags = exports.InjectFlags.Default; }
4119 if (tNode !== null) {
4120 var bloomHash = bloomHashBitOrFactory(token);
4121 // If the ID stored here is a function, this is a special object like ElementRef or TemplateRef
4122 // so just call the factory function to create it.
4123 if (typeof bloomHash === 'function') {
4124 enterDI(lView, tNode);
4125 try {
4126 var value = bloomHash();
4127 if (value == null && !(flags & exports.InjectFlags.Optional)) {
4128 throw new Error("No provider for " + stringifyForError(token) + "!");
4129 }
4130 else {
4131 return value;
4132 }
4133 }
4134 finally {
4135 leaveDI();
4136 }
4137 }
4138 else if (typeof bloomHash == 'number') {
4139 if (bloomHash === -1) {
4140 // `-1` is a special value used to identify `Injector` types.
4141 return new NodeInjector(tNode, lView);
4142 }
4143 // If the token has a bloom hash, then it is a token which could be in NodeInjector.
4144 // A reference to the previous injector TView that was found while climbing the element
4145 // injector tree. This is used to know if viewProviders can be accessed on the current
4146 // injector.
4147 var previousTView = null;
4148 var injectorIndex = getInjectorIndex(tNode, lView);
4149 var parentLocation = NO_PARENT_INJECTOR;
4150 var hostTElementNode = flags & exports.InjectFlags.Host ? lView[DECLARATION_COMPONENT_VIEW][T_HOST] : null;
4151 // If we should skip this injector, or if there is no injector on this node, start by
4152 // searching
4153 // the parent injector.
4154 if (injectorIndex === -1 || flags & exports.InjectFlags.SkipSelf) {
4155 parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lView) :
4156 lView[injectorIndex + PARENT_INJECTOR];
4157 if (!shouldSearchParent(flags, false)) {
4158 injectorIndex = -1;
4159 }
4160 else {
4161 previousTView = lView[TVIEW];
4162 injectorIndex = getParentInjectorIndex(parentLocation);
4163 lView = getParentInjectorView(parentLocation, lView);
4164 }
4165 }
4166 // Traverse up the injector tree until we find a potential match or until we know there
4167 // *isn't* a match.
4168 while (injectorIndex !== -1) {
4169 parentLocation = lView[injectorIndex + PARENT_INJECTOR];
4170 // Check the current injector. If it matches, see if it contains token.
4171 var tView = lView[TVIEW];
4172 if (bloomHasToken(bloomHash, injectorIndex, tView.data)) {
4173 // At this point, we have an injector which *may* contain the token, so we step through
4174 // the providers and directives associated with the injector's corresponding node to get
4175 // the instance.
4176 var instance = searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode);
4177 if (instance !== NOT_FOUND) {
4178 return instance;
4179 }
4180 }
4181 if (shouldSearchParent(flags, lView[TVIEW].data[injectorIndex + TNODE] === hostTElementNode) &&
4182 bloomHasToken(bloomHash, injectorIndex, lView)) {
4183 // The def wasn't found anywhere on this node, so it was a false positive.
4184 // Traverse up the tree and continue searching.
4185 previousTView = tView;
4186 injectorIndex = getParentInjectorIndex(parentLocation);
4187 lView = getParentInjectorView(parentLocation, lView);
4188 }
4189 else {
4190 // If we should not search parent OR If the ancestor bloom filter value does not have the
4191 // bit corresponding to the directive we can give up on traversing up to find the specific
4192 // injector.
4193 injectorIndex = -1;
4194 }
4195 }
4196 }
4197 }
4198 if (flags & exports.InjectFlags.Optional && notFoundValue === undefined) {
4199 // This must be set or the NullInjector will throw for optional deps
4200 notFoundValue = null;
4201 }
4202 if ((flags & (exports.InjectFlags.Self | exports.InjectFlags.Host)) === 0) {
4203 var moduleInjector = lView[INJECTOR$1];
4204 // switch to `injectInjectorOnly` implementation for module injector, since module injector
4205 // should not have access to Component/Directive DI scope (that may happen through
4206 // `directiveInject` implementation)
4207 var previousInjectImplementation = setInjectImplementation(undefined);
4208 try {
4209 if (moduleInjector) {
4210 return moduleInjector.get(token, notFoundValue, flags & exports.InjectFlags.Optional);
4211 }
4212 else {
4213 return injectRootLimpMode(token, notFoundValue, flags & exports.InjectFlags.Optional);
4214 }
4215 }
4216 finally {
4217 setInjectImplementation(previousInjectImplementation);
4218 }
4219 }
4220 if (flags & exports.InjectFlags.Optional) {
4221 return notFoundValue;
4222 }
4223 else {
4224 throw new Error("NodeInjector: NOT_FOUND [" + stringifyForError(token) + "]");
4225 }
4226 }
4227 var NOT_FOUND = {};
4228 function searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode) {
4229 var currentTView = lView[TVIEW];
4230 var tNode = currentTView.data[injectorIndex + TNODE];
4231 // First, we need to determine if view providers can be accessed by the starting element.
4232 // There are two possibities
4233 var canAccessViewProviders = previousTView == null ?
4234 // 1) This is the first invocation `previousTView == null` which means that we are at the
4235 // `TNode` of where injector is starting to look. In such a case the only time we are allowed
4236 // to look into the ViewProviders is if:
4237 // - we are on a component
4238 // - AND the injector set `includeViewProviders` to true (implying that the token can see
4239 // ViewProviders because it is the Component or a Service which itself was declared in
4240 // ViewProviders)
4241 (isComponentHost(tNode) && includeViewProviders) :
4242 // 2) `previousTView != null` which means that we are now walking across the parent nodes.
4243 // In such a case we are only allowed to look into the ViewProviders if:
4244 // - We just crossed from child View to Parent View `previousTView != currentTView`
4245 // - AND the parent TNode is an Element.
4246 // This means that we just came from the Component's View and therefore are allowed to see
4247 // into the ViewProviders.
4248 (previousTView != currentTView && (tNode.type === 3 /* Element */));
4249 // This special case happens when there is a @host on the inject and when we are searching
4250 // on the host element node.
4251 var isHostSpecialCase = (flags & exports.InjectFlags.Host) && hostTElementNode === tNode;
4252 var injectableIdx = locateDirectiveOrProvider(tNode, currentTView, token, canAccessViewProviders, isHostSpecialCase);
4253 if (injectableIdx !== null) {
4254 return getNodeInjectable(lView, currentTView, injectableIdx, tNode);
4255 }
4256 else {
4257 return NOT_FOUND;
4258 }
4259 }
4260 /**
4261 * Searches for the given token among the node's directives and providers.
4262 *
4263 * @param tNode TNode on which directives are present.
4264 * @param tView The tView we are currently processing
4265 * @param token Provider token or type of a directive to look for.
4266 * @param canAccessViewProviders Whether view providers should be considered.
4267 * @param isHostSpecialCase Whether the host special case applies.
4268 * @returns Index of a found directive or provider, or null when none found.
4269 */
4270 function locateDirectiveOrProvider(tNode, tView, token, canAccessViewProviders, isHostSpecialCase) {
4271 var nodeProviderIndexes = tNode.providerIndexes;
4272 var tInjectables = tView.data;
4273 var injectablesStart = nodeProviderIndexes & 1048575 /* ProvidersStartIndexMask */;
4274 var directivesStart = tNode.directiveStart;
4275 var directiveEnd = tNode.directiveEnd;
4276 var cptViewProvidersCount = nodeProviderIndexes >> 20 /* CptViewProvidersCountShift */;
4277 var startingIndex = canAccessViewProviders ? injectablesStart : injectablesStart + cptViewProvidersCount;
4278 // When the host special case applies, only the viewProviders and the component are visible
4279 var endIndex = isHostSpecialCase ? injectablesStart + cptViewProvidersCount : directiveEnd;
4280 for (var i = startingIndex; i < endIndex; i++) {
4281 var providerTokenOrDef = tInjectables[i];
4282 if (i < directivesStart && token === providerTokenOrDef ||
4283 i >= directivesStart && providerTokenOrDef.type === token) {
4284 return i;
4285 }
4286 }
4287 if (isHostSpecialCase) {
4288 var dirDef = tInjectables[directivesStart];
4289 if (dirDef && isComponentDef(dirDef) && dirDef.type === token) {
4290 return directivesStart;
4291 }
4292 }
4293 return null;
4294 }
4295 /**
4296 * Retrieve or instantiate the injectable from the `LView` at particular `index`.
4297 *
4298 * This function checks to see if the value has already been instantiated and if so returns the
4299 * cached `injectable`. Otherwise if it detects that the value is still a factory it
4300 * instantiates the `injectable` and caches the value.
4301 */
4302 function getNodeInjectable(lView, tView, index, tNode) {
4303 var value = lView[index];
4304 var tData = tView.data;
4305 if (isFactory(value)) {
4306 var factory = value;
4307 if (factory.resolving) {
4308 throw new Error("Circular dep for " + stringifyForError(tData[index]));
4309 }
4310 var previousIncludeViewProviders = setIncludeViewProviders(factory.canSeeViewProviders);
4311 factory.resolving = true;
4312 var previousInjectImplementation = void 0;
4313 if (factory.injectImpl) {
4314 previousInjectImplementation = setInjectImplementation(factory.injectImpl);
4315 }
4316 enterDI(lView, tNode);
4317 try {
4318 value = lView[index] = factory.factory(undefined, tData, lView, tNode);
4319 // This code path is hit for both directives and providers.
4320 // For perf reasons, we want to avoid searching for hooks on providers.
4321 // It does no harm to try (the hooks just won't exist), but the extra
4322 // checks are unnecessary and this is a hot path. So we check to see
4323 // if the index of the dependency is in the directive range for this
4324 // tNode. If it's not, we know it's a provider and skip hook registration.
4325 if (tView.firstCreatePass && index >= tNode.directiveStart) {
4326 ngDevMode && assertDirectiveDef(tData[index]);
4327 registerPreOrderHooks(index, tData[index], tView);
4328 }
4329 }
4330 finally {
4331 if (factory.injectImpl)
4332 setInjectImplementation(previousInjectImplementation);
4333 setIncludeViewProviders(previousIncludeViewProviders);
4334 factory.resolving = false;
4335 leaveDI();
4336 }
4337 }
4338 return value;
4339 }
4340 /**
4341 * Returns the bit in an injector's bloom filter that should be used to determine whether or not
4342 * the directive might be provided by the injector.
4343 *
4344 * When a directive is public, it is added to the bloom filter and given a unique ID that can be
4345 * retrieved on the Type. When the directive isn't public or the token is not a directive `null`
4346 * is returned as the node injector can not possibly provide that token.
4347 *
4348 * @param token the injection token
4349 * @returns the matching bit to check in the bloom filter or `null` if the token is not known.
4350 * When the returned value is negative then it represents special values such as `Injector`.
4351 */
4352 function bloomHashBitOrFactory(token) {
4353 ngDevMode && assertDefined(token, 'token must be defined');
4354 if (typeof token === 'string') {
4355 return token.charCodeAt(0) || 0;
4356 }
4357 var tokenId =
4358 // First check with `hasOwnProperty` so we don't get an inherited ID.
4359 token.hasOwnProperty(NG_ELEMENT_ID) ? token[NG_ELEMENT_ID] : undefined;
4360 // Negative token IDs are used for special objects such as `Injector`
4361 return (typeof tokenId === 'number' && tokenId > 0) ? tokenId & BLOOM_MASK : tokenId;
4362 }
4363 function bloomHasToken(bloomHash, injectorIndex, injectorView) {
4364 // Create a mask that targets the specific bit associated with the directive we're looking for.
4365 // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
4366 // to bit positions 0 - 31 in a 32 bit integer.
4367 var mask = 1 << bloomHash;
4368 var b7 = bloomHash & 0x80;
4369 var b6 = bloomHash & 0x40;
4370 var b5 = bloomHash & 0x20;
4371 // Our bloom filter size is 256 bits, which is eight 32-bit bloom filter buckets:
4372 // bf0 = [0 - 31], bf1 = [32 - 63], bf2 = [64 - 95], bf3 = [96 - 127], etc.
4373 // Get the bloom filter value from the appropriate bucket based on the directive's bloomBit.
4374 var value;
4375 if (b7) {
4376 value = b6 ? (b5 ? injectorView[injectorIndex + 7] : injectorView[injectorIndex + 6]) :
4377 (b5 ? injectorView[injectorIndex + 5] : injectorView[injectorIndex + 4]);
4378 }
4379 else {
4380 value = b6 ? (b5 ? injectorView[injectorIndex + 3] : injectorView[injectorIndex + 2]) :
4381 (b5 ? injectorView[injectorIndex + 1] : injectorView[injectorIndex]);
4382 }
4383 // If the bloom filter value has the bit corresponding to the directive's bloomBit flipped on,
4384 // this injector is a potential match.
4385 return !!(value & mask);
4386 }
4387 /** Returns true if flags prevent parent injector from being searched for tokens */
4388 function shouldSearchParent(flags, isFirstHostTNode) {
4389 return !(flags & exports.InjectFlags.Self) && !(flags & exports.InjectFlags.Host && isFirstHostTNode);
4390 }
4391 var NodeInjector = /** @class */ (function () {
4392 function NodeInjector(_tNode, _lView) {
4393 this._tNode = _tNode;
4394 this._lView = _lView;
4395 }
4396 NodeInjector.prototype.get = function (token, notFoundValue) {
4397 return getOrCreateInjectable(this._tNode, this._lView, token, undefined, notFoundValue);
4398 };
4399 return NodeInjector;
4400 }());
4401 /**
4402 * @codeGenApi
4403 */
4404 function ɵɵgetFactoryOf(type) {
4405 var typeAny = type;
4406 if (isForwardRef(type)) {
4407 return (function () {
4408 var factory = ɵɵgetFactoryOf(resolveForwardRef(typeAny));
4409 return factory ? factory() : null;
4410 });
4411 }
4412 var factory = getFactoryDef(typeAny);
4413 if (factory === null) {
4414 var injectorDef = getInjectorDef(typeAny);
4415 factory = injectorDef && injectorDef.factory;
4416 }
4417 return factory || null;
4418 }
4419 /**
4420 * @codeGenApi
4421 */
4422 function ɵɵgetInheritedFactory(type) {
4423 return noSideEffects(function () {
4424 var ownConstructor = type.prototype.constructor;
4425 var ownFactory = ownConstructor[NG_FACTORY_DEF] || ɵɵgetFactoryOf(ownConstructor);
4426 var objectPrototype = Object.prototype;
4427 var parent = Object.getPrototypeOf(type.prototype).constructor;
4428 // Go up the prototype until we hit `Object`.
4429 while (parent && parent !== objectPrototype) {
4430 var factory = parent[NG_FACTORY_DEF] || ɵɵgetFactoryOf(parent);
4431 // If we hit something that has a factory and the factory isn't the same as the type,
4432 // we've found the inherited factory. Note the check that the factory isn't the type's
4433 // own factory is redundant in most cases, but if the user has custom decorators on the
4434 // class, this lookup will start one level down in the prototype chain, causing us to
4435 // find the own factory first and potentially triggering an infinite loop downstream.
4436 if (factory && factory !== ownFactory) {
4437 return factory;
4438 }
4439 parent = Object.getPrototypeOf(parent);
4440 }
4441 // There is no factory defined. Either this was improper usage of inheritance
4442 // (no Angular decorator on the superclass) or there is no constructor at all
4443 // in the inheritance chain. Since the two cases cannot be distinguished, the
4444 // latter has to be assumed.
4445 return function (t) { return new t(); };
4446 });
4447 }
4448
4449 /**
4450 * @license
4451 * Copyright Google LLC All Rights Reserved.
4452 *
4453 * Use of this source code is governed by an MIT-style license that can be
4454 * found in the LICENSE file at https://angular.io/license
4455 */
4456 var ERROR_TYPE = 'ngType';
4457 var ERROR_DEBUG_CONTEXT = 'ngDebugContext';
4458 var ERROR_ORIGINAL_ERROR = 'ngOriginalError';
4459 var ERROR_LOGGER = 'ngErrorLogger';
4460 function wrappedError(message, originalError) {
4461 var msg = message + " caused by: " + (originalError instanceof Error ? originalError.message : originalError);
4462 var error = Error(msg);
4463 error[ERROR_ORIGINAL_ERROR] = originalError;
4464 return error;
4465 }
4466
4467 function getType(error) {
4468 return error[ERROR_TYPE];
4469 }
4470 function getDebugContext(error) {
4471 return error[ERROR_DEBUG_CONTEXT];
4472 }
4473 function getOriginalError(error) {
4474 return error[ERROR_ORIGINAL_ERROR];
4475 }
4476 function getErrorLogger(error) {
4477 return error[ERROR_LOGGER] || defaultErrorLogger;
4478 }
4479 function defaultErrorLogger(console) {
4480 var values = [];
4481 for (var _i = 1; _i < arguments.length; _i++) {
4482 values[_i - 1] = arguments[_i];
4483 }
4484 console.error.apply(console, __spread(values));
4485 }
4486
4487 /**
4488 * @license
4489 * Copyright Google LLC All Rights Reserved.
4490 *
4491 * Use of this source code is governed by an MIT-style license that can be
4492 * found in the LICENSE file at https://angular.io/license
4493 */
4494 /**
4495 * Provides a hook for centralized exception handling.
4496 *
4497 * The default implementation of `ErrorHandler` prints error messages to the `console`. To
4498 * intercept error handling, write a custom exception handler that replaces this default as
4499 * appropriate for your app.
4500 *
4501 * @usageNotes
4502 * ### Example
4503 *
4504 * ```
4505 * class MyErrorHandler implements ErrorHandler {
4506 * handleError(error) {
4507 * // do something with the exception
4508 * }
4509 * }
4510 *
4511 * @NgModule({
4512 * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
4513 * })
4514 * class MyModule {}
4515 * ```
4516 *
4517 * @publicApi
4518 */
4519 var ErrorHandler = /** @class */ (function () {
4520 function ErrorHandler() {
4521 /**
4522 * @internal
4523 */
4524 this._console = console;
4525 }
4526 ErrorHandler.prototype.handleError = function (error) {
4527 var originalError = this._findOriginalError(error);
4528 var context = this._findContext(error);
4529 // Note: Browser consoles show the place from where console.error was called.
4530 // We can use this to give users additional information about the error.
4531 var errorLogger = getErrorLogger(error);
4532 errorLogger(this._console, "ERROR", error);
4533 if (originalError) {
4534 errorLogger(this._console, "ORIGINAL ERROR", originalError);
4535 }
4536 if (context) {
4537 errorLogger(this._console, 'ERROR CONTEXT', context);
4538 }
4539 };
4540 /** @internal */
4541 ErrorHandler.prototype._findContext = function (error) {
4542 if (error) {
4543 return getDebugContext(error) ? getDebugContext(error) :
4544 this._findContext(getOriginalError(error));
4545 }
4546 return null;
4547 };
4548 /** @internal */
4549 ErrorHandler.prototype._findOriginalError = function (error) {
4550 var e = getOriginalError(error);
4551 while (e && getOriginalError(e)) {
4552 e = getOriginalError(e);
4553 }
4554 return e;
4555 };
4556 return ErrorHandler;
4557 }());
4558
4559 /**
4560 * @license
4561 * Copyright Google LLC All Rights Reserved.
4562 *
4563 * Use of this source code is governed by an MIT-style license that can be
4564 * found in the LICENSE file at https://angular.io/license
4565 */
4566 /**
4567 * Defines a schema that allows an NgModule to contain the following:
4568 * - Non-Angular elements named with dash case (`-`).
4569 * - Element properties named with dash case (`-`).
4570 * Dash case is the naming convention for custom elements.
4571 *
4572 * @publicApi
4573 */
4574 var CUSTOM_ELEMENTS_SCHEMA = {
4575 name: 'custom-elements'
4576 };
4577 /**
4578 * Defines a schema that allows any property on any element.
4579 *
4580 * @publicApi
4581 */
4582 var NO_ERRORS_SCHEMA = {
4583 name: 'no-errors-schema'
4584 };
4585
4586 /**
4587 * @license
4588 * Copyright Google LLC All Rights Reserved.
4589 *
4590 * Use of this source code is governed by an MIT-style license that can be
4591 * found in the LICENSE file at https://angular.io/license
4592 */
4593 var SafeValueImpl = /** @class */ (function () {
4594 function SafeValueImpl(changingThisBreaksApplicationSecurity) {
4595 this.changingThisBreaksApplicationSecurity = changingThisBreaksApplicationSecurity;
4596 }
4597 SafeValueImpl.prototype.toString = function () {
4598 return "SafeValue must use [property]=binding: " + this.changingThisBreaksApplicationSecurity +
4599 " (see http://g.co/ng/security#xss)";
4600 };
4601 return SafeValueImpl;
4602 }());
4603 var SafeHtmlImpl = /** @class */ (function (_super) {
4604 __extends(SafeHtmlImpl, _super);
4605 function SafeHtmlImpl() {
4606 return _super !== null && _super.apply(this, arguments) || this;
4607 }
4608 SafeHtmlImpl.prototype.getTypeName = function () {
4609 return "HTML" /* Html */;
4610 };
4611 return SafeHtmlImpl;
4612 }(SafeValueImpl));
4613 var SafeStyleImpl = /** @class */ (function (_super) {
4614 __extends(SafeStyleImpl, _super);
4615 function SafeStyleImpl() {
4616 return _super !== null && _super.apply(this, arguments) || this;
4617 }
4618 SafeStyleImpl.prototype.getTypeName = function () {
4619 return "Style" /* Style */;
4620 };
4621 return SafeStyleImpl;
4622 }(SafeValueImpl));
4623 var SafeScriptImpl = /** @class */ (function (_super) {
4624 __extends(SafeScriptImpl, _super);
4625 function SafeScriptImpl() {
4626 return _super !== null && _super.apply(this, arguments) || this;
4627 }
4628 SafeScriptImpl.prototype.getTypeName = function () {
4629 return "Script" /* Script */;
4630 };
4631 return SafeScriptImpl;
4632 }(SafeValueImpl));
4633 var SafeUrlImpl = /** @class */ (function (_super) {
4634 __extends(SafeUrlImpl, _super);
4635 function SafeUrlImpl() {
4636 return _super !== null && _super.apply(this, arguments) || this;
4637 }
4638 SafeUrlImpl.prototype.getTypeName = function () {
4639 return "URL" /* Url */;
4640 };
4641 return SafeUrlImpl;
4642 }(SafeValueImpl));
4643 var SafeResourceUrlImpl = /** @class */ (function (_super) {
4644 __extends(SafeResourceUrlImpl, _super);
4645 function SafeResourceUrlImpl() {
4646 return _super !== null && _super.apply(this, arguments) || this;
4647 }
4648 SafeResourceUrlImpl.prototype.getTypeName = function () {
4649 return "ResourceURL" /* ResourceUrl */;
4650 };
4651 return SafeResourceUrlImpl;
4652 }(SafeValueImpl));
4653 function unwrapSafeValue(value) {
4654 return value instanceof SafeValueImpl ? value.changingThisBreaksApplicationSecurity :
4655 value;
4656 }
4657 function allowSanitizationBypassAndThrow(value, type) {
4658 var actualType = getSanitizationBypassType(value);
4659 if (actualType != null && actualType !== type) {
4660 // Allow ResourceURLs in URL contexts, they are strictly more trusted.
4661 if (actualType === "ResourceURL" /* ResourceUrl */ && type === "URL" /* Url */)
4662 return true;
4663 throw new Error("Required a safe " + type + ", got a " + actualType + " (see http://g.co/ng/security#xss)");
4664 }
4665 return actualType === type;
4666 }
4667 function getSanitizationBypassType(value) {
4668 return value instanceof SafeValueImpl && value.getTypeName() || null;
4669 }
4670 /**
4671 * Mark `html` string as trusted.
4672 *
4673 * This function wraps the trusted string in `String` and brands it in a way which makes it
4674 * recognizable to {@link htmlSanitizer} to be trusted implicitly.
4675 *
4676 * @param trustedHtml `html` string which needs to be implicitly trusted.
4677 * @returns a `html` which has been branded to be implicitly trusted.
4678 */
4679 function bypassSanitizationTrustHtml(trustedHtml) {
4680 return new SafeHtmlImpl(trustedHtml);
4681 }
4682 /**
4683 * Mark `style` string as trusted.
4684 *
4685 * This function wraps the trusted string in `String` and brands it in a way which makes it
4686 * recognizable to {@link styleSanitizer} to be trusted implicitly.
4687 *
4688 * @param trustedStyle `style` string which needs to be implicitly trusted.
4689 * @returns a `style` hich has been branded to be implicitly trusted.
4690 */
4691 function bypassSanitizationTrustStyle(trustedStyle) {
4692 return new SafeStyleImpl(trustedStyle);
4693 }
4694 /**
4695 * Mark `script` string as trusted.
4696 *
4697 * This function wraps the trusted string in `String` and brands it in a way which makes it
4698 * recognizable to {@link scriptSanitizer} to be trusted implicitly.
4699 *
4700 * @param trustedScript `script` string which needs to be implicitly trusted.
4701 * @returns a `script` which has been branded to be implicitly trusted.
4702 */
4703 function bypassSanitizationTrustScript(trustedScript) {
4704 return new SafeScriptImpl(trustedScript);
4705 }
4706 /**
4707 * Mark `url` string as trusted.
4708 *
4709 * This function wraps the trusted string in `String` and brands it in a way which makes it
4710 * recognizable to {@link urlSanitizer} to be trusted implicitly.
4711 *
4712 * @param trustedUrl `url` string which needs to be implicitly trusted.
4713 * @returns a `url` which has been branded to be implicitly trusted.
4714 */
4715 function bypassSanitizationTrustUrl(trustedUrl) {
4716 return new SafeUrlImpl(trustedUrl);
4717 }
4718 /**
4719 * Mark `url` string as trusted.
4720 *
4721 * This function wraps the trusted string in `String` and brands it in a way which makes it
4722 * recognizable to {@link resourceUrlSanitizer} to be trusted implicitly.
4723 *
4724 * @param trustedResourceUrl `url` string which needs to be implicitly trusted.
4725 * @returns a `url` which has been branded to be implicitly trusted.
4726 */
4727 function bypassSanitizationTrustResourceUrl(trustedResourceUrl) {
4728 return new SafeResourceUrlImpl(trustedResourceUrl);
4729 }
4730
4731 /**
4732 * @license
4733 * Copyright Google LLC All Rights Reserved.
4734 *
4735 * Use of this source code is governed by an MIT-style license that can be
4736 * found in the LICENSE file at https://angular.io/license
4737 */
4738 /**
4739 * This file is used to control if the default rendering pipeline should be `ViewEngine` or `Ivy`.
4740 *
4741 * For more information on how to run and debug tests with either Ivy or View Engine (legacy),
4742 * please see [BAZEL.md](./docs/BAZEL.md).
4743 */
4744 var _devMode = true;
4745 var _runModeLocked = false;
4746 /**
4747 * Returns whether Angular is in development mode. After called once,
4748 * the value is locked and won't change any more.
4749 *
4750 * By default, this is true, unless a user calls `enableProdMode` before calling this.
4751 *
4752 * @publicApi
4753 */
4754 function isDevMode() {
4755 _runModeLocked = true;
4756 return _devMode;
4757 }
4758 /**
4759 * Disable Angular's development mode, which turns off assertions and other
4760 * checks within the framework.
4761 *
4762 * One important assertion this disables verifies that a change detection pass
4763 * does not result in additional changes to any bindings (also known as
4764 * unidirectional data flow).
4765 *
4766 * @publicApi
4767 */
4768 function enableProdMode() {
4769 if (_runModeLocked) {
4770 throw new Error('Cannot enable prod mode after platform setup.');
4771 }
4772 _devMode = false;
4773 }
4774
4775 /**
4776 * @license
4777 * Copyright Google LLC All Rights Reserved.
4778 *
4779 * Use of this source code is governed by an MIT-style license that can be
4780 * found in the LICENSE file at https://angular.io/license
4781 */
4782 /**
4783 * This helper is used to get hold of an inert tree of DOM elements containing dirty HTML
4784 * that needs sanitizing.
4785 * Depending upon browser support we use one of two strategies for doing this.
4786 * Default: DOMParser strategy
4787 * Fallback: InertDocument strategy
4788 */
4789 function getInertBodyHelper(defaultDoc) {
4790 return isDOMParserAvailable() ? new DOMParserHelper() : new InertDocumentHelper(defaultDoc);
4791 }
4792 /**
4793 * Uses DOMParser to create and fill an inert body element.
4794 * This is the default strategy used in browsers that support it.
4795 */
4796 var DOMParserHelper = /** @class */ (function () {
4797 function DOMParserHelper() {
4798 }
4799 DOMParserHelper.prototype.getInertBodyElement = function (html) {
4800 // We add these extra elements to ensure that the rest of the content is parsed as expected
4801 // e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the
4802 // `<head>` tag.
4803 html = '<body><remove></remove>' + html + '</body>';
4804 try {
4805 var body = new window.DOMParser().parseFromString(html, 'text/html').body;
4806 body.removeChild(body.firstChild);
4807 return body;
4808 }
4809 catch (_a) {
4810 return null;
4811 }
4812 };
4813 return DOMParserHelper;
4814 }());
4815 /**
4816 * Use an HTML5 `template` element, if supported, or an inert body element created via
4817 * `createHtmlDocument` to create and fill an inert DOM element.
4818 * This is the fallback strategy if the browser does not support DOMParser.
4819 */
4820 var InertDocumentHelper = /** @class */ (function () {
4821 function InertDocumentHelper(defaultDoc) {
4822 this.defaultDoc = defaultDoc;
4823 this.inertDocument = this.defaultDoc.implementation.createHTMLDocument('sanitization-inert');
4824 if (this.inertDocument.body == null) {
4825 // usually there should be only one body element in the document, but IE doesn't have any, so
4826 // we need to create one.
4827 var inertHtml = this.inertDocument.createElement('html');
4828 this.inertDocument.appendChild(inertHtml);
4829 var inertBodyElement = this.inertDocument.createElement('body');
4830 inertHtml.appendChild(inertBodyElement);
4831 }
4832 }
4833 InertDocumentHelper.prototype.getInertBodyElement = function (html) {
4834 // Prefer using <template> element if supported.
4835 var templateEl = this.inertDocument.createElement('template');
4836 if ('content' in templateEl) {
4837 templateEl.innerHTML = html;
4838 return templateEl;
4839 }
4840 // Note that previously we used to do something like `this.inertDocument.body.innerHTML = html`
4841 // and we returned the inert `body` node. This was changed, because IE seems to treat setting
4842 // `innerHTML` on an inserted element differently, compared to one that hasn't been inserted
4843 // yet. In particular, IE appears to split some of the text into multiple text nodes rather
4844 // than keeping them in a single one which ends up messing with Ivy's i18n parsing further
4845 // down the line. This has been worked around by creating a new inert `body` and using it as
4846 // the root node in which we insert the HTML.
4847 var inertBody = this.inertDocument.createElement('body');
4848 inertBody.innerHTML = html;
4849 // Support: IE 9-11 only
4850 // strip custom-namespaced attributes on IE<=11
4851 if (this.defaultDoc.documentMode) {
4852 this.stripCustomNsAttrs(inertBody);
4853 }
4854 return inertBody;
4855 };
4856 /**
4857 * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1'
4858 * attribute to declare ns1 namespace and prefixes the attribute with 'ns1' (e.g.
4859 * 'ns1:xlink:foo').
4860 *
4861 * This is undesirable since we don't want to allow any of these custom attributes. This method
4862 * strips them all.
4863 */
4864 InertDocumentHelper.prototype.stripCustomNsAttrs = function (el) {
4865 var elAttrs = el.attributes;
4866 // loop backwards so that we can support removals.
4867 for (var i = elAttrs.length - 1; 0 < i; i--) {
4868 var attrib = elAttrs.item(i);
4869 var attrName = attrib.name;
4870 if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) {
4871 el.removeAttribute(attrName);
4872 }
4873 }
4874 var childNode = el.firstChild;
4875 while (childNode) {
4876 if (childNode.nodeType === Node.ELEMENT_NODE)
4877 this.stripCustomNsAttrs(childNode);
4878 childNode = childNode.nextSibling;
4879 }
4880 };
4881 return InertDocumentHelper;
4882 }());
4883 /**
4884 * We need to determine whether the DOMParser exists in the global context and
4885 * supports parsing HTML; HTML parsing support is not as wide as other formats, see
4886 * https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Browser_compatibility.
4887 *
4888 * @suppress {uselessCode}
4889 */
4890 function isDOMParserAvailable() {
4891 try {
4892 return !!new window.DOMParser().parseFromString('', 'text/html');
4893 }
4894 catch (_a) {
4895 return false;
4896 }
4897 }
4898
4899 /**
4900 * @license
4901 * Copyright Google LLC All Rights Reserved.
4902 *
4903 * Use of this source code is governed by an MIT-style license that can be
4904 * found in the LICENSE file at https://angular.io/license
4905 */
4906 /**
4907 * A pattern that recognizes a commonly useful subset of URLs that are safe.
4908 *
4909 * This regular expression matches a subset of URLs that will not cause script
4910 * execution if used in URL context within a HTML document. Specifically, this
4911 * regular expression matches if (comment from here on and regex copied from
4912 * Soy's EscapingConventions):
4913 * (1) Either an allowed protocol (http, https, mailto or ftp).
4914 * (2) or no protocol. A protocol must be followed by a colon. The below
4915 * allows that by allowing colons only after one of the characters [/?#].
4916 * A colon after a hash (#) must be in the fragment.
4917 * Otherwise, a colon after a (?) must be in a query.
4918 * Otherwise, a colon after a single solidus (/) must be in a path.
4919 * Otherwise, a colon after a double solidus (//) must be in the authority
4920 * (before port).
4921 *
4922 * The pattern disallows &, used in HTML entity declarations before
4923 * one of the characters in [/?#]. This disallows HTML entities used in the
4924 * protocol name, which should never happen, e.g. "h&#116;tp" for "http".
4925 * It also disallows HTML entities in the first path part of a relative path,
4926 * e.g. "foo&lt;bar/baz". Our existing escaping functions should not produce
4927 * that. More importantly, it disallows masking of a colon,
4928 * e.g. "javascript&#58;...".
4929 *
4930 * This regular expression was taken from the Closure sanitization library.
4931 */
4932 var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
4933 /* A pattern that matches safe srcset values */
4934 var SAFE_SRCSET_PATTERN = /^(?:(?:https?|file):|[^&:/?#]*(?:[/?#]|$))/gi;
4935 /** A pattern that matches safe data URLs. Only matches image, video and audio types. */
4936 var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i;
4937 function _sanitizeUrl(url) {
4938 url = String(url);
4939 if (url.match(SAFE_URL_PATTERN) || url.match(DATA_URL_PATTERN))
4940 return url;
4941 if (isDevMode()) {
4942 console.warn("WARNING: sanitizing unsafe URL value " + url + " (see http://g.co/ng/security#xss)");
4943 }
4944 return 'unsafe:' + url;
4945 }
4946 function sanitizeSrcset(srcset) {
4947 srcset = String(srcset);
4948 return srcset.split(',').map(function (srcset) { return _sanitizeUrl(srcset.trim()); }).join(', ');
4949 }
4950
4951 function tagSet(tags) {
4952 var e_1, _a;
4953 var res = {};
4954 try {
4955 for (var _b = __values(tags.split(',')), _c = _b.next(); !_c.done; _c = _b.next()) {
4956 var t = _c.value;
4957 res[t] = true;
4958 }
4959 }
4960 catch (e_1_1) { e_1 = { error: e_1_1 }; }
4961 finally {
4962 try {
4963 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
4964 }
4965 finally { if (e_1) throw e_1.error; }
4966 }
4967 return res;
4968 }
4969 function merge() {
4970 var e_2, _a;
4971 var sets = [];
4972 for (var _i = 0; _i < arguments.length; _i++) {
4973 sets[_i] = arguments[_i];
4974 }
4975 var res = {};
4976 try {
4977 for (var sets_1 = __values(sets), sets_1_1 = sets_1.next(); !sets_1_1.done; sets_1_1 = sets_1.next()) {
4978 var s = sets_1_1.value;
4979 for (var v in s) {
4980 if (s.hasOwnProperty(v))
4981 res[v] = true;
4982 }
4983 }
4984 }
4985 catch (e_2_1) { e_2 = { error: e_2_1 }; }
4986 finally {
4987 try {
4988 if (sets_1_1 && !sets_1_1.done && (_a = sets_1.return)) _a.call(sets_1);
4989 }
4990 finally { if (e_2) throw e_2.error; }
4991 }
4992 return res;
4993 }
4994 // Good source of info about elements and attributes
4995 // http://dev.w3.org/html5/spec/Overview.html#semantics
4996 // http://simon.html5.org/html-elements
4997 // Safe Void Elements - HTML5
4998 // http://dev.w3.org/html5/spec/Overview.html#void-elements
4999 var VOID_ELEMENTS = tagSet('area,br,col,hr,img,wbr');
5000 // Elements that you can, intentionally, leave open (and which close themselves)
5001 // http://dev.w3.org/html5/spec/Overview.html#optional-tags
5002 var OPTIONAL_END_TAG_BLOCK_ELEMENTS = tagSet('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr');
5003 var OPTIONAL_END_TAG_INLINE_ELEMENTS = tagSet('rp,rt');
5004 var OPTIONAL_END_TAG_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, OPTIONAL_END_TAG_BLOCK_ELEMENTS);
5005 // Safe Block Elements - HTML5
5006 var BLOCK_ELEMENTS = merge(OPTIONAL_END_TAG_BLOCK_ELEMENTS, tagSet('address,article,' +
5007 'aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
5008 'h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul'));
5009 // Inline Elements - HTML5
5010 var INLINE_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, tagSet('a,abbr,acronym,audio,b,' +
5011 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,' +
5012 'samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video'));
5013 var VALID_ELEMENTS = merge(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS);
5014 // Attributes that have href and hence need to be sanitized
5015 var URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href');
5016 // Attributes that have special href set hence need to be sanitized
5017 var SRCSET_ATTRS = tagSet('srcset');
5018 var HTML_ATTRS = tagSet('abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' +
5019 'compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,' +
5020 'ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,' +
5021 'scope,scrolling,shape,size,sizes,span,srclang,start,summary,tabindex,target,title,translate,type,usemap,' +
5022 'valign,value,vspace,width');
5023 // Accessibility attributes as per WAI-ARIA 1.1 (W3C Working Draft 14 December 2018)
5024 var ARIA_ATTRS = tagSet('aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,' +
5025 'aria-colspan,aria-controls,aria-current,aria-describedby,aria-details,aria-disabled,aria-dropeffect,' +
5026 'aria-errormessage,aria-expanded,aria-flowto,aria-grabbed,aria-haspopup,aria-hidden,aria-invalid,' +
5027 'aria-keyshortcuts,aria-label,aria-labelledby,aria-level,aria-live,aria-modal,aria-multiline,' +
5028 'aria-multiselectable,aria-orientation,aria-owns,aria-placeholder,aria-posinset,aria-pressed,aria-readonly,' +
5029 'aria-relevant,aria-required,aria-roledescription,aria-rowcount,aria-rowindex,aria-rowspan,aria-selected,' +
5030 'aria-setsize,aria-sort,aria-valuemax,aria-valuemin,aria-valuenow,aria-valuetext');
5031 // NB: This currently consciously doesn't support SVG. SVG sanitization has had several security
5032 // issues in the past, so it seems safer to leave it out if possible. If support for binding SVG via
5033 // innerHTML is required, SVG attributes should be added here.
5034 // NB: Sanitization does not allow <form> elements or other active elements (<button> etc). Those
5035 // can be sanitized, but they increase security surface area without a legitimate use case, so they
5036 // are left out here.
5037 var VALID_ATTRS = merge(URI_ATTRS, SRCSET_ATTRS, HTML_ATTRS, ARIA_ATTRS);
5038 // Elements whose content should not be traversed/preserved, if the elements themselves are invalid.
5039 //
5040 // Typically, `<invalid>Some content</invalid>` would traverse (and in this case preserve)
5041 // `Some content`, but strip `invalid-element` opening/closing tags. For some elements, though, we
5042 // don't want to preserve the content, if the elements themselves are going to be removed.
5043 var SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS = tagSet('script,style,template');
5044 /**
5045 * SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
5046 * attributes.
5047 */
5048 var SanitizingHtmlSerializer = /** @class */ (function () {
5049 function SanitizingHtmlSerializer() {
5050 // Explicitly track if something was stripped, to avoid accidentally warning of sanitization just
5051 // because characters were re-encoded.
5052 this.sanitizedSomething = false;
5053 this.buf = [];
5054 }
5055 SanitizingHtmlSerializer.prototype.sanitizeChildren = function (el) {
5056 // This cannot use a TreeWalker, as it has to run on Angular's various DOM adapters.
5057 // However this code never accesses properties off of `document` before deleting its contents
5058 // again, so it shouldn't be vulnerable to DOM clobbering.
5059 var current = el.firstChild;
5060 var traverseContent = true;
5061 while (current) {
5062 if (current.nodeType === Node.ELEMENT_NODE) {
5063 traverseContent = this.startElement(current);
5064 }
5065 else if (current.nodeType === Node.TEXT_NODE) {
5066 this.chars(current.nodeValue);
5067 }
5068 else {
5069 // Strip non-element, non-text nodes.
5070 this.sanitizedSomething = true;
5071 }
5072 if (traverseContent && current.firstChild) {
5073 current = current.firstChild;
5074 continue;
5075 }
5076 while (current) {
5077 // Leaving the element. Walk up and to the right, closing tags as we go.
5078 if (current.nodeType === Node.ELEMENT_NODE) {
5079 this.endElement(current);
5080 }
5081 var next = this.checkClobberedElement(current, current.nextSibling);
5082 if (next) {
5083 current = next;
5084 break;
5085 }
5086 current = this.checkClobberedElement(current, current.parentNode);
5087 }
5088 }
5089 return this.buf.join('');
5090 };
5091 /**
5092 * Sanitizes an opening element tag (if valid) and returns whether the element's contents should
5093 * be traversed. Element content must always be traversed (even if the element itself is not
5094 * valid/safe), unless the element is one of `SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS`.
5095 *
5096 * @param element The element to sanitize.
5097 * @return True if the element's contents should be traversed.
5098 */
5099 SanitizingHtmlSerializer.prototype.startElement = function (element) {
5100 var tagName = element.nodeName.toLowerCase();
5101 if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
5102 this.sanitizedSomething = true;
5103 return !SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS.hasOwnProperty(tagName);
5104 }
5105 this.buf.push('<');
5106 this.buf.push(tagName);
5107 var elAttrs = element.attributes;
5108 for (var i = 0; i < elAttrs.length; i++) {
5109 var elAttr = elAttrs.item(i);
5110 var attrName = elAttr.name;
5111 var lower = attrName.toLowerCase();
5112 if (!VALID_ATTRS.hasOwnProperty(lower)) {
5113 this.sanitizedSomething = true;
5114 continue;
5115 }
5116 var value = elAttr.value;
5117 // TODO(martinprobst): Special case image URIs for data:image/...
5118 if (URI_ATTRS[lower])
5119 value = _sanitizeUrl(value);
5120 if (SRCSET_ATTRS[lower])
5121 value = sanitizeSrcset(value);
5122 this.buf.push(' ', attrName, '="', encodeEntities(value), '"');
5123 }
5124 this.buf.push('>');
5125 return true;
5126 };
5127 SanitizingHtmlSerializer.prototype.endElement = function (current) {
5128 var tagName = current.nodeName.toLowerCase();
5129 if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
5130 this.buf.push('</');
5131 this.buf.push(tagName);
5132 this.buf.push('>');
5133 }
5134 };
5135 SanitizingHtmlSerializer.prototype.chars = function (chars) {
5136 this.buf.push(encodeEntities(chars));
5137 };
5138 SanitizingHtmlSerializer.prototype.checkClobberedElement = function (node, nextNode) {
5139 if (nextNode &&
5140 (node.compareDocumentPosition(nextNode) &
5141 Node.DOCUMENT_POSITION_CONTAINED_BY) === Node.DOCUMENT_POSITION_CONTAINED_BY) {
5142 throw new Error("Failed to sanitize html because the element is clobbered: " + node.outerHTML);
5143 }
5144 return nextNode;
5145 };
5146 return SanitizingHtmlSerializer;
5147 }());
5148 // Regular Expressions for parsing tags and attributes
5149 var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
5150 // ! to ~ is the ASCII range.
5151 var NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g;
5152 /**
5153 * Escapes all potentially dangerous characters, so that the
5154 * resulting string can be safely inserted into attribute or
5155 * element text.
5156 * @param value
5157 */
5158 function encodeEntities(value) {
5159 return value.replace(/&/g, '&amp;')
5160 .replace(SURROGATE_PAIR_REGEXP, function (match) {
5161 var hi = match.charCodeAt(0);
5162 var low = match.charCodeAt(1);
5163 return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
5164 })
5165 .replace(NON_ALPHANUMERIC_REGEXP, function (match) {
5166 return '&#' + match.charCodeAt(0) + ';';
5167 })
5168 .replace(/</g, '&lt;')
5169 .replace(/>/g, '&gt;');
5170 }
5171 var inertBodyHelper;
5172 /**
5173 * Sanitizes the given unsafe, untrusted HTML fragment, and returns HTML text that is safe to add to
5174 * the DOM in a browser environment.
5175 */
5176 function _sanitizeHtml(defaultDoc, unsafeHtmlInput) {
5177 var inertBodyElement = null;
5178 try {
5179 inertBodyHelper = inertBodyHelper || getInertBodyHelper(defaultDoc);
5180 // Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime).
5181 var unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : '';
5182 inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
5183 // mXSS protection. Repeatedly parse the document to make sure it stabilizes, so that a browser
5184 // trying to auto-correct incorrect HTML cannot cause formerly inert HTML to become dangerous.
5185 var mXSSAttempts = 5;
5186 var parsedHtml = unsafeHtml;
5187 do {
5188 if (mXSSAttempts === 0) {
5189 throw new Error('Failed to sanitize html because the input is unstable');
5190 }
5191 mXSSAttempts--;
5192 unsafeHtml = parsedHtml;
5193 parsedHtml = inertBodyElement.innerHTML;
5194 inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
5195 } while (unsafeHtml !== parsedHtml);
5196 var sanitizer = new SanitizingHtmlSerializer();
5197 var safeHtml = sanitizer.sanitizeChildren(getTemplateContent(inertBodyElement) || inertBodyElement);
5198 if (isDevMode() && sanitizer.sanitizedSomething) {
5199 console.warn('WARNING: sanitizing HTML stripped some content, see http://g.co/ng/security#xss');
5200 }
5201 return safeHtml;
5202 }
5203 finally {
5204 // In case anything goes wrong, clear out inertElement to reset the entire DOM structure.
5205 if (inertBodyElement) {
5206 var parent = getTemplateContent(inertBodyElement) || inertBodyElement;
5207 while (parent.firstChild) {
5208 parent.removeChild(parent.firstChild);
5209 }
5210 }
5211 }
5212 }
5213 function getTemplateContent(el) {
5214 return 'content' in el /** Microsoft/TypeScript#21517 */ && isTemplateElement(el) ?
5215 el.content :
5216 null;
5217 }
5218 function isTemplateElement(el) {
5219 return el.nodeType === Node.ELEMENT_NODE && el.nodeName === 'TEMPLATE';
5220 }
5221
5222 /**
5223 * @license
5224 * Copyright Google LLC All Rights Reserved.
5225 *
5226 * Use of this source code is governed by an MIT-style license that can be
5227 * found in the LICENSE file at https://angular.io/license
5228 */
5229 (function (SecurityContext) {
5230 SecurityContext[SecurityContext["NONE"] = 0] = "NONE";
5231 SecurityContext[SecurityContext["HTML"] = 1] = "HTML";
5232 SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE";
5233 SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
5234 SecurityContext[SecurityContext["URL"] = 4] = "URL";
5235 SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
5236 })(exports.SecurityContext || (exports.SecurityContext = {}));
5237
5238 /**
5239 * @license
5240 * Copyright Google LLC All Rights Reserved.
5241 *
5242 * Use of this source code is governed by an MIT-style license that can be
5243 * found in the LICENSE file at https://angular.io/license
5244 */
5245 /**
5246 * An `html` sanitizer which converts untrusted `html` **string** into trusted string by removing
5247 * dangerous content.
5248 *
5249 * This method parses the `html` and locates potentially dangerous content (such as urls and
5250 * javascript) and removes it.
5251 *
5252 * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustHtml}.
5253 *
5254 * @param unsafeHtml untrusted `html`, typically from the user.
5255 * @returns `html` string which is safe to display to user, because all of the dangerous javascript
5256 * and urls have been removed.
5257 *
5258 * @codeGenApi
5259 */
5260 function ɵɵsanitizeHtml(unsafeHtml) {
5261 var sanitizer = getSanitizer();
5262 if (sanitizer) {
5263 return sanitizer.sanitize(exports.SecurityContext.HTML, unsafeHtml) || '';
5264 }
5265 if (allowSanitizationBypassAndThrow(unsafeHtml, "HTML" /* Html */)) {
5266 return unwrapSafeValue(unsafeHtml);
5267 }
5268 return _sanitizeHtml(getDocument(), renderStringify(unsafeHtml));
5269 }
5270 /**
5271 * A `style` sanitizer which converts untrusted `style` **string** into trusted string by removing
5272 * dangerous content.
5273 *
5274 * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustStyle}.
5275 *
5276 * @param unsafeStyle untrusted `style`, typically from the user.
5277 * @returns `style` string which is safe to bind to the `style` properties.
5278 *
5279 * @codeGenApi
5280 */
5281 function ɵɵsanitizeStyle(unsafeStyle) {
5282 var sanitizer = getSanitizer();
5283 if (sanitizer) {
5284 return sanitizer.sanitize(exports.SecurityContext.STYLE, unsafeStyle) || '';
5285 }
5286 if (allowSanitizationBypassAndThrow(unsafeStyle, "Style" /* Style */)) {
5287 return unwrapSafeValue(unsafeStyle);
5288 }
5289 return renderStringify(unsafeStyle);
5290 }
5291 /**
5292 * A `url` sanitizer which converts untrusted `url` **string** into trusted string by removing
5293 * dangerous
5294 * content.
5295 *
5296 * This method parses the `url` and locates potentially dangerous content (such as javascript) and
5297 * removes it.
5298 *
5299 * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustUrl}.
5300 *
5301 * @param unsafeUrl untrusted `url`, typically from the user.
5302 * @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
5303 * all of the dangerous javascript has been removed.
5304 *
5305 * @codeGenApi
5306 */
5307 function ɵɵsanitizeUrl(unsafeUrl) {
5308 var sanitizer = getSanitizer();
5309 if (sanitizer) {
5310 return sanitizer.sanitize(exports.SecurityContext.URL, unsafeUrl) || '';
5311 }
5312 if (allowSanitizationBypassAndThrow(unsafeUrl, "URL" /* Url */)) {
5313 return unwrapSafeValue(unsafeUrl);
5314 }
5315 return _sanitizeUrl(renderStringify(unsafeUrl));
5316 }
5317 /**
5318 * A `url` sanitizer which only lets trusted `url`s through.
5319 *
5320 * This passes only `url`s marked trusted by calling {@link bypassSanitizationTrustResourceUrl}.
5321 *
5322 * @param unsafeResourceUrl untrusted `url`, typically from the user.
5323 * @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
5324 * only trusted `url`s have been allowed to pass.
5325 *
5326 * @codeGenApi
5327 */
5328 function ɵɵsanitizeResourceUrl(unsafeResourceUrl) {
5329 var sanitizer = getSanitizer();
5330 if (sanitizer) {
5331 return sanitizer.sanitize(exports.SecurityContext.RESOURCE_URL, unsafeResourceUrl) || '';
5332 }
5333 if (allowSanitizationBypassAndThrow(unsafeResourceUrl, "ResourceURL" /* ResourceUrl */)) {
5334 return unwrapSafeValue(unsafeResourceUrl);
5335 }
5336 throw new Error('unsafe value used in a resource URL context (see http://g.co/ng/security#xss)');
5337 }
5338 /**
5339 * A `script` sanitizer which only lets trusted javascript through.
5340 *
5341 * This passes only `script`s marked trusted by calling {@link
5342 * bypassSanitizationTrustScript}.
5343 *
5344 * @param unsafeScript untrusted `script`, typically from the user.
5345 * @returns `url` string which is safe to bind to the `<script>` element such as `<img src>`,
5346 * because only trusted `scripts` have been allowed to pass.
5347 *
5348 * @codeGenApi
5349 */
5350 function ɵɵsanitizeScript(unsafeScript) {
5351 var sanitizer = getSanitizer();
5352 if (sanitizer) {
5353 return sanitizer.sanitize(exports.SecurityContext.SCRIPT, unsafeScript) || '';
5354 }
5355 if (allowSanitizationBypassAndThrow(unsafeScript, "Script" /* Script */)) {
5356 return unwrapSafeValue(unsafeScript);
5357 }
5358 throw new Error('unsafe value used in a script context');
5359 }
5360 /**
5361 * Detects which sanitizer to use for URL property, based on tag name and prop name.
5362 *
5363 * The rules are based on the RESOURCE_URL context config from
5364 * `packages/compiler/src/schema/dom_security_schema.ts`.
5365 * If tag and prop names don't match Resource URL schema, use URL sanitizer.
5366 */
5367 function getUrlSanitizer(tag, prop) {
5368 if ((prop === 'src' &&
5369 (tag === 'embed' || tag === 'frame' || tag === 'iframe' || tag === 'media' ||
5370 tag === 'script')) ||
5371 (prop === 'href' && (tag === 'base' || tag === 'link'))) {
5372 return ɵɵsanitizeResourceUrl;
5373 }
5374 return ɵɵsanitizeUrl;
5375 }
5376 /**
5377 * Sanitizes URL, selecting sanitizer function based on tag and property names.
5378 *
5379 * This function is used in case we can't define security context at compile time, when only prop
5380 * name is available. This happens when we generate host bindings for Directives/Components. The
5381 * host element is unknown at compile time, so we defer calculation of specific sanitizer to
5382 * runtime.
5383 *
5384 * @param unsafeUrl untrusted `url`, typically from the user.
5385 * @param tag target element tag name.
5386 * @param prop name of the property that contains the value.
5387 * @returns `url` string which is safe to bind.
5388 *
5389 * @codeGenApi
5390 */
5391 function ɵɵsanitizeUrlOrResourceUrl(unsafeUrl, tag, prop) {
5392 return getUrlSanitizer(tag, prop)(unsafeUrl);
5393 }
5394 function validateAgainstEventProperties(name) {
5395 if (name.toLowerCase().startsWith('on')) {
5396 var msg = "Binding to event property '" + name + "' is disallowed for security reasons, " +
5397 ("please use (" + name.slice(2) + ")=...") +
5398 ("\nIf '" + name + "' is a directive input, make sure the directive is imported by the") +
5399 " current module.";
5400 throw new Error(msg);
5401 }
5402 }
5403 function validateAgainstEventAttributes(name) {
5404 if (name.toLowerCase().startsWith('on')) {
5405 var msg = "Binding to event attribute '" + name + "' is disallowed for security reasons, " +
5406 ("please use (" + name.slice(2) + ")=...");
5407 throw new Error(msg);
5408 }
5409 }
5410 function getSanitizer() {
5411 var lView = getLView();
5412 return lView && lView[SANITIZER];
5413 }
5414
5415 /**
5416 * @license
5417 * Copyright Google LLC All Rights Reserved.
5418 *
5419 * Use of this source code is governed by an MIT-style license that can be
5420 * found in the LICENSE file at https://angular.io/license
5421 */
5422 /**
5423 * THIS FILE CONTAINS CODE WHICH SHOULD BE TREE SHAKEN AND NEVER CALLED FROM PRODUCTION CODE!!!
5424 */
5425 /**
5426 * Creates an `Array` construction with a given name. This is useful when
5427 * looking for memory consumption to see what time of array it is.
5428 *
5429 *
5430 * @param name Name to give to the constructor
5431 * @returns A subclass of `Array` if possible. This can only be done in
5432 * environments which support `class` construct.
5433 */
5434 function createNamedArrayType(name) {
5435 // This should never be called in prod mode, so let's verify that is the case.
5436 if (ngDevMode) {
5437 try {
5438 // We need to do it this way so that TypeScript does not down-level the below code.
5439 var FunctionConstructor = createNamedArrayType.constructor;
5440 return (new FunctionConstructor('Array', "return class " + name + " extends Array{}"))(Array);
5441 }
5442 catch (e) {
5443 // If it does not work just give up and fall back to regular Array.
5444 return Array;
5445 }
5446 }
5447 else {
5448 throw new Error('Looks like we are in \'prod mode\', but we are creating a named Array type, which is wrong! Check your code');
5449 }
5450 }
5451
5452 /**
5453 * @license
5454 * Copyright Google LLC All Rights Reserved.
5455 *
5456 * Use of this source code is governed by an MIT-style license that can be
5457 * found in the LICENSE file at https://angular.io/license
5458 */
5459 function normalizeDebugBindingName(name) {
5460 // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
5461 name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
5462 return "ng-reflect-" + name;
5463 }
5464 var CAMEL_CASE_REGEXP = /([A-Z])/g;
5465 function camelCaseToDashCase(input) {
5466 return input.replace(CAMEL_CASE_REGEXP, function () {
5467 var m = [];
5468 for (var _i = 0; _i < arguments.length; _i++) {
5469 m[_i] = arguments[_i];
5470 }
5471 return '-' + m[1].toLowerCase();
5472 });
5473 }
5474 function normalizeDebugBindingValue(value) {
5475 try {
5476 // Limit the size of the value as otherwise the DOM just gets polluted.
5477 return value != null ? value.toString().slice(0, 30) : value;
5478 }
5479 catch (e) {
5480 return '[ERROR] Exception while trying to serialize the value';
5481 }
5482 }
5483
5484 /**
5485 * @license
5486 * Copyright Google LLC All Rights Reserved.
5487 *
5488 * Use of this source code is governed by an MIT-style license that can be
5489 * found in the LICENSE file at https://angular.io/license
5490 */
5491 /**
5492 * Returns the matching `LContext` data for a given DOM node, directive or component instance.
5493 *
5494 * This function will examine the provided DOM element, component, or directive instance\'s
5495 * monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
5496 * value will be that of the newly created `LContext`.
5497 *
5498 * If the monkey-patched value is the `LView` instance then the context value for that
5499 * target will be created and the monkey-patch reference will be updated. Therefore when this
5500 * function is called it may mutate the provided element\'s, component\'s or any of the associated
5501 * directive\'s monkey-patch values.
5502 *
5503 * If the monkey-patch value is not detected then the code will walk up the DOM until an element
5504 * is found which contains a monkey-patch reference. When that occurs then the provided element
5505 * will be updated with a new context (which is then returned). If the monkey-patch value is not
5506 * detected for a component/directive instance then it will throw an error (all components and
5507 * directives should be automatically monkey-patched by ivy).
5508 *
5509 * @param target Component, Directive or DOM Node.
5510 */
5511 function getLContext(target) {
5512 var mpValue = readPatchedData(target);
5513 if (mpValue) {
5514 // only when it's an array is it considered an LView instance
5515 // ... otherwise it's an already constructed LContext instance
5516 if (Array.isArray(mpValue)) {
5517 var lView = mpValue;
5518 var nodeIndex = void 0;
5519 var component = undefined;
5520 var directives = undefined;
5521 if (isComponentInstance(target)) {
5522 nodeIndex = findViaComponent(lView, target);
5523 if (nodeIndex == -1) {
5524 throw new Error('The provided component was not found in the application');
5525 }
5526 component = target;
5527 }
5528 else if (isDirectiveInstance(target)) {
5529 nodeIndex = findViaDirective(lView, target);
5530 if (nodeIndex == -1) {
5531 throw new Error('The provided directive was not found in the application');
5532 }
5533 directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
5534 }
5535 else {
5536 nodeIndex = findViaNativeElement(lView, target);
5537 if (nodeIndex == -1) {
5538 return null;
5539 }
5540 }
5541 // the goal is not to fill the entire context full of data because the lookups
5542 // are expensive. Instead, only the target data (the element, component, container, ICU
5543 // expression or directive details) are filled into the context. If called multiple times
5544 // with different target values then the missing target data will be filled in.
5545 var native = unwrapRNode(lView[nodeIndex]);
5546 var existingCtx = readPatchedData(native);
5547 var context = (existingCtx && !Array.isArray(existingCtx)) ?
5548 existingCtx :
5549 createLContext(lView, nodeIndex, native);
5550 // only when the component has been discovered then update the monkey-patch
5551 if (component && context.component === undefined) {
5552 context.component = component;
5553 attachPatchData(context.component, context);
5554 }
5555 // only when the directives have been discovered then update the monkey-patch
5556 if (directives && context.directives === undefined) {
5557 context.directives = directives;
5558 for (var i = 0; i < directives.length; i++) {
5559 attachPatchData(directives[i], context);
5560 }
5561 }
5562 attachPatchData(context.native, context);
5563 mpValue = context;
5564 }
5565 }
5566 else {
5567 var rElement = target;
5568 ngDevMode && assertDomNode(rElement);
5569 // if the context is not found then we need to traverse upwards up the DOM
5570 // to find the nearest element that has already been monkey patched with data
5571 var parent = rElement;
5572 while (parent = parent.parentNode) {
5573 var parentContext = readPatchedData(parent);
5574 if (parentContext) {
5575 var lView = void 0;
5576 if (Array.isArray(parentContext)) {
5577 lView = parentContext;
5578 }
5579 else {
5580 lView = parentContext.lView;
5581 }
5582 // the edge of the app was also reached here through another means
5583 // (maybe because the DOM was changed manually).
5584 if (!lView) {
5585 return null;
5586 }
5587 var index = findViaNativeElement(lView, rElement);
5588 if (index >= 0) {
5589 var native = unwrapRNode(lView[index]);
5590 var context = createLContext(lView, index, native);
5591 attachPatchData(native, context);
5592 mpValue = context;
5593 break;
5594 }
5595 }
5596 }
5597 }
5598 return mpValue || null;
5599 }
5600 /**
5601 * Creates an empty instance of a `LContext` context
5602 */
5603 function createLContext(lView, nodeIndex, native) {
5604 return {
5605 lView: lView,
5606 nodeIndex: nodeIndex,
5607 native: native,
5608 component: undefined,
5609 directives: undefined,
5610 localRefs: undefined,
5611 };
5612 }
5613 /**
5614 * Takes a component instance and returns the view for that component.
5615 *
5616 * @param componentInstance
5617 * @returns The component's view
5618 */
5619 function getComponentViewByInstance(componentInstance) {
5620 var lView = readPatchedData(componentInstance);
5621 var view;
5622 if (Array.isArray(lView)) {
5623 var nodeIndex = findViaComponent(lView, componentInstance);
5624 view = getComponentLViewByIndex(nodeIndex, lView);
5625 var context = createLContext(lView, nodeIndex, view[HOST]);
5626 context.component = componentInstance;
5627 attachPatchData(componentInstance, context);
5628 attachPatchData(context.native, context);
5629 }
5630 else {
5631 var context = lView;
5632 view = getComponentLViewByIndex(context.nodeIndex, context.lView);
5633 }
5634 return view;
5635 }
5636 /**
5637 * Assigns the given data to the given target (which could be a component,
5638 * directive or DOM node instance) using monkey-patching.
5639 */
5640 function attachPatchData(target, data) {
5641 target[MONKEY_PATCH_KEY_NAME] = data;
5642 }
5643 function isComponentInstance(instance) {
5644 return instance && instance.constructor && instance.constructor.ɵcmp;
5645 }
5646 function isDirectiveInstance(instance) {
5647 return instance && instance.constructor && instance.constructor.ɵdir;
5648 }
5649 /**
5650 * Locates the element within the given LView and returns the matching index
5651 */
5652 function findViaNativeElement(lView, target) {
5653 var tNode = lView[TVIEW].firstChild;
5654 while (tNode) {
5655 var native = getNativeByTNodeOrNull(tNode, lView);
5656 if (native === target) {
5657 return tNode.index;
5658 }
5659 tNode = traverseNextElement(tNode);
5660 }
5661 return -1;
5662 }
5663 /**
5664 * Locates the next tNode (child, sibling or parent).
5665 */
5666 function traverseNextElement(tNode) {
5667 if (tNode.child) {
5668 return tNode.child;
5669 }
5670 else if (tNode.next) {
5671 return tNode.next;
5672 }
5673 else {
5674 // Let's take the following template: <div><span>text</span></div><component/>
5675 // After checking the text node, we need to find the next parent that has a "next" TNode,
5676 // in this case the parent `div`, so that we can find the component.
5677 while (tNode.parent && !tNode.parent.next) {
5678 tNode = tNode.parent;
5679 }
5680 return tNode.parent && tNode.parent.next;
5681 }
5682 }
5683 /**
5684 * Locates the component within the given LView and returns the matching index
5685 */
5686 function findViaComponent(lView, componentInstance) {
5687 var componentIndices = lView[TVIEW].components;
5688 if (componentIndices) {
5689 for (var i = 0; i < componentIndices.length; i++) {
5690 var elementComponentIndex = componentIndices[i];
5691 var componentView = getComponentLViewByIndex(elementComponentIndex, lView);
5692 if (componentView[CONTEXT] === componentInstance) {
5693 return elementComponentIndex;
5694 }
5695 }
5696 }
5697 else {
5698 var rootComponentView = getComponentLViewByIndex(HEADER_OFFSET, lView);
5699 var rootComponent = rootComponentView[CONTEXT];
5700 if (rootComponent === componentInstance) {
5701 // we are dealing with the root element here therefore we know that the
5702 // element is the very first element after the HEADER data in the lView
5703 return HEADER_OFFSET;
5704 }
5705 }
5706 return -1;
5707 }
5708 /**
5709 * Locates the directive within the given LView and returns the matching index
5710 */
5711 function findViaDirective(lView, directiveInstance) {
5712 // if a directive is monkey patched then it will (by default)
5713 // have a reference to the LView of the current view. The
5714 // element bound to the directive being search lives somewhere
5715 // in the view data. We loop through the nodes and check their
5716 // list of directives for the instance.
5717 var tNode = lView[TVIEW].firstChild;
5718 while (tNode) {
5719 var directiveIndexStart = tNode.directiveStart;
5720 var directiveIndexEnd = tNode.directiveEnd;
5721 for (var i = directiveIndexStart; i < directiveIndexEnd; i++) {
5722 if (lView[i] === directiveInstance) {
5723 return tNode.index;
5724 }
5725 }
5726 tNode = traverseNextElement(tNode);
5727 }
5728 return -1;
5729 }
5730 /**
5731 * Returns a list of directives extracted from the given view based on the
5732 * provided list of directive index values.
5733 *
5734 * @param nodeIndex The node index
5735 * @param lView The target view data
5736 * @param includeComponents Whether or not to include components in returned directives
5737 */
5738 function getDirectivesAtNodeIndex(nodeIndex, lView, includeComponents) {
5739 var tNode = lView[TVIEW].data[nodeIndex];
5740 var directiveStartIndex = tNode.directiveStart;
5741 if (directiveStartIndex == 0)
5742 return EMPTY_ARRAY;
5743 var directiveEndIndex = tNode.directiveEnd;
5744 if (!includeComponents && tNode.flags & 2 /* isComponentHost */)
5745 directiveStartIndex++;
5746 return lView.slice(directiveStartIndex, directiveEndIndex);
5747 }
5748 function getComponentAtNodeIndex(nodeIndex, lView) {
5749 var tNode = lView[TVIEW].data[nodeIndex];
5750 var directiveStartIndex = tNode.directiveStart;
5751 return tNode.flags & 2 /* isComponentHost */ ? lView[directiveStartIndex] : null;
5752 }
5753 /**
5754 * Returns a map of local references (local reference name => element or directive instance) that
5755 * exist on a given element.
5756 */
5757 function discoverLocalRefs(lView, nodeIndex) {
5758 var tNode = lView[TVIEW].data[nodeIndex];
5759 if (tNode && tNode.localNames) {
5760 var result = {};
5761 var localIndex = tNode.index + 1;
5762 for (var i = 0; i < tNode.localNames.length; i += 2) {
5763 result[tNode.localNames[i]] = lView[localIndex];
5764 localIndex++;
5765 }
5766 return result;
5767 }
5768 return null;
5769 }
5770
5771 /** Called when directives inject each other (creating a circular dependency) */
5772 function throwCyclicDependencyError(token) {
5773 throw new Error("Cannot instantiate cyclic dependency! " + token);
5774 }
5775 /** Called when there are multiple component selectors that match a given node */
5776 function throwMultipleComponentError(tNode) {
5777 throw new Error("Multiple components match node with tagname " + tNode.tagName);
5778 }
5779 function throwMixedMultiProviderError() {
5780 throw new Error("Cannot mix multi providers and regular providers");
5781 }
5782 function throwInvalidProviderError(ngModuleType, providers, provider) {
5783 var ngModuleDetail = '';
5784 if (ngModuleType && providers) {
5785 var providerDetail = providers.map(function (v) { return v == provider ? '?' + provider + '?' : '...'; });
5786 ngModuleDetail =
5787 " - only instances of Provider and Type are allowed, got: [" + providerDetail.join(', ') + "]";
5788 }
5789 throw new Error("Invalid provider for the NgModule '" + stringify(ngModuleType) + "'" + ngModuleDetail);
5790 }
5791 /** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */
5792 function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName) {
5793 var field = propName ? " for '" + propName + "'" : '';
5794 var msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value" + field + ": '" + oldValue + "'. Current value: '" + currValue + "'.";
5795 if (creationMode) {
5796 msg +=
5797 " It seems like the view has been created after its parent and its children have been dirty checked." +
5798 " Has it been created in a change detection hook?";
5799 }
5800 // TODO: include debug context, see `viewDebugError` function in
5801 // `packages/core/src/view/errors.ts` for reference.
5802 throw new Error(msg);
5803 }
5804 function constructDetailsForInterpolation(lView, rootIndex, expressionIndex, meta, changedValue) {
5805 var _a = __read(meta.split(INTERPOLATION_DELIMITER)), propName = _a[0], prefix = _a[1], chunks = _a.slice(2);
5806 var oldValue = prefix, newValue = prefix;
5807 for (var i = 0; i < chunks.length; i++) {
5808 var slotIdx = rootIndex + i;
5809 oldValue += "" + lView[slotIdx] + chunks[i];
5810 newValue += "" + (slotIdx === expressionIndex ? changedValue : lView[slotIdx]) + chunks[i];
5811 }
5812 return { propName: propName, oldValue: oldValue, newValue: newValue };
5813 }
5814 /**
5815 * Constructs an object that contains details for the ExpressionChangedAfterItHasBeenCheckedError:
5816 * - property name (for property bindings or interpolations)
5817 * - old and new values, enriched using information from metadata
5818 *
5819 * More information on the metadata storage format can be found in `storePropertyBindingMetadata`
5820 * function description.
5821 */
5822 function getExpressionChangedErrorDetails(lView, bindingIndex, oldValue, newValue) {
5823 var tData = lView[TVIEW].data;
5824 var metadata = tData[bindingIndex];
5825 if (typeof metadata === 'string') {
5826 // metadata for property interpolation
5827 if (metadata.indexOf(INTERPOLATION_DELIMITER) > -1) {
5828 return constructDetailsForInterpolation(lView, bindingIndex, bindingIndex, metadata, newValue);
5829 }
5830 // metadata for property binding
5831 return { propName: metadata, oldValue: oldValue, newValue: newValue };
5832 }
5833 // metadata is not available for this expression, check if this expression is a part of the
5834 // property interpolation by going from the current binding index left and look for a string that
5835 // contains INTERPOLATION_DELIMITER, the layout in tView.data for this case will look like this:
5836 // [..., 'id�Prefix � and � suffix', null, null, null, ...]
5837 if (metadata === null) {
5838 var idx = bindingIndex - 1;
5839 while (typeof tData[idx] !== 'string' && tData[idx + 1] === null) {
5840 idx--;
5841 }
5842 var meta = tData[idx];
5843 if (typeof meta === 'string') {
5844 var matches = meta.match(new RegExp(INTERPOLATION_DELIMITER, 'g'));
5845 // first interpolation delimiter separates property name from interpolation parts (in case of
5846 // property interpolations), so we subtract one from total number of found delimiters
5847 if (matches && (matches.length - 1) > bindingIndex - idx) {
5848 return constructDetailsForInterpolation(lView, idx, bindingIndex, meta, newValue);
5849 }
5850 }
5851 }
5852 return { propName: undefined, oldValue: oldValue, newValue: newValue };
5853 }
5854
5855 /**
5856 * Converts `TNodeType` into human readable text.
5857 * Make sure this matches with `TNodeType`
5858 */
5859 var TNodeTypeAsString = [
5860 'Container',
5861 'Projection',
5862 'View',
5863 'Element',
5864 'ElementContainer',
5865 'IcuContainer' // 5
5866 ];
5867 // Note: This hack is necessary so we don't erroneously get a circular dependency
5868 // failure based on types.
5869 var unusedValueExportToPlacateAjd$4 = 1;
5870 /**
5871 * Returns `true` if the `TNode` has a directive which has `@Input()` for `class` binding.
5872 *
5873 * ```
5874 * <div my-dir [class]="exp"></div>
5875 * ```
5876 * and
5877 * ```
5878 * @Directive({
5879 * })
5880 * class MyDirective {
5881 * @Input()
5882 * class: string;
5883 * }
5884 * ```
5885 *
5886 * In the above case it is necessary to write the reconciled styling information into the
5887 * directive's input.
5888 *
5889 * @param tNode
5890 */
5891 function hasClassInput(tNode) {
5892 return (tNode.flags & 16 /* hasClassInput */) !== 0;
5893 }
5894 /**
5895 * Returns `true` if the `TNode` has a directive which has `@Input()` for `style` binding.
5896 *
5897 * ```
5898 * <div my-dir [style]="exp"></div>
5899 * ```
5900 * and
5901 * ```
5902 * @Directive({
5903 * })
5904 * class MyDirective {
5905 * @Input()
5906 * class: string;
5907 * }
5908 * ```
5909 *
5910 * In the above case it is necessary to write the reconciled styling information into the
5911 * directive's input.
5912 *
5913 * @param tNode
5914 */
5915 function hasStyleInput(tNode) {
5916 return (tNode.flags & 32 /* hasStyleInput */) !== 0;
5917 }
5918
5919 /**
5920 * @license
5921 * Copyright Google LLC All Rights Reserved.
5922 *
5923 * Use of this source code is governed by an MIT-style license that can be
5924 * found in the LICENSE file at https://angular.io/license
5925 */
5926 // Note: This hack is necessary so we don't erroneously get a circular dependency
5927 // failure based on types.
5928 var unusedValueExportToPlacateAjd$5 = 1;
5929
5930 /**
5931 * @license
5932 * Copyright Google LLC All Rights Reserved.
5933 *
5934 * Use of this source code is governed by an MIT-style license that can be
5935 * found in the LICENSE file at https://angular.io/license
5936 */
5937 /**
5938 * Returns an index of `classToSearch` in `className` taking token boundaries into account.
5939 *
5940 * `classIndexOf('AB A', 'A', 0)` will be 3 (not 0 since `AB!==A`)
5941 *
5942 * @param className A string containing classes (whitespace separated)
5943 * @param classToSearch A class name to locate
5944 * @param startingIndex Starting location of search
5945 * @returns an index of the located class (or -1 if not found)
5946 */
5947 function classIndexOf(className, classToSearch, startingIndex) {
5948 ngDevMode && assertNotEqual(classToSearch, '', 'can not look for "" string.');
5949 var end = className.length;
5950 while (true) {
5951 var foundIndex = className.indexOf(classToSearch, startingIndex);
5952 if (foundIndex === -1)
5953 return foundIndex;
5954 if (foundIndex === 0 || className.charCodeAt(foundIndex - 1) <= 32 /* SPACE */) {
5955 // Ensure that it has leading whitespace
5956 var length = classToSearch.length;
5957 if (foundIndex + length === end ||
5958 className.charCodeAt(foundIndex + length) <= 32 /* SPACE */) {
5959 // Ensure that it has trailing whitespace
5960 return foundIndex;
5961 }
5962 }
5963 // False positive, keep searching from where we left off.
5964 startingIndex = foundIndex + 1;
5965 }
5966 }
5967
5968 /**
5969 * @license
5970 * Copyright Google LLC All Rights Reserved.
5971 *
5972 * Use of this source code is governed by an MIT-style license that can be
5973 * found in the LICENSE file at https://angular.io/license
5974 */
5975 var unusedValueToPlacateAjd = unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$5;
5976 var NG_TEMPLATE_SELECTOR = 'ng-template';
5977 /**
5978 * Search the `TAttributes` to see if it contains `cssClassToMatch` (case insensitive)
5979 *
5980 * @param attrs `TAttributes` to search through.
5981 * @param cssClassToMatch class to match (lowercase)
5982 * @param isProjectionMode Whether or not class matching should look into the attribute `class` in
5983 * addition to the `AttributeMarker.Classes`.
5984 */
5985 function isCssClassMatching(attrs, cssClassToMatch, isProjectionMode) {
5986 // TODO(misko): The fact that this function needs to know about `isProjectionMode` seems suspect.
5987 // It is strange to me that sometimes the class information comes in form of `class` attribute
5988 // and sometimes in form of `AttributeMarker.Classes`. Some investigation is needed to determine
5989 // if that is the right behavior.
5990 ngDevMode &&
5991 assertEqual(cssClassToMatch, cssClassToMatch.toLowerCase(), 'Class name expected to be lowercase.');
5992 var i = 0;
5993 while (i < attrs.length) {
5994 var item = attrs[i++];
5995 if (isProjectionMode && item === 'class') {
5996 item = attrs[i];
5997 if (classIndexOf(item.toLowerCase(), cssClassToMatch, 0) !== -1) {
5998 return true;
5999 }
6000 }
6001 else if (item === 1 /* Classes */) {
6002 // We found the classes section. Start searching for the class.
6003 while (i < attrs.length && typeof (item = attrs[i++]) == 'string') {
6004 // while we have strings
6005 if (item.toLowerCase() === cssClassToMatch)
6006 return true;
6007 }
6008 return false;
6009 }
6010 }
6011 return false;
6012 }
6013 /**
6014 * Checks whether the `tNode` represents an inline template (e.g. `*ngFor`).
6015 *
6016 * @param tNode current TNode
6017 */
6018 function isInlineTemplate(tNode) {
6019 return tNode.type === 0 /* Container */ && tNode.tagName !== NG_TEMPLATE_SELECTOR;
6020 }
6021 /**
6022 * Function that checks whether a given tNode matches tag-based selector and has a valid type.
6023 *
6024 * Matching can be performed in 2 modes: projection mode (when we project nodes) and regular
6025 * directive matching mode:
6026 * - in the "directive matching" mode we do _not_ take TContainer's tagName into account if it is
6027 * different from NG_TEMPLATE_SELECTOR (value different from NG_TEMPLATE_SELECTOR indicates that a
6028 * tag name was extracted from * syntax so we would match the same directive twice);
6029 * - in the "projection" mode, we use a tag name potentially extracted from the * syntax processing
6030 * (applicable to TNodeType.Container only).
6031 */
6032 function hasTagAndTypeMatch(tNode, currentSelector, isProjectionMode) {
6033 var tagNameToCompare = tNode.type === 0 /* Container */ && !isProjectionMode ?
6034 NG_TEMPLATE_SELECTOR :
6035 tNode.tagName;
6036 return currentSelector === tagNameToCompare;
6037 }
6038 /**
6039 * A utility function to match an Ivy node static data against a simple CSS selector
6040 *
6041 * @param node static data of the node to match
6042 * @param selector The selector to try matching against the node.
6043 * @param isProjectionMode if `true` we are matching for content projection, otherwise we are doing
6044 * directive matching.
6045 * @returns true if node matches the selector.
6046 */
6047 function isNodeMatchingSelector(tNode, selector, isProjectionMode) {
6048 ngDevMode && assertDefined(selector[0], 'Selector should have a tag name');
6049 var mode = 4 /* ELEMENT */;
6050 var nodeAttrs = tNode.attrs || [];
6051 // Find the index of first attribute that has no value, only a name.
6052 var nameOnlyMarkerIdx = getNameOnlyMarkerIndex(nodeAttrs);
6053 // When processing ":not" selectors, we skip to the next ":not" if the
6054 // current one doesn't match
6055 var skipToNextSelector = false;
6056 for (var i = 0; i < selector.length; i++) {
6057 var current = selector[i];
6058 if (typeof current === 'number') {
6059 // If we finish processing a :not selector and it hasn't failed, return false
6060 if (!skipToNextSelector && !isPositive(mode) && !isPositive(current)) {
6061 return false;
6062 }
6063 // If we are skipping to the next :not() and this mode flag is positive,
6064 // it's a part of the current :not() selector, and we should keep skipping
6065 if (skipToNextSelector && isPositive(current))
6066 continue;
6067 skipToNextSelector = false;
6068 mode = current | (mode & 1 /* NOT */);
6069 continue;
6070 }
6071 if (skipToNextSelector)
6072 continue;
6073 if (mode & 4 /* ELEMENT */) {
6074 mode = 2 /* ATTRIBUTE */ | mode & 1 /* NOT */;
6075 if (current !== '' && !hasTagAndTypeMatch(tNode, current, isProjectionMode) ||
6076 current === '' && selector.length === 1) {
6077 if (isPositive(mode))
6078 return false;
6079 skipToNextSelector = true;
6080 }
6081 }
6082 else {
6083 var selectorAttrValue = mode & 8 /* CLASS */ ? current : selector[++i];
6084 // special case for matching against classes when a tNode has been instantiated with
6085 // class and style values as separate attribute values (e.g. ['title', CLASS, 'foo'])
6086 if ((mode & 8 /* CLASS */) && tNode.attrs !== null) {
6087 if (!isCssClassMatching(tNode.attrs, selectorAttrValue, isProjectionMode)) {
6088 if (isPositive(mode))
6089 return false;
6090 skipToNextSelector = true;
6091 }
6092 continue;
6093 }
6094 var attrName = (mode & 8 /* CLASS */) ? 'class' : current;
6095 var attrIndexInNode = findAttrIndexInNode(attrName, nodeAttrs, isInlineTemplate(tNode), isProjectionMode);
6096 if (attrIndexInNode === -1) {
6097 if (isPositive(mode))
6098 return false;
6099 skipToNextSelector = true;
6100 continue;
6101 }
6102 if (selectorAttrValue !== '') {
6103 var nodeAttrValue = void 0;
6104 if (attrIndexInNode > nameOnlyMarkerIdx) {
6105 nodeAttrValue = '';
6106 }
6107 else {
6108 ngDevMode &&
6109 assertNotEqual(nodeAttrs[attrIndexInNode], 0 /* NamespaceURI */, 'We do not match directives on namespaced attributes');
6110 // we lowercase the attribute value to be able to match
6111 // selectors without case-sensitivity
6112 // (selectors are already in lowercase when generated)
6113 nodeAttrValue = nodeAttrs[attrIndexInNode + 1].toLowerCase();
6114 }
6115 var compareAgainstClassName = mode & 8 /* CLASS */ ? nodeAttrValue : null;
6116 if (compareAgainstClassName &&
6117 classIndexOf(compareAgainstClassName, selectorAttrValue, 0) !== -1 ||
6118 mode & 2 /* ATTRIBUTE */ && selectorAttrValue !== nodeAttrValue) {
6119 if (isPositive(mode))
6120 return false;
6121 skipToNextSelector = true;
6122 }
6123 }
6124 }
6125 }
6126 return isPositive(mode) || skipToNextSelector;
6127 }
6128 function isPositive(mode) {
6129 return (mode & 1 /* NOT */) === 0;
6130 }
6131 /**
6132 * Examines the attribute's definition array for a node to find the index of the
6133 * attribute that matches the given `name`.
6134 *
6135 * NOTE: This will not match namespaced attributes.
6136 *
6137 * Attribute matching depends upon `isInlineTemplate` and `isProjectionMode`.
6138 * The following table summarizes which types of attributes we attempt to match:
6139 *
6140 * ===========================================================================================================
6141 * Modes | Normal Attributes | Bindings Attributes | Template Attributes | I18n
6142 * Attributes
6143 * ===========================================================================================================
6144 * Inline + Projection | YES | YES | NO | YES
6145 * -----------------------------------------------------------------------------------------------------------
6146 * Inline + Directive | NO | NO | YES | NO
6147 * -----------------------------------------------------------------------------------------------------------
6148 * Non-inline + Projection | YES | YES | NO | YES
6149 * -----------------------------------------------------------------------------------------------------------
6150 * Non-inline + Directive | YES | YES | NO | YES
6151 * ===========================================================================================================
6152 *
6153 * @param name the name of the attribute to find
6154 * @param attrs the attribute array to examine
6155 * @param isInlineTemplate true if the node being matched is an inline template (e.g. `*ngFor`)
6156 * rather than a manually expanded template node (e.g `<ng-template>`).
6157 * @param isProjectionMode true if we are matching against content projection otherwise we are
6158 * matching against directives.
6159 */
6160 function findAttrIndexInNode(name, attrs, isInlineTemplate, isProjectionMode) {
6161 if (attrs === null)
6162 return -1;
6163 var i = 0;
6164 if (isProjectionMode || !isInlineTemplate) {
6165 var bindingsMode = false;
6166 while (i < attrs.length) {
6167 var maybeAttrName = attrs[i];
6168 if (maybeAttrName === name) {
6169 return i;
6170 }
6171 else if (maybeAttrName === 3 /* Bindings */ || maybeAttrName === 6 /* I18n */) {
6172 bindingsMode = true;
6173 }
6174 else if (maybeAttrName === 1 /* Classes */ || maybeAttrName === 2 /* Styles */) {
6175 var value = attrs[++i];
6176 // We should skip classes here because we have a separate mechanism for
6177 // matching classes in projection mode.
6178 while (typeof value === 'string') {
6179 value = attrs[++i];
6180 }
6181 continue;
6182 }
6183 else if (maybeAttrName === 4 /* Template */) {
6184 // We do not care about Template attributes in this scenario.
6185 break;
6186 }
6187 else if (maybeAttrName === 0 /* NamespaceURI */) {
6188 // Skip the whole namespaced attribute and value. This is by design.
6189 i += 4;
6190 continue;
6191 }
6192 // In binding mode there are only names, rather than name-value pairs.
6193 i += bindingsMode ? 1 : 2;
6194 }
6195 // We did not match the attribute
6196 return -1;
6197 }
6198 else {
6199 return matchTemplateAttribute(attrs, name);
6200 }
6201 }
6202 function isNodeMatchingSelectorList(tNode, selector, isProjectionMode) {
6203 if (isProjectionMode === void 0) { isProjectionMode = false; }
6204 for (var i = 0; i < selector.length; i++) {
6205 if (isNodeMatchingSelector(tNode, selector[i], isProjectionMode)) {
6206 return true;
6207 }
6208 }
6209 return false;
6210 }
6211 function getProjectAsAttrValue(tNode) {
6212 var nodeAttrs = tNode.attrs;
6213 if (nodeAttrs != null) {
6214 var ngProjectAsAttrIdx = nodeAttrs.indexOf(5 /* ProjectAs */);
6215 // only check for ngProjectAs in attribute names, don't accidentally match attribute's value
6216 // (attribute names are stored at even indexes)
6217 if ((ngProjectAsAttrIdx & 1) === 0) {
6218 return nodeAttrs[ngProjectAsAttrIdx + 1];
6219 }
6220 }
6221 return null;
6222 }
6223 function getNameOnlyMarkerIndex(nodeAttrs) {
6224 for (var i = 0; i < nodeAttrs.length; i++) {
6225 var nodeAttr = nodeAttrs[i];
6226 if (isNameOnlyAttributeMarker(nodeAttr)) {
6227 return i;
6228 }
6229 }
6230 return nodeAttrs.length;
6231 }
6232 function matchTemplateAttribute(attrs, name) {
6233 var i = attrs.indexOf(4 /* Template */);
6234 if (i > -1) {
6235 i++;
6236 while (i < attrs.length) {
6237 var attr = attrs[i];
6238 // Return in case we checked all template attrs and are switching to the next section in the
6239 // attrs array (that starts with a number that represents an attribute marker).
6240 if (typeof attr === 'number')
6241 return -1;
6242 if (attr === name)
6243 return i;
6244 i++;
6245 }
6246 }
6247 return -1;
6248 }
6249 /**
6250 * Checks whether a selector is inside a CssSelectorList
6251 * @param selector Selector to be checked.
6252 * @param list List in which to look for the selector.
6253 */
6254 function isSelectorInSelectorList(selector, list) {
6255 selectorListLoop: for (var i = 0; i < list.length; i++) {
6256 var currentSelectorInList = list[i];
6257 if (selector.length !== currentSelectorInList.length) {
6258 continue;
6259 }
6260 for (var j = 0; j < selector.length; j++) {
6261 if (selector[j] !== currentSelectorInList[j]) {
6262 continue selectorListLoop;
6263 }
6264 }
6265 return true;
6266 }
6267 return false;
6268 }
6269 function maybeWrapInNotSelector(isNegativeMode, chunk) {
6270 return isNegativeMode ? ':not(' + chunk.trim() + ')' : chunk;
6271 }
6272 function stringifyCSSSelector(selector) {
6273 var result = selector[0];
6274 var i = 1;
6275 var mode = 2 /* ATTRIBUTE */;
6276 var currentChunk = '';
6277 var isNegativeMode = false;
6278 while (i < selector.length) {
6279 var valueOrMarker = selector[i];
6280 if (typeof valueOrMarker === 'string') {
6281 if (mode & 2 /* ATTRIBUTE */) {
6282 var attrValue = selector[++i];
6283 currentChunk +=
6284 '[' + valueOrMarker + (attrValue.length > 0 ? '="' + attrValue + '"' : '') + ']';
6285 }
6286 else if (mode & 8 /* CLASS */) {
6287 currentChunk += '.' + valueOrMarker;
6288 }
6289 else if (mode & 4 /* ELEMENT */) {
6290 currentChunk += ' ' + valueOrMarker;
6291 }
6292 }
6293 else {
6294 //
6295 // Append current chunk to the final result in case we come across SelectorFlag, which
6296 // indicates that the previous section of a selector is over. We need to accumulate content
6297 // between flags to make sure we wrap the chunk later in :not() selector if needed, e.g.
6298 // ```
6299 // ['', Flags.CLASS, '.classA', Flags.CLASS | Flags.NOT, '.classB', '.classC']
6300 // ```
6301 // should be transformed to `.classA :not(.classB .classC)`.
6302 //
6303 // Note: for negative selector part, we accumulate content between flags until we find the
6304 // next negative flag. This is needed to support a case where `:not()` rule contains more than
6305 // one chunk, e.g. the following selector:
6306 // ```
6307 // ['', Flags.ELEMENT | Flags.NOT, 'p', Flags.CLASS, 'foo', Flags.CLASS | Flags.NOT, 'bar']
6308 // ```
6309 // should be stringified to `:not(p.foo) :not(.bar)`
6310 //
6311 if (currentChunk !== '' && !isPositive(valueOrMarker)) {
6312 result += maybeWrapInNotSelector(isNegativeMode, currentChunk);
6313 currentChunk = '';
6314 }
6315 mode = valueOrMarker;
6316 // According to CssSelector spec, once we come across `SelectorFlags.NOT` flag, the negative
6317 // mode is maintained for remaining chunks of a selector.
6318 isNegativeMode = isNegativeMode || !isPositive(mode);
6319 }
6320 i++;
6321 }
6322 if (currentChunk !== '') {
6323 result += maybeWrapInNotSelector(isNegativeMode, currentChunk);
6324 }
6325 return result;
6326 }
6327 /**
6328 * Generates string representation of CSS selector in parsed form.
6329 *
6330 * ComponentDef and DirectiveDef are generated with the selector in parsed form to avoid doing
6331 * additional parsing at runtime (for example, for directive matching). However in some cases (for
6332 * example, while bootstrapping a component), a string version of the selector is required to query
6333 * for the host element on the page. This function takes the parsed form of a selector and returns
6334 * its string representation.
6335 *
6336 * @param selectorList selector in parsed form
6337 * @returns string representation of a given selector
6338 */
6339 function stringifyCSSSelectorList(selectorList) {
6340 return selectorList.map(stringifyCSSSelector).join(',');
6341 }
6342 /**
6343 * Extracts attributes and classes information from a given CSS selector.
6344 *
6345 * This function is used while creating a component dynamically. In this case, the host element
6346 * (that is created dynamically) should contain attributes and classes specified in component's CSS
6347 * selector.
6348 *
6349 * @param selector CSS selector in parsed form (in a form of array)
6350 * @returns object with `attrs` and `classes` fields that contain extracted information
6351 */
6352 function extractAttrsAndClassesFromSelector(selector) {
6353 var attrs = [];
6354 var classes = [];
6355 var i = 1;
6356 var mode = 2 /* ATTRIBUTE */;
6357 while (i < selector.length) {
6358 var valueOrMarker = selector[i];
6359 if (typeof valueOrMarker === 'string') {
6360 if (mode === 2 /* ATTRIBUTE */) {
6361 if (valueOrMarker !== '') {
6362 attrs.push(valueOrMarker, selector[++i]);
6363 }
6364 }
6365 else if (mode === 8 /* CLASS */) {
6366 classes.push(valueOrMarker);
6367 }
6368 }
6369 else {
6370 // According to CssSelector spec, once we come across `SelectorFlags.NOT` flag, the negative
6371 // mode is maintained for remaining chunks of a selector. Since attributes and classes are
6372 // extracted only for "positive" part of the selector, we can stop here.
6373 if (!isPositive(mode))
6374 break;
6375 mode = valueOrMarker;
6376 }
6377 i++;
6378 }
6379 return { attrs: attrs, classes: classes };
6380 }
6381
6382 /**
6383 * @license
6384 * Copyright Google LLC All Rights Reserved.
6385 *
6386 * Use of this source code is governed by an MIT-style license that can be
6387 * found in the LICENSE file at https://angular.io/license
6388 */
6389 /** A special value which designates that a value has not changed. */
6390 var NO_CHANGE = (typeof ngDevMode === 'undefined' || ngDevMode) ? { __brand__: 'NO_CHANGE' } : {};
6391
6392 /**
6393 * @license
6394 * Copyright Google LLC All Rights Reserved.
6395 *
6396 * Use of this source code is governed by an MIT-style license that can be
6397 * found in the LICENSE file at https://angular.io/license
6398 */
6399 /**
6400 * Gets the parent LView of the passed LView, if the PARENT is an LContainer, will get the parent of
6401 * that LContainer, which is an LView
6402 * @param lView the lView whose parent to get
6403 */
6404 function getLViewParent(lView) {
6405 ngDevMode && assertLView(lView);
6406 var parent = lView[PARENT];
6407 return isLContainer(parent) ? parent[PARENT] : parent;
6408 }
6409 /**
6410 * Retrieve the root view from any component or `LView` by walking the parent `LView` until
6411 * reaching the root `LView`.
6412 *
6413 * @param componentOrLView any component or `LView`
6414 */
6415 function getRootView(componentOrLView) {
6416 ngDevMode && assertDefined(componentOrLView, 'component');
6417 var lView = isLView(componentOrLView) ? componentOrLView : readPatchedLView(componentOrLView);
6418 while (lView && !(lView[FLAGS] & 512 /* IsRoot */)) {
6419 lView = getLViewParent(lView);
6420 }
6421 ngDevMode && assertLView(lView);
6422 return lView;
6423 }
6424 /**
6425 * Returns the `RootContext` instance that is associated with
6426 * the application where the target is situated. It does this by walking the parent views until it
6427 * gets to the root view, then getting the context off of that.
6428 *
6429 * @param viewOrComponent the `LView` or component to get the root context for.
6430 */
6431 function getRootContext(viewOrComponent) {
6432 var rootView = getRootView(viewOrComponent);
6433 ngDevMode &&
6434 assertDefined(rootView[CONTEXT], 'RootView has no context. Perhaps it is disconnected?');
6435 return rootView[CONTEXT];
6436 }
6437 /**
6438 * Gets the first `LContainer` in the LView or `null` if none exists.
6439 */
6440 function getFirstLContainer(lView) {
6441 return getNearestLContainer(lView[CHILD_HEAD]);
6442 }
6443 /**
6444 * Gets the next `LContainer` that is a sibling of the given container.
6445 */
6446 function getNextLContainer(container) {
6447 return getNearestLContainer(container[NEXT]);
6448 }
6449 function getNearestLContainer(viewOrContainer) {
6450 while (viewOrContainer !== null && !isLContainer(viewOrContainer)) {
6451 viewOrContainer = viewOrContainer[NEXT];
6452 }
6453 return viewOrContainer;
6454 }
6455
6456 /**
6457 * @license
6458 * Copyright Google LLC All Rights Reserved.
6459 *
6460 * Use of this source code is governed by an MIT-style license that can be
6461 * found in the LICENSE file at https://angular.io/license
6462 */
6463 /**
6464 * Advances to an element for later binding instructions.
6465 *
6466 * Used in conjunction with instructions like {@link property} to act on elements with specified
6467 * indices, for example those created with {@link element} or {@link elementStart}.
6468 *
6469 * ```ts
6470 * (rf: RenderFlags, ctx: any) => {
6471 * if (rf & 1) {
6472 * text(0, 'Hello');
6473 * text(1, 'Goodbye')
6474 * element(2, 'div');
6475 * }
6476 * if (rf & 2) {
6477 * advance(2); // Advance twice to the <div>.
6478 * property('title', 'test');
6479 * }
6480 * }
6481 * ```
6482 * @param delta Number of elements to advance forwards by.
6483 *
6484 * @codeGenApi
6485 */
6486 function ɵɵadvance(delta) {
6487 ngDevMode && assertGreaterThan(delta, 0, 'Can only advance forward');
6488 selectIndexInternal(getTView(), getLView(), getSelectedIndex() + delta, getCheckNoChangesMode());
6489 }
6490 /**
6491 * Selects an element for later binding instructions.
6492 * @deprecated No longer being generated, but still used in unit tests.
6493 * @codeGenApi
6494 */
6495 function ɵɵselect(index) {
6496 // TODO(misko): Remove this function as it is no longer being used.
6497 selectIndexInternal(getTView(), getLView(), index, getCheckNoChangesMode());
6498 }
6499 function selectIndexInternal(tView, lView, index, checkNoChangesMode) {
6500 ngDevMode && assertGreaterThan(index, -1, 'Invalid index');
6501 ngDevMode && assertIndexInRange(lView, index + HEADER_OFFSET);
6502 // Flush the initial hooks for elements in the view that have been added up to this point.
6503 // PERF WARNING: do NOT extract this to a separate function without running benchmarks
6504 if (!checkNoChangesMode) {
6505 var hooksInitPhaseCompleted = (lView[FLAGS] & 3 /* InitPhaseStateMask */) === 3 /* InitPhaseCompleted */;
6506 if (hooksInitPhaseCompleted) {
6507 var preOrderCheckHooks = tView.preOrderCheckHooks;
6508 if (preOrderCheckHooks !== null) {
6509 executeCheckHooks(lView, preOrderCheckHooks, index);
6510 }
6511 }
6512 else {
6513 var preOrderHooks = tView.preOrderHooks;
6514 if (preOrderHooks !== null) {
6515 executeInitAndCheckHooks(lView, preOrderHooks, 0 /* OnInitHooksToBeRun */, index);
6516 }
6517 }
6518 }
6519 // We must set the selected index *after* running the hooks, because hooks may have side-effects
6520 // that cause other template functions to run, thus updating the selected index, which is global
6521 // state. If we run `setSelectedIndex` *before* we run the hooks, in some cases the selected index
6522 // will be altered by the time we leave the `ɵɵadvance` instruction.
6523 setSelectedIndex(index);
6524 }
6525
6526 /**
6527 * @license
6528 * Copyright Google LLC All Rights Reserved.
6529 *
6530 * Use of this source code is governed by an MIT-style license that can be
6531 * found in the LICENSE file at https://angular.io/license
6532 */
6533 function toTStylingRange(prev, next) {
6534 ngDevMode && assertNumberInRange(prev, 0, 32767 /* UNSIGNED_MASK */);
6535 ngDevMode && assertNumberInRange(next, 0, 32767 /* UNSIGNED_MASK */);
6536 return (prev << 17 /* PREV_SHIFT */ | next << 2 /* NEXT_SHIFT */);
6537 }
6538 function getTStylingRangePrev(tStylingRange) {
6539 ngDevMode && assertNumber(tStylingRange, 'expected number');
6540 return (tStylingRange >> 17 /* PREV_SHIFT */) & 32767 /* UNSIGNED_MASK */;
6541 }
6542 function getTStylingRangePrevDuplicate(tStylingRange) {
6543 ngDevMode && assertNumber(tStylingRange, 'expected number');
6544 return (tStylingRange & 2 /* PREV_DUPLICATE */) ==
6545 2 /* PREV_DUPLICATE */;
6546 }
6547 function setTStylingRangePrev(tStylingRange, previous) {
6548 ngDevMode && assertNumber(tStylingRange, 'expected number');
6549 ngDevMode && assertNumberInRange(previous, 0, 32767 /* UNSIGNED_MASK */);
6550 return ((tStylingRange & ~4294836224 /* PREV_MASK */) |
6551 (previous << 17 /* PREV_SHIFT */));
6552 }
6553 function setTStylingRangePrevDuplicate(tStylingRange) {
6554 ngDevMode && assertNumber(tStylingRange, 'expected number');
6555 return (tStylingRange | 2 /* PREV_DUPLICATE */);
6556 }
6557 function getTStylingRangeNext(tStylingRange) {
6558 ngDevMode && assertNumber(tStylingRange, 'expected number');
6559 return (tStylingRange & 131068 /* NEXT_MASK */) >> 2 /* NEXT_SHIFT */;
6560 }
6561 function setTStylingRangeNext(tStylingRange, next) {
6562 ngDevMode && assertNumber(tStylingRange, 'expected number');
6563 ngDevMode && assertNumberInRange(next, 0, 32767 /* UNSIGNED_MASK */);
6564 return ((tStylingRange & ~131068 /* NEXT_MASK */) | //
6565 next << 2 /* NEXT_SHIFT */);
6566 }
6567 function getTStylingRangeNextDuplicate(tStylingRange) {
6568 ngDevMode && assertNumber(tStylingRange, 'expected number');
6569 return (tStylingRange & 1 /* NEXT_DUPLICATE */) ===
6570 1 /* NEXT_DUPLICATE */;
6571 }
6572 function setTStylingRangeNextDuplicate(tStylingRange) {
6573 ngDevMode && assertNumber(tStylingRange, 'expected number');
6574 return (tStylingRange | 1 /* NEXT_DUPLICATE */);
6575 }
6576 function getTStylingRangeTail(tStylingRange) {
6577 ngDevMode && assertNumber(tStylingRange, 'expected number');
6578 var next = getTStylingRangeNext(tStylingRange);
6579 return next === 0 ? getTStylingRangePrev(tStylingRange) : next;
6580 }
6581
6582 /**
6583 * @license
6584 * Copyright Google LLC All Rights Reserved.
6585 *
6586 * Use of this source code is governed by an MIT-style license that can be
6587 * found in the LICENSE file at https://angular.io/license
6588 */
6589 /**
6590 * Patch a `debug` property on top of the existing object.
6591 *
6592 * NOTE: always call this method with `ngDevMode && attachDebugObject(...)`
6593 *
6594 * @param obj Object to patch
6595 * @param debug Value to patch
6596 */
6597 function attachDebugObject(obj, debug) {
6598 if (ngDevMode) {
6599 Object.defineProperty(obj, 'debug', { value: debug, enumerable: false });
6600 }
6601 else {
6602 throw new Error('This method should be guarded with `ngDevMode` so that it can be tree shaken in production!');
6603 }
6604 }
6605 /**
6606 * Patch a `debug` property getter on top of the existing object.
6607 *
6608 * NOTE: always call this method with `ngDevMode && attachDebugObject(...)`
6609 *
6610 * @param obj Object to patch
6611 * @param debugGetter Getter returning a value to patch
6612 */
6613 function attachDebugGetter(obj, debugGetter) {
6614 if (ngDevMode) {
6615 Object.defineProperty(obj, 'debug', { get: debugGetter, enumerable: false });
6616 }
6617 else {
6618 throw new Error('This method should be guarded with `ngDevMode` so that it can be tree shaken in production!');
6619 }
6620 }
6621
6622 /**
6623 * @license
6624 * Copyright Google LLC All Rights Reserved.
6625 *
6626 * Use of this source code is governed by an MIT-style license that can be
6627 * found in the LICENSE file at https://angular.io/license
6628 */
6629 var NG_DEV_MODE = ((typeof ngDevMode === 'undefined' || !!ngDevMode) && initNgDevMode());
6630 /*
6631 * This file contains conditionally attached classes which provide human readable (debug) level
6632 * information for `LView`, `LContainer` and other internal data structures. These data structures
6633 * are stored internally as array which makes it very difficult during debugging to reason about the
6634 * current state of the system.
6635 *
6636 * Patching the array with extra property does change the array's hidden class' but it does not
6637 * change the cost of access, therefore this patching should not have significant if any impact in
6638 * `ngDevMode` mode. (see: https://jsperf.com/array-vs-monkey-patch-array)
6639 *
6640 * So instead of seeing:
6641 * ```
6642 * Array(30) [Object, 659, null, …]
6643 * ```
6644 *
6645 * You get to see:
6646 * ```
6647 * LViewDebug {
6648 * views: [...],
6649 * flags: {attached: true, ...}
6650 * nodes: [
6651 * {html: '<div id="123">', ..., nodes: [
6652 * {html: '<span>', ..., nodes: null}
6653 * ]}
6654 * ]
6655 * }
6656 * ```
6657 */
6658 var LVIEW_COMPONENT_CACHE;
6659 var LVIEW_EMBEDDED_CACHE;
6660 var LVIEW_ROOT;
6661 /**
6662 * This function clones a blueprint and creates LView.
6663 *
6664 * Simple slice will keep the same type, and we need it to be LView
6665 */
6666 function cloneToLViewFromTViewBlueprint(tView) {
6667 var debugTView = tView;
6668 var lView = getLViewToClone(debugTView.type, tView.template && tView.template.name);
6669 return lView.concat(tView.blueprint);
6670 }
6671 function getLViewToClone(type, name) {
6672 switch (type) {
6673 case 0 /* Root */:
6674 if (LVIEW_ROOT === undefined)
6675 LVIEW_ROOT = new (createNamedArrayType('LRootView'))();
6676 return LVIEW_ROOT;
6677 case 1 /* Component */:
6678 if (LVIEW_COMPONENT_CACHE === undefined)
6679 LVIEW_COMPONENT_CACHE = new Map();
6680 var componentArray = LVIEW_COMPONENT_CACHE.get(name);
6681 if (componentArray === undefined) {
6682 componentArray = new (createNamedArrayType('LComponentView' + nameSuffix(name)))();
6683 LVIEW_COMPONENT_CACHE.set(name, componentArray);
6684 }
6685 return componentArray;
6686 case 2 /* Embedded */:
6687 if (LVIEW_EMBEDDED_CACHE === undefined)
6688 LVIEW_EMBEDDED_CACHE = new Map();
6689 var embeddedArray = LVIEW_EMBEDDED_CACHE.get(name);
6690 if (embeddedArray === undefined) {
6691 embeddedArray = new (createNamedArrayType('LEmbeddedView' + nameSuffix(name)))();
6692 LVIEW_EMBEDDED_CACHE.set(name, embeddedArray);
6693 }
6694 return embeddedArray;
6695 }
6696 throw new Error('unreachable code');
6697 }
6698 function nameSuffix(text) {
6699 if (text == null)
6700 return '';
6701 var index = text.lastIndexOf('_Template');
6702 return '_' + (index === -1 ? text : text.substr(0, index));
6703 }
6704 /**
6705 * This class is a debug version of Object literal so that we can have constructor name show up
6706 * in
6707 * debug tools in ngDevMode.
6708 */
6709 var TViewConstructor = /** @class */ (function () {
6710 function TView(type, //
6711 id, //
6712 blueprint, //
6713 template, //
6714 queries, //
6715 viewQuery, //
6716 node, //
6717 data, //
6718 bindingStartIndex, //
6719 expandoStartIndex, //
6720 expandoInstructions, //
6721 firstCreatePass, //
6722 firstUpdatePass, //
6723 staticViewQueries, //
6724 staticContentQueries, //
6725 preOrderHooks, //
6726 preOrderCheckHooks, //
6727 contentHooks, //
6728 contentCheckHooks, //
6729 viewHooks, //
6730 viewCheckHooks, //
6731 destroyHooks, //
6732 cleanup, //
6733 contentQueries, //
6734 components, //
6735 directiveRegistry, //
6736 pipeRegistry, //
6737 firstChild, //
6738 schemas, //
6739 consts, //
6740 incompleteFirstPass, //
6741 _decls, //
6742 _vars) {
6743 this.type = type;
6744 this.id = id;
6745 this.blueprint = blueprint;
6746 this.template = template;
6747 this.queries = queries;
6748 this.viewQuery = viewQuery;
6749 this.node = node;
6750 this.data = data;
6751 this.bindingStartIndex = bindingStartIndex;
6752 this.expandoStartIndex = expandoStartIndex;
6753 this.expandoInstructions = expandoInstructions;
6754 this.firstCreatePass = firstCreatePass;
6755 this.firstUpdatePass = firstUpdatePass;
6756 this.staticViewQueries = staticViewQueries;
6757 this.staticContentQueries = staticContentQueries;
6758 this.preOrderHooks = preOrderHooks;
6759 this.preOrderCheckHooks = preOrderCheckHooks;
6760 this.contentHooks = contentHooks;
6761 this.contentCheckHooks = contentCheckHooks;
6762 this.viewHooks = viewHooks;
6763 this.viewCheckHooks = viewCheckHooks;
6764 this.destroyHooks = destroyHooks;
6765 this.cleanup = cleanup;
6766 this.contentQueries = contentQueries;
6767 this.components = components;
6768 this.directiveRegistry = directiveRegistry;
6769 this.pipeRegistry = pipeRegistry;
6770 this.firstChild = firstChild;
6771 this.schemas = schemas;
6772 this.consts = consts;
6773 this.incompleteFirstPass = incompleteFirstPass;
6774 this._decls = _decls;
6775 this._vars = _vars;
6776 }
6777 Object.defineProperty(TView.prototype, "template_", {
6778 get: function () {
6779 var buf = [];
6780 processTNodeChildren(this.firstChild, buf);
6781 return buf.join('');
6782 },
6783 enumerable: false,
6784 configurable: true
6785 });
6786 return TView;
6787 }());
6788 var TNode = /** @class */ (function () {
6789 function TNode(tView_, //
6790 type, //
6791 index, //
6792 injectorIndex, //
6793 directiveStart, //
6794 directiveEnd, //
6795 directiveStylingLast, //
6796 propertyBindings, //
6797 flags, //
6798 providerIndexes, //
6799 tagName, //
6800 attrs, //
6801 mergedAttrs, //
6802 localNames, //
6803 initialInputs, //
6804 inputs, //
6805 outputs, //
6806 tViews, //
6807 next, //
6808 projectionNext, //
6809 child, //
6810 parent, //
6811 projection, //
6812 styles, //
6813 stylesWithoutHost, //
6814 residualStyles, //
6815 classes, //
6816 classesWithoutHost, //
6817 residualClasses, //
6818 classBindings, //
6819 styleBindings) {
6820 this.tView_ = tView_;
6821 this.type = type;
6822 this.index = index;
6823 this.injectorIndex = injectorIndex;
6824 this.directiveStart = directiveStart;
6825 this.directiveEnd = directiveEnd;
6826 this.directiveStylingLast = directiveStylingLast;
6827 this.propertyBindings = propertyBindings;
6828 this.flags = flags;
6829 this.providerIndexes = providerIndexes;
6830 this.tagName = tagName;
6831 this.attrs = attrs;
6832 this.mergedAttrs = mergedAttrs;
6833 this.localNames = localNames;
6834 this.initialInputs = initialInputs;
6835 this.inputs = inputs;
6836 this.outputs = outputs;
6837 this.tViews = tViews;
6838 this.next = next;
6839 this.projectionNext = projectionNext;
6840 this.child = child;
6841 this.parent = parent;
6842 this.projection = projection;
6843 this.styles = styles;
6844 this.stylesWithoutHost = stylesWithoutHost;
6845 this.residualStyles = residualStyles;
6846 this.classes = classes;
6847 this.classesWithoutHost = classesWithoutHost;
6848 this.residualClasses = residualClasses;
6849 this.classBindings = classBindings;
6850 this.styleBindings = styleBindings;
6851 }
6852 Object.defineProperty(TNode.prototype, "type_", {
6853 get: function () {
6854 switch (this.type) {
6855 case 0 /* Container */:
6856 return 'TNodeType.Container';
6857 case 3 /* Element */:
6858 return 'TNodeType.Element';
6859 case 4 /* ElementContainer */:
6860 return 'TNodeType.ElementContainer';
6861 case 5 /* IcuContainer */:
6862 return 'TNodeType.IcuContainer';
6863 case 1 /* Projection */:
6864 return 'TNodeType.Projection';
6865 case 2 /* View */:
6866 return 'TNodeType.View';
6867 default:
6868 return 'TNodeType.???';
6869 }
6870 },
6871 enumerable: false,
6872 configurable: true
6873 });
6874 Object.defineProperty(TNode.prototype, "flags_", {
6875 get: function () {
6876 var flags = [];
6877 if (this.flags & 16 /* hasClassInput */)
6878 flags.push('TNodeFlags.hasClassInput');
6879 if (this.flags & 8 /* hasContentQuery */)
6880 flags.push('TNodeFlags.hasContentQuery');
6881 if (this.flags & 32 /* hasStyleInput */)
6882 flags.push('TNodeFlags.hasStyleInput');
6883 if (this.flags & 128 /* hasHostBindings */)
6884 flags.push('TNodeFlags.hasHostBindings');
6885 if (this.flags & 2 /* isComponentHost */)
6886 flags.push('TNodeFlags.isComponentHost');
6887 if (this.flags & 1 /* isDirectiveHost */)
6888 flags.push('TNodeFlags.isDirectiveHost');
6889 if (this.flags & 64 /* isDetached */)
6890 flags.push('TNodeFlags.isDetached');
6891 if (this.flags & 4 /* isProjected */)
6892 flags.push('TNodeFlags.isProjected');
6893 return flags.join('|');
6894 },
6895 enumerable: false,
6896 configurable: true
6897 });
6898 Object.defineProperty(TNode.prototype, "template_", {
6899 get: function () {
6900 var buf = [];
6901 buf.push('<', this.tagName || this.type_);
6902 if (this.attrs) {
6903 for (var i = 0; i < this.attrs.length;) {
6904 var attrName = this.attrs[i++];
6905 if (typeof attrName == 'number') {
6906 break;
6907 }
6908 var attrValue = this.attrs[i++];
6909 buf.push(' ', attrName, '="', attrValue, '"');
6910 }
6911 }
6912 buf.push('>');
6913 processTNodeChildren(this.child, buf);
6914 buf.push('</', this.tagName || this.type_, '>');
6915 return buf.join('');
6916 },
6917 enumerable: false,
6918 configurable: true
6919 });
6920 Object.defineProperty(TNode.prototype, "styleBindings_", {
6921 get: function () {
6922 return toDebugStyleBinding(this, false);
6923 },
6924 enumerable: false,
6925 configurable: true
6926 });
6927 Object.defineProperty(TNode.prototype, "classBindings_", {
6928 get: function () {
6929 return toDebugStyleBinding(this, true);
6930 },
6931 enumerable: false,
6932 configurable: true
6933 });
6934 return TNode;
6935 }());
6936 var TNodeDebug = TNode;
6937 function toDebugStyleBinding(tNode, isClassBased) {
6938 var tData = tNode.tView_.data;
6939 var bindings = [];
6940 var range = isClassBased ? tNode.classBindings : tNode.styleBindings;
6941 var prev = getTStylingRangePrev(range);
6942 var next = getTStylingRangeNext(range);
6943 var isTemplate = next !== 0;
6944 var cursor = isTemplate ? next : prev;
6945 while (cursor !== 0) {
6946 var itemKey = tData[cursor];
6947 var itemRange = tData[cursor + 1];
6948 bindings.unshift({
6949 key: itemKey,
6950 index: cursor,
6951 isTemplate: isTemplate,
6952 prevDuplicate: getTStylingRangePrevDuplicate(itemRange),
6953 nextDuplicate: getTStylingRangeNextDuplicate(itemRange),
6954 nextIndex: getTStylingRangeNext(itemRange),
6955 prevIndex: getTStylingRangePrev(itemRange),
6956 });
6957 if (cursor === prev)
6958 isTemplate = false;
6959 cursor = getTStylingRangePrev(itemRange);
6960 }
6961 bindings.push((isClassBased ? tNode.residualClasses : tNode.residualStyles) || null);
6962 return bindings;
6963 }
6964 function processTNodeChildren(tNode, buf) {
6965 while (tNode) {
6966 buf.push(tNode.template_);
6967 tNode = tNode.next;
6968 }
6969 }
6970 var TViewData = NG_DEV_MODE && createNamedArrayType('TViewData') || null;
6971 var TVIEWDATA_EMPTY; // can't initialize here or it will not be tree shaken, because
6972 // `LView` constructor could have side-effects.
6973 /**
6974 * This function clones a blueprint and creates TData.
6975 *
6976 * Simple slice will keep the same type, and we need it to be TData
6977 */
6978 function cloneToTViewData(list) {
6979 if (TVIEWDATA_EMPTY === undefined)
6980 TVIEWDATA_EMPTY = new TViewData();
6981 return TVIEWDATA_EMPTY.concat(list);
6982 }
6983 var LViewBlueprint = NG_DEV_MODE && createNamedArrayType('LViewBlueprint') || null;
6984 var MatchesArray = NG_DEV_MODE && createNamedArrayType('MatchesArray') || null;
6985 var TViewComponents = NG_DEV_MODE && createNamedArrayType('TViewComponents') || null;
6986 var TNodeLocalNames = NG_DEV_MODE && createNamedArrayType('TNodeLocalNames') || null;
6987 var TNodeInitialInputs = NG_DEV_MODE && createNamedArrayType('TNodeInitialInputs') || null;
6988 var TNodeInitialData = NG_DEV_MODE && createNamedArrayType('TNodeInitialData') || null;
6989 var LCleanup = NG_DEV_MODE && createNamedArrayType('LCleanup') || null;
6990 var TCleanup = NG_DEV_MODE && createNamedArrayType('TCleanup') || null;
6991 function attachLViewDebug(lView) {
6992 attachDebugObject(lView, new LViewDebug(lView));
6993 }
6994 function attachLContainerDebug(lContainer) {
6995 attachDebugObject(lContainer, new LContainerDebug(lContainer));
6996 }
6997 function toDebug(obj) {
6998 if (obj) {
6999 var debug = obj.debug;
7000 assertDefined(debug, 'Object does not have a debug representation.');
7001 return debug;
7002 }
7003 else {
7004 return obj;
7005 }
7006 }
7007 /**
7008 * Use this method to unwrap a native element in `LView` and convert it into HTML for easier
7009 * reading.
7010 *
7011 * @param value possibly wrapped native DOM node.
7012 * @param includeChildren If `true` then the serialized HTML form will include child elements
7013 * (same
7014 * as `outerHTML`). If `false` then the serialized HTML form will only contain the element
7015 * itself
7016 * (will not serialize child elements).
7017 */
7018 function toHtml(value, includeChildren) {
7019 if (includeChildren === void 0) { includeChildren = false; }
7020 var node = unwrapRNode(value);
7021 if (node) {
7022 switch (node.nodeType) {
7023 case Node.TEXT_NODE:
7024 return node.textContent;
7025 case Node.COMMENT_NODE:
7026 return "<!--" + node.textContent + "-->";
7027 case Node.ELEMENT_NODE:
7028 var outerHTML = node.outerHTML;
7029 if (includeChildren) {
7030 return outerHTML;
7031 }
7032 else {
7033 var innerHTML = '>' + node.innerHTML + '<';
7034 return (outerHTML.split(innerHTML)[0]) + '>';
7035 }
7036 }
7037 }
7038 return null;
7039 }
7040 var LViewDebug = /** @class */ (function () {
7041 function LViewDebug(_raw_lView) {
7042 this._raw_lView = _raw_lView;
7043 }
7044 Object.defineProperty(LViewDebug.prototype, "flags", {
7045 /**
7046 * Flags associated with the `LView` unpacked into a more readable state.
7047 */
7048 get: function () {
7049 var flags = this._raw_lView[FLAGS];
7050 return {
7051 __raw__flags__: flags,
7052 initPhaseState: flags & 3 /* InitPhaseStateMask */,
7053 creationMode: !!(flags & 4 /* CreationMode */),
7054 firstViewPass: !!(flags & 8 /* FirstLViewPass */),
7055 checkAlways: !!(flags & 16 /* CheckAlways */),
7056 dirty: !!(flags & 64 /* Dirty */),
7057 attached: !!(flags & 128 /* Attached */),
7058 destroyed: !!(flags & 256 /* Destroyed */),
7059 isRoot: !!(flags & 512 /* IsRoot */),
7060 indexWithinInitPhase: flags >> 11 /* IndexWithinInitPhaseShift */,
7061 };
7062 },
7063 enumerable: false,
7064 configurable: true
7065 });
7066 Object.defineProperty(LViewDebug.prototype, "parent", {
7067 get: function () {
7068 return toDebug(this._raw_lView[PARENT]);
7069 },
7070 enumerable: false,
7071 configurable: true
7072 });
7073 Object.defineProperty(LViewDebug.prototype, "hostHTML", {
7074 get: function () {
7075 return toHtml(this._raw_lView[HOST], true);
7076 },
7077 enumerable: false,
7078 configurable: true
7079 });
7080 Object.defineProperty(LViewDebug.prototype, "html", {
7081 get: function () {
7082 return (this.nodes || []).map(function (node) { return toHtml(node.native, true); }).join('');
7083 },
7084 enumerable: false,
7085 configurable: true
7086 });
7087 Object.defineProperty(LViewDebug.prototype, "context", {
7088 get: function () {
7089 return this._raw_lView[CONTEXT];
7090 },
7091 enumerable: false,
7092 configurable: true
7093 });
7094 Object.defineProperty(LViewDebug.prototype, "nodes", {
7095 /**
7096 * The tree of nodes associated with the current `LView`. The nodes have been normalized into
7097 * a tree structure with relevant details pulled out for readability.
7098 */
7099 get: function () {
7100 var lView = this._raw_lView;
7101 var tNode = lView[TVIEW].firstChild;
7102 return toDebugNodes(tNode, lView);
7103 },
7104 enumerable: false,
7105 configurable: true
7106 });
7107 Object.defineProperty(LViewDebug.prototype, "tView", {
7108 get: function () {
7109 return this._raw_lView[TVIEW];
7110 },
7111 enumerable: false,
7112 configurable: true
7113 });
7114 Object.defineProperty(LViewDebug.prototype, "cleanup", {
7115 get: function () {
7116 return this._raw_lView[CLEANUP];
7117 },
7118 enumerable: false,
7119 configurable: true
7120 });
7121 Object.defineProperty(LViewDebug.prototype, "injector", {
7122 get: function () {
7123 return this._raw_lView[INJECTOR$1];
7124 },
7125 enumerable: false,
7126 configurable: true
7127 });
7128 Object.defineProperty(LViewDebug.prototype, "rendererFactory", {
7129 get: function () {
7130 return this._raw_lView[RENDERER_FACTORY];
7131 },
7132 enumerable: false,
7133 configurable: true
7134 });
7135 Object.defineProperty(LViewDebug.prototype, "renderer", {
7136 get: function () {
7137 return this._raw_lView[RENDERER];
7138 },
7139 enumerable: false,
7140 configurable: true
7141 });
7142 Object.defineProperty(LViewDebug.prototype, "sanitizer", {
7143 get: function () {
7144 return this._raw_lView[SANITIZER];
7145 },
7146 enumerable: false,
7147 configurable: true
7148 });
7149 Object.defineProperty(LViewDebug.prototype, "childHead", {
7150 get: function () {
7151 return toDebug(this._raw_lView[CHILD_HEAD]);
7152 },
7153 enumerable: false,
7154 configurable: true
7155 });
7156 Object.defineProperty(LViewDebug.prototype, "next", {
7157 get: function () {
7158 return toDebug(this._raw_lView[NEXT]);
7159 },
7160 enumerable: false,
7161 configurable: true
7162 });
7163 Object.defineProperty(LViewDebug.prototype, "childTail", {
7164 get: function () {
7165 return toDebug(this._raw_lView[CHILD_TAIL]);
7166 },
7167 enumerable: false,
7168 configurable: true
7169 });
7170 Object.defineProperty(LViewDebug.prototype, "declarationView", {
7171 get: function () {
7172 return toDebug(this._raw_lView[DECLARATION_VIEW]);
7173 },
7174 enumerable: false,
7175 configurable: true
7176 });
7177 Object.defineProperty(LViewDebug.prototype, "queries", {
7178 get: function () {
7179 return this._raw_lView[QUERIES];
7180 },
7181 enumerable: false,
7182 configurable: true
7183 });
7184 Object.defineProperty(LViewDebug.prototype, "tHost", {
7185 get: function () {
7186 return this._raw_lView[T_HOST];
7187 },
7188 enumerable: false,
7189 configurable: true
7190 });
7191 Object.defineProperty(LViewDebug.prototype, "decls", {
7192 get: function () {
7193 var tView = this.tView;
7194 var start = HEADER_OFFSET;
7195 return toLViewRange(this.tView, this._raw_lView, start, start + tView._decls);
7196 },
7197 enumerable: false,
7198 configurable: true
7199 });
7200 Object.defineProperty(LViewDebug.prototype, "vars", {
7201 get: function () {
7202 var tView = this.tView;
7203 var start = HEADER_OFFSET + tView._decls;
7204 return toLViewRange(this.tView, this._raw_lView, start, start + tView._vars);
7205 },
7206 enumerable: false,
7207 configurable: true
7208 });
7209 Object.defineProperty(LViewDebug.prototype, "i18n", {
7210 get: function () {
7211 var tView = this.tView;
7212 var start = HEADER_OFFSET + tView._decls + tView._vars;
7213 return toLViewRange(this.tView, this._raw_lView, start, this.tView.expandoStartIndex);
7214 },
7215 enumerable: false,
7216 configurable: true
7217 });
7218 Object.defineProperty(LViewDebug.prototype, "expando", {
7219 get: function () {
7220 var tView = this.tView;
7221 return toLViewRange(this.tView, this._raw_lView, this.tView.expandoStartIndex, this._raw_lView.length);
7222 },
7223 enumerable: false,
7224 configurable: true
7225 });
7226 Object.defineProperty(LViewDebug.prototype, "childViews", {
7227 /**
7228 * Normalized view of child views (and containers) attached at this location.
7229 */
7230 get: function () {
7231 var childViews = [];
7232 var child = this.childHead;
7233 while (child) {
7234 childViews.push(child);
7235 child = child.next;
7236 }
7237 return childViews;
7238 },
7239 enumerable: false,
7240 configurable: true
7241 });
7242 return LViewDebug;
7243 }());
7244 function toLViewRange(tView, lView, start, end) {
7245 var content = [];
7246 for (var index = start; index < end; index++) {
7247 content.push({ index: index, t: tView.data[index], l: lView[index] });
7248 }
7249 return { start: start, end: end, length: end - start, content: content };
7250 }
7251 /**
7252 * Turns a flat list of nodes into a tree by walking the associated `TNode` tree.
7253 *
7254 * @param tNode
7255 * @param lView
7256 */
7257 function toDebugNodes(tNode, lView) {
7258 if (tNode) {
7259 var debugNodes = [];
7260 var tNodeCursor = tNode;
7261 while (tNodeCursor) {
7262 debugNodes.push(buildDebugNode(tNodeCursor, lView, tNodeCursor.index));
7263 tNodeCursor = tNodeCursor.next;
7264 }
7265 return debugNodes;
7266 }
7267 else {
7268 return [];
7269 }
7270 }
7271 function buildDebugNode(tNode, lView, nodeIndex) {
7272 var rawValue = lView[nodeIndex];
7273 var native = unwrapRNode(rawValue);
7274 return {
7275 html: toHtml(native),
7276 type: TNodeTypeAsString[tNode.type],
7277 native: native,
7278 children: toDebugNodes(tNode.child, lView),
7279 };
7280 }
7281 var LContainerDebug = /** @class */ (function () {
7282 function LContainerDebug(_raw_lContainer) {
7283 this._raw_lContainer = _raw_lContainer;
7284 }
7285 Object.defineProperty(LContainerDebug.prototype, "hasTransplantedViews", {
7286 get: function () {
7287 return this._raw_lContainer[HAS_TRANSPLANTED_VIEWS];
7288 },
7289 enumerable: false,
7290 configurable: true
7291 });
7292 Object.defineProperty(LContainerDebug.prototype, "views", {
7293 get: function () {
7294 return this._raw_lContainer.slice(CONTAINER_HEADER_OFFSET)
7295 .map(toDebug);
7296 },
7297 enumerable: false,
7298 configurable: true
7299 });
7300 Object.defineProperty(LContainerDebug.prototype, "parent", {
7301 get: function () {
7302 return toDebug(this._raw_lContainer[PARENT]);
7303 },
7304 enumerable: false,
7305 configurable: true
7306 });
7307 Object.defineProperty(LContainerDebug.prototype, "movedViews", {
7308 get: function () {
7309 return this._raw_lContainer[MOVED_VIEWS];
7310 },
7311 enumerable: false,
7312 configurable: true
7313 });
7314 Object.defineProperty(LContainerDebug.prototype, "host", {
7315 get: function () {
7316 return this._raw_lContainer[HOST];
7317 },
7318 enumerable: false,
7319 configurable: true
7320 });
7321 Object.defineProperty(LContainerDebug.prototype, "native", {
7322 get: function () {
7323 return this._raw_lContainer[NATIVE];
7324 },
7325 enumerable: false,
7326 configurable: true
7327 });
7328 Object.defineProperty(LContainerDebug.prototype, "next", {
7329 get: function () {
7330 return toDebug(this._raw_lContainer[NEXT]);
7331 },
7332 enumerable: false,
7333 configurable: true
7334 });
7335 return LContainerDebug;
7336 }());
7337 /**
7338 * Return an `LView` value if found.
7339 *
7340 * @param value `LView` if any
7341 */
7342 function readLViewValue(value) {
7343 while (Array.isArray(value)) {
7344 // This check is not quite right, as it does not take into account `StylingContext`
7345 // This is why it is in debug, not in util.ts
7346 if (value.length >= HEADER_OFFSET - 1)
7347 return value;
7348 value = value[HOST];
7349 }
7350 return null;
7351 }
7352
7353 var ɵ0$4 = function () { return Promise.resolve(null); };
7354 /**
7355 * A permanent marker promise which signifies that the current CD tree is
7356 * clean.
7357 */
7358 var _CLEAN_PROMISE = (ɵ0$4)();
7359 /**
7360 * Process the `TView.expandoInstructions`. (Execute the `hostBindings`.)
7361 *
7362 * @param tView `TView` containing the `expandoInstructions`
7363 * @param lView `LView` associated with the `TView`
7364 */
7365 function setHostBindingsByExecutingExpandoInstructions(tView, lView) {
7366 ngDevMode && assertSame(tView, lView[TVIEW], '`LView` is not associated with the `TView`!');
7367 try {
7368 var expandoInstructions = tView.expandoInstructions;
7369 if (expandoInstructions !== null) {
7370 var bindingRootIndex = tView.expandoStartIndex;
7371 var currentDirectiveIndex = -1;
7372 var currentElementIndex = -1;
7373 // TODO(misko): PERF It is possible to get here with `TView.expandoInstructions` containing no
7374 // functions to execute. This is wasteful as there is no work to be done, but we still need
7375 // to iterate over the instructions.
7376 // In example of this is in this test: `host_binding_spec.ts`
7377 // `fit('should not cause problems if detectChanges is called when a property updates', ...`
7378 // In the above test we get here with expando [0, 0, 1] which requires a lot of processing but
7379 // there is no function to execute.
7380 for (var i = 0; i < expandoInstructions.length; i++) {
7381 var instruction = expandoInstructions[i];
7382 if (typeof instruction === 'number') {
7383 if (instruction <= 0) {
7384 // Negative numbers mean that we are starting new EXPANDO block and need to update
7385 // the current element and directive index.
7386 // Important: In JS `-x` and `0-x` is not the same! If `x===0` then `-x` will produce
7387 // `-0` which requires non standard math arithmetic and it can prevent VM optimizations.
7388 // `0-0` will always produce `0` and will not cause a potential deoptimization in VM.
7389 // TODO(misko): PERF This should be refactored to use `~instruction` as that does not
7390 // suffer from `-0` and it is faster/more compact.
7391 currentElementIndex = 0 - instruction;
7392 setSelectedIndex(currentElementIndex);
7393 // Injector block and providers are taken into account.
7394 var providerCount = expandoInstructions[++i];
7395 bindingRootIndex += INJECTOR_BLOOM_PARENT_SIZE + providerCount;
7396 currentDirectiveIndex = bindingRootIndex;
7397 }
7398 else {
7399 // This is either the injector size (so the binding root can skip over directives
7400 // and get to the first set of host bindings on this node) or the host var count
7401 // (to get to the next set of host bindings on this node).
7402 bindingRootIndex += instruction;
7403 }
7404 }
7405 else {
7406 // If it's not a number, it's a host binding function that needs to be executed.
7407 if (instruction !== null) {
7408 ngDevMode &&
7409 assertLessThan(currentDirectiveIndex, 1048576 /* CptViewProvidersCountShifter */, 'Reached the max number of host bindings');
7410 setBindingRootForHostBindings(bindingRootIndex, currentDirectiveIndex);
7411 var hostCtx = lView[currentDirectiveIndex];
7412 instruction(2 /* Update */, hostCtx);
7413 }
7414 // TODO(misko): PERF Relying on incrementing the `currentDirectiveIndex` here is
7415 // sub-optimal. The implications are that if we have a lot of directives but none of them
7416 // have host bindings we nevertheless need to iterate over the expando instructions to
7417 // update the counter. It would be much better if we could encode the
7418 // `currentDirectiveIndex` into the `expandoInstruction` array so that we only need to
7419 // iterate over those directives which actually have `hostBindings`.
7420 currentDirectiveIndex++;
7421 }
7422 }
7423 }
7424 }
7425 finally {
7426 setSelectedIndex(-1);
7427 }
7428 }
7429 /** Refreshes all content queries declared by directives in a given view */
7430 function refreshContentQueries(tView, lView) {
7431 var contentQueries = tView.contentQueries;
7432 if (contentQueries !== null) {
7433 for (var i = 0; i < contentQueries.length; i += 2) {
7434 var queryStartIdx = contentQueries[i];
7435 var directiveDefIdx = contentQueries[i + 1];
7436 if (directiveDefIdx !== -1) {
7437 var directiveDef = tView.data[directiveDefIdx];
7438 ngDevMode &&
7439 assertDefined(directiveDef.contentQueries, 'contentQueries function should be defined');
7440 setCurrentQueryIndex(queryStartIdx);
7441 directiveDef.contentQueries(2 /* Update */, lView[directiveDefIdx], directiveDefIdx);
7442 }
7443 }
7444 }
7445 }
7446 /** Refreshes child components in the current view (update mode). */
7447 function refreshChildComponents(hostLView, components) {
7448 for (var i = 0; i < components.length; i++) {
7449 refreshComponent(hostLView, components[i]);
7450 }
7451 }
7452 /** Renders child components in the current view (creation mode). */
7453 function renderChildComponents(hostLView, components) {
7454 for (var i = 0; i < components.length; i++) {
7455 renderComponent(hostLView, components[i]);
7456 }
7457 }
7458 /**
7459 * Creates a native element from a tag name, using a renderer.
7460 * @param name the tag name
7461 * @param renderer A renderer to use
7462 * @returns the element created
7463 */
7464 function elementCreate(name, renderer, namespace) {
7465 if (isProceduralRenderer(renderer)) {
7466 return renderer.createElement(name, namespace);
7467 }
7468 else {
7469 return namespace === null ? renderer.createElement(name) :
7470 renderer.createElementNS(namespace, name);
7471 }
7472 }
7473 function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector) {
7474 var lView = ngDevMode ? cloneToLViewFromTViewBlueprint(tView) : tView.blueprint.slice();
7475 lView[HOST] = host;
7476 lView[FLAGS] = flags | 4 /* CreationMode */ | 128 /* Attached */ | 8 /* FirstLViewPass */;
7477 resetPreOrderHookFlags(lView);
7478 lView[PARENT] = lView[DECLARATION_VIEW] = parentLView;
7479 lView[CONTEXT] = context;
7480 lView[RENDERER_FACTORY] = (rendererFactory || parentLView && parentLView[RENDERER_FACTORY]);
7481 ngDevMode && assertDefined(lView[RENDERER_FACTORY], 'RendererFactory is required');
7482 lView[RENDERER] = (renderer || parentLView && parentLView[RENDERER]);
7483 ngDevMode && assertDefined(lView[RENDERER], 'Renderer is required');
7484 lView[SANITIZER] = sanitizer || parentLView && parentLView[SANITIZER] || null;
7485 lView[INJECTOR$1] = injector || parentLView && parentLView[INJECTOR$1] || null;
7486 lView[T_HOST] = tHostNode;
7487 ngDevMode &&
7488 assertEqual(tView.type == 2 /* Embedded */ ? parentLView !== null : true, true, 'Embedded views must have parentLView');
7489 lView[DECLARATION_COMPONENT_VIEW] =
7490 tView.type == 2 /* Embedded */ ? parentLView[DECLARATION_COMPONENT_VIEW] : lView;
7491 ngDevMode && attachLViewDebug(lView);
7492 return lView;
7493 }
7494 function getOrCreateTNode(tView, tHostNode, index, type, name, attrs) {
7495 // Keep this function short, so that the VM will inline it.
7496 var adjustedIndex = index + HEADER_OFFSET;
7497 var tNode = tView.data[adjustedIndex] ||
7498 createTNodeAtIndex(tView, tHostNode, adjustedIndex, type, name, attrs);
7499 setPreviousOrParentTNode(tNode, true);
7500 return tNode;
7501 }
7502 function createTNodeAtIndex(tView, tHostNode, adjustedIndex, type, name, attrs) {
7503 var previousOrParentTNode = getPreviousOrParentTNode();
7504 var isParent = getIsParent();
7505 var parent = isParent ? previousOrParentTNode : previousOrParentTNode && previousOrParentTNode.parent;
7506 // Parents cannot cross component boundaries because components will be used in multiple places,
7507 // so it's only set if the view is the same.
7508 var parentInSameView = parent && parent !== tHostNode;
7509 var tParentNode = parentInSameView ? parent : null;
7510 var tNode = tView.data[adjustedIndex] =
7511 createTNode(tView, tParentNode, type, adjustedIndex, name, attrs);
7512 // Assign a pointer to the first child node of a given view. The first node is not always the one
7513 // at index 0, in case of i18n, index 0 can be the instruction `i18nStart` and the first node has
7514 // the index 1 or more, so we can't just check node index.
7515 if (tView.firstChild === null) {
7516 tView.firstChild = tNode;
7517 }
7518 if (previousOrParentTNode) {
7519 if (isParent && previousOrParentTNode.child == null &&
7520 (tNode.parent !== null || previousOrParentTNode.type === 2 /* View */)) {
7521 // We are in the same view, which means we are adding content node to the parent view.
7522 previousOrParentTNode.child = tNode;
7523 }
7524 else if (!isParent) {
7525 previousOrParentTNode.next = tNode;
7526 }
7527 }
7528 return tNode;
7529 }
7530 function assignTViewNodeToLView(tView, tParentNode, index, lView) {
7531 // View nodes are not stored in data because they can be added / removed at runtime (which
7532 // would cause indices to change). Their TNodes are instead stored in tView.node.
7533 var tNode = tView.node;
7534 if (tNode == null) {
7535 ngDevMode && tParentNode &&
7536 assertNodeOfPossibleTypes(tParentNode, [3 /* Element */, 0 /* Container */]);
7537 tView.node = tNode = createTNode(tView, tParentNode, //
7538 2 /* View */, index, null, null);
7539 }
7540 lView[T_HOST] = tNode;
7541 }
7542 /**
7543 * When elements are created dynamically after a view blueprint is created (e.g. through
7544 * i18nApply() or ComponentFactory.create), we need to adjust the blueprint for future
7545 * template passes.
7546 *
7547 * @param tView `TView` associated with `LView`
7548 * @param view The `LView` containing the blueprint to adjust
7549 * @param numSlotsToAlloc The number of slots to alloc in the LView, should be >0
7550 */
7551 function allocExpando(tView, lView, numSlotsToAlloc) {
7552 ngDevMode &&
7553 assertGreaterThan(numSlotsToAlloc, 0, 'The number of slots to alloc should be greater than 0');
7554 if (numSlotsToAlloc > 0) {
7555 if (tView.firstCreatePass) {
7556 for (var i = 0; i < numSlotsToAlloc; i++) {
7557 tView.blueprint.push(null);
7558 tView.data.push(null);
7559 lView.push(null);
7560 }
7561 // We should only increment the expando start index if there aren't already directives
7562 // and injectors saved in the "expando" section
7563 if (!tView.expandoInstructions) {
7564 tView.expandoStartIndex += numSlotsToAlloc;
7565 }
7566 else {
7567 // Since we're adding the dynamic nodes into the expando section, we need to let the host
7568 // bindings know that they should skip x slots
7569 tView.expandoInstructions.push(numSlotsToAlloc);
7570 }
7571 }
7572 }
7573 }
7574 //////////////////////////
7575 //// Render
7576 //////////////////////////
7577 /**
7578 * Processes a view in the creation mode. This includes a number of steps in a specific order:
7579 * - creating view query functions (if any);
7580 * - executing a template function in the creation mode;
7581 * - updating static queries (if any);
7582 * - creating child components defined in a given view.
7583 */
7584 function renderView(tView, lView, context) {
7585 ngDevMode && assertEqual(isCreationMode(lView), true, 'Should be run in creation mode');
7586 enterView(lView, lView[T_HOST]);
7587 try {
7588 var viewQuery = tView.viewQuery;
7589 if (viewQuery !== null) {
7590 executeViewQueryFn(1 /* Create */, viewQuery, context);
7591 }
7592 // Execute a template associated with this view, if it exists. A template function might not be
7593 // defined for the root component views.
7594 var templateFn = tView.template;
7595 if (templateFn !== null) {
7596 executeTemplate(tView, lView, templateFn, 1 /* Create */, context);
7597 }
7598 // This needs to be set before children are processed to support recursive components.
7599 // This must be set to false immediately after the first creation run because in an
7600 // ngFor loop, all the views will be created together before update mode runs and turns
7601 // off firstCreatePass. If we don't set it here, instances will perform directive
7602 // matching, etc again and again.
7603 if (tView.firstCreatePass) {
7604 tView.firstCreatePass = false;
7605 }
7606 // We resolve content queries specifically marked as `static` in creation mode. Dynamic
7607 // content queries are resolved during change detection (i.e. update mode), after embedded
7608 // views are refreshed (see block above).
7609 if (tView.staticContentQueries) {
7610 refreshContentQueries(tView, lView);
7611 }
7612 // We must materialize query results before child components are processed
7613 // in case a child component has projected a container. The LContainer needs
7614 // to exist so the embedded views are properly attached by the container.
7615 if (tView.staticViewQueries) {
7616 executeViewQueryFn(2 /* Update */, tView.viewQuery, context);
7617 }
7618 // Render child component views.
7619 var components = tView.components;
7620 if (components !== null) {
7621 renderChildComponents(lView, components);
7622 }
7623 }
7624 catch (error) {
7625 // If we didn't manage to get past the first template pass due to
7626 // an error, mark the view as corrupted so we can try to recover.
7627 if (tView.firstCreatePass) {
7628 tView.incompleteFirstPass = true;
7629 }
7630 throw error;
7631 }
7632 finally {
7633 lView[FLAGS] &= ~4 /* CreationMode */;
7634 leaveView();
7635 }
7636 }
7637 /**
7638 * Processes a view in update mode. This includes a number of steps in a specific order:
7639 * - executing a template function in update mode;
7640 * - executing hooks;
7641 * - refreshing queries;
7642 * - setting host bindings;
7643 * - refreshing child (embedded and component) views.
7644 */
7645 function refreshView(tView, lView, templateFn, context) {
7646 ngDevMode && assertEqual(isCreationMode(lView), false, 'Should be run in update mode');
7647 var flags = lView[FLAGS];
7648 if ((flags & 256 /* Destroyed */) === 256 /* Destroyed */)
7649 return;
7650 enterView(lView, lView[T_HOST]);
7651 var checkNoChangesMode = getCheckNoChangesMode();
7652 try {
7653 resetPreOrderHookFlags(lView);
7654 setBindingIndex(tView.bindingStartIndex);
7655 if (templateFn !== null) {
7656 executeTemplate(tView, lView, templateFn, 2 /* Update */, context);
7657 }
7658 var hooksInitPhaseCompleted = (flags & 3 /* InitPhaseStateMask */) === 3 /* InitPhaseCompleted */;
7659 // execute pre-order hooks (OnInit, OnChanges, DoCheck)
7660 // PERF WARNING: do NOT extract this to a separate function without running benchmarks
7661 if (!checkNoChangesMode) {
7662 if (hooksInitPhaseCompleted) {
7663 var preOrderCheckHooks = tView.preOrderCheckHooks;
7664 if (preOrderCheckHooks !== null) {
7665 executeCheckHooks(lView, preOrderCheckHooks, null);
7666 }
7667 }
7668 else {
7669 var preOrderHooks = tView.preOrderHooks;
7670 if (preOrderHooks !== null) {
7671 executeInitAndCheckHooks(lView, preOrderHooks, 0 /* OnInitHooksToBeRun */, null);
7672 }
7673 incrementInitPhaseFlags(lView, 0 /* OnInitHooksToBeRun */);
7674 }
7675 }
7676 // First mark transplanted views that are declared in this lView as needing a refresh at their
7677 // insertion points. This is needed to avoid the situation where the template is defined in this
7678 // `LView` but its declaration appears after the insertion component.
7679 markTransplantedViewsForRefresh(lView);
7680 refreshEmbeddedViews(lView);
7681 // Content query results must be refreshed before content hooks are called.
7682 if (tView.contentQueries !== null) {
7683 refreshContentQueries(tView, lView);
7684 }
7685 // execute content hooks (AfterContentInit, AfterContentChecked)
7686 // PERF WARNING: do NOT extract this to a separate function without running benchmarks
7687 if (!checkNoChangesMode) {
7688 if (hooksInitPhaseCompleted) {
7689 var contentCheckHooks = tView.contentCheckHooks;
7690 if (contentCheckHooks !== null) {
7691 executeCheckHooks(lView, contentCheckHooks);
7692 }
7693 }
7694 else {
7695 var contentHooks = tView.contentHooks;
7696 if (contentHooks !== null) {
7697 executeInitAndCheckHooks(lView, contentHooks, 1 /* AfterContentInitHooksToBeRun */);
7698 }
7699 incrementInitPhaseFlags(lView, 1 /* AfterContentInitHooksToBeRun */);
7700 }
7701 }
7702 setHostBindingsByExecutingExpandoInstructions(tView, lView);
7703 // Refresh child component views.
7704 var components = tView.components;
7705 if (components !== null) {
7706 refreshChildComponents(lView, components);
7707 }
7708 // View queries must execute after refreshing child components because a template in this view
7709 // could be inserted in a child component. If the view query executes before child component
7710 // refresh, the template might not yet be inserted.
7711 var viewQuery = tView.viewQuery;
7712 if (viewQuery !== null) {
7713 executeViewQueryFn(2 /* Update */, viewQuery, context);
7714 }
7715 // execute view hooks (AfterViewInit, AfterViewChecked)
7716 // PERF WARNING: do NOT extract this to a separate function without running benchmarks
7717 if (!checkNoChangesMode) {
7718 if (hooksInitPhaseCompleted) {
7719 var viewCheckHooks = tView.viewCheckHooks;
7720 if (viewCheckHooks !== null) {
7721 executeCheckHooks(lView, viewCheckHooks);
7722 }
7723 }
7724 else {
7725 var viewHooks = tView.viewHooks;
7726 if (viewHooks !== null) {
7727 executeInitAndCheckHooks(lView, viewHooks, 2 /* AfterViewInitHooksToBeRun */);
7728 }
7729 incrementInitPhaseFlags(lView, 2 /* AfterViewInitHooksToBeRun */);
7730 }
7731 }
7732 if (tView.firstUpdatePass === true) {
7733 // We need to make sure that we only flip the flag on successful `refreshView` only
7734 // Don't do this in `finally` block.
7735 // If we did this in `finally` block then an exception could block the execution of styling
7736 // instructions which in turn would be unable to insert themselves into the styling linked
7737 // list. The result of this would be that if the exception would not be throw on subsequent CD
7738 // the styling would be unable to process it data and reflect to the DOM.
7739 tView.firstUpdatePass = false;
7740 }
7741 // Do not reset the dirty state when running in check no changes mode. We don't want components
7742 // to behave differently depending on whether check no changes is enabled or not. For example:
7743 // Marking an OnPush component as dirty from within the `ngAfterViewInit` hook in order to
7744 // refresh a `NgClass` binding should work. If we would reset the dirty state in the check
7745 // no changes cycle, the component would be not be dirty for the next update pass. This would
7746 // be different in production mode where the component dirty state is not reset.
7747 if (!checkNoChangesMode) {
7748 lView[FLAGS] &= ~(64 /* Dirty */ | 8 /* FirstLViewPass */);
7749 }
7750 if (lView[FLAGS] & 1024 /* RefreshTransplantedView */) {
7751 lView[FLAGS] &= ~1024 /* RefreshTransplantedView */;
7752 updateTransplantedViewCount(lView[PARENT], -1);
7753 }
7754 }
7755 finally {
7756 leaveView();
7757 }
7758 }
7759 function renderComponentOrTemplate(tView, lView, templateFn, context) {
7760 var rendererFactory = lView[RENDERER_FACTORY];
7761 var normalExecutionPath = !getCheckNoChangesMode();
7762 var creationModeIsActive = isCreationMode(lView);
7763 try {
7764 if (normalExecutionPath && !creationModeIsActive && rendererFactory.begin) {
7765 rendererFactory.begin();
7766 }
7767 if (creationModeIsActive) {
7768 renderView(tView, lView, context);
7769 }
7770 refreshView(tView, lView, templateFn, context);
7771 }
7772 finally {
7773 if (normalExecutionPath && !creationModeIsActive && rendererFactory.end) {
7774 rendererFactory.end();
7775 }
7776 }
7777 }
7778 function executeTemplate(tView, lView, templateFn, rf, context) {
7779 var prevSelectedIndex = getSelectedIndex();
7780 try {
7781 setSelectedIndex(-1);
7782 if (rf & 2 /* Update */ && lView.length > HEADER_OFFSET) {
7783 // When we're updating, inherently select 0 so we don't
7784 // have to generate that instruction for most update blocks.
7785 selectIndexInternal(tView, lView, 0, getCheckNoChangesMode());
7786 }
7787 templateFn(rf, context);
7788 }
7789 finally {
7790 setSelectedIndex(prevSelectedIndex);
7791 }
7792 }
7793 //////////////////////////
7794 //// Element
7795 //////////////////////////
7796 function executeContentQueries(tView, tNode, lView) {
7797 if (isContentQueryHost(tNode)) {
7798 var start = tNode.directiveStart;
7799 var end = tNode.directiveEnd;
7800 for (var directiveIndex = start; directiveIndex < end; directiveIndex++) {
7801 var def = tView.data[directiveIndex];
7802 if (def.contentQueries) {
7803 def.contentQueries(1 /* Create */, lView[directiveIndex], directiveIndex);
7804 }
7805 }
7806 }
7807 }
7808 /**
7809 * Creates directive instances.
7810 */
7811 function createDirectivesInstances(tView, lView, tNode) {
7812 if (!getBindingsEnabled())
7813 return;
7814 instantiateAllDirectives(tView, lView, tNode, getNativeByTNode(tNode, lView));
7815 if ((tNode.flags & 128 /* hasHostBindings */) === 128 /* hasHostBindings */) {
7816 invokeDirectivesHostBindings(tView, lView, tNode);
7817 }
7818 }
7819 /**
7820 * Takes a list of local names and indices and pushes the resolved local variable values
7821 * to LView in the same order as they are loaded in the template with load().
7822 */
7823 function saveResolvedLocalsInData(viewData, tNode, localRefExtractor) {
7824 if (localRefExtractor === void 0) { localRefExtractor = getNativeByTNode; }
7825 var localNames = tNode.localNames;
7826 if (localNames !== null) {
7827 var localIndex = tNode.index + 1;
7828 for (var i = 0; i < localNames.length; i += 2) {
7829 var index = localNames[i + 1];
7830 var value = index === -1 ?
7831 localRefExtractor(tNode, viewData) :
7832 viewData[index];
7833 viewData[localIndex++] = value;
7834 }
7835 }
7836 }
7837 /**
7838 * Gets TView from a template function or creates a new TView
7839 * if it doesn't already exist.
7840 *
7841 * @param def ComponentDef
7842 * @returns TView
7843 */
7844 function getOrCreateTComponentView(def) {
7845 var tView = def.tView;
7846 // Create a TView if there isn't one, or recreate it if the first create pass didn't
7847 // complete successfuly since we can't know for sure whether it's in a usable shape.
7848 if (tView === null || tView.incompleteFirstPass) {
7849 return def.tView = createTView(1 /* Component */, -1, def.template, def.decls, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery, def.schemas, def.consts);
7850 }
7851 return tView;
7852 }
7853 /**
7854 * Creates a TView instance
7855 *
7856 * @param viewIndex The viewBlockId for inline views, or -1 if it's a component/dynamic
7857 * @param templateFn Template function
7858 * @param decls The number of nodes, local refs, and pipes in this template
7859 * @param directives Registry of directives for this view
7860 * @param pipes Registry of pipes for this view
7861 * @param viewQuery View queries for this view
7862 * @param schemas Schemas for this view
7863 * @param consts Constants for this view
7864 */
7865 function createTView(type, viewIndex, templateFn, decls, vars, directives, pipes, viewQuery, schemas, consts) {
7866 ngDevMode && ngDevMode.tView++;
7867 var bindingStartIndex = HEADER_OFFSET + decls;
7868 // This length does not yet contain host bindings from child directives because at this point,
7869 // we don't know which directives are active on this template. As soon as a directive is matched
7870 // that has a host binding, we will update the blueprint with that def's hostVars count.
7871 var initialViewLength = bindingStartIndex + vars;
7872 var blueprint = createViewBlueprint(bindingStartIndex, initialViewLength);
7873 var tView = blueprint[TVIEW] = ngDevMode ?
7874 new TViewConstructor(type, viewIndex, // id: number,
7875 blueprint, // blueprint: LView,
7876 templateFn, // template: ComponentTemplate<{}>|null,
7877 null, // queries: TQueries|null
7878 viewQuery, // viewQuery: ViewQueriesFunction<{}>|null,
7879 null, // node: TViewNode|TElementNode|null,
7880 cloneToTViewData(blueprint).fill(null, bindingStartIndex), // data: TData,
7881 bindingStartIndex, // bindingStartIndex: number,
7882 initialViewLength, // expandoStartIndex: number,
7883 null, // expandoInstructions: ExpandoInstructions|null,
7884 true, // firstCreatePass: boolean,
7885 true, // firstUpdatePass: boolean,
7886 false, // staticViewQueries: boolean,
7887 false, // staticContentQueries: boolean,
7888 null, // preOrderHooks: HookData|null,
7889 null, // preOrderCheckHooks: HookData|null,
7890 null, // contentHooks: HookData|null,
7891 null, // contentCheckHooks: HookData|null,
7892 null, // viewHooks: HookData|null,
7893 null, // viewCheckHooks: HookData|null,
7894 null, // destroyHooks: DestroyHookData|null,
7895 null, // cleanup: any[]|null,
7896 null, // contentQueries: number[]|null,
7897 null, // components: number[]|null,
7898 typeof directives === 'function' ?
7899 directives() :
7900 directives, // directiveRegistry: DirectiveDefList|null,
7901 typeof pipes === 'function' ? pipes() : pipes, // pipeRegistry: PipeDefList|null,
7902 null, // firstChild: TNode|null,
7903 schemas, // schemas: SchemaMetadata[]|null,
7904 consts, // consts: TConstants|null
7905 false, // incompleteFirstPass: boolean
7906 decls, // ngDevMode only: decls
7907 vars) :
7908 {
7909 type: type,
7910 id: viewIndex,
7911 blueprint: blueprint,
7912 template: templateFn,
7913 queries: null,
7914 viewQuery: viewQuery,
7915 node: null,
7916 data: blueprint.slice().fill(null, bindingStartIndex),
7917 bindingStartIndex: bindingStartIndex,
7918 expandoStartIndex: initialViewLength,
7919 expandoInstructions: null,
7920 firstCreatePass: true,
7921 firstUpdatePass: true,
7922 staticViewQueries: false,
7923 staticContentQueries: false,
7924 preOrderHooks: null,
7925 preOrderCheckHooks: null,
7926 contentHooks: null,
7927 contentCheckHooks: null,
7928 viewHooks: null,
7929 viewCheckHooks: null,
7930 destroyHooks: null,
7931 cleanup: null,
7932 contentQueries: null,
7933 components: null,
7934 directiveRegistry: typeof directives === 'function' ? directives() : directives,
7935 pipeRegistry: typeof pipes === 'function' ? pipes() : pipes,
7936 firstChild: null,
7937 schemas: schemas,
7938 consts: consts,
7939 incompleteFirstPass: false
7940 };
7941 if (ngDevMode) {
7942 // For performance reasons it is important that the tView retains the same shape during runtime.
7943 // (To make sure that all of the code is monomorphic.) For this reason we seal the object to
7944 // prevent class transitions.
7945 Object.seal(tView);
7946 }
7947 return tView;
7948 }
7949 function createViewBlueprint(bindingStartIndex, initialViewLength) {
7950 var blueprint = ngDevMode ? new LViewBlueprint() : [];
7951 for (var i = 0; i < initialViewLength; i++) {
7952 blueprint.push(i < bindingStartIndex ? null : NO_CHANGE);
7953 }
7954 return blueprint;
7955 }
7956 function createError(text, token) {
7957 return new Error("Renderer: " + text + " [" + stringifyForError(token) + "]");
7958 }
7959 function assertHostNodeExists(rElement, elementOrSelector) {
7960 if (!rElement) {
7961 if (typeof elementOrSelector === 'string') {
7962 throw createError('Host node with selector not found:', elementOrSelector);
7963 }
7964 else {
7965 throw createError('Host node is required:', elementOrSelector);
7966 }
7967 }
7968 }
7969 /**
7970 * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
7971 *
7972 * @param rendererFactory Factory function to create renderer instance.
7973 * @param elementOrSelector Render element or CSS selector to locate the element.
7974 * @param encapsulation View Encapsulation defined for component that requests host element.
7975 */
7976 function locateHostElement(renderer, elementOrSelector, encapsulation) {
7977 if (isProceduralRenderer(renderer)) {
7978 // When using native Shadow DOM, do not clear host element to allow native slot projection
7979 var preserveContent = encapsulation === exports.ViewEncapsulation.ShadowDom;
7980 return renderer.selectRootElement(elementOrSelector, preserveContent);
7981 }
7982 var rElement = typeof elementOrSelector === 'string' ?
7983 renderer.querySelector(elementOrSelector) :
7984 elementOrSelector;
7985 ngDevMode && assertHostNodeExists(rElement, elementOrSelector);
7986 // Always clear host element's content when Renderer3 is in use. For procedural renderer case we
7987 // make it depend on whether ShadowDom encapsulation is used (in which case the content should be
7988 // preserved to allow native slot projection). ShadowDom encapsulation requires procedural
7989 // renderer, and procedural renderer case is handled above.
7990 rElement.textContent = '';
7991 return rElement;
7992 }
7993 /**
7994 * Saves context for this cleanup function in LView.cleanupInstances.
7995 *
7996 * On the first template pass, saves in TView:
7997 * - Cleanup function
7998 * - Index of context we just saved in LView.cleanupInstances
7999 */
8000 function storeCleanupWithContext(tView, lView, context, cleanupFn) {
8001 var lCleanup = getLCleanup(lView);
8002 lCleanup.push(context);
8003 if (tView.firstCreatePass) {
8004 getTViewCleanup(tView).push(cleanupFn, lCleanup.length - 1);
8005 }
8006 }
8007 /**
8008 * Constructs a TNode object from the arguments.
8009 *
8010 * @param tView `TView` to which this `TNode` belongs (used only in `ngDevMode`)
8011 * @param type The type of the node
8012 * @param adjustedIndex The index of the TNode in TView.data, adjusted for HEADER_OFFSET
8013 * @param tagName The tag name of the node
8014 * @param attrs The attributes defined on this node
8015 * @param tViews Any TViews attached to this node
8016 * @returns the TNode object
8017 */
8018 function createTNode(tView, tParent, type, adjustedIndex, tagName, attrs) {
8019 ngDevMode && ngDevMode.tNode++;
8020 var injectorIndex = tParent ? tParent.injectorIndex : -1;
8021 var tNode = ngDevMode ?
8022 new TNodeDebug(tView, // tView_: TView
8023 type, // type: TNodeType
8024 adjustedIndex, // index: number
8025 injectorIndex, // injectorIndex: number
8026 -1, // directiveStart: number
8027 -1, // directiveEnd: number
8028 -1, // directiveStylingLast: number
8029 null, // propertyBindings: number[]|null
8030 0, // flags: TNodeFlags
8031 0, // providerIndexes: TNodeProviderIndexes
8032 tagName, // tagName: string|null
8033 attrs, // attrs: (string|AttributeMarker|(string|SelectorFlags)[])[]|null
8034 null, // mergedAttrs
8035 null, // localNames: (string|number)[]|null
8036 undefined, // initialInputs: (string[]|null)[]|null|undefined
8037 null, // inputs: PropertyAliases|null
8038 null, // outputs: PropertyAliases|null
8039 null, // tViews: ITView|ITView[]|null
8040 null, // next: ITNode|null
8041 null, // projectionNext: ITNode|null
8042 null, // child: ITNode|null
8043 tParent, // parent: TElementNode|TContainerNode|null
8044 null, // projection: number|(ITNode|RNode[])[]|null
8045 null, // styles: string|null
8046 null, // stylesWithoutHost: string|null
8047 undefined, // residualStyles: string|null
8048 null, // classes: string|null
8049 null, // classesWithoutHost: string|null
8050 undefined, // residualClasses: string|null
8051 0, // classBindings: TStylingRange;
8052 0) :
8053 {
8054 type: type,
8055 index: adjustedIndex,
8056 injectorIndex: injectorIndex,
8057 directiveStart: -1,
8058 directiveEnd: -1,
8059 directiveStylingLast: -1,
8060 propertyBindings: null,
8061 flags: 0,
8062 providerIndexes: 0,
8063 tagName: tagName,
8064 attrs: attrs,
8065 mergedAttrs: null,
8066 localNames: null,
8067 initialInputs: undefined,
8068 inputs: null,
8069 outputs: null,
8070 tViews: null,
8071 next: null,
8072 projectionNext: null,
8073 child: null,
8074 parent: tParent,
8075 projection: null,
8076 styles: null,
8077 stylesWithoutHost: null,
8078 residualStyles: undefined,
8079 classes: null,
8080 classesWithoutHost: null,
8081 residualClasses: undefined,
8082 classBindings: 0,
8083 styleBindings: 0,
8084 };
8085 if (ngDevMode) {
8086 // For performance reasons it is important that the tNode retains the same shape during runtime.
8087 // (To make sure that all of the code is monomorphic.) For this reason we seal the object to
8088 // prevent class transitions.
8089 Object.seal(tNode);
8090 }
8091 return tNode;
8092 }
8093 function generatePropertyAliases(inputAliasMap, directiveDefIdx, propStore) {
8094 for (var publicName in inputAliasMap) {
8095 if (inputAliasMap.hasOwnProperty(publicName)) {
8096 propStore = propStore === null ? {} : propStore;
8097 var internalName = inputAliasMap[publicName];
8098 if (propStore.hasOwnProperty(publicName)) {
8099 propStore[publicName].push(directiveDefIdx, internalName);
8100 }
8101 else {
8102 (propStore[publicName] = [directiveDefIdx, internalName]);
8103 }
8104 }
8105 }
8106 return propStore;
8107 }
8108 /**
8109 * Initializes data structures required to work with directive outputs and outputs.
8110 * Initialization is done for all directives matched on a given TNode.
8111 */
8112 function initializeInputAndOutputAliases(tView, tNode) {
8113 ngDevMode && assertFirstCreatePass(tView);
8114 var start = tNode.directiveStart;
8115 var end = tNode.directiveEnd;
8116 var defs = tView.data;
8117 var tNodeAttrs = tNode.attrs;
8118 var inputsFromAttrs = ngDevMode ? new TNodeInitialInputs() : [];
8119 var inputsStore = null;
8120 var outputsStore = null;
8121 for (var i = start; i < end; i++) {
8122 var directiveDef = defs[i];
8123 var directiveInputs = directiveDef.inputs;
8124 // Do not use unbound attributes as inputs to structural directives, since structural
8125 // directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
8126 // TODO(FW-1930): microsyntax expressions may also contain unbound/static attributes, which
8127 // should be set for inline templates.
8128 var initialInputs = (tNodeAttrs !== null && !isInlineTemplate(tNode)) ?
8129 generateInitialInputs(directiveInputs, tNodeAttrs) :
8130 null;
8131 inputsFromAttrs.push(initialInputs);
8132 inputsStore = generatePropertyAliases(directiveInputs, i, inputsStore);
8133 outputsStore = generatePropertyAliases(directiveDef.outputs, i, outputsStore);
8134 }
8135 if (inputsStore !== null) {
8136 if (inputsStore.hasOwnProperty('class')) {
8137 tNode.flags |= 16 /* hasClassInput */;
8138 }
8139 if (inputsStore.hasOwnProperty('style')) {
8140 tNode.flags |= 32 /* hasStyleInput */;
8141 }
8142 }
8143 tNode.initialInputs = inputsFromAttrs;
8144 tNode.inputs = inputsStore;
8145 tNode.outputs = outputsStore;
8146 }
8147 /**
8148 * Mapping between attributes names that don't correspond to their element property names.
8149 *
8150 * Performance note: this function is written as a series of if checks (instead of, say, a property
8151 * object lookup) for performance reasons - the series of `if` checks seems to be the fastest way of
8152 * mapping property names. Do NOT change without benchmarking.
8153 *
8154 * Note: this mapping has to be kept in sync with the equally named mapping in the template
8155 * type-checking machinery of ngtsc.
8156 */
8157 function mapPropName(name) {
8158 if (name === 'class')
8159 return 'className';
8160 if (name === 'for')
8161 return 'htmlFor';
8162 if (name === 'formaction')
8163 return 'formAction';
8164 if (name === 'innerHtml')
8165 return 'innerHTML';
8166 if (name === 'readonly')
8167 return 'readOnly';
8168 if (name === 'tabindex')
8169 return 'tabIndex';
8170 return name;
8171 }
8172 function elementPropertyInternal(tView, tNode, lView, propName, value, renderer, sanitizer, nativeOnly) {
8173 ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
8174 var element = getNativeByTNode(tNode, lView);
8175 var inputData = tNode.inputs;
8176 var dataValue;
8177 if (!nativeOnly && inputData != null && (dataValue = inputData[propName])) {
8178 setInputsForProperty(tView, lView, dataValue, propName, value);
8179 if (isComponentHost(tNode))
8180 markDirtyIfOnPush(lView, tNode.index);
8181 if (ngDevMode) {
8182 setNgReflectProperties(lView, element, tNode.type, dataValue, value);
8183 }
8184 }
8185 else if (tNode.type === 3 /* Element */) {
8186 propName = mapPropName(propName);
8187 if (ngDevMode) {
8188 validateAgainstEventProperties(propName);
8189 if (!validateProperty(tView, element, propName, tNode)) {
8190 // Return here since we only log warnings for unknown properties.
8191 logUnknownPropertyError(propName, tNode);
8192 return;
8193 }
8194 ngDevMode.rendererSetProperty++;
8195 }
8196 // It is assumed that the sanitizer is only added when the compiler determines that the
8197 // property is risky, so sanitization can be done without further checks.
8198 value = sanitizer != null ? sanitizer(value, tNode.tagName || '', propName) : value;
8199 if (isProceduralRenderer(renderer)) {
8200 renderer.setProperty(element, propName, value);
8201 }
8202 else if (!isAnimationProp(propName)) {
8203 element.setProperty ? element.setProperty(propName, value) :
8204 element[propName] = value;
8205 }
8206 }
8207 else if (tNode.type === 0 /* Container */ || tNode.type === 4 /* ElementContainer */) {
8208 // If the node is a container and the property didn't
8209 // match any of the inputs or schemas we should throw.
8210 if (ngDevMode && !matchingSchemas(tView, tNode.tagName)) {
8211 logUnknownPropertyError(propName, tNode);
8212 }
8213 }
8214 }
8215 /** If node is an OnPush component, marks its LView dirty. */
8216 function markDirtyIfOnPush(lView, viewIndex) {
8217 ngDevMode && assertLView(lView);
8218 var childComponentLView = getComponentLViewByIndex(viewIndex, lView);
8219 if (!(childComponentLView[FLAGS] & 16 /* CheckAlways */)) {
8220 childComponentLView[FLAGS] |= 64 /* Dirty */;
8221 }
8222 }
8223 function setNgReflectProperty(lView, element, type, attrName, value) {
8224 var _a;
8225 var renderer = lView[RENDERER];
8226 attrName = normalizeDebugBindingName(attrName);
8227 var debugValue = normalizeDebugBindingValue(value);
8228 if (type === 3 /* Element */) {
8229 if (value == null) {
8230 isProceduralRenderer(renderer) ? renderer.removeAttribute(element, attrName) :
8231 element.removeAttribute(attrName);
8232 }
8233 else {
8234 isProceduralRenderer(renderer) ?
8235 renderer.setAttribute(element, attrName, debugValue) :
8236 element.setAttribute(attrName, debugValue);
8237 }
8238 }
8239 else {
8240 var textContent = "bindings=" + JSON.stringify((_a = {}, _a[attrName] = debugValue, _a), null, 2);
8241 if (isProceduralRenderer(renderer)) {
8242 renderer.setValue(element, textContent);
8243 }
8244 else {
8245 element.textContent = textContent;
8246 }
8247 }
8248 }
8249 function setNgReflectProperties(lView, element, type, dataValue, value) {
8250 if (type === 3 /* Element */ || type === 0 /* Container */) {
8251 /**
8252 * dataValue is an array containing runtime input or output names for the directives:
8253 * i+0: directive instance index
8254 * i+1: privateName
8255 *
8256 * e.g. [0, 'change', 'change-minified']
8257 * we want to set the reflected property with the privateName: dataValue[i+1]
8258 */
8259 for (var i = 0; i < dataValue.length; i += 2) {
8260 setNgReflectProperty(lView, element, type, dataValue[i + 1], value);
8261 }
8262 }
8263 }
8264 function validateProperty(tView, element, propName, tNode) {
8265 // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
8266 // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
8267 // defined as an array (as an empty array in case `schemas` field is not defined) and we should
8268 // execute the check below.
8269 if (tView.schemas === null)
8270 return true;
8271 // The property is considered valid if the element matches the schema, it exists on the element
8272 // or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
8273 if (matchingSchemas(tView, tNode.tagName) || propName in element || isAnimationProp(propName)) {
8274 return true;
8275 }
8276 // Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
8277 // need to account for both here, while being careful for `typeof null` also returning 'object'.
8278 return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
8279 }
8280 function matchingSchemas(tView, tagName) {
8281 var schemas = tView.schemas;
8282 if (schemas !== null) {
8283 for (var i = 0; i < schemas.length; i++) {
8284 var schema = schemas[i];
8285 if (schema === NO_ERRORS_SCHEMA ||
8286 schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
8287 return true;
8288 }
8289 }
8290 }
8291 return false;
8292 }
8293 /**
8294 * Logs an error that a property is not supported on an element.
8295 * @param propName Name of the invalid property.
8296 * @param tNode Node on which we encountered the property.
8297 */
8298 function logUnknownPropertyError(propName, tNode) {
8299 console.error("Can't bind to '" + propName + "' since it isn't a known property of '" + tNode.tagName + "'.");
8300 }
8301 /**
8302 * Instantiate a root component.
8303 */
8304 function instantiateRootComponent(tView, lView, def) {
8305 var rootTNode = getPreviousOrParentTNode();
8306 if (tView.firstCreatePass) {
8307 if (def.providersResolver)
8308 def.providersResolver(def);
8309 generateExpandoInstructionBlock(tView, rootTNode, 1);
8310 baseResolveDirective(tView, lView, def);
8311 }
8312 var directive = getNodeInjectable(lView, tView, lView.length - 1, rootTNode);
8313 attachPatchData(directive, lView);
8314 var native = getNativeByTNode(rootTNode, lView);
8315 if (native) {
8316 attachPatchData(native, lView);
8317 }
8318 return directive;
8319 }
8320 /**
8321 * Resolve the matched directives on a node.
8322 */
8323 function resolveDirectives(tView, lView, tNode, localRefs) {
8324 // Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in
8325 // tsickle.
8326 ngDevMode && assertFirstCreatePass(tView);
8327 var hasDirectives = false;
8328 if (getBindingsEnabled()) {
8329 var directiveDefs = findDirectiveDefMatches(tView, lView, tNode);
8330 var exportsMap = localRefs === null ? null : { '': -1 };
8331 if (directiveDefs !== null) {
8332 var totalDirectiveHostVars = 0;
8333 hasDirectives = true;
8334 initTNodeFlags(tNode, tView.data.length, directiveDefs.length);
8335 // When the same token is provided by several directives on the same node, some rules apply in
8336 // the viewEngine:
8337 // - viewProviders have priority over providers
8338 // - the last directive in NgModule.declarations has priority over the previous one
8339 // So to match these rules, the order in which providers are added in the arrays is very
8340 // important.
8341 for (var i = 0; i < directiveDefs.length; i++) {
8342 var def = directiveDefs[i];
8343 if (def.providersResolver)
8344 def.providersResolver(def);
8345 }
8346 generateExpandoInstructionBlock(tView, tNode, directiveDefs.length);
8347 var preOrderHooksFound = false;
8348 var preOrderCheckHooksFound = false;
8349 for (var i = 0; i < directiveDefs.length; i++) {
8350 var def = directiveDefs[i];
8351 // Merge the attrs in the order of matches. This assumes that the first directive is the
8352 // component itself, so that the component has the least priority.
8353 tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
8354 baseResolveDirective(tView, lView, def);
8355 saveNameToExportMap(tView.data.length - 1, def, exportsMap);
8356 if (def.contentQueries !== null)
8357 tNode.flags |= 8 /* hasContentQuery */;
8358 if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0)
8359 tNode.flags |= 128 /* hasHostBindings */;
8360 var lifeCycleHooks = def.type.prototype;
8361 // Only push a node index into the preOrderHooks array if this is the first
8362 // pre-order hook found on this node.
8363 if (!preOrderHooksFound &&
8364 (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngOnInit || lifeCycleHooks.ngDoCheck)) {
8365 // We will push the actual hook function into this array later during dir instantiation.
8366 // We cannot do it now because we must ensure hooks are registered in the same
8367 // order that directives are created (i.e. injection order).
8368 (tView.preOrderHooks || (tView.preOrderHooks = [])).push(tNode.index - HEADER_OFFSET);
8369 preOrderHooksFound = true;
8370 }
8371 if (!preOrderCheckHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngDoCheck)) {
8372 (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = []))
8373 .push(tNode.index - HEADER_OFFSET);
8374 preOrderCheckHooksFound = true;
8375 }
8376 addHostBindingsToExpandoInstructions(tView, def);
8377 totalDirectiveHostVars += def.hostVars;
8378 }
8379 initializeInputAndOutputAliases(tView, tNode);
8380 growHostVarsSpace(tView, lView, totalDirectiveHostVars);
8381 }
8382 if (exportsMap)
8383 cacheMatchingLocalNames(tNode, localRefs, exportsMap);
8384 }
8385 // Merge the template attrs last so that they have the highest priority.
8386 tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
8387 return hasDirectives;
8388 }
8389 /**
8390 * Add `hostBindings` to the `TView.expandoInstructions`.
8391 *
8392 * @param tView `TView` to which the `hostBindings` should be added.
8393 * @param def `ComponentDef`/`DirectiveDef`, which contains the `hostVars`/`hostBindings` to add.
8394 */
8395 function addHostBindingsToExpandoInstructions(tView, def) {
8396 ngDevMode && assertFirstCreatePass(tView);
8397 var expando = tView.expandoInstructions;
8398 // TODO(misko): PERF we are adding `hostBindings` even if there is nothing to add! This is
8399 // suboptimal for performance. `def.hostBindings` may be null,
8400 // but we still need to push null to the array as a placeholder
8401 // to ensure the directive counter is incremented (so host
8402 // binding functions always line up with the corrective directive).
8403 // This is suboptimal for performance. See `currentDirectiveIndex`
8404 // comment in `setHostBindingsByExecutingExpandoInstructions` for more
8405 // details. expando.push(def.hostBindings);
8406 expando.push(def.hostBindings);
8407 var hostVars = def.hostVars;
8408 if (hostVars !== 0) {
8409 expando.push(def.hostVars);
8410 }
8411 }
8412 /**
8413 * Grow the `LView`, blueprint and `TView.data` to accommodate the `hostBindings`.
8414 *
8415 * To support locality we don't know ahead of time how many `hostVars` of the containing directives
8416 * we need to allocate. For this reason we allow growing these data structures as we discover more
8417 * directives to accommodate them.
8418 *
8419 * @param tView `TView` which needs to be grown.
8420 * @param lView `LView` which needs to be grown.
8421 * @param count Size by which we need to grow the data structures.
8422 */
8423 function growHostVarsSpace(tView, lView, count) {
8424 ngDevMode && assertFirstCreatePass(tView);
8425 ngDevMode && assertSame(tView, lView[TVIEW], '`LView` must be associated with `TView`!');
8426 for (var i = 0; i < count; i++) {
8427 lView.push(NO_CHANGE);
8428 tView.blueprint.push(NO_CHANGE);
8429 tView.data.push(null);
8430 }
8431 }
8432 /**
8433 * Instantiate all the directives that were previously resolved on the current node.
8434 */
8435 function instantiateAllDirectives(tView, lView, tNode, native) {
8436 var start = tNode.directiveStart;
8437 var end = tNode.directiveEnd;
8438 if (!tView.firstCreatePass) {
8439 getOrCreateNodeInjectorForNode(tNode, lView);
8440 }
8441 attachPatchData(native, lView);
8442 var initialInputs = tNode.initialInputs;
8443 for (var i = start; i < end; i++) {
8444 var def = tView.data[i];
8445 var isComponent = isComponentDef(def);
8446 if (isComponent) {
8447 ngDevMode && assertNodeOfPossibleTypes(tNode, [3 /* Element */]);
8448 addComponentLogic(lView, tNode, def);
8449 }
8450 var directive = getNodeInjectable(lView, tView, i, tNode);
8451 attachPatchData(directive, lView);
8452 if (initialInputs !== null) {
8453 setInputsFromAttrs(lView, i - start, directive, def, tNode, initialInputs);
8454 }
8455 if (isComponent) {
8456 var componentView = getComponentLViewByIndex(tNode.index, lView);
8457 componentView[CONTEXT] = directive;
8458 }
8459 }
8460 }
8461 function invokeDirectivesHostBindings(tView, lView, tNode) {
8462 var start = tNode.directiveStart;
8463 var end = tNode.directiveEnd;
8464 var expando = tView.expandoInstructions;
8465 var firstCreatePass = tView.firstCreatePass;
8466 var elementIndex = tNode.index - HEADER_OFFSET;
8467 var currentDirectiveIndex = getCurrentDirectiveIndex();
8468 try {
8469 setSelectedIndex(elementIndex);
8470 for (var dirIndex = start; dirIndex < end; dirIndex++) {
8471 var def = tView.data[dirIndex];
8472 var directive = lView[dirIndex];
8473 setCurrentDirectiveIndex(dirIndex);
8474 if (def.hostBindings !== null || def.hostVars !== 0 || def.hostAttrs !== null) {
8475 invokeHostBindingsInCreationMode(def, directive);
8476 }
8477 else if (firstCreatePass) {
8478 expando.push(null);
8479 }
8480 }
8481 }
8482 finally {
8483 setSelectedIndex(-1);
8484 setCurrentDirectiveIndex(currentDirectiveIndex);
8485 }
8486 }
8487 /**
8488 * Invoke the host bindings in creation mode.
8489 *
8490 * @param def `DirectiveDef` which may contain the `hostBindings` function.
8491 * @param directive Instance of directive.
8492 */
8493 function invokeHostBindingsInCreationMode(def, directive) {
8494 if (def.hostBindings !== null) {
8495 def.hostBindings(1 /* Create */, directive);
8496 }
8497 }
8498 /**
8499 * Generates a new block in TView.expandoInstructions for this node.
8500 *
8501 * Each expando block starts with the element index (turned negative so we can distinguish
8502 * it from the hostVar count) and the directive count. See more in VIEW_DATA.md.
8503 */
8504 function generateExpandoInstructionBlock(tView, tNode, directiveCount) {
8505 ngDevMode &&
8506 assertEqual(tView.firstCreatePass, true, 'Expando block should only be generated on first create pass.');
8507 // Important: In JS `-x` and `0-x` is not the same! If `x===0` then `-x` will produce `-0` which
8508 // requires non standard math arithmetic and it can prevent VM optimizations.
8509 // `0-0` will always produce `0` and will not cause a potential deoptimization in VM.
8510 var elementIndex = HEADER_OFFSET - tNode.index;
8511 var providerStartIndex = tNode.providerIndexes & 1048575 /* ProvidersStartIndexMask */;
8512 var providerCount = tView.data.length - providerStartIndex;
8513 (tView.expandoInstructions || (tView.expandoInstructions = []))
8514 .push(elementIndex, providerCount, directiveCount);
8515 }
8516 /**
8517 * Matches the current node against all available selectors.
8518 * If a component is matched (at most one), it is returned in first position in the array.
8519 */
8520 function findDirectiveDefMatches(tView, viewData, tNode) {
8521 ngDevMode && assertFirstCreatePass(tView);
8522 ngDevMode &&
8523 assertNodeOfPossibleTypes(tNode, [3 /* Element */, 4 /* ElementContainer */, 0 /* Container */]);
8524 var registry = tView.directiveRegistry;
8525 var matches = null;
8526 if (registry) {
8527 for (var i = 0; i < registry.length; i++) {
8528 var def = registry[i];
8529 if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */ false)) {
8530 matches || (matches = ngDevMode ? new MatchesArray() : []);
8531 diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, viewData), tView, def.type);
8532 if (isComponentDef(def)) {
8533 ngDevMode &&
8534 assertNodeOfPossibleTypes(tNode, [3 /* Element */], "\"" + tNode.tagName + "\" tags cannot be used as component hosts. " +
8535 ("Please use a different tag to activate the " + stringify(def.type) + " component."));
8536 if (tNode.flags & 2 /* isComponentHost */)
8537 throwMultipleComponentError(tNode);
8538 markAsComponentHost(tView, tNode);
8539 // The component is always stored first with directives after.
8540 matches.unshift(def);
8541 }
8542 else {
8543 matches.push(def);
8544 }
8545 }
8546 }
8547 }
8548 return matches;
8549 }
8550 /**
8551 * Marks a given TNode as a component's host. This consists of:
8552 * - setting appropriate TNode flags;
8553 * - storing index of component's host element so it will be queued for view refresh during CD.
8554 */
8555 function markAsComponentHost(tView, hostTNode) {
8556 ngDevMode && assertFirstCreatePass(tView);
8557 hostTNode.flags |= 2 /* isComponentHost */;
8558 (tView.components || (tView.components = ngDevMode ? new TViewComponents() : []))
8559 .push(hostTNode.index);
8560 }
8561 /** Caches local names and their matching directive indices for query and template lookups. */
8562 function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
8563 if (localRefs) {
8564 var localNames = tNode.localNames = ngDevMode ? new TNodeLocalNames() : [];
8565 // Local names must be stored in tNode in the same order that localRefs are defined
8566 // in the template to ensure the data is loaded in the same slots as their refs
8567 // in the template (for template queries).
8568 for (var i = 0; i < localRefs.length; i += 2) {
8569 var index = exportsMap[localRefs[i + 1]];
8570 if (index == null)
8571 throw new Error("Export of name '" + localRefs[i + 1] + "' not found!");
8572 localNames.push(localRefs[i], index);
8573 }
8574 }
8575 }
8576 /**
8577 * Builds up an export map as directives are created, so local refs can be quickly mapped
8578 * to their directive instances.
8579 */
8580 function saveNameToExportMap(index, def, exportsMap) {
8581 if (exportsMap) {
8582 if (def.exportAs) {
8583 for (var i = 0; i < def.exportAs.length; i++) {
8584 exportsMap[def.exportAs[i]] = index;
8585 }
8586 }
8587 if (isComponentDef(def))
8588 exportsMap[''] = index;
8589 }
8590 }
8591 /**
8592 * Initializes the flags on the current node, setting all indices to the initial index,
8593 * the directive count to 0, and adding the isComponent flag.
8594 * @param index the initial index
8595 */
8596 function initTNodeFlags(tNode, index, numberOfDirectives) {
8597 ngDevMode &&
8598 assertNotEqual(numberOfDirectives, tNode.directiveEnd - tNode.directiveStart, 'Reached the max number of directives');
8599 tNode.flags |= 1 /* isDirectiveHost */;
8600 // When the first directive is created on a node, save the index
8601 tNode.directiveStart = index;
8602 tNode.directiveEnd = index + numberOfDirectives;
8603 tNode.providerIndexes = index;
8604 }
8605 function baseResolveDirective(tView, viewData, def) {
8606 tView.data.push(def);
8607 var directiveFactory = def.factory || (def.factory = getFactoryDef(def.type, true));
8608 var nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), null);
8609 tView.blueprint.push(nodeInjectorFactory);
8610 viewData.push(nodeInjectorFactory);
8611 }
8612 function addComponentLogic(lView, hostTNode, def) {
8613 var native = getNativeByTNode(hostTNode, lView);
8614 var tView = getOrCreateTComponentView(def);
8615 // Only component views should be added to the view tree directly. Embedded views are
8616 // accessed through their containers because they may be removed / re-added later.
8617 var rendererFactory = lView[RENDERER_FACTORY];
8618 var componentView = addToViewTree(lView, createLView(lView, tView, null, def.onPush ? 64 /* Dirty */ : 16 /* CheckAlways */, native, hostTNode, rendererFactory, rendererFactory.createRenderer(native, def)));
8619 // Component view will always be created before any injected LContainers,
8620 // so this is a regular element, wrap it with the component view
8621 lView[hostTNode.index] = componentView;
8622 }
8623 function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace) {
8624 if (ngDevMode) {
8625 assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
8626 validateAgainstEventAttributes(name);
8627 assertNodeNotOfTypes(tNode, [0 /* Container */, 4 /* ElementContainer */], "Attempted to set attribute `" + name + "` on a container node. " +
8628 "Host bindings are not valid on ng-container or ng-template.");
8629 }
8630 var element = getNativeByTNode(tNode, lView);
8631 var renderer = lView[RENDERER];
8632 if (value == null) {
8633 ngDevMode && ngDevMode.rendererRemoveAttribute++;
8634 isProceduralRenderer(renderer) ? renderer.removeAttribute(element, name, namespace) :
8635 element.removeAttribute(name);
8636 }
8637 else {
8638 ngDevMode && ngDevMode.rendererSetAttribute++;
8639 var strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tNode.tagName || '', name);
8640 if (isProceduralRenderer(renderer)) {
8641 renderer.setAttribute(element, name, strValue, namespace);
8642 }
8643 else {
8644 namespace ? element.setAttributeNS(namespace, name, strValue) :
8645 element.setAttribute(name, strValue);
8646 }
8647 }
8648 }
8649 /**
8650 * Sets initial input properties on directive instances from attribute data
8651 *
8652 * @param lView Current LView that is being processed.
8653 * @param directiveIndex Index of the directive in directives array
8654 * @param instance Instance of the directive on which to set the initial inputs
8655 * @param def The directive def that contains the list of inputs
8656 * @param tNode The static data for this node
8657 */
8658 function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initialInputData) {
8659 var initialInputs = initialInputData[directiveIndex];
8660 if (initialInputs !== null) {
8661 var setInput = def.setInput;
8662 for (var i = 0; i < initialInputs.length;) {
8663 var publicName = initialInputs[i++];
8664 var privateName = initialInputs[i++];
8665 var value = initialInputs[i++];
8666 if (setInput !== null) {
8667 def.setInput(instance, value, publicName, privateName);
8668 }
8669 else {
8670 instance[privateName] = value;
8671 }
8672 if (ngDevMode) {
8673 var nativeElement = getNativeByTNode(tNode, lView);
8674 setNgReflectProperty(lView, nativeElement, tNode.type, privateName, value);
8675 }
8676 }
8677 }
8678 }
8679 /**
8680 * Generates initialInputData for a node and stores it in the template's static storage
8681 * so subsequent template invocations don't have to recalculate it.
8682 *
8683 * initialInputData is an array containing values that need to be set as input properties
8684 * for directives on this node, but only once on creation. We need this array to support
8685 * the case where you set an @Input property of a directive using attribute-like syntax.
8686 * e.g. if you have a `name` @Input, you can set it once like this:
8687 *
8688 * <my-component name="Bess"></my-component>
8689 *
8690 * @param inputs The list of inputs from the directive def
8691 * @param attrs The static attrs on this node
8692 */
8693 function generateInitialInputs(inputs, attrs) {
8694 var inputsToStore = null;
8695 var i = 0;
8696 while (i < attrs.length) {
8697 var attrName = attrs[i];
8698 if (attrName === 0 /* NamespaceURI */) {
8699 // We do not allow inputs on namespaced attributes.
8700 i += 4;
8701 continue;
8702 }
8703 else if (attrName === 5 /* ProjectAs */) {
8704 // Skip over the `ngProjectAs` value.
8705 i += 2;
8706 continue;
8707 }
8708 // If we hit any other attribute markers, we're done anyway. None of those are valid inputs.
8709 if (typeof attrName === 'number')
8710 break;
8711 if (inputs.hasOwnProperty(attrName)) {
8712 if (inputsToStore === null)
8713 inputsToStore = [];
8714 inputsToStore.push(attrName, inputs[attrName], attrs[i + 1]);
8715 }
8716 i += 2;
8717 }
8718 return inputsToStore;
8719 }
8720 //////////////////////////
8721 //// ViewContainer & View
8722 //////////////////////////
8723 // Not sure why I need to do `any` here but TS complains later.
8724 var LContainerArray = ((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode()) &&
8725 createNamedArrayType('LContainer');
8726 /**
8727 * Creates a LContainer, either from a container instruction, or for a ViewContainerRef.
8728 *
8729 * @param hostNative The host element for the LContainer
8730 * @param hostTNode The host TNode for the LContainer
8731 * @param currentView The parent view of the LContainer
8732 * @param native The native comment element
8733 * @param isForViewContainerRef Optional a flag indicating the ViewContainerRef case
8734 * @returns LContainer
8735 */
8736 function createLContainer(hostNative, currentView, native, tNode) {
8737 ngDevMode && assertLView(currentView);
8738 ngDevMode && !isProceduralRenderer(currentView[RENDERER]) && assertDomNode(native);
8739 // https://jsperf.com/array-literal-vs-new-array-really
8740 var lContainer = new (ngDevMode ? LContainerArray : Array)(hostNative, // host native
8741 true, // Boolean `true` in this position signifies that this is an `LContainer`
8742 false, // has transplanted views
8743 currentView, // parent
8744 null, // next
8745 0, // transplanted views to refresh count
8746 tNode, // t_host
8747 native, // native,
8748 null, // view refs
8749 null);
8750 ngDevMode &&
8751 assertEqual(lContainer.length, CONTAINER_HEADER_OFFSET, 'Should allocate correct number of slots for LContainer header.');
8752 ngDevMode && attachLContainerDebug(lContainer);
8753 return lContainer;
8754 }
8755 /**
8756 * Goes over embedded views (ones created through ViewContainerRef APIs) and refreshes
8757 * them by executing an associated template function.
8758 */
8759 function refreshEmbeddedViews(lView) {
8760 for (var lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
8761 for (var i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
8762 var embeddedLView = lContainer[i];
8763 var embeddedTView = embeddedLView[TVIEW];
8764 ngDevMode && assertDefined(embeddedTView, 'TView must be allocated');
8765 if (viewAttachedToChangeDetector(embeddedLView)) {
8766 refreshView(embeddedTView, embeddedLView, embeddedTView.template, embeddedLView[CONTEXT]);
8767 }
8768 }
8769 }
8770 }
8771 /**
8772 * Mark transplanted views as needing to be refreshed at their insertion points.
8773 *
8774 * @param lView The `LView` that may have transplanted views.
8775 */
8776 function markTransplantedViewsForRefresh(lView) {
8777 for (var lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
8778 if (!lContainer[HAS_TRANSPLANTED_VIEWS])
8779 continue;
8780 var movedViews = lContainer[MOVED_VIEWS];
8781 ngDevMode && assertDefined(movedViews, 'Transplanted View flags set but missing MOVED_VIEWS');
8782 for (var i = 0; i < movedViews.length; i++) {
8783 var movedLView = movedViews[i];
8784 var insertionLContainer = movedLView[PARENT];
8785 ngDevMode && assertLContainer(insertionLContainer);
8786 // We don't want to increment the counter if the moved LView was already marked for
8787 // refresh.
8788 if ((movedLView[FLAGS] & 1024 /* RefreshTransplantedView */) === 0) {
8789 updateTransplantedViewCount(insertionLContainer, 1);
8790 }
8791 // Note, it is possible that the `movedViews` is tracking views that are transplanted *and*
8792 // those that aren't (declaration component === insertion component). In the latter case,
8793 // it's fine to add the flag, as we will clear it immediately in
8794 // `refreshEmbeddedViews` for the view currently being refreshed.
8795 movedLView[FLAGS] |= 1024 /* RefreshTransplantedView */;
8796 }
8797 }
8798 }
8799 /////////////
8800 /**
8801 * Refreshes components by entering the component view and processing its bindings, queries, etc.
8802 *
8803 * @param componentHostIdx Element index in LView[] (adjusted for HEADER_OFFSET)
8804 */
8805 function refreshComponent(hostLView, componentHostIdx) {
8806 ngDevMode && assertEqual(isCreationMode(hostLView), false, 'Should be run in update mode');
8807 var componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
8808 // Only attached components that are CheckAlways or OnPush and dirty should be refreshed
8809 if (viewAttachedToChangeDetector(componentView)) {
8810 var tView = componentView[TVIEW];
8811 if (componentView[FLAGS] & (16 /* CheckAlways */ | 64 /* Dirty */)) {
8812 refreshView(tView, componentView, tView.template, componentView[CONTEXT]);
8813 }
8814 else if (componentView[TRANSPLANTED_VIEWS_TO_REFRESH] > 0) {
8815 // Only attached components that are CheckAlways or OnPush and dirty should be refreshed
8816 refreshContainsDirtyView(componentView);
8817 }
8818 }
8819 }
8820 /**
8821 * Refreshes all transplanted views marked with `LViewFlags.RefreshTransplantedView` that are
8822 * children or descendants of the given lView.
8823 *
8824 * @param lView The lView which contains descendant transplanted views that need to be refreshed.
8825 */
8826 function refreshContainsDirtyView(lView) {
8827 for (var lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
8828 for (var i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
8829 var embeddedLView = lContainer[i];
8830 if (embeddedLView[FLAGS] & 1024 /* RefreshTransplantedView */) {
8831 var embeddedTView = embeddedLView[TVIEW];
8832 ngDevMode && assertDefined(embeddedTView, 'TView must be allocated');
8833 refreshView(embeddedTView, embeddedLView, embeddedTView.template, embeddedLView[CONTEXT]);
8834 }
8835 else if (embeddedLView[TRANSPLANTED_VIEWS_TO_REFRESH] > 0) {
8836 refreshContainsDirtyView(embeddedLView);
8837 }
8838 }
8839 }
8840 var tView = lView[TVIEW];
8841 // Refresh child component views.
8842 var components = tView.components;
8843 if (components !== null) {
8844 for (var i = 0; i < components.length; i++) {
8845 var componentView = getComponentLViewByIndex(components[i], lView);
8846 // Only attached components that are CheckAlways or OnPush and dirty should be refreshed
8847 if (viewAttachedToChangeDetector(componentView) &&
8848 componentView[TRANSPLANTED_VIEWS_TO_REFRESH] > 0) {
8849 refreshContainsDirtyView(componentView);
8850 }
8851 }
8852 }
8853 }
8854 function renderComponent(hostLView, componentHostIdx) {
8855 ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode');
8856 var componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
8857 var componentTView = componentView[TVIEW];
8858 syncViewWithBlueprint(componentTView, componentView);
8859 renderView(componentTView, componentView, componentView[CONTEXT]);
8860 }
8861 /**
8862 * Syncs an LView instance with its blueprint if they have gotten out of sync.
8863 *
8864 * Typically, blueprints and their view instances should always be in sync, so the loop here
8865 * will be skipped. However, consider this case of two components side-by-side:
8866 *
8867 * App template:
8868 * ```
8869 * <comp></comp>
8870 * <comp></comp>
8871 * ```
8872 *
8873 * The following will happen:
8874 * 1. App template begins processing.
8875 * 2. First <comp> is matched as a component and its LView is created.
8876 * 3. Second <comp> is matched as a component and its LView is created.
8877 * 4. App template completes processing, so it's time to check child templates.
8878 * 5. First <comp> template is checked. It has a directive, so its def is pushed to blueprint.
8879 * 6. Second <comp> template is checked. Its blueprint has been updated by the first
8880 * <comp> template, but its LView was created before this update, so it is out of sync.
8881 *
8882 * Note that embedded views inside ngFor loops will never be out of sync because these views
8883 * are processed as soon as they are created.
8884 *
8885 * @param tView The `TView` that contains the blueprint for syncing
8886 * @param lView The view to sync
8887 */
8888 function syncViewWithBlueprint(tView, lView) {
8889 for (var i = lView.length; i < tView.blueprint.length; i++) {
8890 lView.push(tView.blueprint[i]);
8891 }
8892 }
8893 /**
8894 * Adds LView or LContainer to the end of the current view tree.
8895 *
8896 * This structure will be used to traverse through nested views to remove listeners
8897 * and call onDestroy callbacks.
8898 *
8899 * @param lView The view where LView or LContainer should be added
8900 * @param adjustedHostIndex Index of the view's host node in LView[], adjusted for header
8901 * @param lViewOrLContainer The LView or LContainer to add to the view tree
8902 * @returns The state passed in
8903 */
8904 function addToViewTree(lView, lViewOrLContainer) {
8905 // TODO(benlesh/misko): This implementation is incorrect, because it always adds the LContainer
8906 // to the end of the queue, which means if the developer retrieves the LContainers from RNodes out
8907 // of order, the change detection will run out of order, as the act of retrieving the the
8908 // LContainer from the RNode is what adds it to the queue.
8909 if (lView[CHILD_HEAD]) {
8910 lView[CHILD_TAIL][NEXT] = lViewOrLContainer;
8911 }
8912 else {
8913 lView[CHILD_HEAD] = lViewOrLContainer;
8914 }
8915 lView[CHILD_TAIL] = lViewOrLContainer;
8916 return lViewOrLContainer;
8917 }
8918 ///////////////////////////////
8919 //// Change detection
8920 ///////////////////////////////
8921 /**
8922 * Marks current view and all ancestors dirty.
8923 *
8924 * Returns the root view because it is found as a byproduct of marking the view tree
8925 * dirty, and can be used by methods that consume markViewDirty() to easily schedule
8926 * change detection. Otherwise, such methods would need to traverse up the view tree
8927 * an additional time to get the root view and schedule a tick on it.
8928 *
8929 * @param lView The starting LView to mark dirty
8930 * @returns the root LView
8931 */
8932 function markViewDirty(lView) {
8933 while (lView) {
8934 lView[FLAGS] |= 64 /* Dirty */;
8935 var parent = getLViewParent(lView);
8936 // Stop traversing up as soon as you find a root view that wasn't attached to any container
8937 if (isRootView(lView) && !parent) {
8938 return lView;
8939 }
8940 // continue otherwise
8941 lView = parent;
8942 }
8943 return null;
8944 }
8945 /**
8946 * Used to schedule change detection on the whole application.
8947 *
8948 * Unlike `tick`, `scheduleTick` coalesces multiple calls into one change detection run.
8949 * It is usually called indirectly by calling `markDirty` when the view needs to be
8950 * re-rendered.
8951 *
8952 * Typically `scheduleTick` uses `requestAnimationFrame` to coalesce multiple
8953 * `scheduleTick` requests. The scheduling function can be overridden in
8954 * `renderComponent`'s `scheduler` option.
8955 */
8956 function scheduleTick(rootContext, flags) {
8957 var nothingScheduled = rootContext.flags === 0 /* Empty */;
8958 rootContext.flags |= flags;
8959 if (nothingScheduled && rootContext.clean == _CLEAN_PROMISE) {
8960 var res_1;
8961 rootContext.clean = new Promise(function (r) { return res_1 = r; });
8962 rootContext.scheduler(function () {
8963 if (rootContext.flags & 1 /* DetectChanges */) {
8964 rootContext.flags &= ~1 /* DetectChanges */;
8965 tickRootContext(rootContext);
8966 }
8967 if (rootContext.flags & 2 /* FlushPlayers */) {
8968 rootContext.flags &= ~2 /* FlushPlayers */;
8969 var playerHandler = rootContext.playerHandler;
8970 if (playerHandler) {
8971 playerHandler.flushPlayers();
8972 }
8973 }
8974 rootContext.clean = _CLEAN_PROMISE;
8975 res_1(null);
8976 });
8977 }
8978 }
8979 function tickRootContext(rootContext) {
8980 for (var i = 0; i < rootContext.components.length; i++) {
8981 var rootComponent = rootContext.components[i];
8982 var lView = readPatchedLView(rootComponent);
8983 var tView = lView[TVIEW];
8984 renderComponentOrTemplate(tView, lView, tView.template, rootComponent);
8985 }
8986 }
8987 function detectChangesInternal(tView, lView, context) {
8988 var rendererFactory = lView[RENDERER_FACTORY];
8989 if (rendererFactory.begin)
8990 rendererFactory.begin();
8991 try {
8992 refreshView(tView, lView, tView.template, context);
8993 }
8994 catch (error) {
8995 handleError(lView, error);
8996 throw error;
8997 }
8998 finally {
8999 if (rendererFactory.end)
9000 rendererFactory.end();
9001 }
9002 }
9003 /**
9004 * Synchronously perform change detection on a root view and its components.
9005 *
9006 * @param lView The view which the change detection should be performed on.
9007 */
9008 function detectChangesInRootView(lView) {
9009 tickRootContext(lView[CONTEXT]);
9010 }
9011 function checkNoChangesInternal(tView, view, context) {
9012 setCheckNoChangesMode(true);
9013 try {
9014 detectChangesInternal(tView, view, context);
9015 }
9016 finally {
9017 setCheckNoChangesMode(false);
9018 }
9019 }
9020 /**
9021 * Checks the change detector on a root view and its components, and throws if any changes are
9022 * detected.
9023 *
9024 * This is used in development mode to verify that running change detection doesn't
9025 * introduce other changes.
9026 *
9027 * @param lView The view which the change detection should be checked on.
9028 */
9029 function checkNoChangesInRootView(lView) {
9030 setCheckNoChangesMode(true);
9031 try {
9032 detectChangesInRootView(lView);
9033 }
9034 finally {
9035 setCheckNoChangesMode(false);
9036 }
9037 }
9038 function executeViewQueryFn(flags, viewQueryFn, component) {
9039 ngDevMode && assertDefined(viewQueryFn, 'View queries function to execute must be defined.');
9040 setCurrentQueryIndex(0);
9041 viewQueryFn(flags, component);
9042 }
9043 ///////////////////////////////
9044 //// Bindings & interpolations
9045 ///////////////////////////////
9046 /**
9047 * Stores meta-data for a property binding to be used by TestBed's `DebugElement.properties`.
9048 *
9049 * In order to support TestBed's `DebugElement.properties` we need to save, for each binding:
9050 * - a bound property name;
9051 * - a static parts of interpolated strings;
9052 *
9053 * A given property metadata is saved at the binding's index in the `TView.data` (in other words, a
9054 * property binding metadata will be stored in `TView.data` at the same index as a bound value in
9055 * `LView`). Metadata are represented as `INTERPOLATION_DELIMITER`-delimited string with the
9056 * following format:
9057 * - `propertyName` for bound properties;
9058 * - `propertyName�prefix�interpolation_static_part1�..interpolation_static_partN�suffix` for
9059 * interpolated properties.
9060 *
9061 * @param tData `TData` where meta-data will be saved;
9062 * @param tNode `TNode` that is a target of the binding;
9063 * @param propertyName bound property name;
9064 * @param bindingIndex binding index in `LView`
9065 * @param interpolationParts static interpolation parts (for property interpolations)
9066 */
9067 function storePropertyBindingMetadata(tData, tNode, propertyName, bindingIndex) {
9068 var interpolationParts = [];
9069 for (var _i = 4; _i < arguments.length; _i++) {
9070 interpolationParts[_i - 4] = arguments[_i];
9071 }
9072 // Binding meta-data are stored only the first time a given property instruction is processed.
9073 // Since we don't have a concept of the "first update pass" we need to check for presence of the
9074 // binding meta-data to decide if one should be stored (or if was stored already).
9075 if (tData[bindingIndex] === null) {
9076 if (tNode.inputs == null || !tNode.inputs[propertyName]) {
9077 var propBindingIdxs = tNode.propertyBindings || (tNode.propertyBindings = []);
9078 propBindingIdxs.push(bindingIndex);
9079 var bindingMetadata = propertyName;
9080 if (interpolationParts.length > 0) {
9081 bindingMetadata +=
9082 INTERPOLATION_DELIMITER + interpolationParts.join(INTERPOLATION_DELIMITER);
9083 }
9084 tData[bindingIndex] = bindingMetadata;
9085 }
9086 }
9087 }
9088 var CLEAN_PROMISE = _CLEAN_PROMISE;
9089 function getLCleanup(view) {
9090 // top level variables should not be exported for performance reasons (PERF_NOTES.md)
9091 return view[CLEANUP] || (view[CLEANUP] = ngDevMode ? new LCleanup() : []);
9092 }
9093 function getTViewCleanup(tView) {
9094 return tView.cleanup || (tView.cleanup = ngDevMode ? new TCleanup() : []);
9095 }
9096 /**
9097 * There are cases where the sub component's renderer needs to be included
9098 * instead of the current renderer (see the componentSyntheticHost* instructions).
9099 */
9100 function loadComponentRenderer(currentDef, tNode, lView) {
9101 // TODO(FW-2043): the `currentDef` is null when host bindings are invoked while creating root
9102 // component (see packages/core/src/render3/component.ts). This is not consistent with the process
9103 // of creating inner components, when current directive index is available in the state. In order
9104 // to avoid relying on current def being `null` (thus special-casing root component creation), the
9105 // process of creating root component should be unified with the process of creating inner
9106 // components.
9107 if (currentDef === null || isComponentDef(currentDef)) {
9108 lView = unwrapLView(lView[tNode.index]);
9109 }
9110 return lView[RENDERER];
9111 }
9112 /** Handles an error thrown in an LView. */
9113 function handleError(lView, error) {
9114 var injector = lView[INJECTOR$1];
9115 var errorHandler = injector ? injector.get(ErrorHandler, null) : null;
9116 errorHandler && errorHandler.handleError(error);
9117 }
9118 /**
9119 * Set the inputs of directives at the current node to corresponding value.
9120 *
9121 * @param tView The current TView
9122 * @param lView the `LView` which contains the directives.
9123 * @param inputs mapping between the public "input" name and privately-known,
9124 * possibly minified, property names to write to.
9125 * @param value Value to set.
9126 */
9127 function setInputsForProperty(tView, lView, inputs, publicName, value) {
9128 for (var i = 0; i < inputs.length;) {
9129 var index = inputs[i++];
9130 var privateName = inputs[i++];
9131 var instance = lView[index];
9132 ngDevMode && assertIndexInRange(lView, index);
9133 var def = tView.data[index];
9134 if (def.setInput !== null) {
9135 def.setInput(instance, value, publicName, privateName);
9136 }
9137 else {
9138 instance[privateName] = value;
9139 }
9140 }
9141 }
9142 /**
9143 * Updates a text binding at a given index in a given LView.
9144 */
9145 function textBindingInternal(lView, index, value) {
9146 ngDevMode && assertNotSame(value, NO_CHANGE, 'value should not be NO_CHANGE');
9147 ngDevMode && assertIndexInRange(lView, index + HEADER_OFFSET);
9148 var element = getNativeByIndex(index, lView);
9149 ngDevMode && assertDefined(element, 'native element should exist');
9150 ngDevMode && ngDevMode.rendererSetText++;
9151 var renderer = lView[RENDERER];
9152 isProceduralRenderer(renderer) ? renderer.setValue(element, value) : element.textContent = value;
9153 }
9154
9155 /**
9156 * @license
9157 * Copyright Google LLC All Rights Reserved.
9158 *
9159 * Use of this source code is governed by an MIT-style license that can be
9160 * found in the LICENSE file at https://angular.io/license
9161 */
9162 var unusedValueToPlacateAjd$1 = unusedValueExportToPlacateAjd + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$2 + unusedValueExportToPlacateAjd$1;
9163 function getLContainer(tNode, embeddedView) {
9164 ngDevMode && assertLView(embeddedView);
9165 var container = embeddedView[PARENT];
9166 if (tNode.index === -1) {
9167 // This is a dynamically created view inside a dynamic container.
9168 // The parent isn't an LContainer if the embedded view hasn't been attached yet.
9169 return isLContainer(container) ? container : null;
9170 }
9171 else {
9172 ngDevMode && assertLContainer(container);
9173 // This is a inline view node (e.g. embeddedViewStart)
9174 return container;
9175 }
9176 }
9177 /**
9178 * Retrieves render parent for a given view.
9179 * Might be null if a view is not yet attached to any container.
9180 */
9181 function getContainerRenderParent(tViewNode, view) {
9182 var container = getLContainer(tViewNode, view);
9183 return container ? nativeParentNode(view[RENDERER], container[NATIVE]) : null;
9184 }
9185 /**
9186 * NOTE: for performance reasons, the possible actions are inlined within the function instead of
9187 * being passed as an argument.
9188 */
9189 function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode) {
9190 // If this slot was allocated for a text node dynamically created by i18n, the text node itself
9191 // won't be created until i18nApply() in the update block, so this node should be skipped.
9192 // For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
9193 // in `i18n_spec.ts`.
9194 if (lNodeToHandle != null) {
9195 var lContainer = void 0;
9196 var isComponent = false;
9197 // We are expecting an RNode, but in the case of a component or LContainer the `RNode` is
9198 // wrapped in an array which needs to be unwrapped. We need to know if it is a component and if
9199 // it has LContainer so that we can process all of those cases appropriately.
9200 if (isLContainer(lNodeToHandle)) {
9201 lContainer = lNodeToHandle;
9202 }
9203 else if (isLView(lNodeToHandle)) {
9204 isComponent = true;
9205 ngDevMode && assertDefined(lNodeToHandle[HOST], 'HOST must be defined for a component LView');
9206 lNodeToHandle = lNodeToHandle[HOST];
9207 }
9208 var rNode = unwrapRNode(lNodeToHandle);
9209 ngDevMode && !isProceduralRenderer(renderer) && assertDomNode(rNode);
9210 if (action === 0 /* Create */ && parent !== null) {
9211 if (beforeNode == null) {
9212 nativeAppendChild(renderer, parent, rNode);
9213 }
9214 else {
9215 nativeInsertBefore(renderer, parent, rNode, beforeNode || null);
9216 }
9217 }
9218 else if (action === 1 /* Insert */ && parent !== null) {
9219 nativeInsertBefore(renderer, parent, rNode, beforeNode || null);
9220 }
9221 else if (action === 2 /* Detach */) {
9222 nativeRemoveNode(renderer, rNode, isComponent);
9223 }
9224 else if (action === 3 /* Destroy */) {
9225 ngDevMode && ngDevMode.rendererDestroyNode++;
9226 renderer.destroyNode(rNode);
9227 }
9228 if (lContainer != null) {
9229 applyContainer(renderer, action, lContainer, parent, beforeNode);
9230 }
9231 }
9232 }
9233 function createTextNode(value, renderer) {
9234 ngDevMode && ngDevMode.rendererCreateTextNode++;
9235 ngDevMode && ngDevMode.rendererSetText++;
9236 return isProceduralRenderer(renderer) ? renderer.createText(value) :
9237 renderer.createTextNode(value);
9238 }
9239 function addRemoveViewFromContainer(tView, lView, insertMode, beforeNode) {
9240 var renderParent = getContainerRenderParent(tView.node, lView);
9241 ngDevMode && assertNodeType(tView.node, 2 /* View */);
9242 if (renderParent) {
9243 var renderer = lView[RENDERER];
9244 var action = insertMode ? 1 /* Insert */ : 2 /* Detach */;
9245 applyView(tView, lView, renderer, action, renderParent, beforeNode);
9246 }
9247 }
9248 /**
9249 * Detach a `LView` from the DOM by detaching its nodes.
9250 *
9251 * @param tView The `TView' of the `LView` to be detached
9252 * @param lView the `LView` to be detached.
9253 */
9254 function renderDetachView(tView, lView) {
9255 applyView(tView, lView, lView[RENDERER], 2 /* Detach */, null, null);
9256 }
9257 /**
9258 * Traverses down and up the tree of views and containers to remove listeners and
9259 * call onDestroy callbacks.
9260 *
9261 * Notes:
9262 * - Because it's used for onDestroy calls, it needs to be bottom-up.
9263 * - Must process containers instead of their views to avoid splicing
9264 * when views are destroyed and re-added.
9265 * - Using a while loop because it's faster than recursion
9266 * - Destroy only called on movement to sibling or movement to parent (laterally or up)
9267 *
9268 * @param rootView The view to destroy
9269 */
9270 function destroyViewTree(rootView) {
9271 // If the view has no children, we can clean it up and return early.
9272 var lViewOrLContainer = rootView[CHILD_HEAD];
9273 if (!lViewOrLContainer) {
9274 return cleanUpView(rootView[TVIEW], rootView);
9275 }
9276 while (lViewOrLContainer) {
9277 var next = null;
9278 if (isLView(lViewOrLContainer)) {
9279 // If LView, traverse down to child.
9280 next = lViewOrLContainer[CHILD_HEAD];
9281 }
9282 else {
9283 ngDevMode && assertLContainer(lViewOrLContainer);
9284 // If container, traverse down to its first LView.
9285 var firstView = lViewOrLContainer[CONTAINER_HEADER_OFFSET];
9286 if (firstView)
9287 next = firstView;
9288 }
9289 if (!next) {
9290 // Only clean up view when moving to the side or up, as destroy hooks
9291 // should be called in order from the bottom up.
9292 while (lViewOrLContainer && !lViewOrLContainer[NEXT] && lViewOrLContainer !== rootView) {
9293 isLView(lViewOrLContainer) && cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
9294 lViewOrLContainer = getParentState(lViewOrLContainer, rootView);
9295 }
9296 if (lViewOrLContainer === null)
9297 lViewOrLContainer = rootView;
9298 isLView(lViewOrLContainer) && cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
9299 next = lViewOrLContainer && lViewOrLContainer[NEXT];
9300 }
9301 lViewOrLContainer = next;
9302 }
9303 }
9304 /**
9305 * Inserts a view into a container.
9306 *
9307 * This adds the view to the container's array of active views in the correct
9308 * position. It also adds the view's elements to the DOM if the container isn't a
9309 * root node of another view (in that case, the view's elements will be added when
9310 * the container's parent view is added later).
9311 *
9312 * @param tView The `TView' of the `LView` to insert
9313 * @param lView The view to insert
9314 * @param lContainer The container into which the view should be inserted
9315 * @param index Which index in the container to insert the child view into
9316 */
9317 function insertView(tView, lView, lContainer, index) {
9318 ngDevMode && assertLView(lView);
9319 ngDevMode && assertLContainer(lContainer);
9320 var indexInContainer = CONTAINER_HEADER_OFFSET + index;
9321 var containerLength = lContainer.length;
9322 if (index > 0) {
9323 // This is a new view, we need to add it to the children.
9324 lContainer[indexInContainer - 1][NEXT] = lView;
9325 }
9326 if (index < containerLength - CONTAINER_HEADER_OFFSET) {
9327 lView[NEXT] = lContainer[indexInContainer];
9328 addToArray(lContainer, CONTAINER_HEADER_OFFSET + index, lView);
9329 }
9330 else {
9331 lContainer.push(lView);
9332 lView[NEXT] = null;
9333 }
9334 lView[PARENT] = lContainer;
9335 // track views where declaration and insertion points are different
9336 var declarationLContainer = lView[DECLARATION_LCONTAINER];
9337 if (declarationLContainer !== null && lContainer !== declarationLContainer) {
9338 trackMovedView(declarationLContainer, lView);
9339 }
9340 // notify query that a new view has been added
9341 var lQueries = lView[QUERIES];
9342 if (lQueries !== null) {
9343 lQueries.insertView(tView);
9344 }
9345 // Sets the attached flag
9346 lView[FLAGS] |= 128 /* Attached */;
9347 }
9348 /**
9349 * Track views created from the declaration container (TemplateRef) and inserted into a
9350 * different LContainer.
9351 */
9352 function trackMovedView(declarationContainer, lView) {
9353 ngDevMode && assertDefined(lView, 'LView required');
9354 ngDevMode && assertLContainer(declarationContainer);
9355 var movedViews = declarationContainer[MOVED_VIEWS];
9356 var insertedLContainer = lView[PARENT];
9357 ngDevMode && assertLContainer(insertedLContainer);
9358 var insertedComponentLView = insertedLContainer[PARENT][DECLARATION_COMPONENT_VIEW];
9359 ngDevMode && assertDefined(insertedComponentLView, 'Missing insertedComponentLView');
9360 var declaredComponentLView = lView[DECLARATION_COMPONENT_VIEW];
9361 ngDevMode && assertDefined(declaredComponentLView, 'Missing declaredComponentLView');
9362 if (declaredComponentLView !== insertedComponentLView) {
9363 // At this point the declaration-component is not same as insertion-component; this means that
9364 // this is a transplanted view. Mark the declared lView as having transplanted views so that
9365 // those views can participate in CD.
9366 declarationContainer[HAS_TRANSPLANTED_VIEWS] = true;
9367 }
9368 if (movedViews === null) {
9369 declarationContainer[MOVED_VIEWS] = [lView];
9370 }
9371 else {
9372 movedViews.push(lView);
9373 }
9374 }
9375 function detachMovedView(declarationContainer, lView) {
9376 ngDevMode && assertLContainer(declarationContainer);
9377 ngDevMode &&
9378 assertDefined(declarationContainer[MOVED_VIEWS], 'A projected view should belong to a non-empty projected views collection');
9379 var movedViews = declarationContainer[MOVED_VIEWS];
9380 var declarationViewIndex = movedViews.indexOf(lView);
9381 var insertionLContainer = lView[PARENT];
9382 ngDevMode && assertLContainer(insertionLContainer);
9383 // If the view was marked for refresh but then detached before it was checked (where the flag
9384 // would be cleared and the counter decremented), we need to decrement the view counter here
9385 // instead.
9386 if (lView[FLAGS] & 1024 /* RefreshTransplantedView */) {
9387 updateTransplantedViewCount(insertionLContainer, -1);
9388 }
9389 movedViews.splice(declarationViewIndex, 1);
9390 }
9391 /**
9392 * Detaches a view from a container.
9393 *
9394 * This method removes the view from the container's array of active views. It also
9395 * removes the view's elements from the DOM.
9396 *
9397 * @param lContainer The container from which to detach a view
9398 * @param removeIndex The index of the view to detach
9399 * @returns Detached LView instance.
9400 */
9401 function detachView(lContainer, removeIndex) {
9402 if (lContainer.length <= CONTAINER_HEADER_OFFSET)
9403 return;
9404 var indexInContainer = CONTAINER_HEADER_OFFSET + removeIndex;
9405 var viewToDetach = lContainer[indexInContainer];
9406 if (viewToDetach) {
9407 var declarationLContainer = viewToDetach[DECLARATION_LCONTAINER];
9408 if (declarationLContainer !== null && declarationLContainer !== lContainer) {
9409 detachMovedView(declarationLContainer, viewToDetach);
9410 }
9411 if (removeIndex > 0) {
9412 lContainer[indexInContainer - 1][NEXT] = viewToDetach[NEXT];
9413 }
9414 var removedLView = removeFromArray(lContainer, CONTAINER_HEADER_OFFSET + removeIndex);
9415 addRemoveViewFromContainer(viewToDetach[TVIEW], viewToDetach, false, null);
9416 // notify query that a view has been removed
9417 var lQueries = removedLView[QUERIES];
9418 if (lQueries !== null) {
9419 lQueries.detachView(removedLView[TVIEW]);
9420 }
9421 viewToDetach[PARENT] = null;
9422 viewToDetach[NEXT] = null;
9423 // Unsets the attached flag
9424 viewToDetach[FLAGS] &= ~128 /* Attached */;
9425 }
9426 return viewToDetach;
9427 }
9428 /**
9429 * A standalone function which destroys an LView,
9430 * conducting clean up (e.g. removing listeners, calling onDestroys).
9431 *
9432 * @param tView The `TView' of the `LView` to be destroyed
9433 * @param lView The view to be destroyed.
9434 */
9435 function destroyLView(tView, lView) {
9436 if (!(lView[FLAGS] & 256 /* Destroyed */)) {
9437 var renderer = lView[RENDERER];
9438 if (isProceduralRenderer(renderer) && renderer.destroyNode) {
9439 applyView(tView, lView, renderer, 3 /* Destroy */, null, null);
9440 }
9441 destroyViewTree(lView);
9442 }
9443 }
9444 /**
9445 * Determines which LViewOrLContainer to jump to when traversing back up the
9446 * tree in destroyViewTree.
9447 *
9448 * Normally, the view's parent LView should be checked, but in the case of
9449 * embedded views, the container (which is the view node's parent, but not the
9450 * LView's parent) needs to be checked for a possible next property.
9451 *
9452 * @param lViewOrLContainer The LViewOrLContainer for which we need a parent state
9453 * @param rootView The rootView, so we don't propagate too far up the view tree
9454 * @returns The correct parent LViewOrLContainer
9455 */
9456 function getParentState(lViewOrLContainer, rootView) {
9457 var tNode;
9458 if (isLView(lViewOrLContainer) && (tNode = lViewOrLContainer[T_HOST]) &&
9459 tNode.type === 2 /* View */) {
9460 // if it's an embedded view, the state needs to go up to the container, in case the
9461 // container has a next
9462 return getLContainer(tNode, lViewOrLContainer);
9463 }
9464 else {
9465 // otherwise, use parent view for containers or component views
9466 return lViewOrLContainer[PARENT] === rootView ? null : lViewOrLContainer[PARENT];
9467 }
9468 }
9469 /**
9470 * Calls onDestroys hooks for all directives and pipes in a given view and then removes all
9471 * listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks
9472 * can be propagated to @Output listeners.
9473 *
9474 * @param tView `TView` for the `LView` to clean up.
9475 * @param lView The LView to clean up
9476 */
9477 function cleanUpView(tView, lView) {
9478 if (!(lView[FLAGS] & 256 /* Destroyed */)) {
9479 // Usually the Attached flag is removed when the view is detached from its parent, however
9480 // if it's a root view, the flag won't be unset hence why we're also removing on destroy.
9481 lView[FLAGS] &= ~128 /* Attached */;
9482 // Mark the LView as destroyed *before* executing the onDestroy hooks. An onDestroy hook
9483 // runs arbitrary user code, which could include its own `viewRef.destroy()` (or similar). If
9484 // We don't flag the view as destroyed before the hooks, this could lead to an infinite loop.
9485 // This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is
9486 // really more of an "afterDestroy" hook if you think about it.
9487 lView[FLAGS] |= 256 /* Destroyed */;
9488 executeOnDestroys(tView, lView);
9489 removeListeners(tView, lView);
9490 var hostTNode = lView[T_HOST];
9491 // For component views only, the local renderer is destroyed as clean up time.
9492 if (hostTNode && hostTNode.type === 3 /* Element */ &&
9493 isProceduralRenderer(lView[RENDERER])) {
9494 ngDevMode && ngDevMode.rendererDestroy++;
9495 lView[RENDERER].destroy();
9496 }
9497 var declarationContainer = lView[DECLARATION_LCONTAINER];
9498 // we are dealing with an embedded view that is still inserted into a container
9499 if (declarationContainer !== null && isLContainer(lView[PARENT])) {
9500 // and this is a projected view
9501 if (declarationContainer !== lView[PARENT]) {
9502 detachMovedView(declarationContainer, lView);
9503 }
9504 // For embedded views still attached to a container: remove query result from this view.
9505 var lQueries = lView[QUERIES];
9506 if (lQueries !== null) {
9507 lQueries.detachView(tView);
9508 }
9509 }
9510 }
9511 }
9512 /** Removes listeners and unsubscribes from output subscriptions */
9513 function removeListeners(tView, lView) {
9514 var tCleanup = tView.cleanup;
9515 if (tCleanup !== null) {
9516 var lCleanup = lView[CLEANUP];
9517 for (var i = 0; i < tCleanup.length - 1; i += 2) {
9518 if (typeof tCleanup[i] === 'string') {
9519 // This is a native DOM listener
9520 var idxOrTargetGetter = tCleanup[i + 1];
9521 var target = typeof idxOrTargetGetter === 'function' ?
9522 idxOrTargetGetter(lView) :
9523 unwrapRNode(lView[idxOrTargetGetter]);
9524 var listener = lCleanup[tCleanup[i + 2]];
9525 var useCaptureOrSubIdx = tCleanup[i + 3];
9526 if (typeof useCaptureOrSubIdx === 'boolean') {
9527 // native DOM listener registered with Renderer3
9528 target.removeEventListener(tCleanup[i], listener, useCaptureOrSubIdx);
9529 }
9530 else {
9531 if (useCaptureOrSubIdx >= 0) {
9532 // unregister
9533 lCleanup[useCaptureOrSubIdx]();
9534 }
9535 else {
9536 // Subscription
9537 lCleanup[-useCaptureOrSubIdx].unsubscribe();
9538 }
9539 }
9540 i += 2;
9541 }
9542 else {
9543 // This is a cleanup function that is grouped with the index of its context
9544 var context = lCleanup[tCleanup[i + 1]];
9545 tCleanup[i].call(context);
9546 }
9547 }
9548 lView[CLEANUP] = null;
9549 }
9550 }
9551 /** Calls onDestroy hooks for this view */
9552 function executeOnDestroys(tView, lView) {
9553 var destroyHooks;
9554 if (tView != null && (destroyHooks = tView.destroyHooks) != null) {
9555 for (var i = 0; i < destroyHooks.length; i += 2) {
9556 var context = lView[destroyHooks[i]];
9557 // Only call the destroy hook if the context has been requested.
9558 if (!(context instanceof NodeInjectorFactory)) {
9559 var toCall = destroyHooks[i + 1];
9560 if (Array.isArray(toCall)) {
9561 for (var j = 0; j < toCall.length; j += 2) {
9562 toCall[j + 1].call(context[toCall[j]]);
9563 }
9564 }
9565 else {
9566 toCall.call(context);
9567 }
9568 }
9569 }
9570 }
9571 }
9572 /**
9573 * Returns a native element if a node can be inserted into the given parent.
9574 *
9575 * There are two reasons why we may not be able to insert a element immediately.
9576 * - Projection: When creating a child content element of a component, we have to skip the
9577 * insertion because the content of a component will be projected.
9578 * `<component><content>delayed due to projection</content></component>`
9579 * - Parent container is disconnected: This can happen when we are inserting a view into
9580 * parent container, which itself is disconnected. For example the parent container is part
9581 * of a View which has not be inserted or is made for projection but has not been inserted
9582 * into destination.
9583 */
9584 function getRenderParent(tView, tNode, currentView) {
9585 // Skip over element and ICU containers as those are represented by a comment node and
9586 // can't be used as a render parent.
9587 var parentTNode = tNode.parent;
9588 while (parentTNode != null &&
9589 (parentTNode.type === 4 /* ElementContainer */ ||
9590 parentTNode.type === 5 /* IcuContainer */)) {
9591 tNode = parentTNode;
9592 parentTNode = tNode.parent;
9593 }
9594 // If the parent tNode is null, then we are inserting across views: either into an embedded view
9595 // or a component view.
9596 if (parentTNode == null) {
9597 var hostTNode = currentView[T_HOST];
9598 if (hostTNode.type === 2 /* View */) {
9599 // We are inserting a root element of an embedded view We might delay insertion of children
9600 // for a given view if it is disconnected. This might happen for 2 main reasons:
9601 // - view is not inserted into any container(view was created but not inserted yet)
9602 // - view is inserted into a container but the container itself is not inserted into the DOM
9603 // (container might be part of projection or child of a view that is not inserted yet).
9604 // In other words we can insert children of a given view if this view was inserted into a
9605 // container and the container itself has its render parent determined.
9606 return getContainerRenderParent(hostTNode, currentView);
9607 }
9608 else {
9609 // We are inserting a root element of the component view into the component host element and
9610 // it should always be eager.
9611 ngDevMode && assertNodeOfPossibleTypes(hostTNode, [3 /* Element */]);
9612 return currentView[HOST];
9613 }
9614 }
9615 else {
9616 var isIcuCase = tNode && tNode.type === 5 /* IcuContainer */;
9617 // If the parent of this node is an ICU container, then it is represented by comment node and we
9618 // need to use it as an anchor. If it is projected then it's direct parent node is the renderer.
9619 if (isIcuCase && tNode.flags & 4 /* isProjected */) {
9620 return getNativeByTNode(tNode, currentView).parentNode;
9621 }
9622 ngDevMode && assertNodeType(parentTNode, 3 /* Element */);
9623 if (parentTNode.flags & 2 /* isComponentHost */) {
9624 var tData = tView.data;
9625 var tNode_1 = tData[parentTNode.index];
9626 var encapsulation = tData[tNode_1.directiveStart].encapsulation;
9627 // We've got a parent which is an element in the current view. We just need to verify if the
9628 // parent element is not a component. Component's content nodes are not inserted immediately
9629 // because they will be projected, and so doing insert at this point would be wasteful.
9630 // Since the projection would then move it to its final destination. Note that we can't
9631 // make this assumption when using the Shadow DOM, because the native projection placeholders
9632 // (<content> or <slot>) have to be in place as elements are being inserted.
9633 if (encapsulation !== exports.ViewEncapsulation.ShadowDom &&
9634 encapsulation !== exports.ViewEncapsulation.Native) {
9635 return null;
9636 }
9637 }
9638 return getNativeByTNode(parentTNode, currentView);
9639 }
9640 }
9641 /**
9642 * Inserts a native node before another native node for a given parent using {@link Renderer3}.
9643 * This is a utility function that can be used when native nodes were determined - it abstracts an
9644 * actual renderer being used.
9645 */
9646 function nativeInsertBefore(renderer, parent, child, beforeNode) {
9647 ngDevMode && ngDevMode.rendererInsertBefore++;
9648 if (isProceduralRenderer(renderer)) {
9649 renderer.insertBefore(parent, child, beforeNode);
9650 }
9651 else {
9652 parent.insertBefore(child, beforeNode, true);
9653 }
9654 }
9655 function nativeAppendChild(renderer, parent, child) {
9656 ngDevMode && ngDevMode.rendererAppendChild++;
9657 ngDevMode && assertDefined(parent, 'parent node must be defined');
9658 if (isProceduralRenderer(renderer)) {
9659 renderer.appendChild(parent, child);
9660 }
9661 else {
9662 parent.appendChild(child);
9663 }
9664 }
9665 function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode) {
9666 if (beforeNode !== null) {
9667 nativeInsertBefore(renderer, parent, child, beforeNode);
9668 }
9669 else {
9670 nativeAppendChild(renderer, parent, child);
9671 }
9672 }
9673 /** Removes a node from the DOM given its native parent. */
9674 function nativeRemoveChild(renderer, parent, child, isHostElement) {
9675 if (isProceduralRenderer(renderer)) {
9676 renderer.removeChild(parent, child, isHostElement);
9677 }
9678 else {
9679 parent.removeChild(child);
9680 }
9681 }
9682 /**
9683 * Returns a native parent of a given native node.
9684 */
9685 function nativeParentNode(renderer, node) {
9686 return (isProceduralRenderer(renderer) ? renderer.parentNode(node) : node.parentNode);
9687 }
9688 /**
9689 * Returns a native sibling of a given native node.
9690 */
9691 function nativeNextSibling(renderer, node) {
9692 return isProceduralRenderer(renderer) ? renderer.nextSibling(node) : node.nextSibling;
9693 }
9694 /**
9695 * Finds a native "anchor" node for cases where we can't append a native child directly
9696 * (`appendChild`) and need to use a reference (anchor) node for the `insertBefore` operation.
9697 * @param parentTNode
9698 * @param lView
9699 */
9700 function getNativeAnchorNode(parentTNode, lView) {
9701 if (parentTNode.type === 2 /* View */) {
9702 var lContainer = getLContainer(parentTNode, lView);
9703 if (lContainer === null)
9704 return null;
9705 var index = lContainer.indexOf(lView, CONTAINER_HEADER_OFFSET) - CONTAINER_HEADER_OFFSET;
9706 return getBeforeNodeForView(index, lContainer);
9707 }
9708 else if (parentTNode.type === 4 /* ElementContainer */ ||
9709 parentTNode.type === 5 /* IcuContainer */) {
9710 return getNativeByTNode(parentTNode, lView);
9711 }
9712 return null;
9713 }
9714 /**
9715 * Appends the `child` native node (or a collection of nodes) to the `parent`.
9716 *
9717 * The element insertion might be delayed {@link canInsertNativeNode}.
9718 *
9719 * @param tView The `TView' to be appended
9720 * @param lView The current LView
9721 * @param childEl The native child (or children) that should be appended
9722 * @param childTNode The TNode of the child element
9723 * @returns Whether or not the child was appended
9724 */
9725 function appendChild(tView, lView, childEl, childTNode) {
9726 var renderParent = getRenderParent(tView, childTNode, lView);
9727 if (renderParent != null) {
9728 var renderer = lView[RENDERER];
9729 var parentTNode = childTNode.parent || lView[T_HOST];
9730 var anchorNode = getNativeAnchorNode(parentTNode, lView);
9731 if (Array.isArray(childEl)) {
9732 for (var i = 0; i < childEl.length; i++) {
9733 nativeAppendOrInsertBefore(renderer, renderParent, childEl[i], anchorNode);
9734 }
9735 }
9736 else {
9737 nativeAppendOrInsertBefore(renderer, renderParent, childEl, anchorNode);
9738 }
9739 }
9740 }
9741 /**
9742 * Returns the first native node for a given LView, starting from the provided TNode.
9743 *
9744 * Native nodes are returned in the order in which those appear in the native tree (DOM).
9745 */
9746 function getFirstNativeNode(lView, tNode) {
9747 if (tNode !== null) {
9748 ngDevMode && assertNodeOfPossibleTypes(tNode, [
9749 3 /* Element */, 0 /* Container */, 4 /* ElementContainer */, 5 /* IcuContainer */,
9750 1 /* Projection */
9751 ]);
9752 var tNodeType = tNode.type;
9753 if (tNodeType === 3 /* Element */) {
9754 return getNativeByTNode(tNode, lView);
9755 }
9756 else if (tNodeType === 0 /* Container */) {
9757 return getBeforeNodeForView(-1, lView[tNode.index]);
9758 }
9759 else if (tNodeType === 4 /* ElementContainer */ || tNodeType === 5 /* IcuContainer */) {
9760 var elIcuContainerChild = tNode.child;
9761 if (elIcuContainerChild !== null) {
9762 return getFirstNativeNode(lView, elIcuContainerChild);
9763 }
9764 else {
9765 var rNodeOrLContainer = lView[tNode.index];
9766 if (isLContainer(rNodeOrLContainer)) {
9767 return getBeforeNodeForView(-1, rNodeOrLContainer);
9768 }
9769 else {
9770 return unwrapRNode(rNodeOrLContainer);
9771 }
9772 }
9773 }
9774 else {
9775 var componentView = lView[DECLARATION_COMPONENT_VIEW];
9776 var componentHost = componentView[T_HOST];
9777 var parentView = getLViewParent(componentView);
9778 var firstProjectedTNode = componentHost.projection[tNode.projection];
9779 if (firstProjectedTNode != null) {
9780 return getFirstNativeNode(parentView, firstProjectedTNode);
9781 }
9782 else {
9783 return getFirstNativeNode(lView, tNode.next);
9784 }
9785 }
9786 }
9787 return null;
9788 }
9789 function getBeforeNodeForView(viewIndexInContainer, lContainer) {
9790 var nextViewIndex = CONTAINER_HEADER_OFFSET + viewIndexInContainer + 1;
9791 if (nextViewIndex < lContainer.length) {
9792 var lView = lContainer[nextViewIndex];
9793 var firstTNodeOfView = lView[TVIEW].firstChild;
9794 if (firstTNodeOfView !== null) {
9795 return getFirstNativeNode(lView, firstTNodeOfView);
9796 }
9797 }
9798 return lContainer[NATIVE];
9799 }
9800 /**
9801 * Removes a native node itself using a given renderer. To remove the node we are looking up its
9802 * parent from the native tree as not all platforms / browsers support the equivalent of
9803 * node.remove().
9804 *
9805 * @param renderer A renderer to be used
9806 * @param rNode The native node that should be removed
9807 * @param isHostElement A flag indicating if a node to be removed is a host of a component.
9808 */
9809 function nativeRemoveNode(renderer, rNode, isHostElement) {
9810 var nativeParent = nativeParentNode(renderer, rNode);
9811 if (nativeParent) {
9812 nativeRemoveChild(renderer, nativeParent, rNode, isHostElement);
9813 }
9814 }
9815 /**
9816 * Performs the operation of `action` on the node. Typically this involves inserting or removing
9817 * nodes on the LView or projection boundary.
9818 */
9819 function applyNodes(renderer, action, tNode, lView, renderParent, beforeNode, isProjection) {
9820 while (tNode != null) {
9821 ngDevMode && assertTNodeForLView(tNode, lView);
9822 ngDevMode && assertNodeOfPossibleTypes(tNode, [
9823 0 /* Container */, 3 /* Element */, 4 /* ElementContainer */, 1 /* Projection */,
9824 5 /* IcuContainer */
9825 ]);
9826 var rawSlotValue = lView[tNode.index];
9827 var tNodeType = tNode.type;
9828 if (isProjection) {
9829 if (action === 0 /* Create */) {
9830 rawSlotValue && attachPatchData(unwrapRNode(rawSlotValue), lView);
9831 tNode.flags |= 4 /* isProjected */;
9832 }
9833 }
9834 if ((tNode.flags & 64 /* isDetached */) !== 64 /* isDetached */) {
9835 if (tNodeType === 4 /* ElementContainer */ || tNodeType === 5 /* IcuContainer */) {
9836 applyNodes(renderer, action, tNode.child, lView, renderParent, beforeNode, false);
9837 applyToElementOrContainer(action, renderer, renderParent, rawSlotValue, beforeNode);
9838 }
9839 else if (tNodeType === 1 /* Projection */) {
9840 applyProjectionRecursive(renderer, action, lView, tNode, renderParent, beforeNode);
9841 }
9842 else {
9843 ngDevMode && assertNodeOfPossibleTypes(tNode, [3 /* Element */, 0 /* Container */]);
9844 applyToElementOrContainer(action, renderer, renderParent, rawSlotValue, beforeNode);
9845 }
9846 }
9847 tNode = isProjection ? tNode.projectionNext : tNode.next;
9848 }
9849 }
9850 /**
9851 * `applyView` performs operation on the view as specified in `action` (insert, detach, destroy)
9852 *
9853 * Inserting a view without projection or containers at top level is simple. Just iterate over the
9854 * root nodes of the View, and for each node perform the `action`.
9855 *
9856 * Things get more complicated with containers and projections. That is because coming across:
9857 * - Container: implies that we have to insert/remove/destroy the views of that container as well
9858 * which in turn can have their own Containers at the View roots.
9859 * - Projection: implies that we have to insert/remove/destroy the nodes of the projection. The
9860 * complication is that the nodes we are projecting can themselves have Containers
9861 * or other Projections.
9862 *
9863 * As you can see this is a very recursive problem. Yes recursion is not most efficient but the
9864 * code is complicated enough that trying to implemented with recursion becomes unmaintainable.
9865 *
9866 * @param tView The `TView' which needs to be inserted, detached, destroyed
9867 * @param lView The LView which needs to be inserted, detached, destroyed.
9868 * @param renderer Renderer to use
9869 * @param action action to perform (insert, detach, destroy)
9870 * @param renderParent parent DOM element for insertion/removal.
9871 * @param beforeNode Before which node the insertions should happen.
9872 */
9873 function applyView(tView, lView, renderer, action, renderParent, beforeNode) {
9874 ngDevMode && assertNodeType(tView.node, 2 /* View */);
9875 var viewRootTNode = tView.node.child;
9876 applyNodes(renderer, action, viewRootTNode, lView, renderParent, beforeNode, false);
9877 }
9878 /**
9879 * `applyProjection` performs operation on the projection.
9880 *
9881 * Inserting a projection requires us to locate the projected nodes from the parent component. The
9882 * complication is that those nodes themselves could be re-projected from their parent component.
9883 *
9884 * @param tView The `TView` of `LView` which needs to be inserted, detached, destroyed
9885 * @param lView The `LView` which needs to be inserted, detached, destroyed.
9886 * @param tProjectionNode node to project
9887 */
9888 function applyProjection(tView, lView, tProjectionNode) {
9889 var renderer = lView[RENDERER];
9890 var renderParent = getRenderParent(tView, tProjectionNode, lView);
9891 var parentTNode = tProjectionNode.parent || lView[T_HOST];
9892 var beforeNode = getNativeAnchorNode(parentTNode, lView);
9893 applyProjectionRecursive(renderer, 0 /* Create */, lView, tProjectionNode, renderParent, beforeNode);
9894 }
9895 /**
9896 * `applyProjectionRecursive` performs operation on the projection specified by `action` (insert,
9897 * detach, destroy)
9898 *
9899 * Inserting a projection requires us to locate the projected nodes from the parent component. The
9900 * complication is that those nodes themselves could be re-projected from their parent component.
9901 *
9902 * @param renderer Render to use
9903 * @param action action to perform (insert, detach, destroy)
9904 * @param lView The LView which needs to be inserted, detached, destroyed.
9905 * @param tProjectionNode node to project
9906 * @param renderParent parent DOM element for insertion/removal.
9907 * @param beforeNode Before which node the insertions should happen.
9908 */
9909 function applyProjectionRecursive(renderer, action, lView, tProjectionNode, renderParent, beforeNode) {
9910 var componentLView = lView[DECLARATION_COMPONENT_VIEW];
9911 var componentNode = componentLView[T_HOST];
9912 ngDevMode &&
9913 assertEqual(typeof tProjectionNode.projection, 'number', 'expecting projection index');
9914 var nodeToProjectOrRNodes = componentNode.projection[tProjectionNode.projection];
9915 if (Array.isArray(nodeToProjectOrRNodes)) {
9916 // This should not exist, it is a bit of a hack. When we bootstrap a top level node and we
9917 // need to support passing projectable nodes, so we cheat and put them in the TNode
9918 // of the Host TView. (Yes we put instance info at the T Level). We can get away with it
9919 // because we know that that TView is not shared and therefore it will not be a problem.
9920 // This should be refactored and cleaned up.
9921 for (var i = 0; i < nodeToProjectOrRNodes.length; i++) {
9922 var rNode = nodeToProjectOrRNodes[i];
9923 applyToElementOrContainer(action, renderer, renderParent, rNode, beforeNode);
9924 }
9925 }
9926 else {
9927 var nodeToProject = nodeToProjectOrRNodes;
9928 var projectedComponentLView = componentLView[PARENT];
9929 applyNodes(renderer, action, nodeToProject, projectedComponentLView, renderParent, beforeNode, true);
9930 }
9931 }
9932 /**
9933 * `applyContainer` performs an operation on the container and its views as specified by
9934 * `action` (insert, detach, destroy)
9935 *
9936 * Inserting a Container is complicated by the fact that the container may have Views which
9937 * themselves have containers or projections.
9938 *
9939 * @param renderer Renderer to use
9940 * @param action action to perform (insert, detach, destroy)
9941 * @param lContainer The LContainer which needs to be inserted, detached, destroyed.
9942 * @param renderParent parent DOM element for insertion/removal.
9943 * @param beforeNode Before which node the insertions should happen.
9944 */
9945 function applyContainer(renderer, action, lContainer, renderParent, beforeNode) {
9946 ngDevMode && assertLContainer(lContainer);
9947 var anchor = lContainer[NATIVE]; // LContainer has its own before node.
9948 var native = unwrapRNode(lContainer);
9949 // An LContainer can be created dynamically on any node by injecting ViewContainerRef.
9950 // Asking for a ViewContainerRef on an element will result in a creation of a separate anchor node
9951 // (comment in the DOM) that will be different from the LContainer's host node. In this particular
9952 // case we need to execute action on 2 nodes:
9953 // - container's host node (this is done in the executeActionOnElementOrContainer)
9954 // - container's host node (this is done here)
9955 if (anchor !== native) {
9956 // This is very strange to me (Misko). I would expect that the native is same as anchor. I don't
9957 // see a reason why they should be different, but they are.
9958 //
9959 // If they are we need to process the second anchor as well.
9960 applyToElementOrContainer(action, renderer, renderParent, anchor, beforeNode);
9961 }
9962 for (var i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
9963 var lView = lContainer[i];
9964 applyView(lView[TVIEW], lView, renderer, action, renderParent, anchor);
9965 }
9966 }
9967 /**
9968 * Writes class/style to element.
9969 *
9970 * @param renderer Renderer to use.
9971 * @param isClassBased `true` if it should be written to `class` (`false` to write to `style`)
9972 * @param rNode The Node to write to.
9973 * @param prop Property to write to. This would be the class/style name.
9974 * @param value Value to write. If `null`/`undefined`/`false` this is considered a remove (set/add
9975 * otherwise).
9976 */
9977 function applyStyling(renderer, isClassBased, rNode, prop, value) {
9978 var isProcedural = isProceduralRenderer(renderer);
9979 if (isClassBased) {
9980 // We actually want JS true/false here because any truthy value should add the class
9981 if (!value) {
9982 ngDevMode && ngDevMode.rendererRemoveClass++;
9983 if (isProcedural) {
9984 renderer.removeClass(rNode, prop);
9985 }
9986 else {
9987 rNode.classList.remove(prop);
9988 }
9989 }
9990 else {
9991 ngDevMode && ngDevMode.rendererAddClass++;
9992 if (isProcedural) {
9993 renderer.addClass(rNode, prop);
9994 }
9995 else {
9996 ngDevMode && assertDefined(rNode.classList, 'HTMLElement expected');
9997 rNode.classList.add(prop);
9998 }
9999 }
10000 }
10001 else {
10002 // TODO(misko): Can't import RendererStyleFlags2.DashCase as it causes imports to be resolved in
10003 // different order which causes failures. Using direct constant as workaround for now.
10004 var flags = prop.indexOf('-') == -1 ? undefined : 2 /* RendererStyleFlags2.DashCase */;
10005 if (value == null /** || value === undefined */) {
10006 ngDevMode && ngDevMode.rendererRemoveStyle++;
10007 if (isProcedural) {
10008 renderer.removeStyle(rNode, prop, flags);
10009 }
10010 else {
10011 rNode.style.removeProperty(prop);
10012 }
10013 }
10014 else {
10015 ngDevMode && ngDevMode.rendererSetStyle++;
10016 if (isProcedural) {
10017 renderer.setStyle(rNode, prop, value, flags);
10018 }
10019 else {
10020 ngDevMode && assertDefined(rNode.style, 'HTMLElement expected');
10021 rNode.style.setProperty(prop, value);
10022 }
10023 }
10024 }
10025 }
10026 /**
10027 * Write `cssText` to `RElement`.
10028 *
10029 * This function does direct write without any reconciliation. Used for writing initial values, so
10030 * that static styling values do not pull in the style parser.
10031 *
10032 * @param renderer Renderer to use
10033 * @param element The element which needs to be updated.
10034 * @param newValue The new class list to write.
10035 */
10036 function writeDirectStyle(renderer, element, newValue) {
10037 ngDevMode && assertString(newValue, '\'newValue\' should be a string');
10038 if (isProceduralRenderer(renderer)) {
10039 renderer.setAttribute(element, 'style', newValue);
10040 }
10041 else {
10042 element.style.cssText = newValue;
10043 }
10044 ngDevMode && ngDevMode.rendererSetStyle++;
10045 }
10046 /**
10047 * Write `className` to `RElement`.
10048 *
10049 * This function does direct write without any reconciliation. Used for writing initial values, so
10050 * that static styling values do not pull in the style parser.
10051 *
10052 * @param renderer Renderer to use
10053 * @param element The element which needs to be updated.
10054 * @param newValue The new class list to write.
10055 */
10056 function writeDirectClass(renderer, element, newValue) {
10057 ngDevMode && assertString(newValue, '\'newValue\' should be a string');
10058 if (isProceduralRenderer(renderer)) {
10059 if (newValue === '') {
10060 // There are tests in `google3` which expect `element.getAttribute('class')` to be `null`.
10061 renderer.removeAttribute(element, 'class');
10062 }
10063 else {
10064 renderer.setAttribute(element, 'class', newValue);
10065 }
10066 }
10067 else {
10068 element.className = newValue;
10069 }
10070 ngDevMode && ngDevMode.rendererSetClassName++;
10071 }
10072
10073 /**
10074 * @license
10075 * Copyright Google LLC All Rights Reserved.
10076 *
10077 * Use of this source code is governed by an MIT-style license that can be
10078 * found in the LICENSE file at https://angular.io/license
10079 */
10080 /**
10081 * If `startTNode.parent` exists and has an injector, returns TNode for that injector.
10082 * Otherwise, unwraps a parent injector location number to find the view offset from the current
10083 * injector, then walks up the declaration view tree until the TNode of the parent injector is
10084 * found.
10085 *
10086 * @param location The location of the parent injector, which contains the view offset
10087 * @param startView The LView instance from which to start walking up the view tree
10088 * @param startTNode The TNode instance of the starting element
10089 * @returns The TNode of the parent injector
10090 */
10091 function getParentInjectorTNode(location, startView, startTNode) {
10092 // If there is an injector on the parent TNode, retrieve the TNode for that injector.
10093 if (startTNode.parent && startTNode.parent.injectorIndex !== -1) {
10094 // view offset is 0
10095 var injectorIndex = startTNode.parent.injectorIndex;
10096 var tNode = startTNode.parent;
10097 // If tNode.injectorIndex === tNode.parent.injectorIndex, then the index belongs to a parent
10098 // injector.
10099 while (tNode.parent != null && injectorIndex == tNode.parent.injectorIndex) {
10100 tNode = tNode.parent;
10101 }
10102 return tNode;
10103 }
10104 var viewOffset = getParentInjectorViewOffset(location);
10105 // view offset is 1
10106 var parentView = startView;
10107 var parentTNode = startView[T_HOST];
10108 // view offset is superior to 1
10109 while (viewOffset > 1) {
10110 parentView = parentView[DECLARATION_VIEW];
10111 parentTNode = parentView[T_HOST];
10112 viewOffset--;
10113 }
10114 return parentTNode;
10115 }
10116
10117 var ViewRef = /** @class */ (function () {
10118 function ViewRef(
10119 /**
10120 * This represents `LView` associated with the component when ViewRef is a ChangeDetectorRef.
10121 *
10122 * When ViewRef is created for a dynamic component, this also represents the `LView` for the
10123 * component.
10124 *
10125 * For a "regular" ViewRef created for an embedded view, this is the `LView` for the embedded
10126 * view.
10127 *
10128 * @internal
10129 */
10130 _lView,
10131 /**
10132 * This represents the `LView` associated with the point where `ChangeDetectorRef` was
10133 * requested.
10134 *
10135 * This may be different from `_lView` if the `_cdRefInjectingView` is an embedded view.
10136 */
10137 _cdRefInjectingView) {
10138 this._lView = _lView;
10139 this._cdRefInjectingView = _cdRefInjectingView;
10140 this._appRef = null;
10141 this._viewContainerRef = null;
10142 }
10143 Object.defineProperty(ViewRef.prototype, "rootNodes", {
10144 get: function () {
10145 var lView = this._lView;
10146 if (lView[HOST] == null) {
10147 var hostTView = lView[T_HOST];
10148 return collectNativeNodes(lView[TVIEW], lView, hostTView.child, []);
10149 }
10150 return [];
10151 },
10152 enumerable: false,
10153 configurable: true
10154 });
10155 Object.defineProperty(ViewRef.prototype, "context", {
10156 get: function () {
10157 return this._lView[CONTEXT];
10158 },
10159 enumerable: false,
10160 configurable: true
10161 });
10162 Object.defineProperty(ViewRef.prototype, "destroyed", {
10163 get: function () {
10164 return (this._lView[FLAGS] & 256 /* Destroyed */) === 256 /* Destroyed */;
10165 },
10166 enumerable: false,
10167 configurable: true
10168 });
10169 ViewRef.prototype.destroy = function () {
10170 if (this._appRef) {
10171 this._appRef.detachView(this);
10172 }
10173 else if (this._viewContainerRef) {
10174 var index = this._viewContainerRef.indexOf(this);
10175 if (index > -1) {
10176 this._viewContainerRef.detach(index);
10177 }
10178 this._viewContainerRef = null;
10179 }
10180 destroyLView(this._lView[TVIEW], this._lView);
10181 };
10182 ViewRef.prototype.onDestroy = function (callback) {
10183 storeCleanupWithContext(this._lView[TVIEW], this._lView, null, callback);
10184 };
10185 /**
10186 * Marks a view and all of its ancestors dirty.
10187 *
10188 * It also triggers change detection by calling `scheduleTick` internally, which coalesces
10189 * multiple `markForCheck` calls to into one change detection run.
10190 *
10191 * This can be used to ensure an {@link ChangeDetectionStrategy#OnPush OnPush} component is
10192 * checked when it needs to be re-rendered but the two normal triggers haven't marked it
10193 * dirty (i.e. inputs haven't changed and events haven't fired in the view).
10194 *
10195 * <!-- TODO: Add a link to a chapter on OnPush components -->
10196 *
10197 * @usageNotes
10198 * ### Example
10199 *
10200 * ```typescript
10201 * @Component({
10202 * selector: 'my-app',
10203 * template: `Number of ticks: {{numberOfTicks}}`
10204 * changeDetection: ChangeDetectionStrategy.OnPush,
10205 * })
10206 * class AppComponent {
10207 * numberOfTicks = 0;
10208 *
10209 * constructor(private ref: ChangeDetectorRef) {
10210 * setInterval(() => {
10211 * this.numberOfTicks++;
10212 * // the following is required, otherwise the view will not be updated
10213 * this.ref.markForCheck();
10214 * }, 1000);
10215 * }
10216 * }
10217 * ```
10218 */
10219 ViewRef.prototype.markForCheck = function () {
10220 markViewDirty(this._cdRefInjectingView || this._lView);
10221 };
10222 /**
10223 * Detaches the view from the change detection tree.
10224 *
10225 * Detached views will not be checked during change detection runs until they are
10226 * re-attached, even if they are dirty. `detach` can be used in combination with
10227 * {@link ChangeDetectorRef#detectChanges detectChanges} to implement local change
10228 * detection checks.
10229 *
10230 * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
10231 * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
10232 *
10233 * @usageNotes
10234 * ### Example
10235 *
10236 * The following example defines a component with a large list of readonly data.
10237 * Imagine the data changes constantly, many times per second. For performance reasons,
10238 * we want to check and update the list every five seconds. We can do that by detaching
10239 * the component's change detector and doing a local check every five seconds.
10240 *
10241 * ```typescript
10242 * class DataProvider {
10243 * // in a real application the returned data will be different every time
10244 * get data() {
10245 * return [1,2,3,4,5];
10246 * }
10247 * }
10248 *
10249 * @Component({
10250 * selector: 'giant-list',
10251 * template: `
10252 * <li *ngFor="let d of dataProvider.data">Data {{d}}</li>
10253 * `,
10254 * })
10255 * class GiantList {
10256 * constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {
10257 * ref.detach();
10258 * setInterval(() => {
10259 * this.ref.detectChanges();
10260 * }, 5000);
10261 * }
10262 * }
10263 *
10264 * @Component({
10265 * selector: 'app',
10266 * providers: [DataProvider],
10267 * template: `
10268 * <giant-list><giant-list>
10269 * `,
10270 * })
10271 * class App {
10272 * }
10273 * ```
10274 */
10275 ViewRef.prototype.detach = function () {
10276 this._lView[FLAGS] &= ~128 /* Attached */;
10277 };
10278 /**
10279 * Re-attaches a view to the change detection tree.
10280 *
10281 * This can be used to re-attach views that were previously detached from the tree
10282 * using {@link ChangeDetectorRef#detach detach}. Views are attached to the tree by default.
10283 *
10284 * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
10285 *
10286 * @usageNotes
10287 * ### Example
10288 *
10289 * The following example creates a component displaying `live` data. The component will detach
10290 * its change detector from the main change detector tree when the component's live property
10291 * is set to false.
10292 *
10293 * ```typescript
10294 * class DataProvider {
10295 * data = 1;
10296 *
10297 * constructor() {
10298 * setInterval(() => {
10299 * this.data = this.data * 2;
10300 * }, 500);
10301 * }
10302 * }
10303 *
10304 * @Component({
10305 * selector: 'live-data',
10306 * inputs: ['live'],
10307 * template: 'Data: {{dataProvider.data}}'
10308 * })
10309 * class LiveData {
10310 * constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {}
10311 *
10312 * set live(value) {
10313 * if (value) {
10314 * this.ref.reattach();
10315 * } else {
10316 * this.ref.detach();
10317 * }
10318 * }
10319 * }
10320 *
10321 * @Component({
10322 * selector: 'my-app',
10323 * providers: [DataProvider],
10324 * template: `
10325 * Live Update: <input type="checkbox" [(ngModel)]="live">
10326 * <live-data [live]="live"><live-data>
10327 * `,
10328 * })
10329 * class AppComponent {
10330 * live = true;
10331 * }
10332 * ```
10333 */
10334 ViewRef.prototype.reattach = function () {
10335 this._lView[FLAGS] |= 128 /* Attached */;
10336 };
10337 /**
10338 * Checks the view and its children.
10339 *
10340 * This can also be used in combination with {@link ChangeDetectorRef#detach detach} to implement
10341 * local change detection checks.
10342 *
10343 * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
10344 * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
10345 *
10346 * @usageNotes
10347 * ### Example
10348 *
10349 * The following example defines a component with a large list of readonly data.
10350 * Imagine, the data changes constantly, many times per second. For performance reasons,
10351 * we want to check and update the list every five seconds.
10352 *
10353 * We can do that by detaching the component's change detector and doing a local change detection
10354 * check every five seconds.
10355 *
10356 * See {@link ChangeDetectorRef#detach detach} for more information.
10357 */
10358 ViewRef.prototype.detectChanges = function () {
10359 detectChangesInternal(this._lView[TVIEW], this._lView, this.context);
10360 };
10361 /**
10362 * Checks the change detector and its children, and throws if any changes are detected.
10363 *
10364 * This is used in development mode to verify that running change detection doesn't
10365 * introduce other changes.
10366 */
10367 ViewRef.prototype.checkNoChanges = function () {
10368 checkNoChangesInternal(this._lView[TVIEW], this._lView, this.context);
10369 };
10370 ViewRef.prototype.attachToViewContainerRef = function (vcRef) {
10371 if (this._appRef) {
10372 throw new Error('This view is already attached directly to the ApplicationRef!');
10373 }
10374 this._viewContainerRef = vcRef;
10375 };
10376 ViewRef.prototype.detachFromAppRef = function () {
10377 this._appRef = null;
10378 renderDetachView(this._lView[TVIEW], this._lView);
10379 };
10380 ViewRef.prototype.attachToAppRef = function (appRef) {
10381 if (this._viewContainerRef) {
10382 throw new Error('This view is already attached to a ViewContainer!');
10383 }
10384 this._appRef = appRef;
10385 };
10386 return ViewRef;
10387 }());
10388 /** @internal */
10389 var RootViewRef = /** @class */ (function (_super) {
10390 __extends(RootViewRef, _super);
10391 function RootViewRef(_view) {
10392 var _this = _super.call(this, _view) || this;
10393 _this._view = _view;
10394 return _this;
10395 }
10396 RootViewRef.prototype.detectChanges = function () {
10397 detectChangesInRootView(this._view);
10398 };
10399 RootViewRef.prototype.checkNoChanges = function () {
10400 checkNoChangesInRootView(this._view);
10401 };
10402 Object.defineProperty(RootViewRef.prototype, "context", {
10403 get: function () {
10404 return null;
10405 },
10406 enumerable: false,
10407 configurable: true
10408 });
10409 return RootViewRef;
10410 }(ViewRef));
10411 function collectNativeNodes(tView, lView, tNode, result, isProjection) {
10412 if (isProjection === void 0) { isProjection = false; }
10413 while (tNode !== null) {
10414 ngDevMode && assertNodeOfPossibleTypes(tNode, [
10415 3 /* Element */, 0 /* Container */, 1 /* Projection */, 4 /* ElementContainer */,
10416 5 /* IcuContainer */
10417 ]);
10418 var lNode = lView[tNode.index];
10419 if (lNode !== null) {
10420 result.push(unwrapRNode(lNode));
10421 }
10422 // A given lNode can represent either a native node or a LContainer (when it is a host of a
10423 // ViewContainerRef). When we find a LContainer we need to descend into it to collect root nodes
10424 // from the views in this container.
10425 if (isLContainer(lNode)) {
10426 for (var i = CONTAINER_HEADER_OFFSET; i < lNode.length; i++) {
10427 var lViewInAContainer = lNode[i];
10428 var lViewFirstChildTNode = lViewInAContainer[TVIEW].firstChild;
10429 if (lViewFirstChildTNode !== null) {
10430 collectNativeNodes(lViewInAContainer[TVIEW], lViewInAContainer, lViewFirstChildTNode, result);
10431 }
10432 }
10433 }
10434 var tNodeType = tNode.type;
10435 if (tNodeType === 4 /* ElementContainer */ || tNodeType === 5 /* IcuContainer */) {
10436 collectNativeNodes(tView, lView, tNode.child, result);
10437 }
10438 else if (tNodeType === 1 /* Projection */) {
10439 var componentView = lView[DECLARATION_COMPONENT_VIEW];
10440 var componentHost = componentView[T_HOST];
10441 var slotIdx = tNode.projection;
10442 ngDevMode &&
10443 assertDefined(componentHost.projection, 'Components with projection nodes (<ng-content>) must have projection slots defined.');
10444 var nodesInSlot = componentHost.projection[slotIdx];
10445 if (Array.isArray(nodesInSlot)) {
10446 result.push.apply(result, __spread(nodesInSlot));
10447 }
10448 else {
10449 var parentView = getLViewParent(componentView);
10450 ngDevMode &&
10451 assertDefined(parentView, 'Component views should always have a parent view (component\'s host view)');
10452 collectNativeNodes(parentView[TVIEW], parentView, nodesInSlot, result, true);
10453 }
10454 }
10455 tNode = isProjection ? tNode.projectionNext : tNode.next;
10456 }
10457 return result;
10458 }
10459
10460 /**
10461 * Creates an ElementRef from the most recent node.
10462 *
10463 * @returns The ElementRef instance to use
10464 */
10465 function injectElementRef(ElementRefToken) {
10466 return createElementRef(ElementRefToken, getPreviousOrParentTNode(), getLView());
10467 }
10468 var R3ElementRef;
10469 /**
10470 * Creates an ElementRef given a node.
10471 *
10472 * @param ElementRefToken The ElementRef type
10473 * @param tNode The node for which you'd like an ElementRef
10474 * @param view The view to which the node belongs
10475 * @returns The ElementRef instance to use
10476 */
10477 function createElementRef(ElementRefToken, tNode, view) {
10478 if (!R3ElementRef) {
10479 R3ElementRef = /** @class */ (function (_super) {
10480 __extends(ElementRef, _super);
10481 function ElementRef() {
10482 return _super !== null && _super.apply(this, arguments) || this;
10483 }
10484 return ElementRef;
10485 }(ElementRefToken));
10486 }
10487 return new R3ElementRef(getNativeByTNode(tNode, view));
10488 }
10489 var R3TemplateRef;
10490 /**
10491 * Creates a TemplateRef given a node.
10492 *
10493 * @returns The TemplateRef instance to use
10494 */
10495 function injectTemplateRef(TemplateRefToken, ElementRefToken) {
10496 return createTemplateRef(TemplateRefToken, ElementRefToken, getPreviousOrParentTNode(), getLView());
10497 }
10498 /**
10499 * Creates a TemplateRef and stores it on the injector.
10500 *
10501 * @param TemplateRefToken The TemplateRef type
10502 * @param ElementRefToken The ElementRef type
10503 * @param hostTNode The node on which a TemplateRef is requested
10504 * @param hostView The view to which the node belongs
10505 * @returns The TemplateRef instance or null if we can't create a TemplateRef on a given node type
10506 */
10507 function createTemplateRef(TemplateRefToken, ElementRefToken, hostTNode, hostView) {
10508 if (!R3TemplateRef) {
10509 R3TemplateRef = /** @class */ (function (_super) {
10510 __extends(TemplateRef, _super);
10511 function TemplateRef(_declarationView, _declarationTContainer, elementRef) {
10512 var _this = _super.call(this) || this;
10513 _this._declarationView = _declarationView;
10514 _this._declarationTContainer = _declarationTContainer;
10515 _this.elementRef = elementRef;
10516 return _this;
10517 }
10518 TemplateRef.prototype.createEmbeddedView = function (context) {
10519 var embeddedTView = this._declarationTContainer.tViews;
10520 var embeddedLView = createLView(this._declarationView, embeddedTView, context, 16 /* CheckAlways */, null, embeddedTView.node);
10521 var declarationLContainer = this._declarationView[this._declarationTContainer.index];
10522 ngDevMode && assertLContainer(declarationLContainer);
10523 embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
10524 var declarationViewLQueries = this._declarationView[QUERIES];
10525 if (declarationViewLQueries !== null) {
10526 embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
10527 }
10528 renderView(embeddedTView, embeddedLView, context);
10529 return new ViewRef(embeddedLView);
10530 };
10531 return TemplateRef;
10532 }(TemplateRefToken));
10533 }
10534 if (hostTNode.type === 0 /* Container */) {
10535 ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
10536 return new R3TemplateRef(hostView, hostTNode, createElementRef(ElementRefToken, hostTNode, hostView));
10537 }
10538 else {
10539 return null;
10540 }
10541 }
10542 var R3ViewContainerRef;
10543 /**
10544 * Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
10545 * already exists, retrieves the existing ViewContainerRef.
10546 *
10547 * @returns The ViewContainerRef instance to use
10548 */
10549 function injectViewContainerRef(ViewContainerRefToken, ElementRefToken) {
10550 var previousTNode = getPreviousOrParentTNode();
10551 return createContainerRef(ViewContainerRefToken, ElementRefToken, previousTNode, getLView());
10552 }
10553 /**
10554 * Creates a ViewContainerRef and stores it on the injector.
10555 *
10556 * @param ViewContainerRefToken The ViewContainerRef type
10557 * @param ElementRefToken The ElementRef type
10558 * @param hostTNode The node that is requesting a ViewContainerRef
10559 * @param hostView The view to which the node belongs
10560 * @returns The ViewContainerRef instance to use
10561 */
10562 function createContainerRef(ViewContainerRefToken, ElementRefToken, hostTNode, hostView) {
10563 if (!R3ViewContainerRef) {
10564 R3ViewContainerRef = /** @class */ (function (_super) {
10565 __extends(ViewContainerRef, _super);
10566 function ViewContainerRef(_lContainer, _hostTNode, _hostView) {
10567 var _this = _super.call(this) || this;
10568 _this._lContainer = _lContainer;
10569 _this._hostTNode = _hostTNode;
10570 _this._hostView = _hostView;
10571 return _this;
10572 }
10573 Object.defineProperty(ViewContainerRef.prototype, "element", {
10574 get: function () {
10575 return createElementRef(ElementRefToken, this._hostTNode, this._hostView);
10576 },
10577 enumerable: false,
10578 configurable: true
10579 });
10580 Object.defineProperty(ViewContainerRef.prototype, "injector", {
10581 get: function () {
10582 return new NodeInjector(this._hostTNode, this._hostView);
10583 },
10584 enumerable: false,
10585 configurable: true
10586 });
10587 Object.defineProperty(ViewContainerRef.prototype, "parentInjector", {
10588 /** @deprecated No replacement */
10589 get: function () {
10590 var parentLocation = getParentInjectorLocation(this._hostTNode, this._hostView);
10591 var parentView = getParentInjectorView(parentLocation, this._hostView);
10592 var parentTNode = getParentInjectorTNode(parentLocation, this._hostView, this._hostTNode);
10593 return !hasParentInjector(parentLocation) || parentTNode == null ?
10594 new NodeInjector(null, this._hostView) :
10595 new NodeInjector(parentTNode, parentView);
10596 },
10597 enumerable: false,
10598 configurable: true
10599 });
10600 ViewContainerRef.prototype.clear = function () {
10601 while (this.length > 0) {
10602 this.remove(this.length - 1);
10603 }
10604 };
10605 ViewContainerRef.prototype.get = function (index) {
10606 return this._lContainer[VIEW_REFS] !== null && this._lContainer[VIEW_REFS][index] || null;
10607 };
10608 Object.defineProperty(ViewContainerRef.prototype, "length", {
10609 get: function () {
10610 return this._lContainer.length - CONTAINER_HEADER_OFFSET;
10611 },
10612 enumerable: false,
10613 configurable: true
10614 });
10615 ViewContainerRef.prototype.createEmbeddedView = function (templateRef, context, index) {
10616 var viewRef = templateRef.createEmbeddedView(context || {});
10617 this.insert(viewRef, index);
10618 return viewRef;
10619 };
10620 ViewContainerRef.prototype.createComponent = function (componentFactory, index, injector, projectableNodes, ngModuleRef) {
10621 var contextInjector = injector || this.parentInjector;
10622 if (!ngModuleRef && componentFactory.ngModule == null && contextInjector) {
10623 // DO NOT REFACTOR. The code here used to have a `value || undefined` expression
10624 // which seems to cause internal google apps to fail. This is documented in the
10625 // following internal bug issue: go/b/142967802
10626 var result = contextInjector.get(NgModuleRef, null);
10627 if (result) {
10628 ngModuleRef = result;
10629 }
10630 }
10631 var componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
10632 this.insert(componentRef.hostView, index);
10633 return componentRef;
10634 };
10635 ViewContainerRef.prototype.insert = function (viewRef, index) {
10636 var lView = viewRef._lView;
10637 var tView = lView[TVIEW];
10638 if (viewRef.destroyed) {
10639 throw new Error('Cannot insert a destroyed View in a ViewContainer!');
10640 }
10641 this.allocateContainerIfNeeded();
10642 if (viewAttachedToContainer(lView)) {
10643 // If view is already attached, detach it first so we clean up references appropriately.
10644 var prevIdx = this.indexOf(viewRef);
10645 // A view might be attached either to this or a different container. The `prevIdx` for
10646 // those cases will be:
10647 // equal to -1 for views attached to this ViewContainerRef
10648 // >= 0 for views attached to a different ViewContainerRef
10649 if (prevIdx !== -1) {
10650 this.detach(prevIdx);
10651 }
10652 else {
10653 var prevLContainer = lView[PARENT];
10654 ngDevMode &&
10655 assertEqual(isLContainer(prevLContainer), true, 'An attached view should have its PARENT point to a container.');
10656 // We need to re-create a R3ViewContainerRef instance since those are not stored on
10657 // LView (nor anywhere else).
10658 var prevVCRef = new R3ViewContainerRef(prevLContainer, prevLContainer[T_HOST], prevLContainer[PARENT]);
10659 prevVCRef.detach(prevVCRef.indexOf(viewRef));
10660 }
10661 }
10662 var adjustedIdx = this._adjustIndex(index);
10663 insertView(tView, lView, this._lContainer, adjustedIdx);
10664 var beforeNode = getBeforeNodeForView(adjustedIdx, this._lContainer);
10665 addRemoveViewFromContainer(tView, lView, true, beforeNode);
10666 viewRef.attachToViewContainerRef(this);
10667 addToArray(this._lContainer[VIEW_REFS], adjustedIdx, viewRef);
10668 return viewRef;
10669 };
10670 ViewContainerRef.prototype.move = function (viewRef, newIndex) {
10671 if (viewRef.destroyed) {
10672 throw new Error('Cannot move a destroyed View in a ViewContainer!');
10673 }
10674 return this.insert(viewRef, newIndex);
10675 };
10676 ViewContainerRef.prototype.indexOf = function (viewRef) {
10677 var viewRefsArr = this._lContainer[VIEW_REFS];
10678 return viewRefsArr !== null ? viewRefsArr.indexOf(viewRef) : -1;
10679 };
10680 ViewContainerRef.prototype.remove = function (index) {
10681 this.allocateContainerIfNeeded();
10682 var adjustedIdx = this._adjustIndex(index, -1);
10683 var detachedView = detachView(this._lContainer, adjustedIdx);
10684 if (detachedView) {
10685 // Before destroying the view, remove it from the container's array of `ViewRef`s.
10686 // This ensures the view container length is updated before calling
10687 // `destroyLView`, which could recursively call view container methods that
10688 // rely on an accurate container length.
10689 // (e.g. a method on this view container being called by a child directive's OnDestroy
10690 // lifecycle hook)
10691 removeFromArray(this._lContainer[VIEW_REFS], adjustedIdx);
10692 destroyLView(detachedView[TVIEW], detachedView);
10693 }
10694 };
10695 ViewContainerRef.prototype.detach = function (index) {
10696 this.allocateContainerIfNeeded();
10697 var adjustedIdx = this._adjustIndex(index, -1);
10698 var view = detachView(this._lContainer, adjustedIdx);
10699 var wasDetached = view && removeFromArray(this._lContainer[VIEW_REFS], adjustedIdx) != null;
10700 return wasDetached ? new ViewRef(view) : null;
10701 };
10702 ViewContainerRef.prototype._adjustIndex = function (index, shift) {
10703 if (shift === void 0) { shift = 0; }
10704 if (index == null) {
10705 return this.length + shift;
10706 }
10707 if (ngDevMode) {
10708 assertGreaterThan(index, -1, "ViewRef index must be positive, got " + index);
10709 // +1 because it's legal to insert at the end.
10710 assertLessThan(index, this.length + 1 + shift, 'index');
10711 }
10712 return index;
10713 };
10714 ViewContainerRef.prototype.allocateContainerIfNeeded = function () {
10715 if (this._lContainer[VIEW_REFS] === null) {
10716 this._lContainer[VIEW_REFS] = [];
10717 }
10718 };
10719 return ViewContainerRef;
10720 }(ViewContainerRefToken));
10721 }
10722 ngDevMode &&
10723 assertNodeOfPossibleTypes(hostTNode, [0 /* Container */, 3 /* Element */, 4 /* ElementContainer */]);
10724 var lContainer;
10725 var slotValue = hostView[hostTNode.index];
10726 if (isLContainer(slotValue)) {
10727 // If the host is a container, we don't need to create a new LContainer
10728 lContainer = slotValue;
10729 }
10730 else {
10731 var commentNode = void 0;
10732 // If the host is an element container, the native host element is guaranteed to be a
10733 // comment and we can reuse that comment as anchor element for the new LContainer.
10734 // The comment node in question is already part of the DOM structure so we don't need to append
10735 // it again.
10736 if (hostTNode.type === 4 /* ElementContainer */) {
10737 commentNode = unwrapRNode(slotValue);
10738 }
10739 else {
10740 ngDevMode && ngDevMode.rendererCreateComment++;
10741 commentNode = hostView[RENDERER].createComment(ngDevMode ? 'container' : '');
10742 // A `ViewContainerRef` can be injected by the root (topmost / bootstrapped) component. In
10743 // this case we can't use TView / TNode data structures to insert container's marker node
10744 // (both a parent of a comment node and the comment node itself are not part of any view). In
10745 // this specific case we use low-level DOM manipulation to insert container's marker (comment)
10746 // node.
10747 if (isRootView(hostView)) {
10748 var renderer = hostView[RENDERER];
10749 var hostNative = getNativeByTNode(hostTNode, hostView);
10750 var parentOfHostNative = nativeParentNode(renderer, hostNative);
10751 nativeInsertBefore(renderer, parentOfHostNative, commentNode, nativeNextSibling(renderer, hostNative));
10752 }
10753 else {
10754 appendChild(hostView[TVIEW], hostView, commentNode, hostTNode);
10755 }
10756 }
10757 hostView[hostTNode.index] = lContainer =
10758 createLContainer(slotValue, hostView, commentNode, hostTNode);
10759 addToViewTree(hostView, lContainer);
10760 }
10761 return new R3ViewContainerRef(lContainer, hostTNode, hostView);
10762 }
10763 /** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
10764 function injectChangeDetectorRef(isPipe) {
10765 if (isPipe === void 0) { isPipe = false; }
10766 return createViewRef(getPreviousOrParentTNode(), getLView(), isPipe);
10767 }
10768 /**
10769 * Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
10770 *
10771 * @param tNode The node that is requesting a ChangeDetectorRef
10772 * @param lView The view to which the node belongs
10773 * @param isPipe Whether the view is being injected into a pipe.
10774 * @returns The ChangeDetectorRef to use
10775 */
10776 function createViewRef(tNode, lView, isPipe) {
10777 // `isComponentView` will be true for Component and Directives (but not for Pipes).
10778 // See https://github.com/angular/angular/pull/33072 for proper fix
10779 var isComponentView = !isPipe && isComponentHost(tNode);
10780 if (isComponentView) {
10781 // The LView represents the location where the component is declared.
10782 // Instead we want the LView for the component View and so we need to look it up.
10783 var componentView = getComponentLViewByIndex(tNode.index, lView); // look down
10784 return new ViewRef(componentView, componentView);
10785 }
10786 else if (tNode.type === 3 /* Element */ || tNode.type === 0 /* Container */ ||
10787 tNode.type === 4 /* ElementContainer */ || tNode.type === 5 /* IcuContainer */) {
10788 // The LView represents the location where the injection is requested from.
10789 // We need to locate the containing LView (in case where the `lView` is an embedded view)
10790 var hostComponentView = lView[DECLARATION_COMPONENT_VIEW]; // look up
10791 return new ViewRef(hostComponentView, lView);
10792 }
10793 return null;
10794 }
10795 /** Returns a Renderer2 (or throws when application was bootstrapped with Renderer3) */
10796 function getOrCreateRenderer2(view) {
10797 var renderer = view[RENDERER];
10798 if (isProceduralRenderer(renderer)) {
10799 return renderer;
10800 }
10801 else {
10802 throw new Error('Cannot inject Renderer2 when the application uses Renderer3!');
10803 }
10804 }
10805 /** Injects a Renderer2 for the current component. */
10806 function injectRenderer2() {
10807 // We need the Renderer to be based on the component that it's being injected into, however since
10808 // DI happens before we've entered its view, `getLView` will return the parent view instead.
10809 var lView = getLView();
10810 var tNode = getPreviousOrParentTNode();
10811 var nodeAtIndex = getComponentLViewByIndex(tNode.index, lView);
10812 return getOrCreateRenderer2(isLView(nodeAtIndex) ? nodeAtIndex : lView);
10813 }
10814
10815 /**
10816 * @license
10817 * Copyright Google LLC All Rights Reserved.
10818 *
10819 * Use of this source code is governed by an MIT-style license that can be
10820 * found in the LICENSE file at https://angular.io/license
10821 */
10822 /**
10823 * Base class that provides change detection functionality.
10824 * A change-detection tree collects all views that are to be checked for changes.
10825 * Use the methods to add and remove views from the tree, initiate change-detection,
10826 * and explicitly mark views as _dirty_, meaning that they have changed and need to be re-rendered.
10827 *
10828 * @see [Using change detection hooks](guide/lifecycle-hooks#using-change-detection-hooks)
10829 * @see [Defining custom change detection](guide/lifecycle-hooks#defining-custom-change-detection)
10830 *
10831 * @usageNotes
10832 *
10833 * The following examples demonstrate how to modify default change-detection behavior
10834 * to perform explicit detection when needed.
10835 *
10836 * ### Use `markForCheck()` with `CheckOnce` strategy
10837 *
10838 * The following example sets the `OnPush` change-detection strategy for a component
10839 * (`CheckOnce`, rather than the default `CheckAlways`), then forces a second check
10840 * after an interval. See [live demo](http://plnkr.co/edit/GC512b?p=preview).
10841 *
10842 * <code-example path="core/ts/change_detect/change-detection.ts"
10843 * region="mark-for-check"></code-example>
10844 *
10845 * ### Detach change detector to limit how often check occurs
10846 *
10847 * The following example defines a component with a large list of read-only data
10848 * that is expected to change constantly, many times per second.
10849 * To improve performance, we want to check and update the list
10850 * less often than the changes actually occur. To do that, we detach
10851 * the component's change detector and perform an explicit local check every five seconds.
10852 *
10853 * <code-example path="core/ts/change_detect/change-detection.ts" region="detach"></code-example>
10854 *
10855 *
10856 * ### Reattaching a detached component
10857 *
10858 * The following example creates a component displaying live data.
10859 * The component detaches its change detector from the main change detector tree
10860 * when the `live` property is set to false, and reattaches it when the property
10861 * becomes true.
10862 *
10863 * <code-example path="core/ts/change_detect/change-detection.ts" region="reattach"></code-example>
10864 *
10865 * @publicApi
10866 */
10867 var ChangeDetectorRef = /** @class */ (function () {
10868 function ChangeDetectorRef() {
10869 }
10870 return ChangeDetectorRef;
10871 }());
10872 /**
10873 * @internal
10874 * @nocollapse
10875 */
10876 ChangeDetectorRef.__NG_ELEMENT_ID__ = function () { return SWITCH_CHANGE_DETECTOR_REF_FACTORY(); };
10877 var SWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__ = injectChangeDetectorRef;
10878 var SWITCH_CHANGE_DETECTOR_REF_FACTORY__PRE_R3__ = function () {
10879 var args = [];
10880 for (var _i = 0; _i < arguments.length; _i++) {
10881 args[_i] = arguments[_i];
10882 }
10883 };
10884 var ɵ0$5 = SWITCH_CHANGE_DETECTOR_REF_FACTORY__PRE_R3__;
10885 var SWITCH_CHANGE_DETECTOR_REF_FACTORY = SWITCH_CHANGE_DETECTOR_REF_FACTORY__PRE_R3__;
10886
10887 /**
10888 * @license
10889 * Copyright Google LLC All Rights Reserved.
10890 *
10891 * Use of this source code is governed by an MIT-style license that can be
10892 * found in the LICENSE file at https://angular.io/license
10893 */
10894 /**
10895 * @description
10896 *
10897 * Represents a type that a Component or other object is instances of.
10898 *
10899 * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is represented by
10900 * the `MyCustomComponent` constructor function.
10901 *
10902 * @publicApi
10903 */
10904 var Type = Function;
10905 function isType(v) {
10906 return typeof v === 'function';
10907 }
10908
10909 /*
10910 * #########################
10911 * Attention: These Regular expressions have to hold even if the code is minified!
10912 * ##########################
10913 */
10914 /**
10915 * Regular expression that detects pass-through constructors for ES5 output. This Regex
10916 * intends to capture the common delegation pattern emitted by TypeScript and Babel. Also
10917 * it intends to capture the pattern where existing constructors have been downleveled from
10918 * ES2015 to ES5 using TypeScript w/ downlevel iteration. e.g.
10919 *
10920 * ```
10921 * function MyClass() {
10922 * var _this = _super.apply(this, arguments) || this;
10923 * ```
10924 *
10925 * ```
10926 * function MyClass() {
10927 * var _this = _super.apply(this, __spread(arguments)) || this;
10928 * ```
10929 *
10930 * More details can be found in: https://github.com/angular/angular/issues/38453.
10931 */
10932 var ES5_DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*(arguments|[^()]+\(arguments\))\)/;
10933 /** Regular expression that detects ES2015 classes which extend from other classes. */
10934 var ES2015_INHERITED_CLASS = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{/;
10935 /**
10936 * Regular expression that detects ES2015 classes which extend from other classes and
10937 * have an explicit constructor defined.
10938 */
10939 var ES2015_INHERITED_CLASS_WITH_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(/;
10940 /**
10941 * Regular expression that detects ES2015 classes which extend from other classes
10942 * and inherit a constructor.
10943 */
10944 var ES2015_INHERITED_CLASS_WITH_DELEGATE_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(\)\s*{\s*super\(\.\.\.arguments\)/;
10945 /**
10946 * Determine whether a stringified type is a class which delegates its constructor
10947 * to its parent.
10948 *
10949 * This is not trivial since compiled code can actually contain a constructor function
10950 * even if the original source code did not. For instance, when the child class contains
10951 * an initialized instance property.
10952 */
10953 function isDelegateCtor(typeStr) {
10954 return ES5_DELEGATE_CTOR.test(typeStr) ||
10955 ES2015_INHERITED_CLASS_WITH_DELEGATE_CTOR.test(typeStr) ||
10956 (ES2015_INHERITED_CLASS.test(typeStr) && !ES2015_INHERITED_CLASS_WITH_CTOR.test(typeStr));
10957 }
10958 var ReflectionCapabilities = /** @class */ (function () {
10959 function ReflectionCapabilities(reflect) {
10960 this._reflect = reflect || _global['Reflect'];
10961 }
10962 ReflectionCapabilities.prototype.isReflectionEnabled = function () {
10963 return true;
10964 };
10965 ReflectionCapabilities.prototype.factory = function (t) {
10966 return function () {
10967 var args = [];
10968 for (var _i = 0; _i < arguments.length; _i++) {
10969 args[_i] = arguments[_i];
10970 }
10971 return new (t.bind.apply(t, __spread([void 0], args)))();
10972 };
10973 };
10974 /** @internal */
10975 ReflectionCapabilities.prototype._zipTypesAndAnnotations = function (paramTypes, paramAnnotations) {
10976 var result;
10977 if (typeof paramTypes === 'undefined') {
10978 result = newArray(paramAnnotations.length);
10979 }
10980 else {
10981 result = newArray(paramTypes.length);
10982 }
10983 for (var i = 0; i < result.length; i++) {
10984 // TS outputs Object for parameters without types, while Traceur omits
10985 // the annotations. For now we preserve the Traceur behavior to aid
10986 // migration, but this can be revisited.
10987 if (typeof paramTypes === 'undefined') {
10988 result[i] = [];
10989 }
10990 else if (paramTypes[i] && paramTypes[i] != Object) {
10991 result[i] = [paramTypes[i]];
10992 }
10993 else {
10994 result[i] = [];
10995 }
10996 if (paramAnnotations && paramAnnotations[i] != null) {
10997 result[i] = result[i].concat(paramAnnotations[i]);
10998 }
10999 }
11000 return result;
11001 };
11002 ReflectionCapabilities.prototype._ownParameters = function (type, parentCtor) {
11003 var typeStr = type.toString();
11004 // If we have no decorators, we only have function.length as metadata.
11005 // In that case, to detect whether a child class declared an own constructor or not,
11006 // we need to look inside of that constructor to check whether it is
11007 // just calling the parent.
11008 // This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
11009 // that sets 'design:paramtypes' to []
11010 // if a class inherits from another class but has no ctor declared itself.
11011 if (isDelegateCtor(typeStr)) {
11012 return null;
11013 }
11014 // Prefer the direct API.
11015 if (type.parameters && type.parameters !== parentCtor.parameters) {
11016 return type.parameters;
11017 }
11018 // API of tsickle for lowering decorators to properties on the class.
11019 var tsickleCtorParams = type.ctorParameters;
11020 if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
11021 // Newer tsickle uses a function closure
11022 // Retain the non-function case for compatibility with older tsickle
11023 var ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
11024 var paramTypes_1 = ctorParameters.map(function (ctorParam) { return ctorParam && ctorParam.type; });
11025 var paramAnnotations_1 = ctorParameters.map(function (ctorParam) { return ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators); });
11026 return this._zipTypesAndAnnotations(paramTypes_1, paramAnnotations_1);
11027 }
11028 // API for metadata created by invoking the decorators.
11029 var paramAnnotations = type.hasOwnProperty(PARAMETERS) && type[PARAMETERS];
11030 var paramTypes = this._reflect && this._reflect.getOwnMetadata &&
11031 this._reflect.getOwnMetadata('design:paramtypes', type);
11032 if (paramTypes || paramAnnotations) {
11033 return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
11034 }
11035 // If a class has no decorators, at least create metadata
11036 // based on function.length.
11037 // Note: We know that this is a real constructor as we checked
11038 // the content of the constructor above.
11039 return newArray(type.length);
11040 };
11041 ReflectionCapabilities.prototype.parameters = function (type) {
11042 // Note: only report metadata if we have at least one class decorator
11043 // to stay in sync with the static reflector.
11044 if (!isType(type)) {
11045 return [];
11046 }
11047 var parentCtor = getParentCtor(type);
11048 var parameters = this._ownParameters(type, parentCtor);
11049 if (!parameters && parentCtor !== Object) {
11050 parameters = this.parameters(parentCtor);
11051 }
11052 return parameters || [];
11053 };
11054 ReflectionCapabilities.prototype._ownAnnotations = function (typeOrFunc, parentCtor) {
11055 // Prefer the direct API.
11056 if (typeOrFunc.annotations && typeOrFunc.annotations !== parentCtor.annotations) {
11057 var annotations = typeOrFunc.annotations;
11058 if (typeof annotations === 'function' && annotations.annotations) {
11059 annotations = annotations.annotations;
11060 }
11061 return annotations;
11062 }
11063 // API of tsickle for lowering decorators to properties on the class.
11064 if (typeOrFunc.decorators && typeOrFunc.decorators !== parentCtor.decorators) {
11065 return convertTsickleDecoratorIntoMetadata(typeOrFunc.decorators);
11066 }
11067 // API for metadata created by invoking the decorators.
11068 if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {
11069 return typeOrFunc[ANNOTATIONS];
11070 }
11071 return null;
11072 };
11073 ReflectionCapabilities.prototype.annotations = function (typeOrFunc) {
11074 if (!isType(typeOrFunc)) {
11075 return [];
11076 }
11077 var parentCtor = getParentCtor(typeOrFunc);
11078 var ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
11079 var parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
11080 return parentAnnotations.concat(ownAnnotations);
11081 };
11082 ReflectionCapabilities.prototype._ownPropMetadata = function (typeOrFunc, parentCtor) {
11083 // Prefer the direct API.
11084 if (typeOrFunc.propMetadata &&
11085 typeOrFunc.propMetadata !== parentCtor.propMetadata) {
11086 var propMetadata = typeOrFunc.propMetadata;
11087 if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
11088 propMetadata = propMetadata.propMetadata;
11089 }
11090 return propMetadata;
11091 }
11092 // API of tsickle for lowering decorators to properties on the class.
11093 if (typeOrFunc.propDecorators &&
11094 typeOrFunc.propDecorators !== parentCtor.propDecorators) {
11095 var propDecorators_1 = typeOrFunc.propDecorators;
11096 var propMetadata_1 = {};
11097 Object.keys(propDecorators_1).forEach(function (prop) {
11098 propMetadata_1[prop] = convertTsickleDecoratorIntoMetadata(propDecorators_1[prop]);
11099 });
11100 return propMetadata_1;
11101 }
11102 // API for metadata created by invoking the decorators.
11103 if (typeOrFunc.hasOwnProperty(PROP_METADATA)) {
11104 return typeOrFunc[PROP_METADATA];
11105 }
11106 return null;
11107 };
11108 ReflectionCapabilities.prototype.propMetadata = function (typeOrFunc) {
11109 if (!isType(typeOrFunc)) {
11110 return {};
11111 }
11112 var parentCtor = getParentCtor(typeOrFunc);
11113 var propMetadata = {};
11114 if (parentCtor !== Object) {
11115 var parentPropMetadata_1 = this.propMetadata(parentCtor);
11116 Object.keys(parentPropMetadata_1).forEach(function (propName) {
11117 propMetadata[propName] = parentPropMetadata_1[propName];
11118 });
11119 }
11120 var ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
11121 if (ownPropMetadata) {
11122 Object.keys(ownPropMetadata).forEach(function (propName) {
11123 var decorators = [];
11124 if (propMetadata.hasOwnProperty(propName)) {
11125 decorators.push.apply(decorators, __spread(propMetadata[propName]));
11126 }
11127 decorators.push.apply(decorators, __spread(ownPropMetadata[propName]));
11128 propMetadata[propName] = decorators;
11129 });
11130 }
11131 return propMetadata;
11132 };
11133 ReflectionCapabilities.prototype.ownPropMetadata = function (typeOrFunc) {
11134 if (!isType(typeOrFunc)) {
11135 return {};
11136 }
11137 return this._ownPropMetadata(typeOrFunc, getParentCtor(typeOrFunc)) || {};
11138 };
11139 ReflectionCapabilities.prototype.hasLifecycleHook = function (type, lcProperty) {
11140 return type instanceof Type && lcProperty in type.prototype;
11141 };
11142 ReflectionCapabilities.prototype.guards = function (type) {
11143 return {};
11144 };
11145 ReflectionCapabilities.prototype.getter = function (name) {
11146 return new Function('o', 'return o.' + name + ';');
11147 };
11148 ReflectionCapabilities.prototype.setter = function (name) {
11149 return new Function('o', 'v', 'return o.' + name + ' = v;');
11150 };
11151 ReflectionCapabilities.prototype.method = function (name) {
11152 var functionBody = "if (!o." + name + ") throw new Error('\"" + name + "\" is undefined');\n return o." + name + ".apply(o, args);";
11153 return new Function('o', 'args', functionBody);
11154 };
11155 // There is not a concept of import uri in Js, but this is useful in developing Dart applications.
11156 ReflectionCapabilities.prototype.importUri = function (type) {
11157 // StaticSymbol
11158 if (typeof type === 'object' && type['filePath']) {
11159 return type['filePath'];
11160 }
11161 // Runtime type
11162 return "./" + stringify(type);
11163 };
11164 ReflectionCapabilities.prototype.resourceUri = function (type) {
11165 return "./" + stringify(type);
11166 };
11167 ReflectionCapabilities.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
11168 return runtime;
11169 };
11170 ReflectionCapabilities.prototype.resolveEnum = function (enumIdentifier, name) {
11171 return enumIdentifier[name];
11172 };
11173 return ReflectionCapabilities;
11174 }());
11175 function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
11176 if (!decoratorInvocations) {
11177 return [];
11178 }
11179 return decoratorInvocations.map(function (decoratorInvocation) {
11180 var decoratorType = decoratorInvocation.type;
11181 var annotationCls = decoratorType.annotationCls;
11182 var annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
11183 return new (annotationCls.bind.apply(annotationCls, __spread([void 0], annotationArgs)))();
11184 });
11185 }
11186 function getParentCtor(ctor) {
11187 var parentProto = ctor.prototype ? Object.getPrototypeOf(ctor.prototype) : null;
11188 var parentCtor = parentProto ? parentProto.constructor : null;
11189 // Note: We always use `Object` as the null value
11190 // to simplify checking later on.
11191 return parentCtor || Object;
11192 }
11193
11194 /**
11195 * @license
11196 * Copyright Google LLC All Rights Reserved.
11197 *
11198 * Use of this source code is governed by an MIT-style license that can be
11199 * found in the LICENSE file at https://angular.io/license
11200 */
11201 var _reflect = null;
11202 function getReflect() {
11203 return (_reflect = _reflect || new ReflectionCapabilities());
11204 }
11205 function reflectDependencies(type) {
11206 return convertDependencies(getReflect().parameters(type));
11207 }
11208 function convertDependencies(deps) {
11209 var compiler = getCompilerFacade();
11210 return deps.map(function (dep) { return reflectDependency(compiler, dep); });
11211 }
11212 function reflectDependency(compiler, dep) {
11213 var meta = {
11214 token: null,
11215 host: false,
11216 optional: false,
11217 resolved: compiler.R3ResolvedDependencyType.Token,
11218 self: false,
11219 skipSelf: false,
11220 };
11221 function setTokenAndResolvedType(token) {
11222 meta.resolved = compiler.R3ResolvedDependencyType.Token;
11223 meta.token = token;
11224 }
11225 if (Array.isArray(dep) && dep.length > 0) {
11226 for (var j = 0; j < dep.length; j++) {
11227 var param = dep[j];
11228 if (param === undefined) {
11229 // param may be undefined if type of dep is not set by ngtsc
11230 continue;
11231 }
11232 var proto = Object.getPrototypeOf(param);
11233 if (param instanceof Optional || proto.ngMetadataName === 'Optional') {
11234 meta.optional = true;
11235 }
11236 else if (param instanceof SkipSelf || proto.ngMetadataName === 'SkipSelf') {
11237 meta.skipSelf = true;
11238 }
11239 else if (param instanceof Self || proto.ngMetadataName === 'Self') {
11240 meta.self = true;
11241 }
11242 else if (param instanceof Host || proto.ngMetadataName === 'Host') {
11243 meta.host = true;
11244 }
11245 else if (param instanceof Inject) {
11246 meta.token = param.token;
11247 }
11248 else if (param instanceof Attribute) {
11249 if (param.attributeName === undefined) {
11250 throw new Error("Attribute name must be defined.");
11251 }
11252 meta.token = param.attributeName;
11253 meta.resolved = compiler.R3ResolvedDependencyType.Attribute;
11254 }
11255 else if (param === ChangeDetectorRef) {
11256 meta.token = param;
11257 meta.resolved = compiler.R3ResolvedDependencyType.ChangeDetectorRef;
11258 }
11259 else {
11260 setTokenAndResolvedType(param);
11261 }
11262 }
11263 }
11264 else if (dep === undefined || (Array.isArray(dep) && dep.length === 0)) {
11265 meta.token = undefined;
11266 meta.resolved = R3ResolvedDependencyType.Invalid;
11267 }
11268 else {
11269 setTokenAndResolvedType(dep);
11270 }
11271 return meta;
11272 }
11273
11274 /**
11275 * @license
11276 * Copyright Google LLC All Rights Reserved.
11277 *
11278 * Use of this source code is governed by an MIT-style license that can be
11279 * found in the LICENSE file at https://angular.io/license
11280 */
11281 /**
11282 * Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
11283 * injectable def (`ɵprov`) onto the injectable type.
11284 */
11285 function compileInjectable(type, srcMeta) {
11286 var ngInjectableDef = null;
11287 var ngFactoryDef = null;
11288 // if NG_PROV_DEF is already defined on this class then don't overwrite it
11289 if (!type.hasOwnProperty(NG_PROV_DEF)) {
11290 Object.defineProperty(type, NG_PROV_DEF, {
11291 get: function () {
11292 if (ngInjectableDef === null) {
11293 ngInjectableDef = getCompilerFacade().compileInjectable(angularCoreDiEnv, "ng:///" + type.name + "/\u0275prov.js", getInjectableMetadata(type, srcMeta));
11294 }
11295 return ngInjectableDef;
11296 },
11297 });
11298 // On IE10 properties defined via `defineProperty` won't be inherited by child classes,
11299 // which will break inheriting the injectable definition from a grandparent through an
11300 // undecorated parent class. We work around it by defining a method which should be used
11301 // as a fallback. This should only be a problem in JIT mode, because in AOT TypeScript
11302 // seems to have a workaround for static properties. When inheriting from an undecorated
11303 // parent is no longer supported (v11 or later), this can safely be removed.
11304 if (!type.hasOwnProperty(NG_PROV_DEF_FALLBACK)) {
11305 type[NG_PROV_DEF_FALLBACK] = function () { return type[NG_PROV_DEF]; };
11306 }
11307 }
11308 // if NG_FACTORY_DEF is already defined on this class then don't overwrite it
11309 if (!type.hasOwnProperty(NG_FACTORY_DEF)) {
11310 Object.defineProperty(type, NG_FACTORY_DEF, {
11311 get: function () {
11312 if (ngFactoryDef === null) {
11313 var metadata = getInjectableMetadata(type, srcMeta);
11314 var compiler = getCompilerFacade();
11315 ngFactoryDef = compiler.compileFactory(angularCoreDiEnv, "ng:///" + type.name + "/\u0275fac.js", {
11316 name: metadata.name,
11317 type: metadata.type,
11318 typeArgumentCount: metadata.typeArgumentCount,
11319 deps: reflectDependencies(type),
11320 injectFn: 'inject',
11321 target: compiler.R3FactoryTarget.Injectable
11322 });
11323 }
11324 return ngFactoryDef;
11325 },
11326 // Leave this configurable so that the factories from directives or pipes can take precedence.
11327 configurable: true
11328 });
11329 }
11330 }
11331 var ɵ0$6 = getClosureSafeProperty;
11332 var USE_VALUE$1 = getClosureSafeProperty({ provide: String, useValue: ɵ0$6 });
11333 function isUseClassProvider(meta) {
11334 return meta.useClass !== undefined;
11335 }
11336 function isUseValueProvider(meta) {
11337 return USE_VALUE$1 in meta;
11338 }
11339 function isUseFactoryProvider(meta) {
11340 return meta.useFactory !== undefined;
11341 }
11342 function isUseExistingProvider(meta) {
11343 return meta.useExisting !== undefined;
11344 }
11345 function getInjectableMetadata(type, srcMeta) {
11346 // Allow the compilation of a class with a `@Injectable()` decorator without parameters
11347 var meta = srcMeta || { providedIn: null };
11348 var compilerMeta = {
11349 name: type.name,
11350 type: type,
11351 typeArgumentCount: 0,
11352 providedIn: meta.providedIn,
11353 userDeps: undefined,
11354 };
11355 if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
11356 compilerMeta.userDeps = convertDependencies(meta.deps);
11357 }
11358 if (isUseClassProvider(meta)) {
11359 // The user explicitly specified useClass, and may or may not have provided deps.
11360 compilerMeta.useClass = resolveForwardRef(meta.useClass);
11361 }
11362 else if (isUseValueProvider(meta)) {
11363 // The user explicitly specified useValue.
11364 compilerMeta.useValue = resolveForwardRef(meta.useValue);
11365 }
11366 else if (isUseFactoryProvider(meta)) {
11367 // The user explicitly specified useFactory.
11368 compilerMeta.useFactory = meta.useFactory;
11369 }
11370 else if (isUseExistingProvider(meta)) {
11371 // The user explicitly specified useExisting.
11372 compilerMeta.useExisting = resolveForwardRef(meta.useExisting);
11373 }
11374 return compilerMeta;
11375 }
11376
11377 var ɵ0$7 = getClosureSafeProperty;
11378 var USE_VALUE$2 = getClosureSafeProperty({ provide: String, useValue: ɵ0$7 });
11379 var EMPTY_ARRAY$1 = [];
11380 function convertInjectableProviderToFactory(type, provider) {
11381 if (!provider) {
11382 var reflectionCapabilities = new ReflectionCapabilities();
11383 var deps_1 = reflectionCapabilities.parameters(type);
11384 // TODO - convert to flags.
11385 return function () { return new (type.bind.apply(type, __spread([void 0], injectArgs(deps_1))))(); };
11386 }
11387 if (USE_VALUE$2 in provider) {
11388 var valueProvider_1 = provider;
11389 return function () { return valueProvider_1.useValue; };
11390 }
11391 else if (provider.useExisting) {
11392 var existingProvider_1 = provider;
11393 return function () { return ɵɵinject(resolveForwardRef(existingProvider_1.useExisting)); };
11394 }
11395 else if (provider.useFactory) {
11396 var factoryProvider_1 = provider;
11397 return function () { return factoryProvider_1.useFactory.apply(factoryProvider_1, __spread(injectArgs(factoryProvider_1.deps || EMPTY_ARRAY$1))); };
11398 }
11399 else if (provider.useClass) {
11400 var classProvider_1 = provider;
11401 var deps_2 = provider.deps;
11402 if (!deps_2) {
11403 var reflectionCapabilities = new ReflectionCapabilities();
11404 deps_2 = reflectionCapabilities.parameters(type);
11405 }
11406 return function () {
11407 var _a;
11408 return new ((_a = (resolveForwardRef(classProvider_1.useClass))).bind.apply(_a, __spread([void 0], injectArgs(deps_2))))();
11409 };
11410 }
11411 else {
11412 var deps_3 = provider.deps;
11413 if (!deps_3) {
11414 var reflectionCapabilities = new ReflectionCapabilities();
11415 deps_3 = reflectionCapabilities.parameters(type);
11416 }
11417 return function () { return new (type.bind.apply(type, __spread([void 0], injectArgs(deps_3))))(); };
11418 }
11419 }
11420
11421 /**
11422 * @license
11423 * Copyright Google LLC All Rights Reserved.
11424 *
11425 * Use of this source code is governed by an MIT-style license that can be
11426 * found in the LICENSE file at https://angular.io/license
11427 */
11428 var ɵ0$8 = function (type, meta) { return SWITCH_COMPILE_INJECTABLE(type, meta); };
11429 /**
11430 * Injectable decorator and metadata.
11431 *
11432 * @Annotation
11433 * @publicApi
11434 */
11435 var Injectable = makeDecorator('Injectable', undefined, undefined, undefined, ɵ0$8);
11436 /**
11437 * Supports @Injectable() in JIT mode for Render2.
11438 */
11439 function render2CompileInjectable(injectableType, options) {
11440 if (options && options.providedIn !== undefined && !getInjectableDef(injectableType)) {
11441 injectableType.ɵprov = ɵɵdefineInjectable({
11442 token: injectableType,
11443 providedIn: options.providedIn,
11444 factory: convertInjectableProviderToFactory(injectableType, options),
11445 });
11446 }
11447 }
11448 var SWITCH_COMPILE_INJECTABLE__POST_R3__ = compileInjectable;
11449 var SWITCH_COMPILE_INJECTABLE__PRE_R3__ = render2CompileInjectable;
11450 var SWITCH_COMPILE_INJECTABLE = SWITCH_COMPILE_INJECTABLE__PRE_R3__;
11451
11452 /**
11453 * @license
11454 * Copyright Google LLC All Rights Reserved.
11455 *
11456 * Use of this source code is governed by an MIT-style license that can be
11457 * found in the LICENSE file at https://angular.io/license
11458 */
11459 /**
11460 * An internal token whose presence in an injector indicates that the injector should treat itself
11461 * as a root scoped injector when processing requests for unknown tokens which may indicate
11462 * they are provided in the root scope.
11463 */
11464 var INJECTOR_SCOPE = new InjectionToken('Set Injector scope.');
11465
11466 /**
11467 * Marker which indicates that a value has not yet been created from the factory function.
11468 */
11469 var NOT_YET = {};
11470 /**
11471 * Marker which indicates that the factory function for a token is in the process of being called.
11472 *
11473 * If the injector is asked to inject a token with its value set to CIRCULAR, that indicates
11474 * injection of a dependency has recursively attempted to inject the original token, and there is
11475 * a circular dependency among the providers.
11476 */
11477 var CIRCULAR = {};
11478 var EMPTY_ARRAY$2 = [];
11479 /**
11480 * A lazily initialized NullInjector.
11481 */
11482 var NULL_INJECTOR = undefined;
11483 function getNullInjector() {
11484 if (NULL_INJECTOR === undefined) {
11485 NULL_INJECTOR = new NullInjector();
11486 }
11487 return NULL_INJECTOR;
11488 }
11489 /**
11490 * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
11491 *
11492 * @publicApi
11493 */
11494 function createInjector(defType, parent, additionalProviders, name) {
11495 if (parent === void 0) { parent = null; }
11496 if (additionalProviders === void 0) { additionalProviders = null; }
11497 var injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
11498 injector._resolveInjectorDefTypes();
11499 return injector;
11500 }
11501 /**
11502 * Creates a new injector without eagerly resolving its injector types. Can be used in places
11503 * where resolving the injector types immediately can lead to an infinite loop. The injector types
11504 * should be resolved at a later point by calling `_resolveInjectorDefTypes`.
11505 */
11506 function createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name) {
11507 if (parent === void 0) { parent = null; }
11508 if (additionalProviders === void 0) { additionalProviders = null; }
11509 return new R3Injector(defType, additionalProviders, parent || getNullInjector(), name);
11510 }
11511 var R3Injector = /** @class */ (function () {
11512 function R3Injector(def, additionalProviders, parent, source) {
11513 var _this = this;
11514 if (source === void 0) { source = null; }
11515 this.parent = parent;
11516 /**
11517 * Map of tokens to records which contain the instances of those tokens.
11518 * - `null` value implies that we don't have the record. Used by tree-shakable injectors
11519 * to prevent further searches.
11520 */
11521 this.records = new Map();
11522 /**
11523 * The transitive set of `InjectorType`s which define this injector.
11524 */
11525 this.injectorDefTypes = new Set();
11526 /**
11527 * Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
11528 */
11529 this.onDestroy = new Set();
11530 this._destroyed = false;
11531 var dedupStack = [];
11532 // Start off by creating Records for every provider declared in every InjectorType
11533 // included transitively in additional providers then do the same for `def`. This order is
11534 // important because `def` may include providers that override ones in additionalProviders.
11535 additionalProviders &&
11536 deepForEach(additionalProviders, function (provider) { return _this.processProvider(provider, def, additionalProviders); });
11537 deepForEach([def], function (injectorDef) { return _this.processInjectorType(injectorDef, [], dedupStack); });
11538 // Make sure the INJECTOR token provides this injector.
11539 this.records.set(INJECTOR, makeRecord(undefined, this));
11540 // Detect whether this injector has the APP_ROOT_SCOPE token and thus should provide
11541 // any injectable scoped to APP_ROOT_SCOPE.
11542 var record = this.records.get(INJECTOR_SCOPE);
11543 this.scope = record != null ? record.value : null;
11544 // Source name, used for debugging
11545 this.source = source || (typeof def === 'object' ? null : stringify(def));
11546 }
11547 Object.defineProperty(R3Injector.prototype, "destroyed", {
11548 /**
11549 * Flag indicating that this injector was previously destroyed.
11550 */
11551 get: function () {
11552 return this._destroyed;
11553 },
11554 enumerable: false,
11555 configurable: true
11556 });
11557 /**
11558 * Destroy the injector and release references to every instance or provider associated with it.
11559 *
11560 * Also calls the `OnDestroy` lifecycle hooks of every instance that was created for which a
11561 * hook was found.
11562 */
11563 R3Injector.prototype.destroy = function () {
11564 this.assertNotDestroyed();
11565 // Set destroyed = true first, in case lifecycle hooks re-enter destroy().
11566 this._destroyed = true;
11567 try {
11568 // Call all the lifecycle hooks.
11569 this.onDestroy.forEach(function (service) { return service.ngOnDestroy(); });
11570 }
11571 finally {
11572 // Release all references.
11573 this.records.clear();
11574 this.onDestroy.clear();
11575 this.injectorDefTypes.clear();
11576 }
11577 };
11578 R3Injector.prototype.get = function (token, notFoundValue, flags) {
11579 if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
11580 if (flags === void 0) { flags = exports.InjectFlags.Default; }
11581 this.assertNotDestroyed();
11582 // Set the injection context.
11583 var previousInjector = setCurrentInjector(this);
11584 try {
11585 // Check for the SkipSelf flag.
11586 if (!(flags & exports.InjectFlags.SkipSelf)) {
11587 // SkipSelf isn't set, check if the record belongs to this injector.
11588 var record = this.records.get(token);
11589 if (record === undefined) {
11590 // No record, but maybe the token is scoped to this injector. Look for an injectable
11591 // def with a scope matching this injector.
11592 var def = couldBeInjectableType(token) && getInjectableDef(token);
11593 if (def && this.injectableDefInScope(def)) {
11594 // Found an injectable def and it's scoped to this injector. Pretend as if it was here
11595 // all along.
11596 record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
11597 }
11598 else {
11599 record = null;
11600 }
11601 this.records.set(token, record);
11602 }
11603 // If a record was found, get the instance for it and return it.
11604 if (record != null /* NOT null || undefined */) {
11605 return this.hydrate(token, record);
11606 }
11607 }
11608 // Select the next injector based on the Self flag - if self is set, the next injector is
11609 // the NullInjector, otherwise it's the parent.
11610 var nextInjector = !(flags & exports.InjectFlags.Self) ? this.parent : getNullInjector();
11611 // Set the notFoundValue based on the Optional flag - if optional is set and notFoundValue
11612 // is undefined, the value is null, otherwise it's the notFoundValue.
11613 notFoundValue = (flags & exports.InjectFlags.Optional) && notFoundValue === THROW_IF_NOT_FOUND ?
11614 null :
11615 notFoundValue;
11616 return nextInjector.get(token, notFoundValue);
11617 }
11618 catch (e) {
11619 if (e.name === 'NullInjectorError') {
11620 var path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
11621 path.unshift(stringify(token));
11622 if (previousInjector) {
11623 // We still have a parent injector, keep throwing
11624 throw e;
11625 }
11626 else {
11627 // Format & throw the final error message when we don't have any previous injector
11628 return catchInjectorError(e, token, 'R3InjectorError', this.source);
11629 }
11630 }
11631 else {
11632 throw e;
11633 }
11634 }
11635 finally {
11636 // Lastly, clean up the state by restoring the previous injector.
11637 setCurrentInjector(previousInjector);
11638 }
11639 };
11640 /** @internal */
11641 R3Injector.prototype._resolveInjectorDefTypes = function () {
11642 var _this = this;
11643 this.injectorDefTypes.forEach(function (defType) { return _this.get(defType); });
11644 };
11645 R3Injector.prototype.toString = function () {
11646 var tokens = [], records = this.records;
11647 records.forEach(function (v, token) { return tokens.push(stringify(token)); });
11648 return "R3Injector[" + tokens.join(', ') + "]";
11649 };
11650 R3Injector.prototype.assertNotDestroyed = function () {
11651 if (this._destroyed) {
11652 throw new Error('Injector has already been destroyed.');
11653 }
11654 };
11655 /**
11656 * Add an `InjectorType` or `InjectorTypeWithProviders` and all of its transitive providers
11657 * to this injector.
11658 *
11659 * If an `InjectorTypeWithProviders` that declares providers besides the type is specified,
11660 * the function will return "true" to indicate that the providers of the type definition need
11661 * to be processed. This allows us to process providers of injector types after all imports of
11662 * an injector definition are processed. (following View Engine semantics: see FW-1349)
11663 */
11664 R3Injector.prototype.processInjectorType = function (defOrWrappedDef, parents, dedupStack) {
11665 var _this = this;
11666 defOrWrappedDef = resolveForwardRef(defOrWrappedDef);
11667 if (!defOrWrappedDef)
11668 return false;
11669 // Either the defOrWrappedDef is an InjectorType (with injector def) or an
11670 // InjectorDefTypeWithProviders (aka ModuleWithProviders). Detecting either is a megamorphic
11671 // read, so care is taken to only do the read once.
11672 // First attempt to read the injector def (`ɵinj`).
11673 var def = getInjectorDef(defOrWrappedDef);
11674 // If that's not present, then attempt to read ngModule from the InjectorDefTypeWithProviders.
11675 var ngModule = (def == null) && defOrWrappedDef.ngModule || undefined;
11676 // Determine the InjectorType. In the case where `defOrWrappedDef` is an `InjectorType`,
11677 // then this is easy. In the case of an InjectorDefTypeWithProviders, then the definition type
11678 // is the `ngModule`.
11679 var defType = (ngModule === undefined) ? defOrWrappedDef : ngModule;
11680 // Check for circular dependencies.
11681 if (ngDevMode && parents.indexOf(defType) !== -1) {
11682 var defName = stringify(defType);
11683 throw new Error("Circular dependency in DI detected for type " + defName + ". Dependency path: " + parents.map(function (defType) { return stringify(defType); }).join(' > ') + " > " + defName + ".");
11684 }
11685 // Check for multiple imports of the same module
11686 var isDuplicate = dedupStack.indexOf(defType) !== -1;
11687 // Finally, if defOrWrappedType was an `InjectorDefTypeWithProviders`, then the actual
11688 // `InjectorDef` is on its `ngModule`.
11689 if (ngModule !== undefined) {
11690 def = getInjectorDef(ngModule);
11691 }
11692 // If no definition was found, it might be from exports. Remove it.
11693 if (def == null) {
11694 return false;
11695 }
11696 // Add providers in the same way that @NgModule resolution did:
11697 // First, include providers from any imports.
11698 if (def.imports != null && !isDuplicate) {
11699 // Before processing defType's imports, add it to the set of parents. This way, if it ends
11700 // up deeply importing itself, this can be detected.
11701 ngDevMode && parents.push(defType);
11702 // Add it to the set of dedups. This way we can detect multiple imports of the same module
11703 dedupStack.push(defType);
11704 var importTypesWithProviders_1;
11705 try {
11706 deepForEach(def.imports, function (imported) {
11707 if (_this.processInjectorType(imported, parents, dedupStack)) {
11708 if (importTypesWithProviders_1 === undefined)
11709 importTypesWithProviders_1 = [];
11710 // If the processed import is an injector type with providers, we store it in the
11711 // list of import types with providers, so that we can process those afterwards.
11712 importTypesWithProviders_1.push(imported);
11713 }
11714 });
11715 }
11716 finally {
11717 // Remove it from the parents set when finished.
11718 ngDevMode && parents.pop();
11719 }
11720 // Imports which are declared with providers (TypeWithProviders) need to be processed
11721 // after all imported modules are processed. This is similar to how View Engine
11722 // processes/merges module imports in the metadata resolver. See: FW-1349.
11723 if (importTypesWithProviders_1 !== undefined) {
11724 var _loop_1 = function (i) {
11725 var _a = importTypesWithProviders_1[i], ngModule_1 = _a.ngModule, providers = _a.providers;
11726 deepForEach(providers, function (provider) { return _this.processProvider(provider, ngModule_1, providers || EMPTY_ARRAY$2); });
11727 };
11728 for (var i = 0; i < importTypesWithProviders_1.length; i++) {
11729 _loop_1(i);
11730 }
11731 }
11732 }
11733 // Track the InjectorType and add a provider for it. It's important that this is done after the
11734 // def's imports.
11735 this.injectorDefTypes.add(defType);
11736 this.records.set(defType, makeRecord(def.factory, NOT_YET));
11737 // Next, include providers listed on the definition itself.
11738 var defProviders = def.providers;
11739 if (defProviders != null && !isDuplicate) {
11740 var injectorType_1 = defOrWrappedDef;
11741 deepForEach(defProviders, function (provider) { return _this.processProvider(provider, injectorType_1, defProviders); });
11742 }
11743 return (ngModule !== undefined &&
11744 defOrWrappedDef.providers !== undefined);
11745 };
11746 /**
11747 * Process a `SingleProvider` and add it.
11748 */
11749 R3Injector.prototype.processProvider = function (provider, ngModuleType, providers) {
11750 // Determine the token from the provider. Either it's its own token, or has a {provide: ...}
11751 // property.
11752 provider = resolveForwardRef(provider);
11753 var token = isTypeProvider(provider) ? provider : resolveForwardRef(provider && provider.provide);
11754 // Construct a `Record` for the provider.
11755 var record = providerToRecord(provider, ngModuleType, providers);
11756 if (!isTypeProvider(provider) && provider.multi === true) {
11757 // If the provider indicates that it's a multi-provider, process it specially.
11758 // First check whether it's been defined already.
11759 var multiRecord_1 = this.records.get(token);
11760 if (multiRecord_1) {
11761 // It has. Throw a nice error if
11762 if (multiRecord_1.multi === undefined) {
11763 throwMixedMultiProviderError();
11764 }
11765 }
11766 else {
11767 multiRecord_1 = makeRecord(undefined, NOT_YET, true);
11768 multiRecord_1.factory = function () { return injectArgs(multiRecord_1.multi); };
11769 this.records.set(token, multiRecord_1);
11770 }
11771 token = provider;
11772 multiRecord_1.multi.push(provider);
11773 }
11774 else {
11775 var existing = this.records.get(token);
11776 if (existing && existing.multi !== undefined) {
11777 throwMixedMultiProviderError();
11778 }
11779 }
11780 this.records.set(token, record);
11781 };
11782 R3Injector.prototype.hydrate = function (token, record) {
11783 if (record.value === CIRCULAR) {
11784 throwCyclicDependencyError(stringify(token));
11785 }
11786 else if (record.value === NOT_YET) {
11787 record.value = CIRCULAR;
11788 record.value = record.factory();
11789 }
11790 if (typeof record.value === 'object' && record.value && hasOnDestroy(record.value)) {
11791 this.onDestroy.add(record.value);
11792 }
11793 return record.value;
11794 };
11795 R3Injector.prototype.injectableDefInScope = function (def) {
11796 if (!def.providedIn) {
11797 return false;
11798 }
11799 else if (typeof def.providedIn === 'string') {
11800 return def.providedIn === 'any' || (def.providedIn === this.scope);
11801 }
11802 else {
11803 return this.injectorDefTypes.has(def.providedIn);
11804 }
11805 };
11806 return R3Injector;
11807 }());
11808 function injectableDefOrInjectorDefFactory(token) {
11809 // Most tokens will have an injectable def directly on them, which specifies a factory directly.
11810 var injectableDef = getInjectableDef(token);
11811 var factory = injectableDef !== null ? injectableDef.factory : getFactoryDef(token);
11812 if (factory !== null) {
11813 return factory;
11814 }
11815 // If the token is an NgModule, it's also injectable but the factory is on its injector def
11816 // (`ɵinj`)
11817 var injectorDef = getInjectorDef(token);
11818 if (injectorDef !== null) {
11819 return injectorDef.factory;
11820 }
11821 // InjectionTokens should have an injectable def (ɵprov) and thus should be handled above.
11822 // If it's missing that, it's an error.
11823 if (token instanceof InjectionToken) {
11824 throw new Error("Token " + stringify(token) + " is missing a \u0275prov definition.");
11825 }
11826 // Undecorated types can sometimes be created if they have no constructor arguments.
11827 if (token instanceof Function) {
11828 return getUndecoratedInjectableFactory(token);
11829 }
11830 // There was no way to resolve a factory for this token.
11831 throw new Error('unreachable');
11832 }
11833 function getUndecoratedInjectableFactory(token) {
11834 // If the token has parameters then it has dependencies that we cannot resolve implicitly.
11835 var paramLength = token.length;
11836 if (paramLength > 0) {
11837 var args = newArray(paramLength, '?');
11838 throw new Error("Can't resolve all parameters for " + stringify(token) + ": (" + args.join(', ') + ").");
11839 }
11840 // The constructor function appears to have no parameters.
11841 // This might be because it inherits from a super-class. In which case, use an injectable
11842 // def from an ancestor if there is one.
11843 // Otherwise this really is a simple class with no dependencies, so return a factory that
11844 // just instantiates the zero-arg constructor.
11845 var inheritedInjectableDef = getInheritedInjectableDef(token);
11846 if (inheritedInjectableDef !== null) {
11847 return function () { return inheritedInjectableDef.factory(token); };
11848 }
11849 else {
11850 return function () { return new token(); };
11851 }
11852 }
11853 function providerToRecord(provider, ngModuleType, providers) {
11854 if (isValueProvider(provider)) {
11855 return makeRecord(undefined, provider.useValue);
11856 }
11857 else {
11858 var factory = providerToFactory(provider, ngModuleType, providers);
11859 return makeRecord(factory, NOT_YET);
11860 }
11861 }
11862 /**
11863 * Converts a `SingleProvider` into a factory function.
11864 *
11865 * @param provider provider to convert to factory
11866 */
11867 function providerToFactory(provider, ngModuleType, providers) {
11868 var factory = undefined;
11869 if (isTypeProvider(provider)) {
11870 var unwrappedProvider = resolveForwardRef(provider);
11871 return getFactoryDef(unwrappedProvider) || injectableDefOrInjectorDefFactory(unwrappedProvider);
11872 }
11873 else {
11874 if (isValueProvider(provider)) {
11875 factory = function () { return resolveForwardRef(provider.useValue); };
11876 }
11877 else if (isFactoryProvider(provider)) {
11878 factory = function () { return provider.useFactory.apply(provider, __spread(injectArgs(provider.deps || []))); };
11879 }
11880 else if (isExistingProvider(provider)) {
11881 factory = function () { return ɵɵinject(resolveForwardRef(provider.useExisting)); };
11882 }
11883 else {
11884 var classRef_1 = resolveForwardRef(provider &&
11885 (provider.useClass || provider.provide));
11886 if (!classRef_1) {
11887 throwInvalidProviderError(ngModuleType, providers, provider);
11888 }
11889 if (hasDeps(provider)) {
11890 factory = function () { return new ((classRef_1).bind.apply((classRef_1), __spread([void 0], injectArgs(provider.deps))))(); };
11891 }
11892 else {
11893 return getFactoryDef(classRef_1) || injectableDefOrInjectorDefFactory(classRef_1);
11894 }
11895 }
11896 }
11897 return factory;
11898 }
11899 function makeRecord(factory, value, multi) {
11900 if (multi === void 0) { multi = false; }
11901 return {
11902 factory: factory,
11903 value: value,
11904 multi: multi ? [] : undefined,
11905 };
11906 }
11907 function isValueProvider(value) {
11908 return value !== null && typeof value == 'object' && USE_VALUE in value;
11909 }
11910 function isExistingProvider(value) {
11911 return !!(value && value.useExisting);
11912 }
11913 function isFactoryProvider(value) {
11914 return !!(value && value.useFactory);
11915 }
11916 function isTypeProvider(value) {
11917 return typeof value === 'function';
11918 }
11919 function isClassProvider(value) {
11920 return !!value.useClass;
11921 }
11922 function hasDeps(value) {
11923 return !!value.deps;
11924 }
11925 function hasOnDestroy(value) {
11926 return value !== null && typeof value === 'object' &&
11927 typeof value.ngOnDestroy === 'function';
11928 }
11929 function couldBeInjectableType(value) {
11930 return (typeof value === 'function') ||
11931 (typeof value === 'object' && value instanceof InjectionToken);
11932 }
11933
11934 function INJECTOR_IMPL__PRE_R3__(providers, parent, name) {
11935 return new StaticInjector(providers, parent, name);
11936 }
11937 function INJECTOR_IMPL__POST_R3__(providers, parent, name) {
11938 return createInjector({ name: name }, parent, providers, name);
11939 }
11940 var INJECTOR_IMPL = INJECTOR_IMPL__PRE_R3__;
11941 /**
11942 * Concrete injectors implement this interface. Injectors are configured
11943 * with [providers](guide/glossary#provider) that associate
11944 * dependencies of various types with [injection tokens](guide/glossary#di-token).
11945 *
11946 * @see ["DI Providers"](guide/dependency-injection-providers).
11947 * @see `StaticProvider`
11948 *
11949 * @usageNotes
11950 *
11951 * The following example creates a service injector instance.
11952 *
11953 * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
11954 *
11955 * ### Usage example
11956 *
11957 * {@example core/di/ts/injector_spec.ts region='Injector'}
11958 *
11959 * `Injector` returns itself when given `Injector` as a token:
11960 *
11961 * {@example core/di/ts/injector_spec.ts region='injectInjector'}
11962 *
11963 * @publicApi
11964 */
11965 var Injector = /** @class */ (function () {
11966 function Injector() {
11967 }
11968 Injector.create = function (options, parent) {
11969 if (Array.isArray(options)) {
11970 return INJECTOR_IMPL(options, parent, '');
11971 }
11972 else {
11973 return INJECTOR_IMPL(options.providers, options.parent, options.name || '');
11974 }
11975 };
11976 return Injector;
11977 }());
11978 Injector.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
11979 Injector.NULL = new NullInjector();
11980 /** @nocollapse */
11981 Injector.ɵprov = ɵɵdefineInjectable({
11982 token: Injector,
11983 providedIn: 'any',
11984 factory: function () { return ɵɵinject(INJECTOR); },
11985 });
11986 /**
11987 * @internal
11988 * @nocollapse
11989 */
11990 Injector.__NG_ELEMENT_ID__ = -1;
11991 var IDENT = function (value) {
11992 return value;
11993 };
11994 var ɵ0$9 = IDENT;
11995 var EMPTY = [];
11996 var CIRCULAR$1 = IDENT;
11997 var MULTI_PROVIDER_FN = function () {
11998 return Array.prototype.slice.call(arguments);
11999 };
12000 var ɵ1$1 = MULTI_PROVIDER_FN;
12001 var NO_NEW_LINE$1 = 'ɵ';
12002 var StaticInjector = /** @class */ (function () {
12003 function StaticInjector(providers, parent, source) {
12004 if (parent === void 0) { parent = Injector.NULL; }
12005 if (source === void 0) { source = null; }
12006 this.parent = parent;
12007 this.source = source;
12008 var records = this._records = new Map();
12009 records.set(Injector, { token: Injector, fn: IDENT, deps: EMPTY, value: this, useNew: false });
12010 records.set(INJECTOR, { token: INJECTOR, fn: IDENT, deps: EMPTY, value: this, useNew: false });
12011 this.scope = recursivelyProcessProviders(records, providers);
12012 }
12013 StaticInjector.prototype.get = function (token, notFoundValue, flags) {
12014 if (flags === void 0) { flags = exports.InjectFlags.Default; }
12015 var records = this._records;
12016 var record = records.get(token);
12017 if (record === undefined) {
12018 // This means we have never seen this record, see if it is tree shakable provider.
12019 var injectableDef = getInjectableDef(token);
12020 if (injectableDef) {
12021 var providedIn = injectableDef && injectableDef.providedIn;
12022 if (providedIn === 'any' || providedIn != null && providedIn === this.scope) {
12023 records.set(token, record = resolveProvider({ provide: token, useFactory: injectableDef.factory, deps: EMPTY }));
12024 }
12025 }
12026 if (record === undefined) {
12027 // Set record to null to make sure that we don't go through expensive lookup above again.
12028 records.set(token, null);
12029 }
12030 }
12031 var lastInjector = setCurrentInjector(this);
12032 try {
12033 return tryResolveToken(token, record, records, this.parent, notFoundValue, flags);
12034 }
12035 catch (e) {
12036 return catchInjectorError(e, token, 'StaticInjectorError', this.source);
12037 }
12038 finally {
12039 setCurrentInjector(lastInjector);
12040 }
12041 };
12042 StaticInjector.prototype.toString = function () {
12043 var tokens = [], records = this._records;
12044 records.forEach(function (v, token) { return tokens.push(stringify(token)); });
12045 return "StaticInjector[" + tokens.join(', ') + "]";
12046 };
12047 return StaticInjector;
12048 }());
12049 function resolveProvider(provider) {
12050 var deps = computeDeps(provider);
12051 var fn = IDENT;
12052 var value = EMPTY;
12053 var useNew = false;
12054 var provide = resolveForwardRef(provider.provide);
12055 if (USE_VALUE in provider) {
12056 // We need to use USE_VALUE in provider since provider.useValue could be defined as undefined.
12057 value = provider.useValue;
12058 }
12059 else if (provider.useFactory) {
12060 fn = provider.useFactory;
12061 }
12062 else if (provider.useExisting) {
12063 // Just use IDENT
12064 }
12065 else if (provider.useClass) {
12066 useNew = true;
12067 fn = resolveForwardRef(provider.useClass);
12068 }
12069 else if (typeof provide == 'function') {
12070 useNew = true;
12071 fn = provide;
12072 }
12073 else {
12074 throw staticError('StaticProvider does not have [useValue|useFactory|useExisting|useClass] or [provide] is not newable', provider);
12075 }
12076 return { deps: deps, fn: fn, useNew: useNew, value: value };
12077 }
12078 function multiProviderMixError(token) {
12079 return staticError('Cannot mix multi providers and regular providers', token);
12080 }
12081 function recursivelyProcessProviders(records, provider) {
12082 var scope = null;
12083 if (provider) {
12084 provider = resolveForwardRef(provider);
12085 if (Array.isArray(provider)) {
12086 // if we have an array recurse into the array
12087 for (var i = 0; i < provider.length; i++) {
12088 scope = recursivelyProcessProviders(records, provider[i]) || scope;
12089 }
12090 }
12091 else if (typeof provider === 'function') {
12092 // Functions were supported in ReflectiveInjector, but are not here. For safety give useful
12093 // error messages
12094 throw staticError('Function/Class not supported', provider);
12095 }
12096 else if (provider && typeof provider === 'object' && provider.provide) {
12097 // At this point we have what looks like a provider: {provide: ?, ....}
12098 var token = resolveForwardRef(provider.provide);
12099 var resolvedProvider = resolveProvider(provider);
12100 if (provider.multi === true) {
12101 // This is a multi provider.
12102 var multiProvider = records.get(token);
12103 if (multiProvider) {
12104 if (multiProvider.fn !== MULTI_PROVIDER_FN) {
12105 throw multiProviderMixError(token);
12106 }
12107 }
12108 else {
12109 // Create a placeholder factory which will look up the constituents of the multi provider.
12110 records.set(token, multiProvider = {
12111 token: provider.provide,
12112 deps: [],
12113 useNew: false,
12114 fn: MULTI_PROVIDER_FN,
12115 value: EMPTY
12116 });
12117 }
12118 // Treat the provider as the token.
12119 token = provider;
12120 multiProvider.deps.push({ token: token, options: 6 /* Default */ });
12121 }
12122 var record = records.get(token);
12123 if (record && record.fn == MULTI_PROVIDER_FN) {
12124 throw multiProviderMixError(token);
12125 }
12126 if (token === INJECTOR_SCOPE) {
12127 scope = resolvedProvider.value;
12128 }
12129 records.set(token, resolvedProvider);
12130 }
12131 else {
12132 throw staticError('Unexpected provider', provider);
12133 }
12134 }
12135 return scope;
12136 }
12137 function tryResolveToken(token, record, records, parent, notFoundValue, flags) {
12138 try {
12139 return resolveToken(token, record, records, parent, notFoundValue, flags);
12140 }
12141 catch (e) {
12142 // ensure that 'e' is of type Error.
12143 if (!(e instanceof Error)) {
12144 e = new Error(e);
12145 }
12146 var path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
12147 path.unshift(token);
12148 if (record && record.value == CIRCULAR$1) {
12149 // Reset the Circular flag.
12150 record.value = EMPTY;
12151 }
12152 throw e;
12153 }
12154 }
12155 function resolveToken(token, record, records, parent, notFoundValue, flags) {
12156 var value;
12157 if (record && !(flags & exports.InjectFlags.SkipSelf)) {
12158 // If we don't have a record, this implies that we don't own the provider hence don't know how
12159 // to resolve it.
12160 value = record.value;
12161 if (value == CIRCULAR$1) {
12162 throw Error(NO_NEW_LINE$1 + 'Circular dependency');
12163 }
12164 else if (value === EMPTY) {
12165 record.value = CIRCULAR$1;
12166 var obj = undefined;
12167 var useNew = record.useNew;
12168 var fn = record.fn;
12169 var depRecords = record.deps;
12170 var deps = EMPTY;
12171 if (depRecords.length) {
12172 deps = [];
12173 for (var i = 0; i < depRecords.length; i++) {
12174 var depRecord = depRecords[i];
12175 var options = depRecord.options;
12176 var childRecord = options & 2 /* CheckSelf */ ? records.get(depRecord.token) : undefined;
12177 deps.push(tryResolveToken(
12178 // Current Token to resolve
12179 depRecord.token,
12180 // A record which describes how to resolve the token.
12181 // If undefined, this means we don't have such a record
12182 childRecord,
12183 // Other records we know about.
12184 records,
12185 // If we don't know how to resolve dependency and we should not check parent for it,
12186 // than pass in Null injector.
12187 !childRecord && !(options & 4 /* CheckParent */) ? Injector.NULL : parent, options & 1 /* Optional */ ? null : Injector.THROW_IF_NOT_FOUND, exports.InjectFlags.Default));
12188 }
12189 }
12190 record.value = value = useNew ? new (fn.bind.apply(fn, __spread([void 0], deps)))() : fn.apply(obj, deps);
12191 }
12192 }
12193 else if (!(flags & exports.InjectFlags.Self)) {
12194 value = parent.get(token, notFoundValue, exports.InjectFlags.Default);
12195 }
12196 else if (!(flags & exports.InjectFlags.Optional)) {
12197 value = Injector.NULL.get(token, notFoundValue);
12198 }
12199 else {
12200 value = Injector.NULL.get(token, typeof notFoundValue !== 'undefined' ? notFoundValue : null);
12201 }
12202 return value;
12203 }
12204 function computeDeps(provider) {
12205 var deps = EMPTY;
12206 var providerDeps = provider.deps;
12207 if (providerDeps && providerDeps.length) {
12208 deps = [];
12209 for (var i = 0; i < providerDeps.length; i++) {
12210 var options = 6 /* Default */;
12211 var token = resolveForwardRef(providerDeps[i]);
12212 if (Array.isArray(token)) {
12213 for (var j = 0, annotations = token; j < annotations.length; j++) {
12214 var annotation = annotations[j];
12215 if (annotation instanceof Optional || annotation == Optional) {
12216 options = options | 1 /* Optional */;
12217 }
12218 else if (annotation instanceof SkipSelf || annotation == SkipSelf) {
12219 options = options & ~2 /* CheckSelf */;
12220 }
12221 else if (annotation instanceof Self || annotation == Self) {
12222 options = options & ~4 /* CheckParent */;
12223 }
12224 else if (annotation instanceof Inject) {
12225 token = annotation.token;
12226 }
12227 else {
12228 token = resolveForwardRef(annotation);
12229 }
12230 }
12231 }
12232 deps.push({ token: token, options: options });
12233 }
12234 }
12235 else if (provider.useExisting) {
12236 var token = resolveForwardRef(provider.useExisting);
12237 deps = [{ token: token, options: 6 /* Default */ }];
12238 }
12239 else if (!providerDeps && !(USE_VALUE in provider)) {
12240 // useValue & useExisting are the only ones which are exempt from deps all others need it.
12241 throw staticError('\'deps\' required', provider);
12242 }
12243 return deps;
12244 }
12245 function staticError(text, obj) {
12246 return new Error(formatError(text, obj, 'StaticInjectorError'));
12247 }
12248
12249 /**
12250 * @license
12251 * Copyright Google LLC All Rights Reserved.
12252 *
12253 * Use of this source code is governed by an MIT-style license that can be
12254 * found in the LICENSE file at https://angular.io/license
12255 */
12256 function findFirstClosedCycle(keys) {
12257 var res = [];
12258 for (var i = 0; i < keys.length; ++i) {
12259 if (res.indexOf(keys[i]) > -1) {
12260 res.push(keys[i]);
12261 return res;
12262 }
12263 res.push(keys[i]);
12264 }
12265 return res;
12266 }
12267 function constructResolvingPath(keys) {
12268 if (keys.length > 1) {
12269 var reversed = findFirstClosedCycle(keys.slice().reverse());
12270 var tokenStrs = reversed.map(function (k) { return stringify(k.token); });
12271 return ' (' + tokenStrs.join(' -> ') + ')';
12272 }
12273 return '';
12274 }
12275 function injectionError(injector, key, constructResolvingMessage, originalError) {
12276 var keys = [key];
12277 var errMsg = constructResolvingMessage(keys);
12278 var error = (originalError ? wrappedError(errMsg, originalError) : Error(errMsg));
12279 error.addKey = addKey;
12280 error.keys = keys;
12281 error.injectors = [injector];
12282 error.constructResolvingMessage = constructResolvingMessage;
12283 error[ERROR_ORIGINAL_ERROR] = originalError;
12284 return error;
12285 }
12286 function addKey(injector, key) {
12287 this.injectors.push(injector);
12288 this.keys.push(key);
12289 // Note: This updated message won't be reflected in the `.stack` property
12290 this.message = this.constructResolvingMessage(this.keys);
12291 }
12292 /**
12293 * Thrown when trying to retrieve a dependency by key from {@link Injector}, but the
12294 * {@link Injector} does not have a {@link Provider} for the given key.
12295 *
12296 * @usageNotes
12297 * ### Example
12298 *
12299 * ```typescript
12300 * class A {
12301 * constructor(b:B) {}
12302 * }
12303 *
12304 * expect(() => Injector.resolveAndCreate([A])).toThrowError();
12305 * ```
12306 */
12307 function noProviderError(injector, key) {
12308 return injectionError(injector, key, function (keys) {
12309 var first = stringify(keys[0].token);
12310 return "No provider for " + first + "!" + constructResolvingPath(keys);
12311 });
12312 }
12313 /**
12314 * Thrown when dependencies form a cycle.
12315 *
12316 * @usageNotes
12317 * ### Example
12318 *
12319 * ```typescript
12320 * var injector = Injector.resolveAndCreate([
12321 * {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
12322 * {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
12323 * ]);
12324 *
12325 * expect(() => injector.get("one")).toThrowError();
12326 * ```
12327 *
12328 * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
12329 */
12330 function cyclicDependencyError(injector, key) {
12331 return injectionError(injector, key, function (keys) {
12332 return "Cannot instantiate cyclic dependency!" + constructResolvingPath(keys);
12333 });
12334 }
12335 /**
12336 * Thrown when a constructing type returns with an Error.
12337 *
12338 * The `InstantiationError` class contains the original error plus the dependency graph which caused
12339 * this object to be instantiated.
12340 *
12341 * @usageNotes
12342 * ### Example
12343 *
12344 * ```typescript
12345 * class A {
12346 * constructor() {
12347 * throw new Error('message');
12348 * }
12349 * }
12350 *
12351 * var injector = Injector.resolveAndCreate([A]);
12352
12353 * try {
12354 * injector.get(A);
12355 * } catch (e) {
12356 * expect(e instanceof InstantiationError).toBe(true);
12357 * expect(e.originalException.message).toEqual("message");
12358 * expect(e.originalStack).toBeDefined();
12359 * }
12360 * ```
12361 */
12362 function instantiationError(injector, originalException, originalStack, key) {
12363 return injectionError(injector, key, function (keys) {
12364 var first = stringify(keys[0].token);
12365 return originalException.message + ": Error during instantiation of " + first + "!" + constructResolvingPath(keys) + ".";
12366 }, originalException);
12367 }
12368 /**
12369 * Thrown when an object other then {@link Provider} (or `Type`) is passed to {@link Injector}
12370 * creation.
12371 *
12372 * @usageNotes
12373 * ### Example
12374 *
12375 * ```typescript
12376 * expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
12377 * ```
12378 */
12379 function invalidProviderError(provider) {
12380 return Error("Invalid provider - only instances of Provider and Type are allowed, got: " + provider);
12381 }
12382 /**
12383 * Thrown when the class has no annotation information.
12384 *
12385 * Lack of annotation information prevents the {@link Injector} from determining which dependencies
12386 * need to be injected into the constructor.
12387 *
12388 * @usageNotes
12389 * ### Example
12390 *
12391 * ```typescript
12392 * class A {
12393 * constructor(b) {}
12394 * }
12395 *
12396 * expect(() => Injector.resolveAndCreate([A])).toThrowError();
12397 * ```
12398 *
12399 * This error is also thrown when the class not marked with {@link Injectable} has parameter types.
12400 *
12401 * ```typescript
12402 * class B {}
12403 *
12404 * class A {
12405 * constructor(b:B) {} // no information about the parameter types of A is available at runtime.
12406 * }
12407 *
12408 * expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
12409 * ```
12410 *
12411 */
12412 function noAnnotationError(typeOrFunc, params) {
12413 var signature = [];
12414 for (var i = 0, ii = params.length; i < ii; i++) {
12415 var parameter = params[i];
12416 if (!parameter || parameter.length == 0) {
12417 signature.push('?');
12418 }
12419 else {
12420 signature.push(parameter.map(stringify).join(' '));
12421 }
12422 }
12423 return Error('Cannot resolve all parameters for \'' + stringify(typeOrFunc) + '\'(' +
12424 signature.join(', ') + '). ' +
12425 'Make sure that all the parameters are decorated with Inject or have valid type annotations and that \'' +
12426 stringify(typeOrFunc) + '\' is decorated with Injectable.');
12427 }
12428 /**
12429 * Thrown when getting an object by index.
12430 *
12431 * @usageNotes
12432 * ### Example
12433 *
12434 * ```typescript
12435 * class A {}
12436 *
12437 * var injector = Injector.resolveAndCreate([A]);
12438 *
12439 * expect(() => injector.getAt(100)).toThrowError();
12440 * ```
12441 *
12442 */
12443 function outOfBoundsError(index) {
12444 return Error("Index " + index + " is out-of-bounds.");
12445 }
12446 // TODO: add a working example after alpha38 is released
12447 /**
12448 * Thrown when a multi provider and a regular provider are bound to the same token.
12449 *
12450 * @usageNotes
12451 * ### Example
12452 *
12453 * ```typescript
12454 * expect(() => Injector.resolveAndCreate([
12455 * { provide: "Strings", useValue: "string1", multi: true},
12456 * { provide: "Strings", useValue: "string2", multi: false}
12457 * ])).toThrowError();
12458 * ```
12459 */
12460 function mixingMultiProvidersWithRegularProvidersError(provider1, provider2) {
12461 return Error("Cannot mix multi providers and regular providers, got: " + provider1 + " " + provider2);
12462 }
12463
12464 /**
12465 * @license
12466 * Copyright Google LLC All Rights Reserved.
12467 *
12468 * Use of this source code is governed by an MIT-style license that can be
12469 * found in the LICENSE file at https://angular.io/license
12470 */
12471 /**
12472 * A unique object used for retrieving items from the {@link ReflectiveInjector}.
12473 *
12474 * Keys have:
12475 * - a system-wide unique `id`.
12476 * - a `token`.
12477 *
12478 * `Key` is used internally by {@link ReflectiveInjector} because its system-wide unique `id` allows
12479 * the
12480 * injector to store created objects in a more efficient way.
12481 *
12482 * `Key` should not be created directly. {@link ReflectiveInjector} creates keys automatically when
12483 * resolving
12484 * providers.
12485 *
12486 * @deprecated No replacement
12487 * @publicApi
12488 */
12489 var ReflectiveKey = /** @class */ (function () {
12490 /**
12491 * Private
12492 */
12493 function ReflectiveKey(token, id) {
12494 this.token = token;
12495 this.id = id;
12496 if (!token) {
12497 throw new Error('Token must be defined!');
12498 }
12499 this.displayName = stringify(this.token);
12500 }
12501 /**
12502 * Retrieves a `Key` for a token.
12503 */
12504 ReflectiveKey.get = function (token) {
12505 return _globalKeyRegistry.get(resolveForwardRef(token));
12506 };
12507 Object.defineProperty(ReflectiveKey, "numberOfKeys", {
12508 /**
12509 * @returns the number of keys registered in the system.
12510 */
12511 get: function () {
12512 return _globalKeyRegistry.numberOfKeys;
12513 },
12514 enumerable: false,
12515 configurable: true
12516 });
12517 return ReflectiveKey;
12518 }());
12519 var KeyRegistry = /** @class */ (function () {
12520 function KeyRegistry() {
12521 this._allKeys = new Map();
12522 }
12523 KeyRegistry.prototype.get = function (token) {
12524 if (token instanceof ReflectiveKey)
12525 return token;
12526 if (this._allKeys.has(token)) {
12527 return this._allKeys.get(token);
12528 }
12529 var newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys);
12530 this._allKeys.set(token, newKey);
12531 return newKey;
12532 };
12533 Object.defineProperty(KeyRegistry.prototype, "numberOfKeys", {
12534 get: function () {
12535 return this._allKeys.size;
12536 },
12537 enumerable: false,
12538 configurable: true
12539 });
12540 return KeyRegistry;
12541 }());
12542 var _globalKeyRegistry = new KeyRegistry();
12543
12544 /**
12545 * @license
12546 * Copyright Google LLC All Rights Reserved.
12547 *
12548 * Use of this source code is governed by an MIT-style license that can be
12549 * found in the LICENSE file at https://angular.io/license
12550 */
12551 /**
12552 * Provides access to reflection data about symbols. Used internally by Angular
12553 * to power dependency injection and compilation.
12554 */
12555 var Reflector = /** @class */ (function () {
12556 function Reflector(reflectionCapabilities) {
12557 this.reflectionCapabilities = reflectionCapabilities;
12558 }
12559 Reflector.prototype.updateCapabilities = function (caps) {
12560 this.reflectionCapabilities = caps;
12561 };
12562 Reflector.prototype.factory = function (type) {
12563 return this.reflectionCapabilities.factory(type);
12564 };
12565 Reflector.prototype.parameters = function (typeOrFunc) {
12566 return this.reflectionCapabilities.parameters(typeOrFunc);
12567 };
12568 Reflector.prototype.annotations = function (typeOrFunc) {
12569 return this.reflectionCapabilities.annotations(typeOrFunc);
12570 };
12571 Reflector.prototype.propMetadata = function (typeOrFunc) {
12572 return this.reflectionCapabilities.propMetadata(typeOrFunc);
12573 };
12574 Reflector.prototype.hasLifecycleHook = function (type, lcProperty) {
12575 return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty);
12576 };
12577 Reflector.prototype.getter = function (name) {
12578 return this.reflectionCapabilities.getter(name);
12579 };
12580 Reflector.prototype.setter = function (name) {
12581 return this.reflectionCapabilities.setter(name);
12582 };
12583 Reflector.prototype.method = function (name) {
12584 return this.reflectionCapabilities.method(name);
12585 };
12586 Reflector.prototype.importUri = function (type) {
12587 return this.reflectionCapabilities.importUri(type);
12588 };
12589 Reflector.prototype.resourceUri = function (type) {
12590 return this.reflectionCapabilities.resourceUri(type);
12591 };
12592 Reflector.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
12593 return this.reflectionCapabilities.resolveIdentifier(name, moduleUrl, members, runtime);
12594 };
12595 Reflector.prototype.resolveEnum = function (identifier, name) {
12596 return this.reflectionCapabilities.resolveEnum(identifier, name);
12597 };
12598 return Reflector;
12599 }());
12600
12601 /**
12602 * @license
12603 * Copyright Google LLC All Rights Reserved.
12604 *
12605 * Use of this source code is governed by an MIT-style license that can be
12606 * found in the LICENSE file at https://angular.io/license
12607 */
12608 /**
12609 * The {@link Reflector} used internally in Angular to access metadata
12610 * about symbols.
12611 */
12612 var reflector = new Reflector(new ReflectionCapabilities());
12613
12614 /**
12615 * @license
12616 * Copyright Google LLC All Rights Reserved.
12617 *
12618 * Use of this source code is governed by an MIT-style license that can be
12619 * found in the LICENSE file at https://angular.io/license
12620 */
12621 /**
12622 * `Dependency` is used by the framework to extend DI.
12623 * This is internal to Angular and should not be used directly.
12624 */
12625 var ReflectiveDependency = /** @class */ (function () {
12626 function ReflectiveDependency(key, optional, visibility) {
12627 this.key = key;
12628 this.optional = optional;
12629 this.visibility = visibility;
12630 }
12631 ReflectiveDependency.fromKey = function (key) {
12632 return new ReflectiveDependency(key, false, null);
12633 };
12634 return ReflectiveDependency;
12635 }());
12636 var _EMPTY_LIST = [];
12637 var ResolvedReflectiveProvider_ = /** @class */ (function () {
12638 function ResolvedReflectiveProvider_(key, resolvedFactories, multiProvider) {
12639 this.key = key;
12640 this.resolvedFactories = resolvedFactories;
12641 this.multiProvider = multiProvider;
12642 this.resolvedFactory = this.resolvedFactories[0];
12643 }
12644 return ResolvedReflectiveProvider_;
12645 }());
12646 /**
12647 * An internal resolved representation of a factory function created by resolving `Provider`.
12648 * @publicApi
12649 */
12650 var ResolvedReflectiveFactory = /** @class */ (function () {
12651 function ResolvedReflectiveFactory(
12652 /**
12653 * Factory function which can return an instance of an object represented by a key.
12654 */
12655 factory,
12656 /**
12657 * Arguments (dependencies) to the `factory` function.
12658 */
12659 dependencies) {
12660 this.factory = factory;
12661 this.dependencies = dependencies;
12662 }
12663 return ResolvedReflectiveFactory;
12664 }());
12665 /**
12666 * Resolve a single provider.
12667 */
12668 function resolveReflectiveFactory(provider) {
12669 var factoryFn;
12670 var resolvedDeps;
12671 if (provider.useClass) {
12672 var useClass = resolveForwardRef(provider.useClass);
12673 factoryFn = reflector.factory(useClass);
12674 resolvedDeps = _dependenciesFor(useClass);
12675 }
12676 else if (provider.useExisting) {
12677 factoryFn = function (aliasInstance) { return aliasInstance; };
12678 resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
12679 }
12680 else if (provider.useFactory) {
12681 factoryFn = provider.useFactory;
12682 resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
12683 }
12684 else {
12685 factoryFn = function () { return provider.useValue; };
12686 resolvedDeps = _EMPTY_LIST;
12687 }
12688 return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);
12689 }
12690 /**
12691 * Converts the `Provider` into `ResolvedProvider`.
12692 *
12693 * `Injector` internally only uses `ResolvedProvider`, `Provider` contains convenience provider
12694 * syntax.
12695 */
12696 function resolveReflectiveProvider(provider) {
12697 return new ResolvedReflectiveProvider_(ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false);
12698 }
12699 /**
12700 * Resolve a list of Providers.
12701 */
12702 function resolveReflectiveProviders(providers) {
12703 var normalized = _normalizeProviders(providers, []);
12704 var resolved = normalized.map(resolveReflectiveProvider);
12705 var resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());
12706 return Array.from(resolvedProviderMap.values());
12707 }
12708 /**
12709 * Merges a list of ResolvedProviders into a list where each key is contained exactly once and
12710 * multi providers have been merged.
12711 */
12712 function mergeResolvedReflectiveProviders(providers, normalizedProvidersMap) {
12713 for (var i = 0; i < providers.length; i++) {
12714 var provider = providers[i];
12715 var existing = normalizedProvidersMap.get(provider.key.id);
12716 if (existing) {
12717 if (provider.multiProvider !== existing.multiProvider) {
12718 throw mixingMultiProvidersWithRegularProvidersError(existing, provider);
12719 }
12720 if (provider.multiProvider) {
12721 for (var j = 0; j < provider.resolvedFactories.length; j++) {
12722 existing.resolvedFactories.push(provider.resolvedFactories[j]);
12723 }
12724 }
12725 else {
12726 normalizedProvidersMap.set(provider.key.id, provider);
12727 }
12728 }
12729 else {
12730 var resolvedProvider = void 0;
12731 if (provider.multiProvider) {
12732 resolvedProvider = new ResolvedReflectiveProvider_(provider.key, provider.resolvedFactories.slice(), provider.multiProvider);
12733 }
12734 else {
12735 resolvedProvider = provider;
12736 }
12737 normalizedProvidersMap.set(provider.key.id, resolvedProvider);
12738 }
12739 }
12740 return normalizedProvidersMap;
12741 }
12742 function _normalizeProviders(providers, res) {
12743 providers.forEach(function (b) {
12744 if (b instanceof Type) {
12745 res.push({ provide: b, useClass: b });
12746 }
12747 else if (b && typeof b == 'object' && b.provide !== undefined) {
12748 res.push(b);
12749 }
12750 else if (Array.isArray(b)) {
12751 _normalizeProviders(b, res);
12752 }
12753 else {
12754 throw invalidProviderError(b);
12755 }
12756 });
12757 return res;
12758 }
12759 function constructDependencies(typeOrFunc, dependencies) {
12760 if (!dependencies) {
12761 return _dependenciesFor(typeOrFunc);
12762 }
12763 else {
12764 var params_1 = dependencies.map(function (t) { return [t]; });
12765 return dependencies.map(function (t) { return _extractToken(typeOrFunc, t, params_1); });
12766 }
12767 }
12768 function _dependenciesFor(typeOrFunc) {
12769 var params = reflector.parameters(typeOrFunc);
12770 if (!params)
12771 return [];
12772 if (params.some(function (p) { return p == null; })) {
12773 throw noAnnotationError(typeOrFunc, params);
12774 }
12775 return params.map(function (p) { return _extractToken(typeOrFunc, p, params); });
12776 }
12777 function _extractToken(typeOrFunc, metadata, params) {
12778 var token = null;
12779 var optional = false;
12780 if (!Array.isArray(metadata)) {
12781 if (metadata instanceof Inject) {
12782 return _createDependency(metadata.token, optional, null);
12783 }
12784 else {
12785 return _createDependency(metadata, optional, null);
12786 }
12787 }
12788 var visibility = null;
12789 for (var i = 0; i < metadata.length; ++i) {
12790 var paramMetadata = metadata[i];
12791 if (paramMetadata instanceof Type) {
12792 token = paramMetadata;
12793 }
12794 else if (paramMetadata instanceof Inject) {
12795 token = paramMetadata.token;
12796 }
12797 else if (paramMetadata instanceof Optional) {
12798 optional = true;
12799 }
12800 else if (paramMetadata instanceof Self || paramMetadata instanceof SkipSelf) {
12801 visibility = paramMetadata;
12802 }
12803 else if (paramMetadata instanceof InjectionToken) {
12804 token = paramMetadata;
12805 }
12806 }
12807 token = resolveForwardRef(token);
12808 if (token != null) {
12809 return _createDependency(token, optional, visibility);
12810 }
12811 else {
12812 throw noAnnotationError(typeOrFunc, params);
12813 }
12814 }
12815 function _createDependency(token, optional, visibility) {
12816 return new ReflectiveDependency(ReflectiveKey.get(token), optional, visibility);
12817 }
12818
12819 // Threshold for the dynamic version
12820 var UNDEFINED = {};
12821 /**
12822 * A ReflectiveDependency injection container used for instantiating objects and resolving
12823 * dependencies.
12824 *
12825 * An `Injector` is a replacement for a `new` operator, which can automatically resolve the
12826 * constructor dependencies.
12827 *
12828 * In typical use, application code asks for the dependencies in the constructor and they are
12829 * resolved by the `Injector`.
12830 *
12831 * @usageNotes
12832 * ### Example
12833 *
12834 * The following example creates an `Injector` configured to create `Engine` and `Car`.
12835 *
12836 * ```typescript
12837 * @Injectable()
12838 * class Engine {
12839 * }
12840 *
12841 * @Injectable()
12842 * class Car {
12843 * constructor(public engine:Engine) {}
12844 * }
12845 *
12846 * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
12847 * var car = injector.get(Car);
12848 * expect(car instanceof Car).toBe(true);
12849 * expect(car.engine instanceof Engine).toBe(true);
12850 * ```
12851 *
12852 * Notice, we don't use the `new` operator because we explicitly want to have the `Injector`
12853 * resolve all of the object's dependencies automatically.
12854 *
12855 * @deprecated from v5 - slow and brings in a lot of code, Use `Injector.create` instead.
12856 * @publicApi
12857 */
12858 var ReflectiveInjector = /** @class */ (function () {
12859 function ReflectiveInjector() {
12860 }
12861 /**
12862 * Turns an array of provider definitions into an array of resolved providers.
12863 *
12864 * A resolution is a process of flattening multiple nested arrays and converting individual
12865 * providers into an array of `ResolvedReflectiveProvider`s.
12866 *
12867 * @usageNotes
12868 * ### Example
12869 *
12870 * ```typescript
12871 * @Injectable()
12872 * class Engine {
12873 * }
12874 *
12875 * @Injectable()
12876 * class Car {
12877 * constructor(public engine:Engine) {}
12878 * }
12879 *
12880 * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
12881 *
12882 * expect(providers.length).toEqual(2);
12883 *
12884 * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
12885 * expect(providers[0].key.displayName).toBe("Car");
12886 * expect(providers[0].dependencies.length).toEqual(1);
12887 * expect(providers[0].factory).toBeDefined();
12888 *
12889 * expect(providers[1].key.displayName).toBe("Engine");
12890 * });
12891 * ```
12892 *
12893 */
12894 ReflectiveInjector.resolve = function (providers) {
12895 return resolveReflectiveProviders(providers);
12896 };
12897 /**
12898 * Resolves an array of providers and creates an injector from those providers.
12899 *
12900 * The passed-in providers can be an array of `Type`, `Provider`,
12901 * or a recursive array of more providers.
12902 *
12903 * @usageNotes
12904 * ### Example
12905 *
12906 * ```typescript
12907 * @Injectable()
12908 * class Engine {
12909 * }
12910 *
12911 * @Injectable()
12912 * class Car {
12913 * constructor(public engine:Engine) {}
12914 * }
12915 *
12916 * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
12917 * expect(injector.get(Car) instanceof Car).toBe(true);
12918 * ```
12919 */
12920 ReflectiveInjector.resolveAndCreate = function (providers, parent) {
12921 var ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
12922 return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
12923 };
12924 /**
12925 * Creates an injector from previously resolved providers.
12926 *
12927 * This API is the recommended way to construct injectors in performance-sensitive parts.
12928 *
12929 * @usageNotes
12930 * ### Example
12931 *
12932 * ```typescript
12933 * @Injectable()
12934 * class Engine {
12935 * }
12936 *
12937 * @Injectable()
12938 * class Car {
12939 * constructor(public engine:Engine) {}
12940 * }
12941 *
12942 * var providers = ReflectiveInjector.resolve([Car, Engine]);
12943 * var injector = ReflectiveInjector.fromResolvedProviders(providers);
12944 * expect(injector.get(Car) instanceof Car).toBe(true);
12945 * ```
12946 */
12947 ReflectiveInjector.fromResolvedProviders = function (providers, parent) {
12948 return new ReflectiveInjector_(providers, parent);
12949 };
12950 return ReflectiveInjector;
12951 }());
12952 var ReflectiveInjector_ = /** @class */ (function () {
12953 /**
12954 * Private
12955 */
12956 function ReflectiveInjector_(_providers, _parent) {
12957 /** @internal */
12958 this._constructionCounter = 0;
12959 this._providers = _providers;
12960 this.parent = _parent || null;
12961 var len = _providers.length;
12962 this.keyIds = [];
12963 this.objs = [];
12964 for (var i = 0; i < len; i++) {
12965 this.keyIds[i] = _providers[i].key.id;
12966 this.objs[i] = UNDEFINED;
12967 }
12968 }
12969 ReflectiveInjector_.prototype.get = function (token, notFoundValue) {
12970 if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
12971 return this._getByKey(ReflectiveKey.get(token), null, notFoundValue);
12972 };
12973 ReflectiveInjector_.prototype.resolveAndCreateChild = function (providers) {
12974 var ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
12975 return this.createChildFromResolved(ResolvedReflectiveProviders);
12976 };
12977 ReflectiveInjector_.prototype.createChildFromResolved = function (providers) {
12978 var inj = new ReflectiveInjector_(providers);
12979 inj.parent = this;
12980 return inj;
12981 };
12982 ReflectiveInjector_.prototype.resolveAndInstantiate = function (provider) {
12983 return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]);
12984 };
12985 ReflectiveInjector_.prototype.instantiateResolved = function (provider) {
12986 return this._instantiateProvider(provider);
12987 };
12988 ReflectiveInjector_.prototype.getProviderAtIndex = function (index) {
12989 if (index < 0 || index >= this._providers.length) {
12990 throw outOfBoundsError(index);
12991 }
12992 return this._providers[index];
12993 };
12994 /** @internal */
12995 ReflectiveInjector_.prototype._new = function (provider) {
12996 if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
12997 throw cyclicDependencyError(this, provider.key);
12998 }
12999 return this._instantiateProvider(provider);
13000 };
13001 ReflectiveInjector_.prototype._getMaxNumberOfObjects = function () {
13002 return this.objs.length;
13003 };
13004 ReflectiveInjector_.prototype._instantiateProvider = function (provider) {
13005 if (provider.multiProvider) {
13006 var res = [];
13007 for (var i = 0; i < provider.resolvedFactories.length; ++i) {
13008 res[i] = this._instantiate(provider, provider.resolvedFactories[i]);
13009 }
13010 return res;
13011 }
13012 else {
13013 return this._instantiate(provider, provider.resolvedFactories[0]);
13014 }
13015 };
13016 ReflectiveInjector_.prototype._instantiate = function (provider, ResolvedReflectiveFactory) {
13017 var _this = this;
13018 var factory = ResolvedReflectiveFactory.factory;
13019 var deps;
13020 try {
13021 deps =
13022 ResolvedReflectiveFactory.dependencies.map(function (dep) { return _this._getByReflectiveDependency(dep); });
13023 }
13024 catch (e) {
13025 if (e.addKey) {
13026 e.addKey(this, provider.key);
13027 }
13028 throw e;
13029 }
13030 var obj;
13031 try {
13032 obj = factory.apply(void 0, __spread(deps));
13033 }
13034 catch (e) {
13035 throw instantiationError(this, e, e.stack, provider.key);
13036 }
13037 return obj;
13038 };
13039 ReflectiveInjector_.prototype._getByReflectiveDependency = function (dep) {
13040 return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);
13041 };
13042 ReflectiveInjector_.prototype._getByKey = function (key, visibility, notFoundValue) {
13043 if (key === ReflectiveInjector_.INJECTOR_KEY) {
13044 return this;
13045 }
13046 if (visibility instanceof Self) {
13047 return this._getByKeySelf(key, notFoundValue);
13048 }
13049 else {
13050 return this._getByKeyDefault(key, notFoundValue, visibility);
13051 }
13052 };
13053 ReflectiveInjector_.prototype._getObjByKeyId = function (keyId) {
13054 for (var i = 0; i < this.keyIds.length; i++) {
13055 if (this.keyIds[i] === keyId) {
13056 if (this.objs[i] === UNDEFINED) {
13057 this.objs[i] = this._new(this._providers[i]);
13058 }
13059 return this.objs[i];
13060 }
13061 }
13062 return UNDEFINED;
13063 };
13064 /** @internal */
13065 ReflectiveInjector_.prototype._throwOrNull = function (key, notFoundValue) {
13066 if (notFoundValue !== THROW_IF_NOT_FOUND) {
13067 return notFoundValue;
13068 }
13069 else {
13070 throw noProviderError(this, key);
13071 }
13072 };
13073 /** @internal */
13074 ReflectiveInjector_.prototype._getByKeySelf = function (key, notFoundValue) {
13075 var obj = this._getObjByKeyId(key.id);
13076 return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);
13077 };
13078 /** @internal */
13079 ReflectiveInjector_.prototype._getByKeyDefault = function (key, notFoundValue, visibility) {
13080 var inj;
13081 if (visibility instanceof SkipSelf) {
13082 inj = this.parent;
13083 }
13084 else {
13085 inj = this;
13086 }
13087 while (inj instanceof ReflectiveInjector_) {
13088 var inj_ = inj;
13089 var obj = inj_._getObjByKeyId(key.id);
13090 if (obj !== UNDEFINED)
13091 return obj;
13092 inj = inj_.parent;
13093 }
13094 if (inj !== null) {
13095 return inj.get(key.token, notFoundValue);
13096 }
13097 else {
13098 return this._throwOrNull(key, notFoundValue);
13099 }
13100 };
13101 Object.defineProperty(ReflectiveInjector_.prototype, "displayName", {
13102 get: function () {
13103 var providers = _mapProviders(this, function (b) { return ' "' + b.key.displayName + '" '; })
13104 .join(', ');
13105 return "ReflectiveInjector(providers: [" + providers + "])";
13106 },
13107 enumerable: false,
13108 configurable: true
13109 });
13110 ReflectiveInjector_.prototype.toString = function () {
13111 return this.displayName;
13112 };
13113 return ReflectiveInjector_;
13114 }());
13115 ReflectiveInjector_.INJECTOR_KEY = ReflectiveKey.get(Injector);
13116 function _mapProviders(injector, fn) {
13117 var res = [];
13118 for (var i = 0; i < injector._providers.length; ++i) {
13119 res[i] = fn(injector.getProviderAtIndex(i));
13120 }
13121 return res;
13122 }
13123
13124 /**
13125 * @license
13126 * Copyright Google LLC All Rights Reserved.
13127 *
13128 * Use of this source code is governed by an MIT-style license that can be
13129 * found in the LICENSE file at https://angular.io/license
13130 */
13131
13132 /**
13133 * @license
13134 * Copyright Google LLC All Rights Reserved.
13135 *
13136 * Use of this source code is governed by an MIT-style license that can be
13137 * found in the LICENSE file at https://angular.io/license
13138 */
13139
13140 /**
13141 * @license
13142 * Copyright Google LLC All Rights Reserved.
13143 *
13144 * Use of this source code is governed by an MIT-style license that can be
13145 * found in the LICENSE file at https://angular.io/license
13146 */
13147 /**
13148 * A DI token that you can use to create a virtual [provider](guide/glossary#provider)
13149 * that will populate the `entryComponents` field of components and NgModules
13150 * based on its `useValue` property value.
13151 * All components that are referenced in the `useValue` value (either directly
13152 * or in a nested array or map) are added to the `entryComponents` property.
13153 *
13154 * @usageNotes
13155 *
13156 * The following example shows how the router can populate the `entryComponents`
13157 * field of an NgModule based on a router configuration that refers
13158 * to components.
13159 *
13160 * ```typescript
13161 * // helper function inside the router
13162 * function provideRoutes(routes) {
13163 * return [
13164 * {provide: ROUTES, useValue: routes},
13165 * {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: routes, multi: true}
13166 * ];
13167 * }
13168 *
13169 * // user code
13170 * let routes = [
13171 * {path: '/root', component: RootComp},
13172 * {path: '/teams', component: TeamsComp}
13173 * ];
13174 *
13175 * @NgModule({
13176 * providers: [provideRoutes(routes)]
13177 * })
13178 * class ModuleWithRoutes {}
13179 * ```
13180 *
13181 * @publicApi
13182 * @deprecated Since 9.0.0. With Ivy, this property is no longer necessary.
13183 */
13184 var ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken('AnalyzeForEntryComponents');
13185 /**
13186 * Base class for query metadata.
13187 *
13188 * @see `ContentChildren`.
13189 * @see `ContentChild`.
13190 * @see `ViewChildren`.
13191 * @see `ViewChild`.
13192 *
13193 * @publicApi
13194 */
13195 var Query = /** @class */ (function () {
13196 function Query() {
13197 }
13198 return Query;
13199 }());
13200 var ɵ0$a = function (selector, data) {
13201 if (data === void 0) { data = {}; }
13202 return (Object.assign({ selector: selector, first: false, isViewQuery: false, descendants: false }, data));
13203 };
13204 /**
13205 * ContentChildren decorator and metadata.
13206 *
13207 *
13208 * @Annotation
13209 * @publicApi
13210 */
13211 var ContentChildren = makePropDecorator('ContentChildren', ɵ0$a, Query);
13212 var ɵ1$2 = function (selector, data) {
13213 if (data === void 0) { data = {}; }
13214 return (Object.assign({ selector: selector, first: true, isViewQuery: false, descendants: true }, data));
13215 };
13216 /**
13217 * ContentChild decorator and metadata.
13218 *
13219 *
13220 * @Annotation
13221 *
13222 * @publicApi
13223 */
13224 var ContentChild = makePropDecorator('ContentChild', ɵ1$2, Query);
13225 var ɵ2 = function (selector, data) {
13226 if (data === void 0) { data = {}; }
13227 return (Object.assign({ selector: selector, first: false, isViewQuery: true, descendants: true }, data));
13228 };
13229 /**
13230 * ViewChildren decorator and metadata.
13231 *
13232 * @Annotation
13233 * @publicApi
13234 */
13235 var ViewChildren = makePropDecorator('ViewChildren', ɵ2, Query);
13236 var ɵ3 = function (selector, data) { return (Object.assign({ selector: selector, first: true, isViewQuery: true, descendants: true }, data)); };
13237 /**
13238 * ViewChild decorator and metadata.
13239 *
13240 * @Annotation
13241 * @publicApi
13242 */
13243 var ViewChild = makePropDecorator('ViewChild', ɵ3, Query);
13244
13245 /**
13246 * @license
13247 * Copyright Google LLC All Rights Reserved.
13248 *
13249 * Use of this source code is governed by an MIT-style license that can be
13250 * found in the LICENSE file at https://angular.io/license
13251 */
13252 /**
13253 * Used to resolve resource URLs on `@Component` when used with JIT compilation.
13254 *
13255 * Example:
13256 * ```
13257 * @Component({
13258 * selector: 'my-comp',
13259 * templateUrl: 'my-comp.html', // This requires asynchronous resolution
13260 * })
13261 * class MyComponent{
13262 * }
13263 *
13264 * // Calling `renderComponent` will fail because `renderComponent` is a synchronous process
13265 * // and `MyComponent`'s `@Component.templateUrl` needs to be resolved asynchronously.
13266 *
13267 * // Calling `resolveComponentResources()` will resolve `@Component.templateUrl` into
13268 * // `@Component.template`, which allows `renderComponent` to proceed in a synchronous manner.
13269 *
13270 * // Use browser's `fetch()` function as the default resource resolution strategy.
13271 * resolveComponentResources(fetch).then(() => {
13272 * // After resolution all URLs have been converted into `template` strings.
13273 * renderComponent(MyComponent);
13274 * });
13275 *
13276 * ```
13277 *
13278 * NOTE: In AOT the resolution happens during compilation, and so there should be no need
13279 * to call this method outside JIT mode.
13280 *
13281 * @param resourceResolver a function which is responsible for returning a `Promise` to the
13282 * contents of the resolved URL. Browser's `fetch()` method is a good default implementation.
13283 */
13284 function resolveComponentResources(resourceResolver) {
13285 // Store all promises which are fetching the resources.
13286 var componentResolved = [];
13287 // Cache so that we don't fetch the same resource more than once.
13288 var urlMap = new Map();
13289 function cachedResourceResolve(url) {
13290 var promise = urlMap.get(url);
13291 if (!promise) {
13292 var resp = resourceResolver(url);
13293 urlMap.set(url, promise = resp.then(unwrapResponse));
13294 }
13295 return promise;
13296 }
13297 componentResourceResolutionQueue.forEach(function (component, type) {
13298 var promises = [];
13299 if (component.templateUrl) {
13300 promises.push(cachedResourceResolve(component.templateUrl).then(function (template) {
13301 component.template = template;
13302 }));
13303 }
13304 var styleUrls = component.styleUrls;
13305 var styles = component.styles || (component.styles = []);
13306 var styleOffset = component.styles.length;
13307 styleUrls && styleUrls.forEach(function (styleUrl, index) {
13308 styles.push(''); // pre-allocate array.
13309 promises.push(cachedResourceResolve(styleUrl).then(function (style) {
13310 styles[styleOffset + index] = style;
13311 styleUrls.splice(styleUrls.indexOf(styleUrl), 1);
13312 if (styleUrls.length == 0) {
13313 component.styleUrls = undefined;
13314 }
13315 }));
13316 });
13317 var fullyResolved = Promise.all(promises).then(function () { return componentDefResolved(type); });
13318 componentResolved.push(fullyResolved);
13319 });
13320 clearResolutionOfComponentResourcesQueue();
13321 return Promise.all(componentResolved).then(function () { return undefined; });
13322 }
13323 var componentResourceResolutionQueue = new Map();
13324 // Track when existing ɵcmp for a Type is waiting on resources.
13325 var componentDefPendingResolution = new Set();
13326 function maybeQueueResolutionOfComponentResources(type, metadata) {
13327 if (componentNeedsResolution(metadata)) {
13328 componentResourceResolutionQueue.set(type, metadata);
13329 componentDefPendingResolution.add(type);
13330 }
13331 }
13332 function isComponentDefPendingResolution(type) {
13333 return componentDefPendingResolution.has(type);
13334 }
13335 function componentNeedsResolution(component) {
13336 return !!((component.templateUrl && !component.hasOwnProperty('template')) ||
13337 component.styleUrls && component.styleUrls.length);
13338 }
13339 function clearResolutionOfComponentResourcesQueue() {
13340 var old = componentResourceResolutionQueue;
13341 componentResourceResolutionQueue = new Map();
13342 return old;
13343 }
13344 function restoreComponentResolutionQueue(queue) {
13345 componentDefPendingResolution.clear();
13346 queue.forEach(function (_, type) { return componentDefPendingResolution.add(type); });
13347 componentResourceResolutionQueue = queue;
13348 }
13349 function isComponentResourceResolutionQueueEmpty() {
13350 return componentResourceResolutionQueue.size === 0;
13351 }
13352 function unwrapResponse(response) {
13353 return typeof response == 'string' ? response : response.text();
13354 }
13355 function componentDefResolved(type) {
13356 componentDefPendingResolution.delete(type);
13357 }
13358
13359 /**
13360 * @license
13361 * Copyright Google LLC All Rights Reserved.
13362 *
13363 * Use of this source code is governed by an MIT-style license that can be
13364 * found in the LICENSE file at https://angular.io/license
13365 */
13366 /**
13367 * Compute the static styling (class/style) from `TAttributes`.
13368 *
13369 * This function should be called during `firstCreatePass` only.
13370 *
13371 * @param tNode The `TNode` into which the styling information should be loaded.
13372 * @param attrs `TAttributes` containing the styling information.
13373 * @param writeToHost Where should the resulting static styles be written?
13374 * - `false` Write to `TNode.stylesWithoutHost` / `TNode.classesWithoutHost`
13375 * - `true` Write to `TNode.styles` / `TNode.classes`
13376 */
13377 function computeStaticStyling(tNode, attrs, writeToHost) {
13378 ngDevMode &&
13379 assertFirstCreatePass(getTView(), 'Expecting to be called in first template pass only');
13380 var styles = writeToHost ? tNode.styles : null;
13381 var classes = writeToHost ? tNode.classes : null;
13382 var mode = 0;
13383 if (attrs !== null) {
13384 for (var i = 0; i < attrs.length; i++) {
13385 var value = attrs[i];
13386 if (typeof value === 'number') {
13387 mode = value;
13388 }
13389 else if (mode == 1 /* Classes */) {
13390 classes = concatStringsWithSpace(classes, value);
13391 }
13392 else if (mode == 2 /* Styles */) {
13393 var style = value;
13394 var styleValue = attrs[++i];
13395 styles = concatStringsWithSpace(styles, style + ': ' + styleValue + ';');
13396 }
13397 }
13398 }
13399 writeToHost ? tNode.styles = styles : tNode.stylesWithoutHost = styles;
13400 writeToHost ? tNode.classes = classes : tNode.classesWithoutHost = classes;
13401 }
13402
13403 /**
13404 * @license
13405 * Copyright Google LLC All Rights Reserved.
13406 *
13407 * Use of this source code is governed by an MIT-style license that can be
13408 * found in the LICENSE file at https://angular.io/license
13409 */
13410 var _symbolIterator = null;
13411 function getSymbolIterator() {
13412 if (!_symbolIterator) {
13413 var Symbol = _global['Symbol'];
13414 if (Symbol && Symbol.iterator) {
13415 _symbolIterator = Symbol.iterator;
13416 }
13417 else {
13418 // es6-shim specific logic
13419 var keys = Object.getOwnPropertyNames(Map.prototype);
13420 for (var i = 0; i < keys.length; ++i) {
13421 var key = keys[i];
13422 if (key !== 'entries' && key !== 'size' &&
13423 Map.prototype[key] === Map.prototype['entries']) {
13424 _symbolIterator = key;
13425 }
13426 }
13427 }
13428 }
13429 return _symbolIterator;
13430 }
13431
13432 /**
13433 * @license
13434 * Copyright Google LLC All Rights Reserved.
13435 *
13436 * Use of this source code is governed by an MIT-style license that can be
13437 * found in the LICENSE file at https://angular.io/license
13438 */
13439 function devModeEqual(a, b) {
13440 var isListLikeIterableA = isListLikeIterable(a);
13441 var isListLikeIterableB = isListLikeIterable(b);
13442 if (isListLikeIterableA && isListLikeIterableB) {
13443 return areIterablesEqual(a, b, devModeEqual);
13444 }
13445 else {
13446 var isAObject = a && (typeof a === 'object' || typeof a === 'function');
13447 var isBObject = b && (typeof b === 'object' || typeof b === 'function');
13448 if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
13449 return true;
13450 }
13451 else {
13452 return Object.is(a, b);
13453 }
13454 }
13455 }
13456 /**
13457 * Indicates that the result of a {@link Pipe} transformation has changed even though the
13458 * reference has not changed.
13459 *
13460 * Wrapped values are unwrapped automatically during the change detection, and the unwrapped value
13461 * is stored.
13462 *
13463 * Example:
13464 *
13465 * ```
13466 * if (this._latestValue === this._latestReturnedValue) {
13467 * return this._latestReturnedValue;
13468 * } else {
13469 * this._latestReturnedValue = this._latestValue;
13470 * return WrappedValue.wrap(this._latestValue); // this will force update
13471 * }
13472 * ```
13473 *
13474 * @publicApi
13475 * @deprecated from v10 stop using. (No replacement, deemed unnecessary.)
13476 */
13477 var WrappedValue = /** @class */ (function () {
13478 function WrappedValue(value) {
13479 this.wrapped = value;
13480 }
13481 /** Creates a wrapped value. */
13482 WrappedValue.wrap = function (value) {
13483 return new WrappedValue(value);
13484 };
13485 /**
13486 * Returns the underlying value of a wrapped value.
13487 * Returns the given `value` when it is not wrapped.
13488 **/
13489 WrappedValue.unwrap = function (value) {
13490 return WrappedValue.isWrapped(value) ? value.wrapped : value;
13491 };
13492 /** Returns true if `value` is a wrapped value. */
13493 WrappedValue.isWrapped = function (value) {
13494 return value instanceof WrappedValue;
13495 };
13496 return WrappedValue;
13497 }());
13498 function isListLikeIterable(obj) {
13499 if (!isJsObject(obj))
13500 return false;
13501 return Array.isArray(obj) ||
13502 (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
13503 getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
13504 }
13505 function areIterablesEqual(a, b, comparator) {
13506 var iterator1 = a[getSymbolIterator()]();
13507 var iterator2 = b[getSymbolIterator()]();
13508 while (true) {
13509 var item1 = iterator1.next();
13510 var item2 = iterator2.next();
13511 if (item1.done && item2.done)
13512 return true;
13513 if (item1.done || item2.done)
13514 return false;
13515 if (!comparator(item1.value, item2.value))
13516 return false;
13517 }
13518 }
13519 function iterateListLike(obj, fn) {
13520 if (Array.isArray(obj)) {
13521 for (var i = 0; i < obj.length; i++) {
13522 fn(obj[i]);
13523 }
13524 }
13525 else {
13526 var iterator = obj[getSymbolIterator()]();
13527 var item = void 0;
13528 while (!((item = iterator.next()).done)) {
13529 fn(item.value);
13530 }
13531 }
13532 }
13533 function isJsObject(o) {
13534 return o !== null && (typeof o === 'function' || typeof o === 'object');
13535 }
13536
13537 /**
13538 * @license
13539 * Copyright Google LLC All Rights Reserved.
13540 *
13541 * Use of this source code is governed by an MIT-style license that can be
13542 * found in the LICENSE file at https://angular.io/license
13543 */
13544 // TODO(misko): consider inlining
13545 /** Updates binding and returns the value. */
13546 function updateBinding(lView, bindingIndex, value) {
13547 return lView[bindingIndex] = value;
13548 }
13549 /** Gets the current binding value. */
13550 function getBinding(lView, bindingIndex) {
13551 ngDevMode && assertIndexInRange(lView, bindingIndex);
13552 ngDevMode &&
13553 assertNotSame(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
13554 return lView[bindingIndex];
13555 }
13556 /**
13557 * Updates binding if changed, then returns whether it was updated.
13558 *
13559 * This function also checks the `CheckNoChangesMode` and throws if changes are made.
13560 * Some changes (Objects/iterables) during `CheckNoChangesMode` are exempt to comply with VE
13561 * behavior.
13562 *
13563 * @param lView current `LView`
13564 * @param bindingIndex The binding in the `LView` to check
13565 * @param value New value to check against `lView[bindingIndex]`
13566 * @returns `true` if the bindings has changed. (Throws if binding has changed during
13567 * `CheckNoChangesMode`)
13568 */
13569 function bindingUpdated(lView, bindingIndex, value) {
13570 ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
13571 ngDevMode &&
13572 assertLessThan(bindingIndex, lView.length, "Slot should have been initialized to NO_CHANGE");
13573 var oldValue = lView[bindingIndex];
13574 if (Object.is(oldValue, value)) {
13575 return false;
13576 }
13577 else {
13578 if (ngDevMode && getCheckNoChangesMode()) {
13579 // View engine didn't report undefined values as changed on the first checkNoChanges pass
13580 // (before the change detection was run).
13581 var oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
13582 if (!devModeEqual(oldValueToCompare, value)) {
13583 var details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
13584 throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName);
13585 }
13586 // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
13587 // For this reason we exit as if no change. The early exit is needed to prevent the changed
13588 // value to be written into `LView` (If we would write the new value that we would not see it
13589 // as change on next CD.)
13590 return false;
13591 }
13592 lView[bindingIndex] = value;
13593 return true;
13594 }
13595 }
13596 /** Updates 2 bindings if changed, then returns whether either was updated. */
13597 function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
13598 var different = bindingUpdated(lView, bindingIndex, exp1);
13599 return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
13600 }
13601 /** Updates 3 bindings if changed, then returns whether any was updated. */
13602 function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
13603 var different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
13604 return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
13605 }
13606 /** Updates 4 bindings if changed, then returns whether any was updated. */
13607 function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
13608 var different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
13609 return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
13610 }
13611
13612 /**
13613 * @license
13614 * Copyright Google LLC All Rights Reserved.
13615 *
13616 * Use of this source code is governed by an MIT-style license that can be
13617 * found in the LICENSE file at https://angular.io/license
13618 */
13619 /**
13620 * Updates the value of or removes a bound attribute on an Element.
13621 *
13622 * Used in the case of `[attr.title]="value"`
13623 *
13624 * @param name name The name of the attribute.
13625 * @param value value The attribute is removed when value is `null` or `undefined`.
13626 * Otherwise the attribute value is set to the stringified value.
13627 * @param sanitizer An optional function used to sanitize the value.
13628 * @param namespace Optional namespace to use when setting the attribute.
13629 *
13630 * @codeGenApi
13631 */
13632 function ɵɵattribute(name, value, sanitizer, namespace) {
13633 var lView = getLView();
13634 var bindingIndex = nextBindingIndex();
13635 if (bindingUpdated(lView, bindingIndex, value)) {
13636 var tView = getTView();
13637 var tNode = getSelectedTNode();
13638 elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace);
13639 ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex);
13640 }
13641 return ɵɵattribute;
13642 }
13643
13644 /**
13645 * @license
13646 * Copyright Google LLC All Rights Reserved.
13647 *
13648 * Use of this source code is governed by an MIT-style license that can be
13649 * found in the LICENSE file at https://angular.io/license
13650 */
13651 /**
13652 * Create interpolation bindings with a variable number of expressions.
13653 *
13654 * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
13655 * Those are faster because there is no need to create an array of expressions and iterate over it.
13656 *
13657 * `values`:
13658 * - has static text at even indexes,
13659 * - has evaluated expressions at odd indexes.
13660 *
13661 * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
13662 */
13663 function interpolationV(lView, values) {
13664 ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
13665 ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
13666 var isBindingUpdated = false;
13667 var bindingIndex = getBindingIndex();
13668 for (var i = 1; i < values.length; i += 2) {
13669 // Check if bindings (odd indexes) have changed
13670 isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated;
13671 }
13672 setBindingIndex(bindingIndex);
13673 if (!isBindingUpdated) {
13674 return NO_CHANGE;
13675 }
13676 // Build the updated content
13677 var content = values[0];
13678 for (var i = 1; i < values.length; i += 2) {
13679 content += renderStringify(values[i]) + values[i + 1];
13680 }
13681 return content;
13682 }
13683 /**
13684 * Creates an interpolation binding with 1 expression.
13685 *
13686 * @param prefix static value used for concatenation only.
13687 * @param v0 value checked for change.
13688 * @param suffix static value used for concatenation only.
13689 */
13690 function interpolation1(lView, prefix, v0, suffix) {
13691 var different = bindingUpdated(lView, nextBindingIndex(), v0);
13692 return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE;
13693 }
13694 /**
13695 * Creates an interpolation binding with 2 expressions.
13696 */
13697 function interpolation2(lView, prefix, v0, i0, v1, suffix) {
13698 var bindingIndex = getBindingIndex();
13699 var different = bindingUpdated2(lView, bindingIndex, v0, v1);
13700 incrementBindingIndex(2);
13701 return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE;
13702 }
13703 /**
13704 * Creates an interpolation binding with 3 expressions.
13705 */
13706 function interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix) {
13707 var bindingIndex = getBindingIndex();
13708 var different = bindingUpdated3(lView, bindingIndex, v0, v1, v2);
13709 incrementBindingIndex(3);
13710 return different ?
13711 prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix :
13712 NO_CHANGE;
13713 }
13714 /**
13715 * Create an interpolation binding with 4 expressions.
13716 */
13717 function interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
13718 var bindingIndex = getBindingIndex();
13719 var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
13720 incrementBindingIndex(4);
13721 return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
13722 renderStringify(v2) + i2 + renderStringify(v3) + suffix :
13723 NO_CHANGE;
13724 }
13725 /**
13726 * Creates an interpolation binding with 5 expressions.
13727 */
13728 function interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
13729 var bindingIndex = getBindingIndex();
13730 var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
13731 different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
13732 incrementBindingIndex(5);
13733 return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
13734 renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + suffix :
13735 NO_CHANGE;
13736 }
13737 /**
13738 * Creates an interpolation binding with 6 expressions.
13739 */
13740 function interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
13741 var bindingIndex = getBindingIndex();
13742 var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
13743 different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
13744 incrementBindingIndex(6);
13745 return different ?
13746 prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
13747 renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix :
13748 NO_CHANGE;
13749 }
13750 /**
13751 * Creates an interpolation binding with 7 expressions.
13752 */
13753 function interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
13754 var bindingIndex = getBindingIndex();
13755 var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
13756 different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
13757 incrementBindingIndex(7);
13758 return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
13759 renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
13760 renderStringify(v5) + i5 + renderStringify(v6) + suffix :
13761 NO_CHANGE;
13762 }
13763 /**
13764 * Creates an interpolation binding with 8 expressions.
13765 */
13766 function interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
13767 var bindingIndex = getBindingIndex();
13768 var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
13769 different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
13770 incrementBindingIndex(8);
13771 return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
13772 renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
13773 renderStringify(v5) + i5 + renderStringify(v6) + i6 + renderStringify(v7) + suffix :
13774 NO_CHANGE;
13775 }
13776
13777 /**
13778 *
13779 * Update an interpolated attribute on an element with single bound value surrounded by text.
13780 *
13781 * Used when the value passed to a property has 1 interpolated value in it:
13782 *
13783 * ```html
13784 * <div attr.title="prefix{{v0}}suffix"></div>
13785 * ```
13786 *
13787 * Its compiled representation is::
13788 *
13789 * ```ts
13790 * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
13791 * ```
13792 *
13793 * @param attrName The name of the attribute to update
13794 * @param prefix Static value used for concatenation only.
13795 * @param v0 Value checked for change.
13796 * @param suffix Static value used for concatenation only.
13797 * @param sanitizer An optional sanitizer function
13798 * @returns itself, so that it may be chained.
13799 * @codeGenApi
13800 */
13801 function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
13802 var lView = getLView();
13803 var interpolatedValue = interpolation1(lView, prefix, v0, suffix);
13804 if (interpolatedValue !== NO_CHANGE) {
13805 var tNode = getSelectedTNode();
13806 elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
13807 ngDevMode &&
13808 storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix);
13809 }
13810 return ɵɵattributeInterpolate1;
13811 }
13812 /**
13813 *
13814 * Update an interpolated attribute on an element with 2 bound values surrounded by text.
13815 *
13816 * Used when the value passed to a property has 2 interpolated values in it:
13817 *
13818 * ```html
13819 * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
13820 * ```
13821 *
13822 * Its compiled representation is::
13823 *
13824 * ```ts
13825 * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
13826 * ```
13827 *
13828 * @param attrName The name of the attribute to update
13829 * @param prefix Static value used for concatenation only.
13830 * @param v0 Value checked for change.
13831 * @param i0 Static value used for concatenation only.
13832 * @param v1 Value checked for change.
13833 * @param suffix Static value used for concatenation only.
13834 * @param sanitizer An optional sanitizer function
13835 * @returns itself, so that it may be chained.
13836 * @codeGenApi
13837 */
13838 function ɵɵattributeInterpolate2(attrName, prefix, v0, i0, v1, suffix, sanitizer, namespace) {
13839 var lView = getLView();
13840 var interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
13841 if (interpolatedValue !== NO_CHANGE) {
13842 var tNode = getSelectedTNode();
13843 elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
13844 ngDevMode &&
13845 storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix);
13846 }
13847 return ɵɵattributeInterpolate2;
13848 }
13849 /**
13850 *
13851 * Update an interpolated attribute on an element with 3 bound values surrounded by text.
13852 *
13853 * Used when the value passed to a property has 3 interpolated values in it:
13854 *
13855 * ```html
13856 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
13857 * ```
13858 *
13859 * Its compiled representation is::
13860 *
13861 * ```ts
13862 * ɵɵattributeInterpolate3(
13863 * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
13864 * ```
13865 *
13866 * @param attrName The name of the attribute to update
13867 * @param prefix Static value used for concatenation only.
13868 * @param v0 Value checked for change.
13869 * @param i0 Static value used for concatenation only.
13870 * @param v1 Value checked for change.
13871 * @param i1 Static value used for concatenation only.
13872 * @param v2 Value checked for change.
13873 * @param suffix Static value used for concatenation only.
13874 * @param sanitizer An optional sanitizer function
13875 * @returns itself, so that it may be chained.
13876 * @codeGenApi
13877 */
13878 function ɵɵattributeInterpolate3(attrName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer, namespace) {
13879 var lView = getLView();
13880 var interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
13881 if (interpolatedValue !== NO_CHANGE) {
13882 var tNode = getSelectedTNode();
13883 elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
13884 ngDevMode &&
13885 storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, i1, suffix);
13886 }
13887 return ɵɵattributeInterpolate3;
13888 }
13889 /**
13890 *
13891 * Update an interpolated attribute on an element with 4 bound values surrounded by text.
13892 *
13893 * Used when the value passed to a property has 4 interpolated values in it:
13894 *
13895 * ```html
13896 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
13897 * ```
13898 *
13899 * Its compiled representation is::
13900 *
13901 * ```ts
13902 * ɵɵattributeInterpolate4(
13903 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
13904 * ```
13905 *
13906 * @param attrName The name of the attribute to update
13907 * @param prefix Static value used for concatenation only.
13908 * @param v0 Value checked for change.
13909 * @param i0 Static value used for concatenation only.
13910 * @param v1 Value checked for change.
13911 * @param i1 Static value used for concatenation only.
13912 * @param v2 Value checked for change.
13913 * @param i2 Static value used for concatenation only.
13914 * @param v3 Value checked for change.
13915 * @param suffix Static value used for concatenation only.
13916 * @param sanitizer An optional sanitizer function
13917 * @returns itself, so that it may be chained.
13918 * @codeGenApi
13919 */
13920 function ɵɵattributeInterpolate4(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer, namespace) {
13921 var lView = getLView();
13922 var interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
13923 if (interpolatedValue !== NO_CHANGE) {
13924 var tNode = getSelectedTNode();
13925 elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
13926 ngDevMode &&
13927 storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix);
13928 }
13929 return ɵɵattributeInterpolate4;
13930 }
13931 /**
13932 *
13933 * Update an interpolated attribute on an element with 5 bound values surrounded by text.
13934 *
13935 * Used when the value passed to a property has 5 interpolated values in it:
13936 *
13937 * ```html
13938 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
13939 * ```
13940 *
13941 * Its compiled representation is::
13942 *
13943 * ```ts
13944 * ɵɵattributeInterpolate5(
13945 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
13946 * ```
13947 *
13948 * @param attrName The name of the attribute to update
13949 * @param prefix Static value used for concatenation only.
13950 * @param v0 Value checked for change.
13951 * @param i0 Static value used for concatenation only.
13952 * @param v1 Value checked for change.
13953 * @param i1 Static value used for concatenation only.
13954 * @param v2 Value checked for change.
13955 * @param i2 Static value used for concatenation only.
13956 * @param v3 Value checked for change.
13957 * @param i3 Static value used for concatenation only.
13958 * @param v4 Value checked for change.
13959 * @param suffix Static value used for concatenation only.
13960 * @param sanitizer An optional sanitizer function
13961 * @returns itself, so that it may be chained.
13962 * @codeGenApi
13963 */
13964 function ɵɵattributeInterpolate5(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer, namespace) {
13965 var lView = getLView();
13966 var interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
13967 if (interpolatedValue !== NO_CHANGE) {
13968 var tNode = getSelectedTNode();
13969 elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
13970 ngDevMode &&
13971 storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix);
13972 }
13973 return ɵɵattributeInterpolate5;
13974 }
13975 /**
13976 *
13977 * Update an interpolated attribute on an element with 6 bound values surrounded by text.
13978 *
13979 * Used when the value passed to a property has 6 interpolated values in it:
13980 *
13981 * ```html
13982 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
13983 * ```
13984 *
13985 * Its compiled representation is::
13986 *
13987 * ```ts
13988 * ɵɵattributeInterpolate6(
13989 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
13990 * ```
13991 *
13992 * @param attrName The name of the attribute to update
13993 * @param prefix Static value used for concatenation only.
13994 * @param v0 Value checked for change.
13995 * @param i0 Static value used for concatenation only.
13996 * @param v1 Value checked for change.
13997 * @param i1 Static value used for concatenation only.
13998 * @param v2 Value checked for change.
13999 * @param i2 Static value used for concatenation only.
14000 * @param v3 Value checked for change.
14001 * @param i3 Static value used for concatenation only.
14002 * @param v4 Value checked for change.
14003 * @param i4 Static value used for concatenation only.
14004 * @param v5 Value checked for change.
14005 * @param suffix Static value used for concatenation only.
14006 * @param sanitizer An optional sanitizer function
14007 * @returns itself, so that it may be chained.
14008 * @codeGenApi
14009 */
14010 function ɵɵattributeInterpolate6(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer, namespace) {
14011 var lView = getLView();
14012 var interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
14013 if (interpolatedValue !== NO_CHANGE) {
14014 var tNode = getSelectedTNode();
14015 elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14016 ngDevMode &&
14017 storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix);
14018 }
14019 return ɵɵattributeInterpolate6;
14020 }
14021 /**
14022 *
14023 * Update an interpolated attribute on an element with 7 bound values surrounded by text.
14024 *
14025 * Used when the value passed to a property has 7 interpolated values in it:
14026 *
14027 * ```html
14028 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
14029 * ```
14030 *
14031 * Its compiled representation is::
14032 *
14033 * ```ts
14034 * ɵɵattributeInterpolate7(
14035 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
14036 * ```
14037 *
14038 * @param attrName The name of the attribute to update
14039 * @param prefix Static value used for concatenation only.
14040 * @param v0 Value checked for change.
14041 * @param i0 Static value used for concatenation only.
14042 * @param v1 Value checked for change.
14043 * @param i1 Static value used for concatenation only.
14044 * @param v2 Value checked for change.
14045 * @param i2 Static value used for concatenation only.
14046 * @param v3 Value checked for change.
14047 * @param i3 Static value used for concatenation only.
14048 * @param v4 Value checked for change.
14049 * @param i4 Static value used for concatenation only.
14050 * @param v5 Value checked for change.
14051 * @param i5 Static value used for concatenation only.
14052 * @param v6 Value checked for change.
14053 * @param suffix Static value used for concatenation only.
14054 * @param sanitizer An optional sanitizer function
14055 * @returns itself, so that it may be chained.
14056 * @codeGenApi
14057 */
14058 function ɵɵattributeInterpolate7(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer, namespace) {
14059 var lView = getLView();
14060 var interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
14061 if (interpolatedValue !== NO_CHANGE) {
14062 var tNode = getSelectedTNode();
14063 elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14064 ngDevMode &&
14065 storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, i5, suffix);
14066 }
14067 return ɵɵattributeInterpolate7;
14068 }
14069 /**
14070 *
14071 * Update an interpolated attribute on an element with 8 bound values surrounded by text.
14072 *
14073 * Used when the value passed to a property has 8 interpolated values in it:
14074 *
14075 * ```html
14076 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
14077 * ```
14078 *
14079 * Its compiled representation is::
14080 *
14081 * ```ts
14082 * ɵɵattributeInterpolate8(
14083 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
14084 * ```
14085 *
14086 * @param attrName The name of the attribute to update
14087 * @param prefix Static value used for concatenation only.
14088 * @param v0 Value checked for change.
14089 * @param i0 Static value used for concatenation only.
14090 * @param v1 Value checked for change.
14091 * @param i1 Static value used for concatenation only.
14092 * @param v2 Value checked for change.
14093 * @param i2 Static value used for concatenation only.
14094 * @param v3 Value checked for change.
14095 * @param i3 Static value used for concatenation only.
14096 * @param v4 Value checked for change.
14097 * @param i4 Static value used for concatenation only.
14098 * @param v5 Value checked for change.
14099 * @param i5 Static value used for concatenation only.
14100 * @param v6 Value checked for change.
14101 * @param i6 Static value used for concatenation only.
14102 * @param v7 Value checked for change.
14103 * @param suffix Static value used for concatenation only.
14104 * @param sanitizer An optional sanitizer function
14105 * @returns itself, so that it may be chained.
14106 * @codeGenApi
14107 */
14108 function ɵɵattributeInterpolate8(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer, namespace) {
14109 var lView = getLView();
14110 var interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
14111 if (interpolatedValue !== NO_CHANGE) {
14112 var tNode = getSelectedTNode();
14113 elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14114 ngDevMode &&
14115 storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, i5, i6, suffix);
14116 }
14117 return ɵɵattributeInterpolate8;
14118 }
14119 /**
14120 * Update an interpolated attribute on an element with 9 or more bound values surrounded by text.
14121 *
14122 * Used when the number of interpolated values exceeds 8.
14123 *
14124 * ```html
14125 * <div
14126 * title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
14127 * ```
14128 *
14129 * Its compiled representation is::
14130 *
14131 * ```ts
14132 * ɵɵattributeInterpolateV(
14133 * 'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
14134 * 'suffix']);
14135 * ```
14136 *
14137 * @param attrName The name of the attribute to update.
14138 * @param values The collection of values and the strings in-between those values, beginning with
14139 * a string prefix and ending with a string suffix.
14140 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
14141 * @param sanitizer An optional sanitizer function
14142 * @returns itself, so that it may be chained.
14143 * @codeGenApi
14144 */
14145 function ɵɵattributeInterpolateV(attrName, values, sanitizer, namespace) {
14146 var lView = getLView();
14147 var interpolated = interpolationV(lView, values);
14148 if (interpolated !== NO_CHANGE) {
14149 var tNode = getSelectedTNode();
14150 elementAttributeInternal(tNode, lView, attrName, interpolated, sanitizer, namespace);
14151 if (ngDevMode) {
14152 var interpolationInBetween = [values[0]]; // prefix
14153 for (var i = 2; i < values.length; i += 2) {
14154 interpolationInBetween.push(values[i]);
14155 }
14156 storePropertyBindingMetadata.apply(void 0, __spread([getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - interpolationInBetween.length + 1], interpolationInBetween));
14157 }
14158 }
14159 return ɵɵattributeInterpolateV;
14160 }
14161
14162 /**
14163 * @license
14164 * Copyright Google LLC All Rights Reserved.
14165 *
14166 * Use of this source code is governed by an MIT-style license that can be
14167 * found in the LICENSE file at https://angular.io/license
14168 */
14169 /**
14170 * Synchronously perform change detection on a component (and possibly its sub-components).
14171 *
14172 * This function triggers change detection in a synchronous way on a component.
14173 *
14174 * @param component The component which the change detection should be performed on.
14175 */
14176 function detectChanges(component) {
14177 var view = getComponentViewByInstance(component);
14178 detectChangesInternal(view[TVIEW], view, component);
14179 }
14180 /**
14181 * Marks the component as dirty (needing change detection). Marking a component dirty will
14182 * schedule a change detection on it at some point in the future.
14183 *
14184 * Marking an already dirty component as dirty won't do anything. Only one outstanding change
14185 * detection can be scheduled per component tree.
14186 *
14187 * @param component Component to mark as dirty.
14188 */
14189 function markDirty(component) {
14190 ngDevMode && assertDefined(component, 'component');
14191 var rootView = markViewDirty(getComponentViewByInstance(component));
14192 ngDevMode && assertDefined(rootView[CONTEXT], 'rootContext should be defined');
14193 scheduleTick(rootView[CONTEXT], 1 /* DetectChanges */);
14194 }
14195 /**
14196 * Used to perform change detection on the whole application.
14197 *
14198 * This is equivalent to `detectChanges`, but invoked on root component. Additionally, `tick`
14199 * executes lifecycle hooks and conditionally checks components based on their
14200 * `ChangeDetectionStrategy` and dirtiness.
14201 *
14202 * The preferred way to trigger change detection is to call `markDirty`. `markDirty` internally
14203 * schedules `tick` using a scheduler in order to coalesce multiple `markDirty` calls into a
14204 * single change detection run. By default, the scheduler is `requestAnimationFrame`, but can
14205 * be changed when calling `renderComponent` and providing the `scheduler` option.
14206 */
14207 function tick(component) {
14208 var rootView = getRootView(component);
14209 var rootContext = rootView[CONTEXT];
14210 tickRootContext(rootContext);
14211 }
14212
14213 /**
14214 * @license
14215 * Copyright Google LLC All Rights Reserved.
14216 *
14217 * Use of this source code is governed by an MIT-style license that can be
14218 * found in the LICENSE file at https://angular.io/license
14219 */
14220 function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) {
14221 ngDevMode && assertFirstCreatePass(tView);
14222 ngDevMode && ngDevMode.firstCreatePass++;
14223 var tViewConsts = tView.consts;
14224 // TODO(pk): refactor getOrCreateTNode to have the "create" only version
14225 var tNode = getOrCreateTNode(tView, lView[T_HOST], index, 0 /* Container */, tagName || null, getConstant(tViewConsts, attrsIndex));
14226 resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
14227 registerPostOrderHooks(tView, tNode);
14228 var embeddedTView = tNode.tViews = createTView(2 /* Embedded */, -1, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts);
14229 var embeddedTViewNode = createTNode(tView, null, 2 /* View */, -1, null, null);
14230 embeddedTViewNode.injectorIndex = tNode.injectorIndex;
14231 embeddedTView.node = embeddedTViewNode;
14232 if (tView.queries !== null) {
14233 tView.queries.template(tView, tNode);
14234 embeddedTView.queries = tView.queries.embeddedTView(tNode);
14235 }
14236 return tNode;
14237 }
14238 /**
14239 * Creates an LContainer for an ng-template (dynamically-inserted view), e.g.
14240 *
14241 * <ng-template #foo>
14242 * <div></div>
14243 * </ng-template>
14244 *
14245 * @param index The index of the container in the data array
14246 * @param templateFn Inline template
14247 * @param decls The number of nodes, local refs, and pipes for this template
14248 * @param vars The number of bindings for this template
14249 * @param tagName The name of the container element, if applicable
14250 * @param attrsIndex Index of template attributes in the `consts` array.
14251 * @param localRefs Index of the local references in the `consts` array.
14252 * @param localRefExtractor A function which extracts local-refs values from the template.
14253 * Defaults to the current element associated with the local-ref.
14254 *
14255 * @codeGenApi
14256 */
14257 function ɵɵtemplate(index, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex, localRefExtractor) {
14258 var lView = getLView();
14259 var tView = getTView();
14260 var adjustedIndex = index + HEADER_OFFSET;
14261 var tNode = tView.firstCreatePass ?
14262 templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) :
14263 tView.data[adjustedIndex];
14264 setPreviousOrParentTNode(tNode, false);
14265 var comment = lView[RENDERER].createComment(ngDevMode ? 'container' : '');
14266 appendChild(tView, lView, comment, tNode);
14267 attachPatchData(comment, lView);
14268 addToViewTree(lView, lView[adjustedIndex] = createLContainer(comment, lView, comment, tNode));
14269 if (isDirectiveHost(tNode)) {
14270 createDirectivesInstances(tView, lView, tNode);
14271 }
14272 if (localRefsIndex != null) {
14273 saveResolvedLocalsInData(lView, tNode, localRefExtractor);
14274 }
14275 }
14276
14277 /**
14278 * @license
14279 * Copyright Google LLC All Rights Reserved.
14280 *
14281 * Use of this source code is governed by an MIT-style license that can be
14282 * found in the LICENSE file at https://angular.io/license
14283 */
14284 /** Store a value in the `data` at a given `index`. */
14285 function store(tView, lView, index, value) {
14286 // We don't store any static data for local variables, so the first time
14287 // we see the template, we should store as null to avoid a sparse array
14288 var adjustedIndex = index + HEADER_OFFSET;
14289 if (adjustedIndex >= tView.data.length) {
14290 tView.data[adjustedIndex] = null;
14291 tView.blueprint[adjustedIndex] = null;
14292 }
14293 lView[adjustedIndex] = value;
14294 }
14295 /**
14296 * Retrieves a local reference from the current contextViewData.
14297 *
14298 * If the reference to retrieve is in a parent view, this instruction is used in conjunction
14299 * with a nextContext() call, which walks up the tree and updates the contextViewData instance.
14300 *
14301 * @param index The index of the local ref in contextViewData.
14302 *
14303 * @codeGenApi
14304 */
14305 function ɵɵreference(index) {
14306 var contextLView = getContextLView();
14307 return load(contextLView, index);
14308 }
14309
14310 /**
14311 * @license
14312 * Copyright Google LLC All Rights Reserved.
14313 *
14314 * Use of this source code is governed by an MIT-style license that can be
14315 * found in the LICENSE file at https://angular.io/license
14316 */
14317 function ɵɵdirectiveInject(token, flags) {
14318 if (flags === void 0) { flags = exports.InjectFlags.Default; }
14319 var lView = getLView();
14320 // Fall back to inject() if view hasn't been created. This situation can happen in tests
14321 // if inject utilities are used before bootstrapping.
14322 if (lView == null)
14323 return ɵɵinject(token, flags);
14324 var tNode = getPreviousOrParentTNode();
14325 return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
14326 }
14327 /**
14328 * Facade for the attribute injection from DI.
14329 *
14330 * @codeGenApi
14331 */
14332 function ɵɵinjectAttribute(attrNameToInject) {
14333 return injectAttributeImpl(getPreviousOrParentTNode(), attrNameToInject);
14334 }
14335 /**
14336 * Throws an error indicating that a factory function could not be generated by the compiler for a
14337 * particular class.
14338 *
14339 * This instruction allows the actual error message to be optimized away when ngDevMode is turned
14340 * off, saving bytes of generated code while still providing a good experience in dev mode.
14341 *
14342 * The name of the class is not mentioned here, but will be in the generated factory function name
14343 * and thus in the stack trace.
14344 *
14345 * @codeGenApi
14346 */
14347 function ɵɵinvalidFactory() {
14348 var msg = ngDevMode ? "This constructor was not compatible with Dependency Injection." : 'invalid';
14349 throw new Error(msg);
14350 }
14351
14352 /**
14353 * @license
14354 * Copyright Google LLC All Rights Reserved.
14355 *
14356 * Use of this source code is governed by an MIT-style license that can be
14357 * found in the LICENSE file at https://angular.io/license
14358 */
14359 /**
14360 * Update a property on a selected element.
14361 *
14362 * Operates on the element selected by index via the {@link select} instruction.
14363 *
14364 * If the property name also exists as an input property on one of the element's directives,
14365 * the component property will be set instead of the element property. This check must
14366 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled
14367 *
14368 * @param propName Name of property. Because it is going to DOM, this is not subject to
14369 * renaming as part of minification.
14370 * @param value New value to write.
14371 * @param sanitizer An optional function used to sanitize the value.
14372 * @returns This function returns itself so that it may be chained
14373 * (e.g. `property('name', ctx.name)('title', ctx.title)`)
14374 *
14375 * @codeGenApi
14376 */
14377 function ɵɵproperty(propName, value, sanitizer) {
14378 var lView = getLView();
14379 var bindingIndex = nextBindingIndex();
14380 if (bindingUpdated(lView, bindingIndex, value)) {
14381 var tView = getTView();
14382 var tNode = getSelectedTNode();
14383 elementPropertyInternal(tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, false);
14384 ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
14385 }
14386 return ɵɵproperty;
14387 }
14388 /**
14389 * Given `<div style="..." my-dir>` and `MyDir` with `@Input('style')` we need to write to
14390 * directive input.
14391 */
14392 function setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isClassBased) {
14393 var inputs = tNode.inputs;
14394 var property = isClassBased ? 'class' : 'style';
14395 // We support both 'class' and `className` hence the fallback.
14396 setInputsForProperty(tView, lView, inputs[property], property, value);
14397 }
14398
14399 /**
14400 * @license
14401 * Copyright Google LLC All Rights Reserved.
14402 *
14403 * Use of this source code is governed by an MIT-style license that can be
14404 * found in the LICENSE file at https://angular.io/license
14405 */
14406 function elementStartFirstCreatePass(index, tView, lView, native, name, attrsIndex, localRefsIndex) {
14407 ngDevMode && assertFirstCreatePass(tView);
14408 ngDevMode && ngDevMode.firstCreatePass++;
14409 var tViewConsts = tView.consts;
14410 var attrs = getConstant(tViewConsts, attrsIndex);
14411 var tNode = getOrCreateTNode(tView, lView[T_HOST], index, 3 /* Element */, name, attrs);
14412 var hasDirectives = resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
14413 ngDevMode && logUnknownElementError(tView, native, tNode, hasDirectives);
14414 if (tNode.attrs !== null) {
14415 computeStaticStyling(tNode, tNode.attrs, false);
14416 }
14417 if (tNode.mergedAttrs !== null) {
14418 computeStaticStyling(tNode, tNode.mergedAttrs, true);
14419 }
14420 if (tView.queries !== null) {
14421 tView.queries.elementStart(tView, tNode);
14422 }
14423 return tNode;
14424 }
14425 /**
14426 * Create DOM element. The instruction must later be followed by `elementEnd()` call.
14427 *
14428 * @param index Index of the element in the LView array
14429 * @param name Name of the DOM Node
14430 * @param attrsIndex Index of the element's attributes in the `consts` array.
14431 * @param localRefsIndex Index of the element's local references in the `consts` array.
14432 *
14433 * Attributes and localRefs are passed as an array of strings where elements with an even index
14434 * hold an attribute name and elements with an odd index hold an attribute value, ex.:
14435 * ['id', 'warning5', 'class', 'alert']
14436 *
14437 * @codeGenApi
14438 */
14439 function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
14440 var lView = getLView();
14441 var tView = getTView();
14442 var adjustedIndex = HEADER_OFFSET + index;
14443 ngDevMode &&
14444 assertEqual(getBindingIndex(), tView.bindingStartIndex, 'elements should be created before any bindings');
14445 ngDevMode && ngDevMode.rendererCreateElement++;
14446 ngDevMode && assertIndexInRange(lView, adjustedIndex);
14447 var renderer = lView[RENDERER];
14448 var native = lView[adjustedIndex] = elementCreate(name, renderer, getNamespace());
14449 var tNode = tView.firstCreatePass ?
14450 elementStartFirstCreatePass(index, tView, lView, native, name, attrsIndex, localRefsIndex) :
14451 tView.data[adjustedIndex];
14452 setPreviousOrParentTNode(tNode, true);
14453 var mergedAttrs = tNode.mergedAttrs;
14454 if (mergedAttrs !== null) {
14455 setUpAttributes(renderer, native, mergedAttrs);
14456 }
14457 var classes = tNode.classes;
14458 if (classes !== null) {
14459 writeDirectClass(renderer, native, classes);
14460 }
14461 var styles = tNode.styles;
14462 if (styles !== null) {
14463 writeDirectStyle(renderer, native, styles);
14464 }
14465 appendChild(tView, lView, native, tNode);
14466 // any immediate children of a component or template container must be pre-emptively
14467 // monkey-patched with the component view data so that the element can be inspected
14468 // later on using any element discovery utility methods (see `element_discovery.ts`)
14469 if (getElementDepthCount() === 0) {
14470 attachPatchData(native, lView);
14471 }
14472 increaseElementDepthCount();
14473 if (isDirectiveHost(tNode)) {
14474 createDirectivesInstances(tView, lView, tNode);
14475 executeContentQueries(tView, tNode, lView);
14476 }
14477 if (localRefsIndex !== null) {
14478 saveResolvedLocalsInData(lView, tNode);
14479 }
14480 }
14481 /**
14482 * Mark the end of the element.
14483 *
14484 * @codeGenApi
14485 */
14486 function ɵɵelementEnd() {
14487 var previousOrParentTNode = getPreviousOrParentTNode();
14488 ngDevMode && assertDefined(previousOrParentTNode, 'No parent node to close.');
14489 if (getIsParent()) {
14490 setIsNotParent();
14491 }
14492 else {
14493 ngDevMode && assertHasParent(getPreviousOrParentTNode());
14494 previousOrParentTNode = previousOrParentTNode.parent;
14495 setPreviousOrParentTNode(previousOrParentTNode, false);
14496 }
14497 var tNode = previousOrParentTNode;
14498 ngDevMode && assertNodeType(tNode, 3 /* Element */);
14499 decreaseElementDepthCount();
14500 var tView = getTView();
14501 if (tView.firstCreatePass) {
14502 registerPostOrderHooks(tView, previousOrParentTNode);
14503 if (isContentQueryHost(previousOrParentTNode)) {
14504 tView.queries.elementEnd(previousOrParentTNode);
14505 }
14506 }
14507 if (tNode.classesWithoutHost != null && hasClassInput(tNode)) {
14508 setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.classesWithoutHost, true);
14509 }
14510 if (tNode.stylesWithoutHost != null && hasStyleInput(tNode)) {
14511 setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.stylesWithoutHost, false);
14512 }
14513 }
14514 /**
14515 * Creates an empty element using {@link elementStart} and {@link elementEnd}
14516 *
14517 * @param index Index of the element in the data array
14518 * @param name Name of the DOM Node
14519 * @param attrsIndex Index of the element's attributes in the `consts` array.
14520 * @param localRefsIndex Index of the element's local references in the `consts` array.
14521 *
14522 * @codeGenApi
14523 */
14524 function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
14525 ɵɵelementStart(index, name, attrsIndex, localRefsIndex);
14526 ɵɵelementEnd();
14527 }
14528 function logUnknownElementError(tView, element, tNode, hasDirectives) {
14529 var schemas = tView.schemas;
14530 // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
14531 // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
14532 // defined as an array (as an empty array in case `schemas` field is not defined) and we should
14533 // execute the check below.
14534 if (schemas === null)
14535 return;
14536 var tagName = tNode.tagName;
14537 // If the element matches any directive, it's considered as valid.
14538 if (!hasDirectives && tagName !== null) {
14539 // The element is unknown if it's an instance of HTMLUnknownElement or it isn't registered
14540 // as a custom element. Note that unknown elements with a dash in their name won't be instances
14541 // of HTMLUnknownElement in browsers that support web components.
14542 var isUnknown =
14543 // Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
14544 // because while most browsers return 'function', IE returns 'object'.
14545 (typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
14546 element instanceof HTMLUnknownElement) ||
14547 (typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
14548 !customElements.get(tagName));
14549 if (isUnknown && !matchingSchemas(tView, tagName)) {
14550 var message = "'" + tagName + "' is not a known element:\n";
14551 message += "1. If '" + tagName + "' is an Angular component, then verify that it is part of this module.\n";
14552 if (tagName && tagName.indexOf('-') > -1) {
14553 message += "2. If '" + tagName + "' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.";
14554 }
14555 else {
14556 message +=
14557 "2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.";
14558 }
14559 console.error(message);
14560 }
14561 }
14562 }
14563
14564 /**
14565 * @license
14566 * Copyright Google LLC All Rights Reserved.
14567 *
14568 * Use of this source code is governed by an MIT-style license that can be
14569 * found in the LICENSE file at https://angular.io/license
14570 */
14571 function elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, localRefsIndex) {
14572 ngDevMode && ngDevMode.firstCreatePass++;
14573 var tViewConsts = tView.consts;
14574 var attrs = getConstant(tViewConsts, attrsIndex);
14575 var tNode = getOrCreateTNode(tView, lView[T_HOST], index, 4 /* ElementContainer */, 'ng-container', attrs);
14576 // While ng-container doesn't necessarily support styling, we use the style context to identify
14577 // and execute directives on the ng-container.
14578 if (attrs !== null) {
14579 computeStaticStyling(tNode, attrs, true);
14580 }
14581 var localRefs = getConstant(tViewConsts, localRefsIndex);
14582 resolveDirectives(tView, lView, tNode, localRefs);
14583 if (tView.queries !== null) {
14584 tView.queries.elementStart(tView, tNode);
14585 }
14586 return tNode;
14587 }
14588 /**
14589 * Creates a logical container for other nodes (<ng-container>) backed by a comment node in the DOM.
14590 * The instruction must later be followed by `elementContainerEnd()` call.
14591 *
14592 * @param index Index of the element in the LView array
14593 * @param attrsIndex Index of the container attributes in the `consts` array.
14594 * @param localRefsIndex Index of the container's local references in the `consts` array.
14595 *
14596 * Even if this instruction accepts a set of attributes no actual attribute values are propagated to
14597 * the DOM (as a comment node can't have attributes). Attributes are here only for directive
14598 * matching purposes and setting initial inputs of directives.
14599 *
14600 * @codeGenApi
14601 */
14602 function ɵɵelementContainerStart(index, attrsIndex, localRefsIndex) {
14603 var lView = getLView();
14604 var tView = getTView();
14605 var adjustedIndex = index + HEADER_OFFSET;
14606 ngDevMode && assertIndexInRange(lView, adjustedIndex);
14607 ngDevMode &&
14608 assertEqual(getBindingIndex(), tView.bindingStartIndex, 'element containers should be created before any bindings');
14609 var tNode = tView.firstCreatePass ?
14610 elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, localRefsIndex) :
14611 tView.data[adjustedIndex];
14612 setPreviousOrParentTNode(tNode, true);
14613 ngDevMode && ngDevMode.rendererCreateComment++;
14614 var native = lView[adjustedIndex] =
14615 lView[RENDERER].createComment(ngDevMode ? 'ng-container' : '');
14616 appendChild(tView, lView, native, tNode);
14617 attachPatchData(native, lView);
14618 if (isDirectiveHost(tNode)) {
14619 createDirectivesInstances(tView, lView, tNode);
14620 executeContentQueries(tView, tNode, lView);
14621 }
14622 if (localRefsIndex != null) {
14623 saveResolvedLocalsInData(lView, tNode);
14624 }
14625 }
14626 /**
14627 * Mark the end of the <ng-container>.
14628 *
14629 * @codeGenApi
14630 */
14631 function ɵɵelementContainerEnd() {
14632 var previousOrParentTNode = getPreviousOrParentTNode();
14633 var tView = getTView();
14634 if (getIsParent()) {
14635 setIsNotParent();
14636 }
14637 else {
14638 ngDevMode && assertHasParent(previousOrParentTNode);
14639 previousOrParentTNode = previousOrParentTNode.parent;
14640 setPreviousOrParentTNode(previousOrParentTNode, false);
14641 }
14642 ngDevMode && assertNodeType(previousOrParentTNode, 4 /* ElementContainer */);
14643 if (tView.firstCreatePass) {
14644 registerPostOrderHooks(tView, previousOrParentTNode);
14645 if (isContentQueryHost(previousOrParentTNode)) {
14646 tView.queries.elementEnd(previousOrParentTNode);
14647 }
14648 }
14649 }
14650 /**
14651 * Creates an empty logical container using {@link elementContainerStart}
14652 * and {@link elementContainerEnd}
14653 *
14654 * @param index Index of the element in the LView array
14655 * @param attrsIndex Index of the container attributes in the `consts` array.
14656 * @param localRefsIndex Index of the container's local references in the `consts` array.
14657 *
14658 * @codeGenApi
14659 */
14660 function ɵɵelementContainer(index, attrsIndex, localRefsIndex) {
14661 ɵɵelementContainerStart(index, attrsIndex, localRefsIndex);
14662 ɵɵelementContainerEnd();
14663 }
14664
14665 /**
14666 * Returns the current OpaqueViewState instance.
14667 *
14668 * Used in conjunction with the restoreView() instruction to save a snapshot
14669 * of the current view and restore it when listeners are invoked. This allows
14670 * walking the declaration view tree in listeners to get vars from parent views.
14671 *
14672 * @codeGenApi
14673 */
14674 function ɵɵgetCurrentView() {
14675 return getLView();
14676 }
14677
14678 /**
14679 * @license
14680 * Copyright Google LLC All Rights Reserved.
14681 *
14682 * Use of this source code is governed by an MIT-style license that can be
14683 * found in the LICENSE file at https://angular.io/license
14684 */
14685 /**
14686 * Determine if the argument is shaped like a Promise
14687 */
14688 function isPromise(obj) {
14689 // allow any Promise/A+ compliant thenable.
14690 // It's up to the caller to ensure that obj.then conforms to the spec
14691 return !!obj && typeof obj.then === 'function';
14692 }
14693 /**
14694 * Determine if the argument is an Observable
14695 */
14696 function isObservable(obj) {
14697 // TODO: use isObservable once we update pass rxjs 6.1
14698 // https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md#610-2018-05-03
14699 return !!obj && typeof obj.subscribe === 'function';
14700 }
14701
14702 /**
14703 * @license
14704 * Copyright Google LLC All Rights Reserved.
14705 *
14706 * Use of this source code is governed by an MIT-style license that can be
14707 * found in the LICENSE file at https://angular.io/license
14708 */
14709 /**
14710 * Adds an event listener to the current node.
14711 *
14712 * If an output exists on one of the node's directives, it also subscribes to the output
14713 * and saves the subscription for later cleanup.
14714 *
14715 * @param eventName Name of the event
14716 * @param listenerFn The function to be called when event emits
14717 * @param useCapture Whether or not to use capture in event listener
14718 * @param eventTargetResolver Function that returns global target information in case this listener
14719 * should be attached to a global object like window, document or body
14720 *
14721 * @codeGenApi
14722 */
14723 function ɵɵlistener(eventName, listenerFn, useCapture, eventTargetResolver) {
14724 if (useCapture === void 0) { useCapture = false; }
14725 var lView = getLView();
14726 var tView = getTView();
14727 var tNode = getPreviousOrParentTNode();
14728 listenerInternal(tView, lView, lView[RENDERER], tNode, eventName, listenerFn, useCapture, eventTargetResolver);
14729 return ɵɵlistener;
14730 }
14731 /**
14732 * Registers a synthetic host listener (e.g. `(@foo.start)`) on a component or directive.
14733 *
14734 * This instruction is for compatibility purposes and is designed to ensure that a
14735 * synthetic host listener (e.g. `@HostListener('@foo.start')`) properly gets rendered
14736 * in the component's renderer. Normally all host listeners are evaluated with the
14737 * parent component's renderer, but, in the case of animation @triggers, they need
14738 * to be evaluated with the sub component's renderer (because that's where the
14739 * animation triggers are defined).
14740 *
14741 * Do not use this instruction as a replacement for `listener`. This instruction
14742 * only exists to ensure compatibility with the ViewEngine's host binding behavior.
14743 *
14744 * @param eventName Name of the event
14745 * @param listenerFn The function to be called when event emits
14746 * @param useCapture Whether or not to use capture in event listener
14747 * @param eventTargetResolver Function that returns global target information in case this listener
14748 * should be attached to a global object like window, document or body
14749 *
14750 * @codeGenApi
14751 */
14752 function ɵɵsyntheticHostListener(eventName, listenerFn, useCapture, eventTargetResolver) {
14753 if (useCapture === void 0) { useCapture = false; }
14754 var tNode = getPreviousOrParentTNode();
14755 var lView = getLView();
14756 var tView = getTView();
14757 var currentDef = getCurrentDirectiveDef(tView.data);
14758 var renderer = loadComponentRenderer(currentDef, tNode, lView);
14759 listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn, useCapture, eventTargetResolver);
14760 return ɵɵsyntheticHostListener;
14761 }
14762 /**
14763 * A utility function that checks if a given element has already an event handler registered for an
14764 * event with a specified name. The TView.cleanup data structure is used to find out which events
14765 * are registered for a given element.
14766 */
14767 function findExistingListener(tView, lView, eventName, tNodeIdx) {
14768 var tCleanup = tView.cleanup;
14769 if (tCleanup != null) {
14770 for (var i = 0; i < tCleanup.length - 1; i += 2) {
14771 var cleanupEventName = tCleanup[i];
14772 if (cleanupEventName === eventName && tCleanup[i + 1] === tNodeIdx) {
14773 // We have found a matching event name on the same node but it might not have been
14774 // registered yet, so we must explicitly verify entries in the LView cleanup data
14775 // structures.
14776 var lCleanup = lView[CLEANUP];
14777 var listenerIdxInLCleanup = tCleanup[i + 2];
14778 return lCleanup.length > listenerIdxInLCleanup ? lCleanup[listenerIdxInLCleanup] : null;
14779 }
14780 // TView.cleanup can have a mix of 4-elements entries (for event handler cleanups) or
14781 // 2-element entries (for directive and queries destroy hooks). As such we can encounter
14782 // blocks of 4 or 2 items in the tView.cleanup and this is why we iterate over 2 elements
14783 // first and jump another 2 elements if we detect listeners cleanup (4 elements). Also check
14784 // documentation of TView.cleanup for more details of this data structure layout.
14785 if (typeof cleanupEventName === 'string') {
14786 i += 2;
14787 }
14788 }
14789 }
14790 return null;
14791 }
14792 function listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn, useCapture, eventTargetResolver) {
14793 if (useCapture === void 0) { useCapture = false; }
14794 var isTNodeDirectiveHost = isDirectiveHost(tNode);
14795 var firstCreatePass = tView.firstCreatePass;
14796 var tCleanup = firstCreatePass && (tView.cleanup || (tView.cleanup = []));
14797 // When the ɵɵlistener instruction was generated and is executed we know that there is either a
14798 // native listener or a directive output on this element. As such we we know that we will have to
14799 // register a listener and store its cleanup function on LView.
14800 var lCleanup = getLCleanup(lView);
14801 ngDevMode &&
14802 assertNodeOfPossibleTypes(tNode, [3 /* Element */, 0 /* Container */, 4 /* ElementContainer */]);
14803 var processOutputs = true;
14804 // add native event listener - applicable to elements only
14805 if (tNode.type === 3 /* Element */) {
14806 var native = getNativeByTNode(tNode, lView);
14807 var resolved = eventTargetResolver ? eventTargetResolver(native) : EMPTY_OBJ;
14808 var target = resolved.target || native;
14809 var lCleanupIndex = lCleanup.length;
14810 var idxOrTargetGetter = eventTargetResolver ?
14811 function (_lView) { return eventTargetResolver(unwrapRNode(_lView[tNode.index])).target; } :
14812 tNode.index;
14813 // In order to match current behavior, native DOM event listeners must be added for all
14814 // events (including outputs).
14815 if (isProceduralRenderer(renderer)) {
14816 // There might be cases where multiple directives on the same element try to register an event
14817 // handler function for the same event. In this situation we want to avoid registration of
14818 // several native listeners as each registration would be intercepted by NgZone and
14819 // trigger change detection. This would mean that a single user action would result in several
14820 // change detections being invoked. To avoid this situation we want to have only one call to
14821 // native handler registration (for the same element and same type of event).
14822 //
14823 // In order to have just one native event handler in presence of multiple handler functions,
14824 // we just register a first handler function as a native event listener and then chain
14825 // (coalesce) other handler functions on top of the first native handler function.
14826 var existingListener = null;
14827 // Please note that the coalescing described here doesn't happen for events specifying an
14828 // alternative target (ex. (document:click)) - this is to keep backward compatibility with the
14829 // view engine.
14830 // Also, we don't have to search for existing listeners is there are no directives
14831 // matching on a given node as we can't register multiple event handlers for the same event in
14832 // a template (this would mean having duplicate attributes).
14833 if (!eventTargetResolver && isTNodeDirectiveHost) {
14834 existingListener = findExistingListener(tView, lView, eventName, tNode.index);
14835 }
14836 if (existingListener !== null) {
14837 // Attach a new listener to coalesced listeners list, maintaining the order in which
14838 // listeners are registered. For performance reasons, we keep a reference to the last
14839 // listener in that list (in `__ngLastListenerFn__` field), so we can avoid going through
14840 // the entire set each time we need to add a new listener.
14841 var lastListenerFn = existingListener.__ngLastListenerFn__ || existingListener;
14842 lastListenerFn.__ngNextListenerFn__ = listenerFn;
14843 existingListener.__ngLastListenerFn__ = listenerFn;
14844 processOutputs = false;
14845 }
14846 else {
14847 // The first argument of `listen` function in Procedural Renderer is:
14848 // - either a target name (as a string) in case of global target (window, document, body)
14849 // - or element reference (in all other cases)
14850 listenerFn = wrapListener(tNode, lView, listenerFn, false /** preventDefault */);
14851 var cleanupFn = renderer.listen(resolved.name || target, eventName, listenerFn);
14852 ngDevMode && ngDevMode.rendererAddEventListener++;
14853 lCleanup.push(listenerFn, cleanupFn);
14854 tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, lCleanupIndex + 1);
14855 }
14856 }
14857 else {
14858 listenerFn = wrapListener(tNode, lView, listenerFn, true /** preventDefault */);
14859 target.addEventListener(eventName, listenerFn, useCapture);
14860 ngDevMode && ngDevMode.rendererAddEventListener++;
14861 lCleanup.push(listenerFn);
14862 tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, useCapture);
14863 }
14864 }
14865 // subscribe to directive outputs
14866 var outputs = tNode.outputs;
14867 var props;
14868 if (processOutputs && outputs !== null && (props = outputs[eventName])) {
14869 var propsLength = props.length;
14870 if (propsLength) {
14871 for (var i = 0; i < propsLength; i += 2) {
14872 var index = props[i];
14873 ngDevMode && assertIndexInRange(lView, index);
14874 var minifiedName = props[i + 1];
14875 var directiveInstance = lView[index];
14876 var output = directiveInstance[minifiedName];
14877 if (ngDevMode && !isObservable(output)) {
14878 throw new Error("@Output " + minifiedName + " not initialized in '" + directiveInstance.constructor.name + "'.");
14879 }
14880 var subscription = output.subscribe(listenerFn);
14881 var idx = lCleanup.length;
14882 lCleanup.push(listenerFn, subscription);
14883 tCleanup && tCleanup.push(eventName, tNode.index, idx, -(idx + 1));
14884 }
14885 }
14886 }
14887 }
14888 function executeListenerWithErrorHandling(lView, listenerFn, e) {
14889 try {
14890 // Only explicitly returning false from a listener should preventDefault
14891 return listenerFn(e) !== false;
14892 }
14893 catch (error) {
14894 handleError(lView, error);
14895 return false;
14896 }
14897 }
14898 /**
14899 * Wraps an event listener with a function that marks ancestors dirty and prevents default behavior,
14900 * if applicable.
14901 *
14902 * @param tNode The TNode associated with this listener
14903 * @param lView The LView that contains this listener
14904 * @param listenerFn The listener function to call
14905 * @param wrapWithPreventDefault Whether or not to prevent default behavior
14906 * (the procedural renderer does this already, so in those cases, we should skip)
14907 */
14908 function wrapListener(tNode, lView, listenerFn, wrapWithPreventDefault) {
14909 // Note: we are performing most of the work in the listener function itself
14910 // to optimize listener registration.
14911 return function wrapListenerIn_markDirtyAndPreventDefault(e) {
14912 // Ivy uses `Function` as a special token that allows us to unwrap the function
14913 // so that it can be invoked programmatically by `DebugNode.triggerEventHandler`.
14914 if (e === Function) {
14915 return listenerFn;
14916 }
14917 // In order to be backwards compatible with View Engine, events on component host nodes
14918 // must also mark the component view itself dirty (i.e. the view that it owns).
14919 var startView = tNode.flags & 2 /* isComponentHost */ ?
14920 getComponentLViewByIndex(tNode.index, lView) :
14921 lView;
14922 // See interfaces/view.ts for more on LViewFlags.ManualOnPush
14923 if ((lView[FLAGS] & 32 /* ManualOnPush */) === 0) {
14924 markViewDirty(startView);
14925 }
14926 var result = executeListenerWithErrorHandling(lView, listenerFn, e);
14927 // A just-invoked listener function might have coalesced listeners so we need to check for
14928 // their presence and invoke as needed.
14929 var nextListenerFn = wrapListenerIn_markDirtyAndPreventDefault.__ngNextListenerFn__;
14930 while (nextListenerFn) {
14931 // We should prevent default if any of the listeners explicitly return false
14932 result = executeListenerWithErrorHandling(lView, nextListenerFn, e) && result;
14933 nextListenerFn = nextListenerFn.__ngNextListenerFn__;
14934 }
14935 if (wrapWithPreventDefault && result === false) {
14936 e.preventDefault();
14937 // Necessary for legacy browsers that don't support preventDefault (e.g. IE)
14938 e.returnValue = false;
14939 }
14940 return result;
14941 };
14942 }
14943
14944 /**
14945 * @license
14946 * Copyright Google LLC All Rights Reserved.
14947 *
14948 * Use of this source code is governed by an MIT-style license that can be
14949 * found in the LICENSE file at https://angular.io/license
14950 */
14951
14952 /**
14953 * @license
14954 * Copyright Google LLC All Rights Reserved.
14955 *
14956 * Use of this source code is governed by an MIT-style license that can be
14957 * found in the LICENSE file at https://angular.io/license
14958 */
14959 /**
14960 * Retrieves a context at the level specified and saves it as the global, contextViewData.
14961 * Will get the next level up if level is not specified.
14962 *
14963 * This is used to save contexts of parent views so they can be bound in embedded views, or
14964 * in conjunction with reference() to bind a ref from a parent view.
14965 *
14966 * @param level The relative level of the view from which to grab context compared to contextVewData
14967 * @returns context
14968 *
14969 * @codeGenApi
14970 */
14971 function ɵɵnextContext(level) {
14972 if (level === void 0) { level = 1; }
14973 return nextContextImpl(level);
14974 }
14975
14976 /**
14977 * @license
14978 * Copyright Google LLC All Rights Reserved.
14979 *
14980 * Use of this source code is governed by an MIT-style license that can be
14981 * found in the LICENSE file at https://angular.io/license
14982 */
14983 /**
14984 * Checks a given node against matching projection slots and returns the
14985 * determined slot index. Returns "null" if no slot matched the given node.
14986 *
14987 * This function takes into account the parsed ngProjectAs selector from the
14988 * node's attributes. If present, it will check whether the ngProjectAs selector
14989 * matches any of the projection slot selectors.
14990 */
14991 function matchingProjectionSlotIndex(tNode, projectionSlots) {
14992 var wildcardNgContentIndex = null;
14993 var ngProjectAsAttrVal = getProjectAsAttrValue(tNode);
14994 for (var i = 0; i < projectionSlots.length; i++) {
14995 var slotValue = projectionSlots[i];
14996 // The last wildcard projection slot should match all nodes which aren't matching
14997 // any selector. This is necessary to be backwards compatible with view engine.
14998 if (slotValue === '*') {
14999 wildcardNgContentIndex = i;
15000 continue;
15001 }
15002 // If we ran into an `ngProjectAs` attribute, we should match its parsed selector
15003 // to the list of selectors, otherwise we fall back to matching against the node.
15004 if (ngProjectAsAttrVal === null ?
15005 isNodeMatchingSelectorList(tNode, slotValue, /* isProjectionMode */ true) :
15006 isSelectorInSelectorList(ngProjectAsAttrVal, slotValue)) {
15007 return i; // first matching selector "captures" a given node
15008 }
15009 }
15010 return wildcardNgContentIndex;
15011 }
15012 /**
15013 * Instruction to distribute projectable nodes among <ng-content> occurrences in a given template.
15014 * It takes all the selectors from the entire component's template and decides where
15015 * each projected node belongs (it re-distributes nodes among "buckets" where each "bucket" is
15016 * backed by a selector).
15017 *
15018 * This function requires CSS selectors to be provided in 2 forms: parsed (by a compiler) and text,
15019 * un-parsed form.
15020 *
15021 * The parsed form is needed for efficient matching of a node against a given CSS selector.
15022 * The un-parsed, textual form is needed for support of the ngProjectAs attribute.
15023 *
15024 * Having a CSS selector in 2 different formats is not ideal, but alternatives have even more
15025 * drawbacks:
15026 * - having only a textual form would require runtime parsing of CSS selectors;
15027 * - we can't have only a parsed as we can't re-construct textual form from it (as entered by a
15028 * template author).
15029 *
15030 * @param projectionSlots? A collection of projection slots. A projection slot can be based
15031 * on a parsed CSS selectors or set to the wildcard selector ("*") in order to match
15032 * all nodes which do not match any selector. If not specified, a single wildcard
15033 * selector projection slot will be defined.
15034 *
15035 * @codeGenApi
15036 */
15037 function ɵɵprojectionDef(projectionSlots) {
15038 var componentNode = getLView()[DECLARATION_COMPONENT_VIEW][T_HOST];
15039 if (!componentNode.projection) {
15040 // If no explicit projection slots are defined, fall back to a single
15041 // projection slot with the wildcard selector.
15042 var numProjectionSlots = projectionSlots ? projectionSlots.length : 1;
15043 var projectionHeads = componentNode.projection =
15044 newArray(numProjectionSlots, null);
15045 var tails = projectionHeads.slice();
15046 var componentChild = componentNode.child;
15047 while (componentChild !== null) {
15048 var slotIndex = projectionSlots ? matchingProjectionSlotIndex(componentChild, projectionSlots) : 0;
15049 if (slotIndex !== null) {
15050 if (tails[slotIndex]) {
15051 tails[slotIndex].projectionNext = componentChild;
15052 }
15053 else {
15054 projectionHeads[slotIndex] = componentChild;
15055 }
15056 tails[slotIndex] = componentChild;
15057 }
15058 componentChild = componentChild.next;
15059 }
15060 }
15061 }
15062 var delayProjection = false;
15063 function setDelayProjection(value) {
15064 delayProjection = value;
15065 }
15066 /**
15067 * Inserts previously re-distributed projected nodes. This instruction must be preceded by a call
15068 * to the projectionDef instruction.
15069 *
15070 * @param nodeIndex
15071 * @param selectorIndex:
15072 * - 0 when the selector is `*` (or unspecified as this is the default value),
15073 * - 1 based index of the selector from the {@link projectionDef}
15074 *
15075 * @codeGenApi
15076 */
15077 function ɵɵprojection(nodeIndex, selectorIndex, attrs) {
15078 if (selectorIndex === void 0) { selectorIndex = 0; }
15079 var lView = getLView();
15080 var tView = getTView();
15081 var tProjectionNode = getOrCreateTNode(tView, lView[T_HOST], nodeIndex, 1 /* Projection */, null, attrs || null);
15082 // We can't use viewData[HOST_NODE] because projection nodes can be nested in embedded views.
15083 if (tProjectionNode.projection === null)
15084 tProjectionNode.projection = selectorIndex;
15085 // `<ng-content>` has no content
15086 setIsNotParent();
15087 // We might need to delay the projection of nodes if they are in the middle of an i18n block
15088 if (!delayProjection) {
15089 // re-distribution of projectable nodes is stored on a component's view level
15090 applyProjection(tView, lView, tProjectionNode);
15091 }
15092 }
15093
15094 /**
15095 *
15096 * Update an interpolated property on an element with a lone bound value
15097 *
15098 * Used when the value passed to a property has 1 interpolated value in it, an no additional text
15099 * surrounds that interpolated value:
15100 *
15101 * ```html
15102 * <div title="{{v0}}"></div>
15103 * ```
15104 *
15105 * Its compiled representation is::
15106 *
15107 * ```ts
15108 * ɵɵpropertyInterpolate('title', v0);
15109 * ```
15110 *
15111 * If the property name also exists as an input property on one of the element's directives,
15112 * the component property will be set instead of the element property. This check must
15113 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15114 *
15115 * @param propName The name of the property to update
15116 * @param prefix Static value used for concatenation only.
15117 * @param v0 Value checked for change.
15118 * @param suffix Static value used for concatenation only.
15119 * @param sanitizer An optional sanitizer function
15120 * @returns itself, so that it may be chained.
15121 * @codeGenApi
15122 */
15123 function ɵɵpropertyInterpolate(propName, v0, sanitizer) {
15124 ɵɵpropertyInterpolate1(propName, '', v0, '', sanitizer);
15125 return ɵɵpropertyInterpolate;
15126 }
15127 /**
15128 *
15129 * Update an interpolated property on an element with single bound value surrounded by text.
15130 *
15131 * Used when the value passed to a property has 1 interpolated value in it:
15132 *
15133 * ```html
15134 * <div title="prefix{{v0}}suffix"></div>
15135 * ```
15136 *
15137 * Its compiled representation is::
15138 *
15139 * ```ts
15140 * ɵɵpropertyInterpolate1('title', 'prefix', v0, 'suffix');
15141 * ```
15142 *
15143 * If the property name also exists as an input property on one of the element's directives,
15144 * the component property will be set instead of the element property. This check must
15145 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15146 *
15147 * @param propName The name of the property to update
15148 * @param prefix Static value used for concatenation only.
15149 * @param v0 Value checked for change.
15150 * @param suffix Static value used for concatenation only.
15151 * @param sanitizer An optional sanitizer function
15152 * @returns itself, so that it may be chained.
15153 * @codeGenApi
15154 */
15155 function ɵɵpropertyInterpolate1(propName, prefix, v0, suffix, sanitizer) {
15156 var lView = getLView();
15157 var interpolatedValue = interpolation1(lView, prefix, v0, suffix);
15158 if (interpolatedValue !== NO_CHANGE) {
15159 var tView = getTView();
15160 var tNode = getSelectedTNode();
15161 elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
15162 ngDevMode &&
15163 storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 1, prefix, suffix);
15164 }
15165 return ɵɵpropertyInterpolate1;
15166 }
15167 /**
15168 *
15169 * Update an interpolated property on an element with 2 bound values surrounded by text.
15170 *
15171 * Used when the value passed to a property has 2 interpolated values in it:
15172 *
15173 * ```html
15174 * <div title="prefix{{v0}}-{{v1}}suffix"></div>
15175 * ```
15176 *
15177 * Its compiled representation is::
15178 *
15179 * ```ts
15180 * ɵɵpropertyInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
15181 * ```
15182 *
15183 * If the property name also exists as an input property on one of the element's directives,
15184 * the component property will be set instead of the element property. This check must
15185 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15186 *
15187 * @param propName The name of the property to update
15188 * @param prefix Static value used for concatenation only.
15189 * @param v0 Value checked for change.
15190 * @param i0 Static value used for concatenation only.
15191 * @param v1 Value checked for change.
15192 * @param suffix Static value used for concatenation only.
15193 * @param sanitizer An optional sanitizer function
15194 * @returns itself, so that it may be chained.
15195 * @codeGenApi
15196 */
15197 function ɵɵpropertyInterpolate2(propName, prefix, v0, i0, v1, suffix, sanitizer) {
15198 var lView = getLView();
15199 var interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
15200 if (interpolatedValue !== NO_CHANGE) {
15201 var tView = getTView();
15202 var tNode = getSelectedTNode();
15203 elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
15204 ngDevMode &&
15205 storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 2, prefix, i0, suffix);
15206 }
15207 return ɵɵpropertyInterpolate2;
15208 }
15209 /**
15210 *
15211 * Update an interpolated property on an element with 3 bound values surrounded by text.
15212 *
15213 * Used when the value passed to a property has 3 interpolated values in it:
15214 *
15215 * ```html
15216 * <div title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
15217 * ```
15218 *
15219 * Its compiled representation is::
15220 *
15221 * ```ts
15222 * ɵɵpropertyInterpolate3(
15223 * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
15224 * ```
15225 *
15226 * If the property name also exists as an input property on one of the element's directives,
15227 * the component property will be set instead of the element property. This check must
15228 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15229 *
15230 * @param propName The name of the property to update
15231 * @param prefix Static value used for concatenation only.
15232 * @param v0 Value checked for change.
15233 * @param i0 Static value used for concatenation only.
15234 * @param v1 Value checked for change.
15235 * @param i1 Static value used for concatenation only.
15236 * @param v2 Value checked for change.
15237 * @param suffix Static value used for concatenation only.
15238 * @param sanitizer An optional sanitizer function
15239 * @returns itself, so that it may be chained.
15240 * @codeGenApi
15241 */
15242 function ɵɵpropertyInterpolate3(propName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer) {
15243 var lView = getLView();
15244 var interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
15245 if (interpolatedValue !== NO_CHANGE) {
15246 var tView = getTView();
15247 var tNode = getSelectedTNode();
15248 elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
15249 ngDevMode &&
15250 storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 3, prefix, i0, i1, suffix);
15251 }
15252 return ɵɵpropertyInterpolate3;
15253 }
15254 /**
15255 *
15256 * Update an interpolated property on an element with 4 bound values surrounded by text.
15257 *
15258 * Used when the value passed to a property has 4 interpolated values in it:
15259 *
15260 * ```html
15261 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
15262 * ```
15263 *
15264 * Its compiled representation is::
15265 *
15266 * ```ts
15267 * ɵɵpropertyInterpolate4(
15268 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
15269 * ```
15270 *
15271 * If the property name also exists as an input property on one of the element's directives,
15272 * the component property will be set instead of the element property. This check must
15273 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15274 *
15275 * @param propName The name of the property to update
15276 * @param prefix Static value used for concatenation only.
15277 * @param v0 Value checked for change.
15278 * @param i0 Static value used for concatenation only.
15279 * @param v1 Value checked for change.
15280 * @param i1 Static value used for concatenation only.
15281 * @param v2 Value checked for change.
15282 * @param i2 Static value used for concatenation only.
15283 * @param v3 Value checked for change.
15284 * @param suffix Static value used for concatenation only.
15285 * @param sanitizer An optional sanitizer function
15286 * @returns itself, so that it may be chained.
15287 * @codeGenApi
15288 */
15289 function ɵɵpropertyInterpolate4(propName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer) {
15290 var lView = getLView();
15291 var interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
15292 if (interpolatedValue !== NO_CHANGE) {
15293 var tView = getTView();
15294 var tNode = getSelectedTNode();
15295 elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
15296 ngDevMode &&
15297 storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix);
15298 }
15299 return ɵɵpropertyInterpolate4;
15300 }
15301 /**
15302 *
15303 * Update an interpolated property on an element with 5 bound values surrounded by text.
15304 *
15305 * Used when the value passed to a property has 5 interpolated values in it:
15306 *
15307 * ```html
15308 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
15309 * ```
15310 *
15311 * Its compiled representation is::
15312 *
15313 * ```ts
15314 * ɵɵpropertyInterpolate5(
15315 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
15316 * ```
15317 *
15318 * If the property name also exists as an input property on one of the element's directives,
15319 * the component property will be set instead of the element property. This check must
15320 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15321 *
15322 * @param propName The name of the property to update
15323 * @param prefix Static value used for concatenation only.
15324 * @param v0 Value checked for change.
15325 * @param i0 Static value used for concatenation only.
15326 * @param v1 Value checked for change.
15327 * @param i1 Static value used for concatenation only.
15328 * @param v2 Value checked for change.
15329 * @param i2 Static value used for concatenation only.
15330 * @param v3 Value checked for change.
15331 * @param i3 Static value used for concatenation only.
15332 * @param v4 Value checked for change.
15333 * @param suffix Static value used for concatenation only.
15334 * @param sanitizer An optional sanitizer function
15335 * @returns itself, so that it may be chained.
15336 * @codeGenApi
15337 */
15338 function ɵɵpropertyInterpolate5(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer) {
15339 var lView = getLView();
15340 var interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
15341 if (interpolatedValue !== NO_CHANGE) {
15342 var tView = getTView();
15343 var tNode = getSelectedTNode();
15344 elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
15345 ngDevMode &&
15346 storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix);
15347 }
15348 return ɵɵpropertyInterpolate5;
15349 }
15350 /**
15351 *
15352 * Update an interpolated property on an element with 6 bound values surrounded by text.
15353 *
15354 * Used when the value passed to a property has 6 interpolated values in it:
15355 *
15356 * ```html
15357 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
15358 * ```
15359 *
15360 * Its compiled representation is::
15361 *
15362 * ```ts
15363 * ɵɵpropertyInterpolate6(
15364 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
15365 * ```
15366 *
15367 * If the property name also exists as an input property on one of the element's directives,
15368 * the component property will be set instead of the element property. This check must
15369 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15370 *
15371 * @param propName The name of the property to update
15372 * @param prefix Static value used for concatenation only.
15373 * @param v0 Value checked for change.
15374 * @param i0 Static value used for concatenation only.
15375 * @param v1 Value checked for change.
15376 * @param i1 Static value used for concatenation only.
15377 * @param v2 Value checked for change.
15378 * @param i2 Static value used for concatenation only.
15379 * @param v3 Value checked for change.
15380 * @param i3 Static value used for concatenation only.
15381 * @param v4 Value checked for change.
15382 * @param i4 Static value used for concatenation only.
15383 * @param v5 Value checked for change.
15384 * @param suffix Static value used for concatenation only.
15385 * @param sanitizer An optional sanitizer function
15386 * @returns itself, so that it may be chained.
15387 * @codeGenApi
15388 */
15389 function ɵɵpropertyInterpolate6(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer) {
15390 var lView = getLView();
15391 var interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
15392 if (interpolatedValue !== NO_CHANGE) {
15393 var tView = getTView();
15394 var tNode = getSelectedTNode();
15395 elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
15396 ngDevMode &&
15397 storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix);
15398 }
15399 return ɵɵpropertyInterpolate6;
15400 }
15401 /**
15402 *
15403 * Update an interpolated property on an element with 7 bound values surrounded by text.
15404 *
15405 * Used when the value passed to a property has 7 interpolated values in it:
15406 *
15407 * ```html
15408 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
15409 * ```
15410 *
15411 * Its compiled representation is::
15412 *
15413 * ```ts
15414 * ɵɵpropertyInterpolate7(
15415 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
15416 * ```
15417 *
15418 * If the property name also exists as an input property on one of the element's directives,
15419 * the component property will be set instead of the element property. This check must
15420 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15421 *
15422 * @param propName The name of the property to update
15423 * @param prefix Static value used for concatenation only.
15424 * @param v0 Value checked for change.
15425 * @param i0 Static value used for concatenation only.
15426 * @param v1 Value checked for change.
15427 * @param i1 Static value used for concatenation only.
15428 * @param v2 Value checked for change.
15429 * @param i2 Static value used for concatenation only.
15430 * @param v3 Value checked for change.
15431 * @param i3 Static value used for concatenation only.
15432 * @param v4 Value checked for change.
15433 * @param i4 Static value used for concatenation only.
15434 * @param v5 Value checked for change.
15435 * @param i5 Static value used for concatenation only.
15436 * @param v6 Value checked for change.
15437 * @param suffix Static value used for concatenation only.
15438 * @param sanitizer An optional sanitizer function
15439 * @returns itself, so that it may be chained.
15440 * @codeGenApi
15441 */
15442 function ɵɵpropertyInterpolate7(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer) {
15443 var lView = getLView();
15444 var interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
15445 if (interpolatedValue !== NO_CHANGE) {
15446 var tView = getTView();
15447 var tNode = getSelectedTNode();
15448 elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
15449 ngDevMode &&
15450 storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, i5, suffix);
15451 }
15452 return ɵɵpropertyInterpolate7;
15453 }
15454 /**
15455 *
15456 * Update an interpolated property on an element with 8 bound values surrounded by text.
15457 *
15458 * Used when the value passed to a property has 8 interpolated values in it:
15459 *
15460 * ```html
15461 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
15462 * ```
15463 *
15464 * Its compiled representation is::
15465 *
15466 * ```ts
15467 * ɵɵpropertyInterpolate8(
15468 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
15469 * ```
15470 *
15471 * If the property name also exists as an input property on one of the element's directives,
15472 * the component property will be set instead of the element property. This check must
15473 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15474 *
15475 * @param propName The name of the property to update
15476 * @param prefix Static value used for concatenation only.
15477 * @param v0 Value checked for change.
15478 * @param i0 Static value used for concatenation only.
15479 * @param v1 Value checked for change.
15480 * @param i1 Static value used for concatenation only.
15481 * @param v2 Value checked for change.
15482 * @param i2 Static value used for concatenation only.
15483 * @param v3 Value checked for change.
15484 * @param i3 Static value used for concatenation only.
15485 * @param v4 Value checked for change.
15486 * @param i4 Static value used for concatenation only.
15487 * @param v5 Value checked for change.
15488 * @param i5 Static value used for concatenation only.
15489 * @param v6 Value checked for change.
15490 * @param i6 Static value used for concatenation only.
15491 * @param v7 Value checked for change.
15492 * @param suffix Static value used for concatenation only.
15493 * @param sanitizer An optional sanitizer function
15494 * @returns itself, so that it may be chained.
15495 * @codeGenApi
15496 */
15497 function ɵɵpropertyInterpolate8(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer) {
15498 var lView = getLView();
15499 var interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
15500 if (interpolatedValue !== NO_CHANGE) {
15501 var tView = getTView();
15502 var tNode = getSelectedTNode();
15503 elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
15504 ngDevMode &&
15505 storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, i5, i6, suffix);
15506 }
15507 return ɵɵpropertyInterpolate8;
15508 }
15509 /**
15510 * Update an interpolated property on an element with 9 or more bound values surrounded by text.
15511 *
15512 * Used when the number of interpolated values exceeds 8.
15513 *
15514 * ```html
15515 * <div
15516 * title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
15517 * ```
15518 *
15519 * Its compiled representation is::
15520 *
15521 * ```ts
15522 * ɵɵpropertyInterpolateV(
15523 * 'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
15524 * 'suffix']);
15525 * ```
15526 *
15527 * If the property name also exists as an input property on one of the element's directives,
15528 * the component property will be set instead of the element property. This check must
15529 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
15530 *
15531 * @param propName The name of the property to update.
15532 * @param values The collection of values and the strings inbetween those values, beginning with a
15533 * string prefix and ending with a string suffix.
15534 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
15535 * @param sanitizer An optional sanitizer function
15536 * @returns itself, so that it may be chained.
15537 * @codeGenApi
15538 */
15539 function ɵɵpropertyInterpolateV(propName, values, sanitizer) {
15540 var lView = getLView();
15541 var interpolatedValue = interpolationV(lView, values);
15542 if (interpolatedValue !== NO_CHANGE) {
15543 var tView = getTView();
15544 var tNode = getSelectedTNode();
15545 elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
15546 if (ngDevMode) {
15547 var interpolationInBetween = [values[0]]; // prefix
15548 for (var i = 2; i < values.length; i += 2) {
15549 interpolationInBetween.push(values[i]);
15550 }
15551 storePropertyBindingMetadata.apply(void 0, __spread([tView.data, tNode, propName, getBindingIndex() - interpolationInBetween.length + 1], interpolationInBetween));
15552 }
15553 }
15554 return ɵɵpropertyInterpolateV;
15555 }
15556
15557 /**
15558 * @license
15559 * Copyright Google LLC All Rights Reserved.
15560 *
15561 * Use of this source code is governed by an MIT-style license that can be
15562 * found in the LICENSE file at https://angular.io/license
15563 */
15564 /**
15565 * This file contains reuseable "empty" symbols that can be used as default return values
15566 * in different parts of the rendering code. Because the same symbols are returned, this
15567 * allows for identity checks against these values to be consistently used by the framework
15568 * code.
15569 */
15570 var EMPTY_OBJ$1 = {};
15571 var EMPTY_ARRAY$3 = [];
15572 // freezing the values prevents any code from accidentally inserting new values in
15573 if ((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode()) {
15574 // These property accesses can be ignored because ngDevMode will be set to false
15575 // when optimizing code and the whole if statement will be dropped.
15576 // tslint:disable-next-line:no-toplevel-property-access
15577 Object.freeze(EMPTY_OBJ$1);
15578 // tslint:disable-next-line:no-toplevel-property-access
15579 Object.freeze(EMPTY_ARRAY$3);
15580 }
15581
15582 /**
15583 * @license
15584 * Copyright Google LLC All Rights Reserved.
15585 *
15586 * Use of this source code is governed by an MIT-style license that can be
15587 * found in the LICENSE file at https://angular.io/license
15588 */
15589 /**
15590 * NOTE: The word `styling` is used interchangeably as style or class styling.
15591 *
15592 * This file contains code to link styling instructions together so that they can be replayed in
15593 * priority order. The file exists because Ivy styling instruction execution order does not match
15594 * that of the priority order. The purpose of this code is to create a linked list so that the
15595 * instructions can be traversed in priority order when computing the styles.
15596 *
15597 * Assume we are dealing with the following code:
15598 * ```
15599 * @Component({
15600 * template: `
15601 * <my-cmp [style]=" {color: '#001'} "
15602 * [style.color]=" #002 "
15603 * dir-style-color-1
15604 * dir-style-color-2> `
15605 * })
15606 * class ExampleComponent {
15607 * static ngComp = ... {
15608 * ...
15609 * // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
15610 * ɵɵstyleMap({color: '#001'});
15611 * ɵɵstyleProp('color', '#002');
15612 * ...
15613 * }
15614 * }
15615 *
15616 * @Directive({
15617 * selector: `[dir-style-color-1]',
15618 * })
15619 * class Style1Directive {
15620 * @HostBinding('style') style = {color: '#005'};
15621 * @HostBinding('style.color') color = '#006';
15622 *
15623 * static ngDir = ... {
15624 * ...
15625 * // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
15626 * ɵɵstyleMap({color: '#005'});
15627 * ɵɵstyleProp('color', '#006');
15628 * ...
15629 * }
15630 * }
15631 *
15632 * @Directive({
15633 * selector: `[dir-style-color-2]',
15634 * })
15635 * class Style2Directive {
15636 * @HostBinding('style') style = {color: '#007'};
15637 * @HostBinding('style.color') color = '#008';
15638 *
15639 * static ngDir = ... {
15640 * ...
15641 * // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
15642 * ɵɵstyleMap({color: '#007'});
15643 * ɵɵstyleProp('color', '#008');
15644 * ...
15645 * }
15646 * }
15647 *
15648 * @Directive({
15649 * selector: `my-cmp',
15650 * })
15651 * class MyComponent {
15652 * @HostBinding('style') style = {color: '#003'};
15653 * @HostBinding('style.color') color = '#004';
15654 *
15655 * static ngComp = ... {
15656 * ...
15657 * // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
15658 * ɵɵstyleMap({color: '#003'});
15659 * ɵɵstyleProp('color', '#004');
15660 * ...
15661 * }
15662 * }
15663 * ```
15664 *
15665 * The Order of instruction execution is:
15666 *
15667 * NOTE: the comment binding location is for illustrative purposes only.
15668 *
15669 * ```
15670 * // Template: (ExampleComponent)
15671 * ɵɵstyleMap({color: '#001'}); // Binding index: 10
15672 * ɵɵstyleProp('color', '#002'); // Binding index: 12
15673 * // MyComponent
15674 * ɵɵstyleMap({color: '#003'}); // Binding index: 20
15675 * ɵɵstyleProp('color', '#004'); // Binding index: 22
15676 * // Style1Directive
15677 * ɵɵstyleMap({color: '#005'}); // Binding index: 24
15678 * ɵɵstyleProp('color', '#006'); // Binding index: 26
15679 * // Style2Directive
15680 * ɵɵstyleMap({color: '#007'}); // Binding index: 28
15681 * ɵɵstyleProp('color', '#008'); // Binding index: 30
15682 * ```
15683 *
15684 * The correct priority order of concatenation is:
15685 *
15686 * ```
15687 * // MyComponent
15688 * ɵɵstyleMap({color: '#003'}); // Binding index: 20
15689 * ɵɵstyleProp('color', '#004'); // Binding index: 22
15690 * // Style1Directive
15691 * ɵɵstyleMap({color: '#005'}); // Binding index: 24
15692 * ɵɵstyleProp('color', '#006'); // Binding index: 26
15693 * // Style2Directive
15694 * ɵɵstyleMap({color: '#007'}); // Binding index: 28
15695 * ɵɵstyleProp('color', '#008'); // Binding index: 30
15696 * // Template: (ExampleComponent)
15697 * ɵɵstyleMap({color: '#001'}); // Binding index: 10
15698 * ɵɵstyleProp('color', '#002'); // Binding index: 12
15699 * ```
15700 *
15701 * What color should be rendered?
15702 *
15703 * Once the items are correctly sorted in the list, the answer is simply the last item in the
15704 * concatenation list which is `#002`.
15705 *
15706 * To do so we keep a linked list of all of the bindings which pertain to this element.
15707 * Notice that the bindings are inserted in the order of execution, but the `TView.data` allows
15708 * us to traverse them in the order of priority.
15709 *
15710 * |Idx|`TView.data`|`LView` | Notes
15711 * |---|------------|-----------------|--------------
15712 * |...| | |
15713 * |10 |`null` |`{color: '#001'}`| `ɵɵstyleMap('color', {color: '#001'})`
15714 * |11 |`30 | 12` | ... |
15715 * |12 |`color` |`'#002'` | `ɵɵstyleProp('color', '#002')`
15716 * |13 |`10 | 0` | ... |
15717 * |...| | |
15718 * |20 |`null` |`{color: '#003'}`| `ɵɵstyleMap('color', {color: '#003'})`
15719 * |21 |`0 | 22` | ... |
15720 * |22 |`color` |`'#004'` | `ɵɵstyleProp('color', '#004')`
15721 * |23 |`20 | 24` | ... |
15722 * |24 |`null` |`{color: '#005'}`| `ɵɵstyleMap('color', {color: '#005'})`
15723 * |25 |`22 | 26` | ... |
15724 * |26 |`color` |`'#006'` | `ɵɵstyleProp('color', '#006')`
15725 * |27 |`24 | 28` | ... |
15726 * |28 |`null` |`{color: '#007'}`| `ɵɵstyleMap('color', {color: '#007'})`
15727 * |29 |`26 | 30` | ... |
15728 * |30 |`color` |`'#008'` | `ɵɵstyleProp('color', '#008')`
15729 * |31 |`28 | 10` | ... |
15730 *
15731 * The above data structure allows us to re-concatenate the styling no matter which data binding
15732 * changes.
15733 *
15734 * NOTE: in addition to keeping track of next/previous index the `TView.data` also stores prev/next
15735 * duplicate bit. The duplicate bit if true says there either is a binding with the same name or
15736 * there is a map (which may contain the name). This information is useful in knowing if other
15737 * styles with higher priority need to be searched for overwrites.
15738 *
15739 * NOTE: See `should support example in 'tnode_linked_list.ts' documentation` in
15740 * `tnode_linked_list_spec.ts` for working example.
15741 */
15742 var __unused_const_as_closure_does_not_like_standalone_comment_blocks__;
15743 /**
15744 * Insert new `tStyleValue` at `TData` and link existing style bindings such that we maintain linked
15745 * list of styles and compute the duplicate flag.
15746 *
15747 * Note: this function is executed during `firstUpdatePass` only to populate the `TView.data`.
15748 *
15749 * The function works by keeping track of `tStylingRange` which contains two pointers pointing to
15750 * the head/tail of the template portion of the styles.
15751 * - if `isHost === false` (we are template) then insertion is at tail of `TStylingRange`
15752 * - if `isHost === true` (we are host binding) then insertion is at head of `TStylingRange`
15753 *
15754 * @param tData The `TData` to insert into.
15755 * @param tNode `TNode` associated with the styling element.
15756 * @param tStylingKey See `TStylingKey`.
15757 * @param index location of where `tStyleValue` should be stored (and linked into list.)
15758 * @param isHostBinding `true` if the insertion is for a `hostBinding`. (insertion is in front of
15759 * template.)
15760 * @param isClassBinding True if the associated `tStylingKey` as a `class` styling.
15761 * `tNode.classBindings` should be used (or `tNode.styleBindings` otherwise.)
15762 */
15763 function insertTStylingBinding(tData, tNode, tStylingKeyWithStatic, index, isHostBinding, isClassBinding) {
15764 ngDevMode && assertFirstUpdatePass(getTView());
15765 var tBindings = isClassBinding ? tNode.classBindings : tNode.styleBindings;
15766 var tmplHead = getTStylingRangePrev(tBindings);
15767 var tmplTail = getTStylingRangeNext(tBindings);
15768 tData[index] = tStylingKeyWithStatic;
15769 var isKeyDuplicateOfStatic = false;
15770 var tStylingKey;
15771 if (Array.isArray(tStylingKeyWithStatic)) {
15772 // We are case when the `TStylingKey` contains static fields as well.
15773 var staticKeyValueArray = tStylingKeyWithStatic;
15774 tStylingKey = staticKeyValueArray[1]; // unwrap.
15775 // We need to check if our key is present in the static so that we can mark it as duplicate.
15776 if (tStylingKey === null ||
15777 keyValueArrayIndexOf(staticKeyValueArray, tStylingKey) > 0) {
15778 // tStylingKey is present in the statics, need to mark it as duplicate.
15779 isKeyDuplicateOfStatic = true;
15780 }
15781 }
15782 else {
15783 tStylingKey = tStylingKeyWithStatic;
15784 }
15785 if (isHostBinding) {
15786 // We are inserting host bindings
15787 // If we don't have template bindings then `tail` is 0.
15788 var hasTemplateBindings = tmplTail !== 0;
15789 // This is important to know because that means that the `head` can't point to the first
15790 // template bindings (there are none.) Instead the head points to the tail of the template.
15791 if (hasTemplateBindings) {
15792 // template head's "prev" will point to last host binding or to 0 if no host bindings yet
15793 var previousNode = getTStylingRangePrev(tData[tmplHead + 1]);
15794 tData[index + 1] = toTStylingRange(previousNode, tmplHead);
15795 // if a host binding has already been registered, we need to update the next of that host
15796 // binding to point to this one
15797 if (previousNode !== 0) {
15798 // We need to update the template-tail value to point to us.
15799 tData[previousNode + 1] =
15800 setTStylingRangeNext(tData[previousNode + 1], index);
15801 }
15802 // The "previous" of the template binding head should point to this host binding
15803 tData[tmplHead + 1] = setTStylingRangePrev(tData[tmplHead + 1], index);
15804 }
15805 else {
15806 tData[index + 1] = toTStylingRange(tmplHead, 0);
15807 // if a host binding has already been registered, we need to update the next of that host
15808 // binding to point to this one
15809 if (tmplHead !== 0) {
15810 // We need to update the template-tail value to point to us.
15811 tData[tmplHead + 1] = setTStylingRangeNext(tData[tmplHead + 1], index);
15812 }
15813 // if we don't have template, the head points to template-tail, and needs to be advanced.
15814 tmplHead = index;
15815 }
15816 }
15817 else {
15818 // We are inserting in template section.
15819 // We need to set this binding's "previous" to the current template tail
15820 tData[index + 1] = toTStylingRange(tmplTail, 0);
15821 ngDevMode &&
15822 assertEqual(tmplHead !== 0 && tmplTail === 0, false, 'Adding template bindings after hostBindings is not allowed.');
15823 if (tmplHead === 0) {
15824 tmplHead = index;
15825 }
15826 else {
15827 // We need to update the previous value "next" to point to this binding
15828 tData[tmplTail + 1] = setTStylingRangeNext(tData[tmplTail + 1], index);
15829 }
15830 tmplTail = index;
15831 }
15832 // Now we need to update / compute the duplicates.
15833 // Starting with our location search towards head (least priority)
15834 if (isKeyDuplicateOfStatic) {
15835 tData[index + 1] = setTStylingRangePrevDuplicate(tData[index + 1]);
15836 }
15837 markDuplicates(tData, tStylingKey, index, true, isClassBinding);
15838 markDuplicates(tData, tStylingKey, index, false, isClassBinding);
15839 markDuplicateOfResidualStyling(tNode, tStylingKey, tData, index, isClassBinding);
15840 tBindings = toTStylingRange(tmplHead, tmplTail);
15841 if (isClassBinding) {
15842 tNode.classBindings = tBindings;
15843 }
15844 else {
15845 tNode.styleBindings = tBindings;
15846 }
15847 }
15848 /**
15849 * Look into the residual styling to see if the current `tStylingKey` is duplicate of residual.
15850 *
15851 * @param tNode `TNode` where the residual is stored.
15852 * @param tStylingKey `TStylingKey` to store.
15853 * @param tData `TData` associated with the current `LView`.
15854 * @param index location of where `tStyleValue` should be stored (and linked into list.)
15855 * @param isClassBinding True if the associated `tStylingKey` as a `class` styling.
15856 * `tNode.classBindings` should be used (or `tNode.styleBindings` otherwise.)
15857 */
15858 function markDuplicateOfResidualStyling(tNode, tStylingKey, tData, index, isClassBinding) {
15859 var residual = isClassBinding ? tNode.residualClasses : tNode.residualStyles;
15860 if (residual != null /* or undefined */ && typeof tStylingKey == 'string' &&
15861 keyValueArrayIndexOf(residual, tStylingKey) >= 0) {
15862 // We have duplicate in the residual so mark ourselves as duplicate.
15863 tData[index + 1] = setTStylingRangeNextDuplicate(tData[index + 1]);
15864 }
15865 }
15866 /**
15867 * Marks `TStyleValue`s as duplicates if another style binding in the list has the same
15868 * `TStyleValue`.
15869 *
15870 * NOTE: this function is intended to be called twice once with `isPrevDir` set to `true` and once
15871 * with it set to `false` to search both the previous as well as next items in the list.
15872 *
15873 * No duplicate case
15874 * ```
15875 * [style.color]
15876 * [style.width.px] <<- index
15877 * [style.height.px]
15878 * ```
15879 *
15880 * In the above case adding `[style.width.px]` to the existing `[style.color]` produces no
15881 * duplicates because `width` is not found in any other part of the linked list.
15882 *
15883 * Duplicate case
15884 * ```
15885 * [style.color]
15886 * [style.width.em]
15887 * [style.width.px] <<- index
15888 * ```
15889 * In the above case adding `[style.width.px]` will produce a duplicate with `[style.width.em]`
15890 * because `width` is found in the chain.
15891 *
15892 * Map case 1
15893 * ```
15894 * [style.width.px]
15895 * [style.color]
15896 * [style] <<- index
15897 * ```
15898 * In the above case adding `[style]` will produce a duplicate with any other bindings because
15899 * `[style]` is a Map and as such is fully dynamic and could produce `color` or `width`.
15900 *
15901 * Map case 2
15902 * ```
15903 * [style]
15904 * [style.width.px]
15905 * [style.color] <<- index
15906 * ```
15907 * In the above case adding `[style.color]` will produce a duplicate because there is already a
15908 * `[style]` binding which is a Map and as such is fully dynamic and could produce `color` or
15909 * `width`.
15910 *
15911 * NOTE: Once `[style]` (Map) is added into the system all things are mapped as duplicates.
15912 * NOTE: We use `style` as example, but same logic is applied to `class`es as well.
15913 *
15914 * @param tData `TData` where the linked list is stored.
15915 * @param tStylingKey `TStylingKeyPrimitive` which contains the value to compare to other keys in
15916 * the linked list.
15917 * @param index Starting location in the linked list to search from
15918 * @param isPrevDir Direction.
15919 * - `true` for previous (lower priority);
15920 * - `false` for next (higher priority).
15921 */
15922 function markDuplicates(tData, tStylingKey, index, isPrevDir, isClassBinding) {
15923 var tStylingAtIndex = tData[index + 1];
15924 var isMap = tStylingKey === null;
15925 var cursor = isPrevDir ? getTStylingRangePrev(tStylingAtIndex) : getTStylingRangeNext(tStylingAtIndex);
15926 var foundDuplicate = false;
15927 // We keep iterating as long as we have a cursor
15928 // AND either:
15929 // - we found what we are looking for, OR
15930 // - we are a map in which case we have to continue searching even after we find what we were
15931 // looking for since we are a wild card and everything needs to be flipped to duplicate.
15932 while (cursor !== 0 && (foundDuplicate === false || isMap)) {
15933 ngDevMode && assertIndexInRange(tData, cursor);
15934 var tStylingValueAtCursor = tData[cursor];
15935 var tStyleRangeAtCursor = tData[cursor + 1];
15936 if (isStylingMatch(tStylingValueAtCursor, tStylingKey)) {
15937 foundDuplicate = true;
15938 tData[cursor + 1] = isPrevDir ? setTStylingRangeNextDuplicate(tStyleRangeAtCursor) :
15939 setTStylingRangePrevDuplicate(tStyleRangeAtCursor);
15940 }
15941 cursor = isPrevDir ? getTStylingRangePrev(tStyleRangeAtCursor) :
15942 getTStylingRangeNext(tStyleRangeAtCursor);
15943 }
15944 if (foundDuplicate) {
15945 // if we found a duplicate, than mark ourselves.
15946 tData[index + 1] = isPrevDir ? setTStylingRangePrevDuplicate(tStylingAtIndex) :
15947 setTStylingRangeNextDuplicate(tStylingAtIndex);
15948 }
15949 }
15950 /**
15951 * Determines if two `TStylingKey`s are a match.
15952 *
15953 * When computing weather a binding contains a duplicate, we need to compare if the instruction
15954 * `TStylingKey` has a match.
15955 *
15956 * Here are examples of `TStylingKey`s which match given `tStylingKeyCursor` is:
15957 * - `color`
15958 * - `color` // Match another color
15959 * - `null` // That means that `tStylingKey` is a `classMap`/`styleMap` instruction
15960 * - `['', 'color', 'other', true]` // wrapped `color` so match
15961 * - `['', null, 'other', true]` // wrapped `null` so match
15962 * - `['', 'width', 'color', 'value']` // wrapped static value contains a match on `'color'`
15963 * - `null` // `tStylingKeyCursor` always match as it is `classMap`/`styleMap` instruction
15964 *
15965 * @param tStylingKeyCursor
15966 * @param tStylingKey
15967 */
15968 function isStylingMatch(tStylingKeyCursor, tStylingKey) {
15969 ngDevMode &&
15970 assertNotEqual(Array.isArray(tStylingKey), true, 'Expected that \'tStylingKey\' has been unwrapped');
15971 if (tStylingKeyCursor === null || // If the cursor is `null` it means that we have map at that
15972 // location so we must assume that we have a match.
15973 tStylingKey == null || // If `tStylingKey` is `null` then it is a map therefor assume that it
15974 // contains a match.
15975 (Array.isArray(tStylingKeyCursor) ? tStylingKeyCursor[1] : tStylingKeyCursor) ===
15976 tStylingKey // If the keys match explicitly than we are a match.
15977 ) {
15978 return true;
15979 }
15980 else if (Array.isArray(tStylingKeyCursor) && typeof tStylingKey === 'string') {
15981 // if we did not find a match, but `tStylingKeyCursor` is `KeyValueArray` that means cursor has
15982 // statics and we need to check those as well.
15983 return keyValueArrayIndexOf(tStylingKeyCursor, tStylingKey) >=
15984 0; // see if we are matching the key
15985 }
15986 return false;
15987 }
15988
15989 /**
15990 * @license
15991 * Copyright Google LLC All Rights Reserved.
15992 *
15993 * Use of this source code is governed by an MIT-style license that can be
15994 * found in the LICENSE file at https://angular.io/license
15995 */
15996 // Global state of the parser. (This makes parser non-reentrant, but that is not an issue)
15997 var parserState = {
15998 textEnd: 0,
15999 key: 0,
16000 keyEnd: 0,
16001 value: 0,
16002 valueEnd: 0,
16003 };
16004 /**
16005 * Retrieves the last parsed `key` of style.
16006 * @param text the text to substring the key from.
16007 */
16008 function getLastParsedKey(text) {
16009 return text.substring(parserState.key, parserState.keyEnd);
16010 }
16011 /**
16012 * Retrieves the last parsed `value` of style.
16013 * @param text the text to substring the key from.
16014 */
16015 function getLastParsedValue(text) {
16016 return text.substring(parserState.value, parserState.valueEnd);
16017 }
16018 /**
16019 * Initializes `className` string for parsing and parses the first token.
16020 *
16021 * This function is intended to be used in this format:
16022 * ```
16023 * for (let i = parseClassName(text); i >= 0; i = parseClassNameNext(text, i)) {
16024 * const key = getLastParsedKey();
16025 * ...
16026 * }
16027 * ```
16028 * @param text `className` to parse
16029 * @returns index where the next invocation of `parseClassNameNext` should resume.
16030 */
16031 function parseClassName(text) {
16032 resetParserState(text);
16033 return parseClassNameNext(text, consumeWhitespace(text, 0, parserState.textEnd));
16034 }
16035 /**
16036 * Parses next `className` token.
16037 *
16038 * This function is intended to be used in this format:
16039 * ```
16040 * for (let i = parseClassName(text); i >= 0; i = parseClassNameNext(text, i)) {
16041 * const key = getLastParsedKey();
16042 * ...
16043 * }
16044 * ```
16045 *
16046 * @param text `className` to parse
16047 * @param index where the parsing should resume.
16048 * @returns index where the next invocation of `parseClassNameNext` should resume.
16049 */
16050 function parseClassNameNext(text, index) {
16051 var end = parserState.textEnd;
16052 if (end === index) {
16053 return -1;
16054 }
16055 index = parserState.keyEnd = consumeClassToken(text, parserState.key = index, end);
16056 return consumeWhitespace(text, index, end);
16057 }
16058 /**
16059 * Initializes `cssText` string for parsing and parses the first key/values.
16060 *
16061 * This function is intended to be used in this format:
16062 * ```
16063 * for (let i = parseStyle(text); i >= 0; i = parseStyleNext(text, i))) {
16064 * const key = getLastParsedKey();
16065 * const value = getLastParsedValue();
16066 * ...
16067 * }
16068 * ```
16069 * @param text `cssText` to parse
16070 * @returns index where the next invocation of `parseStyleNext` should resume.
16071 */
16072 function parseStyle(text) {
16073 resetParserState(text);
16074 return parseStyleNext(text, consumeWhitespace(text, 0, parserState.textEnd));
16075 }
16076 /**
16077 * Parses the next `cssText` key/values.
16078 *
16079 * This function is intended to be used in this format:
16080 * ```
16081 * for (let i = parseStyle(text); i >= 0; i = parseStyleNext(text, i))) {
16082 * const key = getLastParsedKey();
16083 * const value = getLastParsedValue();
16084 * ...
16085 * }
16086 *
16087 * @param text `cssText` to parse
16088 * @param index where the parsing should resume.
16089 * @returns index where the next invocation of `parseStyleNext` should resume.
16090 */
16091 function parseStyleNext(text, startIndex) {
16092 var end = parserState.textEnd;
16093 var index = parserState.key = consumeWhitespace(text, startIndex, end);
16094 if (end === index) {
16095 // we reached an end so just quit
16096 return -1;
16097 }
16098 index = parserState.keyEnd = consumeStyleKey(text, index, end);
16099 index = consumeSeparator(text, index, end, 58 /* COLON */);
16100 index = parserState.value = consumeWhitespace(text, index, end);
16101 index = parserState.valueEnd = consumeStyleValue(text, index, end);
16102 return consumeSeparator(text, index, end, 59 /* SEMI_COLON */);
16103 }
16104 /**
16105 * Reset the global state of the styling parser.
16106 * @param text The styling text to parse.
16107 */
16108 function resetParserState(text) {
16109 parserState.key = 0;
16110 parserState.keyEnd = 0;
16111 parserState.value = 0;
16112 parserState.valueEnd = 0;
16113 parserState.textEnd = text.length;
16114 }
16115 /**
16116 * Returns index of next non-whitespace character.
16117 *
16118 * @param text Text to scan
16119 * @param startIndex Starting index of character where the scan should start.
16120 * @param endIndex Ending index of character where the scan should end.
16121 * @returns Index of next non-whitespace character (May be the same as `start` if no whitespace at
16122 * that location.)
16123 */
16124 function consumeWhitespace(text, startIndex, endIndex) {
16125 while (startIndex < endIndex && text.charCodeAt(startIndex) <= 32 /* SPACE */) {
16126 startIndex++;
16127 }
16128 return startIndex;
16129 }
16130 /**
16131 * Returns index of last char in class token.
16132 *
16133 * @param text Text to scan
16134 * @param startIndex Starting index of character where the scan should start.
16135 * @param endIndex Ending index of character where the scan should end.
16136 * @returns Index after last char in class token.
16137 */
16138 function consumeClassToken(text, startIndex, endIndex) {
16139 while (startIndex < endIndex && text.charCodeAt(startIndex) > 32 /* SPACE */) {
16140 startIndex++;
16141 }
16142 return startIndex;
16143 }
16144 /**
16145 * Consumes all of the characters belonging to style key and token.
16146 *
16147 * @param text Text to scan
16148 * @param startIndex Starting index of character where the scan should start.
16149 * @param endIndex Ending index of character where the scan should end.
16150 * @returns Index after last style key character.
16151 */
16152 function consumeStyleKey(text, startIndex, endIndex) {
16153 var ch;
16154 while (startIndex < endIndex &&
16155 ((ch = text.charCodeAt(startIndex)) === 45 /* DASH */ || ch === 95 /* UNDERSCORE */ ||
16156 ((ch & -33 /* UPPER_CASE */) >= 65 /* A */ && (ch & -33 /* UPPER_CASE */) <= 90 /* Z */) ||
16157 (ch >= 48 /* ZERO */ && ch <= 57 /* NINE */))) {
16158 startIndex++;
16159 }
16160 return startIndex;
16161 }
16162 /**
16163 * Consumes all whitespace and the separator `:` after the style key.
16164 *
16165 * @param text Text to scan
16166 * @param startIndex Starting index of character where the scan should start.
16167 * @param endIndex Ending index of character where the scan should end.
16168 * @returns Index after separator and surrounding whitespace.
16169 */
16170 function consumeSeparator(text, startIndex, endIndex, separator) {
16171 startIndex = consumeWhitespace(text, startIndex, endIndex);
16172 if (startIndex < endIndex) {
16173 if (ngDevMode && text.charCodeAt(startIndex) !== separator) {
16174 malformedStyleError(text, String.fromCharCode(separator), startIndex);
16175 }
16176 startIndex++;
16177 }
16178 return startIndex;
16179 }
16180 /**
16181 * Consumes style value honoring `url()` and `""` text.
16182 *
16183 * @param text Text to scan
16184 * @param startIndex Starting index of character where the scan should start.
16185 * @param endIndex Ending index of character where the scan should end.
16186 * @returns Index after last style value character.
16187 */
16188 function consumeStyleValue(text, startIndex, endIndex) {
16189 var ch1 = -1; // 1st previous character
16190 var ch2 = -1; // 2nd previous character
16191 var ch3 = -1; // 3rd previous character
16192 var i = startIndex;
16193 var lastChIndex = i;
16194 while (i < endIndex) {
16195 var ch = text.charCodeAt(i++);
16196 if (ch === 59 /* SEMI_COLON */) {
16197 return lastChIndex;
16198 }
16199 else if (ch === 34 /* DOUBLE_QUOTE */ || ch === 39 /* SINGLE_QUOTE */) {
16200 lastChIndex = i = consumeQuotedText(text, ch, i, endIndex);
16201 }
16202 else if (startIndex ===
16203 i - 4 && // We have seen only 4 characters so far "URL(" (Ignore "foo_URL()")
16204 ch3 === 85 /* U */ &&
16205 ch2 === 82 /* R */ && ch1 === 76 /* L */ && ch === 40 /* OPEN_PAREN */) {
16206 lastChIndex = i = consumeQuotedText(text, 41 /* CLOSE_PAREN */, i, endIndex);
16207 }
16208 else if (ch > 32 /* SPACE */) {
16209 // if we have a non-whitespace character then capture its location
16210 lastChIndex = i;
16211 }
16212 ch3 = ch2;
16213 ch2 = ch1;
16214 ch1 = ch & -33 /* UPPER_CASE */;
16215 }
16216 return lastChIndex;
16217 }
16218 /**
16219 * Consumes all of the quoted characters.
16220 *
16221 * @param text Text to scan
16222 * @param quoteCharCode CharCode of either `"` or `'` quote or `)` for `url(...)`.
16223 * @param startIndex Starting index of character where the scan should start.
16224 * @param endIndex Ending index of character where the scan should end.
16225 * @returns Index after quoted characters.
16226 */
16227 function consumeQuotedText(text, quoteCharCode, startIndex, endIndex) {
16228 var ch1 = -1; // 1st previous character
16229 var index = startIndex;
16230 while (index < endIndex) {
16231 var ch = text.charCodeAt(index++);
16232 if (ch == quoteCharCode && ch1 !== 92 /* BACK_SLASH */) {
16233 return index;
16234 }
16235 if (ch == 92 /* BACK_SLASH */ && ch1 === 92 /* BACK_SLASH */) {
16236 // two back slashes cancel each other out. For example `"\\"` should properly end the
16237 // quotation. (It should not assume that the last `"` is escaped.)
16238 ch1 = 0;
16239 }
16240 else {
16241 ch1 = ch;
16242 }
16243 }
16244 throw ngDevMode ? malformedStyleError(text, String.fromCharCode(quoteCharCode), endIndex) :
16245 new Error();
16246 }
16247 function malformedStyleError(text, expecting, index) {
16248 ngDevMode && assertEqual(typeof text === 'string', true, 'String expected here');
16249 throw throwError("Malformed style at location " + index + " in string '" + text.substring(0, index) + '[>>' +
16250 text.substring(index, index + 1) + '<<]' + text.substr(index + 1) +
16251 ("'. Expecting '" + expecting + "'."));
16252 }
16253
16254 /**
16255 * @license
16256 * Copyright Google LLC All Rights Reserved.
16257 *
16258 * Use of this source code is governed by an MIT-style license that can be
16259 * found in the LICENSE file at https://angular.io/license
16260 */
16261 /**
16262 * Update a style binding on an element with the provided value.
16263 *
16264 * If the style value is falsy then it will be removed from the element
16265 * (or assigned a different value depending if there are any styles placed
16266 * on the element with `styleMap` or any static styles that are
16267 * present from when the element was created with `styling`).
16268 *
16269 * Note that the styling element is updated as part of `stylingApply`.
16270 *
16271 * @param prop A valid CSS property.
16272 * @param value New value to write (`null` or an empty string to remove).
16273 * @param suffix Optional suffix. Used with scalar values to add unit such as `px`.
16274 *
16275 * Note that this will apply the provided style value to the host element if this function is called
16276 * within a host binding function.
16277 *
16278 * @codeGenApi
16279 */
16280 function ɵɵstyleProp(prop, value, suffix) {
16281 checkStylingProperty(prop, value, suffix, false);
16282 return ɵɵstyleProp;
16283 }
16284 /**
16285 * Update a class binding on an element with the provided value.
16286 *
16287 * This instruction is meant to handle the `[class.foo]="exp"` case and,
16288 * therefore, the class binding itself must already be allocated using
16289 * `styling` within the creation block.
16290 *
16291 * @param prop A valid CSS class (only one).
16292 * @param value A true/false value which will turn the class on or off.
16293 *
16294 * Note that this will apply the provided class value to the host element if this function
16295 * is called within a host binding function.
16296 *
16297 * @codeGenApi
16298 */
16299 function ɵɵclassProp(className, value) {
16300 checkStylingProperty(className, value, null, true);
16301 return ɵɵclassProp;
16302 }
16303 /**
16304 * Update style bindings using an object literal on an element.
16305 *
16306 * This instruction is meant to apply styling via the `[style]="exp"` template bindings.
16307 * When styles are applied to the element they will then be updated with respect to
16308 * any styles/classes set via `styleProp`. If any styles are set to falsy
16309 * then they will be removed from the element.
16310 *
16311 * Note that the styling instruction will not be applied until `stylingApply` is called.
16312 *
16313 * @param styles A key/value style map of the styles that will be applied to the given element.
16314 * Any missing styles (that have already been applied to the element beforehand) will be
16315 * removed (unset) from the element's styling.
16316 *
16317 * Note that this will apply the provided styleMap value to the host element if this function
16318 * is called within a host binding.
16319 *
16320 * @codeGenApi
16321 */
16322 function ɵɵstyleMap(styles) {
16323 checkStylingMap(styleKeyValueArraySet, styleStringParser, styles, false);
16324 }
16325 /**
16326 * Parse text as style and add values to KeyValueArray.
16327 *
16328 * This code is pulled out to a separate function so that it can be tree shaken away if it is not
16329 * needed. It is only referenced from `ɵɵstyleMap`.
16330 *
16331 * @param keyValueArray KeyValueArray to add parsed values to.
16332 * @param text text to parse.
16333 */
16334 function styleStringParser(keyValueArray, text) {
16335 for (var i = parseStyle(text); i >= 0; i = parseStyleNext(text, i)) {
16336 styleKeyValueArraySet(keyValueArray, getLastParsedKey(text), getLastParsedValue(text));
16337 }
16338 }
16339 /**
16340 * Update class bindings using an object literal or class-string on an element.
16341 *
16342 * This instruction is meant to apply styling via the `[class]="exp"` template bindings.
16343 * When classes are applied to the element they will then be updated with
16344 * respect to any styles/classes set via `classProp`. If any
16345 * classes are set to falsy then they will be removed from the element.
16346 *
16347 * Note that the styling instruction will not be applied until `stylingApply` is called.
16348 * Note that this will the provided classMap value to the host element if this function is called
16349 * within a host binding.
16350 *
16351 * @param classes A key/value map or string of CSS classes that will be added to the
16352 * given element. Any missing classes (that have already been applied to the element
16353 * beforehand) will be removed (unset) from the element's list of CSS classes.
16354 *
16355 * @codeGenApi
16356 */
16357 function ɵɵclassMap(classes) {
16358 checkStylingMap(keyValueArraySet, classStringParser, classes, true);
16359 }
16360 /**
16361 * Parse text as class and add values to KeyValueArray.
16362 *
16363 * This code is pulled out to a separate function so that it can be tree shaken away if it is not
16364 * needed. It is only referenced from `ɵɵclassMap`.
16365 *
16366 * @param keyValueArray KeyValueArray to add parsed values to.
16367 * @param text text to parse.
16368 */
16369 function classStringParser(keyValueArray, text) {
16370 for (var i = parseClassName(text); i >= 0; i = parseClassNameNext(text, i)) {
16371 keyValueArraySet(keyValueArray, getLastParsedKey(text), true);
16372 }
16373 }
16374 /**
16375 * Common code between `ɵɵclassProp` and `ɵɵstyleProp`.
16376 *
16377 * @param prop property name.
16378 * @param value binding value.
16379 * @param suffix suffix for the property (e.g. `em` or `px`)
16380 * @param isClassBased `true` if `class` change (`false` if `style`)
16381 */
16382 function checkStylingProperty(prop, value, suffix, isClassBased) {
16383 var lView = getLView();
16384 var tView = getTView();
16385 // Styling instructions use 2 slots per binding.
16386 // 1. one for the value / TStylingKey
16387 // 2. one for the intermittent-value / TStylingRange
16388 var bindingIndex = incrementBindingIndex(2);
16389 if (tView.firstUpdatePass) {
16390 stylingFirstUpdatePass(tView, prop, bindingIndex, isClassBased);
16391 }
16392 if (value !== NO_CHANGE && bindingUpdated(lView, bindingIndex, value)) {
16393 var tNode = tView.data[getSelectedIndex() + HEADER_OFFSET];
16394 updateStyling(tView, tNode, lView, lView[RENDERER], prop, lView[bindingIndex + 1] = normalizeSuffix(value, suffix), isClassBased, bindingIndex);
16395 }
16396 }
16397 /**
16398 * Common code between `ɵɵclassMap` and `ɵɵstyleMap`.
16399 *
16400 * @param keyValueArraySet (See `keyValueArraySet` in "util/array_utils") Gets passed in as a
16401 * function so that `style` can be processed. This is done for tree shaking purposes.
16402 * @param stringParser Parser used to parse `value` if `string`. (Passed in as `style` and `class`
16403 * have different parsers.)
16404 * @param value bound value from application
16405 * @param isClassBased `true` if `class` change (`false` if `style`)
16406 */
16407 function checkStylingMap(keyValueArraySet, stringParser, value, isClassBased) {
16408 var tView = getTView();
16409 var bindingIndex = incrementBindingIndex(2);
16410 if (tView.firstUpdatePass) {
16411 stylingFirstUpdatePass(tView, null, bindingIndex, isClassBased);
16412 }
16413 var lView = getLView();
16414 if (value !== NO_CHANGE && bindingUpdated(lView, bindingIndex, value)) {
16415 // `getSelectedIndex()` should be here (rather than in instruction) so that it is guarded by the
16416 // if so as not to read unnecessarily.
16417 var tNode = tView.data[getSelectedIndex() + HEADER_OFFSET];
16418 if (hasStylingInputShadow(tNode, isClassBased) && !isInHostBindings(tView, bindingIndex)) {
16419 if (ngDevMode) {
16420 // verify that if we are shadowing then `TData` is appropriately marked so that we skip
16421 // processing this binding in styling resolution.
16422 var tStylingKey = tView.data[bindingIndex];
16423 assertEqual(Array.isArray(tStylingKey) ? tStylingKey[1] : tStylingKey, false, 'Styling linked list shadow input should be marked as \'false\'');
16424 }
16425 // VE does not concatenate the static portion like we are doing here.
16426 // Instead VE just ignores the static completely if dynamic binding is present.
16427 // Because of locality we have already set the static portion because we don't know if there
16428 // is a dynamic portion until later. If we would ignore the static portion it would look like
16429 // the binding has removed it. This would confuse `[ngStyle]`/`[ngClass]` to do the wrong
16430 // thing as it would think that the static portion was removed. For this reason we
16431 // concatenate it so that `[ngStyle]`/`[ngClass]` can continue to work on changed.
16432 var staticPrefix = isClassBased ? tNode.classesWithoutHost : tNode.stylesWithoutHost;
16433 ngDevMode && isClassBased === false && staticPrefix !== null &&
16434 assertEqual(staticPrefix.endsWith(';'), true, 'Expecting static portion to end with \';\'');
16435 if (staticPrefix !== null) {
16436 // We want to make sure that falsy values of `value` become empty strings.
16437 value = concatStringsWithSpace(staticPrefix, value ? value : '');
16438 }
16439 // Given `<div [style] my-dir>` such that `my-dir` has `@Input('style')`.
16440 // This takes over the `[style]` binding. (Same for `[class]`)
16441 setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isClassBased);
16442 }
16443 else {
16444 updateStylingMap(tView, tNode, lView, lView[RENDERER], lView[bindingIndex + 1], lView[bindingIndex + 1] = toStylingKeyValueArray(keyValueArraySet, stringParser, value), isClassBased, bindingIndex);
16445 }
16446 }
16447 }
16448 /**
16449 * Determines when the binding is in `hostBindings` section
16450 *
16451 * @param tView Current `TView`
16452 * @param bindingIndex index of binding which we would like if it is in `hostBindings`
16453 */
16454 function isInHostBindings(tView, bindingIndex) {
16455 // All host bindings are placed after the expando section.
16456 return bindingIndex >= tView.expandoStartIndex;
16457 }
16458 /**
16459 * Collects the necessary information to insert the binding into a linked list of style bindings
16460 * using `insertTStylingBinding`.
16461 *
16462 * @param tView `TView` where the binding linked list will be stored.
16463 * @param tStylingKey Property/key of the binding.
16464 * @param bindingIndex Index of binding associated with the `prop`
16465 * @param isClassBased `true` if `class` change (`false` if `style`)
16466 */
16467 function stylingFirstUpdatePass(tView, tStylingKey, bindingIndex, isClassBased) {
16468 ngDevMode && assertFirstUpdatePass(tView);
16469 var tData = tView.data;
16470 if (tData[bindingIndex + 1] === null) {
16471 // The above check is necessary because we don't clear first update pass until first successful
16472 // (no exception) template execution. This prevents the styling instruction from double adding
16473 // itself to the list.
16474 // `getSelectedIndex()` should be here (rather than in instruction) so that it is guarded by the
16475 // if so as not to read unnecessarily.
16476 var tNode = tData[getSelectedIndex() + HEADER_OFFSET];
16477 var isHostBindings = isInHostBindings(tView, bindingIndex);
16478 if (hasStylingInputShadow(tNode, isClassBased) && tStylingKey === null && !isHostBindings) {
16479 // `tStylingKey === null` implies that we are either `[style]` or `[class]` binding.
16480 // If there is a directive which uses `@Input('style')` or `@Input('class')` than
16481 // we need to neutralize this binding since that directive is shadowing it.
16482 // We turn this into a noop by setting the key to `false`
16483 tStylingKey = false;
16484 }
16485 tStylingKey = wrapInStaticStylingKey(tData, tNode, tStylingKey, isClassBased);
16486 insertTStylingBinding(tData, tNode, tStylingKey, bindingIndex, isHostBindings, isClassBased);
16487 }
16488 }
16489 /**
16490 * Adds static styling information to the binding if applicable.
16491 *
16492 * The linked list of styles not only stores the list and keys, but also stores static styling
16493 * information on some of the keys. This function determines if the key should contain the styling
16494 * information and computes it.
16495 *
16496 * See `TStylingStatic` for more details.
16497 *
16498 * @param tData `TData` where the linked list is stored.
16499 * @param tNode `TNode` for which the styling is being computed.
16500 * @param stylingKey `TStylingKeyPrimitive` which may need to be wrapped into `TStylingKey`
16501 * @param isClassBased `true` if `class` (`false` if `style`)
16502 */
16503 function wrapInStaticStylingKey(tData, tNode, stylingKey, isClassBased) {
16504 var hostDirectiveDef = getCurrentDirectiveDef(tData);
16505 var residual = isClassBased ? tNode.residualClasses : tNode.residualStyles;
16506 if (hostDirectiveDef === null) {
16507 // We are in template node.
16508 // If template node already had styling instruction then it has already collected the static
16509 // styling and there is no need to collect them again. We know that we are the first styling
16510 // instruction because the `TNode.*Bindings` points to 0 (nothing has been inserted yet).
16511 var isFirstStylingInstructionInTemplate = (isClassBased ? tNode.classBindings : tNode.styleBindings) === 0;
16512 if (isFirstStylingInstructionInTemplate) {
16513 // It would be nice to be able to get the statics from `mergeAttrs`, however, at this point
16514 // they are already merged and it would not be possible to figure which property belongs where
16515 // in the priority.
16516 stylingKey = collectStylingFromDirectives(null, tData, tNode, stylingKey, isClassBased);
16517 stylingKey = collectStylingFromTAttrs(stylingKey, tNode.attrs, isClassBased);
16518 // We know that if we have styling binding in template we can't have residual.
16519 residual = null;
16520 }
16521 }
16522 else {
16523 // We are in host binding node and there was no binding instruction in template node.
16524 // This means that we need to compute the residual.
16525 var directiveStylingLast = tNode.directiveStylingLast;
16526 var isFirstStylingInstructionInHostBinding = directiveStylingLast === -1 || tData[directiveStylingLast] !== hostDirectiveDef;
16527 if (isFirstStylingInstructionInHostBinding) {
16528 stylingKey =
16529 collectStylingFromDirectives(hostDirectiveDef, tData, tNode, stylingKey, isClassBased);
16530 if (residual === null) {
16531 // - If `null` than either:
16532 // - Template styling instruction already ran and it has consumed the static
16533 // styling into its `TStylingKey` and so there is no need to update residual. Instead
16534 // we need to update the `TStylingKey` associated with the first template node
16535 // instruction. OR
16536 // - Some other styling instruction ran and determined that there are no residuals
16537 var templateStylingKey = getTemplateHeadTStylingKey(tData, tNode, isClassBased);
16538 if (templateStylingKey !== undefined && Array.isArray(templateStylingKey)) {
16539 // Only recompute if `templateStylingKey` had static values. (If no static value found
16540 // then there is nothing to do since this operation can only produce less static keys, not
16541 // more.)
16542 templateStylingKey = collectStylingFromDirectives(null, tData, tNode, templateStylingKey[1] /* unwrap previous statics */, isClassBased);
16543 templateStylingKey =
16544 collectStylingFromTAttrs(templateStylingKey, tNode.attrs, isClassBased);
16545 setTemplateHeadTStylingKey(tData, tNode, isClassBased, templateStylingKey);
16546 }
16547 }
16548 else {
16549 // We only need to recompute residual if it is not `null`.
16550 // - If existing residual (implies there was no template styling). This means that some of
16551 // the statics may have moved from the residual to the `stylingKey` and so we have to
16552 // recompute.
16553 // - If `undefined` this is the first time we are running.
16554 residual = collectResidual(tData, tNode, isClassBased);
16555 }
16556 }
16557 }
16558 if (residual !== undefined) {
16559 isClassBased ? (tNode.residualClasses = residual) : (tNode.residualStyles = residual);
16560 }
16561 return stylingKey;
16562 }
16563 /**
16564 * Retrieve the `TStylingKey` for the template styling instruction.
16565 *
16566 * This is needed since `hostBinding` styling instructions are inserted after the template
16567 * instruction. While the template instruction needs to update the residual in `TNode` the
16568 * `hostBinding` instructions need to update the `TStylingKey` of the template instruction because
16569 * the template instruction is downstream from the `hostBindings` instructions.
16570 *
16571 * @param tData `TData` where the linked list is stored.
16572 * @param tNode `TNode` for which the styling is being computed.
16573 * @param isClassBased `true` if `class` (`false` if `style`)
16574 * @return `TStylingKey` if found or `undefined` if not found.
16575 */
16576 function getTemplateHeadTStylingKey(tData, tNode, isClassBased) {
16577 var bindings = isClassBased ? tNode.classBindings : tNode.styleBindings;
16578 if (getTStylingRangeNext(bindings) === 0) {
16579 // There does not seem to be a styling instruction in the `template`.
16580 return undefined;
16581 }
16582 return tData[getTStylingRangePrev(bindings)];
16583 }
16584 /**
16585 * Update the `TStylingKey` of the first template instruction in `TNode`.
16586 *
16587 * Logically `hostBindings` styling instructions are of lower priority than that of the template.
16588 * However, they execute after the template styling instructions. This means that they get inserted
16589 * in front of the template styling instructions.
16590 *
16591 * If we have a template styling instruction and a new `hostBindings` styling instruction is
16592 * executed it means that it may need to steal static fields from the template instruction. This
16593 * method allows us to update the first template instruction `TStylingKey` with a new value.
16594 *
16595 * Assume:
16596 * ```
16597 * <div my-dir style="color: red" [style.color]="tmplExp"></div>
16598 *
16599 * @Directive({
16600 * host: {
16601 * 'style': 'width: 100px',
16602 * '[style.color]': 'dirExp',
16603 * }
16604 * })
16605 * class MyDir {}
16606 * ```
16607 *
16608 * when `[style.color]="tmplExp"` executes it creates this data structure.
16609 * ```
16610 * ['', 'color', 'color', 'red', 'width', '100px'],
16611 * ```
16612 *
16613 * The reason for this is that the template instruction does not know if there are styling
16614 * instructions and must assume that there are none and must collect all of the static styling.
16615 * (both
16616 * `color' and 'width`)
16617 *
16618 * When `'[style.color]': 'dirExp',` executes we need to insert a new data into the linked list.
16619 * ```
16620 * ['', 'color', 'width', '100px'], // newly inserted
16621 * ['', 'color', 'color', 'red', 'width', '100px'], // this is wrong
16622 * ```
16623 *
16624 * Notice that the template statics is now wrong as it incorrectly contains `width` so we need to
16625 * update it like so:
16626 * ```
16627 * ['', 'color', 'width', '100px'],
16628 * ['', 'color', 'color', 'red'], // UPDATE
16629 * ```
16630 *
16631 * @param tData `TData` where the linked list is stored.
16632 * @param tNode `TNode` for which the styling is being computed.
16633 * @param isClassBased `true` if `class` (`false` if `style`)
16634 * @param tStylingKey New `TStylingKey` which is replacing the old one.
16635 */
16636 function setTemplateHeadTStylingKey(tData, tNode, isClassBased, tStylingKey) {
16637 var bindings = isClassBased ? tNode.classBindings : tNode.styleBindings;
16638 ngDevMode &&
16639 assertNotEqual(getTStylingRangeNext(bindings), 0, 'Expecting to have at least one template styling binding.');
16640 tData[getTStylingRangePrev(bindings)] = tStylingKey;
16641 }
16642 /**
16643 * Collect all static values after the current `TNode.directiveStylingLast` index.
16644 *
16645 * Collect the remaining styling information which has not yet been collected by an existing
16646 * styling instruction.
16647 *
16648 * @param tData `TData` where the `DirectiveDefs` are stored.
16649 * @param tNode `TNode` which contains the directive range.
16650 * @param isClassBased `true` if `class` (`false` if `style`)
16651 */
16652 function collectResidual(tData, tNode, isClassBased) {
16653 var residual = undefined;
16654 var directiveEnd = tNode.directiveEnd;
16655 ngDevMode &&
16656 assertNotEqual(tNode.directiveStylingLast, -1, 'By the time this function gets called at least one hostBindings-node styling instruction must have executed.');
16657 // We add `1 + tNode.directiveStart` because we need to skip the current directive (as we are
16658 // collecting things after the last `hostBindings` directive which had a styling instruction.)
16659 for (var i = 1 + tNode.directiveStylingLast; i < directiveEnd; i++) {
16660 var attrs = tData[i].hostAttrs;
16661 residual = collectStylingFromTAttrs(residual, attrs, isClassBased);
16662 }
16663 return collectStylingFromTAttrs(residual, tNode.attrs, isClassBased);
16664 }
16665 /**
16666 * Collect the static styling information with lower priority than `hostDirectiveDef`.
16667 *
16668 * (This is opposite of residual styling.)
16669 *
16670 * @param hostDirectiveDef `DirectiveDef` for which we want to collect lower priority static
16671 * styling. (Or `null` if template styling)
16672 * @param tData `TData` where the linked list is stored.
16673 * @param tNode `TNode` for which the styling is being computed.
16674 * @param stylingKey Existing `TStylingKey` to update or wrap.
16675 * @param isClassBased `true` if `class` (`false` if `style`)
16676 */
16677 function collectStylingFromDirectives(hostDirectiveDef, tData, tNode, stylingKey, isClassBased) {
16678 // We need to loop because there can be directives which have `hostAttrs` but don't have
16679 // `hostBindings` so this loop catches up to the current directive..
16680 var currentDirective = null;
16681 var directiveEnd = tNode.directiveEnd;
16682 var directiveStylingLast = tNode.directiveStylingLast;
16683 if (directiveStylingLast === -1) {
16684 directiveStylingLast = tNode.directiveStart;
16685 }
16686 else {
16687 directiveStylingLast++;
16688 }
16689 while (directiveStylingLast < directiveEnd) {
16690 currentDirective = tData[directiveStylingLast];
16691 ngDevMode && assertDefined(currentDirective, 'expected to be defined');
16692 stylingKey = collectStylingFromTAttrs(stylingKey, currentDirective.hostAttrs, isClassBased);
16693 if (currentDirective === hostDirectiveDef)
16694 break;
16695 directiveStylingLast++;
16696 }
16697 if (hostDirectiveDef !== null) {
16698 // we only advance the styling cursor if we are collecting data from host bindings.
16699 // Template executes before host bindings and so if we would update the index,
16700 // host bindings would not get their statics.
16701 tNode.directiveStylingLast = directiveStylingLast;
16702 }
16703 return stylingKey;
16704 }
16705 /**
16706 * Convert `TAttrs` into `TStylingStatic`.
16707 *
16708 * @param stylingKey existing `TStylingKey` to update or wrap.
16709 * @param attrs `TAttributes` to process.
16710 * @param isClassBased `true` if `class` (`false` if `style`)
16711 */
16712 function collectStylingFromTAttrs(stylingKey, attrs, isClassBased) {
16713 var desiredMarker = isClassBased ? 1 /* Classes */ : 2 /* Styles */;
16714 var currentMarker = -1 /* ImplicitAttributes */;
16715 if (attrs !== null) {
16716 for (var i = 0; i < attrs.length; i++) {
16717 var item = attrs[i];
16718 if (typeof item === 'number') {
16719 currentMarker = item;
16720 }
16721 else {
16722 if (currentMarker === desiredMarker) {
16723 if (!Array.isArray(stylingKey)) {
16724 stylingKey = stylingKey === undefined ? [] : ['', stylingKey];
16725 }
16726 keyValueArraySet(stylingKey, item, isClassBased ? true : attrs[++i]);
16727 }
16728 }
16729 }
16730 }
16731 return stylingKey === undefined ? null : stylingKey;
16732 }
16733 /**
16734 * Convert user input to `KeyValueArray`.
16735 *
16736 * This function takes user input which could be `string`, Object literal, or iterable and converts
16737 * it into a consistent representation. The output of this is `KeyValueArray` (which is an array
16738 * where
16739 * even indexes contain keys and odd indexes contain values for those keys).
16740 *
16741 * The advantage of converting to `KeyValueArray` is that we can perform diff in an input
16742 * independent
16743 * way.
16744 * (ie we can compare `foo bar` to `['bar', 'baz'] and determine a set of changes which need to be
16745 * applied)
16746 *
16747 * The fact that `KeyValueArray` is sorted is very important because it allows us to compute the
16748 * difference in linear fashion without the need to allocate any additional data.
16749 *
16750 * For example if we kept this as a `Map` we would have to iterate over previous `Map` to determine
16751 * which values need to be deleted, over the new `Map` to determine additions, and we would have to
16752 * keep additional `Map` to keep track of duplicates or items which have not yet been visited.
16753 *
16754 * @param keyValueArraySet (See `keyValueArraySet` in "util/array_utils") Gets passed in as a
16755 * function so that `style` can be processed. This is done
16756 * for tree shaking purposes.
16757 * @param stringParser The parser is passed in so that it will be tree shakable. See
16758 * `styleStringParser` and `classStringParser`
16759 * @param value The value to parse/convert to `KeyValueArray`
16760 */
16761 function toStylingKeyValueArray(keyValueArraySet, stringParser, value) {
16762 if (value == null /*|| value === undefined */ || value === '')
16763 return EMPTY_ARRAY$3;
16764 var styleKeyValueArray = [];
16765 var unwrappedValue = unwrapSafeValue(value);
16766 if (Array.isArray(unwrappedValue)) {
16767 for (var i = 0; i < unwrappedValue.length; i++) {
16768 keyValueArraySet(styleKeyValueArray, unwrappedValue[i], true);
16769 }
16770 }
16771 else if (typeof unwrappedValue === 'object') {
16772 for (var key in unwrappedValue) {
16773 if (unwrappedValue.hasOwnProperty(key)) {
16774 keyValueArraySet(styleKeyValueArray, key, unwrappedValue[key]);
16775 }
16776 }
16777 }
16778 else if (typeof unwrappedValue === 'string') {
16779 stringParser(styleKeyValueArray, unwrappedValue);
16780 }
16781 else {
16782 ngDevMode &&
16783 throwError('Unsupported styling type ' + typeof unwrappedValue + ': ' + unwrappedValue);
16784 }
16785 return styleKeyValueArray;
16786 }
16787 /**
16788 * Set a `value` for a `key`.
16789 *
16790 * See: `keyValueArraySet` for details
16791 *
16792 * @param keyValueArray KeyValueArray to add to.
16793 * @param key Style key to add.
16794 * @param value The value to set.
16795 */
16796 function styleKeyValueArraySet(keyValueArray, key, value) {
16797 keyValueArraySet(keyValueArray, key, unwrapSafeValue(value));
16798 }
16799 /**
16800 * Update map based styling.
16801 *
16802 * Map based styling could be anything which contains more than one binding. For example `string`,
16803 * or object literal. Dealing with all of these types would complicate the logic so
16804 * instead this function expects that the complex input is first converted into normalized
16805 * `KeyValueArray`. The advantage of normalization is that we get the values sorted, which makes it
16806 * very cheap to compute deltas between the previous and current value.
16807 *
16808 * @param tView Associated `TView.data` contains the linked list of binding priorities.
16809 * @param tNode `TNode` where the binding is located.
16810 * @param lView `LView` contains the values associated with other styling binding at this `TNode`.
16811 * @param renderer Renderer to use if any updates.
16812 * @param oldKeyValueArray Previous value represented as `KeyValueArray`
16813 * @param newKeyValueArray Current value represented as `KeyValueArray`
16814 * @param isClassBased `true` if `class` (`false` if `style`)
16815 * @param bindingIndex Binding index of the binding.
16816 */
16817 function updateStylingMap(tView, tNode, lView, renderer, oldKeyValueArray, newKeyValueArray, isClassBased, bindingIndex) {
16818 if (oldKeyValueArray === NO_CHANGE) {
16819 // On first execution the oldKeyValueArray is NO_CHANGE => treat it as empty KeyValueArray.
16820 oldKeyValueArray = EMPTY_ARRAY$3;
16821 }
16822 var oldIndex = 0;
16823 var newIndex = 0;
16824 var oldKey = 0 < oldKeyValueArray.length ? oldKeyValueArray[0] : null;
16825 var newKey = 0 < newKeyValueArray.length ? newKeyValueArray[0] : null;
16826 while (oldKey !== null || newKey !== null) {
16827 ngDevMode && assertLessThan(oldIndex, 999, 'Are we stuck in infinite loop?');
16828 ngDevMode && assertLessThan(newIndex, 999, 'Are we stuck in infinite loop?');
16829 var oldValue = oldIndex < oldKeyValueArray.length ? oldKeyValueArray[oldIndex + 1] : undefined;
16830 var newValue = newIndex < newKeyValueArray.length ? newKeyValueArray[newIndex + 1] : undefined;
16831 var setKey = null;
16832 var setValue = undefined;
16833 if (oldKey === newKey) {
16834 // UPDATE: Keys are equal => new value is overwriting old value.
16835 oldIndex += 2;
16836 newIndex += 2;
16837 if (oldValue !== newValue) {
16838 setKey = newKey;
16839 setValue = newValue;
16840 }
16841 }
16842 else if (newKey === null || oldKey !== null && oldKey < newKey) {
16843 // DELETE: oldKey key is missing or we did not find the oldKey in the newValue
16844 // (because the keyValueArray is sorted and `newKey` is found later alphabetically).
16845 // `"background" < "color"` so we need to delete `"background"` because it is not found in the
16846 // new array.
16847 oldIndex += 2;
16848 setKey = oldKey;
16849 }
16850 else {
16851 // CREATE: newKey's is earlier alphabetically than oldKey's (or no oldKey) => we have new key.
16852 // `"color" > "background"` so we need to add `color` because it is in new array but not in
16853 // old array.
16854 ngDevMode && assertDefined(newKey, 'Expecting to have a valid key');
16855 newIndex += 2;
16856 setKey = newKey;
16857 setValue = newValue;
16858 }
16859 if (setKey !== null) {
16860 updateStyling(tView, tNode, lView, renderer, setKey, setValue, isClassBased, bindingIndex);
16861 }
16862 oldKey = oldIndex < oldKeyValueArray.length ? oldKeyValueArray[oldIndex] : null;
16863 newKey = newIndex < newKeyValueArray.length ? newKeyValueArray[newIndex] : null;
16864 }
16865 }
16866 /**
16867 * Update a simple (property name) styling.
16868 *
16869 * This function takes `prop` and updates the DOM to that value. The function takes the binding
16870 * value as well as binding priority into consideration to determine which value should be written
16871 * to DOM. (For example it may be determined that there is a higher priority overwrite which blocks
16872 * the DOM write, or if the value goes to `undefined` a lower priority overwrite may be consulted.)
16873 *
16874 * @param tView Associated `TView.data` contains the linked list of binding priorities.
16875 * @param tNode `TNode` where the binding is located.
16876 * @param lView `LView` contains the values associated with other styling binding at this `TNode`.
16877 * @param renderer Renderer to use if any updates.
16878 * @param prop Either style property name or a class name.
16879 * @param value Either style value for `prop` or `true`/`false` if `prop` is class.
16880 * @param isClassBased `true` if `class` (`false` if `style`)
16881 * @param bindingIndex Binding index of the binding.
16882 */
16883 function updateStyling(tView, tNode, lView, renderer, prop, value, isClassBased, bindingIndex) {
16884 if (tNode.type !== 3 /* Element */) {
16885 // It is possible to have styling on non-elements (such as ng-container).
16886 // This is rare, but it does happen. In such a case, just ignore the binding.
16887 return;
16888 }
16889 var tData = tView.data;
16890 var tRange = tData[bindingIndex + 1];
16891 var higherPriorityValue = getTStylingRangeNextDuplicate(tRange) ?
16892 findStylingValue(tData, tNode, lView, prop, getTStylingRangeNext(tRange), isClassBased) :
16893 undefined;
16894 if (!isStylingValuePresent(higherPriorityValue)) {
16895 // We don't have a next duplicate, or we did not find a duplicate value.
16896 if (!isStylingValuePresent(value)) {
16897 // We should delete current value or restore to lower priority value.
16898 if (getTStylingRangePrevDuplicate(tRange)) {
16899 // We have a possible prev duplicate, let's retrieve it.
16900 value = findStylingValue(tData, null, lView, prop, bindingIndex, isClassBased);
16901 }
16902 }
16903 var rNode = getNativeByIndex(getSelectedIndex(), lView);
16904 applyStyling(renderer, isClassBased, rNode, prop, value);
16905 }
16906 }
16907 /**
16908 * Search for styling value with higher priority which is overwriting current value, or a
16909 * value of lower priority to which we should fall back if the value is `undefined`.
16910 *
16911 * When value is being applied at a location, related values need to be consulted.
16912 * - If there is a higher priority binding, we should be using that one instead.
16913 * For example `<div [style]="{color:exp1}" [style.color]="exp2">` change to `exp1`
16914 * requires that we check `exp2` to see if it is set to value other than `undefined`.
16915 * - If there is a lower priority binding and we are changing to `undefined`
16916 * For example `<div [style]="{color:exp1}" [style.color]="exp2">` change to `exp2` to
16917 * `undefined` requires that we check `exp1` (and static values) and use that as new value.
16918 *
16919 * NOTE: The styling stores two values.
16920 * 1. The raw value which came from the application is stored at `index + 0` location. (This value
16921 * is used for dirty checking).
16922 * 2. The normalized value is stored at `index + 1`.
16923 *
16924 * @param tData `TData` used for traversing the priority.
16925 * @param tNode `TNode` to use for resolving static styling. Also controls search direction.
16926 * - `TNode` search next and quit as soon as `isStylingValuePresent(value)` is true.
16927 * If no value found consult `tNode.residualStyle`/`tNode.residualClass` for default value.
16928 * - `null` search prev and go all the way to end. Return last value where
16929 * `isStylingValuePresent(value)` is true.
16930 * @param lView `LView` used for retrieving the actual values.
16931 * @param prop Property which we are interested in.
16932 * @param index Starting index in the linked list of styling bindings where the search should start.
16933 * @param isClassBased `true` if `class` (`false` if `style`)
16934 */
16935 function findStylingValue(tData, tNode, lView, prop, index, isClassBased) {
16936 // `TNode` to use for resolving static styling. Also controls search direction.
16937 // - `TNode` search next and quit as soon as `isStylingValuePresent(value)` is true.
16938 // If no value found consult `tNode.residualStyle`/`tNode.residualClass` for default value.
16939 // - `null` search prev and go all the way to end. Return last value where
16940 // `isStylingValuePresent(value)` is true.
16941 var isPrevDirection = tNode === null;
16942 var value = undefined;
16943 while (index > 0) {
16944 var rawKey = tData[index];
16945 var containsStatics = Array.isArray(rawKey);
16946 // Unwrap the key if we contain static values.
16947 var key = containsStatics ? rawKey[1] : rawKey;
16948 var isStylingMap = key === null;
16949 var valueAtLViewIndex = lView[index + 1];
16950 if (valueAtLViewIndex === NO_CHANGE) {
16951 // In firstUpdatePass the styling instructions create a linked list of styling.
16952 // On subsequent passes it is possible for a styling instruction to try to read a binding
16953 // which
16954 // has not yet executed. In that case we will find `NO_CHANGE` and we should assume that
16955 // we have `undefined` (or empty array in case of styling-map instruction) instead. This
16956 // allows the resolution to apply the value (which may later be overwritten when the
16957 // binding actually executes.)
16958 valueAtLViewIndex = isStylingMap ? EMPTY_ARRAY$3 : undefined;
16959 }
16960 var currentValue = isStylingMap ? keyValueArrayGet(valueAtLViewIndex, prop) :
16961 key === prop ? valueAtLViewIndex : undefined;
16962 if (containsStatics && !isStylingValuePresent(currentValue)) {
16963 currentValue = keyValueArrayGet(rawKey, prop);
16964 }
16965 if (isStylingValuePresent(currentValue)) {
16966 value = currentValue;
16967 if (isPrevDirection) {
16968 return value;
16969 }
16970 }
16971 var tRange = tData[index + 1];
16972 index = isPrevDirection ? getTStylingRangePrev(tRange) : getTStylingRangeNext(tRange);
16973 }
16974 if (tNode !== null) {
16975 // in case where we are going in next direction AND we did not find anything, we need to
16976 // consult residual styling
16977 var residual = isClassBased ? tNode.residualClasses : tNode.residualStyles;
16978 if (residual != null /** OR residual !=== undefined */) {
16979 value = keyValueArrayGet(residual, prop);
16980 }
16981 }
16982 return value;
16983 }
16984 /**
16985 * Determines if the binding value should be used (or if the value is 'undefined' and hence priority
16986 * resolution should be used.)
16987 *
16988 * @param value Binding style value.
16989 */
16990 function isStylingValuePresent(value) {
16991 // Currently only `undefined` value is considered non-binding. That is `undefined` says I don't
16992 // have an opinion as to what this binding should be and you should consult other bindings by
16993 // priority to determine the valid value.
16994 // This is extracted into a single function so that we have a single place to control this.
16995 return value !== undefined;
16996 }
16997 /**
16998 * Normalizes and/or adds a suffix to the value.
16999 *
17000 * If value is `null`/`undefined` no suffix is added
17001 * @param value
17002 * @param suffix
17003 */
17004 function normalizeSuffix(value, suffix) {
17005 if (value == null /** || value === undefined */) {
17006 // do nothing
17007 }
17008 else if (typeof suffix === 'string') {
17009 value = value + suffix;
17010 }
17011 else if (typeof value === 'object') {
17012 value = stringify(unwrapSafeValue(value));
17013 }
17014 return value;
17015 }
17016 /**
17017 * Tests if the `TNode` has input shadow.
17018 *
17019 * An input shadow is when a directive steals (shadows) the input by using `@Input('style')` or
17020 * `@Input('class')` as input.
17021 *
17022 * @param tNode `TNode` which we would like to see if it has shadow.
17023 * @param isClassBased `true` if `class` (`false` if `style`)
17024 */
17025 function hasStylingInputShadow(tNode, isClassBased) {
17026 return (tNode.flags & (isClassBased ? 16 /* hasClassInput */ : 32 /* hasStyleInput */)) !== 0;
17027 }
17028
17029 /**
17030 * @license
17031 * Copyright Google LLC All Rights Reserved.
17032 *
17033 * Use of this source code is governed by an MIT-style license that can be
17034 * found in the LICENSE file at https://angular.io/license
17035 */
17036 /**
17037 * Create static text node
17038 *
17039 * @param index Index of the node in the data array
17040 * @param value Static string value to write.
17041 *
17042 * @codeGenApi
17043 */
17044 function ɵɵtext(index, value) {
17045 if (value === void 0) { value = ''; }
17046 var lView = getLView();
17047 var tView = getTView();
17048 var adjustedIndex = index + HEADER_OFFSET;
17049 ngDevMode &&
17050 assertEqual(getBindingIndex(), tView.bindingStartIndex, 'text nodes should be created before any bindings');
17051 ngDevMode && assertIndexInRange(lView, adjustedIndex);
17052 var tNode = tView.firstCreatePass ?
17053 getOrCreateTNode(tView, lView[T_HOST], index, 3 /* Element */, null, null) :
17054 tView.data[adjustedIndex];
17055 var textNative = lView[adjustedIndex] = createTextNode(value, lView[RENDERER]);
17056 appendChild(tView, lView, textNative, tNode);
17057 // Text nodes are self closing.
17058 setPreviousOrParentTNode(tNode, false);
17059 }
17060
17061 /**
17062 * @license
17063 * Copyright Google LLC All Rights Reserved.
17064 *
17065 * Use of this source code is governed by an MIT-style license that can be
17066 * found in the LICENSE file at https://angular.io/license
17067 */
17068 /**
17069 *
17070 * Update text content with a lone bound value
17071 *
17072 * Used when a text node has 1 interpolated value in it, an no additional text
17073 * surrounds that interpolated value:
17074 *
17075 * ```html
17076 * <div>{{v0}}</div>
17077 * ```
17078 *
17079 * Its compiled representation is:
17080 *
17081 * ```ts
17082 * ɵɵtextInterpolate(v0);
17083 * ```
17084 * @returns itself, so that it may be chained.
17085 * @see textInterpolateV
17086 * @codeGenApi
17087 */
17088 function ɵɵtextInterpolate(v0) {
17089 ɵɵtextInterpolate1('', v0, '');
17090 return ɵɵtextInterpolate;
17091 }
17092 /**
17093 *
17094 * Update text content with single bound value surrounded by other text.
17095 *
17096 * Used when a text node has 1 interpolated value in it:
17097 *
17098 * ```html
17099 * <div>prefix{{v0}}suffix</div>
17100 * ```
17101 *
17102 * Its compiled representation is:
17103 *
17104 * ```ts
17105 * ɵɵtextInterpolate1('prefix', v0, 'suffix');
17106 * ```
17107 * @returns itself, so that it may be chained.
17108 * @see textInterpolateV
17109 * @codeGenApi
17110 */
17111 function ɵɵtextInterpolate1(prefix, v0, suffix) {
17112 var lView = getLView();
17113 var interpolated = interpolation1(lView, prefix, v0, suffix);
17114 if (interpolated !== NO_CHANGE) {
17115 textBindingInternal(lView, getSelectedIndex(), interpolated);
17116 }
17117 return ɵɵtextInterpolate1;
17118 }
17119 /**
17120 *
17121 * Update text content with 2 bound values surrounded by other text.
17122 *
17123 * Used when a text node has 2 interpolated values in it:
17124 *
17125 * ```html
17126 * <div>prefix{{v0}}-{{v1}}suffix</div>
17127 * ```
17128 *
17129 * Its compiled representation is:
17130 *
17131 * ```ts
17132 * ɵɵtextInterpolate2('prefix', v0, '-', v1, 'suffix');
17133 * ```
17134 * @returns itself, so that it may be chained.
17135 * @see textInterpolateV
17136 * @codeGenApi
17137 */
17138 function ɵɵtextInterpolate2(prefix, v0, i0, v1, suffix) {
17139 var lView = getLView();
17140 var interpolated = interpolation2(lView, prefix, v0, i0, v1, suffix);
17141 if (interpolated !== NO_CHANGE) {
17142 textBindingInternal(lView, getSelectedIndex(), interpolated);
17143 }
17144 return ɵɵtextInterpolate2;
17145 }
17146 /**
17147 *
17148 * Update text content with 3 bound values surrounded by other text.
17149 *
17150 * Used when a text node has 3 interpolated values in it:
17151 *
17152 * ```html
17153 * <div>prefix{{v0}}-{{v1}}-{{v2}}suffix</div>
17154 * ```
17155 *
17156 * Its compiled representation is:
17157 *
17158 * ```ts
17159 * ɵɵtextInterpolate3(
17160 * 'prefix', v0, '-', v1, '-', v2, 'suffix');
17161 * ```
17162 * @returns itself, so that it may be chained.
17163 * @see textInterpolateV
17164 * @codeGenApi
17165 */
17166 function ɵɵtextInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
17167 var lView = getLView();
17168 var interpolated = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
17169 if (interpolated !== NO_CHANGE) {
17170 textBindingInternal(lView, getSelectedIndex(), interpolated);
17171 }
17172 return ɵɵtextInterpolate3;
17173 }
17174 /**
17175 *
17176 * Update text content with 4 bound values surrounded by other text.
17177 *
17178 * Used when a text node has 4 interpolated values in it:
17179 *
17180 * ```html
17181 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix</div>
17182 * ```
17183 *
17184 * Its compiled representation is:
17185 *
17186 * ```ts
17187 * ɵɵtextInterpolate4(
17188 * 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
17189 * ```
17190 * @returns itself, so that it may be chained.
17191 * @see ɵɵtextInterpolateV
17192 * @codeGenApi
17193 */
17194 function ɵɵtextInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
17195 var lView = getLView();
17196 var interpolated = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
17197 if (interpolated !== NO_CHANGE) {
17198 textBindingInternal(lView, getSelectedIndex(), interpolated);
17199 }
17200 return ɵɵtextInterpolate4;
17201 }
17202 /**
17203 *
17204 * Update text content with 5 bound values surrounded by other text.
17205 *
17206 * Used when a text node has 5 interpolated values in it:
17207 *
17208 * ```html
17209 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix</div>
17210 * ```
17211 *
17212 * Its compiled representation is:
17213 *
17214 * ```ts
17215 * ɵɵtextInterpolate5(
17216 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
17217 * ```
17218 * @returns itself, so that it may be chained.
17219 * @see textInterpolateV
17220 * @codeGenApi
17221 */
17222 function ɵɵtextInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
17223 var lView = getLView();
17224 var interpolated = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
17225 if (interpolated !== NO_CHANGE) {
17226 textBindingInternal(lView, getSelectedIndex(), interpolated);
17227 }
17228 return ɵɵtextInterpolate5;
17229 }
17230 /**
17231 *
17232 * Update text content with 6 bound values surrounded by other text.
17233 *
17234 * Used when a text node has 6 interpolated values in it:
17235 *
17236 * ```html
17237 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix</div>
17238 * ```
17239 *
17240 * Its compiled representation is:
17241 *
17242 * ```ts
17243 * ɵɵtextInterpolate6(
17244 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
17245 * ```
17246 *
17247 * @param i4 Static value used for concatenation only.
17248 * @param v5 Value checked for change. @returns itself, so that it may be chained.
17249 * @see textInterpolateV
17250 * @codeGenApi
17251 */
17252 function ɵɵtextInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
17253 var lView = getLView();
17254 var interpolated = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
17255 if (interpolated !== NO_CHANGE) {
17256 textBindingInternal(lView, getSelectedIndex(), interpolated);
17257 }
17258 return ɵɵtextInterpolate6;
17259 }
17260 /**
17261 *
17262 * Update text content with 7 bound values surrounded by other text.
17263 *
17264 * Used when a text node has 7 interpolated values in it:
17265 *
17266 * ```html
17267 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix</div>
17268 * ```
17269 *
17270 * Its compiled representation is:
17271 *
17272 * ```ts
17273 * ɵɵtextInterpolate7(
17274 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
17275 * ```
17276 * @returns itself, so that it may be chained.
17277 * @see textInterpolateV
17278 * @codeGenApi
17279 */
17280 function ɵɵtextInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
17281 var lView = getLView();
17282 var interpolated = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
17283 if (interpolated !== NO_CHANGE) {
17284 textBindingInternal(lView, getSelectedIndex(), interpolated);
17285 }
17286 return ɵɵtextInterpolate7;
17287 }
17288 /**
17289 *
17290 * Update text content with 8 bound values surrounded by other text.
17291 *
17292 * Used when a text node has 8 interpolated values in it:
17293 *
17294 * ```html
17295 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix</div>
17296 * ```
17297 *
17298 * Its compiled representation is:
17299 *
17300 * ```ts
17301 * ɵɵtextInterpolate8(
17302 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
17303 * ```
17304 * @returns itself, so that it may be chained.
17305 * @see textInterpolateV
17306 * @codeGenApi
17307 */
17308 function ɵɵtextInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
17309 var lView = getLView();
17310 var interpolated = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
17311 if (interpolated !== NO_CHANGE) {
17312 textBindingInternal(lView, getSelectedIndex(), interpolated);
17313 }
17314 return ɵɵtextInterpolate8;
17315 }
17316 /**
17317 * Update text content with 9 or more bound values other surrounded by text.
17318 *
17319 * Used when the number of interpolated values exceeds 8.
17320 *
17321 * ```html
17322 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix</div>
17323 * ```
17324 *
17325 * Its compiled representation is:
17326 *
17327 * ```ts
17328 * ɵɵtextInterpolateV(
17329 * ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
17330 * 'suffix']);
17331 * ```
17332 *.
17333 * @param values The collection of values and the strings in between those values, beginning with
17334 * a string prefix and ending with a string suffix.
17335 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
17336 *
17337 * @returns itself, so that it may be chained.
17338 * @codeGenApi
17339 */
17340 function ɵɵtextInterpolateV(values) {
17341 var lView = getLView();
17342 var interpolated = interpolationV(lView, values);
17343 if (interpolated !== NO_CHANGE) {
17344 textBindingInternal(lView, getSelectedIndex(), interpolated);
17345 }
17346 return ɵɵtextInterpolateV;
17347 }
17348
17349 /**
17350 * @license
17351 * Copyright Google LLC All Rights Reserved.
17352 *
17353 * Use of this source code is governed by an MIT-style license that can be
17354 * found in the LICENSE file at https://angular.io/license
17355 */
17356 /**
17357 *
17358 * Update an interpolated class on an element with single bound value surrounded by text.
17359 *
17360 * Used when the value passed to a property has 1 interpolated value in it:
17361 *
17362 * ```html
17363 * <div class="prefix{{v0}}suffix"></div>
17364 * ```
17365 *
17366 * Its compiled representation is:
17367 *
17368 * ```ts
17369 * ɵɵclassMapInterpolate1('prefix', v0, 'suffix');
17370 * ```
17371 *
17372 * @param prefix Static value used for concatenation only.
17373 * @param v0 Value checked for change.
17374 * @param suffix Static value used for concatenation only.
17375 * @codeGenApi
17376 */
17377 function ɵɵclassMapInterpolate1(prefix, v0, suffix) {
17378 var lView = getLView();
17379 var interpolatedValue = interpolation1(lView, prefix, v0, suffix);
17380 checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
17381 }
17382 /**
17383 *
17384 * Update an interpolated class on an element with 2 bound values surrounded by text.
17385 *
17386 * Used when the value passed to a property has 2 interpolated values in it:
17387 *
17388 * ```html
17389 * <div class="prefix{{v0}}-{{v1}}suffix"></div>
17390 * ```
17391 *
17392 * Its compiled representation is:
17393 *
17394 * ```ts
17395 * ɵɵclassMapInterpolate2('prefix', v0, '-', v1, 'suffix');
17396 * ```
17397 *
17398 * @param prefix Static value used for concatenation only.
17399 * @param v0 Value checked for change.
17400 * @param i0 Static value used for concatenation only.
17401 * @param v1 Value checked for change.
17402 * @param suffix Static value used for concatenation only.
17403 * @codeGenApi
17404 */
17405 function ɵɵclassMapInterpolate2(prefix, v0, i0, v1, suffix) {
17406 var lView = getLView();
17407 var interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
17408 checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
17409 }
17410 /**
17411 *
17412 * Update an interpolated class on an element with 3 bound values surrounded by text.
17413 *
17414 * Used when the value passed to a property has 3 interpolated values in it:
17415 *
17416 * ```html
17417 * <div class="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
17418 * ```
17419 *
17420 * Its compiled representation is:
17421 *
17422 * ```ts
17423 * ɵɵclassMapInterpolate3(
17424 * 'prefix', v0, '-', v1, '-', v2, 'suffix');
17425 * ```
17426 *
17427 * @param prefix Static value used for concatenation only.
17428 * @param v0 Value checked for change.
17429 * @param i0 Static value used for concatenation only.
17430 * @param v1 Value checked for change.
17431 * @param i1 Static value used for concatenation only.
17432 * @param v2 Value checked for change.
17433 * @param suffix Static value used for concatenation only.
17434 * @codeGenApi
17435 */
17436 function ɵɵclassMapInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
17437 var lView = getLView();
17438 var interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
17439 checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
17440 }
17441 /**
17442 *
17443 * Update an interpolated class on an element with 4 bound values surrounded by text.
17444 *
17445 * Used when the value passed to a property has 4 interpolated values in it:
17446 *
17447 * ```html
17448 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
17449 * ```
17450 *
17451 * Its compiled representation is:
17452 *
17453 * ```ts
17454 * ɵɵclassMapInterpolate4(
17455 * 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
17456 * ```
17457 *
17458 * @param prefix Static value used for concatenation only.
17459 * @param v0 Value checked for change.
17460 * @param i0 Static value used for concatenation only.
17461 * @param v1 Value checked for change.
17462 * @param i1 Static value used for concatenation only.
17463 * @param v2 Value checked for change.
17464 * @param i2 Static value used for concatenation only.
17465 * @param v3 Value checked for change.
17466 * @param suffix Static value used for concatenation only.
17467 * @codeGenApi
17468 */
17469 function ɵɵclassMapInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
17470 var lView = getLView();
17471 var interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
17472 checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
17473 }
17474 /**
17475 *
17476 * Update an interpolated class on an element with 5 bound values surrounded by text.
17477 *
17478 * Used when the value passed to a property has 5 interpolated values in it:
17479 *
17480 * ```html
17481 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
17482 * ```
17483 *
17484 * Its compiled representation is:
17485 *
17486 * ```ts
17487 * ɵɵclassMapInterpolate5(
17488 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
17489 * ```
17490 *
17491 * @param prefix Static value used for concatenation only.
17492 * @param v0 Value checked for change.
17493 * @param i0 Static value used for concatenation only.
17494 * @param v1 Value checked for change.
17495 * @param i1 Static value used for concatenation only.
17496 * @param v2 Value checked for change.
17497 * @param i2 Static value used for concatenation only.
17498 * @param v3 Value checked for change.
17499 * @param i3 Static value used for concatenation only.
17500 * @param v4 Value checked for change.
17501 * @param suffix Static value used for concatenation only.
17502 * @codeGenApi
17503 */
17504 function ɵɵclassMapInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
17505 var lView = getLView();
17506 var interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
17507 checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
17508 }
17509 /**
17510 *
17511 * Update an interpolated class on an element with 6 bound values surrounded by text.
17512 *
17513 * Used when the value passed to a property has 6 interpolated values in it:
17514 *
17515 * ```html
17516 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
17517 * ```
17518 *
17519 * Its compiled representation is:
17520 *
17521 * ```ts
17522 * ɵɵclassMapInterpolate6(
17523 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
17524 * ```
17525 *
17526 * @param prefix Static value used for concatenation only.
17527 * @param v0 Value checked for change.
17528 * @param i0 Static value used for concatenation only.
17529 * @param v1 Value checked for change.
17530 * @param i1 Static value used for concatenation only.
17531 * @param v2 Value checked for change.
17532 * @param i2 Static value used for concatenation only.
17533 * @param v3 Value checked for change.
17534 * @param i3 Static value used for concatenation only.
17535 * @param v4 Value checked for change.
17536 * @param i4 Static value used for concatenation only.
17537 * @param v5 Value checked for change.
17538 * @param suffix Static value used for concatenation only.
17539 * @codeGenApi
17540 */
17541 function ɵɵclassMapInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
17542 var lView = getLView();
17543 var interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
17544 checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
17545 }
17546 /**
17547 *
17548 * Update an interpolated class on an element with 7 bound values surrounded by text.
17549 *
17550 * Used when the value passed to a property has 7 interpolated values in it:
17551 *
17552 * ```html
17553 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
17554 * ```
17555 *
17556 * Its compiled representation is:
17557 *
17558 * ```ts
17559 * ɵɵclassMapInterpolate7(
17560 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
17561 * ```
17562 *
17563 * @param prefix Static value used for concatenation only.
17564 * @param v0 Value checked for change.
17565 * @param i0 Static value used for concatenation only.
17566 * @param v1 Value checked for change.
17567 * @param i1 Static value used for concatenation only.
17568 * @param v2 Value checked for change.
17569 * @param i2 Static value used for concatenation only.
17570 * @param v3 Value checked for change.
17571 * @param i3 Static value used for concatenation only.
17572 * @param v4 Value checked for change.
17573 * @param i4 Static value used for concatenation only.
17574 * @param v5 Value checked for change.
17575 * @param i5 Static value used for concatenation only.
17576 * @param v6 Value checked for change.
17577 * @param suffix Static value used for concatenation only.
17578 * @codeGenApi
17579 */
17580 function ɵɵclassMapInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
17581 var lView = getLView();
17582 var interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
17583 checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
17584 }
17585 /**
17586 *
17587 * Update an interpolated class on an element with 8 bound values surrounded by text.
17588 *
17589 * Used when the value passed to a property has 8 interpolated values in it:
17590 *
17591 * ```html
17592 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
17593 * ```
17594 *
17595 * Its compiled representation is:
17596 *
17597 * ```ts
17598 * ɵɵclassMapInterpolate8(
17599 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
17600 * ```
17601 *
17602 * @param prefix Static value used for concatenation only.
17603 * @param v0 Value checked for change.
17604 * @param i0 Static value used for concatenation only.
17605 * @param v1 Value checked for change.
17606 * @param i1 Static value used for concatenation only.
17607 * @param v2 Value checked for change.
17608 * @param i2 Static value used for concatenation only.
17609 * @param v3 Value checked for change.
17610 * @param i3 Static value used for concatenation only.
17611 * @param v4 Value checked for change.
17612 * @param i4 Static value used for concatenation only.
17613 * @param v5 Value checked for change.
17614 * @param i5 Static value used for concatenation only.
17615 * @param v6 Value checked for change.
17616 * @param i6 Static value used for concatenation only.
17617 * @param v7 Value checked for change.
17618 * @param suffix Static value used for concatenation only.
17619 * @codeGenApi
17620 */
17621 function ɵɵclassMapInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
17622 var lView = getLView();
17623 var interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
17624 checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
17625 }
17626 /**
17627 * Update an interpolated class on an element with 9 or more bound values surrounded by text.
17628 *
17629 * Used when the number of interpolated values exceeds 8.
17630 *
17631 * ```html
17632 * <div
17633 * class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
17634 * ```
17635 *
17636 * Its compiled representation is:
17637 *
17638 * ```ts
17639 * ɵɵclassMapInterpolateV(
17640 * ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
17641 * 'suffix']);
17642 * ```
17643 *.
17644 * @param values The collection of values and the strings in-between those values, beginning with
17645 * a string prefix and ending with a string suffix.
17646 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
17647 * @codeGenApi
17648 */
17649 function ɵɵclassMapInterpolateV(values) {
17650 var lView = getLView();
17651 var interpolatedValue = interpolationV(lView, values);
17652 checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
17653 }
17654
17655 /**
17656 * @license
17657 * Copyright Google LLC All Rights Reserved.
17658 *
17659 * Use of this source code is governed by an MIT-style license that can be
17660 * found in the LICENSE file at https://angular.io/license
17661 */
17662 /**
17663 *
17664 * Update an interpolated style on an element with single bound value surrounded by text.
17665 *
17666 * Used when the value passed to a property has 1 interpolated value in it:
17667 *
17668 * ```html
17669 * <div style="key: {{v0}}suffix"></div>
17670 * ```
17671 *
17672 * Its compiled representation is:
17673 *
17674 * ```ts
17675 * ɵɵstyleMapInterpolate1('key: ', v0, 'suffix');
17676 * ```
17677 *
17678 * @param prefix Static value used for concatenation only.
17679 * @param v0 Value checked for change.
17680 * @param suffix Static value used for concatenation only.
17681 * @codeGenApi
17682 */
17683 function ɵɵstyleMapInterpolate1(prefix, v0, suffix) {
17684 var lView = getLView();
17685 var interpolatedValue = interpolation1(lView, prefix, v0, suffix);
17686 ɵɵstyleMap(interpolatedValue);
17687 }
17688 /**
17689 *
17690 * Update an interpolated style on an element with 2 bound values surrounded by text.
17691 *
17692 * Used when the value passed to a property has 2 interpolated values in it:
17693 *
17694 * ```html
17695 * <div style="key: {{v0}}; key1: {{v1}}suffix"></div>
17696 * ```
17697 *
17698 * Its compiled representation is:
17699 *
17700 * ```ts
17701 * ɵɵstyleMapInterpolate2('key: ', v0, '; key1: ', v1, 'suffix');
17702 * ```
17703 *
17704 * @param prefix Static value used for concatenation only.
17705 * @param v0 Value checked for change.
17706 * @param i0 Static value used for concatenation only.
17707 * @param v1 Value checked for change.
17708 * @param suffix Static value used for concatenation only.
17709 * @codeGenApi
17710 */
17711 function ɵɵstyleMapInterpolate2(prefix, v0, i0, v1, suffix) {
17712 var lView = getLView();
17713 var interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
17714 ɵɵstyleMap(interpolatedValue);
17715 }
17716 /**
17717 *
17718 * Update an interpolated style on an element with 3 bound values surrounded by text.
17719 *
17720 * Used when the value passed to a property has 3 interpolated values in it:
17721 *
17722 * ```html
17723 * <div style="key: {{v0}}; key2: {{v1}}; key2: {{v2}}suffix"></div>
17724 * ```
17725 *
17726 * Its compiled representation is:
17727 *
17728 * ```ts
17729 * ɵɵstyleMapInterpolate3(
17730 * 'key: ', v0, '; key1: ', v1, '; key2: ', v2, 'suffix');
17731 * ```
17732 *
17733 * @param prefix Static value used for concatenation only.
17734 * @param v0 Value checked for change.
17735 * @param i0 Static value used for concatenation only.
17736 * @param v1 Value checked for change.
17737 * @param i1 Static value used for concatenation only.
17738 * @param v2 Value checked for change.
17739 * @param suffix Static value used for concatenation only.
17740 * @codeGenApi
17741 */
17742 function ɵɵstyleMapInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
17743 var lView = getLView();
17744 var interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
17745 ɵɵstyleMap(interpolatedValue);
17746 }
17747 /**
17748 *
17749 * Update an interpolated style on an element with 4 bound values surrounded by text.
17750 *
17751 * Used when the value passed to a property has 4 interpolated values in it:
17752 *
17753 * ```html
17754 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}suffix"></div>
17755 * ```
17756 *
17757 * Its compiled representation is:
17758 *
17759 * ```ts
17760 * ɵɵstyleMapInterpolate4(
17761 * 'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, 'suffix');
17762 * ```
17763 *
17764 * @param prefix Static value used for concatenation only.
17765 * @param v0 Value checked for change.
17766 * @param i0 Static value used for concatenation only.
17767 * @param v1 Value checked for change.
17768 * @param i1 Static value used for concatenation only.
17769 * @param v2 Value checked for change.
17770 * @param i2 Static value used for concatenation only.
17771 * @param v3 Value checked for change.
17772 * @param suffix Static value used for concatenation only.
17773 * @codeGenApi
17774 */
17775 function ɵɵstyleMapInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
17776 var lView = getLView();
17777 var interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
17778 ɵɵstyleMap(interpolatedValue);
17779 }
17780 /**
17781 *
17782 * Update an interpolated style on an element with 5 bound values surrounded by text.
17783 *
17784 * Used when the value passed to a property has 5 interpolated values in it:
17785 *
17786 * ```html
17787 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}suffix"></div>
17788 * ```
17789 *
17790 * Its compiled representation is:
17791 *
17792 * ```ts
17793 * ɵɵstyleMapInterpolate5(
17794 * 'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, 'suffix');
17795 * ```
17796 *
17797 * @param prefix Static value used for concatenation only.
17798 * @param v0 Value checked for change.
17799 * @param i0 Static value used for concatenation only.
17800 * @param v1 Value checked for change.
17801 * @param i1 Static value used for concatenation only.
17802 * @param v2 Value checked for change.
17803 * @param i2 Static value used for concatenation only.
17804 * @param v3 Value checked for change.
17805 * @param i3 Static value used for concatenation only.
17806 * @param v4 Value checked for change.
17807 * @param suffix Static value used for concatenation only.
17808 * @codeGenApi
17809 */
17810 function ɵɵstyleMapInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
17811 var lView = getLView();
17812 var interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
17813 ɵɵstyleMap(interpolatedValue);
17814 }
17815 /**
17816 *
17817 * Update an interpolated style on an element with 6 bound values surrounded by text.
17818 *
17819 * Used when the value passed to a property has 6 interpolated values in it:
17820 *
17821 * ```html
17822 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}};
17823 * key5: {{v5}}suffix"></div>
17824 * ```
17825 *
17826 * Its compiled representation is:
17827 *
17828 * ```ts
17829 * ɵɵstyleMapInterpolate6(
17830 * 'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
17831 * 'suffix');
17832 * ```
17833 *
17834 * @param prefix Static value used for concatenation only.
17835 * @param v0 Value checked for change.
17836 * @param i0 Static value used for concatenation only.
17837 * @param v1 Value checked for change.
17838 * @param i1 Static value used for concatenation only.
17839 * @param v2 Value checked for change.
17840 * @param i2 Static value used for concatenation only.
17841 * @param v3 Value checked for change.
17842 * @param i3 Static value used for concatenation only.
17843 * @param v4 Value checked for change.
17844 * @param i4 Static value used for concatenation only.
17845 * @param v5 Value checked for change.
17846 * @param suffix Static value used for concatenation only.
17847 * @codeGenApi
17848 */
17849 function ɵɵstyleMapInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
17850 var lView = getLView();
17851 var interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
17852 ɵɵstyleMap(interpolatedValue);
17853 }
17854 /**
17855 *
17856 * Update an interpolated style on an element with 7 bound values surrounded by text.
17857 *
17858 * Used when the value passed to a property has 7 interpolated values in it:
17859 *
17860 * ```html
17861 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}; key5: {{v5}};
17862 * key6: {{v6}}suffix"></div>
17863 * ```
17864 *
17865 * Its compiled representation is:
17866 *
17867 * ```ts
17868 * ɵɵstyleMapInterpolate7(
17869 * 'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
17870 * '; key6: ', v6, 'suffix');
17871 * ```
17872 *
17873 * @param prefix Static value used for concatenation only.
17874 * @param v0 Value checked for change.
17875 * @param i0 Static value used for concatenation only.
17876 * @param v1 Value checked for change.
17877 * @param i1 Static value used for concatenation only.
17878 * @param v2 Value checked for change.
17879 * @param i2 Static value used for concatenation only.
17880 * @param v3 Value checked for change.
17881 * @param i3 Static value used for concatenation only.
17882 * @param v4 Value checked for change.
17883 * @param i4 Static value used for concatenation only.
17884 * @param v5 Value checked for change.
17885 * @param i5 Static value used for concatenation only.
17886 * @param v6 Value checked for change.
17887 * @param suffix Static value used for concatenation only.
17888 * @codeGenApi
17889 */
17890 function ɵɵstyleMapInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
17891 var lView = getLView();
17892 var interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
17893 ɵɵstyleMap(interpolatedValue);
17894 }
17895 /**
17896 *
17897 * Update an interpolated style on an element with 8 bound values surrounded by text.
17898 *
17899 * Used when the value passed to a property has 8 interpolated values in it:
17900 *
17901 * ```html
17902 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}; key5: {{v5}};
17903 * key6: {{v6}}; key7: {{v7}}suffix"></div>
17904 * ```
17905 *
17906 * Its compiled representation is:
17907 *
17908 * ```ts
17909 * ɵɵstyleMapInterpolate8(
17910 * 'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
17911 * '; key6: ', v6, '; key7: ', v7, 'suffix');
17912 * ```
17913 *
17914 * @param prefix Static value used for concatenation only.
17915 * @param v0 Value checked for change.
17916 * @param i0 Static value used for concatenation only.
17917 * @param v1 Value checked for change.
17918 * @param i1 Static value used for concatenation only.
17919 * @param v2 Value checked for change.
17920 * @param i2 Static value used for concatenation only.
17921 * @param v3 Value checked for change.
17922 * @param i3 Static value used for concatenation only.
17923 * @param v4 Value checked for change.
17924 * @param i4 Static value used for concatenation only.
17925 * @param v5 Value checked for change.
17926 * @param i5 Static value used for concatenation only.
17927 * @param v6 Value checked for change.
17928 * @param i6 Static value used for concatenation only.
17929 * @param v7 Value checked for change.
17930 * @param suffix Static value used for concatenation only.
17931 * @codeGenApi
17932 */
17933 function ɵɵstyleMapInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
17934 var lView = getLView();
17935 var interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
17936 ɵɵstyleMap(interpolatedValue);
17937 }
17938 /**
17939 * Update an interpolated style on an element with 9 or more bound values surrounded by text.
17940 *
17941 * Used when the number of interpolated values exceeds 8.
17942 *
17943 * ```html
17944 * <div
17945 * class="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}; key5: {{v5}};
17946 * key6: {{v6}}; key7: {{v7}}; key8: {{v8}}; key9: {{v9}}suffix"></div>
17947 * ```
17948 *
17949 * Its compiled representation is:
17950 *
17951 * ```ts
17952 * ɵɵstyleMapInterpolateV(
17953 * ['key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
17954 * '; key6: ', v6, '; key7: ', v7, '; key8: ', v8, '; key9: ', v9, 'suffix']);
17955 * ```
17956 *.
17957 * @param values The collection of values and the strings in-between those values, beginning with
17958 * a string prefix and ending with a string suffix.
17959 * (e.g. `['prefix', value0, '; key2: ', value1, '; key2: ', value2, ..., value99, 'suffix']`)
17960 * @codeGenApi
17961 */
17962 function ɵɵstyleMapInterpolateV(values) {
17963 var lView = getLView();
17964 var interpolatedValue = interpolationV(lView, values);
17965 ɵɵstyleMap(interpolatedValue);
17966 }
17967
17968 /**
17969 * @license
17970 * Copyright Google LLC All Rights Reserved.
17971 *
17972 * Use of this source code is governed by an MIT-style license that can be
17973 * found in the LICENSE file at https://angular.io/license
17974 */
17975 /**
17976 *
17977 * Update an interpolated style property on an element with single bound value surrounded by text.
17978 *
17979 * Used when the value passed to a property has 1 interpolated value in it:
17980 *
17981 * ```html
17982 * <div style.color="prefix{{v0}}suffix"></div>
17983 * ```
17984 *
17985 * Its compiled representation is:
17986 *
17987 * ```ts
17988 * ɵɵstylePropInterpolate1(0, 'prefix', v0, 'suffix');
17989 * ```
17990 *
17991 * @param styleIndex Index of style to update. This index value refers to the
17992 * index of the style in the style bindings array that was passed into
17993 * `styling`.
17994 * @param prefix Static value used for concatenation only.
17995 * @param v0 Value checked for change.
17996 * @param suffix Static value used for concatenation only.
17997 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
17998 * @returns itself, so that it may be chained.
17999 * @codeGenApi
18000 */
18001 function ɵɵstylePropInterpolate1(prop, prefix, v0, suffix, valueSuffix) {
18002 var lView = getLView();
18003 var interpolatedValue = interpolation1(lView, prefix, v0, suffix);
18004 checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
18005 return ɵɵstylePropInterpolate1;
18006 }
18007 /**
18008 *
18009 * Update an interpolated style property on an element with 2 bound values surrounded by text.
18010 *
18011 * Used when the value passed to a property has 2 interpolated values in it:
18012 *
18013 * ```html
18014 * <div style.color="prefix{{v0}}-{{v1}}suffix"></div>
18015 * ```
18016 *
18017 * Its compiled representation is:
18018 *
18019 * ```ts
18020 * ɵɵstylePropInterpolate2(0, 'prefix', v0, '-', v1, 'suffix');
18021 * ```
18022 *
18023 * @param styleIndex Index of style to update. This index value refers to the
18024 * index of the style in the style bindings array that was passed into
18025 * `styling`.
18026 * @param prefix Static value used for concatenation only.
18027 * @param v0 Value checked for change.
18028 * @param i0 Static value used for concatenation only.
18029 * @param v1 Value checked for change.
18030 * @param suffix Static value used for concatenation only.
18031 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
18032 * @returns itself, so that it may be chained.
18033 * @codeGenApi
18034 */
18035 function ɵɵstylePropInterpolate2(prop, prefix, v0, i0, v1, suffix, valueSuffix) {
18036 var lView = getLView();
18037 var interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
18038 checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
18039 return ɵɵstylePropInterpolate2;
18040 }
18041 /**
18042 *
18043 * Update an interpolated style property on an element with 3 bound values surrounded by text.
18044 *
18045 * Used when the value passed to a property has 3 interpolated values in it:
18046 *
18047 * ```html
18048 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
18049 * ```
18050 *
18051 * Its compiled representation is:
18052 *
18053 * ```ts
18054 * ɵɵstylePropInterpolate3(0, 'prefix', v0, '-', v1, '-', v2, 'suffix');
18055 * ```
18056 *
18057 * @param styleIndex Index of style to update. This index value refers to the
18058 * index of the style in the style bindings array that was passed into
18059 * `styling`.
18060 * @param prefix Static value used for concatenation only.
18061 * @param v0 Value checked for change.
18062 * @param i0 Static value used for concatenation only.
18063 * @param v1 Value checked for change.
18064 * @param i1 Static value used for concatenation only.
18065 * @param v2 Value checked for change.
18066 * @param suffix Static value used for concatenation only.
18067 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
18068 * @returns itself, so that it may be chained.
18069 * @codeGenApi
18070 */
18071 function ɵɵstylePropInterpolate3(prop, prefix, v0, i0, v1, i1, v2, suffix, valueSuffix) {
18072 var lView = getLView();
18073 var interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
18074 checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
18075 return ɵɵstylePropInterpolate3;
18076 }
18077 /**
18078 *
18079 * Update an interpolated style property on an element with 4 bound values surrounded by text.
18080 *
18081 * Used when the value passed to a property has 4 interpolated values in it:
18082 *
18083 * ```html
18084 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
18085 * ```
18086 *
18087 * Its compiled representation is:
18088 *
18089 * ```ts
18090 * ɵɵstylePropInterpolate4(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
18091 * ```
18092 *
18093 * @param styleIndex Index of style to update. This index value refers to the
18094 * index of the style in the style bindings array that was passed into
18095 * `styling`.
18096 * @param prefix Static value used for concatenation only.
18097 * @param v0 Value checked for change.
18098 * @param i0 Static value used for concatenation only.
18099 * @param v1 Value checked for change.
18100 * @param i1 Static value used for concatenation only.
18101 * @param v2 Value checked for change.
18102 * @param i2 Static value used for concatenation only.
18103 * @param v3 Value checked for change.
18104 * @param suffix Static value used for concatenation only.
18105 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
18106 * @returns itself, so that it may be chained.
18107 * @codeGenApi
18108 */
18109 function ɵɵstylePropInterpolate4(prop, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, valueSuffix) {
18110 var lView = getLView();
18111 var interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
18112 checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
18113 return ɵɵstylePropInterpolate4;
18114 }
18115 /**
18116 *
18117 * Update an interpolated style property on an element with 5 bound values surrounded by text.
18118 *
18119 * Used when the value passed to a property has 5 interpolated values in it:
18120 *
18121 * ```html
18122 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
18123 * ```
18124 *
18125 * Its compiled representation is:
18126 *
18127 * ```ts
18128 * ɵɵstylePropInterpolate5(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
18129 * ```
18130 *
18131 * @param styleIndex Index of style to update. This index value refers to the
18132 * index of the style in the style bindings array that was passed into
18133 * `styling`.
18134 * @param prefix Static value used for concatenation only.
18135 * @param v0 Value checked for change.
18136 * @param i0 Static value used for concatenation only.
18137 * @param v1 Value checked for change.
18138 * @param i1 Static value used for concatenation only.
18139 * @param v2 Value checked for change.
18140 * @param i2 Static value used for concatenation only.
18141 * @param v3 Value checked for change.
18142 * @param i3 Static value used for concatenation only.
18143 * @param v4 Value checked for change.
18144 * @param suffix Static value used for concatenation only.
18145 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
18146 * @returns itself, so that it may be chained.
18147 * @codeGenApi
18148 */
18149 function ɵɵstylePropInterpolate5(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, valueSuffix) {
18150 var lView = getLView();
18151 var interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
18152 checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
18153 return ɵɵstylePropInterpolate5;
18154 }
18155 /**
18156 *
18157 * Update an interpolated style property on an element with 6 bound values surrounded by text.
18158 *
18159 * Used when the value passed to a property has 6 interpolated values in it:
18160 *
18161 * ```html
18162 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
18163 * ```
18164 *
18165 * Its compiled representation is:
18166 *
18167 * ```ts
18168 * ɵɵstylePropInterpolate6(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
18169 * ```
18170 *
18171 * @param styleIndex Index of style to update. This index value refers to the
18172 * index of the style in the style bindings array that was passed into
18173 * `styling`.
18174 * @param prefix Static value used for concatenation only.
18175 * @param v0 Value checked for change.
18176 * @param i0 Static value used for concatenation only.
18177 * @param v1 Value checked for change.
18178 * @param i1 Static value used for concatenation only.
18179 * @param v2 Value checked for change.
18180 * @param i2 Static value used for concatenation only.
18181 * @param v3 Value checked for change.
18182 * @param i3 Static value used for concatenation only.
18183 * @param v4 Value checked for change.
18184 * @param i4 Static value used for concatenation only.
18185 * @param v5 Value checked for change.
18186 * @param suffix Static value used for concatenation only.
18187 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
18188 * @returns itself, so that it may be chained.
18189 * @codeGenApi
18190 */
18191 function ɵɵstylePropInterpolate6(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, valueSuffix) {
18192 var lView = getLView();
18193 var interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
18194 checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
18195 return ɵɵstylePropInterpolate6;
18196 }
18197 /**
18198 *
18199 * Update an interpolated style property on an element with 7 bound values surrounded by text.
18200 *
18201 * Used when the value passed to a property has 7 interpolated values in it:
18202 *
18203 * ```html
18204 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
18205 * ```
18206 *
18207 * Its compiled representation is:
18208 *
18209 * ```ts
18210 * ɵɵstylePropInterpolate7(
18211 * 0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
18212 * ```
18213 *
18214 * @param styleIndex Index of style to update. This index value refers to the
18215 * index of the style in the style bindings array that was passed into
18216 * `styling`.
18217 * @param prefix Static value used for concatenation only.
18218 * @param v0 Value checked for change.
18219 * @param i0 Static value used for concatenation only.
18220 * @param v1 Value checked for change.
18221 * @param i1 Static value used for concatenation only.
18222 * @param v2 Value checked for change.
18223 * @param i2 Static value used for concatenation only.
18224 * @param v3 Value checked for change.
18225 * @param i3 Static value used for concatenation only.
18226 * @param v4 Value checked for change.
18227 * @param i4 Static value used for concatenation only.
18228 * @param v5 Value checked for change.
18229 * @param i5 Static value used for concatenation only.
18230 * @param v6 Value checked for change.
18231 * @param suffix Static value used for concatenation only.
18232 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
18233 * @returns itself, so that it may be chained.
18234 * @codeGenApi
18235 */
18236 function ɵɵstylePropInterpolate7(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, valueSuffix) {
18237 var lView = getLView();
18238 var interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
18239 checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
18240 return ɵɵstylePropInterpolate7;
18241 }
18242 /**
18243 *
18244 * Update an interpolated style property on an element with 8 bound values surrounded by text.
18245 *
18246 * Used when the value passed to a property has 8 interpolated values in it:
18247 *
18248 * ```html
18249 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
18250 * ```
18251 *
18252 * Its compiled representation is:
18253 *
18254 * ```ts
18255 * ɵɵstylePropInterpolate8(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6,
18256 * '-', v7, 'suffix');
18257 * ```
18258 *
18259 * @param styleIndex Index of style to update. This index value refers to the
18260 * index of the style in the style bindings array that was passed into
18261 * `styling`.
18262 * @param prefix Static value used for concatenation only.
18263 * @param v0 Value checked for change.
18264 * @param i0 Static value used for concatenation only.
18265 * @param v1 Value checked for change.
18266 * @param i1 Static value used for concatenation only.
18267 * @param v2 Value checked for change.
18268 * @param i2 Static value used for concatenation only.
18269 * @param v3 Value checked for change.
18270 * @param i3 Static value used for concatenation only.
18271 * @param v4 Value checked for change.
18272 * @param i4 Static value used for concatenation only.
18273 * @param v5 Value checked for change.
18274 * @param i5 Static value used for concatenation only.
18275 * @param v6 Value checked for change.
18276 * @param i6 Static value used for concatenation only.
18277 * @param v7 Value checked for change.
18278 * @param suffix Static value used for concatenation only.
18279 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
18280 * @returns itself, so that it may be chained.
18281 * @codeGenApi
18282 */
18283 function ɵɵstylePropInterpolate8(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, valueSuffix) {
18284 var lView = getLView();
18285 var interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
18286 checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
18287 return ɵɵstylePropInterpolate8;
18288 }
18289 /**
18290 * Update an interpolated style property on an element with 9 or more bound values surrounded by
18291 * text.
18292 *
18293 * Used when the number of interpolated values exceeds 8.
18294 *
18295 * ```html
18296 * <div
18297 * style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix">
18298 * </div>
18299 * ```
18300 *
18301 * Its compiled representation is:
18302 *
18303 * ```ts
18304 * ɵɵstylePropInterpolateV(
18305 * 0, ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
18306 * 'suffix']);
18307 * ```
18308 *
18309 * @param styleIndex Index of style to update. This index value refers to the
18310 * index of the style in the style bindings array that was passed into
18311 * `styling`..
18312 * @param values The collection of values and the strings in-between those values, beginning with
18313 * a string prefix and ending with a string suffix.
18314 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
18315 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
18316 * @returns itself, so that it may be chained.
18317 * @codeGenApi
18318 */
18319 function ɵɵstylePropInterpolateV(prop, values, valueSuffix) {
18320 var lView = getLView();
18321 var interpolatedValue = interpolationV(lView, values);
18322 checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
18323 return ɵɵstylePropInterpolateV;
18324 }
18325
18326 /**
18327 * @license
18328 * Copyright Google LLC All Rights Reserved.
18329 *
18330 * Use of this source code is governed by an MIT-style license that can be
18331 * found in the LICENSE file at https://angular.io/license
18332 */
18333 /**
18334 * Update a property on a host element. Only applies to native node properties, not inputs.
18335 *
18336 * Operates on the element selected by index via the {@link select} instruction.
18337 *
18338 * @param propName Name of property. Because it is going to DOM, this is not subject to
18339 * renaming as part of minification.
18340 * @param value New value to write.
18341 * @param sanitizer An optional function used to sanitize the value.
18342 * @returns This function returns itself so that it may be chained
18343 * (e.g. `property('name', ctx.name)('title', ctx.title)`)
18344 *
18345 * @codeGenApi
18346 */
18347 function ɵɵhostProperty(propName, value, sanitizer) {
18348 var lView = getLView();
18349 var bindingIndex = nextBindingIndex();
18350 if (bindingUpdated(lView, bindingIndex, value)) {
18351 var tView = getTView();
18352 var tNode = getSelectedTNode();
18353 elementPropertyInternal(tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, true);
18354 ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
18355 }
18356 return ɵɵhostProperty;
18357 }
18358 /**
18359 * Updates a synthetic host binding (e.g. `[@foo]`) on a component or directive.
18360 *
18361 * This instruction is for compatibility purposes and is designed to ensure that a
18362 * synthetic host binding (e.g. `@HostBinding('@foo')`) properly gets rendered in
18363 * the component's renderer. Normally all host bindings are evaluated with the parent
18364 * component's renderer, but, in the case of animation @triggers, they need to be
18365 * evaluated with the sub component's renderer (because that's where the animation
18366 * triggers are defined).
18367 *
18368 * Do not use this instruction as a replacement for `elementProperty`. This instruction
18369 * only exists to ensure compatibility with the ViewEngine's host binding behavior.
18370 *
18371 * @param index The index of the element to update in the data array
18372 * @param propName Name of property. Because it is going to DOM, this is not subject to
18373 * renaming as part of minification.
18374 * @param value New value to write.
18375 * @param sanitizer An optional function used to sanitize the value.
18376 *
18377 * @codeGenApi
18378 */
18379 function ɵɵsyntheticHostProperty(propName, value, sanitizer) {
18380 var lView = getLView();
18381 var bindingIndex = nextBindingIndex();
18382 if (bindingUpdated(lView, bindingIndex, value)) {
18383 var tView = getTView();
18384 var tNode = getSelectedTNode();
18385 var currentDef = getCurrentDirectiveDef(tView.data);
18386 var renderer = loadComponentRenderer(currentDef, tNode, lView);
18387 elementPropertyInternal(tView, tNode, lView, propName, value, renderer, sanitizer, true);
18388 ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
18389 }
18390 return ɵɵsyntheticHostProperty;
18391 }
18392
18393 /**
18394 * @license
18395 * Copyright Google LLC All Rights Reserved.
18396 *
18397 * Use of this source code is governed by an MIT-style license that can be
18398 * found in the LICENSE file at https://angular.io/license
18399 */
18400
18401 /**
18402 * Retrieves the component instance associated with a given DOM element.
18403 *
18404 * @usageNotes
18405 * Given the following DOM structure:
18406 * ```html
18407 * <my-app>
18408 * <div>
18409 * <child-comp></child-comp>
18410 * </div>
18411 * </my-app>
18412 * ```
18413 * Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
18414 * associated with this DOM element.
18415 *
18416 * Calling the function on `<my-app>` will return the `MyApp` instance.
18417 *
18418 *
18419 * @param element DOM element from which the component should be retrieved.
18420 * @returns Component instance associated with the element or `null` if there
18421 * is no component associated with it.
18422 *
18423 * @publicApi
18424 * @globalApi ng
18425 */
18426 function getComponent(element) {
18427 assertDomElement(element);
18428 var context = loadLContext(element, false);
18429 if (context === null)
18430 return null;
18431 if (context.component === undefined) {
18432 context.component = getComponentAtNodeIndex(context.nodeIndex, context.lView);
18433 }
18434 return context.component;
18435 }
18436 /**
18437 * If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
18438 * view that the element is part of. Otherwise retrieves the instance of the component whose view
18439 * owns the element (in this case, the result is the same as calling `getOwningComponent`).
18440 *
18441 * @param element Element for which to get the surrounding component instance.
18442 * @returns Instance of the component that is around the element or null if the element isn't
18443 * inside any component.
18444 *
18445 * @publicApi
18446 * @globalApi ng
18447 */
18448 function getContext(element) {
18449 assertDomElement(element);
18450 var context = loadLContext(element, false);
18451 return context === null ? null : context.lView[CONTEXT];
18452 }
18453 /**
18454 * Retrieves the component instance whose view contains the DOM element.
18455 *
18456 * For example, if `<child-comp>` is used in the template of `<app-comp>`
18457 * (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
18458 * would return `<app-comp>`.
18459 *
18460 * @param elementOrDir DOM element, component or directive instance
18461 * for which to retrieve the root components.
18462 * @returns Component instance whose view owns the DOM element or null if the element is not
18463 * part of a component view.
18464 *
18465 * @publicApi
18466 * @globalApi ng
18467 */
18468 function getOwningComponent(elementOrDir) {
18469 var context = loadLContext(elementOrDir, false);
18470 if (context === null)
18471 return null;
18472 var lView = context.lView;
18473 var parent;
18474 ngDevMode && assertLView(lView);
18475 while (lView[HOST] === null && (parent = getLViewParent(lView))) {
18476 // As long as lView[HOST] is null we know we are part of sub-template such as `*ngIf`
18477 lView = parent;
18478 }
18479 return lView[FLAGS] & 512 /* IsRoot */ ? null : lView[CONTEXT];
18480 }
18481 /**
18482 * Retrieves all root components associated with a DOM element, directive or component instance.
18483 * Root components are those which have been bootstrapped by Angular.
18484 *
18485 * @param elementOrDir DOM element, component or directive instance
18486 * for which to retrieve the root components.
18487 * @returns Root components associated with the target object.
18488 *
18489 * @publicApi
18490 * @globalApi ng
18491 */
18492 function getRootComponents(elementOrDir) {
18493 return __spread(getRootContext(elementOrDir).components);
18494 }
18495 /**
18496 * Retrieves an `Injector` associated with an element, component or directive instance.
18497 *
18498 * @param elementOrDir DOM element, component or directive instance for which to
18499 * retrieve the injector.
18500 * @returns Injector associated with the element, component or directive instance.
18501 *
18502 * @publicApi
18503 * @globalApi ng
18504 */
18505 function getInjector(elementOrDir) {
18506 var context = loadLContext(elementOrDir, false);
18507 if (context === null)
18508 return Injector.NULL;
18509 var tNode = context.lView[TVIEW].data[context.nodeIndex];
18510 return new NodeInjector(tNode, context.lView);
18511 }
18512 /**
18513 * Retrieve a set of injection tokens at a given DOM node.
18514 *
18515 * @param element Element for which the injection tokens should be retrieved.
18516 */
18517 function getInjectionTokens(element) {
18518 var context = loadLContext(element, false);
18519 if (context === null)
18520 return [];
18521 var lView = context.lView;
18522 var tView = lView[TVIEW];
18523 var tNode = tView.data[context.nodeIndex];
18524 var providerTokens = [];
18525 var startIndex = tNode.providerIndexes & 1048575 /* ProvidersStartIndexMask */;
18526 var endIndex = tNode.directiveEnd;
18527 for (var i = startIndex; i < endIndex; i++) {
18528 var value = tView.data[i];
18529 if (isDirectiveDefHack(value)) {
18530 // The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
18531 // design flaw. We should always store same type so that we can be monomorphic. The issue
18532 // is that for Components/Directives we store the def instead the type. The correct behavior
18533 // is that we should always be storing injectable type in this location.
18534 value = value.type;
18535 }
18536 providerTokens.push(value);
18537 }
18538 return providerTokens;
18539 }
18540 /**
18541 * Retrieves directive instances associated with a given DOM element. Does not include
18542 * component instances.
18543 *
18544 * @usageNotes
18545 * Given the following DOM structure:
18546 * ```
18547 * <my-app>
18548 * <button my-button></button>
18549 * <my-comp></my-comp>
18550 * </my-app>
18551 * ```
18552 * Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
18553 * directive that is associated with the DOM element.
18554 *
18555 * Calling `getDirectives` on `<my-comp>` will return an empty array.
18556 *
18557 * @param element DOM element for which to get the directives.
18558 * @returns Array of directives associated with the element.
18559 *
18560 * @publicApi
18561 * @globalApi ng
18562 */
18563 function getDirectives(element) {
18564 var context = loadLContext(element);
18565 if (context.directives === undefined) {
18566 context.directives = getDirectivesAtNodeIndex(context.nodeIndex, context.lView, false);
18567 }
18568 // The `directives` in this case are a named array called `LComponentView`. Clone the
18569 // result so we don't expose an internal data structure in the user's console.
18570 return context.directives === null ? [] : __spread(context.directives);
18571 }
18572 function loadLContext(target, throwOnNotFound) {
18573 if (throwOnNotFound === void 0) { throwOnNotFound = true; }
18574 var context = getLContext(target);
18575 if (!context && throwOnNotFound) {
18576 throw new Error(ngDevMode ? "Unable to find context associated with " + stringifyForError(target) :
18577 'Invalid ng target');
18578 }
18579 return context;
18580 }
18581 /**
18582 * Retrieve map of local references.
18583 *
18584 * The references are retrieved as a map of local reference name to element or directive instance.
18585 *
18586 * @param target DOM element, component or directive instance for which to retrieve
18587 * the local references.
18588 */
18589 function getLocalRefs(target) {
18590 var context = loadLContext(target, false);
18591 if (context === null)
18592 return {};
18593 if (context.localRefs === undefined) {
18594 context.localRefs = discoverLocalRefs(context.lView, context.nodeIndex);
18595 }
18596 return context.localRefs || {};
18597 }
18598 /**
18599 * Retrieves the host element of a component or directive instance.
18600 * The host element is the DOM element that matched the selector of the directive.
18601 *
18602 * @param componentOrDirective Component or directive instance for which the host
18603 * element should be retrieved.
18604 * @returns Host element of the target.
18605 *
18606 * @publicApi
18607 * @globalApi ng
18608 */
18609 function getHostElement(componentOrDirective) {
18610 return getLContext(componentOrDirective).native;
18611 }
18612 /**
18613 * Retrieves the rendered text for a given component.
18614 *
18615 * This function retrieves the host element of a component and
18616 * and then returns the `textContent` for that element. This implies
18617 * that the text returned will include re-projected content of
18618 * the component as well.
18619 *
18620 * @param component The component to return the content text for.
18621 */
18622 function getRenderedText(component) {
18623 var hostElement = getHostElement(component);
18624 return hostElement.textContent || '';
18625 }
18626 function loadLContextFromNode(node) {
18627 if (!(node instanceof Node))
18628 throw new Error('Expecting instance of DOM Element');
18629 return loadLContext(node);
18630 }
18631 /**
18632 * Retrieves a list of event listeners associated with a DOM element. The list does include host
18633 * listeners, but it does not include event listeners defined outside of the Angular context
18634 * (e.g. through `addEventListener`).
18635 *
18636 * @usageNotes
18637 * Given the following DOM structure:
18638 * ```
18639 * <my-app>
18640 * <div (click)="doSomething()"></div>
18641 * </my-app>
18642 *
18643 * ```
18644 * Calling `getListeners` on `<div>` will return an object that looks as follows:
18645 * ```
18646 * {
18647 * name: 'click',
18648 * element: <div>,
18649 * callback: () => doSomething(),
18650 * useCapture: false
18651 * }
18652 * ```
18653 *
18654 * @param element Element for which the DOM listeners should be retrieved.
18655 * @returns Array of event listeners on the DOM element.
18656 *
18657 * @publicApi
18658 * @globalApi ng
18659 */
18660 function getListeners(element) {
18661 assertDomElement(element);
18662 var lContext = loadLContext(element, false);
18663 if (lContext === null)
18664 return [];
18665 var lView = lContext.lView;
18666 var tView = lView[TVIEW];
18667 var lCleanup = lView[CLEANUP];
18668 var tCleanup = tView.cleanup;
18669 var listeners = [];
18670 if (tCleanup && lCleanup) {
18671 for (var i = 0; i < tCleanup.length;) {
18672 var firstParam = tCleanup[i++];
18673 var secondParam = tCleanup[i++];
18674 if (typeof firstParam === 'string') {
18675 var name = firstParam;
18676 var listenerElement = unwrapRNode(lView[secondParam]);
18677 var callback = lCleanup[tCleanup[i++]];
18678 var useCaptureOrIndx = tCleanup[i++];
18679 // if useCaptureOrIndx is boolean then report it as is.
18680 // if useCaptureOrIndx is positive number then it in unsubscribe method
18681 // if useCaptureOrIndx is negative number then it is a Subscription
18682 var type = (typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0) ? 'dom' : 'output';
18683 var useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
18684 if (element == listenerElement) {
18685 listeners.push({ element: element, name: name, callback: callback, useCapture: useCapture, type: type });
18686 }
18687 }
18688 }
18689 }
18690 listeners.sort(sortListeners);
18691 return listeners;
18692 }
18693 function sortListeners(a, b) {
18694 if (a.name == b.name)
18695 return 0;
18696 return a.name < b.name ? -1 : 1;
18697 }
18698 /**
18699 * This function should not exist because it is megamorphic and only mostly correct.
18700 *
18701 * See call site for more info.
18702 */
18703 function isDirectiveDefHack(obj) {
18704 return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
18705 }
18706 /**
18707 * Returns the attached `DebugNode` instance for an element in the DOM.
18708 *
18709 * @param element DOM element which is owned by an existing component's view.
18710 */
18711 function getDebugNode(element) {
18712 var debugNode = null;
18713 var lContext = loadLContextFromNode(element);
18714 var lView = lContext.lView;
18715 var nodeIndex = lContext.nodeIndex;
18716 if (nodeIndex !== -1) {
18717 var valueInLView = lView[nodeIndex];
18718 // this means that value in the lView is a component with its own
18719 // data. In this situation the TNode is not accessed at the same spot.
18720 var tNode = isLView(valueInLView) ? valueInLView[T_HOST] :
18721 getTNode(lView[TVIEW], nodeIndex - HEADER_OFFSET);
18722 debugNode = buildDebugNode(tNode, lView, nodeIndex);
18723 }
18724 return debugNode;
18725 }
18726 /**
18727 * Retrieve the component `LView` from component/element.
18728 *
18729 * NOTE: `LView` is a private and should not be leaked outside.
18730 * Don't export this method to `ng.*` on window.
18731 *
18732 * @param target DOM element or component instance for which to retrieve the LView.
18733 */
18734 function getComponentLView(target) {
18735 var lContext = loadLContext(target);
18736 var nodeIndx = lContext.nodeIndex;
18737 var lView = lContext.lView;
18738 var componentLView = lView[nodeIndx];
18739 ngDevMode && assertLView(componentLView);
18740 return componentLView;
18741 }
18742 /** Asserts that a value is a DOM Element. */
18743 function assertDomElement(value) {
18744 if (typeof Element !== 'undefined' && !(value instanceof Element)) {
18745 throw new Error('Expecting instance of DOM Element');
18746 }
18747 }
18748
18749 /**
18750 * @license
18751 * Copyright Google LLC All Rights Reserved.
18752 *
18753 * Use of this source code is governed by an MIT-style license that can be
18754 * found in the LICENSE file at https://angular.io/license
18755 */
18756 /**
18757 * Marks a component for check (in case of OnPush components) and synchronously
18758 * performs change detection on the application this component belongs to.
18759 *
18760 * @param component Component to {@link ChangeDetectorRef#markForCheck mark for check}.
18761 *
18762 * @publicApi
18763 * @globalApi ng
18764 */
18765 function applyChanges(component) {
18766 markDirty(component);
18767 getRootComponents(component).forEach(function (rootComponent) { return detectChanges(rootComponent); });
18768 }
18769
18770 /**
18771 * @license
18772 * Copyright Google LLC All Rights Reserved.
18773 *
18774 * Use of this source code is governed by an MIT-style license that can be
18775 * found in the LICENSE file at https://angular.io/license
18776 */
18777 /**
18778 * This file introduces series of globally accessible debug tools
18779 * to allow for the Angular debugging story to function.
18780 *
18781 * To see this in action run the following command:
18782 *
18783 * bazel run --config=ivy
18784 * //packages/core/test/bundling/todo:devserver
18785 *
18786 * Then load `localhost:5432` and start using the console tools.
18787 */
18788 /**
18789 * This value reflects the property on the window where the dev
18790 * tools are patched (window.ng).
18791 * */
18792 var GLOBAL_PUBLISH_EXPANDO_KEY = 'ng';
18793 var _published = false;
18794 /**
18795 * Publishes a collection of default debug tools onto`window.ng`.
18796 *
18797 * These functions are available globally when Angular is in development
18798 * mode and are automatically stripped away from prod mode is on.
18799 */
18800 function publishDefaultGlobalUtils() {
18801 if (!_published) {
18802 _published = true;
18803 publishGlobalUtil('getComponent', getComponent);
18804 publishGlobalUtil('getContext', getContext);
18805 publishGlobalUtil('getListeners', getListeners);
18806 publishGlobalUtil('getOwningComponent', getOwningComponent);
18807 publishGlobalUtil('getHostElement', getHostElement);
18808 publishGlobalUtil('getInjector', getInjector);
18809 publishGlobalUtil('getRootComponents', getRootComponents);
18810 publishGlobalUtil('getDirectives', getDirectives);
18811 publishGlobalUtil('applyChanges', applyChanges);
18812 }
18813 }
18814 /**
18815 * Publishes the given function to `window.ng` so that it can be
18816 * used from the browser console when an application is not in production.
18817 */
18818 function publishGlobalUtil(name, fn) {
18819 if (typeof COMPILED === 'undefined' || !COMPILED) {
18820 // Note: we can't export `ng` when using closure enhanced optimization as:
18821 // - closure declares globals itself for minified names, which sometimes clobber our `ng` global
18822 // - we can't declare a closure extern as the namespace `ng` is already used within Google
18823 // for typings for AngularJS (via `goog.provide('ng....')`).
18824 var w = _global;
18825 ngDevMode && assertDefined(fn, 'function not defined');
18826 if (w) {
18827 var container = w[GLOBAL_PUBLISH_EXPANDO_KEY];
18828 if (!container) {
18829 container = w[GLOBAL_PUBLISH_EXPANDO_KEY] = {};
18830 }
18831 container[name] = fn;
18832 }
18833 }
18834 }
18835
18836 /**
18837 * @license
18838 * Copyright Google LLC All Rights Reserved.
18839 *
18840 * Use of this source code is governed by an MIT-style license that can be
18841 * found in the LICENSE file at https://angular.io/license
18842 */
18843 var ɵ0$b = function (token, notFoundValue) {
18844 throw new Error('NullInjector: Not found: ' + stringifyForError(token));
18845 };
18846 // TODO: A hack to not pull in the NullInjector from @angular/core.
18847 var NULL_INJECTOR$1 = {
18848 get: ɵ0$b
18849 };
18850 /**
18851 * Bootstraps a Component into an existing host element and returns an instance
18852 * of the component.
18853 *
18854 * Use this function to bootstrap a component into the DOM tree. Each invocation
18855 * of this function will create a separate tree of components, injectors and
18856 * change detection cycles and lifetimes. To dynamically insert a new component
18857 * into an existing tree such that it shares the same injection, change detection
18858 * and object lifetime, use {@link ViewContainer#createComponent}.
18859 *
18860 * @param componentType Component to bootstrap
18861 * @param options Optional parameters which control bootstrapping
18862 */
18863 function renderComponent$1(componentType /* Type as workaround for: Microsoft/TypeScript/issues/4881 */, opts) {
18864 if (opts === void 0) { opts = {}; }
18865 ngDevMode && publishDefaultGlobalUtils();
18866 ngDevMode && assertComponentType(componentType);
18867 var rendererFactory = opts.rendererFactory || domRendererFactory3;
18868 var sanitizer = opts.sanitizer || null;
18869 var componentDef = getComponentDef(componentType);
18870 if (componentDef.type != componentType)
18871 componentDef.type = componentType;
18872 // The first index of the first selector is the tag name.
18873 var componentTag = componentDef.selectors[0][0];
18874 var hostRenderer = rendererFactory.createRenderer(null, null);
18875 var hostRNode = locateHostElement(hostRenderer, opts.host || componentTag, componentDef.encapsulation);
18876 var rootFlags = componentDef.onPush ? 64 /* Dirty */ | 512 /* IsRoot */ :
18877 16 /* CheckAlways */ | 512 /* IsRoot */;
18878 var rootContext = createRootContext(opts.scheduler, opts.playerHandler);
18879 var renderer = rendererFactory.createRenderer(hostRNode, componentDef);
18880 var rootTView = createTView(0 /* Root */, -1, null, 1, 0, null, null, null, null, null);
18881 var rootView = createLView(null, rootTView, rootContext, rootFlags, null, null, rendererFactory, renderer, undefined, opts.injector || null);
18882 enterView(rootView, null);
18883 var component;
18884 try {
18885 if (rendererFactory.begin)
18886 rendererFactory.begin();
18887 var componentView = createRootComponentView(hostRNode, componentDef, rootView, rendererFactory, renderer, sanitizer);
18888 component = createRootComponent(componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);
18889 // create mode pass
18890 renderView(rootTView, rootView, null);
18891 // update mode pass
18892 refreshView(rootTView, rootView, null, null);
18893 }
18894 finally {
18895 leaveView();
18896 if (rendererFactory.end)
18897 rendererFactory.end();
18898 }
18899 return component;
18900 }
18901 /**
18902 * Creates the root component view and the root component node.
18903 *
18904 * @param rNode Render host element.
18905 * @param def ComponentDef
18906 * @param rootView The parent view where the host node is stored
18907 * @param hostRenderer The current renderer
18908 * @param sanitizer The sanitizer, if provided
18909 *
18910 * @returns Component view created
18911 */
18912 function createRootComponentView(rNode, def, rootView, rendererFactory, hostRenderer, sanitizer) {
18913 var tView = rootView[TVIEW];
18914 ngDevMode && assertIndexInRange(rootView, 0 + HEADER_OFFSET);
18915 rootView[0 + HEADER_OFFSET] = rNode;
18916 var tNode = getOrCreateTNode(tView, null, 0, 3 /* Element */, null, null);
18917 var mergedAttrs = tNode.mergedAttrs = def.hostAttrs;
18918 if (mergedAttrs !== null) {
18919 computeStaticStyling(tNode, mergedAttrs, true);
18920 if (rNode !== null) {
18921 setUpAttributes(hostRenderer, rNode, mergedAttrs);
18922 if (tNode.classes !== null) {
18923 writeDirectClass(hostRenderer, rNode, tNode.classes);
18924 }
18925 if (tNode.styles !== null) {
18926 writeDirectStyle(hostRenderer, rNode, tNode.styles);
18927 }
18928 }
18929 }
18930 var viewRenderer = rendererFactory.createRenderer(rNode, def);
18931 var componentView = createLView(rootView, getOrCreateTComponentView(def), null, def.onPush ? 64 /* Dirty */ : 16 /* CheckAlways */, rootView[HEADER_OFFSET], tNode, rendererFactory, viewRenderer, sanitizer);
18932 if (tView.firstCreatePass) {
18933 diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
18934 markAsComponentHost(tView, tNode);
18935 initTNodeFlags(tNode, rootView.length, 1);
18936 }
18937 addToViewTree(rootView, componentView);
18938 // Store component view at node index, with node as the HOST
18939 return rootView[HEADER_OFFSET] = componentView;
18940 }
18941 /**
18942 * Creates a root component and sets it up with features and host bindings. Shared by
18943 * renderComponent() and ViewContainerRef.createComponent().
18944 */
18945 function createRootComponent(componentView, componentDef, rootLView, rootContext, hostFeatures) {
18946 var tView = rootLView[TVIEW];
18947 // Create directive instance with factory() and store at next index in viewData
18948 var component = instantiateRootComponent(tView, rootLView, componentDef);
18949 rootContext.components.push(component);
18950 componentView[CONTEXT] = component;
18951 hostFeatures && hostFeatures.forEach(function (feature) { return feature(component, componentDef); });
18952 // We want to generate an empty QueryList for root content queries for backwards
18953 // compatibility with ViewEngine.
18954 if (componentDef.contentQueries) {
18955 componentDef.contentQueries(1 /* Create */, component, rootLView.length - 1);
18956 }
18957 var rootTNode = getPreviousOrParentTNode();
18958 if (tView.firstCreatePass &&
18959 (componentDef.hostBindings !== null || componentDef.hostAttrs !== null)) {
18960 var elementIndex = rootTNode.index - HEADER_OFFSET;
18961 setSelectedIndex(elementIndex);
18962 var rootTView = rootLView[TVIEW];
18963 addHostBindingsToExpandoInstructions(rootTView, componentDef);
18964 growHostVarsSpace(rootTView, rootLView, componentDef.hostVars);
18965 invokeHostBindingsInCreationMode(componentDef, component);
18966 }
18967 return component;
18968 }
18969 function createRootContext(scheduler, playerHandler) {
18970 return {
18971 components: [],
18972 scheduler: scheduler || defaultScheduler,
18973 clean: CLEAN_PROMISE,
18974 playerHandler: playerHandler || null,
18975 flags: 0 /* Empty */
18976 };
18977 }
18978 /**
18979 * Used to enable lifecycle hooks on the root component.
18980 *
18981 * Include this feature when calling `renderComponent` if the root component
18982 * you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
18983 * be called properly.
18984 *
18985 * Example:
18986 *
18987 * ```
18988 * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
18989 * ```
18990 */
18991 function LifecycleHooksFeature(component, def) {
18992 var rootTView = readPatchedLView(component)[TVIEW];
18993 var dirIndex = rootTView.data.length - 1;
18994 // TODO(misko): replace `as TNode` with createTNode call. (needs refactoring to lose dep on
18995 // LNode).
18996 registerPostOrderHooks(rootTView, { directiveStart: dirIndex, directiveEnd: dirIndex + 1 });
18997 }
18998 /**
18999 * Wait on component until it is rendered.
19000 *
19001 * This function returns a `Promise` which is resolved when the component's
19002 * change detection is executed. This is determined by finding the scheduler
19003 * associated with the `component`'s render tree and waiting until the scheduler
19004 * flushes. If nothing is scheduled, the function returns a resolved promise.
19005 *
19006 * Example:
19007 * ```
19008 * await whenRendered(myComponent);
19009 * ```
19010 *
19011 * @param component Component to wait upon
19012 * @returns Promise which resolves when the component is rendered.
19013 */
19014 function whenRendered(component) {
19015 return getRootContext(component).clean;
19016 }
19017
19018 /**
19019 * @license
19020 * Copyright Google LLC All Rights Reserved.
19021 *
19022 * Use of this source code is governed by an MIT-style license that can be
19023 * found in the LICENSE file at https://angular.io/license
19024 */
19025 function getSuperType(type) {
19026 return Object.getPrototypeOf(type.prototype).constructor;
19027 }
19028 /**
19029 * Merges the definition from a super class to a sub class.
19030 * @param definition The definition that is a SubClass of another directive of component
19031 *
19032 * @codeGenApi
19033 */
19034 function ɵɵInheritDefinitionFeature(definition) {
19035 var superType = getSuperType(definition.type);
19036 var shouldInheritFields = true;
19037 var inheritanceChain = [definition];
19038 while (superType) {
19039 var superDef = undefined;
19040 if (isComponentDef(definition)) {
19041 // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
19042 superDef = superType.ɵcmp || superType.ɵdir;
19043 }
19044 else {
19045 if (superType.ɵcmp) {
19046 throw new Error('Directives cannot inherit Components');
19047 }
19048 // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
19049 superDef = superType.ɵdir;
19050 }
19051 if (superDef) {
19052 if (shouldInheritFields) {
19053 inheritanceChain.push(superDef);
19054 // Some fields in the definition may be empty, if there were no values to put in them that
19055 // would've justified object creation. Unwrap them if necessary.
19056 var writeableDef = definition;
19057 writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
19058 writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
19059 writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
19060 // Merge hostBindings
19061 var superHostBindings = superDef.hostBindings;
19062 superHostBindings && inheritHostBindings(definition, superHostBindings);
19063 // Merge queries
19064 var superViewQuery = superDef.viewQuery;
19065 var superContentQueries = superDef.contentQueries;
19066 superViewQuery && inheritViewQuery(definition, superViewQuery);
19067 superContentQueries && inheritContentQueries(definition, superContentQueries);
19068 // Merge inputs and outputs
19069 fillProperties(definition.inputs, superDef.inputs);
19070 fillProperties(definition.declaredInputs, superDef.declaredInputs);
19071 fillProperties(definition.outputs, superDef.outputs);
19072 // Merge animations metadata.
19073 // If `superDef` is a Component, the `data` field is present (defaults to an empty object).
19074 if (isComponentDef(superDef) && superDef.data.animation) {
19075 // If super def is a Component, the `definition` is also a Component, since Directives can
19076 // not inherit Components (we throw an error above and cannot reach this code).
19077 var defData = definition.data;
19078 defData.animation = (defData.animation || []).concat(superDef.data.animation);
19079 }
19080 }
19081 // Run parent features
19082 var features = superDef.features;
19083 if (features) {
19084 for (var i = 0; i < features.length; i++) {
19085 var feature = features[i];
19086 if (feature && feature.ngInherit) {
19087 feature(definition);
19088 }
19089 // If `InheritDefinitionFeature` is a part of the current `superDef`, it means that this
19090 // def already has all the necessary information inherited from its super class(es), so we
19091 // can stop merging fields from super classes. However we need to iterate through the
19092 // prototype chain to look for classes that might contain other "features" (like
19093 // NgOnChanges), which we should invoke for the original `definition`. We set the
19094 // `shouldInheritFields` flag to indicate that, essentially skipping fields inheritance
19095 // logic and only invoking functions from the "features" list.
19096 if (feature === ɵɵInheritDefinitionFeature) {
19097 shouldInheritFields = false;
19098 }
19099 }
19100 }
19101 }
19102 superType = Object.getPrototypeOf(superType);
19103 }
19104 mergeHostAttrsAcrossInheritance(inheritanceChain);
19105 }
19106 /**
19107 * Merge the `hostAttrs` and `hostVars` from the inherited parent to the base class.
19108 *
19109 * @param inheritanceChain A list of `WritableDefs` starting at the top most type and listing
19110 * sub-types in order. For each type take the `hostAttrs` and `hostVars` and merge it with the child
19111 * type.
19112 */
19113 function mergeHostAttrsAcrossInheritance(inheritanceChain) {
19114 var hostVars = 0;
19115 var hostAttrs = null;
19116 // We process the inheritance order from the base to the leaves here.
19117 for (var i = inheritanceChain.length - 1; i >= 0; i--) {
19118 var def = inheritanceChain[i];
19119 // For each `hostVars`, we need to add the superclass amount.
19120 def.hostVars = (hostVars += def.hostVars);
19121 // for each `hostAttrs` we need to merge it with superclass.
19122 def.hostAttrs =
19123 mergeHostAttrs(def.hostAttrs, hostAttrs = mergeHostAttrs(hostAttrs, def.hostAttrs));
19124 }
19125 }
19126 function maybeUnwrapEmpty(value) {
19127 if (value === EMPTY_OBJ) {
19128 return {};
19129 }
19130 else if (value === EMPTY_ARRAY) {
19131 return [];
19132 }
19133 else {
19134 return value;
19135 }
19136 }
19137 function inheritViewQuery(definition, superViewQuery) {
19138 var prevViewQuery = definition.viewQuery;
19139 if (prevViewQuery) {
19140 definition.viewQuery = function (rf, ctx) {
19141 superViewQuery(rf, ctx);
19142 prevViewQuery(rf, ctx);
19143 };
19144 }
19145 else {
19146 definition.viewQuery = superViewQuery;
19147 }
19148 }
19149 function inheritContentQueries(definition, superContentQueries) {
19150 var prevContentQueries = definition.contentQueries;
19151 if (prevContentQueries) {
19152 definition.contentQueries = function (rf, ctx, directiveIndex) {
19153 superContentQueries(rf, ctx, directiveIndex);
19154 prevContentQueries(rf, ctx, directiveIndex);
19155 };
19156 }
19157 else {
19158 definition.contentQueries = superContentQueries;
19159 }
19160 }
19161 function inheritHostBindings(definition, superHostBindings) {
19162 var prevHostBindings = definition.hostBindings;
19163 if (prevHostBindings) {
19164 definition.hostBindings = function (rf, ctx) {
19165 superHostBindings(rf, ctx);
19166 prevHostBindings(rf, ctx);
19167 };
19168 }
19169 else {
19170 definition.hostBindings = superHostBindings;
19171 }
19172 }
19173
19174 /**
19175 * Fields which exist on either directive or component definitions, and need to be copied from
19176 * parent to child classes by the `ɵɵCopyDefinitionFeature`.
19177 */
19178 var COPY_DIRECTIVE_FIELDS = [
19179 // The child class should use the providers of its parent.
19180 'providersResolver',
19181 ];
19182 /**
19183 * Fields which exist only on component definitions, and need to be copied from parent to child
19184 * classes by the `ɵɵCopyDefinitionFeature`.
19185 *
19186 * The type here allows any field of `ComponentDef` which is not also a property of `DirectiveDef`,
19187 * since those should go in `COPY_DIRECTIVE_FIELDS` above.
19188 */
19189 var COPY_COMPONENT_FIELDS = [
19190 // The child class should use the template function of its parent, including all template
19191 // semantics.
19192 'template',
19193 'decls',
19194 'consts',
19195 'vars',
19196 'onPush',
19197 'ngContentSelectors',
19198 // The child class should use the CSS styles of its parent, including all styling semantics.
19199 'styles',
19200 'encapsulation',
19201 // The child class should be checked by the runtime in the same way as its parent.
19202 'schemas',
19203 ];
19204 /**
19205 * Copies the fields not handled by the `ɵɵInheritDefinitionFeature` from the supertype of a
19206 * definition.
19207 *
19208 * This exists primarily to support ngcc migration of an existing View Engine pattern, where an
19209 * entire decorator is inherited from a parent to a child class. When ngcc detects this case, it
19210 * generates a skeleton definition on the child class, and applies this feature.
19211 *
19212 * The `ɵɵCopyDefinitionFeature` then copies any needed fields from the parent class' definition,
19213 * including things like the component template function.
19214 *
19215 * @param definition The definition of a child class which inherits from a parent class with its
19216 * own definition.
19217 *
19218 * @codeGenApi
19219 */
19220 function ɵɵCopyDefinitionFeature(definition) {
19221 var e_1, _a, e_2, _b;
19222 var superType = getSuperType(definition.type);
19223 var superDef = undefined;
19224 if (isComponentDef(definition)) {
19225 // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
19226 superDef = superType.ɵcmp;
19227 }
19228 else {
19229 // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
19230 superDef = superType.ɵdir;
19231 }
19232 // Needed because `definition` fields are readonly.
19233 var defAny = definition;
19234 try {
19235 // Copy over any fields that apply to either directives or components.
19236 for (var COPY_DIRECTIVE_FIELDS_1 = __values(COPY_DIRECTIVE_FIELDS), COPY_DIRECTIVE_FIELDS_1_1 = COPY_DIRECTIVE_FIELDS_1.next(); !COPY_DIRECTIVE_FIELDS_1_1.done; COPY_DIRECTIVE_FIELDS_1_1 = COPY_DIRECTIVE_FIELDS_1.next()) {
19237 var field = COPY_DIRECTIVE_FIELDS_1_1.value;
19238 defAny[field] = superDef[field];
19239 }
19240 }
19241 catch (e_1_1) { e_1 = { error: e_1_1 }; }
19242 finally {
19243 try {
19244 if (COPY_DIRECTIVE_FIELDS_1_1 && !COPY_DIRECTIVE_FIELDS_1_1.done && (_a = COPY_DIRECTIVE_FIELDS_1.return)) _a.call(COPY_DIRECTIVE_FIELDS_1);
19245 }
19246 finally { if (e_1) throw e_1.error; }
19247 }
19248 if (isComponentDef(superDef)) {
19249 try {
19250 // Copy over any component-specific fields.
19251 for (var COPY_COMPONENT_FIELDS_1 = __values(COPY_COMPONENT_FIELDS), COPY_COMPONENT_FIELDS_1_1 = COPY_COMPONENT_FIELDS_1.next(); !COPY_COMPONENT_FIELDS_1_1.done; COPY_COMPONENT_FIELDS_1_1 = COPY_COMPONENT_FIELDS_1.next()) {
19252 var field = COPY_COMPONENT_FIELDS_1_1.value;
19253 defAny[field] = superDef[field];
19254 }
19255 }
19256 catch (e_2_1) { e_2 = { error: e_2_1 }; }
19257 finally {
19258 try {
19259 if (COPY_COMPONENT_FIELDS_1_1 && !COPY_COMPONENT_FIELDS_1_1.done && (_b = COPY_COMPONENT_FIELDS_1.return)) _b.call(COPY_COMPONENT_FIELDS_1);
19260 }
19261 finally { if (e_2) throw e_2.error; }
19262 }
19263 }
19264 }
19265
19266 /**
19267 * @license
19268 * Copyright Google LLC All Rights Reserved.
19269 *
19270 * Use of this source code is governed by an MIT-style license that can be
19271 * found in the LICENSE file at https://angular.io/license
19272 */
19273 /**
19274 * Resolves the providers which are defined in the DirectiveDef.
19275 *
19276 * When inserting the tokens and the factories in their respective arrays, we can assume that
19277 * this method is called first for the component (if any), and then for other directives on the same
19278 * node.
19279 * As a consequence,the providers are always processed in that order:
19280 * 1) The view providers of the component
19281 * 2) The providers of the component
19282 * 3) The providers of the other directives
19283 * This matches the structure of the injectables arrays of a view (for each node).
19284 * So the tokens and the factories can be pushed at the end of the arrays, except
19285 * in one case for multi providers.
19286 *
19287 * @param def the directive definition
19288 * @param providers: Array of `providers`.
19289 * @param viewProviders: Array of `viewProviders`.
19290 */
19291 function providersResolver(def, providers, viewProviders) {
19292 var tView = getTView();
19293 if (tView.firstCreatePass) {
19294 var isComponent = isComponentDef(def);
19295 // The list of view providers is processed first, and the flags are updated
19296 resolveProvider$1(viewProviders, tView.data, tView.blueprint, isComponent, true);
19297 // Then, the list of providers is processed, and the flags are updated
19298 resolveProvider$1(providers, tView.data, tView.blueprint, isComponent, false);
19299 }
19300 }
19301 /**
19302 * Resolves a provider and publishes it to the DI system.
19303 */
19304 function resolveProvider$1(provider, tInjectables, lInjectablesBlueprint, isComponent, isViewProvider) {
19305 provider = resolveForwardRef(provider);
19306 if (Array.isArray(provider)) {
19307 // Recursively call `resolveProvider`
19308 // Recursion is OK in this case because this code will not be in hot-path once we implement
19309 // cloning of the initial state.
19310 for (var i = 0; i < provider.length; i++) {
19311 resolveProvider$1(provider[i], tInjectables, lInjectablesBlueprint, isComponent, isViewProvider);
19312 }
19313 }
19314 else {
19315 var tView = getTView();
19316 var lView = getLView();
19317 var token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
19318 var providerFactory = providerToFactory(provider);
19319 var tNode = getPreviousOrParentTNode();
19320 var beginIndex = tNode.providerIndexes & 1048575 /* ProvidersStartIndexMask */;
19321 var endIndex = tNode.directiveStart;
19322 var cptViewProvidersCount = tNode.providerIndexes >> 20 /* CptViewProvidersCountShift */;
19323 if (isTypeProvider(provider) || !provider.multi) {
19324 // Single provider case: the factory is created and pushed immediately
19325 var factory = new NodeInjectorFactory(providerFactory, isViewProvider, ɵɵdirectiveInject);
19326 var existingFactoryIndex = indexOf(token, tInjectables, isViewProvider ? beginIndex : beginIndex + cptViewProvidersCount, endIndex);
19327 if (existingFactoryIndex === -1) {
19328 diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, token);
19329 registerDestroyHooksIfSupported(tView, provider, tInjectables.length);
19330 tInjectables.push(token);
19331 tNode.directiveStart++;
19332 tNode.directiveEnd++;
19333 if (isViewProvider) {
19334 tNode.providerIndexes += 1048576 /* CptViewProvidersCountShifter */;
19335 }
19336 lInjectablesBlueprint.push(factory);
19337 lView.push(factory);
19338 }
19339 else {
19340 lInjectablesBlueprint[existingFactoryIndex] = factory;
19341 lView[existingFactoryIndex] = factory;
19342 }
19343 }
19344 else {
19345 // Multi provider case:
19346 // We create a multi factory which is going to aggregate all the values.
19347 // Since the output of such a factory depends on content or view injection,
19348 // we create two of them, which are linked together.
19349 //
19350 // The first one (for view providers) is always in the first block of the injectables array,
19351 // and the second one (for providers) is always in the second block.
19352 // This is important because view providers have higher priority. When a multi token
19353 // is being looked up, the view providers should be found first.
19354 // Note that it is not possible to have a multi factory in the third block (directive block).
19355 //
19356 // The algorithm to process multi providers is as follows:
19357 // 1) If the multi provider comes from the `viewProviders` of the component:
19358 // a) If the special view providers factory doesn't exist, it is created and pushed.
19359 // b) Else, the multi provider is added to the existing multi factory.
19360 // 2) If the multi provider comes from the `providers` of the component or of another
19361 // directive:
19362 // a) If the multi factory doesn't exist, it is created and provider pushed into it.
19363 // It is also linked to the multi factory for view providers, if it exists.
19364 // b) Else, the multi provider is added to the existing multi factory.
19365 var existingProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex + cptViewProvidersCount, endIndex);
19366 var existingViewProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex, beginIndex + cptViewProvidersCount);
19367 var doesProvidersFactoryExist = existingProvidersFactoryIndex >= 0 &&
19368 lInjectablesBlueprint[existingProvidersFactoryIndex];
19369 var doesViewProvidersFactoryExist = existingViewProvidersFactoryIndex >= 0 &&
19370 lInjectablesBlueprint[existingViewProvidersFactoryIndex];
19371 if (isViewProvider && !doesViewProvidersFactoryExist ||
19372 !isViewProvider && !doesProvidersFactoryExist) {
19373 // Cases 1.a and 2.a
19374 diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, token);
19375 var factory = multiFactory(isViewProvider ? multiViewProvidersFactoryResolver : multiProvidersFactoryResolver, lInjectablesBlueprint.length, isViewProvider, isComponent, providerFactory);
19376 if (!isViewProvider && doesViewProvidersFactoryExist) {
19377 lInjectablesBlueprint[existingViewProvidersFactoryIndex].providerFactory = factory;
19378 }
19379 registerDestroyHooksIfSupported(tView, provider, tInjectables.length, 0);
19380 tInjectables.push(token);
19381 tNode.directiveStart++;
19382 tNode.directiveEnd++;
19383 if (isViewProvider) {
19384 tNode.providerIndexes += 1048576 /* CptViewProvidersCountShifter */;
19385 }
19386 lInjectablesBlueprint.push(factory);
19387 lView.push(factory);
19388 }
19389 else {
19390 // Cases 1.b and 2.b
19391 var indexInFactory = multiFactoryAdd(lInjectablesBlueprint[isViewProvider ? existingViewProvidersFactoryIndex :
19392 existingProvidersFactoryIndex], providerFactory, !isViewProvider && isComponent);
19393 registerDestroyHooksIfSupported(tView, provider, existingProvidersFactoryIndex > -1 ? existingProvidersFactoryIndex :
19394 existingViewProvidersFactoryIndex, indexInFactory);
19395 }
19396 if (!isViewProvider && isComponent && doesViewProvidersFactoryExist) {
19397 lInjectablesBlueprint[existingViewProvidersFactoryIndex].componentProviders++;
19398 }
19399 }
19400 }
19401 }
19402 /**
19403 * Registers the `ngOnDestroy` hook of a provider, if the provider supports destroy hooks.
19404 * @param tView `TView` in which to register the hook.
19405 * @param provider Provider whose hook should be registered.
19406 * @param contextIndex Index under which to find the context for the hook when it's being invoked.
19407 * @param indexInFactory Only required for `multi` providers. Index of the provider in the multi
19408 * provider factory.
19409 */
19410 function registerDestroyHooksIfSupported(tView, provider, contextIndex, indexInFactory) {
19411 var providerIsTypeProvider = isTypeProvider(provider);
19412 if (providerIsTypeProvider || isClassProvider(provider)) {
19413 var prototype = (provider.useClass || provider).prototype;
19414 var ngOnDestroy = prototype.ngOnDestroy;
19415 if (ngOnDestroy) {
19416 var hooks = tView.destroyHooks || (tView.destroyHooks = []);
19417 if (!providerIsTypeProvider && provider.multi) {
19418 ngDevMode &&
19419 assertDefined(indexInFactory, 'indexInFactory when registering multi factory destroy hook');
19420 var existingCallbacksIndex = hooks.indexOf(contextIndex);
19421 if (existingCallbacksIndex === -1) {
19422 hooks.push(contextIndex, [indexInFactory, ngOnDestroy]);
19423 }
19424 else {
19425 hooks[existingCallbacksIndex + 1].push(indexInFactory, ngOnDestroy);
19426 }
19427 }
19428 else {
19429 hooks.push(contextIndex, ngOnDestroy);
19430 }
19431 }
19432 }
19433 }
19434 /**
19435 * Add a factory in a multi factory.
19436 * @returns Index at which the factory was inserted.
19437 */
19438 function multiFactoryAdd(multiFactory, factory, isComponentProvider) {
19439 if (isComponentProvider) {
19440 multiFactory.componentProviders++;
19441 }
19442 return multiFactory.multi.push(factory) - 1;
19443 }
19444 /**
19445 * Returns the index of item in the array, but only in the begin to end range.
19446 */
19447 function indexOf(item, arr, begin, end) {
19448 for (var i = begin; i < end; i++) {
19449 if (arr[i] === item)
19450 return i;
19451 }
19452 return -1;
19453 }
19454 /**
19455 * Use this with `multi` `providers`.
19456 */
19457 function multiProvidersFactoryResolver(_, tData, lData, tNode) {
19458 return multiResolve(this.multi, []);
19459 }
19460 /**
19461 * Use this with `multi` `viewProviders`.
19462 *
19463 * This factory knows how to concatenate itself with the existing `multi` `providers`.
19464 */
19465 function multiViewProvidersFactoryResolver(_, tData, lView, tNode) {
19466 var factories = this.multi;
19467 var result;
19468 if (this.providerFactory) {
19469 var componentCount = this.providerFactory.componentProviders;
19470 var multiProviders = getNodeInjectable(lView, lView[TVIEW], this.providerFactory.index, tNode);
19471 // Copy the section of the array which contains `multi` `providers` from the component
19472 result = multiProviders.slice(0, componentCount);
19473 // Insert the `viewProvider` instances.
19474 multiResolve(factories, result);
19475 // Copy the section of the array which contains `multi` `providers` from other directives
19476 for (var i = componentCount; i < multiProviders.length; i++) {
19477 result.push(multiProviders[i]);
19478 }
19479 }
19480 else {
19481 result = [];
19482 // Insert the `viewProvider` instances.
19483 multiResolve(factories, result);
19484 }
19485 return result;
19486 }
19487 /**
19488 * Maps an array of factories into an array of values.
19489 */
19490 function multiResolve(factories, result) {
19491 for (var i = 0; i < factories.length; i++) {
19492 var factory = factories[i];
19493 result.push(factory());
19494 }
19495 return result;
19496 }
19497 /**
19498 * Creates a multi factory.
19499 */
19500 function multiFactory(factoryFn, index, isViewProvider, isComponent, f) {
19501 var factory = new NodeInjectorFactory(factoryFn, isViewProvider, ɵɵdirectiveInject);
19502 factory.multi = [];
19503 factory.index = index;
19504 factory.componentProviders = 0;
19505 multiFactoryAdd(factory, f, isComponent && !isViewProvider);
19506 return factory;
19507 }
19508
19509 /**
19510 * This feature resolves the providers of a directive (or component),
19511 * and publish them into the DI system, making it visible to others for injection.
19512 *
19513 * For example:
19514 * ```ts
19515 * class ComponentWithProviders {
19516 * constructor(private greeter: GreeterDE) {}
19517 *
19518 * static ɵcmp = defineComponent({
19519 * type: ComponentWithProviders,
19520 * selectors: [['component-with-providers']],
19521 * factory: () => new ComponentWithProviders(directiveInject(GreeterDE as any)),
19522 * decls: 1,
19523 * vars: 1,
19524 * template: function(fs: RenderFlags, ctx: ComponentWithProviders) {
19525 * if (fs & RenderFlags.Create) {
19526 * ɵɵtext(0);
19527 * }
19528 * if (fs & RenderFlags.Update) {
19529 * ɵɵtextInterpolate(ctx.greeter.greet());
19530 * }
19531 * },
19532 * features: [ProvidersFeature([GreeterDE])]
19533 * });
19534 * }
19535 * ```
19536 *
19537 * @param definition
19538 *
19539 * @codeGenApi
19540 */
19541 function ɵɵProvidersFeature(providers, viewProviders) {
19542 if (viewProviders === void 0) { viewProviders = []; }
19543 return function (definition) {
19544 definition.providersResolver =
19545 function (def, processProvidersFn) {
19546 return providersResolver(def, //
19547 processProvidersFn ? processProvidersFn(providers) : providers, //
19548 viewProviders);
19549 };
19550 };
19551 }
19552
19553 /**
19554 * @license
19555 * Copyright Google LLC All Rights Reserved.
19556 *
19557 * Use of this source code is governed by an MIT-style license that can be
19558 * found in the LICENSE file at https://angular.io/license
19559 */
19560 /**
19561 * Represents a component created by a `ComponentFactory`.
19562 * Provides access to the component instance and related objects,
19563 * and provides the means of destroying the instance.
19564 *
19565 * @publicApi
19566 */
19567 var ComponentRef = /** @class */ (function () {
19568 function ComponentRef() {
19569 }
19570 return ComponentRef;
19571 }());
19572 /**
19573 * Base class for a factory that can create a component dynamically.
19574 * Instantiate a factory for a given type of component with `resolveComponentFactory()`.
19575 * Use the resulting `ComponentFactory.create()` method to create a component of that type.
19576 *
19577 * @see [Dynamic Components](guide/dynamic-component-loader)
19578 *
19579 * @publicApi
19580 */
19581 var ComponentFactory = /** @class */ (function () {
19582 function ComponentFactory() {
19583 }
19584 return ComponentFactory;
19585 }());
19586
19587 function noComponentFactoryError(component) {
19588 var error = Error("No component factory found for " + stringify(component) + ". Did you add it to @NgModule.entryComponents?");
19589 error[ERROR_COMPONENT] = component;
19590 return error;
19591 }
19592 var ERROR_COMPONENT = 'ngComponent';
19593 function getComponent$1(error) {
19594 return error[ERROR_COMPONENT];
19595 }
19596 var _NullComponentFactoryResolver = /** @class */ (function () {
19597 function _NullComponentFactoryResolver() {
19598 }
19599 _NullComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
19600 throw noComponentFactoryError(component);
19601 };
19602 return _NullComponentFactoryResolver;
19603 }());
19604 /**
19605 * A simple registry that maps `Components` to generated `ComponentFactory` classes
19606 * that can be used to create instances of components.
19607 * Use to obtain the factory for a given component type,
19608 * then use the factory's `create()` method to create a component of that type.
19609 *
19610 * @see [Dynamic Components](guide/dynamic-component-loader)
19611 * @publicApi
19612 */
19613 var ComponentFactoryResolver = /** @class */ (function () {
19614 function ComponentFactoryResolver() {
19615 }
19616 return ComponentFactoryResolver;
19617 }());
19618 ComponentFactoryResolver.NULL = new _NullComponentFactoryResolver();
19619 var CodegenComponentFactoryResolver = /** @class */ (function () {
19620 function CodegenComponentFactoryResolver(factories, _parent, _ngModule) {
19621 this._parent = _parent;
19622 this._ngModule = _ngModule;
19623 this._factories = new Map();
19624 for (var i = 0; i < factories.length; i++) {
19625 var factory = factories[i];
19626 this._factories.set(factory.componentType, factory);
19627 }
19628 }
19629 CodegenComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
19630 var factory = this._factories.get(component);
19631 if (!factory && this._parent) {
19632 factory = this._parent.resolveComponentFactory(component);
19633 }
19634 if (!factory) {
19635 throw noComponentFactoryError(component);
19636 }
19637 return new ComponentFactoryBoundToModule(factory, this._ngModule);
19638 };
19639 return CodegenComponentFactoryResolver;
19640 }());
19641 var ComponentFactoryBoundToModule = /** @class */ (function (_super) {
19642 __extends(ComponentFactoryBoundToModule, _super);
19643 function ComponentFactoryBoundToModule(factory, ngModule) {
19644 var _this = _super.call(this) || this;
19645 _this.factory = factory;
19646 _this.ngModule = ngModule;
19647 _this.selector = factory.selector;
19648 _this.componentType = factory.componentType;
19649 _this.ngContentSelectors = factory.ngContentSelectors;
19650 _this.inputs = factory.inputs;
19651 _this.outputs = factory.outputs;
19652 return _this;
19653 }
19654 ComponentFactoryBoundToModule.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
19655 return this.factory.create(injector, projectableNodes, rootSelectorOrNode, ngModule || this.ngModule);
19656 };
19657 return ComponentFactoryBoundToModule;
19658 }(ComponentFactory));
19659
19660 /**
19661 * @license
19662 * Copyright Google LLC All Rights Reserved.
19663 *
19664 * Use of this source code is governed by an MIT-style license that can be
19665 * found in the LICENSE file at https://angular.io/license
19666 */
19667 function noop() {
19668 var args = [];
19669 for (var _i = 0; _i < arguments.length; _i++) {
19670 args[_i] = arguments[_i];
19671 }
19672 // Do nothing.
19673 }
19674
19675 /**
19676 * @license
19677 * Copyright Google LLC All Rights Reserved.
19678 *
19679 * Use of this source code is governed by an MIT-style license that can be
19680 * found in the LICENSE file at https://angular.io/license
19681 */
19682 /**
19683 * A wrapper around a native element inside of a View.
19684 *
19685 * An `ElementRef` is backed by a render-specific element. In the browser, this is usually a DOM
19686 * element.
19687 *
19688 * @security Permitting direct access to the DOM can make your application more vulnerable to
19689 * XSS attacks. Carefully review any use of `ElementRef` in your code. For more detail, see the
19690 * [Security Guide](http://g.co/ng/security).
19691 *
19692 * @publicApi
19693 */
19694 // Note: We don't expose things like `Injector`, `ViewContainer`, ... here,
19695 // i.e. users have to ask for what they need. With that, we can build better analysis tools
19696 // and could do better codegen in the future.
19697 var ElementRef = /** @class */ (function () {
19698 function ElementRef(nativeElement) {
19699 this.nativeElement = nativeElement;
19700 }
19701 return ElementRef;
19702 }());
19703 /**
19704 * @internal
19705 * @nocollapse
19706 */
19707 ElementRef.__NG_ELEMENT_ID__ = function () { return SWITCH_ELEMENT_REF_FACTORY(ElementRef); };
19708 var SWITCH_ELEMENT_REF_FACTORY__POST_R3__ = injectElementRef;
19709 var SWITCH_ELEMENT_REF_FACTORY__PRE_R3__ = noop;
19710 var SWITCH_ELEMENT_REF_FACTORY = SWITCH_ELEMENT_REF_FACTORY__PRE_R3__;
19711
19712 /**
19713 * @license
19714 * Copyright Google LLC All Rights Reserved.
19715 *
19716 * Use of this source code is governed by an MIT-style license that can be
19717 * found in the LICENSE file at https://angular.io/license
19718 */
19719 var Renderer2Interceptor = new InjectionToken('Renderer2Interceptor');
19720 /**
19721 * Creates and initializes a custom renderer that implements the `Renderer2` base class.
19722 *
19723 * @publicApi
19724 */
19725 var RendererFactory2 = /** @class */ (function () {
19726 function RendererFactory2() {
19727 }
19728 return RendererFactory2;
19729 }());
19730 (function (RendererStyleFlags2) {
19731 // TODO(misko): This needs to be refactored into a separate file so that it can be imported from
19732 // `node_manipulation.ts` Currently doing the import cause resolution order to change and fails
19733 // the tests. The work around is to have hard coded value in `node_manipulation.ts` for now.
19734 /**
19735 * Marks a style as important.
19736 */
19737 RendererStyleFlags2[RendererStyleFlags2["Important"] = 1] = "Important";
19738 /**
19739 * Marks a style as using dash case naming (this-is-dash-case).
19740 */
19741 RendererStyleFlags2[RendererStyleFlags2["DashCase"] = 2] = "DashCase";
19742 })(exports.RendererStyleFlags2 || (exports.RendererStyleFlags2 = {}));
19743 /**
19744 * Extend this base class to implement custom rendering. By default, Angular
19745 * renders a template into DOM. You can use custom rendering to intercept
19746 * rendering calls, or to render to something other than DOM.
19747 *
19748 * Create your custom renderer using `RendererFactory2`.
19749 *
19750 * Use a custom renderer to bypass Angular's templating and
19751 * make custom UI changes that can't be expressed declaratively.
19752 * For example if you need to set a property or an attribute whose name is
19753 * not statically known, use the `setProperty()` or
19754 * `setAttribute()` method.
19755 *
19756 * @publicApi
19757 */
19758 var Renderer2 = /** @class */ (function () {
19759 function Renderer2() {
19760 }
19761 return Renderer2;
19762 }());
19763 /**
19764 * @internal
19765 * @nocollapse
19766 */
19767 Renderer2.__NG_ELEMENT_ID__ = function () { return SWITCH_RENDERER2_FACTORY(); };
19768 var SWITCH_RENDERER2_FACTORY__POST_R3__ = injectRenderer2;
19769 var SWITCH_RENDERER2_FACTORY__PRE_R3__ = noop;
19770 var SWITCH_RENDERER2_FACTORY = SWITCH_RENDERER2_FACTORY__PRE_R3__;
19771
19772 /**
19773 * @license
19774 * Copyright Google LLC All Rights Reserved.
19775 *
19776 * Use of this source code is governed by an MIT-style license that can be
19777 * found in the LICENSE file at https://angular.io/license
19778 */
19779 /**
19780 * Sanitizer is used by the views to sanitize potentially dangerous values.
19781 *
19782 * @publicApi
19783 */
19784 var Sanitizer = /** @class */ (function () {
19785 function Sanitizer() {
19786 }
19787 return Sanitizer;
19788 }());
19789 /** @nocollapse */
19790 Sanitizer.ɵprov = ɵɵdefineInjectable({
19791 token: Sanitizer,
19792 providedIn: 'root',
19793 factory: function () { return null; },
19794 });
19795
19796 /**
19797 * @license
19798 * Copyright Google LLC All Rights Reserved.
19799 *
19800 * Use of this source code is governed by an MIT-style license that can be
19801 * found in the LICENSE file at https://angular.io/license
19802 */
19803 /**
19804 * @description Represents the version of Angular
19805 *
19806 * @publicApi
19807 */
19808 var Version = /** @class */ (function () {
19809 function Version(full) {
19810 this.full = full;
19811 this.major = full.split('.')[0];
19812 this.minor = full.split('.')[1];
19813 this.patch = full.split('.').slice(2).join('.');
19814 }
19815 return Version;
19816 }());
19817 /**
19818 * @publicApi
19819 */
19820 var VERSION = new Version('10.0.10');
19821
19822 /**
19823 * @license
19824 * Copyright Google LLC All Rights Reserved.
19825 *
19826 * Use of this source code is governed by an MIT-style license that can be
19827 * found in the LICENSE file at https://angular.io/license
19828 */
19829 var DefaultIterableDifferFactory = /** @class */ (function () {
19830 function DefaultIterableDifferFactory() {
19831 }
19832 DefaultIterableDifferFactory.prototype.supports = function (obj) {
19833 return isListLikeIterable(obj);
19834 };
19835 DefaultIterableDifferFactory.prototype.create = function (trackByFn) {
19836 return new DefaultIterableDiffer(trackByFn);
19837 };
19838 return DefaultIterableDifferFactory;
19839 }());
19840 var trackByIdentity = function (index, item) { return item; };
19841 var ɵ0$c = trackByIdentity;
19842 /**
19843 * @deprecated v4.0.0 - Should not be part of public API.
19844 * @publicApi
19845 */
19846 var DefaultIterableDiffer = /** @class */ (function () {
19847 function DefaultIterableDiffer(trackByFn) {
19848 this.length = 0;
19849 // Keeps track of the used records at any point in time (during & across `_check()` calls)
19850 this._linkedRecords = null;
19851 // Keeps track of the removed records at any point in time during `_check()` calls.
19852 this._unlinkedRecords = null;
19853 this._previousItHead = null;
19854 this._itHead = null;
19855 this._itTail = null;
19856 this._additionsHead = null;
19857 this._additionsTail = null;
19858 this._movesHead = null;
19859 this._movesTail = null;
19860 this._removalsHead = null;
19861 this._removalsTail = null;
19862 // Keeps track of records where custom track by is the same, but item identity has changed
19863 this._identityChangesHead = null;
19864 this._identityChangesTail = null;
19865 this._trackByFn = trackByFn || trackByIdentity;
19866 }
19867 DefaultIterableDiffer.prototype.forEachItem = function (fn) {
19868 var record;
19869 for (record = this._itHead; record !== null; record = record._next) {
19870 fn(record);
19871 }
19872 };
19873 DefaultIterableDiffer.prototype.forEachOperation = function (fn) {
19874 var nextIt = this._itHead;
19875 var nextRemove = this._removalsHead;
19876 var addRemoveOffset = 0;
19877 var moveOffsets = null;
19878 while (nextIt || nextRemove) {
19879 // Figure out which is the next record to process
19880 // Order: remove, add, move
19881 var record = !nextRemove ||
19882 nextIt &&
19883 nextIt.currentIndex <
19884 getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ?
19885 nextIt :
19886 nextRemove;
19887 var adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets);
19888 var currentIndex = record.currentIndex;
19889 // consume the item, and adjust the addRemoveOffset and update moveDistance if necessary
19890 if (record === nextRemove) {
19891 addRemoveOffset--;
19892 nextRemove = nextRemove._nextRemoved;
19893 }
19894 else {
19895 nextIt = nextIt._next;
19896 if (record.previousIndex == null) {
19897 addRemoveOffset++;
19898 }
19899 else {
19900 // INVARIANT: currentIndex < previousIndex
19901 if (!moveOffsets)
19902 moveOffsets = [];
19903 var localMovePreviousIndex = adjPreviousIndex - addRemoveOffset;
19904 var localCurrentIndex = currentIndex - addRemoveOffset;
19905 if (localMovePreviousIndex != localCurrentIndex) {
19906 for (var i = 0; i < localMovePreviousIndex; i++) {
19907 var offset = i < moveOffsets.length ? moveOffsets[i] : (moveOffsets[i] = 0);
19908 var index = offset + i;
19909 if (localCurrentIndex <= index && index < localMovePreviousIndex) {
19910 moveOffsets[i] = offset + 1;
19911 }
19912 }
19913 var previousIndex = record.previousIndex;
19914 moveOffsets[previousIndex] = localCurrentIndex - localMovePreviousIndex;
19915 }
19916 }
19917 }
19918 if (adjPreviousIndex !== currentIndex) {
19919 fn(record, adjPreviousIndex, currentIndex);
19920 }
19921 }
19922 };
19923 DefaultIterableDiffer.prototype.forEachPreviousItem = function (fn) {
19924 var record;
19925 for (record = this._previousItHead; record !== null; record = record._nextPrevious) {
19926 fn(record);
19927 }
19928 };
19929 DefaultIterableDiffer.prototype.forEachAddedItem = function (fn) {
19930 var record;
19931 for (record = this._additionsHead; record !== null; record = record._nextAdded) {
19932 fn(record);
19933 }
19934 };
19935 DefaultIterableDiffer.prototype.forEachMovedItem = function (fn) {
19936 var record;
19937 for (record = this._movesHead; record !== null; record = record._nextMoved) {
19938 fn(record);
19939 }
19940 };
19941 DefaultIterableDiffer.prototype.forEachRemovedItem = function (fn) {
19942 var record;
19943 for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
19944 fn(record);
19945 }
19946 };
19947 DefaultIterableDiffer.prototype.forEachIdentityChange = function (fn) {
19948 var record;
19949 for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) {
19950 fn(record);
19951 }
19952 };
19953 DefaultIterableDiffer.prototype.diff = function (collection) {
19954 if (collection == null)
19955 collection = [];
19956 if (!isListLikeIterable(collection)) {
19957 throw new Error("Error trying to diff '" + stringify(collection) + "'. Only arrays and iterables are allowed");
19958 }
19959 if (this.check(collection)) {
19960 return this;
19961 }
19962 else {
19963 return null;
19964 }
19965 };
19966 DefaultIterableDiffer.prototype.onDestroy = function () { };
19967 DefaultIterableDiffer.prototype.check = function (collection) {
19968 var _this = this;
19969 this._reset();
19970 var record = this._itHead;
19971 var mayBeDirty = false;
19972 var index;
19973 var item;
19974 var itemTrackBy;
19975 if (Array.isArray(collection)) {
19976 this.length = collection.length;
19977 for (var index_1 = 0; index_1 < this.length; index_1++) {
19978 item = collection[index_1];
19979 itemTrackBy = this._trackByFn(index_1, item);
19980 if (record === null || !Object.is(record.trackById, itemTrackBy)) {
19981 record = this._mismatch(record, item, itemTrackBy, index_1);
19982 mayBeDirty = true;
19983 }
19984 else {
19985 if (mayBeDirty) {
19986 // TODO(misko): can we limit this to duplicates only?
19987 record = this._verifyReinsertion(record, item, itemTrackBy, index_1);
19988 }
19989 if (!Object.is(record.item, item))
19990 this._addIdentityChange(record, item);
19991 }
19992 record = record._next;
19993 }
19994 }
19995 else {
19996 index = 0;
19997 iterateListLike(collection, function (item) {
19998 itemTrackBy = _this._trackByFn(index, item);
19999 if (record === null || !Object.is(record.trackById, itemTrackBy)) {
20000 record = _this._mismatch(record, item, itemTrackBy, index);
20001 mayBeDirty = true;
20002 }
20003 else {
20004 if (mayBeDirty) {
20005 // TODO(misko): can we limit this to duplicates only?
20006 record = _this._verifyReinsertion(record, item, itemTrackBy, index);
20007 }
20008 if (!Object.is(record.item, item))
20009 _this._addIdentityChange(record, item);
20010 }
20011 record = record._next;
20012 index++;
20013 });
20014 this.length = index;
20015 }
20016 this._truncate(record);
20017 this.collection = collection;
20018 return this.isDirty;
20019 };
20020 Object.defineProperty(DefaultIterableDiffer.prototype, "isDirty", {
20021 /* CollectionChanges is considered dirty if it has any additions, moves, removals, or identity
20022 * changes.
20023 */
20024 get: function () {
20025 return this._additionsHead !== null || this._movesHead !== null ||
20026 this._removalsHead !== null || this._identityChangesHead !== null;
20027 },
20028 enumerable: false,
20029 configurable: true
20030 });
20031 /**
20032 * Reset the state of the change objects to show no changes. This means set previousKey to
20033 * currentKey, and clear all of the queues (additions, moves, removals).
20034 * Set the previousIndexes of moved and added items to their currentIndexes
20035 * Reset the list of additions, moves and removals
20036 *
20037 * @internal
20038 */
20039 DefaultIterableDiffer.prototype._reset = function () {
20040 if (this.isDirty) {
20041 var record = void 0;
20042 var nextRecord = void 0;
20043 for (record = this._previousItHead = this._itHead; record !== null; record = record._next) {
20044 record._nextPrevious = record._next;
20045 }
20046 for (record = this._additionsHead; record !== null; record = record._nextAdded) {
20047 record.previousIndex = record.currentIndex;
20048 }
20049 this._additionsHead = this._additionsTail = null;
20050 for (record = this._movesHead; record !== null; record = nextRecord) {
20051 record.previousIndex = record.currentIndex;
20052 nextRecord = record._nextMoved;
20053 }
20054 this._movesHead = this._movesTail = null;
20055 this._removalsHead = this._removalsTail = null;
20056 this._identityChangesHead = this._identityChangesTail = null;
20057 // TODO(vicb): when assert gets supported
20058 // assert(!this.isDirty);
20059 }
20060 };
20061 /**
20062 * This is the core function which handles differences between collections.
20063 *
20064 * - `record` is the record which we saw at this position last time. If null then it is a new
20065 * item.
20066 * - `item` is the current item in the collection
20067 * - `index` is the position of the item in the collection
20068 *
20069 * @internal
20070 */
20071 DefaultIterableDiffer.prototype._mismatch = function (record, item, itemTrackBy, index) {
20072 // The previous record after which we will append the current one.
20073 var previousRecord;
20074 if (record === null) {
20075 previousRecord = this._itTail;
20076 }
20077 else {
20078 previousRecord = record._prev;
20079 // Remove the record from the collection since we know it does not match the item.
20080 this._remove(record);
20081 }
20082 // Attempt to see if we have seen the item before.
20083 record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
20084 if (record !== null) {
20085 // We have seen this before, we need to move it forward in the collection.
20086 // But first we need to check if identity changed, so we can update in view if necessary
20087 if (!Object.is(record.item, item))
20088 this._addIdentityChange(record, item);
20089 this._moveAfter(record, previousRecord, index);
20090 }
20091 else {
20092 // Never seen it, check evicted list.
20093 record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
20094 if (record !== null) {
20095 // It is an item which we have evicted earlier: reinsert it back into the list.
20096 // But first we need to check if identity changed, so we can update in view if necessary
20097 if (!Object.is(record.item, item))
20098 this._addIdentityChange(record, item);
20099 this._reinsertAfter(record, previousRecord, index);
20100 }
20101 else {
20102 // It is a new item: add it.
20103 record =
20104 this._addAfter(new IterableChangeRecord_(item, itemTrackBy), previousRecord, index);
20105 }
20106 }
20107 return record;
20108 };
20109 /**
20110 * This check is only needed if an array contains duplicates. (Short circuit of nothing dirty)
20111 *
20112 * Use case: `[a, a]` => `[b, a, a]`
20113 *
20114 * If we did not have this check then the insertion of `b` would:
20115 * 1) evict first `a`
20116 * 2) insert `b` at `0` index.
20117 * 3) leave `a` at index `1` as is. <-- this is wrong!
20118 * 3) reinsert `a` at index 2. <-- this is wrong!
20119 *
20120 * The correct behavior is:
20121 * 1) evict first `a`
20122 * 2) insert `b` at `0` index.
20123 * 3) reinsert `a` at index 1.
20124 * 3) move `a` at from `1` to `2`.
20125 *
20126 *
20127 * Double check that we have not evicted a duplicate item. We need to check if the item type may
20128 * have already been removed:
20129 * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
20130 * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
20131 * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
20132 * at the end.
20133 *
20134 * @internal
20135 */
20136 DefaultIterableDiffer.prototype._verifyReinsertion = function (record, item, itemTrackBy, index) {
20137 var reinsertRecord = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
20138 if (reinsertRecord !== null) {
20139 record = this._reinsertAfter(reinsertRecord, record._prev, index);
20140 }
20141 else if (record.currentIndex != index) {
20142 record.currentIndex = index;
20143 this._addToMoves(record, index);
20144 }
20145 return record;
20146 };
20147 /**
20148 * Get rid of any excess {@link IterableChangeRecord_}s from the previous collection
20149 *
20150 * - `record` The first excess {@link IterableChangeRecord_}.
20151 *
20152 * @internal
20153 */
20154 DefaultIterableDiffer.prototype._truncate = function (record) {
20155 // Anything after that needs to be removed;
20156 while (record !== null) {
20157 var nextRecord = record._next;
20158 this._addToRemovals(this._unlink(record));
20159 record = nextRecord;
20160 }
20161 if (this._unlinkedRecords !== null) {
20162 this._unlinkedRecords.clear();
20163 }
20164 if (this._additionsTail !== null) {
20165 this._additionsTail._nextAdded = null;
20166 }
20167 if (this._movesTail !== null) {
20168 this._movesTail._nextMoved = null;
20169 }
20170 if (this._itTail !== null) {
20171 this._itTail._next = null;
20172 }
20173 if (this._removalsTail !== null) {
20174 this._removalsTail._nextRemoved = null;
20175 }
20176 if (this._identityChangesTail !== null) {
20177 this._identityChangesTail._nextIdentityChange = null;
20178 }
20179 };
20180 /** @internal */
20181 DefaultIterableDiffer.prototype._reinsertAfter = function (record, prevRecord, index) {
20182 if (this._unlinkedRecords !== null) {
20183 this._unlinkedRecords.remove(record);
20184 }
20185 var prev = record._prevRemoved;
20186 var next = record._nextRemoved;
20187 if (prev === null) {
20188 this._removalsHead = next;
20189 }
20190 else {
20191 prev._nextRemoved = next;
20192 }
20193 if (next === null) {
20194 this._removalsTail = prev;
20195 }
20196 else {
20197 next._prevRemoved = prev;
20198 }
20199 this._insertAfter(record, prevRecord, index);
20200 this._addToMoves(record, index);
20201 return record;
20202 };
20203 /** @internal */
20204 DefaultIterableDiffer.prototype._moveAfter = function (record, prevRecord, index) {
20205 this._unlink(record);
20206 this._insertAfter(record, prevRecord, index);
20207 this._addToMoves(record, index);
20208 return record;
20209 };
20210 /** @internal */
20211 DefaultIterableDiffer.prototype._addAfter = function (record, prevRecord, index) {
20212 this._insertAfter(record, prevRecord, index);
20213 if (this._additionsTail === null) {
20214 // TODO(vicb):
20215 // assert(this._additionsHead === null);
20216 this._additionsTail = this._additionsHead = record;
20217 }
20218 else {
20219 // TODO(vicb):
20220 // assert(_additionsTail._nextAdded === null);
20221 // assert(record._nextAdded === null);
20222 this._additionsTail = this._additionsTail._nextAdded = record;
20223 }
20224 return record;
20225 };
20226 /** @internal */
20227 DefaultIterableDiffer.prototype._insertAfter = function (record, prevRecord, index) {
20228 // TODO(vicb):
20229 // assert(record != prevRecord);
20230 // assert(record._next === null);
20231 // assert(record._prev === null);
20232 var next = prevRecord === null ? this._itHead : prevRecord._next;
20233 // TODO(vicb):
20234 // assert(next != record);
20235 // assert(prevRecord != record);
20236 record._next = next;
20237 record._prev = prevRecord;
20238 if (next === null) {
20239 this._itTail = record;
20240 }
20241 else {
20242 next._prev = record;
20243 }
20244 if (prevRecord === null) {
20245 this._itHead = record;
20246 }
20247 else {
20248 prevRecord._next = record;
20249 }
20250 if (this._linkedRecords === null) {
20251 this._linkedRecords = new _DuplicateMap();
20252 }
20253 this._linkedRecords.put(record);
20254 record.currentIndex = index;
20255 return record;
20256 };
20257 /** @internal */
20258 DefaultIterableDiffer.prototype._remove = function (record) {
20259 return this._addToRemovals(this._unlink(record));
20260 };
20261 /** @internal */
20262 DefaultIterableDiffer.prototype._unlink = function (record) {
20263 if (this._linkedRecords !== null) {
20264 this._linkedRecords.remove(record);
20265 }
20266 var prev = record._prev;
20267 var next = record._next;
20268 // TODO(vicb):
20269 // assert((record._prev = null) === null);
20270 // assert((record._next = null) === null);
20271 if (prev === null) {
20272 this._itHead = next;
20273 }
20274 else {
20275 prev._next = next;
20276 }
20277 if (next === null) {
20278 this._itTail = prev;
20279 }
20280 else {
20281 next._prev = prev;
20282 }
20283 return record;
20284 };
20285 /** @internal */
20286 DefaultIterableDiffer.prototype._addToMoves = function (record, toIndex) {
20287 // TODO(vicb):
20288 // assert(record._nextMoved === null);
20289 if (record.previousIndex === toIndex) {
20290 return record;
20291 }
20292 if (this._movesTail === null) {
20293 // TODO(vicb):
20294 // assert(_movesHead === null);
20295 this._movesTail = this._movesHead = record;
20296 }
20297 else {
20298 // TODO(vicb):
20299 // assert(_movesTail._nextMoved === null);
20300 this._movesTail = this._movesTail._nextMoved = record;
20301 }
20302 return record;
20303 };
20304 DefaultIterableDiffer.prototype._addToRemovals = function (record) {
20305 if (this._unlinkedRecords === null) {
20306 this._unlinkedRecords = new _DuplicateMap();
20307 }
20308 this._unlinkedRecords.put(record);
20309 record.currentIndex = null;
20310 record._nextRemoved = null;
20311 if (this._removalsTail === null) {
20312 // TODO(vicb):
20313 // assert(_removalsHead === null);
20314 this._removalsTail = this._removalsHead = record;
20315 record._prevRemoved = null;
20316 }
20317 else {
20318 // TODO(vicb):
20319 // assert(_removalsTail._nextRemoved === null);
20320 // assert(record._nextRemoved === null);
20321 record._prevRemoved = this._removalsTail;
20322 this._removalsTail = this._removalsTail._nextRemoved = record;
20323 }
20324 return record;
20325 };
20326 /** @internal */
20327 DefaultIterableDiffer.prototype._addIdentityChange = function (record, item) {
20328 record.item = item;
20329 if (this._identityChangesTail === null) {
20330 this._identityChangesTail = this._identityChangesHead = record;
20331 }
20332 else {
20333 this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record;
20334 }
20335 return record;
20336 };
20337 return DefaultIterableDiffer;
20338 }());
20339 var IterableChangeRecord_ = /** @class */ (function () {
20340 function IterableChangeRecord_(item, trackById) {
20341 this.item = item;
20342 this.trackById = trackById;
20343 this.currentIndex = null;
20344 this.previousIndex = null;
20345 /** @internal */
20346 this._nextPrevious = null;
20347 /** @internal */
20348 this._prev = null;
20349 /** @internal */
20350 this._next = null;
20351 /** @internal */
20352 this._prevDup = null;
20353 /** @internal */
20354 this._nextDup = null;
20355 /** @internal */
20356 this._prevRemoved = null;
20357 /** @internal */
20358 this._nextRemoved = null;
20359 /** @internal */
20360 this._nextAdded = null;
20361 /** @internal */
20362 this._nextMoved = null;
20363 /** @internal */
20364 this._nextIdentityChange = null;
20365 }
20366 return IterableChangeRecord_;
20367 }());
20368 // A linked list of CollectionChangeRecords with the same IterableChangeRecord_.item
20369 var _DuplicateItemRecordList = /** @class */ (function () {
20370 function _DuplicateItemRecordList() {
20371 /** @internal */
20372 this._head = null;
20373 /** @internal */
20374 this._tail = null;
20375 }
20376 /**
20377 * Append the record to the list of duplicates.
20378 *
20379 * Note: by design all records in the list of duplicates hold the same value in record.item.
20380 */
20381 _DuplicateItemRecordList.prototype.add = function (record) {
20382 if (this._head === null) {
20383 this._head = this._tail = record;
20384 record._nextDup = null;
20385 record._prevDup = null;
20386 }
20387 else {
20388 // TODO(vicb):
20389 // assert(record.item == _head.item ||
20390 // record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
20391 this._tail._nextDup = record;
20392 record._prevDup = this._tail;
20393 record._nextDup = null;
20394 this._tail = record;
20395 }
20396 };
20397 // Returns a IterableChangeRecord_ having IterableChangeRecord_.trackById == trackById and
20398 // IterableChangeRecord_.currentIndex >= atOrAfterIndex
20399 _DuplicateItemRecordList.prototype.get = function (trackById, atOrAfterIndex) {
20400 var record;
20401 for (record = this._head; record !== null; record = record._nextDup) {
20402 if ((atOrAfterIndex === null || atOrAfterIndex <= record.currentIndex) &&
20403 Object.is(record.trackById, trackById)) {
20404 return record;
20405 }
20406 }
20407 return null;
20408 };
20409 /**
20410 * Remove one {@link IterableChangeRecord_} from the list of duplicates.
20411 *
20412 * Returns whether the list of duplicates is empty.
20413 */
20414 _DuplicateItemRecordList.prototype.remove = function (record) {
20415 // TODO(vicb):
20416 // assert(() {
20417 // // verify that the record being removed is in the list.
20418 // for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) {
20419 // if (identical(cursor, record)) return true;
20420 // }
20421 // return false;
20422 //});
20423 var prev = record._prevDup;
20424 var next = record._nextDup;
20425 if (prev === null) {
20426 this._head = next;
20427 }
20428 else {
20429 prev._nextDup = next;
20430 }
20431 if (next === null) {
20432 this._tail = prev;
20433 }
20434 else {
20435 next._prevDup = prev;
20436 }
20437 return this._head === null;
20438 };
20439 return _DuplicateItemRecordList;
20440 }());
20441 var _DuplicateMap = /** @class */ (function () {
20442 function _DuplicateMap() {
20443 this.map = new Map();
20444 }
20445 _DuplicateMap.prototype.put = function (record) {
20446 var key = record.trackById;
20447 var duplicates = this.map.get(key);
20448 if (!duplicates) {
20449 duplicates = new _DuplicateItemRecordList();
20450 this.map.set(key, duplicates);
20451 }
20452 duplicates.add(record);
20453 };
20454 /**
20455 * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
20456 * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
20457 *
20458 * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
20459 * have any more `a`s needs to return the second `a`.
20460 */
20461 _DuplicateMap.prototype.get = function (trackById, atOrAfterIndex) {
20462 var key = trackById;
20463 var recordList = this.map.get(key);
20464 return recordList ? recordList.get(trackById, atOrAfterIndex) : null;
20465 };
20466 /**
20467 * Removes a {@link IterableChangeRecord_} from the list of duplicates.
20468 *
20469 * The list of duplicates also is removed from the map if it gets empty.
20470 */
20471 _DuplicateMap.prototype.remove = function (record) {
20472 var key = record.trackById;
20473 var recordList = this.map.get(key);
20474 // Remove the list of duplicates when it gets empty
20475 if (recordList.remove(record)) {
20476 this.map.delete(key);
20477 }
20478 return record;
20479 };
20480 Object.defineProperty(_DuplicateMap.prototype, "isEmpty", {
20481 get: function () {
20482 return this.map.size === 0;
20483 },
20484 enumerable: false,
20485 configurable: true
20486 });
20487 _DuplicateMap.prototype.clear = function () {
20488 this.map.clear();
20489 };
20490 return _DuplicateMap;
20491 }());
20492 function getPreviousIndex(item, addRemoveOffset, moveOffsets) {
20493 var previousIndex = item.previousIndex;
20494 if (previousIndex === null)
20495 return previousIndex;
20496 var moveOffset = 0;
20497 if (moveOffsets && previousIndex < moveOffsets.length) {
20498 moveOffset = moveOffsets[previousIndex];
20499 }
20500 return previousIndex + addRemoveOffset + moveOffset;
20501 }
20502
20503 /**
20504 * @license
20505 * Copyright Google LLC All Rights Reserved.
20506 *
20507 * Use of this source code is governed by an MIT-style license that can be
20508 * found in the LICENSE file at https://angular.io/license
20509 */
20510 var DefaultKeyValueDifferFactory = /** @class */ (function () {
20511 function DefaultKeyValueDifferFactory() {
20512 }
20513 DefaultKeyValueDifferFactory.prototype.supports = function (obj) {
20514 return obj instanceof Map || isJsObject(obj);
20515 };
20516 DefaultKeyValueDifferFactory.prototype.create = function () {
20517 return new DefaultKeyValueDiffer();
20518 };
20519 return DefaultKeyValueDifferFactory;
20520 }());
20521 var DefaultKeyValueDiffer = /** @class */ (function () {
20522 function DefaultKeyValueDiffer() {
20523 this._records = new Map();
20524 this._mapHead = null;
20525 // _appendAfter is used in the check loop
20526 this._appendAfter = null;
20527 this._previousMapHead = null;
20528 this._changesHead = null;
20529 this._changesTail = null;
20530 this._additionsHead = null;
20531 this._additionsTail = null;
20532 this._removalsHead = null;
20533 this._removalsTail = null;
20534 }
20535 Object.defineProperty(DefaultKeyValueDiffer.prototype, "isDirty", {
20536 get: function () {
20537 return this._additionsHead !== null || this._changesHead !== null ||
20538 this._removalsHead !== null;
20539 },
20540 enumerable: false,
20541 configurable: true
20542 });
20543 DefaultKeyValueDiffer.prototype.forEachItem = function (fn) {
20544 var record;
20545 for (record = this._mapHead; record !== null; record = record._next) {
20546 fn(record);
20547 }
20548 };
20549 DefaultKeyValueDiffer.prototype.forEachPreviousItem = function (fn) {
20550 var record;
20551 for (record = this._previousMapHead; record !== null; record = record._nextPrevious) {
20552 fn(record);
20553 }
20554 };
20555 DefaultKeyValueDiffer.prototype.forEachChangedItem = function (fn) {
20556 var record;
20557 for (record = this._changesHead; record !== null; record = record._nextChanged) {
20558 fn(record);
20559 }
20560 };
20561 DefaultKeyValueDiffer.prototype.forEachAddedItem = function (fn) {
20562 var record;
20563 for (record = this._additionsHead; record !== null; record = record._nextAdded) {
20564 fn(record);
20565 }
20566 };
20567 DefaultKeyValueDiffer.prototype.forEachRemovedItem = function (fn) {
20568 var record;
20569 for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
20570 fn(record);
20571 }
20572 };
20573 DefaultKeyValueDiffer.prototype.diff = function (map) {
20574 if (!map) {
20575 map = new Map();
20576 }
20577 else if (!(map instanceof Map || isJsObject(map))) {
20578 throw new Error("Error trying to diff '" + stringify(map) + "'. Only maps and objects are allowed");
20579 }
20580 return this.check(map) ? this : null;
20581 };
20582 DefaultKeyValueDiffer.prototype.onDestroy = function () { };
20583 /**
20584 * Check the current state of the map vs the previous.
20585 * The algorithm is optimised for when the keys do no change.
20586 */
20587 DefaultKeyValueDiffer.prototype.check = function (map) {
20588 var _this = this;
20589 this._reset();
20590 var insertBefore = this._mapHead;
20591 this._appendAfter = null;
20592 this._forEach(map, function (value, key) {
20593 if (insertBefore && insertBefore.key === key) {
20594 _this._maybeAddToChanges(insertBefore, value);
20595 _this._appendAfter = insertBefore;
20596 insertBefore = insertBefore._next;
20597 }
20598 else {
20599 var record = _this._getOrCreateRecordForKey(key, value);
20600 insertBefore = _this._insertBeforeOrAppend(insertBefore, record);
20601 }
20602 });
20603 // Items remaining at the end of the list have been deleted
20604 if (insertBefore) {
20605 if (insertBefore._prev) {
20606 insertBefore._prev._next = null;
20607 }
20608 this._removalsHead = insertBefore;
20609 for (var record = insertBefore; record !== null; record = record._nextRemoved) {
20610 if (record === this._mapHead) {
20611 this._mapHead = null;
20612 }
20613 this._records.delete(record.key);
20614 record._nextRemoved = record._next;
20615 record.previousValue = record.currentValue;
20616 record.currentValue = null;
20617 record._prev = null;
20618 record._next = null;
20619 }
20620 }
20621 // Make sure tails have no next records from previous runs
20622 if (this._changesTail)
20623 this._changesTail._nextChanged = null;
20624 if (this._additionsTail)
20625 this._additionsTail._nextAdded = null;
20626 return this.isDirty;
20627 };
20628 /**
20629 * Inserts a record before `before` or append at the end of the list when `before` is null.
20630 *
20631 * Notes:
20632 * - This method appends at `this._appendAfter`,
20633 * - This method updates `this._appendAfter`,
20634 * - The return value is the new value for the insertion pointer.
20635 */
20636 DefaultKeyValueDiffer.prototype._insertBeforeOrAppend = function (before, record) {
20637 if (before) {
20638 var prev = before._prev;
20639 record._next = before;
20640 record._prev = prev;
20641 before._prev = record;
20642 if (prev) {
20643 prev._next = record;
20644 }
20645 if (before === this._mapHead) {
20646 this._mapHead = record;
20647 }
20648 this._appendAfter = before;
20649 return before;
20650 }
20651 if (this._appendAfter) {
20652 this._appendAfter._next = record;
20653 record._prev = this._appendAfter;
20654 }
20655 else {
20656 this._mapHead = record;
20657 }
20658 this._appendAfter = record;
20659 return null;
20660 };
20661 DefaultKeyValueDiffer.prototype._getOrCreateRecordForKey = function (key, value) {
20662 if (this._records.has(key)) {
20663 var record_1 = this._records.get(key);
20664 this._maybeAddToChanges(record_1, value);
20665 var prev = record_1._prev;
20666 var next = record_1._next;
20667 if (prev) {
20668 prev._next = next;
20669 }
20670 if (next) {
20671 next._prev = prev;
20672 }
20673 record_1._next = null;
20674 record_1._prev = null;
20675 return record_1;
20676 }
20677 var record = new KeyValueChangeRecord_(key);
20678 this._records.set(key, record);
20679 record.currentValue = value;
20680 this._addToAdditions(record);
20681 return record;
20682 };
20683 /** @internal */
20684 DefaultKeyValueDiffer.prototype._reset = function () {
20685 if (this.isDirty) {
20686 var record = void 0;
20687 // let `_previousMapHead` contain the state of the map before the changes
20688 this._previousMapHead = this._mapHead;
20689 for (record = this._previousMapHead; record !== null; record = record._next) {
20690 record._nextPrevious = record._next;
20691 }
20692 // Update `record.previousValue` with the value of the item before the changes
20693 // We need to update all changed items (that's those which have been added and changed)
20694 for (record = this._changesHead; record !== null; record = record._nextChanged) {
20695 record.previousValue = record.currentValue;
20696 }
20697 for (record = this._additionsHead; record != null; record = record._nextAdded) {
20698 record.previousValue = record.currentValue;
20699 }
20700 this._changesHead = this._changesTail = null;
20701 this._additionsHead = this._additionsTail = null;
20702 this._removalsHead = null;
20703 }
20704 };
20705 // Add the record or a given key to the list of changes only when the value has actually changed
20706 DefaultKeyValueDiffer.prototype._maybeAddToChanges = function (record, newValue) {
20707 if (!Object.is(newValue, record.currentValue)) {
20708 record.previousValue = record.currentValue;
20709 record.currentValue = newValue;
20710 this._addToChanges(record);
20711 }
20712 };
20713 DefaultKeyValueDiffer.prototype._addToAdditions = function (record) {
20714 if (this._additionsHead === null) {
20715 this._additionsHead = this._additionsTail = record;
20716 }
20717 else {
20718 this._additionsTail._nextAdded = record;
20719 this._additionsTail = record;
20720 }
20721 };
20722 DefaultKeyValueDiffer.prototype._addToChanges = function (record) {
20723 if (this._changesHead === null) {
20724 this._changesHead = this._changesTail = record;
20725 }
20726 else {
20727 this._changesTail._nextChanged = record;
20728 this._changesTail = record;
20729 }
20730 };
20731 /** @internal */
20732 DefaultKeyValueDiffer.prototype._forEach = function (obj, fn) {
20733 if (obj instanceof Map) {
20734 obj.forEach(fn);
20735 }
20736 else {
20737 Object.keys(obj).forEach(function (k) { return fn(obj[k], k); });
20738 }
20739 };
20740 return DefaultKeyValueDiffer;
20741 }());
20742 var KeyValueChangeRecord_ = /** @class */ (function () {
20743 function KeyValueChangeRecord_(key) {
20744 this.key = key;
20745 this.previousValue = null;
20746 this.currentValue = null;
20747 /** @internal */
20748 this._nextPrevious = null;
20749 /** @internal */
20750 this._next = null;
20751 /** @internal */
20752 this._prev = null;
20753 /** @internal */
20754 this._nextAdded = null;
20755 /** @internal */
20756 this._nextRemoved = null;
20757 /** @internal */
20758 this._nextChanged = null;
20759 }
20760 return KeyValueChangeRecord_;
20761 }());
20762
20763 /**
20764 * @license
20765 * Copyright Google LLC All Rights Reserved.
20766 *
20767 * Use of this source code is governed by an MIT-style license that can be
20768 * found in the LICENSE file at https://angular.io/license
20769 */
20770 /**
20771 * A repository of different iterable diffing strategies used by NgFor, NgClass, and others.
20772 *
20773 * @publicApi
20774 */
20775 var IterableDiffers = /** @class */ (function () {
20776 function IterableDiffers(factories) {
20777 this.factories = factories;
20778 }
20779 IterableDiffers.create = function (factories, parent) {
20780 if (parent != null) {
20781 var copied = parent.factories.slice();
20782 factories = factories.concat(copied);
20783 }
20784 return new IterableDiffers(factories);
20785 };
20786 /**
20787 * Takes an array of {@link IterableDifferFactory} and returns a provider used to extend the
20788 * inherited {@link IterableDiffers} instance with the provided factories and return a new
20789 * {@link IterableDiffers} instance.
20790 *
20791 * @usageNotes
20792 * ### Example
20793 *
20794 * The following example shows how to extend an existing list of factories,
20795 * which will only be applied to the injector for this component and its children.
20796 * This step is all that's required to make a new {@link IterableDiffer} available.
20797 *
20798 * ```
20799 * @Component({
20800 * viewProviders: [
20801 * IterableDiffers.extend([new ImmutableListDiffer()])
20802 * ]
20803 * })
20804 * ```
20805 */
20806 IterableDiffers.extend = function (factories) {
20807 return {
20808 provide: IterableDiffers,
20809 useFactory: function (parent) {
20810 if (!parent) {
20811 // Typically would occur when calling IterableDiffers.extend inside of dependencies passed
20812 // to
20813 // bootstrap(), which would override default pipes instead of extending them.
20814 throw new Error('Cannot extend IterableDiffers without a parent injector');
20815 }
20816 return IterableDiffers.create(factories, parent);
20817 },
20818 // Dependency technically isn't optional, but we can provide a better error message this way.
20819 deps: [[IterableDiffers, new SkipSelf(), new Optional()]]
20820 };
20821 };
20822 IterableDiffers.prototype.find = function (iterable) {
20823 var factory = this.factories.find(function (f) { return f.supports(iterable); });
20824 if (factory != null) {
20825 return factory;
20826 }
20827 else {
20828 throw new Error("Cannot find a differ supporting object '" + iterable + "' of type '" + getTypeNameForDebugging(iterable) + "'");
20829 }
20830 };
20831 return IterableDiffers;
20832 }());
20833 /** @nocollapse */
20834 IterableDiffers.ɵprov = ɵɵdefineInjectable({
20835 token: IterableDiffers,
20836 providedIn: 'root',
20837 factory: function () { return new IterableDiffers([new DefaultIterableDifferFactory()]); }
20838 });
20839 function getTypeNameForDebugging(type) {
20840 return type['name'] || typeof type;
20841 }
20842
20843 /**
20844 * @license
20845 * Copyright Google LLC All Rights Reserved.
20846 *
20847 * Use of this source code is governed by an MIT-style license that can be
20848 * found in the LICENSE file at https://angular.io/license
20849 */
20850 /**
20851 * A repository of different Map diffing strategies used by NgClass, NgStyle, and others.
20852 *
20853 * @publicApi
20854 */
20855 var KeyValueDiffers = /** @class */ (function () {
20856 function KeyValueDiffers(factories) {
20857 this.factories = factories;
20858 }
20859 KeyValueDiffers.create = function (factories, parent) {
20860 if (parent) {
20861 var copied = parent.factories.slice();
20862 factories = factories.concat(copied);
20863 }
20864 return new KeyValueDiffers(factories);
20865 };
20866 /**
20867 * Takes an array of {@link KeyValueDifferFactory} and returns a provider used to extend the
20868 * inherited {@link KeyValueDiffers} instance with the provided factories and return a new
20869 * {@link KeyValueDiffers} instance.
20870 *
20871 * @usageNotes
20872 * ### Example
20873 *
20874 * The following example shows how to extend an existing list of factories,
20875 * which will only be applied to the injector for this component and its children.
20876 * This step is all that's required to make a new {@link KeyValueDiffer} available.
20877 *
20878 * ```
20879 * @Component({
20880 * viewProviders: [
20881 * KeyValueDiffers.extend([new ImmutableMapDiffer()])
20882 * ]
20883 * })
20884 * ```
20885 */
20886 KeyValueDiffers.extend = function (factories) {
20887 return {
20888 provide: KeyValueDiffers,
20889 useFactory: function (parent) {
20890 if (!parent) {
20891 // Typically would occur when calling KeyValueDiffers.extend inside of dependencies passed
20892 // to bootstrap(), which would override default pipes instead of extending them.
20893 throw new Error('Cannot extend KeyValueDiffers without a parent injector');
20894 }
20895 return KeyValueDiffers.create(factories, parent);
20896 },
20897 // Dependency technically isn't optional, but we can provide a better error message this way.
20898 deps: [[KeyValueDiffers, new SkipSelf(), new Optional()]]
20899 };
20900 };
20901 KeyValueDiffers.prototype.find = function (kv) {
20902 var factory = this.factories.find(function (f) { return f.supports(kv); });
20903 if (factory) {
20904 return factory;
20905 }
20906 throw new Error("Cannot find a differ supporting object '" + kv + "'");
20907 };
20908 return KeyValueDiffers;
20909 }());
20910 /** @nocollapse */
20911 KeyValueDiffers.ɵprov = ɵɵdefineInjectable({
20912 token: KeyValueDiffers,
20913 providedIn: 'root',
20914 factory: function () { return new KeyValueDiffers([new DefaultKeyValueDifferFactory()]); }
20915 });
20916
20917 /**
20918 * @license
20919 * Copyright Google LLC All Rights Reserved.
20920 *
20921 * Use of this source code is governed by an MIT-style license that can be
20922 * found in the LICENSE file at https://angular.io/license
20923 */
20924 /**
20925 * Structural diffing for `Object`s and `Map`s.
20926 */
20927 var keyValDiff = [new DefaultKeyValueDifferFactory()];
20928 /**
20929 * Structural diffing for `Iterable` types such as `Array`s.
20930 */
20931 var iterableDiff = [new DefaultIterableDifferFactory()];
20932 var defaultIterableDiffers = new IterableDiffers(iterableDiff);
20933 var defaultKeyValueDiffers = new KeyValueDiffers(keyValDiff);
20934
20935 /**
20936 * @license
20937 * Copyright Google LLC All Rights Reserved.
20938 *
20939 * Use of this source code is governed by an MIT-style license that can be
20940 * found in the LICENSE file at https://angular.io/license
20941 */
20942 /**
20943 * Represents an embedded template that can be used to instantiate embedded views.
20944 * To instantiate embedded views based on a template, use the `ViewContainerRef`
20945 * method `createEmbeddedView()`.
20946 *
20947 * Access a `TemplateRef` instance by placing a directive on an `<ng-template>`
20948 * element (or directive prefixed with `*`). The `TemplateRef` for the embedded view
20949 * is injected into the constructor of the directive,
20950 * using the `TemplateRef` token.
20951 *
20952 * You can also use a `Query` to find a `TemplateRef` associated with
20953 * a component or a directive.
20954 *
20955 * @see `ViewContainerRef`
20956 * @see [Navigate the Component Tree with DI](guide/dependency-injection-navtree)
20957 *
20958 * @publicApi
20959 */
20960 var TemplateRef = /** @class */ (function () {
20961 function TemplateRef() {
20962 }
20963 return TemplateRef;
20964 }());
20965 /**
20966 * @internal
20967 * @nocollapse
20968 */
20969 TemplateRef.__NG_ELEMENT_ID__ = function () { return SWITCH_TEMPLATE_REF_FACTORY(TemplateRef, ElementRef); };
20970 var SWITCH_TEMPLATE_REF_FACTORY__POST_R3__ = injectTemplateRef;
20971 var SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__ = noop;
20972 var SWITCH_TEMPLATE_REF_FACTORY = SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__;
20973
20974 /**
20975 * @license
20976 * Copyright Google LLC All Rights Reserved.
20977 *
20978 * Use of this source code is governed by an MIT-style license that can be
20979 * found in the LICENSE file at https://angular.io/license
20980 */
20981 /**
20982 * Represents a container where one or more views can be attached to a component.
20983 *
20984 * Can contain *host views* (created by instantiating a
20985 * component with the `createComponent()` method), and *embedded views*
20986 * (created by instantiating a `TemplateRef` with the `createEmbeddedView()` method).
20987 *
20988 * A view container instance can contain other view containers,
20989 * creating a [view hierarchy](guide/glossary#view-tree).
20990 *
20991 * @see `ComponentRef`
20992 * @see `EmbeddedViewRef`
20993 *
20994 * @publicApi
20995 */
20996 var ViewContainerRef = /** @class */ (function () {
20997 function ViewContainerRef() {
20998 }
20999 return ViewContainerRef;
21000 }());
21001 /**
21002 * @internal
21003 * @nocollapse
21004 */
21005 ViewContainerRef.__NG_ELEMENT_ID__ = function () { return SWITCH_VIEW_CONTAINER_REF_FACTORY(ViewContainerRef, ElementRef); };
21006 var SWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__ = injectViewContainerRef;
21007 var SWITCH_VIEW_CONTAINER_REF_FACTORY__PRE_R3__ = noop;
21008 var SWITCH_VIEW_CONTAINER_REF_FACTORY = SWITCH_VIEW_CONTAINER_REF_FACTORY__PRE_R3__;
21009
21010 /**
21011 * @license
21012 * Copyright Google LLC All Rights Reserved.
21013 *
21014 * Use of this source code is governed by an MIT-style license that can be
21015 * found in the LICENSE file at https://angular.io/license
21016 */
21017 function expressionChangedAfterItHasBeenCheckedError(context, oldValue, currValue, isFirstCheck) {
21018 var msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '" + oldValue + "'. Current value: '" + currValue + "'.";
21019 if (isFirstCheck) {
21020 msg +=
21021 " It seems like the view has been created after its parent and its children have been dirty checked." +
21022 " Has it been created in a change detection hook ?";
21023 }
21024 return viewDebugError(msg, context);
21025 }
21026 function viewWrappedDebugError(err, context) {
21027 if (!(err instanceof Error)) {
21028 // errors that are not Error instances don't have a stack,
21029 // so it is ok to wrap them into a new Error object...
21030 err = new Error(err.toString());
21031 }
21032 _addDebugContext(err, context);
21033 return err;
21034 }
21035 function viewDebugError(msg, context) {
21036 var err = new Error(msg);
21037 _addDebugContext(err, context);
21038 return err;
21039 }
21040 function _addDebugContext(err, context) {
21041 err[ERROR_DEBUG_CONTEXT] = context;
21042 err[ERROR_LOGGER] = context.logError.bind(context);
21043 }
21044 function isViewDebugError(err) {
21045 return !!getDebugContext(err);
21046 }
21047 function viewDestroyedError(action) {
21048 return new Error("ViewDestroyedError: Attempt to use a destroyed view: " + action);
21049 }
21050
21051 /**
21052 * @license
21053 * Copyright Google LLC All Rights Reserved.
21054 *
21055 * Use of this source code is governed by an MIT-style license that can be
21056 * found in the LICENSE file at https://angular.io/license
21057 */
21058 // Called before each cycle of a view's check to detect whether this is in the
21059 // initState for which we need to call ngOnInit, ngAfterContentInit or ngAfterViewInit
21060 // lifecycle methods. Returns true if this check cycle should call lifecycle
21061 // methods.
21062 function shiftInitState(view, priorInitState, newInitState) {
21063 // Only update the InitState if we are currently in the prior state.
21064 // For example, only move into CallingInit if we are in BeforeInit. Only
21065 // move into CallingContentInit if we are in CallingInit. Normally this will
21066 // always be true because of how checkCycle is called in checkAndUpdateView.
21067 // However, if checkAndUpdateView is called recursively or if an exception is
21068 // thrown while checkAndUpdateView is running, checkAndUpdateView starts over
21069 // from the beginning. This ensures the state is monotonically increasing,
21070 // terminating in the AfterInit state, which ensures the Init methods are called
21071 // at least once and only once.
21072 var state = view.state;
21073 var initState = state & 1792 /* InitState_Mask */;
21074 if (initState === priorInitState) {
21075 view.state = (state & ~1792 /* InitState_Mask */) | newInitState;
21076 view.initIndex = -1;
21077 return true;
21078 }
21079 return initState === newInitState;
21080 }
21081 // Returns true if the lifecycle init method should be called for the node with
21082 // the given init index.
21083 function shouldCallLifecycleInitHook(view, initState, index) {
21084 if ((view.state & 1792 /* InitState_Mask */) === initState && view.initIndex <= index) {
21085 view.initIndex = index + 1;
21086 return true;
21087 }
21088 return false;
21089 }
21090 /**
21091 * Node instance data.
21092 *
21093 * We have a separate type per NodeType to save memory
21094 * (TextData | ElementData | ProviderData | PureExpressionData | QueryList<any>)
21095 *
21096 * To keep our code monomorphic,
21097 * we prohibit using `NodeData` directly but enforce the use of accessors (`asElementData`, ...).
21098 * This way, no usage site can get a `NodeData` from view.nodes and then use it for different
21099 * purposes.
21100 */
21101 var NodeData = /** @class */ (function () {
21102 function NodeData() {
21103 }
21104 return NodeData;
21105 }());
21106 /**
21107 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
21108 */
21109 function asTextData(view, index) {
21110 return view.nodes[index];
21111 }
21112 /**
21113 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
21114 */
21115 function asElementData(view, index) {
21116 return view.nodes[index];
21117 }
21118 /**
21119 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
21120 */
21121 function asProviderData(view, index) {
21122 return view.nodes[index];
21123 }
21124 /**
21125 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
21126 */
21127 function asPureExpressionData(view, index) {
21128 return view.nodes[index];
21129 }
21130 /**
21131 * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
21132 */
21133 function asQueryList(view, index) {
21134 return view.nodes[index];
21135 }
21136 var DebugContext = /** @class */ (function () {
21137 function DebugContext() {
21138 }
21139 return DebugContext;
21140 }());
21141 /**
21142 * This object is used to prevent cycles in the source files and to have a place where
21143 * debug mode can hook it. It is lazily filled when `isDevMode` is known.
21144 */
21145 var Services = {
21146 setCurrentNode: undefined,
21147 createRootView: undefined,
21148 createEmbeddedView: undefined,
21149 createComponentView: undefined,
21150 createNgModuleRef: undefined,
21151 overrideProvider: undefined,
21152 overrideComponentView: undefined,
21153 clearOverrides: undefined,
21154 checkAndUpdateView: undefined,
21155 checkNoChangesView: undefined,
21156 destroyView: undefined,
21157 resolveDep: undefined,
21158 createDebugContext: undefined,
21159 handleEvent: undefined,
21160 updateDirectives: undefined,
21161 updateRenderer: undefined,
21162 dirtyParentQueries: undefined,
21163 };
21164
21165 var NOOP = function () { };
21166 var _tokenKeyCache = new Map();
21167 function tokenKey(token) {
21168 var key = _tokenKeyCache.get(token);
21169 if (!key) {
21170 key = stringify(token) + '_' + _tokenKeyCache.size;
21171 _tokenKeyCache.set(token, key);
21172 }
21173 return key;
21174 }
21175 function unwrapValue(view, nodeIdx, bindingIdx, value) {
21176 if (WrappedValue.isWrapped(value)) {
21177 value = WrappedValue.unwrap(value);
21178 var globalBindingIdx = view.def.nodes[nodeIdx].bindingIndex + bindingIdx;
21179 var oldValue = WrappedValue.unwrap(view.oldValues[globalBindingIdx]);
21180 view.oldValues[globalBindingIdx] = new WrappedValue(oldValue);
21181 }
21182 return value;
21183 }
21184 var UNDEFINED_RENDERER_TYPE_ID = '$$undefined';
21185 var EMPTY_RENDERER_TYPE_ID = '$$empty';
21186 // Attention: this function is called as top level function.
21187 // Putting any logic in here will destroy closure tree shaking!
21188 function createRendererType2(values) {
21189 return {
21190 id: UNDEFINED_RENDERER_TYPE_ID,
21191 styles: values.styles,
21192 encapsulation: values.encapsulation,
21193 data: values.data
21194 };
21195 }
21196 var _renderCompCount$1 = 0;
21197 function resolveRendererType2(type) {
21198 if (type && type.id === UNDEFINED_RENDERER_TYPE_ID) {
21199 // first time we see this RendererType2. Initialize it...
21200 var isFilled = ((type.encapsulation != null && type.encapsulation !== exports.ViewEncapsulation.None) ||
21201 type.styles.length || Object.keys(type.data).length);
21202 if (isFilled) {
21203 type.id = "c" + _renderCompCount$1++;
21204 }
21205 else {
21206 type.id = EMPTY_RENDERER_TYPE_ID;
21207 }
21208 }
21209 if (type && type.id === EMPTY_RENDERER_TYPE_ID) {
21210 type = null;
21211 }
21212 return type || null;
21213 }
21214 function checkBinding(view, def, bindingIdx, value) {
21215 var oldValues = view.oldValues;
21216 if ((view.state & 2 /* FirstCheck */) ||
21217 !Object.is(oldValues[def.bindingIndex + bindingIdx], value)) {
21218 return true;
21219 }
21220 return false;
21221 }
21222 function checkAndUpdateBinding(view, def, bindingIdx, value) {
21223 if (checkBinding(view, def, bindingIdx, value)) {
21224 view.oldValues[def.bindingIndex + bindingIdx] = value;
21225 return true;
21226 }
21227 return false;
21228 }
21229 function checkBindingNoChanges(view, def, bindingIdx, value) {
21230 var oldValue = view.oldValues[def.bindingIndex + bindingIdx];
21231 if ((view.state & 1 /* BeforeFirstCheck */) || !devModeEqual(oldValue, value)) {
21232 var bindingName = def.bindings[bindingIdx].name;
21233 throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, def.nodeIndex), bindingName + ": " + oldValue, bindingName + ": " + value, (view.state & 1 /* BeforeFirstCheck */) !== 0);
21234 }
21235 }
21236 function markParentViewsForCheck(view) {
21237 var currView = view;
21238 while (currView) {
21239 if (currView.def.flags & 2 /* OnPush */) {
21240 currView.state |= 8 /* ChecksEnabled */;
21241 }
21242 currView = currView.viewContainerParent || currView.parent;
21243 }
21244 }
21245 function markParentViewsForCheckProjectedViews(view, endView) {
21246 var currView = view;
21247 while (currView && currView !== endView) {
21248 currView.state |= 64 /* CheckProjectedViews */;
21249 currView = currView.viewContainerParent || currView.parent;
21250 }
21251 }
21252 function dispatchEvent(view, nodeIndex, eventName, event) {
21253 try {
21254 var nodeDef = view.def.nodes[nodeIndex];
21255 var startView = nodeDef.flags & 33554432 /* ComponentView */ ?
21256 asElementData(view, nodeIndex).componentView :
21257 view;
21258 markParentViewsForCheck(startView);
21259 return Services.handleEvent(view, nodeIndex, eventName, event);
21260 }
21261 catch (e) {
21262 // Attention: Don't rethrow, as it would cancel Observable subscriptions!
21263 view.root.errorHandler.handleError(e);
21264 }
21265 }
21266 function declaredViewContainer(view) {
21267 if (view.parent) {
21268 var parentView = view.parent;
21269 return asElementData(parentView, view.parentNodeDef.nodeIndex);
21270 }
21271 return null;
21272 }
21273 /**
21274 * for component views, this is the host element.
21275 * for embedded views, this is the index of the parent node
21276 * that contains the view container.
21277 */
21278 function viewParentEl(view) {
21279 var parentView = view.parent;
21280 if (parentView) {
21281 return view.parentNodeDef.parent;
21282 }
21283 else {
21284 return null;
21285 }
21286 }
21287 function renderNode(view, def) {
21288 switch (def.flags & 201347067 /* Types */) {
21289 case 1 /* TypeElement */:
21290 return asElementData(view, def.nodeIndex).renderElement;
21291 case 2 /* TypeText */:
21292 return asTextData(view, def.nodeIndex).renderText;
21293 }
21294 }
21295 function elementEventFullName(target, name) {
21296 return target ? target + ":" + name : name;
21297 }
21298 function isComponentView(view) {
21299 return !!view.parent && !!(view.parentNodeDef.flags & 32768 /* Component */);
21300 }
21301 function isEmbeddedView(view) {
21302 return !!view.parent && !(view.parentNodeDef.flags & 32768 /* Component */);
21303 }
21304 function filterQueryId(queryId) {
21305 return 1 << (queryId % 32);
21306 }
21307 function splitMatchedQueriesDsl(matchedQueriesDsl) {
21308 var matchedQueries = {};
21309 var matchedQueryIds = 0;
21310 var references = {};
21311 if (matchedQueriesDsl) {
21312 matchedQueriesDsl.forEach(function (_a) {
21313 var _b = __read(_a, 2), queryId = _b[0], valueType = _b[1];
21314 if (typeof queryId === 'number') {
21315 matchedQueries[queryId] = valueType;
21316 matchedQueryIds |= filterQueryId(queryId);
21317 }
21318 else {
21319 references[queryId] = valueType;
21320 }
21321 });
21322 }
21323 return { matchedQueries: matchedQueries, references: references, matchedQueryIds: matchedQueryIds };
21324 }
21325 function splitDepsDsl(deps, sourceName) {
21326 return deps.map(function (value) {
21327 var _a;
21328 var token;
21329 var flags;
21330 if (Array.isArray(value)) {
21331 _a = __read(value, 2), flags = _a[0], token = _a[1];
21332 }
21333 else {
21334 flags = 0 /* None */;
21335 token = value;
21336 }
21337 if (token && (typeof token === 'function' || typeof token === 'object') && sourceName) {
21338 Object.defineProperty(token, SOURCE, { value: sourceName, configurable: true });
21339 }
21340 return { flags: flags, token: token, tokenKey: tokenKey(token) };
21341 });
21342 }
21343 function getParentRenderElement(view, renderHost, def) {
21344 var renderParent = def.renderParent;
21345 if (renderParent) {
21346 if ((renderParent.flags & 1 /* TypeElement */) === 0 ||
21347 (renderParent.flags & 33554432 /* ComponentView */) === 0 ||
21348 (renderParent.element.componentRendererType &&
21349 renderParent.element.componentRendererType.encapsulation === exports.ViewEncapsulation.Native)) {
21350 // only children of non components, or children of components with native encapsulation should
21351 // be attached.
21352 return asElementData(view, def.renderParent.nodeIndex).renderElement;
21353 }
21354 }
21355 else {
21356 return renderHost;
21357 }
21358 }
21359 var DEFINITION_CACHE = new WeakMap();
21360 function resolveDefinition(factory) {
21361 var value = DEFINITION_CACHE.get(factory);
21362 if (!value) {
21363 value = factory(function () { return NOOP; });
21364 value.factory = factory;
21365 DEFINITION_CACHE.set(factory, value);
21366 }
21367 return value;
21368 }
21369 function rootRenderNodes(view) {
21370 var renderNodes = [];
21371 visitRootRenderNodes(view, 0 /* Collect */, undefined, undefined, renderNodes);
21372 return renderNodes;
21373 }
21374 function visitRootRenderNodes(view, action, parentNode, nextSibling, target) {
21375 // We need to re-compute the parent node in case the nodes have been moved around manually
21376 if (action === 3 /* RemoveChild */) {
21377 parentNode = view.renderer.parentNode(renderNode(view, view.def.lastRenderRootNode));
21378 }
21379 visitSiblingRenderNodes(view, action, 0, view.def.nodes.length - 1, parentNode, nextSibling, target);
21380 }
21381 function visitSiblingRenderNodes(view, action, startIndex, endIndex, parentNode, nextSibling, target) {
21382 for (var i = startIndex; i <= endIndex; i++) {
21383 var nodeDef = view.def.nodes[i];
21384 if (nodeDef.flags & (1 /* TypeElement */ | 2 /* TypeText */ | 8 /* TypeNgContent */)) {
21385 visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target);
21386 }
21387 // jump to next sibling
21388 i += nodeDef.childCount;
21389 }
21390 }
21391 function visitProjectedRenderNodes(view, ngContentIndex, action, parentNode, nextSibling, target) {
21392 var compView = view;
21393 while (compView && !isComponentView(compView)) {
21394 compView = compView.parent;
21395 }
21396 var hostView = compView.parent;
21397 var hostElDef = viewParentEl(compView);
21398 var startIndex = hostElDef.nodeIndex + 1;
21399 var endIndex = hostElDef.nodeIndex + hostElDef.childCount;
21400 for (var i = startIndex; i <= endIndex; i++) {
21401 var nodeDef = hostView.def.nodes[i];
21402 if (nodeDef.ngContentIndex === ngContentIndex) {
21403 visitRenderNode(hostView, nodeDef, action, parentNode, nextSibling, target);
21404 }
21405 // jump to next sibling
21406 i += nodeDef.childCount;
21407 }
21408 if (!hostView.parent) {
21409 // a root view
21410 var projectedNodes = view.root.projectableNodes[ngContentIndex];
21411 if (projectedNodes) {
21412 for (var i = 0; i < projectedNodes.length; i++) {
21413 execRenderNodeAction(view, projectedNodes[i], action, parentNode, nextSibling, target);
21414 }
21415 }
21416 }
21417 }
21418 function visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target) {
21419 if (nodeDef.flags & 8 /* TypeNgContent */) {
21420 visitProjectedRenderNodes(view, nodeDef.ngContent.index, action, parentNode, nextSibling, target);
21421 }
21422 else {
21423 var rn = renderNode(view, nodeDef);
21424 if (action === 3 /* RemoveChild */ && (nodeDef.flags & 33554432 /* ComponentView */) &&
21425 (nodeDef.bindingFlags & 48 /* CatSyntheticProperty */)) {
21426 // Note: we might need to do both actions.
21427 if (nodeDef.bindingFlags & (16 /* SyntheticProperty */)) {
21428 execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
21429 }
21430 if (nodeDef.bindingFlags & (32 /* SyntheticHostProperty */)) {
21431 var compView = asElementData(view, nodeDef.nodeIndex).componentView;
21432 execRenderNodeAction(compView, rn, action, parentNode, nextSibling, target);
21433 }
21434 }
21435 else {
21436 execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
21437 }
21438 if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
21439 var embeddedViews = asElementData(view, nodeDef.nodeIndex).viewContainer._embeddedViews;
21440 for (var k = 0; k < embeddedViews.length; k++) {
21441 visitRootRenderNodes(embeddedViews[k], action, parentNode, nextSibling, target);
21442 }
21443 }
21444 if (nodeDef.flags & 1 /* TypeElement */ && !nodeDef.element.name) {
21445 visitSiblingRenderNodes(view, action, nodeDef.nodeIndex + 1, nodeDef.nodeIndex + nodeDef.childCount, parentNode, nextSibling, target);
21446 }
21447 }
21448 }
21449 function execRenderNodeAction(view, renderNode, action, parentNode, nextSibling, target) {
21450 var renderer = view.renderer;
21451 switch (action) {
21452 case 1 /* AppendChild */:
21453 renderer.appendChild(parentNode, renderNode);
21454 break;
21455 case 2 /* InsertBefore */:
21456 renderer.insertBefore(parentNode, renderNode, nextSibling);
21457 break;
21458 case 3 /* RemoveChild */:
21459 renderer.removeChild(parentNode, renderNode);
21460 break;
21461 case 0 /* Collect */:
21462 target.push(renderNode);
21463 break;
21464 }
21465 }
21466 var NS_PREFIX_RE = /^:([^:]+):(.+)$/;
21467 function splitNamespace(name) {
21468 if (name[0] === ':') {
21469 var match = name.match(NS_PREFIX_RE);
21470 return [match[1], match[2]];
21471 }
21472 return ['', name];
21473 }
21474 function calcBindingFlags(bindings) {
21475 var flags = 0;
21476 for (var i = 0; i < bindings.length; i++) {
21477 flags |= bindings[i].flags;
21478 }
21479 return flags;
21480 }
21481 function interpolate(valueCount, constAndInterp) {
21482 var result = '';
21483 for (var i = 0; i < valueCount * 2; i = i + 2) {
21484 result = result + constAndInterp[i] + _toStringWithNull(constAndInterp[i + 1]);
21485 }
21486 return result + constAndInterp[valueCount * 2];
21487 }
21488 function inlineInterpolate(valueCount, c0, a1, c1, a2, c2, a3, c3, a4, c4, a5, c5, a6, c6, a7, c7, a8, c8, a9, c9) {
21489 switch (valueCount) {
21490 case 1:
21491 return c0 + _toStringWithNull(a1) + c1;
21492 case 2:
21493 return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2;
21494 case 3:
21495 return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
21496 c3;
21497 case 4:
21498 return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
21499 c3 + _toStringWithNull(a4) + c4;
21500 case 5:
21501 return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
21502 c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5;
21503 case 6:
21504 return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
21505 c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) + c6;
21506 case 7:
21507 return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
21508 c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) +
21509 c6 + _toStringWithNull(a7) + c7;
21510 case 8:
21511 return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
21512 c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) +
21513 c6 + _toStringWithNull(a7) + c7 + _toStringWithNull(a8) + c8;
21514 case 9:
21515 return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
21516 c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) +
21517 c6 + _toStringWithNull(a7) + c7 + _toStringWithNull(a8) + c8 + _toStringWithNull(a9) + c9;
21518 default:
21519 throw new Error("Does not support more than 9 expressions");
21520 }
21521 }
21522 function _toStringWithNull(v) {
21523 return v != null ? v.toString() : '';
21524 }
21525 var EMPTY_ARRAY$4 = [];
21526 var EMPTY_MAP = {};
21527
21528 var UNDEFINED_VALUE = {};
21529 var InjectorRefTokenKey = tokenKey(Injector);
21530 var INJECTORRefTokenKey = tokenKey(INJECTOR);
21531 var NgModuleRefTokenKey = tokenKey(NgModuleRef);
21532 function moduleProvideDef(flags, token, value, deps) {
21533 // Need to resolve forwardRefs as e.g. for `useValue` we
21534 // lowered the expression and then stopped evaluating it,
21535 // i.e. also didn't unwrap it.
21536 value = resolveForwardRef(value);
21537 var depDefs = splitDepsDsl(deps, stringify(token));
21538 return {
21539 // will bet set by the module definition
21540 index: -1,
21541 deps: depDefs,
21542 flags: flags,
21543 token: token,
21544 value: value
21545 };
21546 }
21547 function moduleDef(providers) {
21548 var providersByKey = {};
21549 var modules = [];
21550 var scope = null;
21551 for (var i = 0; i < providers.length; i++) {
21552 var provider = providers[i];
21553 if (provider.token === INJECTOR_SCOPE) {
21554 scope = provider.value;
21555 }
21556 if (provider.flags & 1073741824 /* TypeNgModule */) {
21557 modules.push(provider.token);
21558 }
21559 provider.index = i;
21560 providersByKey[tokenKey(provider.token)] = provider;
21561 }
21562 return {
21563 // Will be filled later...
21564 factory: null,
21565 providersByKey: providersByKey,
21566 providers: providers,
21567 modules: modules,
21568 scope: scope,
21569 };
21570 }
21571 function initNgModule(data) {
21572 var def = data._def;
21573 var providers = data._providers = newArray(def.providers.length);
21574 for (var i = 0; i < def.providers.length; i++) {
21575 var provDef = def.providers[i];
21576 if (!(provDef.flags & 4096 /* LazyProvider */)) {
21577 // Make sure the provider has not been already initialized outside this loop.
21578 if (providers[i] === undefined) {
21579 providers[i] = _createProviderInstance(data, provDef);
21580 }
21581 }
21582 }
21583 }
21584 function resolveNgModuleDep(data, depDef, notFoundValue) {
21585 if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
21586 var former = setCurrentInjector(data);
21587 try {
21588 if (depDef.flags & 8 /* Value */) {
21589 return depDef.token;
21590 }
21591 if (depDef.flags & 2 /* Optional */) {
21592 notFoundValue = null;
21593 }
21594 if (depDef.flags & 1 /* SkipSelf */) {
21595 return data._parent.get(depDef.token, notFoundValue);
21596 }
21597 var tokenKey_1 = depDef.tokenKey;
21598 switch (tokenKey_1) {
21599 case InjectorRefTokenKey:
21600 case INJECTORRefTokenKey:
21601 case NgModuleRefTokenKey:
21602 return data;
21603 }
21604 var providerDef = data._def.providersByKey[tokenKey_1];
21605 var injectableDef = void 0;
21606 if (providerDef) {
21607 var providerInstance = data._providers[providerDef.index];
21608 if (providerInstance === undefined) {
21609 providerInstance = data._providers[providerDef.index] =
21610 _createProviderInstance(data, providerDef);
21611 }
21612 return providerInstance === UNDEFINED_VALUE ? undefined : providerInstance;
21613 }
21614 else if ((injectableDef = getInjectableDef(depDef.token)) && targetsModule(data, injectableDef)) {
21615 var index = data._providers.length;
21616 data._def.providers[index] = data._def.providersByKey[depDef.tokenKey] = {
21617 flags: 1024 /* TypeFactoryProvider */ | 4096 /* LazyProvider */,
21618 value: injectableDef.factory,
21619 deps: [],
21620 index: index,
21621 token: depDef.token,
21622 };
21623 data._providers[index] = UNDEFINED_VALUE;
21624 return (data._providers[index] =
21625 _createProviderInstance(data, data._def.providersByKey[depDef.tokenKey]));
21626 }
21627 else if (depDef.flags & 4 /* Self */) {
21628 return notFoundValue;
21629 }
21630 return data._parent.get(depDef.token, notFoundValue);
21631 }
21632 finally {
21633 setCurrentInjector(former);
21634 }
21635 }
21636 function moduleTransitivelyPresent(ngModule, scope) {
21637 return ngModule._def.modules.indexOf(scope) > -1;
21638 }
21639 function targetsModule(ngModule, def) {
21640 var providedIn = def.providedIn;
21641 return providedIn != null &&
21642 (providedIn === 'any' || providedIn === ngModule._def.scope ||
21643 moduleTransitivelyPresent(ngModule, providedIn));
21644 }
21645 function _createProviderInstance(ngModule, providerDef) {
21646 var injectable;
21647 switch (providerDef.flags & 201347067 /* Types */) {
21648 case 512 /* TypeClassProvider */:
21649 injectable = _createClass(ngModule, providerDef.value, providerDef.deps);
21650 break;
21651 case 1024 /* TypeFactoryProvider */:
21652 injectable = _callFactory(ngModule, providerDef.value, providerDef.deps);
21653 break;
21654 case 2048 /* TypeUseExistingProvider */:
21655 injectable = resolveNgModuleDep(ngModule, providerDef.deps[0]);
21656 break;
21657 case 256 /* TypeValueProvider */:
21658 injectable = providerDef.value;
21659 break;
21660 }
21661 // The read of `ngOnDestroy` here is slightly expensive as it's megamorphic, so it should be
21662 // avoided if possible. The sequence of checks here determines whether ngOnDestroy needs to be
21663 // checked. It might not if the `injectable` isn't an object or if NodeFlags.OnDestroy is already
21664 // set (ngOnDestroy was detected statically).
21665 if (injectable !== UNDEFINED_VALUE && injectable !== null && typeof injectable === 'object' &&
21666 !(providerDef.flags & 131072 /* OnDestroy */) && typeof injectable.ngOnDestroy === 'function') {
21667 providerDef.flags |= 131072 /* OnDestroy */;
21668 }
21669 return injectable === undefined ? UNDEFINED_VALUE : injectable;
21670 }
21671 function _createClass(ngModule, ctor, deps) {
21672 var len = deps.length;
21673 switch (len) {
21674 case 0:
21675 return new ctor();
21676 case 1:
21677 return new ctor(resolveNgModuleDep(ngModule, deps[0]));
21678 case 2:
21679 return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
21680 case 3:
21681 return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
21682 default:
21683 var depValues = [];
21684 for (var i = 0; i < len; i++) {
21685 depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
21686 }
21687 return new (ctor.bind.apply(ctor, __spread([void 0], depValues)))();
21688 }
21689 }
21690 function _callFactory(ngModule, factory, deps) {
21691 var len = deps.length;
21692 switch (len) {
21693 case 0:
21694 return factory();
21695 case 1:
21696 return factory(resolveNgModuleDep(ngModule, deps[0]));
21697 case 2:
21698 return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
21699 case 3:
21700 return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
21701 default:
21702 var depValues = [];
21703 for (var i = 0; i < len; i++) {
21704 depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
21705 }
21706 return factory.apply(void 0, __spread(depValues));
21707 }
21708 }
21709 function callNgModuleLifecycle(ngModule, lifecycles) {
21710 var def = ngModule._def;
21711 var destroyed = new Set();
21712 for (var i = 0; i < def.providers.length; i++) {
21713 var provDef = def.providers[i];
21714 if (provDef.flags & 131072 /* OnDestroy */) {
21715 var instance = ngModule._providers[i];
21716 if (instance && instance !== UNDEFINED_VALUE) {
21717 var onDestroy = instance.ngOnDestroy;
21718 if (typeof onDestroy === 'function' && !destroyed.has(instance)) {
21719 onDestroy.apply(instance);
21720 destroyed.add(instance);
21721 }
21722 }
21723 }
21724 }
21725 }
21726
21727 /**
21728 * @license
21729 * Copyright Google LLC All Rights Reserved.
21730 *
21731 * Use of this source code is governed by an MIT-style license that can be
21732 * found in the LICENSE file at https://angular.io/license
21733 */
21734 function attachEmbeddedView(parentView, elementData, viewIndex, view) {
21735 var embeddedViews = elementData.viewContainer._embeddedViews;
21736 if (viewIndex === null || viewIndex === undefined) {
21737 viewIndex = embeddedViews.length;
21738 }
21739 view.viewContainerParent = parentView;
21740 addToArray(embeddedViews, viewIndex, view);
21741 attachProjectedView(elementData, view);
21742 Services.dirtyParentQueries(view);
21743 var prevView = viewIndex > 0 ? embeddedViews[viewIndex - 1] : null;
21744 renderAttachEmbeddedView(elementData, prevView, view);
21745 }
21746 function attachProjectedView(vcElementData, view) {
21747 var dvcElementData = declaredViewContainer(view);
21748 if (!dvcElementData || dvcElementData === vcElementData ||
21749 view.state & 16 /* IsProjectedView */) {
21750 return;
21751 }
21752 // Note: For performance reasons, we
21753 // - add a view to template._projectedViews only 1x throughout its lifetime,
21754 // and remove it not until the view is destroyed.
21755 // (hard, as when a parent view is attached/detached we would need to attach/detach all
21756 // nested projected views as well, even across component boundaries).
21757 // - don't track the insertion order of views in the projected views array
21758 // (hard, as when the views of the same template are inserted different view containers)
21759 view.state |= 16 /* IsProjectedView */;
21760 var projectedViews = dvcElementData.template._projectedViews;
21761 if (!projectedViews) {
21762 projectedViews = dvcElementData.template._projectedViews = [];
21763 }
21764 projectedViews.push(view);
21765 // Note: we are changing the NodeDef here as we cannot calculate
21766 // the fact whether a template is used for projection during compilation.
21767 markNodeAsProjectedTemplate(view.parent.def, view.parentNodeDef);
21768 }
21769 function markNodeAsProjectedTemplate(viewDef, nodeDef) {
21770 if (nodeDef.flags & 4 /* ProjectedTemplate */) {
21771 return;
21772 }
21773 viewDef.nodeFlags |= 4 /* ProjectedTemplate */;
21774 nodeDef.flags |= 4 /* ProjectedTemplate */;
21775 var parentNodeDef = nodeDef.parent;
21776 while (parentNodeDef) {
21777 parentNodeDef.childFlags |= 4 /* ProjectedTemplate */;
21778 parentNodeDef = parentNodeDef.parent;
21779 }
21780 }
21781 function detachEmbeddedView(elementData, viewIndex) {
21782 var embeddedViews = elementData.viewContainer._embeddedViews;
21783 if (viewIndex == null || viewIndex >= embeddedViews.length) {
21784 viewIndex = embeddedViews.length - 1;
21785 }
21786 if (viewIndex < 0) {
21787 return null;
21788 }
21789 var view = embeddedViews[viewIndex];
21790 view.viewContainerParent = null;
21791 removeFromArray(embeddedViews, viewIndex);
21792 // See attachProjectedView for why we don't update projectedViews here.
21793 Services.dirtyParentQueries(view);
21794 renderDetachView$1(view);
21795 return view;
21796 }
21797 function detachProjectedView(view) {
21798 if (!(view.state & 16 /* IsProjectedView */)) {
21799 return;
21800 }
21801 var dvcElementData = declaredViewContainer(view);
21802 if (dvcElementData) {
21803 var projectedViews = dvcElementData.template._projectedViews;
21804 if (projectedViews) {
21805 removeFromArray(projectedViews, projectedViews.indexOf(view));
21806 Services.dirtyParentQueries(view);
21807 }
21808 }
21809 }
21810 function moveEmbeddedView(elementData, oldViewIndex, newViewIndex) {
21811 var embeddedViews = elementData.viewContainer._embeddedViews;
21812 var view = embeddedViews[oldViewIndex];
21813 removeFromArray(embeddedViews, oldViewIndex);
21814 if (newViewIndex == null) {
21815 newViewIndex = embeddedViews.length;
21816 }
21817 addToArray(embeddedViews, newViewIndex, view);
21818 // Note: Don't need to change projectedViews as the order in there
21819 // as always invalid...
21820 Services.dirtyParentQueries(view);
21821 renderDetachView$1(view);
21822 var prevView = newViewIndex > 0 ? embeddedViews[newViewIndex - 1] : null;
21823 renderAttachEmbeddedView(elementData, prevView, view);
21824 return view;
21825 }
21826 function renderAttachEmbeddedView(elementData, prevView, view) {
21827 var prevRenderNode = prevView ? renderNode(prevView, prevView.def.lastRenderRootNode) : elementData.renderElement;
21828 var parentNode = view.renderer.parentNode(prevRenderNode);
21829 var nextSibling = view.renderer.nextSibling(prevRenderNode);
21830 // Note: We can't check if `nextSibling` is present, as on WebWorkers it will always be!
21831 // However, browsers automatically do `appendChild` when there is no `nextSibling`.
21832 visitRootRenderNodes(view, 2 /* InsertBefore */, parentNode, nextSibling, undefined);
21833 }
21834 function renderDetachView$1(view) {
21835 visitRootRenderNodes(view, 3 /* RemoveChild */, null, null, undefined);
21836 }
21837
21838 var EMPTY_CONTEXT = {};
21839 // Attention: this function is called as top level function.
21840 // Putting any logic in here will destroy closure tree shaking!
21841 function createComponentFactory(selector, componentType, viewDefFactory, inputs, outputs, ngContentSelectors) {
21842 return new ComponentFactory_(selector, componentType, viewDefFactory, inputs, outputs, ngContentSelectors);
21843 }
21844 function getComponentViewDefinitionFactory(componentFactory) {
21845 return componentFactory.viewDefFactory;
21846 }
21847 var ComponentFactory_ = /** @class */ (function (_super) {
21848 __extends(ComponentFactory_, _super);
21849 function ComponentFactory_(selector, componentType, viewDefFactory, _inputs, _outputs, ngContentSelectors) {
21850 var _this =
21851 // Attention: this ctor is called as top level function.
21852 // Putting any logic in here will destroy closure tree shaking!
21853 _super.call(this) || this;
21854 _this.selector = selector;
21855 _this.componentType = componentType;
21856 _this._inputs = _inputs;
21857 _this._outputs = _outputs;
21858 _this.ngContentSelectors = ngContentSelectors;
21859 _this.viewDefFactory = viewDefFactory;
21860 return _this;
21861 }
21862 Object.defineProperty(ComponentFactory_.prototype, "inputs", {
21863 get: function () {
21864 var inputsArr = [];
21865 var inputs = this._inputs;
21866 for (var propName in inputs) {
21867 var templateName = inputs[propName];
21868 inputsArr.push({ propName: propName, templateName: templateName });
21869 }
21870 return inputsArr;
21871 },
21872 enumerable: false,
21873 configurable: true
21874 });
21875 Object.defineProperty(ComponentFactory_.prototype, "outputs", {
21876 get: function () {
21877 var outputsArr = [];
21878 for (var propName in this._outputs) {
21879 var templateName = this._outputs[propName];
21880 outputsArr.push({ propName: propName, templateName: templateName });
21881 }
21882 return outputsArr;
21883 },
21884 enumerable: false,
21885 configurable: true
21886 });
21887 /**
21888 * Creates a new component.
21889 */
21890 ComponentFactory_.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
21891 if (!ngModule) {
21892 throw new Error('ngModule should be provided');
21893 }
21894 var viewDef = resolveDefinition(this.viewDefFactory);
21895 var componentNodeIndex = viewDef.nodes[0].element.componentProvider.nodeIndex;
21896 var view = Services.createRootView(injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
21897 var component = asProviderData(view, componentNodeIndex).instance;
21898 if (rootSelectorOrNode) {
21899 view.renderer.setAttribute(asElementData(view, 0).renderElement, 'ng-version', VERSION.full);
21900 }
21901 return new ComponentRef_(view, new ViewRef_(view), component);
21902 };
21903 return ComponentFactory_;
21904 }(ComponentFactory));
21905 var ComponentRef_ = /** @class */ (function (_super) {
21906 __extends(ComponentRef_, _super);
21907 function ComponentRef_(_view, _viewRef, _component) {
21908 var _this = _super.call(this) || this;
21909 _this._view = _view;
21910 _this._viewRef = _viewRef;
21911 _this._component = _component;
21912 _this._elDef = _this._view.def.nodes[0];
21913 _this.hostView = _viewRef;
21914 _this.changeDetectorRef = _viewRef;
21915 _this.instance = _component;
21916 return _this;
21917 }
21918 Object.defineProperty(ComponentRef_.prototype, "location", {
21919 get: function () {
21920 return new ElementRef(asElementData(this._view, this._elDef.nodeIndex).renderElement);
21921 },
21922 enumerable: false,
21923 configurable: true
21924 });
21925 Object.defineProperty(ComponentRef_.prototype, "injector", {
21926 get: function () {
21927 return new Injector_(this._view, this._elDef);
21928 },
21929 enumerable: false,
21930 configurable: true
21931 });
21932 Object.defineProperty(ComponentRef_.prototype, "componentType", {
21933 get: function () {
21934 return this._component.constructor;
21935 },
21936 enumerable: false,
21937 configurable: true
21938 });
21939 ComponentRef_.prototype.destroy = function () {
21940 this._viewRef.destroy();
21941 };
21942 ComponentRef_.prototype.onDestroy = function (callback) {
21943 this._viewRef.onDestroy(callback);
21944 };
21945 return ComponentRef_;
21946 }(ComponentRef));
21947 function createViewContainerData(view, elDef, elData) {
21948 return new ViewContainerRef_(view, elDef, elData);
21949 }
21950 var ViewContainerRef_ = /** @class */ (function () {
21951 function ViewContainerRef_(_view, _elDef, _data) {
21952 this._view = _view;
21953 this._elDef = _elDef;
21954 this._data = _data;
21955 /**
21956 * @internal
21957 */
21958 this._embeddedViews = [];
21959 }
21960 Object.defineProperty(ViewContainerRef_.prototype, "element", {
21961 get: function () {
21962 return new ElementRef(this._data.renderElement);
21963 },
21964 enumerable: false,
21965 configurable: true
21966 });
21967 Object.defineProperty(ViewContainerRef_.prototype, "injector", {
21968 get: function () {
21969 return new Injector_(this._view, this._elDef);
21970 },
21971 enumerable: false,
21972 configurable: true
21973 });
21974 Object.defineProperty(ViewContainerRef_.prototype, "parentInjector", {
21975 /** @deprecated No replacement */
21976 get: function () {
21977 var view = this._view;
21978 var elDef = this._elDef.parent;
21979 while (!elDef && view) {
21980 elDef = viewParentEl(view);
21981 view = view.parent;
21982 }
21983 return view ? new Injector_(view, elDef) : new Injector_(this._view, null);
21984 },
21985 enumerable: false,
21986 configurable: true
21987 });
21988 ViewContainerRef_.prototype.clear = function () {
21989 var len = this._embeddedViews.length;
21990 for (var i = len - 1; i >= 0; i--) {
21991 var view = detachEmbeddedView(this._data, i);
21992 Services.destroyView(view);
21993 }
21994 };
21995 ViewContainerRef_.prototype.get = function (index) {
21996 var view = this._embeddedViews[index];
21997 if (view) {
21998 var ref = new ViewRef_(view);
21999 ref.attachToViewContainerRef(this);
22000 return ref;
22001 }
22002 return null;
22003 };
22004 Object.defineProperty(ViewContainerRef_.prototype, "length", {
22005 get: function () {
22006 return this._embeddedViews.length;
22007 },
22008 enumerable: false,
22009 configurable: true
22010 });
22011 ViewContainerRef_.prototype.createEmbeddedView = function (templateRef, context, index) {
22012 var viewRef = templateRef.createEmbeddedView(context || {});
22013 this.insert(viewRef, index);
22014 return viewRef;
22015 };
22016 ViewContainerRef_.prototype.createComponent = function (componentFactory, index, injector, projectableNodes, ngModuleRef) {
22017 var contextInjector = injector || this.parentInjector;
22018 if (!ngModuleRef && !(componentFactory instanceof ComponentFactoryBoundToModule)) {
22019 ngModuleRef = contextInjector.get(NgModuleRef);
22020 }
22021 var componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
22022 this.insert(componentRef.hostView, index);
22023 return componentRef;
22024 };
22025 ViewContainerRef_.prototype.insert = function (viewRef, index) {
22026 if (viewRef.destroyed) {
22027 throw new Error('Cannot insert a destroyed View in a ViewContainer!');
22028 }
22029 var viewRef_ = viewRef;
22030 var viewData = viewRef_._view;
22031 attachEmbeddedView(this._view, this._data, index, viewData);
22032 viewRef_.attachToViewContainerRef(this);
22033 return viewRef;
22034 };
22035 ViewContainerRef_.prototype.move = function (viewRef, currentIndex) {
22036 if (viewRef.destroyed) {
22037 throw new Error('Cannot move a destroyed View in a ViewContainer!');
22038 }
22039 var previousIndex = this._embeddedViews.indexOf(viewRef._view);
22040 moveEmbeddedView(this._data, previousIndex, currentIndex);
22041 return viewRef;
22042 };
22043 ViewContainerRef_.prototype.indexOf = function (viewRef) {
22044 return this._embeddedViews.indexOf(viewRef._view);
22045 };
22046 ViewContainerRef_.prototype.remove = function (index) {
22047 var viewData = detachEmbeddedView(this._data, index);
22048 if (viewData) {
22049 Services.destroyView(viewData);
22050 }
22051 };
22052 ViewContainerRef_.prototype.detach = function (index) {
22053 var view = detachEmbeddedView(this._data, index);
22054 return view ? new ViewRef_(view) : null;
22055 };
22056 return ViewContainerRef_;
22057 }());
22058 function createChangeDetectorRef(view) {
22059 return new ViewRef_(view);
22060 }
22061 var ViewRef_ = /** @class */ (function () {
22062 function ViewRef_(_view) {
22063 this._view = _view;
22064 this._viewContainerRef = null;
22065 this._appRef = null;
22066 }
22067 Object.defineProperty(ViewRef_.prototype, "rootNodes", {
22068 get: function () {
22069 return rootRenderNodes(this._view);
22070 },
22071 enumerable: false,
22072 configurable: true
22073 });
22074 Object.defineProperty(ViewRef_.prototype, "context", {
22075 get: function () {
22076 return this._view.context;
22077 },
22078 enumerable: false,
22079 configurable: true
22080 });
22081 Object.defineProperty(ViewRef_.prototype, "destroyed", {
22082 get: function () {
22083 return (this._view.state & 128 /* Destroyed */) !== 0;
22084 },
22085 enumerable: false,
22086 configurable: true
22087 });
22088 ViewRef_.prototype.markForCheck = function () {
22089 markParentViewsForCheck(this._view);
22090 };
22091 ViewRef_.prototype.detach = function () {
22092 this._view.state &= ~4 /* Attached */;
22093 };
22094 ViewRef_.prototype.detectChanges = function () {
22095 var fs = this._view.root.rendererFactory;
22096 if (fs.begin) {
22097 fs.begin();
22098 }
22099 try {
22100 Services.checkAndUpdateView(this._view);
22101 }
22102 finally {
22103 if (fs.end) {
22104 fs.end();
22105 }
22106 }
22107 };
22108 ViewRef_.prototype.checkNoChanges = function () {
22109 Services.checkNoChangesView(this._view);
22110 };
22111 ViewRef_.prototype.reattach = function () {
22112 this._view.state |= 4 /* Attached */;
22113 };
22114 ViewRef_.prototype.onDestroy = function (callback) {
22115 if (!this._view.disposables) {
22116 this._view.disposables = [];
22117 }
22118 this._view.disposables.push(callback);
22119 };
22120 ViewRef_.prototype.destroy = function () {
22121 if (this._appRef) {
22122 this._appRef.detachView(this);
22123 }
22124 else if (this._viewContainerRef) {
22125 this._viewContainerRef.detach(this._viewContainerRef.indexOf(this));
22126 }
22127 Services.destroyView(this._view);
22128 };
22129 ViewRef_.prototype.detachFromAppRef = function () {
22130 this._appRef = null;
22131 renderDetachView$1(this._view);
22132 Services.dirtyParentQueries(this._view);
22133 };
22134 ViewRef_.prototype.attachToAppRef = function (appRef) {
22135 if (this._viewContainerRef) {
22136 throw new Error('This view is already attached to a ViewContainer!');
22137 }
22138 this._appRef = appRef;
22139 };
22140 ViewRef_.prototype.attachToViewContainerRef = function (vcRef) {
22141 if (this._appRef) {
22142 throw new Error('This view is already attached directly to the ApplicationRef!');
22143 }
22144 this._viewContainerRef = vcRef;
22145 };
22146 return ViewRef_;
22147 }());
22148 function createTemplateData(view, def) {
22149 return new TemplateRef_(view, def);
22150 }
22151 var TemplateRef_ = /** @class */ (function (_super) {
22152 __extends(TemplateRef_, _super);
22153 function TemplateRef_(_parentView, _def) {
22154 var _this = _super.call(this) || this;
22155 _this._parentView = _parentView;
22156 _this._def = _def;
22157 return _this;
22158 }
22159 TemplateRef_.prototype.createEmbeddedView = function (context) {
22160 return new ViewRef_(Services.createEmbeddedView(this._parentView, this._def, this._def.element.template, context));
22161 };
22162 Object.defineProperty(TemplateRef_.prototype, "elementRef", {
22163 get: function () {
22164 return new ElementRef(asElementData(this._parentView, this._def.nodeIndex).renderElement);
22165 },
22166 enumerable: false,
22167 configurable: true
22168 });
22169 return TemplateRef_;
22170 }(TemplateRef));
22171 function createInjector$1(view, elDef) {
22172 return new Injector_(view, elDef);
22173 }
22174 var Injector_ = /** @class */ (function () {
22175 function Injector_(view, elDef) {
22176 this.view = view;
22177 this.elDef = elDef;
22178 }
22179 Injector_.prototype.get = function (token, notFoundValue) {
22180 if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
22181 var allowPrivateServices = this.elDef ? (this.elDef.flags & 33554432 /* ComponentView */) !== 0 : false;
22182 return Services.resolveDep(this.view, this.elDef, allowPrivateServices, { flags: 0 /* None */, token: token, tokenKey: tokenKey(token) }, notFoundValue);
22183 };
22184 return Injector_;
22185 }());
22186 function nodeValue(view, index) {
22187 var def = view.def.nodes[index];
22188 if (def.flags & 1 /* TypeElement */) {
22189 var elData = asElementData(view, def.nodeIndex);
22190 return def.element.template ? elData.template : elData.renderElement;
22191 }
22192 else if (def.flags & 2 /* TypeText */) {
22193 return asTextData(view, def.nodeIndex).renderText;
22194 }
22195 else if (def.flags & (20224 /* CatProvider */ | 16 /* TypePipe */)) {
22196 return asProviderData(view, def.nodeIndex).instance;
22197 }
22198 throw new Error("Illegal state: read nodeValue for node index " + index);
22199 }
22200 function createNgModuleRef(moduleType, parent, bootstrapComponents, def) {
22201 return new NgModuleRef_(moduleType, parent, bootstrapComponents, def);
22202 }
22203 var NgModuleRef_ = /** @class */ (function () {
22204 function NgModuleRef_(_moduleType, _parent, _bootstrapComponents, _def) {
22205 this._moduleType = _moduleType;
22206 this._parent = _parent;
22207 this._bootstrapComponents = _bootstrapComponents;
22208 this._def = _def;
22209 this._destroyListeners = [];
22210 this._destroyed = false;
22211 this.injector = this;
22212 initNgModule(this);
22213 }
22214 NgModuleRef_.prototype.get = function (token, notFoundValue, injectFlags) {
22215 if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
22216 if (injectFlags === void 0) { injectFlags = exports.InjectFlags.Default; }
22217 var flags = 0 /* None */;
22218 if (injectFlags & exports.InjectFlags.SkipSelf) {
22219 flags |= 1 /* SkipSelf */;
22220 }
22221 else if (injectFlags & exports.InjectFlags.Self) {
22222 flags |= 4 /* Self */;
22223 }
22224 return resolveNgModuleDep(this, { token: token, tokenKey: tokenKey(token), flags: flags }, notFoundValue);
22225 };
22226 Object.defineProperty(NgModuleRef_.prototype, "instance", {
22227 get: function () {
22228 return this.get(this._moduleType);
22229 },
22230 enumerable: false,
22231 configurable: true
22232 });
22233 Object.defineProperty(NgModuleRef_.prototype, "componentFactoryResolver", {
22234 get: function () {
22235 return this.get(ComponentFactoryResolver);
22236 },
22237 enumerable: false,
22238 configurable: true
22239 });
22240 NgModuleRef_.prototype.destroy = function () {
22241 if (this._destroyed) {
22242 throw new Error("The ng module " + stringify(this.instance.constructor) + " has already been destroyed.");
22243 }
22244 this._destroyed = true;
22245 callNgModuleLifecycle(this, 131072 /* OnDestroy */);
22246 this._destroyListeners.forEach(function (listener) { return listener(); });
22247 };
22248 NgModuleRef_.prototype.onDestroy = function (callback) {
22249 this._destroyListeners.push(callback);
22250 };
22251 return NgModuleRef_;
22252 }());
22253
22254 var Renderer2TokenKey = tokenKey(Renderer2);
22255 var ElementRefTokenKey = tokenKey(ElementRef);
22256 var ViewContainerRefTokenKey = tokenKey(ViewContainerRef);
22257 var TemplateRefTokenKey = tokenKey(TemplateRef);
22258 var ChangeDetectorRefTokenKey = tokenKey(ChangeDetectorRef);
22259 var InjectorRefTokenKey$1 = tokenKey(Injector);
22260 var INJECTORRefTokenKey$1 = tokenKey(INJECTOR);
22261 function directiveDef(checkIndex, flags, matchedQueries, childCount, ctor, deps, props, outputs) {
22262 var bindings = [];
22263 if (props) {
22264 for (var prop in props) {
22265 var _a = __read(props[prop], 2), bindingIndex = _a[0], nonMinifiedName = _a[1];
22266 bindings[bindingIndex] = {
22267 flags: 8 /* TypeProperty */,
22268 name: prop,
22269 nonMinifiedName: nonMinifiedName,
22270 ns: null,
22271 securityContext: null,
22272 suffix: null
22273 };
22274 }
22275 }
22276 var outputDefs = [];
22277 if (outputs) {
22278 for (var propName in outputs) {
22279 outputDefs.push({ type: 1 /* DirectiveOutput */, propName: propName, target: null, eventName: outputs[propName] });
22280 }
22281 }
22282 flags |= 16384 /* TypeDirective */;
22283 return _def(checkIndex, flags, matchedQueries, childCount, ctor, ctor, deps, bindings, outputDefs);
22284 }
22285 function pipeDef(flags, ctor, deps) {
22286 flags |= 16 /* TypePipe */;
22287 return _def(-1, flags, null, 0, ctor, ctor, deps);
22288 }
22289 function providerDef(flags, matchedQueries, token, value, deps) {
22290 return _def(-1, flags, matchedQueries, 0, token, value, deps);
22291 }
22292 function _def(checkIndex, flags, matchedQueriesDsl, childCount, token, value, deps, bindings, outputs) {
22293 var _a = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _a.matchedQueries, references = _a.references, matchedQueryIds = _a.matchedQueryIds;
22294 if (!outputs) {
22295 outputs = [];
22296 }
22297 if (!bindings) {
22298 bindings = [];
22299 }
22300 // Need to resolve forwardRefs as e.g. for `useValue` we
22301 // lowered the expression and then stopped evaluating it,
22302 // i.e. also didn't unwrap it.
22303 value = resolveForwardRef(value);
22304 var depDefs = splitDepsDsl(deps, stringify(token));
22305 return {
22306 // will bet set by the view definition
22307 nodeIndex: -1,
22308 parent: null,
22309 renderParent: null,
22310 bindingIndex: -1,
22311 outputIndex: -1,
22312 // regular values
22313 checkIndex: checkIndex,
22314 flags: flags,
22315 childFlags: 0,
22316 directChildFlags: 0,
22317 childMatchedQueries: 0,
22318 matchedQueries: matchedQueries,
22319 matchedQueryIds: matchedQueryIds,
22320 references: references,
22321 ngContentIndex: -1,
22322 childCount: childCount,
22323 bindings: bindings,
22324 bindingFlags: calcBindingFlags(bindings),
22325 outputs: outputs,
22326 element: null,
22327 provider: { token: token, value: value, deps: depDefs },
22328 text: null,
22329 query: null,
22330 ngContent: null
22331 };
22332 }
22333 function createProviderInstance(view, def) {
22334 return _createProviderInstance$1(view, def);
22335 }
22336 function createPipeInstance(view, def) {
22337 // deps are looked up from component.
22338 var compView = view;
22339 while (compView.parent && !isComponentView(compView)) {
22340 compView = compView.parent;
22341 }
22342 // pipes can see the private services of the component
22343 var allowPrivateServices = true;
22344 // pipes are always eager and classes!
22345 return createClass(compView.parent, viewParentEl(compView), allowPrivateServices, def.provider.value, def.provider.deps);
22346 }
22347 function createDirectiveInstance(view, def) {
22348 // components can see other private services, other directives can't.
22349 var allowPrivateServices = (def.flags & 32768 /* Component */) > 0;
22350 // directives are always eager and classes!
22351 var instance = createClass(view, def.parent, allowPrivateServices, def.provider.value, def.provider.deps);
22352 if (def.outputs.length) {
22353 for (var i = 0; i < def.outputs.length; i++) {
22354 var output = def.outputs[i];
22355 var outputObservable = instance[output.propName];
22356 if (isObservable(outputObservable)) {
22357 var subscription = outputObservable.subscribe(eventHandlerClosure(view, def.parent.nodeIndex, output.eventName));
22358 view.disposables[def.outputIndex + i] = subscription.unsubscribe.bind(subscription);
22359 }
22360 else {
22361 throw new Error("@Output " + output.propName + " not initialized in '" + instance.constructor.name + "'.");
22362 }
22363 }
22364 }
22365 return instance;
22366 }
22367 function eventHandlerClosure(view, index, eventName) {
22368 return function (event) { return dispatchEvent(view, index, eventName, event); };
22369 }
22370 function checkAndUpdateDirectiveInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
22371 var providerData = asProviderData(view, def.nodeIndex);
22372 var directive = providerData.instance;
22373 var changed = false;
22374 var changes = undefined;
22375 var bindLen = def.bindings.length;
22376 if (bindLen > 0 && checkBinding(view, def, 0, v0)) {
22377 changed = true;
22378 changes = updateProp(view, providerData, def, 0, v0, changes);
22379 }
22380 if (bindLen > 1 && checkBinding(view, def, 1, v1)) {
22381 changed = true;
22382 changes = updateProp(view, providerData, def, 1, v1, changes);
22383 }
22384 if (bindLen > 2 && checkBinding(view, def, 2, v2)) {
22385 changed = true;
22386 changes = updateProp(view, providerData, def, 2, v2, changes);
22387 }
22388 if (bindLen > 3 && checkBinding(view, def, 3, v3)) {
22389 changed = true;
22390 changes = updateProp(view, providerData, def, 3, v3, changes);
22391 }
22392 if (bindLen > 4 && checkBinding(view, def, 4, v4)) {
22393 changed = true;
22394 changes = updateProp(view, providerData, def, 4, v4, changes);
22395 }
22396 if (bindLen > 5 && checkBinding(view, def, 5, v5)) {
22397 changed = true;
22398 changes = updateProp(view, providerData, def, 5, v5, changes);
22399 }
22400 if (bindLen > 6 && checkBinding(view, def, 6, v6)) {
22401 changed = true;
22402 changes = updateProp(view, providerData, def, 6, v6, changes);
22403 }
22404 if (bindLen > 7 && checkBinding(view, def, 7, v7)) {
22405 changed = true;
22406 changes = updateProp(view, providerData, def, 7, v7, changes);
22407 }
22408 if (bindLen > 8 && checkBinding(view, def, 8, v8)) {
22409 changed = true;
22410 changes = updateProp(view, providerData, def, 8, v8, changes);
22411 }
22412 if (bindLen > 9 && checkBinding(view, def, 9, v9)) {
22413 changed = true;
22414 changes = updateProp(view, providerData, def, 9, v9, changes);
22415 }
22416 if (changes) {
22417 directive.ngOnChanges(changes);
22418 }
22419 if ((def.flags & 65536 /* OnInit */) &&
22420 shouldCallLifecycleInitHook(view, 256 /* InitState_CallingOnInit */, def.nodeIndex)) {
22421 directive.ngOnInit();
22422 }
22423 if (def.flags & 262144 /* DoCheck */) {
22424 directive.ngDoCheck();
22425 }
22426 return changed;
22427 }
22428 function checkAndUpdateDirectiveDynamic(view, def, values) {
22429 var providerData = asProviderData(view, def.nodeIndex);
22430 var directive = providerData.instance;
22431 var changed = false;
22432 var changes = undefined;
22433 for (var i = 0; i < values.length; i++) {
22434 if (checkBinding(view, def, i, values[i])) {
22435 changed = true;
22436 changes = updateProp(view, providerData, def, i, values[i], changes);
22437 }
22438 }
22439 if (changes) {
22440 directive.ngOnChanges(changes);
22441 }
22442 if ((def.flags & 65536 /* OnInit */) &&
22443 shouldCallLifecycleInitHook(view, 256 /* InitState_CallingOnInit */, def.nodeIndex)) {
22444 directive.ngOnInit();
22445 }
22446 if (def.flags & 262144 /* DoCheck */) {
22447 directive.ngDoCheck();
22448 }
22449 return changed;
22450 }
22451 function _createProviderInstance$1(view, def) {
22452 // private services can see other private services
22453 var allowPrivateServices = (def.flags & 8192 /* PrivateProvider */) > 0;
22454 var providerDef = def.provider;
22455 switch (def.flags & 201347067 /* Types */) {
22456 case 512 /* TypeClassProvider */:
22457 return createClass(view, def.parent, allowPrivateServices, providerDef.value, providerDef.deps);
22458 case 1024 /* TypeFactoryProvider */:
22459 return callFactory(view, def.parent, allowPrivateServices, providerDef.value, providerDef.deps);
22460 case 2048 /* TypeUseExistingProvider */:
22461 return resolveDep(view, def.parent, allowPrivateServices, providerDef.deps[0]);
22462 case 256 /* TypeValueProvider */:
22463 return providerDef.value;
22464 }
22465 }
22466 function createClass(view, elDef, allowPrivateServices, ctor, deps) {
22467 var len = deps.length;
22468 switch (len) {
22469 case 0:
22470 return new ctor();
22471 case 1:
22472 return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]));
22473 case 2:
22474 return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
22475 case 3:
22476 return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
22477 default:
22478 var depValues = [];
22479 for (var i = 0; i < len; i++) {
22480 depValues.push(resolveDep(view, elDef, allowPrivateServices, deps[i]));
22481 }
22482 return new (ctor.bind.apply(ctor, __spread([void 0], depValues)))();
22483 }
22484 }
22485 function callFactory(view, elDef, allowPrivateServices, factory, deps) {
22486 var len = deps.length;
22487 switch (len) {
22488 case 0:
22489 return factory();
22490 case 1:
22491 return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]));
22492 case 2:
22493 return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
22494 case 3:
22495 return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
22496 default:
22497 var depValues = [];
22498 for (var i = 0; i < len; i++) {
22499 depValues.push(resolveDep(view, elDef, allowPrivateServices, deps[i]));
22500 }
22501 return factory.apply(void 0, __spread(depValues));
22502 }
22503 }
22504 // This default value is when checking the hierarchy for a token.
22505 //
22506 // It means both:
22507 // - the token is not provided by the current injector,
22508 // - only the element injectors should be checked (ie do not check module injectors
22509 //
22510 // mod1
22511 // /
22512 // el1 mod2
22513 // \ /
22514 // el2
22515 //
22516 // When requesting el2.injector.get(token), we should check in the following order and return the
22517 // first found value:
22518 // - el2.injector.get(token, default)
22519 // - el1.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) -> do not check the module
22520 // - mod2.injector.get(token, default)
22521 var NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
22522 function resolveDep(view, elDef, allowPrivateServices, depDef, notFoundValue) {
22523 if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
22524 if (depDef.flags & 8 /* Value */) {
22525 return depDef.token;
22526 }
22527 var startView = view;
22528 if (depDef.flags & 2 /* Optional */) {
22529 notFoundValue = null;
22530 }
22531 var tokenKey = depDef.tokenKey;
22532 if (tokenKey === ChangeDetectorRefTokenKey) {
22533 // directives on the same element as a component should be able to control the change detector
22534 // of that component as well.
22535 allowPrivateServices = !!(elDef && elDef.element.componentView);
22536 }
22537 if (elDef && (depDef.flags & 1 /* SkipSelf */)) {
22538 allowPrivateServices = false;
22539 elDef = elDef.parent;
22540 }
22541 var searchView = view;
22542 while (searchView) {
22543 if (elDef) {
22544 switch (tokenKey) {
22545 case Renderer2TokenKey: {
22546 var compView = findCompView(searchView, elDef, allowPrivateServices);
22547 return compView.renderer;
22548 }
22549 case ElementRefTokenKey:
22550 return new ElementRef(asElementData(searchView, elDef.nodeIndex).renderElement);
22551 case ViewContainerRefTokenKey:
22552 return asElementData(searchView, elDef.nodeIndex).viewContainer;
22553 case TemplateRefTokenKey: {
22554 if (elDef.element.template) {
22555 return asElementData(searchView, elDef.nodeIndex).template;
22556 }
22557 break;
22558 }
22559 case ChangeDetectorRefTokenKey: {
22560 var cdView = findCompView(searchView, elDef, allowPrivateServices);
22561 return createChangeDetectorRef(cdView);
22562 }
22563 case InjectorRefTokenKey$1:
22564 case INJECTORRefTokenKey$1:
22565 return createInjector$1(searchView, elDef);
22566 default:
22567 var providerDef_1 = (allowPrivateServices ? elDef.element.allProviders :
22568 elDef.element.publicProviders)[tokenKey];
22569 if (providerDef_1) {
22570 var providerData = asProviderData(searchView, providerDef_1.nodeIndex);
22571 if (!providerData) {
22572 providerData = { instance: _createProviderInstance$1(searchView, providerDef_1) };
22573 searchView.nodes[providerDef_1.nodeIndex] = providerData;
22574 }
22575 return providerData.instance;
22576 }
22577 }
22578 }
22579 allowPrivateServices = isComponentView(searchView);
22580 elDef = viewParentEl(searchView);
22581 searchView = searchView.parent;
22582 if (depDef.flags & 4 /* Self */) {
22583 searchView = null;
22584 }
22585 }
22586 var value = startView.root.injector.get(depDef.token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);
22587 if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
22588 notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
22589 // Return the value from the root element injector when
22590 // - it provides it
22591 // (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
22592 // - the module injector should not be checked
22593 // (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
22594 return value;
22595 }
22596 return startView.root.ngModule.injector.get(depDef.token, notFoundValue);
22597 }
22598 function findCompView(view, elDef, allowPrivateServices) {
22599 var compView;
22600 if (allowPrivateServices) {
22601 compView = asElementData(view, elDef.nodeIndex).componentView;
22602 }
22603 else {
22604 compView = view;
22605 while (compView.parent && !isComponentView(compView)) {
22606 compView = compView.parent;
22607 }
22608 }
22609 return compView;
22610 }
22611 function updateProp(view, providerData, def, bindingIdx, value, changes) {
22612 if (def.flags & 32768 /* Component */) {
22613 var compView = asElementData(view, def.parent.nodeIndex).componentView;
22614 if (compView.def.flags & 2 /* OnPush */) {
22615 compView.state |= 8 /* ChecksEnabled */;
22616 }
22617 }
22618 var binding = def.bindings[bindingIdx];
22619 var propName = binding.name;
22620 // Note: This is still safe with Closure Compiler as
22621 // the user passed in the property name as an object has to `providerDef`,
22622 // so Closure Compiler will have renamed the property correctly already.
22623 providerData.instance[propName] = value;
22624 if (def.flags & 524288 /* OnChanges */) {
22625 changes = changes || {};
22626 var oldValue = WrappedValue.unwrap(view.oldValues[def.bindingIndex + bindingIdx]);
22627 var binding_1 = def.bindings[bindingIdx];
22628 changes[binding_1.nonMinifiedName] =
22629 new SimpleChange(oldValue, value, (view.state & 2 /* FirstCheck */) !== 0);
22630 }
22631 view.oldValues[def.bindingIndex + bindingIdx] = value;
22632 return changes;
22633 }
22634 // This function calls the ngAfterContentCheck, ngAfterContentInit,
22635 // ngAfterViewCheck, and ngAfterViewInit lifecycle hooks (depending on the node
22636 // flags in lifecycle). Unlike ngDoCheck, ngOnChanges and ngOnInit, which are
22637 // called during a pre-order traversal of the view tree (that is calling the
22638 // parent hooks before the child hooks) these events are sent in using a
22639 // post-order traversal of the tree (children before parents). This changes the
22640 // meaning of initIndex in the view state. For ngOnInit, initIndex tracks the
22641 // expected nodeIndex which a ngOnInit should be called. When sending
22642 // ngAfterContentInit and ngAfterViewInit it is the expected count of
22643 // ngAfterContentInit or ngAfterViewInit methods that have been called. This
22644 // ensure that despite being called recursively or after picking up after an
22645 // exception, the ngAfterContentInit or ngAfterViewInit will be called on the
22646 // correct nodes. Consider for example, the following (where E is an element
22647 // and D is a directive)
22648 // Tree: pre-order index post-order index
22649 // E1 0 6
22650 // E2 1 1
22651 // D3 2 0
22652 // E4 3 5
22653 // E5 4 4
22654 // E6 5 2
22655 // E7 6 3
22656 // As can be seen, the post-order index has an unclear relationship to the
22657 // pre-order index (postOrderIndex === preOrderIndex - parentCount +
22658 // childCount). Since number of calls to ngAfterContentInit and ngAfterViewInit
22659 // are stable (will be the same for the same view regardless of exceptions or
22660 // recursion) we just need to count them which will roughly correspond to the
22661 // post-order index (it skips elements and directives that do not have
22662 // lifecycle hooks).
22663 //
22664 // For example, if an exception is raised in the E6.onAfterViewInit() the
22665 // initIndex is left at 3 (by shouldCallLifecycleInitHook() which set it to
22666 // initIndex + 1). When checkAndUpdateView() is called again D3, E2 and E6 will
22667 // not have their ngAfterViewInit() called but, starting with E7, the rest of
22668 // the view will begin getting ngAfterViewInit() called until a check and
22669 // pass is complete.
22670 //
22671 // This algorthim also handles recursion. Consider if E4's ngAfterViewInit()
22672 // indirectly calls E1's ChangeDetectorRef.detectChanges(). The expected
22673 // initIndex is set to 6, the recusive checkAndUpdateView() starts walk again.
22674 // D3, E2, E6, E7, E5 and E4 are skipped, ngAfterViewInit() is called on E1.
22675 // When the recursion returns the initIndex will be 7 so E1 is skipped as it
22676 // has already been called in the recursively called checkAnUpdateView().
22677 function callLifecycleHooksChildrenFirst(view, lifecycles) {
22678 if (!(view.def.nodeFlags & lifecycles)) {
22679 return;
22680 }
22681 var nodes = view.def.nodes;
22682 var initIndex = 0;
22683 for (var i = 0; i < nodes.length; i++) {
22684 var nodeDef = nodes[i];
22685 var parent = nodeDef.parent;
22686 if (!parent && nodeDef.flags & lifecycles) {
22687 // matching root node (e.g. a pipe)
22688 callProviderLifecycles(view, i, nodeDef.flags & lifecycles, initIndex++);
22689 }
22690 if ((nodeDef.childFlags & lifecycles) === 0) {
22691 // no child matches one of the lifecycles
22692 i += nodeDef.childCount;
22693 }
22694 while (parent && (parent.flags & 1 /* TypeElement */) &&
22695 i === parent.nodeIndex + parent.childCount) {
22696 // last child of an element
22697 if (parent.directChildFlags & lifecycles) {
22698 initIndex = callElementProvidersLifecycles(view, parent, lifecycles, initIndex);
22699 }
22700 parent = parent.parent;
22701 }
22702 }
22703 }
22704 function callElementProvidersLifecycles(view, elDef, lifecycles, initIndex) {
22705 for (var i = elDef.nodeIndex + 1; i <= elDef.nodeIndex + elDef.childCount; i++) {
22706 var nodeDef = view.def.nodes[i];
22707 if (nodeDef.flags & lifecycles) {
22708 callProviderLifecycles(view, i, nodeDef.flags & lifecycles, initIndex++);
22709 }
22710 // only visit direct children
22711 i += nodeDef.childCount;
22712 }
22713 return initIndex;
22714 }
22715 function callProviderLifecycles(view, index, lifecycles, initIndex) {
22716 var providerData = asProviderData(view, index);
22717 if (!providerData) {
22718 return;
22719 }
22720 var provider = providerData.instance;
22721 if (!provider) {
22722 return;
22723 }
22724 Services.setCurrentNode(view, index);
22725 if (lifecycles & 1048576 /* AfterContentInit */ &&
22726 shouldCallLifecycleInitHook(view, 512 /* InitState_CallingAfterContentInit */, initIndex)) {
22727 provider.ngAfterContentInit();
22728 }
22729 if (lifecycles & 2097152 /* AfterContentChecked */) {
22730 provider.ngAfterContentChecked();
22731 }
22732 if (lifecycles & 4194304 /* AfterViewInit */ &&
22733 shouldCallLifecycleInitHook(view, 768 /* InitState_CallingAfterViewInit */, initIndex)) {
22734 provider.ngAfterViewInit();
22735 }
22736 if (lifecycles & 8388608 /* AfterViewChecked */) {
22737 provider.ngAfterViewChecked();
22738 }
22739 if (lifecycles & 131072 /* OnDestroy */) {
22740 provider.ngOnDestroy();
22741 }
22742 }
22743
22744 var ComponentFactoryResolver$1 = /** @class */ (function (_super) {
22745 __extends(ComponentFactoryResolver, _super);
22746 /**
22747 * @param ngModule The NgModuleRef to which all resolved factories are bound.
22748 */
22749 function ComponentFactoryResolver(ngModule) {
22750 var _this = _super.call(this) || this;
22751 _this.ngModule = ngModule;
22752 return _this;
22753 }
22754 ComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
22755 ngDevMode && assertComponentType(component);
22756 var componentDef = getComponentDef(component);
22757 return new ComponentFactory$1(componentDef, this.ngModule);
22758 };
22759 return ComponentFactoryResolver;
22760 }(ComponentFactoryResolver));
22761 function toRefArray(map) {
22762 var array = [];
22763 for (var nonMinified in map) {
22764 if (map.hasOwnProperty(nonMinified)) {
22765 var minified = map[nonMinified];
22766 array.push({ propName: minified, templateName: nonMinified });
22767 }
22768 }
22769 return array;
22770 }
22771 function getNamespace$1(elementName) {
22772 var name = elementName.toLowerCase();
22773 return name === 'svg' ? SVG_NAMESPACE : (name === 'math' ? MATH_ML_NAMESPACE : null);
22774 }
22775 /**
22776 * A change detection scheduler token for {@link RootContext}. This token is the default value used
22777 * for the default `RootContext` found in the {@link ROOT_CONTEXT} token.
22778 */
22779 var SCHEDULER = new InjectionToken('SCHEDULER_TOKEN', {
22780 providedIn: 'root',
22781 factory: function () { return defaultScheduler; },
22782 });
22783 function createChainedInjector(rootViewInjector, moduleInjector) {
22784 return {
22785 get: function (token, notFoundValue, flags) {
22786 var value = rootViewInjector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, flags);
22787 if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
22788 notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
22789 // Return the value from the root element injector when
22790 // - it provides it
22791 // (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
22792 // - the module injector should not be checked
22793 // (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
22794 return value;
22795 }
22796 return moduleInjector.get(token, notFoundValue, flags);
22797 }
22798 };
22799 }
22800 /**
22801 * Render3 implementation of {@link viewEngine_ComponentFactory}.
22802 */
22803 var ComponentFactory$1 = /** @class */ (function (_super) {
22804 __extends(ComponentFactory, _super);
22805 /**
22806 * @param componentDef The component definition.
22807 * @param ngModule The NgModuleRef to which the factory is bound.
22808 */
22809 function ComponentFactory(componentDef, ngModule) {
22810 var _this = _super.call(this) || this;
22811 _this.componentDef = componentDef;
22812 _this.ngModule = ngModule;
22813 _this.componentType = componentDef.type;
22814 _this.selector = stringifyCSSSelectorList(componentDef.selectors);
22815 _this.ngContentSelectors =
22816 componentDef.ngContentSelectors ? componentDef.ngContentSelectors : [];
22817 _this.isBoundToModule = !!ngModule;
22818 return _this;
22819 }
22820 Object.defineProperty(ComponentFactory.prototype, "inputs", {
22821 get: function () {
22822 return toRefArray(this.componentDef.inputs);
22823 },
22824 enumerable: false,
22825 configurable: true
22826 });
22827 Object.defineProperty(ComponentFactory.prototype, "outputs", {
22828 get: function () {
22829 return toRefArray(this.componentDef.outputs);
22830 },
22831 enumerable: false,
22832 configurable: true
22833 });
22834 ComponentFactory.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
22835 ngModule = ngModule || this.ngModule;
22836 var rootViewInjector = ngModule ? createChainedInjector(injector, ngModule.injector) : injector;
22837 var rendererFactory = rootViewInjector.get(RendererFactory2, domRendererFactory3);
22838 var sanitizer = rootViewInjector.get(Sanitizer, null);
22839 var hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
22840 // Determine a tag name used for creating host elements when this component is created
22841 // dynamically. Default to 'div' if this component did not specify any tag name in its selector.
22842 var elementName = this.componentDef.selectors[0][0] || 'div';
22843 var hostRNode = rootSelectorOrNode ?
22844 locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation) :
22845 elementCreate(elementName, rendererFactory.createRenderer(null, this.componentDef), getNamespace$1(elementName));
22846 var rootFlags = this.componentDef.onPush ? 64 /* Dirty */ | 512 /* IsRoot */ :
22847 16 /* CheckAlways */ | 512 /* IsRoot */;
22848 var rootContext = createRootContext();
22849 // Create the root view. Uses empty TView and ContentTemplate.
22850 var rootTView = createTView(0 /* Root */, -1, null, 1, 0, null, null, null, null, null);
22851 var rootLView = createLView(null, rootTView, rootContext, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector);
22852 // rootView is the parent when bootstrapping
22853 // TODO(misko): it looks like we are entering view here but we don't really need to as
22854 // `renderView` does that. However as the code is written it is needed because
22855 // `createRootComponentView` and `createRootComponent` both read global state. Fixing those
22856 // issues would allow us to drop this.
22857 enterView(rootLView, null);
22858 var component;
22859 var tElementNode;
22860 try {
22861 var componentView = createRootComponentView(hostRNode, this.componentDef, rootLView, rendererFactory, hostRenderer);
22862 if (hostRNode) {
22863 if (rootSelectorOrNode) {
22864 setUpAttributes(hostRenderer, hostRNode, ['ng-version', VERSION.full]);
22865 }
22866 else {
22867 // If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
22868 // is not defined), also apply attributes and classes extracted from component selector.
22869 // Extract attributes and classes from the first selector only to match VE behavior.
22870 var _a = extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]), attrs = _a.attrs, classes = _a.classes;
22871 if (attrs) {
22872 setUpAttributes(hostRenderer, hostRNode, attrs);
22873 }
22874 if (classes && classes.length > 0) {
22875 writeDirectClass(hostRenderer, hostRNode, classes.join(' '));
22876 }
22877 }
22878 }
22879 tElementNode = getTNode(rootTView, 0);
22880 if (projectableNodes !== undefined) {
22881 var projection = tElementNode.projection = [];
22882 for (var i = 0; i < this.ngContentSelectors.length; i++) {
22883 var nodesforSlot = projectableNodes[i];
22884 // Projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade
22885 // case). Here we do normalize passed data structure to be an array of arrays to avoid
22886 // complex checks down the line.
22887 // We also normalize the length of the passed in projectable nodes (to match the number of
22888 // <ng-container> slots defined by a component).
22889 projection.push(nodesforSlot != null ? Array.from(nodesforSlot) : null);
22890 }
22891 }
22892 // TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
22893 // executed here?
22894 // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
22895 component = createRootComponent(componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
22896 renderView(rootTView, rootLView, null);
22897 }
22898 finally {
22899 leaveView();
22900 }
22901 var componentRef = new ComponentRef$1(this.componentType, component, createElementRef(ElementRef, tElementNode, rootLView), rootLView, tElementNode);
22902 // The host element of the internal root view is attached to the component's host view node.
22903 ngDevMode && assertNodeOfPossibleTypes(rootTView.node, [2 /* View */]);
22904 rootTView.node.child = tElementNode;
22905 return componentRef;
22906 };
22907 return ComponentFactory;
22908 }(ComponentFactory));
22909 var componentFactoryResolver = new ComponentFactoryResolver$1();
22910 /**
22911 * Creates a ComponentFactoryResolver and stores it on the injector. Or, if the
22912 * ComponentFactoryResolver
22913 * already exists, retrieves the existing ComponentFactoryResolver.
22914 *
22915 * @returns The ComponentFactoryResolver instance to use
22916 */
22917 function injectComponentFactoryResolver() {
22918 return componentFactoryResolver;
22919 }
22920 /**
22921 * Represents an instance of a Component created via a {@link ComponentFactory}.
22922 *
22923 * `ComponentRef` provides access to the Component Instance as well other objects related to this
22924 * Component Instance and allows you to destroy the Component Instance via the {@link #destroy}
22925 * method.
22926 *
22927 */
22928 var ComponentRef$1 = /** @class */ (function (_super) {
22929 __extends(ComponentRef, _super);
22930 function ComponentRef(componentType, instance, location, _rootLView, _tNode) {
22931 var _this = _super.call(this) || this;
22932 _this.location = location;
22933 _this._rootLView = _rootLView;
22934 _this._tNode = _tNode;
22935 _this.destroyCbs = [];
22936 _this.instance = instance;
22937 _this.hostView = _this.changeDetectorRef = new RootViewRef(_rootLView);
22938 assignTViewNodeToLView(_rootLView[TVIEW], null, -1, _rootLView);
22939 _this.componentType = componentType;
22940 return _this;
22941 }
22942 Object.defineProperty(ComponentRef.prototype, "injector", {
22943 get: function () {
22944 return new NodeInjector(this._tNode, this._rootLView);
22945 },
22946 enumerable: false,
22947 configurable: true
22948 });
22949 ComponentRef.prototype.destroy = function () {
22950 if (this.destroyCbs) {
22951 this.destroyCbs.forEach(function (fn) { return fn(); });
22952 this.destroyCbs = null;
22953 !this.hostView.destroyed && this.hostView.destroy();
22954 }
22955 };
22956 ComponentRef.prototype.onDestroy = function (callback) {
22957 if (this.destroyCbs) {
22958 this.destroyCbs.push(callback);
22959 }
22960 };
22961 return ComponentRef;
22962 }(ComponentRef));
22963
22964 /**
22965 * @license
22966 * Copyright Google LLC All Rights Reserved.
22967 *
22968 * Use of this source code is governed by an MIT-style license that can be
22969 * found in the LICENSE file at https://angular.io/license
22970 */
22971 // THIS CODE IS GENERATED - DO NOT MODIFY
22972 // See angular/tools/gulp-tasks/cldr/extract.js
22973 var u = undefined;
22974 function plural(n) {
22975 var i = Math.floor(Math.abs(n)), v = n.toString().replace(/^[^.]*\.?/, '').length;
22976 if (i === 1 && v === 0)
22977 return 1;
22978 return 5;
22979 }
22980 var localeEn = [
22981 'en',
22982 [['a', 'p'], ['AM', 'PM'], u],
22983 [['AM', 'PM'], u, u],
22984 [
22985 ['S', 'M', 'T', 'W', 'T', 'F', 'S'], ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
22986 ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
22987 ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
22988 ],
22989 u,
22990 [
22991 ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
22992 ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
22993 [
22994 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September',
22995 'October', 'November', 'December'
22996 ]
22997 ],
22998 u,
22999 [['B', 'A'], ['BC', 'AD'], ['Before Christ', 'Anno Domini']],
23000 0,
23001 [6, 0],
23002 ['M/d/yy', 'MMM d, y', 'MMMM d, y', 'EEEE, MMMM d, y'],
23003 ['h:mm a', 'h:mm:ss a', 'h:mm:ss a z', 'h:mm:ss a zzzz'],
23004 ['{1}, {0}', u, '{1} \'at\' {0}', u],
23005 ['.', ',', ';', '%', '+', '-', 'E', '×', '‰', '∞', 'NaN', ':'],
23006 ['#,##0.###', '#,##0%', '¤#,##0.00', '#E0'],
23007 'USD',
23008 '$',
23009 'US Dollar',
23010 {},
23011 'ltr',
23012 plural
23013 ];
23014
23015 /**
23016 * @license
23017 * Copyright Google LLC All Rights Reserved.
23018 *
23019 * Use of this source code is governed by an MIT-style license that can be
23020 * found in the LICENSE file at https://angular.io/license
23021 */
23022 /**
23023 * This const is used to store the locale data registered with `registerLocaleData`
23024 */
23025 var LOCALE_DATA = {};
23026 /**
23027 * Register locale data to be used internally by Angular. See the
23028 * ["I18n guide"](guide/i18n#i18n-pipes) to know how to import additional locale data.
23029 *
23030 * The signature `registerLocaleData(data: any, extraData?: any)` is deprecated since v5.1
23031 */
23032 function registerLocaleData(data, localeId, extraData) {
23033 if (typeof localeId !== 'string') {
23034 extraData = localeId;
23035 localeId = data[exports.ɵLocaleDataIndex.LocaleId];
23036 }
23037 localeId = localeId.toLowerCase().replace(/_/g, '-');
23038 LOCALE_DATA[localeId] = data;
23039 if (extraData) {
23040 LOCALE_DATA[localeId][exports.ɵLocaleDataIndex.ExtraData] = extraData;
23041 }
23042 }
23043 /**
23044 * Finds the locale data for a given locale.
23045 *
23046 * @param locale The locale code.
23047 * @returns The locale data.
23048 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n)
23049 */
23050 function findLocaleData(locale) {
23051 var normalizedLocale = normalizeLocale(locale);
23052 var match = getLocaleData(normalizedLocale);
23053 if (match) {
23054 return match;
23055 }
23056 // let's try to find a parent locale
23057 var parentLocale = normalizedLocale.split('-')[0];
23058 match = getLocaleData(parentLocale);
23059 if (match) {
23060 return match;
23061 }
23062 if (parentLocale === 'en') {
23063 return localeEn;
23064 }
23065 throw new Error("Missing locale data for the locale \"" + locale + "\".");
23066 }
23067 /**
23068 * Retrieves the default currency code for the given locale.
23069 *
23070 * The default is defined as the first currency which is still in use.
23071 *
23072 * @param locale The code of the locale whose currency code we want.
23073 * @returns The code of the default currency for the given locale.
23074 *
23075 */
23076 function getLocaleCurrencyCode(locale) {
23077 var data = findLocaleData(locale);
23078 return data[exports.ɵLocaleDataIndex.CurrencyCode] || null;
23079 }
23080 /**
23081 * Retrieves the plural function used by ICU expressions to determine the plural case to use
23082 * for a given locale.
23083 * @param locale A locale code for the locale format rules to use.
23084 * @returns The plural function for the locale.
23085 * @see `NgPlural`
23086 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n)
23087 */
23088 function getLocalePluralCase(locale) {
23089 var data = findLocaleData(locale);
23090 return data[exports.ɵLocaleDataIndex.PluralCase];
23091 }
23092 /**
23093 * Helper function to get the given `normalizedLocale` from `LOCALE_DATA`
23094 * or from the global `ng.common.locale`.
23095 */
23096 function getLocaleData(normalizedLocale) {
23097 if (!(normalizedLocale in LOCALE_DATA)) {
23098 LOCALE_DATA[normalizedLocale] = _global.ng && _global.ng.common && _global.ng.common.locales &&
23099 _global.ng.common.locales[normalizedLocale];
23100 }
23101 return LOCALE_DATA[normalizedLocale];
23102 }
23103 /**
23104 * Helper function to remove all the locale data from `LOCALE_DATA`.
23105 */
23106 function unregisterAllLocaleData() {
23107 LOCALE_DATA = {};
23108 }
23109 (function (LocaleDataIndex) {
23110 LocaleDataIndex[LocaleDataIndex["LocaleId"] = 0] = "LocaleId";
23111 LocaleDataIndex[LocaleDataIndex["DayPeriodsFormat"] = 1] = "DayPeriodsFormat";
23112 LocaleDataIndex[LocaleDataIndex["DayPeriodsStandalone"] = 2] = "DayPeriodsStandalone";
23113 LocaleDataIndex[LocaleDataIndex["DaysFormat"] = 3] = "DaysFormat";
23114 LocaleDataIndex[LocaleDataIndex["DaysStandalone"] = 4] = "DaysStandalone";
23115 LocaleDataIndex[LocaleDataIndex["MonthsFormat"] = 5] = "MonthsFormat";
23116 LocaleDataIndex[LocaleDataIndex["MonthsStandalone"] = 6] = "MonthsStandalone";
23117 LocaleDataIndex[LocaleDataIndex["Eras"] = 7] = "Eras";
23118 LocaleDataIndex[LocaleDataIndex["FirstDayOfWeek"] = 8] = "FirstDayOfWeek";
23119 LocaleDataIndex[LocaleDataIndex["WeekendRange"] = 9] = "WeekendRange";
23120 LocaleDataIndex[LocaleDataIndex["DateFormat"] = 10] = "DateFormat";
23121 LocaleDataIndex[LocaleDataIndex["TimeFormat"] = 11] = "TimeFormat";
23122 LocaleDataIndex[LocaleDataIndex["DateTimeFormat"] = 12] = "DateTimeFormat";
23123 LocaleDataIndex[LocaleDataIndex["NumberSymbols"] = 13] = "NumberSymbols";
23124 LocaleDataIndex[LocaleDataIndex["NumberFormats"] = 14] = "NumberFormats";
23125 LocaleDataIndex[LocaleDataIndex["CurrencyCode"] = 15] = "CurrencyCode";
23126 LocaleDataIndex[LocaleDataIndex["CurrencySymbol"] = 16] = "CurrencySymbol";
23127 LocaleDataIndex[LocaleDataIndex["CurrencyName"] = 17] = "CurrencyName";
23128 LocaleDataIndex[LocaleDataIndex["Currencies"] = 18] = "Currencies";
23129 LocaleDataIndex[LocaleDataIndex["Directionality"] = 19] = "Directionality";
23130 LocaleDataIndex[LocaleDataIndex["PluralCase"] = 20] = "PluralCase";
23131 LocaleDataIndex[LocaleDataIndex["ExtraData"] = 21] = "ExtraData";
23132 })(exports.ɵLocaleDataIndex || (exports.ɵLocaleDataIndex = {}));
23133 /**
23134 * Returns the canonical form of a locale name - lowercase with `_` replaced with `-`.
23135 */
23136 function normalizeLocale(locale) {
23137 return locale.toLowerCase().replace(/_/g, '-');
23138 }
23139
23140 /**
23141 * @license
23142 * Copyright Google LLC All Rights Reserved.
23143 *
23144 * Use of this source code is governed by an MIT-style license that can be
23145 * found in the LICENSE file at https://angular.io/license
23146 */
23147 var pluralMapping = ['zero', 'one', 'two', 'few', 'many'];
23148 /**
23149 * Returns the plural case based on the locale
23150 */
23151 function getPluralCase(value, locale) {
23152 var plural = getLocalePluralCase(locale)(parseInt(value, 10));
23153 var result = pluralMapping[plural];
23154 return (result !== undefined) ? result : 'other';
23155 }
23156 /**
23157 * The locale id that the application is using by default (for translations and ICU expressions).
23158 */
23159 var DEFAULT_LOCALE_ID = 'en-US';
23160 /**
23161 * USD currency code that the application uses by default for CurrencyPipe when no
23162 * DEFAULT_CURRENCY_CODE is provided.
23163 */
23164 var USD_CURRENCY_CODE = 'USD';
23165
23166 /**
23167 * @license
23168 * Copyright Google LLC All Rights Reserved.
23169 *
23170 * Use of this source code is governed by an MIT-style license that can be
23171 * found in the LICENSE file at https://angular.io/license
23172 */
23173 /**
23174 * The locale id that the application is currently using (for translations and ICU expressions).
23175 * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
23176 * but is now defined as a global value.
23177 */
23178 var LOCALE_ID = DEFAULT_LOCALE_ID;
23179 /**
23180 * Sets the locale id that will be used for translations and ICU expressions.
23181 * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
23182 * but is now defined as a global value.
23183 *
23184 * @param localeId
23185 */
23186 function setLocaleId(localeId) {
23187 assertDefined(localeId, "Expected localeId to be defined");
23188 if (typeof localeId === 'string') {
23189 LOCALE_ID = localeId.toLowerCase().replace(/_/g, '-');
23190 }
23191 }
23192 /**
23193 * Gets the locale id that will be used for translations and ICU expressions.
23194 * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
23195 * but is now defined as a global value.
23196 */
23197 function getLocaleId() {
23198 return LOCALE_ID;
23199 }
23200
23201 /**
23202 * @license
23203 * Copyright Google LLC All Rights Reserved.
23204 *
23205 * Use of this source code is governed by an MIT-style license that can be
23206 * found in the LICENSE file at https://angular.io/license
23207 */
23208 /**
23209 * NOTE: changes to the `ngI18nClosureMode` name must be synced with `compiler-cli/src/tooling.ts`.
23210 */
23211 if (typeof ngI18nClosureMode === 'undefined') {
23212 // These property accesses can be ignored because ngI18nClosureMode will be set to false
23213 // when optimizing code and the whole if statement will be dropped.
23214 // Make sure to refer to ngI18nClosureMode as ['ngI18nClosureMode'] for closure.
23215 // NOTE: we need to have it in IIFE so that the tree-shaker is happy.
23216 (function () {
23217 // tslint:disable-next-line:no-toplevel-property-access
23218 _global['ngI18nClosureMode'] =
23219 // TODO(FW-1250): validate that this actually, you know, works.
23220 // tslint:disable-next-line:no-toplevel-property-access
23221 typeof goog !== 'undefined' && typeof goog.getMsg === 'function';
23222 })();
23223 }
23224
23225 /**
23226 * @license
23227 * Copyright Google LLC All Rights Reserved.
23228 *
23229 * Use of this source code is governed by an MIT-style license that can be
23230 * found in the LICENSE file at https://angular.io/license
23231 */
23232 function getParentFromI18nMutateOpCode(mergedCode) {
23233 return mergedCode >>> 17 /* SHIFT_PARENT */;
23234 }
23235 function getRefFromI18nMutateOpCode(mergedCode) {
23236 return (mergedCode & 131064 /* MASK_REF */) >>> 3 /* SHIFT_REF */;
23237 }
23238 function getInstructionFromI18nMutateOpCode(mergedCode) {
23239 return mergedCode & 7 /* MASK_INSTRUCTION */;
23240 }
23241 /**
23242 * Marks that the next string is an element name.
23243 *
23244 * See `I18nMutateOpCodes` documentation.
23245 */
23246 var ELEMENT_MARKER = {
23247 marker: 'element'
23248 };
23249 /**
23250 * Marks that the next string is comment text.
23251 *
23252 * See `I18nMutateOpCodes` documentation.
23253 */
23254 var COMMENT_MARKER = {
23255 marker: 'comment'
23256 };
23257 // Note: This hack is necessary so we don't erroneously get a circular dependency
23258 // failure based on types.
23259 var unusedValueExportToPlacateAjd$6 = 1;
23260
23261 /**
23262 * @license
23263 * Copyright Google LLC All Rights Reserved.
23264 *
23265 * Use of this source code is governed by an MIT-style license that can be
23266 * found in the LICENSE file at https://angular.io/license
23267 */
23268 var i18nIndexStack = [];
23269 var i18nIndexStackPointer = -1;
23270 function popI18nIndex() {
23271 return i18nIndexStack[i18nIndexStackPointer--];
23272 }
23273 function pushI18nIndex(index) {
23274 i18nIndexStack[++i18nIndexStackPointer] = index;
23275 }
23276 var changeMask = 0;
23277 var shiftsCounter = 0;
23278 function setMaskBit(bit) {
23279 if (bit) {
23280 changeMask = changeMask | (1 << shiftsCounter);
23281 }
23282 shiftsCounter++;
23283 }
23284 function applyI18n(tView, lView, index) {
23285 if (shiftsCounter > 0) {
23286 ngDevMode && assertDefined(tView, "tView should be defined");
23287 var tI18n = tView.data[index + HEADER_OFFSET];
23288 var updateOpCodes = void 0;
23289 var tIcus = null;
23290 if (Array.isArray(tI18n)) {
23291 updateOpCodes = tI18n;
23292 }
23293 else {
23294 updateOpCodes = tI18n.update;
23295 tIcus = tI18n.icus;
23296 }
23297 var bindingsStartIndex = getBindingIndex() - shiftsCounter - 1;
23298 applyUpdateOpCodes(tView, tIcus, lView, updateOpCodes, bindingsStartIndex, changeMask);
23299 // Reset changeMask & maskBit to default for the next update cycle
23300 changeMask = 0;
23301 shiftsCounter = 0;
23302 }
23303 }
23304 /**
23305 * Apply `I18nMutateOpCodes` OpCodes.
23306 *
23307 * @param tView Current `TView`
23308 * @param rootIndex Pointer to the root (parent) tNode for the i18n.
23309 * @param createOpCodes OpCodes to process
23310 * @param lView Current `LView`
23311 */
23312 function applyCreateOpCodes(tView, rootindex, createOpCodes, lView) {
23313 var renderer = lView[RENDERER];
23314 var currentTNode = null;
23315 var previousTNode = null;
23316 var visitedNodes = [];
23317 for (var i = 0; i < createOpCodes.length; i++) {
23318 var opCode = createOpCodes[i];
23319 if (typeof opCode == 'string') {
23320 var textRNode = createTextNode(opCode, renderer);
23321 var textNodeIndex = createOpCodes[++i];
23322 ngDevMode && ngDevMode.rendererCreateTextNode++;
23323 previousTNode = currentTNode;
23324 currentTNode =
23325 createDynamicNodeAtIndex(tView, lView, textNodeIndex, 3 /* Element */, textRNode, null);
23326 visitedNodes.push(textNodeIndex);
23327 setIsNotParent();
23328 }
23329 else if (typeof opCode == 'number') {
23330 switch (opCode & 7 /* MASK_INSTRUCTION */) {
23331 case 1 /* AppendChild */:
23332 var destinationNodeIndex = opCode >>> 17 /* SHIFT_PARENT */;
23333 var destinationTNode = void 0;
23334 if (destinationNodeIndex === rootindex) {
23335 // If the destination node is `i18nStart`, we don't have a
23336 // top-level node and we should use the host node instead
23337 destinationTNode = lView[T_HOST];
23338 }
23339 else {
23340 destinationTNode = getTNode(tView, destinationNodeIndex);
23341 }
23342 ngDevMode &&
23343 assertDefined(currentTNode, "You need to create or select a node before you can insert it into the DOM");
23344 previousTNode =
23345 appendI18nNode(tView, currentTNode, destinationTNode, previousTNode, lView);
23346 break;
23347 case 0 /* Select */:
23348 // Negative indices indicate that a given TNode is a sibling node, not a parent node
23349 // (see `i18nStartFirstPass` for additional information).
23350 var isParent = opCode >= 0;
23351 // FIXME(misko): This SHIFT_REF looks suspect as it does not have mask.
23352 var nodeIndex = (isParent ? opCode : ~opCode) >>> 3 /* SHIFT_REF */;
23353 visitedNodes.push(nodeIndex);
23354 previousTNode = currentTNode;
23355 currentTNode = getTNode(tView, nodeIndex);
23356 if (currentTNode) {
23357 setPreviousOrParentTNode(currentTNode, isParent);
23358 }
23359 break;
23360 case 5 /* ElementEnd */:
23361 var elementIndex = opCode >>> 3 /* SHIFT_REF */;
23362 previousTNode = currentTNode = getTNode(tView, elementIndex);
23363 setPreviousOrParentTNode(currentTNode, false);
23364 break;
23365 case 4 /* Attr */:
23366 var elementNodeIndex = opCode >>> 3 /* SHIFT_REF */;
23367 var attrName = createOpCodes[++i];
23368 var attrValue = createOpCodes[++i];
23369 // This code is used for ICU expressions only, since we don't support
23370 // directives/components in ICUs, we don't need to worry about inputs here
23371 elementAttributeInternal(getTNode(tView, elementNodeIndex), lView, attrName, attrValue, null, null);
23372 break;
23373 default:
23374 throw new Error("Unable to determine the type of mutate operation for \"" + opCode + "\"");
23375 }
23376 }
23377 else {
23378 switch (opCode) {
23379 case COMMENT_MARKER:
23380 var commentValue = createOpCodes[++i];
23381 var commentNodeIndex = createOpCodes[++i];
23382 ngDevMode &&
23383 assertEqual(typeof commentValue, 'string', "Expected \"" + commentValue + "\" to be a comment node value");
23384 var commentRNode = renderer.createComment(commentValue);
23385 ngDevMode && ngDevMode.rendererCreateComment++;
23386 previousTNode = currentTNode;
23387 currentTNode = createDynamicNodeAtIndex(tView, lView, commentNodeIndex, 5 /* IcuContainer */, commentRNode, null);
23388 visitedNodes.push(commentNodeIndex);
23389 attachPatchData(commentRNode, lView);
23390 // We will add the case nodes later, during the update phase
23391 setIsNotParent();
23392 break;
23393 case ELEMENT_MARKER:
23394 var tagNameValue = createOpCodes[++i];
23395 var elementNodeIndex = createOpCodes[++i];
23396 ngDevMode &&
23397 assertEqual(typeof tagNameValue, 'string', "Expected \"" + tagNameValue + "\" to be an element node tag name");
23398 var elementRNode = renderer.createElement(tagNameValue);
23399 ngDevMode && ngDevMode.rendererCreateElement++;
23400 previousTNode = currentTNode;
23401 currentTNode = createDynamicNodeAtIndex(tView, lView, elementNodeIndex, 3 /* Element */, elementRNode, tagNameValue);
23402 visitedNodes.push(elementNodeIndex);
23403 break;
23404 default:
23405 throw new Error("Unable to determine the type of mutate operation for \"" + opCode + "\"");
23406 }
23407 }
23408 }
23409 setIsNotParent();
23410 return visitedNodes;
23411 }
23412 /**
23413 * Apply `I18nUpdateOpCodes` OpCodes
23414 *
23415 * @param tView Current `TView`
23416 * @param tIcus If ICUs present than this contains them.
23417 * @param lView Current `LView`
23418 * @param updateOpCodes OpCodes to process
23419 * @param bindingsStartIndex Location of the first `ɵɵi18nApply`
23420 * @param changeMask Each bit corresponds to a `ɵɵi18nExp` (Counting backwards from
23421 * `bindingsStartIndex`)
23422 */
23423 function applyUpdateOpCodes(tView, tIcus, lView, updateOpCodes, bindingsStartIndex, changeMask) {
23424 var caseCreated = false;
23425 for (var i = 0; i < updateOpCodes.length; i++) {
23426 // bit code to check if we should apply the next update
23427 var checkBit = updateOpCodes[i];
23428 // Number of opCodes to skip until next set of update codes
23429 var skipCodes = updateOpCodes[++i];
23430 if (checkBit & changeMask) {
23431 // The value has been updated since last checked
23432 var value = '';
23433 for (var j = i + 1; j <= (i + skipCodes); j++) {
23434 var opCode = updateOpCodes[j];
23435 if (typeof opCode == 'string') {
23436 value += opCode;
23437 }
23438 else if (typeof opCode == 'number') {
23439 if (opCode < 0) {
23440 // Negative opCode represent `i18nExp` values offset.
23441 value += renderStringify(lView[bindingsStartIndex - opCode]);
23442 }
23443 else {
23444 var nodeIndex = opCode >>> 2 /* SHIFT_REF */;
23445 switch (opCode & 3 /* MASK_OPCODE */) {
23446 case 1 /* Attr */:
23447 var propName = updateOpCodes[++j];
23448 var sanitizeFn = updateOpCodes[++j];
23449 elementPropertyInternal(tView, getTNode(tView, nodeIndex), lView, propName, value, lView[RENDERER], sanitizeFn, false);
23450 break;
23451 case 0 /* Text */:
23452 textBindingInternal(lView, nodeIndex, value);
23453 break;
23454 case 2 /* IcuSwitch */:
23455 caseCreated =
23456 applyIcuSwitchCase(tView, tIcus, updateOpCodes[++j], lView, value);
23457 break;
23458 case 3 /* IcuUpdate */:
23459 applyIcuUpdateCase(tView, tIcus, updateOpCodes[++j], bindingsStartIndex, lView, caseCreated);
23460 break;
23461 }
23462 }
23463 }
23464 }
23465 }
23466 i += skipCodes;
23467 }
23468 }
23469 /**
23470 * Apply OpCodes associated with updating an existing ICU.
23471 *
23472 * @param tView Current `TView`
23473 * @param tIcus ICUs active at this location.
23474 * @param tIcuIndex Index into `tIcus` to process.
23475 * @param bindingsStartIndex Location of the first `ɵɵi18nApply`
23476 * @param lView Current `LView`
23477 * @param changeMask Each bit corresponds to a `ɵɵi18nExp` (Counting backwards from
23478 * `bindingsStartIndex`)
23479 */
23480 function applyIcuUpdateCase(tView, tIcus, tIcuIndex, bindingsStartIndex, lView, caseCreated) {
23481 ngDevMode && assertIndexInRange(tIcus, tIcuIndex);
23482 var tIcu = tIcus[tIcuIndex];
23483 ngDevMode && assertIndexInRange(lView, tIcu.currentCaseLViewIndex);
23484 var activeCaseIndex = lView[tIcu.currentCaseLViewIndex];
23485 if (activeCaseIndex !== null) {
23486 var mask = caseCreated ?
23487 -1 : // -1 is same as all bits on, which simulates creation since it marks all bits dirty
23488 changeMask;
23489 applyUpdateOpCodes(tView, tIcus, lView, tIcu.update[activeCaseIndex], bindingsStartIndex, mask);
23490 }
23491 }
23492 /**
23493 * Apply OpCodes associated with switching a case on ICU.
23494 *
23495 * This involves tearing down existing case and than building up a new case.
23496 *
23497 * @param tView Current `TView`
23498 * @param tIcus ICUs active at this location.
23499 * @param tICuIndex Index into `tIcus` to process.
23500 * @param lView Current `LView`
23501 * @param value Value of the case to update to.
23502 * @returns true if a new case was created (needed so that the update executes regardless of the
23503 * bitmask)
23504 */
23505 function applyIcuSwitchCase(tView, tIcus, tICuIndex, lView, value) {
23506 applyIcuSwitchCaseRemove(tView, tIcus, tICuIndex, lView);
23507 // Rebuild a new case for this ICU
23508 var caseCreated = false;
23509 var tIcu = tIcus[tICuIndex];
23510 var caseIndex = getCaseIndex(tIcu, value);
23511 lView[tIcu.currentCaseLViewIndex] = caseIndex !== -1 ? caseIndex : null;
23512 if (caseIndex > -1) {
23513 // Add the nodes for the new case
23514 applyCreateOpCodes(tView, -1, // -1 means we don't have parent node
23515 tIcu.create[caseIndex], lView);
23516 caseCreated = true;
23517 }
23518 return caseCreated;
23519 }
23520 /**
23521 * Apply OpCodes associated with tearing down of DOM.
23522 *
23523 * This involves tearing down existing case and than building up a new case.
23524 *
23525 * @param tView Current `TView`
23526 * @param tIcus ICUs active at this location.
23527 * @param tIcuIndex Index into `tIcus` to process.
23528 * @param lView Current `LView`
23529 * @returns true if a new case was created (needed so that the update executes regardless of the
23530 * bitmask)
23531 */
23532 function applyIcuSwitchCaseRemove(tView, tIcus, tIcuIndex, lView) {
23533 ngDevMode && assertIndexInRange(tIcus, tIcuIndex);
23534 var tIcu = tIcus[tIcuIndex];
23535 var activeCaseIndex = lView[tIcu.currentCaseLViewIndex];
23536 if (activeCaseIndex !== null) {
23537 var removeCodes = tIcu.remove[activeCaseIndex];
23538 for (var k = 0; k < removeCodes.length; k++) {
23539 var removeOpCode = removeCodes[k];
23540 var nodeOrIcuIndex = removeOpCode >>> 3 /* SHIFT_REF */;
23541 switch (removeOpCode & 7 /* MASK_INSTRUCTION */) {
23542 case 3 /* Remove */:
23543 // FIXME(misko): this comment is wrong!
23544 // Remove DOM element, but do *not* mark TNode as detached, since we are
23545 // just switching ICU cases (while keeping the same TNode), so a DOM element
23546 // representing a new ICU case will be re-created.
23547 removeNode(tView, lView, nodeOrIcuIndex, /* markAsDetached */ false);
23548 break;
23549 case 6 /* RemoveNestedIcu */:
23550 applyIcuSwitchCaseRemove(tView, tIcus, nodeOrIcuIndex, lView);
23551 break;
23552 }
23553 }
23554 }
23555 }
23556 function appendI18nNode(tView, tNode, parentTNode, previousTNode, lView) {
23557 ngDevMode && ngDevMode.rendererMoveNode++;
23558 var nextNode = tNode.next;
23559 if (!previousTNode) {
23560 previousTNode = parentTNode;
23561 }
23562 // Re-organize node tree to put this node in the correct position.
23563 if (previousTNode === parentTNode && tNode !== parentTNode.child) {
23564 tNode.next = parentTNode.child;
23565 parentTNode.child = tNode;
23566 }
23567 else if (previousTNode !== parentTNode && tNode !== previousTNode.next) {
23568 tNode.next = previousTNode.next;
23569 previousTNode.next = tNode;
23570 }
23571 else {
23572 tNode.next = null;
23573 }
23574 if (parentTNode !== lView[T_HOST]) {
23575 tNode.parent = parentTNode;
23576 }
23577 // If tNode was moved around, we might need to fix a broken link.
23578 var cursor = tNode.next;
23579 while (cursor) {
23580 if (cursor.next === tNode) {
23581 cursor.next = nextNode;
23582 }
23583 cursor = cursor.next;
23584 }
23585 // If the placeholder to append is a projection, we need to move the projected nodes instead
23586 if (tNode.type === 1 /* Projection */) {
23587 applyProjection(tView, lView, tNode);
23588 return tNode;
23589 }
23590 appendChild(tView, lView, getNativeByTNode(tNode, lView), tNode);
23591 var slotValue = lView[tNode.index];
23592 if (tNode.type !== 0 /* Container */ && isLContainer(slotValue)) {
23593 // Nodes that inject ViewContainerRef also have a comment node that should be moved
23594 appendChild(tView, lView, slotValue[NATIVE], tNode);
23595 }
23596 return tNode;
23597 }
23598 /**
23599 * See `i18nEnd` above.
23600 */
23601 function i18nEndFirstPass(tView, lView) {
23602 ngDevMode &&
23603 assertEqual(getBindingIndex(), tView.bindingStartIndex, 'i18nEnd should be called before any binding');
23604 var rootIndex = popI18nIndex();
23605 var tI18n = tView.data[rootIndex + HEADER_OFFSET];
23606 ngDevMode && assertDefined(tI18n, "You should call i18nStart before i18nEnd");
23607 // Find the last node that was added before `i18nEnd`
23608 var lastCreatedNode = getPreviousOrParentTNode();
23609 // Read the instructions to insert/move/remove DOM elements
23610 var visitedNodes = applyCreateOpCodes(tView, rootIndex, tI18n.create, lView);
23611 // Remove deleted nodes
23612 var index = rootIndex + 1;
23613 while (index <= lastCreatedNode.index - HEADER_OFFSET) {
23614 if (visitedNodes.indexOf(index) === -1) {
23615 removeNode(tView, lView, index, /* markAsDetached */ true);
23616 }
23617 // Check if an element has any local refs and skip them
23618 var tNode = getTNode(tView, index);
23619 if (tNode &&
23620 (tNode.type === 0 /* Container */ || tNode.type === 3 /* Element */ ||
23621 tNode.type === 4 /* ElementContainer */) &&
23622 tNode.localNames !== null) {
23623 // Divide by 2 to get the number of local refs,
23624 // since they are stored as an array that also includes directive indexes,
23625 // i.e. ["localRef", directiveIndex, ...]
23626 index += tNode.localNames.length >> 1;
23627 }
23628 index++;
23629 }
23630 }
23631 function removeNode(tView, lView, index, markAsDetached) {
23632 var removedPhTNode = getTNode(tView, index);
23633 var removedPhRNode = getNativeByIndex(index, lView);
23634 if (removedPhRNode) {
23635 nativeRemoveNode(lView[RENDERER], removedPhRNode);
23636 }
23637 var slotValue = load(lView, index);
23638 if (isLContainer(slotValue)) {
23639 var lContainer = slotValue;
23640 if (removedPhTNode.type !== 0 /* Container */) {
23641 nativeRemoveNode(lView[RENDERER], lContainer[NATIVE]);
23642 }
23643 }
23644 if (markAsDetached) {
23645 // Define this node as detached to avoid projecting it later
23646 removedPhTNode.flags |= 64 /* isDetached */;
23647 }
23648 ngDevMode && ngDevMode.rendererRemoveNode++;
23649 }
23650 /**
23651 * Creates and stores the dynamic TNode, and unhooks it from the tree for now.
23652 */
23653 function createDynamicNodeAtIndex(tView, lView, index, type, native, name) {
23654 var previousOrParentTNode = getPreviousOrParentTNode();
23655 ngDevMode && assertIndexInRange(lView, index + HEADER_OFFSET);
23656 lView[index + HEADER_OFFSET] = native;
23657 // FIXME(misko): Why does this create A TNode??? I would not expect this to be here.
23658 var tNode = getOrCreateTNode(tView, lView[T_HOST], index, type, name, null);
23659 // We are creating a dynamic node, the previous tNode might not be pointing at this node.
23660 // We will link ourselves into the tree later with `appendI18nNode`.
23661 if (previousOrParentTNode && previousOrParentTNode.next === tNode) {
23662 previousOrParentTNode.next = null;
23663 }
23664 return tNode;
23665 }
23666 /**
23667 * Returns the index of the current case of an ICU expression depending on the main binding value
23668 *
23669 * @param icuExpression
23670 * @param bindingValue The value of the main binding used by this ICU expression
23671 */
23672 function getCaseIndex(icuExpression, bindingValue) {
23673 var index = icuExpression.cases.indexOf(bindingValue);
23674 if (index === -1) {
23675 switch (icuExpression.type) {
23676 case 1 /* plural */: {
23677 var resolvedCase = getPluralCase(bindingValue, getLocaleId());
23678 index = icuExpression.cases.indexOf(resolvedCase);
23679 if (index === -1 && resolvedCase !== 'other') {
23680 index = icuExpression.cases.indexOf('other');
23681 }
23682 break;
23683 }
23684 case 0 /* select */: {
23685 index = icuExpression.cases.indexOf('other');
23686 break;
23687 }
23688 }
23689 }
23690 return index;
23691 }
23692
23693 /**
23694 * @license
23695 * Copyright Google LLC All Rights Reserved.
23696 *
23697 * Use of this source code is governed by an MIT-style license that can be
23698 * found in the LICENSE file at https://angular.io/license
23699 */
23700 /**
23701 * Converts `I18nUpdateOpCodes` array into a human readable format.
23702 *
23703 * This function is attached to the `I18nUpdateOpCodes.debug` property if `ngDevMode` is enabled.
23704 * This function provides a human readable view of the opcodes. This is useful when debugging the
23705 * application as well as writing more readable tests.
23706 *
23707 * @param this `I18nUpdateOpCodes` if attached as a method.
23708 * @param opcodes `I18nUpdateOpCodes` if invoked as a function.
23709 */
23710 function i18nUpdateOpCodesToString(opcodes) {
23711 var parser = new OpCodeParser(opcodes || (Array.isArray(this) ? this : []));
23712 var lines = [];
23713 function consumeOpCode(value) {
23714 var ref = value >>> 2 /* SHIFT_REF */;
23715 var opCode = value & 3 /* MASK_OPCODE */;
23716 switch (opCode) {
23717 case 0 /* Text */:
23718 return "(lView[" + ref + "] as Text).textContent = $$$";
23719 case 1 /* Attr */:
23720 var attrName = parser.consumeString();
23721 var sanitizationFn = parser.consumeFunction();
23722 var value_1 = sanitizationFn ? "(" + sanitizationFn + ")($$$)" : '$$$';
23723 return "(lView[" + ref + "] as Element).setAttribute('" + attrName + "', " + value_1 + ")";
23724 case 2 /* IcuSwitch */:
23725 return "icuSwitchCase(lView[" + ref + "] as Comment, " + parser.consumeNumber() + ", $$$)";
23726 case 3 /* IcuUpdate */:
23727 return "icuUpdateCase(lView[" + ref + "] as Comment, " + parser.consumeNumber() + ")";
23728 }
23729 throw new Error('unexpected OpCode');
23730 }
23731 while (parser.hasMore()) {
23732 var mask = parser.consumeNumber();
23733 var size = parser.consumeNumber();
23734 var end = parser.i + size;
23735 var statements = [];
23736 var statement = '';
23737 while (parser.i < end) {
23738 var value = parser.consumeNumberOrString();
23739 if (typeof value === 'string') {
23740 statement += value;
23741 }
23742 else if (value < 0) {
23743 // Negative numbers are ref indexes
23744 statement += '${lView[' + (0 - value) + ']}';
23745 }
23746 else {
23747 // Positive numbers are operations.
23748 var opCodeText = consumeOpCode(value);
23749 statements.push(opCodeText.replace('$$$', '`' + statement + '`') + ';');
23750 statement = '';
23751 }
23752 }
23753 lines.push("if (mask & 0b" + mask.toString(2) + ") { " + statements.join(' ') + " }");
23754 }
23755 return lines;
23756 }
23757 /**
23758 * Converts `I18nMutableOpCodes` array into a human readable format.
23759 *
23760 * This function is attached to the `I18nMutableOpCodes.debug` if `ngDevMode` is enabled. This
23761 * function provides a human readable view of the opcodes. This is useful when debugging the
23762 * application as well as writing more readable tests.
23763 *
23764 * @param this `I18nMutableOpCodes` if attached as a method.
23765 * @param opcodes `I18nMutableOpCodes` if invoked as a function.
23766 */
23767 function i18nMutateOpCodesToString(opcodes) {
23768 var parser = new OpCodeParser(opcodes || (Array.isArray(this) ? this : []));
23769 var lines = [];
23770 function consumeOpCode(opCode) {
23771 var parent = getParentFromI18nMutateOpCode(opCode);
23772 var ref = getRefFromI18nMutateOpCode(opCode);
23773 switch (getInstructionFromI18nMutateOpCode(opCode)) {
23774 case 0 /* Select */:
23775 lastRef = ref;
23776 return '';
23777 case 1 /* AppendChild */:
23778 return "(lView[" + parent + "] as Element).appendChild(lView[" + lastRef + "])";
23779 case 3 /* Remove */:
23780 return "(lView[" + parent + "] as Element).remove(lView[" + ref + "])";
23781 case 4 /* Attr */:
23782 return "(lView[" + ref + "] as Element).setAttribute(\"" + parser.consumeString() + "\", \"" + parser.consumeString() + "\")";
23783 case 5 /* ElementEnd */:
23784 return "setPreviousOrParentTNode(tView.data[" + ref + "] as TNode)";
23785 case 6 /* RemoveNestedIcu */:
23786 return "removeNestedICU(" + ref + ")";
23787 }
23788 throw new Error('Unexpected OpCode');
23789 }
23790 var lastRef = -1;
23791 while (parser.hasMore()) {
23792 var value = parser.consumeNumberStringOrMarker();
23793 if (value === COMMENT_MARKER) {
23794 var text = parser.consumeString();
23795 lastRef = parser.consumeNumber();
23796 lines.push("lView[" + lastRef + "] = document.createComment(\"" + text + "\")");
23797 }
23798 else if (value === ELEMENT_MARKER) {
23799 var text = parser.consumeString();
23800 lastRef = parser.consumeNumber();
23801 lines.push("lView[" + lastRef + "] = document.createElement(\"" + text + "\")");
23802 }
23803 else if (typeof value === 'string') {
23804 lastRef = parser.consumeNumber();
23805 lines.push("lView[" + lastRef + "] = document.createTextNode(\"" + value + "\")");
23806 }
23807 else if (typeof value === 'number') {
23808 var line = consumeOpCode(value);
23809 line && lines.push(line);
23810 }
23811 else {
23812 throw new Error('Unexpected value');
23813 }
23814 }
23815 return lines;
23816 }
23817 var OpCodeParser = /** @class */ (function () {
23818 function OpCodeParser(codes) {
23819 this.i = 0;
23820 this.codes = codes;
23821 }
23822 OpCodeParser.prototype.hasMore = function () {
23823 return this.i < this.codes.length;
23824 };
23825 OpCodeParser.prototype.consumeNumber = function () {
23826 var value = this.codes[this.i++];
23827 assertNumber(value, 'expecting number in OpCode');
23828 return value;
23829 };
23830 OpCodeParser.prototype.consumeString = function () {
23831 var value = this.codes[this.i++];
23832 assertString(value, 'expecting string in OpCode');
23833 return value;
23834 };
23835 OpCodeParser.prototype.consumeFunction = function () {
23836 var value = this.codes[this.i++];
23837 if (value === null || typeof value === 'function') {
23838 return value;
23839 }
23840 throw new Error('expecting function in OpCode');
23841 };
23842 OpCodeParser.prototype.consumeNumberOrString = function () {
23843 var value = this.codes[this.i++];
23844 if (typeof value === 'string') {
23845 return value;
23846 }
23847 assertNumber(value, 'expecting number or string in OpCode');
23848 return value;
23849 };
23850 OpCodeParser.prototype.consumeNumberStringOrMarker = function () {
23851 var value = this.codes[this.i++];
23852 if (typeof value === 'string' || typeof value === 'number' || value == COMMENT_MARKER ||
23853 value == ELEMENT_MARKER) {
23854 return value;
23855 }
23856 assertNumber(value, 'expecting number, string, COMMENT_MARKER or ELEMENT_MARKER in OpCode');
23857 return value;
23858 };
23859 return OpCodeParser;
23860 }());
23861
23862 var BINDING_REGEXP = /�(\d+):?\d*�/gi;
23863 var ICU_REGEXP = /({\s*�\d+:?\d*�\s*,\s*\S{6}\s*,[\s\S]*})/gi;
23864 var NESTED_ICU = /�(\d+)�/;
23865 var ICU_BLOCK_REGEXP = /^\s*(�\d+:?\d*�)\s*,\s*(select|plural)\s*,/;
23866 // Count for the number of vars that will be allocated for each i18n block.
23867 // It is global because this is used in multiple functions that include loops and recursive calls.
23868 // This is reset to 0 when `i18nStartFirstPass` is called.
23869 var i18nVarsCount;
23870 var parentIndexStack = [];
23871 var MARKER = "\uFFFD";
23872 var SUBTEMPLATE_REGEXP = /�\/?\*(\d+:\d+)�/gi;
23873 var PH_REGEXP = /�(\/?[#*!]\d+):?\d*�/gi;
23874 /**
23875 * Angular Dart introduced &ngsp; as a placeholder for non-removable space, see:
23876 * https://github.com/dart-lang/angular/blob/0bb611387d29d65b5af7f9d2515ab571fd3fbee4/_tests/test/compiler/preserve_whitespace_test.dart#L25-L32
23877 * In Angular Dart &ngsp; is converted to the 0xE500 PUA (Private Use Areas) unicode character
23878 * and later on replaced by a space. We are re-implementing the same idea here, since translations
23879 * might contain this special character.
23880 */
23881 var NGSP_UNICODE_REGEXP = /\uE500/g;
23882 function replaceNgsp(value) {
23883 return value.replace(NGSP_UNICODE_REGEXP, ' ');
23884 }
23885 /**
23886 * See `i18nStart` above.
23887 */
23888 function i18nStartFirstPass(lView, tView, index, message, subTemplateIndex) {
23889 var startIndex = tView.blueprint.length - HEADER_OFFSET;
23890 i18nVarsCount = 0;
23891 var previousOrParentTNode = getPreviousOrParentTNode();
23892 var parentTNode = getIsParent() ? previousOrParentTNode : previousOrParentTNode && previousOrParentTNode.parent;
23893 var parentIndex = parentTNode && parentTNode !== lView[T_HOST] ? parentTNode.index - HEADER_OFFSET : index;
23894 var parentIndexPointer = 0;
23895 parentIndexStack[parentIndexPointer] = parentIndex;
23896 var createOpCodes = [];
23897 if (ngDevMode) {
23898 attachDebugGetter(createOpCodes, i18nMutateOpCodesToString);
23899 }
23900 // If the previous node wasn't the direct parent then we have a translation without top level
23901 // element and we need to keep a reference of the previous element if there is one. We should also
23902 // keep track whether an element was a parent node or not, so that the logic that consumes
23903 // the generated `I18nMutateOpCode`s can leverage this information to properly set TNode state
23904 // (whether it's a parent or sibling).
23905 if (index > 0 && previousOrParentTNode !== parentTNode) {
23906 var previousTNodeIndex = previousOrParentTNode.index - HEADER_OFFSET;
23907 // If current TNode is a sibling node, encode it using a negative index. This information is
23908 // required when the `Select` action is processed (see the `readCreateOpCodes` function).
23909 if (!getIsParent()) {
23910 previousTNodeIndex = ~previousTNodeIndex;
23911 }
23912 // Create an OpCode to select the previous TNode
23913 createOpCodes.push(previousTNodeIndex << 3 /* SHIFT_REF */ | 0 /* Select */);
23914 }
23915 var updateOpCodes = [];
23916 if (ngDevMode) {
23917 attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
23918 }
23919 var icuExpressions = [];
23920 if (message === '' && isRootTemplateMessage(subTemplateIndex)) {
23921 // If top level translation is an empty string, do not invoke additional processing
23922 // and just create op codes for empty text node instead.
23923 createOpCodes.push(message, allocNodeIndex(startIndex), parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
23924 }
23925 else {
23926 var templateTranslation = getTranslationForTemplate(message, subTemplateIndex);
23927 var msgParts = replaceNgsp(templateTranslation).split(PH_REGEXP);
23928 for (var i = 0; i < msgParts.length; i++) {
23929 var value = msgParts[i];
23930 if (i & 1) {
23931 // Odd indexes are placeholders (elements and sub-templates)
23932 if (value.charAt(0) === '/') {
23933 // It is a closing tag
23934 if (value.charAt(1) === "#" /* ELEMENT */) {
23935 var phIndex = parseInt(value.substr(2), 10);
23936 parentIndex = parentIndexStack[--parentIndexPointer];
23937 createOpCodes.push(phIndex << 3 /* SHIFT_REF */ | 5 /* ElementEnd */);
23938 }
23939 }
23940 else {
23941 var phIndex = parseInt(value.substr(1), 10);
23942 var isElement = value.charAt(0) === "#" /* ELEMENT */;
23943 // The value represents a placeholder that we move to the designated index.
23944 // Note: positive indicies indicate that a TNode with a given index should also be marked
23945 // as parent while executing `Select` instruction.
23946 createOpCodes.push((isElement ? phIndex : ~phIndex) << 3 /* SHIFT_REF */ |
23947 0 /* Select */, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
23948 if (isElement) {
23949 parentIndexStack[++parentIndexPointer] = parentIndex = phIndex;
23950 }
23951 }
23952 }
23953 else {
23954 // Even indexes are text (including bindings & ICU expressions)
23955 var parts = extractParts(value);
23956 for (var j = 0; j < parts.length; j++) {
23957 if (j & 1) {
23958 // Odd indexes are ICU expressions
23959 var icuExpression = parts[j];
23960 // Verify that ICU expression has the right shape. Translations might contain invalid
23961 // constructions (while original messages were correct), so ICU parsing at runtime may
23962 // not succeed (thus `icuExpression` remains a string).
23963 if (typeof icuExpression !== 'object') {
23964 throw new Error("Unable to parse ICU expression in \"" + templateTranslation + "\" message.");
23965 }
23966 // Create the comment node that will anchor the ICU expression
23967 var icuNodeIndex = allocNodeIndex(startIndex);
23968 createOpCodes.push(COMMENT_MARKER, ngDevMode ? "ICU " + icuNodeIndex : '', icuNodeIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
23969 // Update codes for the ICU expression
23970 var mask = getBindingMask(icuExpression);
23971 icuStart(icuExpressions, icuExpression, icuNodeIndex, icuNodeIndex);
23972 // Since this is recursive, the last TIcu that was pushed is the one we want
23973 var tIcuIndex = icuExpressions.length - 1;
23974 updateOpCodes.push(toMaskBit(icuExpression.mainBinding), // mask of the main binding
23975 3, // skip 3 opCodes if not changed
23976 -1 - icuExpression.mainBinding, icuNodeIndex << 2 /* SHIFT_REF */ | 2 /* IcuSwitch */, tIcuIndex, mask, // mask of all the bindings of this ICU expression
23977 2, // skip 2 opCodes if not changed
23978 icuNodeIndex << 2 /* SHIFT_REF */ | 3 /* IcuUpdate */, tIcuIndex);
23979 }
23980 else if (parts[j] !== '') {
23981 var text = parts[j];
23982 // Even indexes are text (including bindings)
23983 var hasBinding = text.match(BINDING_REGEXP);
23984 // Create text nodes
23985 var textNodeIndex = allocNodeIndex(startIndex);
23986 createOpCodes.push(
23987 // If there is a binding, the value will be set during update
23988 hasBinding ? '' : text, textNodeIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
23989 if (hasBinding) {
23990 addAllToArray(generateBindingUpdateOpCodes(text, textNodeIndex), updateOpCodes);
23991 }
23992 }
23993 }
23994 }
23995 }
23996 }
23997 if (i18nVarsCount > 0) {
23998 allocExpando(tView, lView, i18nVarsCount);
23999 }
24000 // NOTE: local var needed to properly assert the type of `TI18n`.
24001 var tI18n = {
24002 vars: i18nVarsCount,
24003 create: createOpCodes,
24004 update: updateOpCodes,
24005 icus: icuExpressions.length ? icuExpressions : null,
24006 };
24007 tView.data[index + HEADER_OFFSET] = tI18n;
24008 }
24009 /**
24010 * See `i18nAttributes` above.
24011 */
24012 function i18nAttributesFirstPass(lView, tView, index, values) {
24013 var previousElement = getPreviousOrParentTNode();
24014 var previousElementIndex = previousElement.index - HEADER_OFFSET;
24015 var updateOpCodes = [];
24016 if (ngDevMode) {
24017 attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
24018 }
24019 for (var i = 0; i < values.length; i += 2) {
24020 var attrName = values[i];
24021 var message = values[i + 1];
24022 var parts = message.split(ICU_REGEXP);
24023 for (var j = 0; j < parts.length; j++) {
24024 var value = parts[j];
24025 if (j & 1) {
24026 // Odd indexes are ICU expressions
24027 // TODO(ocombe): support ICU expressions in attributes
24028 throw new Error('ICU expressions are not yet supported in attributes');
24029 }
24030 else if (value !== '') {
24031 // Even indexes are text (including bindings)
24032 var hasBinding = !!value.match(BINDING_REGEXP);
24033 if (hasBinding) {
24034 if (tView.firstCreatePass && tView.data[index + HEADER_OFFSET] === null) {
24035 addAllToArray(generateBindingUpdateOpCodes(value, previousElementIndex, attrName), updateOpCodes);
24036 }
24037 }
24038 else {
24039 var tNode = getTNode(tView, previousElementIndex);
24040 // Set attributes for Elements only, for other types (like ElementContainer),
24041 // only set inputs below
24042 if (tNode.type === 3 /* Element */) {
24043 elementAttributeInternal(tNode, lView, attrName, value, null, null);
24044 }
24045 // Check if that attribute is a directive input
24046 var dataValue = tNode.inputs !== null && tNode.inputs[attrName];
24047 if (dataValue) {
24048 setInputsForProperty(tView, lView, dataValue, attrName, value);
24049 if (ngDevMode) {
24050 var element = getNativeByIndex(previousElementIndex, lView);
24051 setNgReflectProperties(lView, element, tNode.type, dataValue, value);
24052 }
24053 }
24054 }
24055 }
24056 }
24057 }
24058 if (tView.firstCreatePass && tView.data[index + HEADER_OFFSET] === null) {
24059 tView.data[index + HEADER_OFFSET] = updateOpCodes;
24060 }
24061 }
24062 /**
24063 * Generate the OpCodes to update the bindings of a string.
24064 *
24065 * @param str The string containing the bindings.
24066 * @param destinationNode Index of the destination node which will receive the binding.
24067 * @param attrName Name of the attribute, if the string belongs to an attribute.
24068 * @param sanitizeFn Sanitization function used to sanitize the string after update, if necessary.
24069 */
24070 function generateBindingUpdateOpCodes(str, destinationNode, attrName, sanitizeFn) {
24071 if (sanitizeFn === void 0) { sanitizeFn = null; }
24072 var updateOpCodes = [null, null]; // Alloc space for mask and size
24073 if (ngDevMode) {
24074 attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
24075 }
24076 var textParts = str.split(BINDING_REGEXP);
24077 var mask = 0;
24078 for (var j = 0; j < textParts.length; j++) {
24079 var textValue = textParts[j];
24080 if (j & 1) {
24081 // Odd indexes are bindings
24082 var bindingIndex = parseInt(textValue, 10);
24083 updateOpCodes.push(-1 - bindingIndex);
24084 mask = mask | toMaskBit(bindingIndex);
24085 }
24086 else if (textValue !== '') {
24087 // Even indexes are text
24088 updateOpCodes.push(textValue);
24089 }
24090 }
24091 updateOpCodes.push(destinationNode << 2 /* SHIFT_REF */ |
24092 (attrName ? 1 /* Attr */ : 0 /* Text */));
24093 if (attrName) {
24094 updateOpCodes.push(attrName, sanitizeFn);
24095 }
24096 updateOpCodes[0] = mask;
24097 updateOpCodes[1] = updateOpCodes.length - 2;
24098 return updateOpCodes;
24099 }
24100 function getBindingMask(icuExpression, mask) {
24101 if (mask === void 0) { mask = 0; }
24102 mask = mask | toMaskBit(icuExpression.mainBinding);
24103 var match;
24104 for (var i = 0; i < icuExpression.values.length; i++) {
24105 var valueArr = icuExpression.values[i];
24106 for (var j = 0; j < valueArr.length; j++) {
24107 var value = valueArr[j];
24108 if (typeof value === 'string') {
24109 while (match = BINDING_REGEXP.exec(value)) {
24110 mask = mask | toMaskBit(parseInt(match[1], 10));
24111 }
24112 }
24113 else {
24114 mask = getBindingMask(value, mask);
24115 }
24116 }
24117 }
24118 return mask;
24119 }
24120 function allocNodeIndex(startIndex) {
24121 return startIndex + i18nVarsCount++;
24122 }
24123 /**
24124 * Convert binding index to mask bit.
24125 *
24126 * Each index represents a single bit on the bit-mask. Because bit-mask only has 32 bits, we make
24127 * the 32nd bit share all masks for all bindings higher than 32. Since it is extremely rare to have
24128 * more than 32 bindings this will be hit very rarely. The downside of hitting this corner case is
24129 * that we will execute binding code more often than necessary. (penalty of performance)
24130 */
24131 function toMaskBit(bindingIndex) {
24132 return 1 << Math.min(bindingIndex, 31);
24133 }
24134 function isRootTemplateMessage(subTemplateIndex) {
24135 return subTemplateIndex === undefined;
24136 }
24137 /**
24138 * Removes everything inside the sub-templates of a message.
24139 */
24140 function removeInnerTemplateTranslation(message) {
24141 var match;
24142 var res = '';
24143 var index = 0;
24144 var inTemplate = false;
24145 var tagMatched;
24146 while ((match = SUBTEMPLATE_REGEXP.exec(message)) !== null) {
24147 if (!inTemplate) {
24148 res += message.substring(index, match.index + match[0].length);
24149 tagMatched = match[1];
24150 inTemplate = true;
24151 }
24152 else {
24153 if (match[0] === MARKER + "/*" + tagMatched + MARKER) {
24154 index = match.index;
24155 inTemplate = false;
24156 }
24157 }
24158 }
24159 ngDevMode &&
24160 assertEqual(inTemplate, false, "Tag mismatch: unable to find the end of the sub-template in the translation \"" + message + "\"");
24161 res += message.substr(index);
24162 return res;
24163 }
24164 /**
24165 * Extracts a part of a message and removes the rest.
24166 *
24167 * This method is used for extracting a part of the message associated with a template. A translated
24168 * message can span multiple templates.
24169 *
24170 * Example:
24171 * ```
24172 * <div i18n>Translate <span *ngIf>me</span>!</div>
24173 * ```
24174 *
24175 * @param message The message to crop
24176 * @param subTemplateIndex Index of the sub-template to extract. If undefined it returns the
24177 * external template and removes all sub-templates.
24178 */
24179 function getTranslationForTemplate(message, subTemplateIndex) {
24180 if (isRootTemplateMessage(subTemplateIndex)) {
24181 // We want the root template message, ignore all sub-templates
24182 return removeInnerTemplateTranslation(message);
24183 }
24184 else {
24185 // We want a specific sub-template
24186 var start = message.indexOf(":" + subTemplateIndex + MARKER) + 2 + subTemplateIndex.toString().length;
24187 var end = message.search(new RegExp(MARKER + "\\/\\*\\d+:" + subTemplateIndex + MARKER));
24188 return removeInnerTemplateTranslation(message.substring(start, end));
24189 }
24190 }
24191 /**
24192 * Generate the OpCodes for ICU expressions.
24193 *
24194 * @param tIcus
24195 * @param icuExpression
24196 * @param startIndex
24197 * @param expandoStartIndex
24198 */
24199 function icuStart(tIcus, icuExpression, startIndex, expandoStartIndex) {
24200 var createCodes = [];
24201 var removeCodes = [];
24202 var updateCodes = [];
24203 var vars = [];
24204 var childIcus = [];
24205 var values = icuExpression.values;
24206 for (var i = 0; i < values.length; i++) {
24207 // Each value is an array of strings & other ICU expressions
24208 var valueArr = values[i];
24209 var nestedIcus = [];
24210 for (var j = 0; j < valueArr.length; j++) {
24211 var value = valueArr[j];
24212 if (typeof value !== 'string') {
24213 // It is an nested ICU expression
24214 var icuIndex = nestedIcus.push(value) - 1;
24215 // Replace nested ICU expression by a comment node
24216 valueArr[j] = "<!--\uFFFD" + icuIndex + "\uFFFD-->";
24217 }
24218 }
24219 var icuCase = parseIcuCase(valueArr.join(''), startIndex, nestedIcus, tIcus, expandoStartIndex);
24220 createCodes.push(icuCase.create);
24221 removeCodes.push(icuCase.remove);
24222 updateCodes.push(icuCase.update);
24223 vars.push(icuCase.vars);
24224 childIcus.push(icuCase.childIcus);
24225 }
24226 var tIcu = {
24227 type: icuExpression.type,
24228 vars: vars,
24229 currentCaseLViewIndex: HEADER_OFFSET +
24230 expandoStartIndex // expandoStartIndex does not include the header so add it.
24231 + 1,
24232 childIcus: childIcus,
24233 cases: icuExpression.cases,
24234 create: createCodes,
24235 remove: removeCodes,
24236 update: updateCodes
24237 };
24238 tIcus.push(tIcu);
24239 // Adding the maximum possible of vars needed (based on the cases with the most vars)
24240 i18nVarsCount += Math.max.apply(Math, __spread(vars));
24241 }
24242 /**
24243 * Parses text containing an ICU expression and produces a JSON object for it.
24244 * Original code from closure library, modified for Angular.
24245 *
24246 * @param pattern Text containing an ICU expression that needs to be parsed.
24247 *
24248 */
24249 function parseICUBlock(pattern) {
24250 var cases = [];
24251 var values = [];
24252 var icuType = 1 /* plural */;
24253 var mainBinding = 0;
24254 pattern = pattern.replace(ICU_BLOCK_REGEXP, function (str, binding, type) {
24255 if (type === 'select') {
24256 icuType = 0 /* select */;
24257 }
24258 else {
24259 icuType = 1 /* plural */;
24260 }
24261 mainBinding = parseInt(binding.substr(1), 10);
24262 return '';
24263 });
24264 var parts = extractParts(pattern);
24265 // Looking for (key block)+ sequence. One of the keys has to be "other".
24266 for (var pos = 0; pos < parts.length;) {
24267 var key = parts[pos++].trim();
24268 if (icuType === 1 /* plural */) {
24269 // Key can be "=x", we just want "x"
24270 key = key.replace(/\s*(?:=)?(\w+)\s*/, '$1');
24271 }
24272 if (key.length) {
24273 cases.push(key);
24274 }
24275 var blocks = extractParts(parts[pos++]);
24276 if (cases.length > values.length) {
24277 values.push(blocks);
24278 }
24279 }
24280 // TODO(ocombe): support ICU expressions in attributes, see #21615
24281 return { type: icuType, mainBinding: mainBinding, cases: cases, values: values };
24282 }
24283 /**
24284 * Transforms a string template into an HTML template and a list of instructions used to update
24285 * attributes or nodes that contain bindings.
24286 *
24287 * @param unsafeHtml The string to parse
24288 * @param parentIndex
24289 * @param nestedIcus
24290 * @param tIcus
24291 * @param expandoStartIndex
24292 */
24293 function parseIcuCase(unsafeHtml, parentIndex, nestedIcus, tIcus, expandoStartIndex) {
24294 var inertBodyHelper = getInertBodyHelper(getDocument());
24295 var inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
24296 if (!inertBodyElement) {
24297 throw new Error('Unable to generate inert body element');
24298 }
24299 var wrapper = getTemplateContent(inertBodyElement) || inertBodyElement;
24300 var opCodes = {
24301 vars: 1,
24302 childIcus: [],
24303 create: [],
24304 remove: [],
24305 update: []
24306 };
24307 if (ngDevMode) {
24308 attachDebugGetter(opCodes.create, i18nMutateOpCodesToString);
24309 attachDebugGetter(opCodes.remove, i18nMutateOpCodesToString);
24310 attachDebugGetter(opCodes.update, i18nUpdateOpCodesToString);
24311 }
24312 parseNodes(wrapper.firstChild, opCodes, parentIndex, nestedIcus, tIcus, expandoStartIndex);
24313 return opCodes;
24314 }
24315 /**
24316 * Breaks pattern into strings and top level {...} blocks.
24317 * Can be used to break a message into text and ICU expressions, or to break an ICU expression into
24318 * keys and cases.
24319 * Original code from closure library, modified for Angular.
24320 *
24321 * @param pattern (sub)Pattern to be broken.
24322 *
24323 */
24324 function extractParts(pattern) {
24325 if (!pattern) {
24326 return [];
24327 }
24328 var prevPos = 0;
24329 var braceStack = [];
24330 var results = [];
24331 var braces = /[{}]/g;
24332 // lastIndex doesn't get set to 0 so we have to.
24333 braces.lastIndex = 0;
24334 var match;
24335 while (match = braces.exec(pattern)) {
24336 var pos = match.index;
24337 if (match[0] == '}') {
24338 braceStack.pop();
24339 if (braceStack.length == 0) {
24340 // End of the block.
24341 var block = pattern.substring(prevPos, pos);
24342 if (ICU_BLOCK_REGEXP.test(block)) {
24343 results.push(parseICUBlock(block));
24344 }
24345 else {
24346 results.push(block);
24347 }
24348 prevPos = pos + 1;
24349 }
24350 }
24351 else {
24352 if (braceStack.length == 0) {
24353 var substring_1 = pattern.substring(prevPos, pos);
24354 results.push(substring_1);
24355 prevPos = pos + 1;
24356 }
24357 braceStack.push('{');
24358 }
24359 }
24360 var substring = pattern.substring(prevPos);
24361 results.push(substring);
24362 return results;
24363 }
24364 /**
24365 * Parses a node, its children and its siblings, and generates the mutate & update OpCodes.
24366 *
24367 * @param currentNode The first node to parse
24368 * @param icuCase The data for the ICU expression case that contains those nodes
24369 * @param parentIndex Index of the current node's parent
24370 * @param nestedIcus Data for the nested ICU expressions that this case contains
24371 * @param tIcus Data for all ICU expressions of the current message
24372 * @param expandoStartIndex Expando start index for the current ICU expression
24373 */
24374 function parseNodes(currentNode, icuCase, parentIndex, nestedIcus, tIcus, expandoStartIndex) {
24375 if (currentNode) {
24376 var nestedIcusToCreate = [];
24377 while (currentNode) {
24378 var nextNode = currentNode.nextSibling;
24379 var newIndex = expandoStartIndex + ++icuCase.vars;
24380 switch (currentNode.nodeType) {
24381 case Node.ELEMENT_NODE:
24382 var element = currentNode;
24383 var tagName = element.tagName.toLowerCase();
24384 if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
24385 // This isn't a valid element, we won't create an element for it
24386 icuCase.vars--;
24387 }
24388 else {
24389 icuCase.create.push(ELEMENT_MARKER, tagName, newIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
24390 var elAttrs = element.attributes;
24391 for (var i = 0; i < elAttrs.length; i++) {
24392 var attr = elAttrs.item(i);
24393 var lowerAttrName = attr.name.toLowerCase();
24394 var hasBinding_1 = !!attr.value.match(BINDING_REGEXP);
24395 // we assume the input string is safe, unless it's using a binding
24396 if (hasBinding_1) {
24397 if (VALID_ATTRS.hasOwnProperty(lowerAttrName)) {
24398 if (URI_ATTRS[lowerAttrName]) {
24399 addAllToArray(generateBindingUpdateOpCodes(attr.value, newIndex, attr.name, _sanitizeUrl), icuCase.update);
24400 }
24401 else if (SRCSET_ATTRS[lowerAttrName]) {
24402 addAllToArray(generateBindingUpdateOpCodes(attr.value, newIndex, attr.name, sanitizeSrcset), icuCase.update);
24403 }
24404 else {
24405 addAllToArray(generateBindingUpdateOpCodes(attr.value, newIndex, attr.name), icuCase.update);
24406 }
24407 }
24408 else {
24409 ngDevMode &&
24410 console.warn("WARNING: ignoring unsafe attribute value " + lowerAttrName + " on element " + tagName + " (see http://g.co/ng/security#xss)");
24411 }
24412 }
24413 else {
24414 icuCase.create.push(newIndex << 3 /* SHIFT_REF */ | 4 /* Attr */, attr.name, attr.value);
24415 }
24416 }
24417 // Parse the children of this node (if any)
24418 parseNodes(currentNode.firstChild, icuCase, newIndex, nestedIcus, tIcus, expandoStartIndex);
24419 // Remove the parent node after the children
24420 icuCase.remove.push(newIndex << 3 /* SHIFT_REF */ | 3 /* Remove */);
24421 }
24422 break;
24423 case Node.TEXT_NODE:
24424 var value = currentNode.textContent || '';
24425 var hasBinding = value.match(BINDING_REGEXP);
24426 icuCase.create.push(hasBinding ? '' : value, newIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
24427 icuCase.remove.push(newIndex << 3 /* SHIFT_REF */ | 3 /* Remove */);
24428 if (hasBinding) {
24429 addAllToArray(generateBindingUpdateOpCodes(value, newIndex), icuCase.update);
24430 }
24431 break;
24432 case Node.COMMENT_NODE:
24433 // Check if the comment node is a placeholder for a nested ICU
24434 var match = NESTED_ICU.exec(currentNode.textContent || '');
24435 if (match) {
24436 var nestedIcuIndex = parseInt(match[1], 10);
24437 var newLocal = ngDevMode ? "nested ICU " + nestedIcuIndex : '';
24438 // Create the comment node that will anchor the ICU expression
24439 icuCase.create.push(COMMENT_MARKER, newLocal, newIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
24440 var nestedIcu = nestedIcus[nestedIcuIndex];
24441 nestedIcusToCreate.push([nestedIcu, newIndex]);
24442 }
24443 else {
24444 // We do not handle any other type of comment
24445 icuCase.vars--;
24446 }
24447 break;
24448 default:
24449 // We do not handle any other type of element
24450 icuCase.vars--;
24451 }
24452 currentNode = nextNode;
24453 }
24454 for (var i = 0; i < nestedIcusToCreate.length; i++) {
24455 var nestedIcu = nestedIcusToCreate[i][0];
24456 var nestedIcuNodeIndex = nestedIcusToCreate[i][1];
24457 icuStart(tIcus, nestedIcu, nestedIcuNodeIndex, expandoStartIndex + icuCase.vars);
24458 // Since this is recursive, the last TIcu that was pushed is the one we want
24459 var nestTIcuIndex = tIcus.length - 1;
24460 icuCase.vars += Math.max.apply(Math, __spread(tIcus[nestTIcuIndex].vars));
24461 icuCase.childIcus.push(nestTIcuIndex);
24462 var mask = getBindingMask(nestedIcu);
24463 icuCase.update.push(toMaskBit(nestedIcu.mainBinding), // mask of the main binding
24464 3, // skip 3 opCodes if not changed
24465 -1 - nestedIcu.mainBinding, nestedIcuNodeIndex << 2 /* SHIFT_REF */ | 2 /* IcuSwitch */,
24466 // FIXME(misko): Index should be part of the opcode
24467 nestTIcuIndex, mask, // mask of all the bindings of this ICU expression
24468 2, // skip 2 opCodes if not changed
24469 nestedIcuNodeIndex << 2 /* SHIFT_REF */ | 3 /* IcuUpdate */, nestTIcuIndex);
24470 icuCase.remove.push(nestTIcuIndex << 3 /* SHIFT_REF */ | 6 /* RemoveNestedIcu */,
24471 // FIXME(misko): Index should be part of the opcode
24472 nestedIcuNodeIndex << 3 /* SHIFT_REF */ | 3 /* Remove */);
24473 }
24474 }
24475 }
24476
24477 /**
24478 * @license
24479 * Copyright Google LLC All Rights Reserved.
24480 *
24481 * Use of this source code is governed by an MIT-style license that can be
24482 * found in the LICENSE file at https://angular.io/license
24483 */
24484 // i18nPostprocess consts
24485 var ROOT_TEMPLATE_ID = 0;
24486 var PP_MULTI_VALUE_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]/;
24487 var PP_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]|(�\/?\*\d+:\d+�)/g;
24488 var PP_ICU_VARS_REGEXP = /({\s*)(VAR_(PLURAL|SELECT)(_\d+)?)(\s*,)/g;
24489 var PP_ICU_PLACEHOLDERS_REGEXP = /{([A-Z0-9_]+)}/g;
24490 var PP_ICUS_REGEXP = /�I18N_EXP_(ICU(_\d+)?)�/g;
24491 var PP_CLOSE_TEMPLATE_REGEXP = /\/\*/;
24492 var PP_TEMPLATE_ID_REGEXP = /\d+\:(\d+)/;
24493 /**
24494 * Handles message string post-processing for internationalization.
24495 *
24496 * Handles message string post-processing by transforming it from intermediate
24497 * format (that might contain some markers that we need to replace) to the final
24498 * form, consumable by i18nStart instruction. Post processing steps include:
24499 *
24500 * 1. Resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
24501 * 2. Replace all ICU vars (like "VAR_PLURAL")
24502 * 3. Replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
24503 * 4. Replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
24504 * in case multiple ICUs have the same placeholder name
24505 *
24506 * @param message Raw translation string for post processing
24507 * @param replacements Set of replacements that should be applied
24508 *
24509 * @returns Transformed string that can be consumed by i18nStart instruction
24510 *
24511 * @codeGenApi
24512 */
24513 function i18nPostprocess(message, replacements) {
24514 if (replacements === void 0) { replacements = {}; }
24515 /**
24516 * Step 1: resolve all multi-value placeholders like [�#5�|�*1:1��#2:1�|�#4:1�]
24517 *
24518 * Note: due to the way we process nested templates (BFS), multi-value placeholders are typically
24519 * grouped by templates, for example: [�#5�|�#6�|�#1:1�|�#3:2�] where �#5� and �#6� belong to root
24520 * template, �#1:1� belong to nested template with index 1 and �#1:2� - nested template with index
24521 * 3. However in real templates the order might be different: i.e. �#1:1� and/or �#3:2� may go in
24522 * front of �#6�. The post processing step restores the right order by keeping track of the
24523 * template id stack and looks for placeholders that belong to the currently active template.
24524 */
24525 var result = message;
24526 if (PP_MULTI_VALUE_PLACEHOLDERS_REGEXP.test(message)) {
24527 var matches_1 = {};
24528 var templateIdsStack_1 = [ROOT_TEMPLATE_ID];
24529 result = result.replace(PP_PLACEHOLDERS_REGEXP, function (m, phs, tmpl) {
24530 var content = phs || tmpl;
24531 var placeholders = matches_1[content] || [];
24532 if (!placeholders.length) {
24533 content.split('|').forEach(function (placeholder) {
24534 var match = placeholder.match(PP_TEMPLATE_ID_REGEXP);
24535 var templateId = match ? parseInt(match[1], 10) : ROOT_TEMPLATE_ID;
24536 var isCloseTemplateTag = PP_CLOSE_TEMPLATE_REGEXP.test(placeholder);
24537 placeholders.push([templateId, isCloseTemplateTag, placeholder]);
24538 });
24539 matches_1[content] = placeholders;
24540 }
24541 if (!placeholders.length) {
24542 throw new Error("i18n postprocess: unmatched placeholder - " + content);
24543 }
24544 var currentTemplateId = templateIdsStack_1[templateIdsStack_1.length - 1];
24545 var idx = 0;
24546 // find placeholder index that matches current template id
24547 for (var i = 0; i < placeholders.length; i++) {
24548 if (placeholders[i][0] === currentTemplateId) {
24549 idx = i;
24550 break;
24551 }
24552 }
24553 // update template id stack based on the current tag extracted
24554 var _a = __read(placeholders[idx], 3), templateId = _a[0], isCloseTemplateTag = _a[1], placeholder = _a[2];
24555 if (isCloseTemplateTag) {
24556 templateIdsStack_1.pop();
24557 }
24558 else if (currentTemplateId !== templateId) {
24559 templateIdsStack_1.push(templateId);
24560 }
24561 // remove processed tag from the list
24562 placeholders.splice(idx, 1);
24563 return placeholder;
24564 });
24565 }
24566 // return current result if no replacements specified
24567 if (!Object.keys(replacements).length) {
24568 return result;
24569 }
24570 /**
24571 * Step 2: replace all ICU vars (like "VAR_PLURAL")
24572 */
24573 result = result.replace(PP_ICU_VARS_REGEXP, function (match, start, key, _type, _idx, end) {
24574 return replacements.hasOwnProperty(key) ? "" + start + replacements[key] + end : match;
24575 });
24576 /**
24577 * Step 3: replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
24578 */
24579 result = result.replace(PP_ICU_PLACEHOLDERS_REGEXP, function (match, key) {
24580 return replacements.hasOwnProperty(key) ? replacements[key] : match;
24581 });
24582 /**
24583 * Step 4: replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�) in case
24584 * multiple ICUs have the same placeholder name
24585 */
24586 result = result.replace(PP_ICUS_REGEXP, function (match, key) {
24587 if (replacements.hasOwnProperty(key)) {
24588 var list = replacements[key];
24589 if (!list.length) {
24590 throw new Error("i18n postprocess: unmatched ICU - " + match + " with key: " + key);
24591 }
24592 return list.shift();
24593 }
24594 return match;
24595 });
24596 return result;
24597 }
24598
24599 /**
24600 * @license
24601 * Copyright Google LLC All Rights Reserved.
24602 *
24603 * Use of this source code is governed by an MIT-style license that can be
24604 * found in the LICENSE file at https://angular.io/license
24605 */
24606 /**
24607 * Marks a block of text as translatable.
24608 *
24609 * The instructions `i18nStart` and `i18nEnd` mark the translation block in the template.
24610 * The translation `message` is the value which is locale specific. The translation string may
24611 * contain placeholders which associate inner elements and sub-templates within the translation.
24612 *
24613 * The translation `message` placeholders are:
24614 * - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
24615 * interpolated into. The placeholder `index` points to the expression binding index. An optional
24616 * `block` that matches the sub-template in which it was declared.
24617 * - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*: Marks the beginning
24618 * and end of DOM element that were embedded in the original translation block. The placeholder
24619 * `index` points to the element index in the template instructions set. An optional `block` that
24620 * matches the sub-template in which it was declared.
24621 * - `�!{index}(:{block})�`/`�/!{index}(:{block})�`: *Projection Placeholder*: Marks the
24622 * beginning and end of <ng-content> that was embedded in the original translation block.
24623 * The placeholder `index` points to the element index in the template instructions set.
24624 * An optional `block` that matches the sub-template in which it was declared.
24625 * - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
24626 * split up and translated separately in each angular template function. The `index` points to the
24627 * `template` instruction index. A `block` that matches the sub-template in which it was declared.
24628 *
24629 * @param index A unique index of the translation in the static block.
24630 * @param message The translation message.
24631 * @param subTemplateIndex Optional sub-template index in the `message`.
24632 *
24633 * @codeGenApi
24634 */
24635 function ɵɵi18nStart(index, message, subTemplateIndex) {
24636 var tView = getTView();
24637 ngDevMode && assertDefined(tView, "tView should be defined");
24638 pushI18nIndex(index);
24639 // We need to delay projections until `i18nEnd`
24640 setDelayProjection(true);
24641 if (tView.firstCreatePass && tView.data[index + HEADER_OFFSET] === null) {
24642 i18nStartFirstPass(getLView(), tView, index, message, subTemplateIndex);
24643 }
24644 }
24645 /**
24646 * Translates a translation block marked by `i18nStart` and `i18nEnd`. It inserts the text/ICU nodes
24647 * into the render tree, moves the placeholder nodes and removes the deleted nodes.
24648 *
24649 * @codeGenApi
24650 */
24651 function ɵɵi18nEnd() {
24652 var lView = getLView();
24653 var tView = getTView();
24654 ngDevMode && assertDefined(tView, "tView should be defined");
24655 i18nEndFirstPass(tView, lView);
24656 // Stop delaying projections
24657 setDelayProjection(false);
24658 }
24659 /**
24660 *
24661 * Use this instruction to create a translation block that doesn't contain any placeholder.
24662 * It calls both {@link i18nStart} and {@link i18nEnd} in one instruction.
24663 *
24664 * The translation `message` is the value which is locale specific. The translation string may
24665 * contain placeholders which associate inner elements and sub-templates within the translation.
24666 *
24667 * The translation `message` placeholders are:
24668 * - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
24669 * interpolated into. The placeholder `index` points to the expression binding index. An optional
24670 * `block` that matches the sub-template in which it was declared.
24671 * - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*: Marks the beginning
24672 * and end of DOM element that were embedded in the original translation block. The placeholder
24673 * `index` points to the element index in the template instructions set. An optional `block` that
24674 * matches the sub-template in which it was declared.
24675 * - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
24676 * split up and translated separately in each angular template function. The `index` points to the
24677 * `template` instruction index. A `block` that matches the sub-template in which it was declared.
24678 *
24679 * @param index A unique index of the translation in the static block.
24680 * @param message The translation message.
24681 * @param subTemplateIndex Optional sub-template index in the `message`.
24682 *
24683 * @codeGenApi
24684 */
24685 function ɵɵi18n(index, message, subTemplateIndex) {
24686 ɵɵi18nStart(index, message, subTemplateIndex);
24687 ɵɵi18nEnd();
24688 }
24689 /**
24690 * Marks a list of attributes as translatable.
24691 *
24692 * @param index A unique index in the static block
24693 * @param values
24694 *
24695 * @codeGenApi
24696 */
24697 function ɵɵi18nAttributes(index, values) {
24698 var lView = getLView();
24699 var tView = getTView();
24700 ngDevMode && assertDefined(tView, "tView should be defined");
24701 i18nAttributesFirstPass(lView, tView, index, values);
24702 }
24703 /**
24704 * Stores the values of the bindings during each update cycle in order to determine if we need to
24705 * update the translated nodes.
24706 *
24707 * @param value The binding's value
24708 * @returns This function returns itself so that it may be chained
24709 * (e.g. `i18nExp(ctx.name)(ctx.title)`)
24710 *
24711 * @codeGenApi
24712 */
24713 function ɵɵi18nExp(value) {
24714 var lView = getLView();
24715 setMaskBit(bindingUpdated(lView, nextBindingIndex(), value));
24716 return ɵɵi18nExp;
24717 }
24718 /**
24719 * Updates a translation block or an i18n attribute when the bindings have changed.
24720 *
24721 * @param index Index of either {@link i18nStart} (translation block) or {@link i18nAttributes}
24722 * (i18n attribute) on which it should update the content.
24723 *
24724 * @codeGenApi
24725 */
24726 function ɵɵi18nApply(index) {
24727 applyI18n(getTView(), getLView(), index);
24728 }
24729 /**
24730 * Handles message string post-processing for internationalization.
24731 *
24732 * Handles message string post-processing by transforming it from intermediate
24733 * format (that might contain some markers that we need to replace) to the final
24734 * form, consumable by i18nStart instruction. Post processing steps include:
24735 *
24736 * 1. Resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
24737 * 2. Replace all ICU vars (like "VAR_PLURAL")
24738 * 3. Replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
24739 * 4. Replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
24740 * in case multiple ICUs have the same placeholder name
24741 *
24742 * @param message Raw translation string for post processing
24743 * @param replacements Set of replacements that should be applied
24744 *
24745 * @returns Transformed string that can be consumed by i18nStart instruction
24746 *
24747 * @codeGenApi
24748 */
24749 function ɵɵi18nPostprocess(message, replacements) {
24750 if (replacements === void 0) { replacements = {}; }
24751 return i18nPostprocess(message, replacements);
24752 }
24753
24754 /**
24755 * Adds decorator, constructor, and property metadata to a given type via static metadata fields
24756 * on the type.
24757 *
24758 * These metadata fields can later be read with Angular's `ReflectionCapabilities` API.
24759 *
24760 * Calls to `setClassMetadata` can be marked as pure, resulting in the metadata assignments being
24761 * tree-shaken away during production builds.
24762 */
24763 function setClassMetadata(type, decorators, ctorParameters, propDecorators) {
24764 return noSideEffects(function () {
24765 var _a;
24766 var clazz = type;
24767 // We determine whether a class has its own metadata by taking the metadata from the
24768 // parent constructor and checking whether it's the same as the subclass metadata below.
24769 // We can't use `hasOwnProperty` here because it doesn't work correctly in IE10 for
24770 // static fields that are defined by TS. See
24771 // https://github.com/angular/angular/pull/28439#issuecomment-459349218.
24772 var parentPrototype = clazz.prototype ? Object.getPrototypeOf(clazz.prototype) : null;
24773 var parentConstructor = parentPrototype && parentPrototype.constructor;
24774 if (decorators !== null) {
24775 if (clazz.decorators !== undefined &&
24776 (!parentConstructor || parentConstructor.decorators !== clazz.decorators)) {
24777 (_a = clazz.decorators).push.apply(_a, __spread(decorators));
24778 }
24779 else {
24780 clazz.decorators = decorators;
24781 }
24782 }
24783 if (ctorParameters !== null) {
24784 // Rather than merging, clobber the existing parameters. If other projects exist which
24785 // use tsickle-style annotations and reflect over them in the same way, this could
24786 // cause issues, but that is vanishingly unlikely.
24787 clazz.ctorParameters = ctorParameters;
24788 }
24789 if (propDecorators !== null) {
24790 // The property decorator objects are merged as it is possible different fields have
24791 // different decorator types. Decorators on individual fields are not merged, as it's
24792 // also incredibly unlikely that a field will be decorated both with an Angular
24793 // decorator and a non-Angular decorator that's also been downleveled.
24794 if (clazz.propDecorators !== undefined &&
24795 (!parentConstructor ||
24796 parentConstructor.propDecorators !== clazz.propDecorators)) {
24797 clazz.propDecorators = Object.assign(Object.assign({}, clazz.propDecorators), propDecorators);
24798 }
24799 else {
24800 clazz.propDecorators = propDecorators;
24801 }
24802 }
24803 });
24804 }
24805
24806 /**
24807 * @license
24808 * Copyright Google LLC All Rights Reserved.
24809 *
24810 * Use of this source code is governed by an MIT-style license that can be
24811 * found in the LICENSE file at https://angular.io/license
24812 */
24813 /**
24814 * Map of module-id to the corresponding NgModule.
24815 * - In pre Ivy we track NgModuleFactory,
24816 * - In post Ivy we track the NgModuleType
24817 */
24818 var modules = new Map();
24819 /**
24820 * Registers a loaded module. Should only be called from generated NgModuleFactory code.
24821 * @publicApi
24822 */
24823 function registerModuleFactory(id, factory) {
24824 var existing = modules.get(id);
24825 assertSameOrNotExisting(id, existing && existing.moduleType, factory.moduleType);
24826 modules.set(id, factory);
24827 }
24828 function assertSameOrNotExisting(id, type, incoming) {
24829 if (type && type !== incoming) {
24830 throw new Error("Duplicate module registered for " + id + " - " + stringify(type) + " vs " + stringify(type.name));
24831 }
24832 }
24833 function registerNgModuleType(ngModuleType) {
24834 if (ngModuleType.ɵmod.id !== null) {
24835 var id = ngModuleType.ɵmod.id;
24836 var existing = modules.get(id);
24837 assertSameOrNotExisting(id, existing, ngModuleType);
24838 modules.set(id, ngModuleType);
24839 }
24840 var imports = ngModuleType.ɵmod.imports;
24841 if (imports instanceof Function) {
24842 imports = imports();
24843 }
24844 if (imports) {
24845 imports.forEach(function (i) { return registerNgModuleType(i); });
24846 }
24847 }
24848 function clearModulesForTest() {
24849 modules.clear();
24850 }
24851 function getRegisteredNgModuleType(id) {
24852 return modules.get(id) || autoRegisterModuleById[id];
24853 }
24854
24855 var NgModuleRef$1 = /** @class */ (function (_super) {
24856 __extends(NgModuleRef$1, _super);
24857 function NgModuleRef$1(ngModuleType, _parent) {
24858 var _this = _super.call(this) || this;
24859 _this._parent = _parent;
24860 // tslint:disable-next-line:require-internal-with-underscore
24861 _this._bootstrapComponents = [];
24862 _this.injector = _this;
24863 _this.destroyCbs = [];
24864 // When bootstrapping a module we have a dependency graph that looks like this:
24865 // ApplicationRef -> ComponentFactoryResolver -> NgModuleRef. The problem is that if the
24866 // module being resolved tries to inject the ComponentFactoryResolver, it'll create a
24867 // circular dependency which will result in a runtime error, because the injector doesn't
24868 // exist yet. We work around the issue by creating the ComponentFactoryResolver ourselves
24869 // and providing it, rather than letting the injector resolve it.
24870 _this.componentFactoryResolver = new ComponentFactoryResolver$1(_this);
24871 var ngModuleDef = getNgModuleDef(ngModuleType);
24872 ngDevMode &&
24873 assertDefined(ngModuleDef, "NgModule '" + stringify(ngModuleType) + "' is not a subtype of 'NgModuleType'.");
24874 var ngLocaleIdDef = getNgLocaleIdDef(ngModuleType);
24875 ngLocaleIdDef && setLocaleId(ngLocaleIdDef);
24876 _this._bootstrapComponents = maybeUnwrapFn(ngModuleDef.bootstrap);
24877 _this._r3Injector = createInjectorWithoutInjectorInstances(ngModuleType, _parent, [
24878 { provide: NgModuleRef, useValue: _this }, {
24879 provide: ComponentFactoryResolver,
24880 useValue: _this.componentFactoryResolver
24881 }
24882 ], stringify(ngModuleType));
24883 // We need to resolve the injector types separately from the injector creation, because
24884 // the module might be trying to use this ref in its contructor for DI which will cause a
24885 // circular error that will eventually error out, because the injector isn't created yet.
24886 _this._r3Injector._resolveInjectorDefTypes();
24887 _this.instance = _this.get(ngModuleType);
24888 return _this;
24889 }
24890 NgModuleRef$1.prototype.get = function (token, notFoundValue, injectFlags) {
24891 if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
24892 if (injectFlags === void 0) { injectFlags = exports.InjectFlags.Default; }
24893 if (token === Injector || token === NgModuleRef || token === INJECTOR) {
24894 return this;
24895 }
24896 return this._r3Injector.get(token, notFoundValue, injectFlags);
24897 };
24898 NgModuleRef$1.prototype.destroy = function () {
24899 ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
24900 var injector = this._r3Injector;
24901 !injector.destroyed && injector.destroy();
24902 this.destroyCbs.forEach(function (fn) { return fn(); });
24903 this.destroyCbs = null;
24904 };
24905 NgModuleRef$1.prototype.onDestroy = function (callback) {
24906 ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
24907 this.destroyCbs.push(callback);
24908 };
24909 return NgModuleRef$1;
24910 }(NgModuleRef));
24911 var NgModuleFactory$1 = /** @class */ (function (_super) {
24912 __extends(NgModuleFactory, _super);
24913 function NgModuleFactory(moduleType) {
24914 var _this = _super.call(this) || this;
24915 _this.moduleType = moduleType;
24916 var ngModuleDef = getNgModuleDef(moduleType);
24917 if (ngModuleDef !== null) {
24918 // Register the NgModule with Angular's module registry. The location (and hence timing) of
24919 // this call is critical to ensure this works correctly (modules get registered when expected)
24920 // without bloating bundles (modules are registered when otherwise not referenced).
24921 //
24922 // In View Engine, registration occurs in the .ngfactory.js file as a side effect. This has
24923 // several practical consequences:
24924 //
24925 // - If an .ngfactory file is not imported from, the module won't be registered (and can be
24926 // tree shaken).
24927 // - If an .ngfactory file is imported from, the module will be registered even if an instance
24928 // is not actually created (via `create` below).
24929 // - Since an .ngfactory file in View Engine references the .ngfactory files of the NgModule's
24930 // imports,
24931 //
24932 // In Ivy, things are a bit different. .ngfactory files still exist for compatibility, but are
24933 // not a required API to use - there are other ways to obtain an NgModuleFactory for a given
24934 // NgModule. Thus, relying on a side effect in the .ngfactory file is not sufficient. Instead,
24935 // the side effect of registration is added here, in the constructor of NgModuleFactory,
24936 // ensuring no matter how a factory is created, the module is registered correctly.
24937 //
24938 // An alternative would be to include the registration side effect inline following the actual
24939 // NgModule definition. This also has the correct timing, but breaks tree-shaking - modules
24940 // will be registered and retained even if they're otherwise never referenced.
24941 registerNgModuleType(moduleType);
24942 }
24943 return _this;
24944 }
24945 NgModuleFactory.prototype.create = function (parentInjector) {
24946 return new NgModuleRef$1(this.moduleType, parentInjector);
24947 };
24948 return NgModuleFactory;
24949 }(NgModuleFactory));
24950
24951 /**
24952 * @license
24953 * Copyright Google LLC All Rights Reserved.
24954 *
24955 * Use of this source code is governed by an MIT-style license that can be
24956 * found in the LICENSE file at https://angular.io/license
24957 */
24958 /**
24959 * Bindings for pure functions are stored after regular bindings.
24960 *
24961 * |-------decls------|---------vars---------| |----- hostVars (dir1) ------|
24962 * ------------------------------------------------------------------------------------------
24963 * | nodes/refs/pipes | bindings | fn slots | injector | dir1 | host bindings | host slots |
24964 * ------------------------------------------------------------------------------------------
24965 * ^ ^
24966 * TView.bindingStartIndex TView.expandoStartIndex
24967 *
24968 * Pure function instructions are given an offset from the binding root. Adding the offset to the
24969 * binding root gives the first index where the bindings are stored. In component views, the binding
24970 * root is the bindingStartIndex. In host bindings, the binding root is the expandoStartIndex +
24971 * any directive instances + any hostVars in directives evaluated before it.
24972 *
24973 * See VIEW_DATA.md for more information about host binding resolution.
24974 */
24975 /**
24976 * If the value hasn't been saved, calls the pure function to store and return the
24977 * value. If it has been saved, returns the saved value.
24978 *
24979 * @param slotOffset the offset from binding root to the reserved slot
24980 * @param pureFn Function that returns a value
24981 * @param thisArg Optional calling context of pureFn
24982 * @returns value
24983 *
24984 * @codeGenApi
24985 */
24986 function ɵɵpureFunction0(slotOffset, pureFn, thisArg) {
24987 var bindingIndex = getBindingRoot() + slotOffset;
24988 var lView = getLView();
24989 return lView[bindingIndex] === NO_CHANGE ?
24990 updateBinding(lView, bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) :
24991 getBinding(lView, bindingIndex);
24992 }
24993 /**
24994 * If the value of the provided exp has changed, calls the pure function to return
24995 * an updated value. Or if the value has not changed, returns cached value.
24996 *
24997 * @param slotOffset the offset from binding root to the reserved slot
24998 * @param pureFn Function that returns an updated value
24999 * @param exp Updated expression value
25000 * @param thisArg Optional calling context of pureFn
25001 * @returns Updated or cached value
25002 *
25003 * @codeGenApi
25004 */
25005 function ɵɵpureFunction1(slotOffset, pureFn, exp, thisArg) {
25006 return pureFunction1Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp, thisArg);
25007 }
25008 /**
25009 * If the value of any provided exp has changed, calls the pure function to return
25010 * an updated value. Or if no values have changed, returns cached value.
25011 *
25012 * @param slotOffset the offset from binding root to the reserved slot
25013 * @param pureFn
25014 * @param exp1
25015 * @param exp2
25016 * @param thisArg Optional calling context of pureFn
25017 * @returns Updated or cached value
25018 *
25019 * @codeGenApi
25020 */
25021 function ɵɵpureFunction2(slotOffset, pureFn, exp1, exp2, thisArg) {
25022 return pureFunction2Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, thisArg);
25023 }
25024 /**
25025 * If the value of any provided exp has changed, calls the pure function to return
25026 * an updated value. Or if no values have changed, returns cached value.
25027 *
25028 * @param slotOffset the offset from binding root to the reserved slot
25029 * @param pureFn
25030 * @param exp1
25031 * @param exp2
25032 * @param exp3
25033 * @param thisArg Optional calling context of pureFn
25034 * @returns Updated or cached value
25035 *
25036 * @codeGenApi
25037 */
25038 function ɵɵpureFunction3(slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
25039 return pureFunction3Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, thisArg);
25040 }
25041 /**
25042 * If the value of any provided exp has changed, calls the pure function to return
25043 * an updated value. Or if no values have changed, returns cached value.
25044 *
25045 * @param slotOffset the offset from binding root to the reserved slot
25046 * @param pureFn
25047 * @param exp1
25048 * @param exp2
25049 * @param exp3
25050 * @param exp4
25051 * @param thisArg Optional calling context of pureFn
25052 * @returns Updated or cached value
25053 *
25054 * @codeGenApi
25055 */
25056 function ɵɵpureFunction4(slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
25057 return pureFunction4Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg);
25058 }
25059 /**
25060 * If the value of any provided exp has changed, calls the pure function to return
25061 * an updated value. Or if no values have changed, returns cached value.
25062 *
25063 * @param slotOffset the offset from binding root to the reserved slot
25064 * @param pureFn
25065 * @param exp1
25066 * @param exp2
25067 * @param exp3
25068 * @param exp4
25069 * @param exp5
25070 * @param thisArg Optional calling context of pureFn
25071 * @returns Updated or cached value
25072 *
25073 * @codeGenApi
25074 */
25075 function ɵɵpureFunction5(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, thisArg) {
25076 var bindingIndex = getBindingRoot() + slotOffset;
25077 var lView = getLView();
25078 var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
25079 return bindingUpdated(lView, bindingIndex + 4, exp5) || different ?
25080 updateBinding(lView, bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) :
25081 pureFn(exp1, exp2, exp3, exp4, exp5)) :
25082 getBinding(lView, bindingIndex + 5);
25083 }
25084 /**
25085 * If the value of any provided exp has changed, calls the pure function to return
25086 * an updated value. Or if no values have changed, returns cached value.
25087 *
25088 * @param slotOffset the offset from binding root to the reserved slot
25089 * @param pureFn
25090 * @param exp1
25091 * @param exp2
25092 * @param exp3
25093 * @param exp4
25094 * @param exp5
25095 * @param exp6
25096 * @param thisArg Optional calling context of pureFn
25097 * @returns Updated or cached value
25098 *
25099 * @codeGenApi
25100 */
25101 function ɵɵpureFunction6(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, thisArg) {
25102 var bindingIndex = getBindingRoot() + slotOffset;
25103 var lView = getLView();
25104 var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
25105 return bindingUpdated2(lView, bindingIndex + 4, exp5, exp6) || different ?
25106 updateBinding(lView, bindingIndex + 6, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) :
25107 pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) :
25108 getBinding(lView, bindingIndex + 6);
25109 }
25110 /**
25111 * If the value of any provided exp has changed, calls the pure function to return
25112 * an updated value. Or if no values have changed, returns cached value.
25113 *
25114 * @param slotOffset the offset from binding root to the reserved slot
25115 * @param pureFn
25116 * @param exp1
25117 * @param exp2
25118 * @param exp3
25119 * @param exp4
25120 * @param exp5
25121 * @param exp6
25122 * @param exp7
25123 * @param thisArg Optional calling context of pureFn
25124 * @returns Updated or cached value
25125 *
25126 * @codeGenApi
25127 */
25128 function ɵɵpureFunction7(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, thisArg) {
25129 var bindingIndex = getBindingRoot() + slotOffset;
25130 var lView = getLView();
25131 var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
25132 return bindingUpdated3(lView, bindingIndex + 4, exp5, exp6, exp7) || different ?
25133 updateBinding(lView, bindingIndex + 7, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7) :
25134 pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7)) :
25135 getBinding(lView, bindingIndex + 7);
25136 }
25137 /**
25138 * If the value of any provided exp has changed, calls the pure function to return
25139 * an updated value. Or if no values have changed, returns cached value.
25140 *
25141 * @param slotOffset the offset from binding root to the reserved slot
25142 * @param pureFn
25143 * @param exp1
25144 * @param exp2
25145 * @param exp3
25146 * @param exp4
25147 * @param exp5
25148 * @param exp6
25149 * @param exp7
25150 * @param exp8
25151 * @param thisArg Optional calling context of pureFn
25152 * @returns Updated or cached value
25153 *
25154 * @codeGenApi
25155 */
25156 function ɵɵpureFunction8(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, thisArg) {
25157 var bindingIndex = getBindingRoot() + slotOffset;
25158 var lView = getLView();
25159 var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
25160 return bindingUpdated4(lView, bindingIndex + 4, exp5, exp6, exp7, exp8) || different ?
25161 updateBinding(lView, bindingIndex + 8, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8) :
25162 pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8)) :
25163 getBinding(lView, bindingIndex + 8);
25164 }
25165 /**
25166 * pureFunction instruction that can support any number of bindings.
25167 *
25168 * If the value of any provided exp has changed, calls the pure function to return
25169 * an updated value. Or if no values have changed, returns cached value.
25170 *
25171 * @param slotOffset the offset from binding root to the reserved slot
25172 * @param pureFn A pure function that takes binding values and builds an object or array
25173 * containing those values.
25174 * @param exps An array of binding values
25175 * @param thisArg Optional calling context of pureFn
25176 * @returns Updated or cached value
25177 *
25178 * @codeGenApi
25179 */
25180 function ɵɵpureFunctionV(slotOffset, pureFn, exps, thisArg) {
25181 return pureFunctionVInternal(getLView(), getBindingRoot(), slotOffset, pureFn, exps, thisArg);
25182 }
25183 /**
25184 * Results of a pure function invocation are stored in LView in a dedicated slot that is initialized
25185 * to NO_CHANGE. In rare situations a pure pipe might throw an exception on the very first
25186 * invocation and not produce any valid results. In this case LView would keep holding the NO_CHANGE
25187 * value. The NO_CHANGE is not something that we can use in expressions / bindings thus we convert
25188 * it to `undefined`.
25189 */
25190 function getPureFunctionReturnValue(lView, returnValueIndex) {
25191 ngDevMode && assertIndexInRange(lView, returnValueIndex);
25192 var lastReturnValue = lView[returnValueIndex];
25193 return lastReturnValue === NO_CHANGE ? undefined : lastReturnValue;
25194 }
25195 /**
25196 * If the value of the provided exp has changed, calls the pure function to return
25197 * an updated value. Or if the value has not changed, returns cached value.
25198 *
25199 * @param lView LView in which the function is being executed.
25200 * @param bindingRoot Binding root index.
25201 * @param slotOffset the offset from binding root to the reserved slot
25202 * @param pureFn Function that returns an updated value
25203 * @param exp Updated expression value
25204 * @param thisArg Optional calling context of pureFn
25205 * @returns Updated or cached value
25206 */
25207 function pureFunction1Internal(lView, bindingRoot, slotOffset, pureFn, exp, thisArg) {
25208 var bindingIndex = bindingRoot + slotOffset;
25209 return bindingUpdated(lView, bindingIndex, exp) ?
25210 updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
25211 getPureFunctionReturnValue(lView, bindingIndex + 1);
25212 }
25213 /**
25214 * If the value of any provided exp has changed, calls the pure function to return
25215 * an updated value. Or if no values have changed, returns cached value.
25216 *
25217 * @param lView LView in which the function is being executed.
25218 * @param bindingRoot Binding root index.
25219 * @param slotOffset the offset from binding root to the reserved slot
25220 * @param pureFn
25221 * @param exp1
25222 * @param exp2
25223 * @param thisArg Optional calling context of pureFn
25224 * @returns Updated or cached value
25225 */
25226 function pureFunction2Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, thisArg) {
25227 var bindingIndex = bindingRoot + slotOffset;
25228 return bindingUpdated2(lView, bindingIndex, exp1, exp2) ?
25229 updateBinding(lView, bindingIndex + 2, thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) :
25230 getPureFunctionReturnValue(lView, bindingIndex + 2);
25231 }
25232 /**
25233 * If the value of any provided exp has changed, calls the pure function to return
25234 * an updated value. Or if no values have changed, returns cached value.
25235 *
25236 * @param lView LView in which the function is being executed.
25237 * @param bindingRoot Binding root index.
25238 * @param slotOffset the offset from binding root to the reserved slot
25239 * @param pureFn
25240 * @param exp1
25241 * @param exp2
25242 * @param exp3
25243 * @param thisArg Optional calling context of pureFn
25244 * @returns Updated or cached value
25245 */
25246 function pureFunction3Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
25247 var bindingIndex = bindingRoot + slotOffset;
25248 return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ?
25249 updateBinding(lView, bindingIndex + 3, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) :
25250 getPureFunctionReturnValue(lView, bindingIndex + 3);
25251 }
25252 /**
25253 * If the value of any provided exp has changed, calls the pure function to return
25254 * an updated value. Or if no values have changed, returns cached value.
25255 *
25256 * @param lView LView in which the function is being executed.
25257 * @param bindingRoot Binding root index.
25258 * @param slotOffset the offset from binding root to the reserved slot
25259 * @param pureFn
25260 * @param exp1
25261 * @param exp2
25262 * @param exp3
25263 * @param exp4
25264 * @param thisArg Optional calling context of pureFn
25265 * @returns Updated or cached value
25266 *
25267 */
25268 function pureFunction4Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
25269 var bindingIndex = bindingRoot + slotOffset;
25270 return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ?
25271 updateBinding(lView, bindingIndex + 4, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) :
25272 getPureFunctionReturnValue(lView, bindingIndex + 4);
25273 }
25274 /**
25275 * pureFunction instruction that can support any number of bindings.
25276 *
25277 * If the value of any provided exp has changed, calls the pure function to return
25278 * an updated value. Or if no values have changed, returns cached value.
25279 *
25280 * @param lView LView in which the function is being executed.
25281 * @param bindingRoot Binding root index.
25282 * @param slotOffset the offset from binding root to the reserved slot
25283 * @param pureFn A pure function that takes binding values and builds an object or array
25284 * containing those values.
25285 * @param exps An array of binding values
25286 * @param thisArg Optional calling context of pureFn
25287 * @returns Updated or cached value
25288 */
25289 function pureFunctionVInternal(lView, bindingRoot, slotOffset, pureFn, exps, thisArg) {
25290 var bindingIndex = bindingRoot + slotOffset;
25291 var different = false;
25292 for (var i = 0; i < exps.length; i++) {
25293 bindingUpdated(lView, bindingIndex++, exps[i]) && (different = true);
25294 }
25295 return different ? updateBinding(lView, bindingIndex, pureFn.apply(thisArg, exps)) :
25296 getPureFunctionReturnValue(lView, bindingIndex);
25297 }
25298
25299 /**
25300 * @license
25301 * Copyright Google LLC All Rights Reserved.
25302 *
25303 * Use of this source code is governed by an MIT-style license that can be
25304 * found in the LICENSE file at https://angular.io/license
25305 */
25306 /**
25307 * Create a pipe.
25308 *
25309 * @param index Pipe index where the pipe will be stored.
25310 * @param pipeName The name of the pipe
25311 * @returns T the instance of the pipe.
25312 *
25313 * @codeGenApi
25314 */
25315 function ɵɵpipe(index, pipeName) {
25316 var tView = getTView();
25317 var pipeDef;
25318 var adjustedIndex = index + HEADER_OFFSET;
25319 if (tView.firstCreatePass) {
25320 pipeDef = getPipeDef$1(pipeName, tView.pipeRegistry);
25321 tView.data[adjustedIndex] = pipeDef;
25322 if (pipeDef.onDestroy) {
25323 (tView.destroyHooks || (tView.destroyHooks = [])).push(adjustedIndex, pipeDef.onDestroy);
25324 }
25325 }
25326 else {
25327 pipeDef = tView.data[adjustedIndex];
25328 }
25329 var pipeFactory = pipeDef.factory || (pipeDef.factory = getFactoryDef(pipeDef.type, true));
25330 var previousInjectImplementation = setInjectImplementation(ɵɵdirectiveInject);
25331 // DI for pipes is supposed to behave like directives when placed on a component
25332 // host node, which means that we have to disable access to `viewProviders`.
25333 var previousIncludeViewProviders = setIncludeViewProviders(false);
25334 var pipeInstance = pipeFactory();
25335 setIncludeViewProviders(previousIncludeViewProviders);
25336 setInjectImplementation(previousInjectImplementation);
25337 store(tView, getLView(), index, pipeInstance);
25338 return pipeInstance;
25339 }
25340 /**
25341 * Searches the pipe registry for a pipe with the given name. If one is found,
25342 * returns the pipe. Otherwise, an error is thrown because the pipe cannot be resolved.
25343 *
25344 * @param name Name of pipe to resolve
25345 * @param registry Full list of available pipes
25346 * @returns Matching PipeDef
25347 */
25348 function getPipeDef$1(name, registry) {
25349 if (registry) {
25350 for (var i = registry.length - 1; i >= 0; i--) {
25351 var pipeDef = registry[i];
25352 if (name === pipeDef.name) {
25353 return pipeDef;
25354 }
25355 }
25356 }
25357 throw new Error("The pipe '" + name + "' could not be found!");
25358 }
25359 /**
25360 * Invokes a pipe with 1 arguments.
25361 *
25362 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
25363 * the pipe only when an input to the pipe changes.
25364 *
25365 * @param index Pipe index where the pipe was stored on creation.
25366 * @param slotOffset the offset in the reserved slot space
25367 * @param v1 1st argument to {@link PipeTransform#transform}.
25368 *
25369 * @codeGenApi
25370 */
25371 function ɵɵpipeBind1(index, slotOffset, v1) {
25372 var lView = getLView();
25373 var pipeInstance = load(lView, index);
25374 return unwrapValue$1(lView, isPure(lView, index) ?
25375 pureFunction1Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, pipeInstance) :
25376 pipeInstance.transform(v1));
25377 }
25378 /**
25379 * Invokes a pipe with 2 arguments.
25380 *
25381 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
25382 * the pipe only when an input to the pipe changes.
25383 *
25384 * @param index Pipe index where the pipe was stored on creation.
25385 * @param slotOffset the offset in the reserved slot space
25386 * @param v1 1st argument to {@link PipeTransform#transform}.
25387 * @param v2 2nd argument to {@link PipeTransform#transform}.
25388 *
25389 * @codeGenApi
25390 */
25391 function ɵɵpipeBind2(index, slotOffset, v1, v2) {
25392 var lView = getLView();
25393 var pipeInstance = load(lView, index);
25394 return unwrapValue$1(lView, isPure(lView, index) ?
25395 pureFunction2Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, pipeInstance) :
25396 pipeInstance.transform(v1, v2));
25397 }
25398 /**
25399 * Invokes a pipe with 3 arguments.
25400 *
25401 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
25402 * the pipe only when an input to the pipe changes.
25403 *
25404 * @param index Pipe index where the pipe was stored on creation.
25405 * @param slotOffset the offset in the reserved slot space
25406 * @param v1 1st argument to {@link PipeTransform#transform}.
25407 * @param v2 2nd argument to {@link PipeTransform#transform}.
25408 * @param v3 4rd argument to {@link PipeTransform#transform}.
25409 *
25410 * @codeGenApi
25411 */
25412 function ɵɵpipeBind3(index, slotOffset, v1, v2, v3) {
25413 var lView = getLView();
25414 var pipeInstance = load(lView, index);
25415 return unwrapValue$1(lView, isPure(lView, index) ? pureFunction3Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, v3, pipeInstance) :
25416 pipeInstance.transform(v1, v2, v3));
25417 }
25418 /**
25419 * Invokes a pipe with 4 arguments.
25420 *
25421 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
25422 * the pipe only when an input to the pipe changes.
25423 *
25424 * @param index Pipe index where the pipe was stored on creation.
25425 * @param slotOffset the offset in the reserved slot space
25426 * @param v1 1st argument to {@link PipeTransform#transform}.
25427 * @param v2 2nd argument to {@link PipeTransform#transform}.
25428 * @param v3 3rd argument to {@link PipeTransform#transform}.
25429 * @param v4 4th argument to {@link PipeTransform#transform}.
25430 *
25431 * @codeGenApi
25432 */
25433 function ɵɵpipeBind4(index, slotOffset, v1, v2, v3, v4) {
25434 var lView = getLView();
25435 var pipeInstance = load(lView, index);
25436 return unwrapValue$1(lView, isPure(lView, index) ? pureFunction4Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, v3, v4, pipeInstance) :
25437 pipeInstance.transform(v1, v2, v3, v4));
25438 }
25439 /**
25440 * Invokes a pipe with variable number of arguments.
25441 *
25442 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
25443 * the pipe only when an input to the pipe changes.
25444 *
25445 * @param index Pipe index where the pipe was stored on creation.
25446 * @param slotOffset the offset in the reserved slot space
25447 * @param values Array of arguments to pass to {@link PipeTransform#transform} method.
25448 *
25449 * @codeGenApi
25450 */
25451 function ɵɵpipeBindV(index, slotOffset, values) {
25452 var lView = getLView();
25453 var pipeInstance = load(lView, index);
25454 return unwrapValue$1(lView, isPure(lView, index) ?
25455 pureFunctionVInternal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, values, pipeInstance) :
25456 pipeInstance.transform.apply(pipeInstance, values));
25457 }
25458 function isPure(lView, index) {
25459 return lView[TVIEW].data[index + HEADER_OFFSET].pure;
25460 }
25461 /**
25462 * Unwrap the output of a pipe transformation.
25463 * In order to trick change detection into considering that the new value is always different from
25464 * the old one, the old value is overwritten by NO_CHANGE.
25465 *
25466 * @param newValue the pipe transformation output.
25467 */
25468 function unwrapValue$1(lView, newValue) {
25469 if (WrappedValue.isWrapped(newValue)) {
25470 newValue = WrappedValue.unwrap(newValue);
25471 // The NO_CHANGE value needs to be written at the index where the impacted binding value is
25472 // stored
25473 var bindingToInvalidateIdx = getBindingIndex();
25474 lView[bindingToInvalidateIdx] = NO_CHANGE;
25475 }
25476 return newValue;
25477 }
25478
25479 var EventEmitter_ = /** @class */ (function (_super) {
25480 __extends(EventEmitter_, _super);
25481 function EventEmitter_(isAsync) {
25482 if (isAsync === void 0) { isAsync = false; }
25483 var _this = _super.call(this) || this;
25484 _this.__isAsync = isAsync;
25485 return _this;
25486 }
25487 EventEmitter_.prototype.emit = function (value) {
25488 _super.prototype.next.call(this, value);
25489 };
25490 EventEmitter_.prototype.subscribe = function (generatorOrNext, error, complete) {
25491 var schedulerFn;
25492 var errorFn = function (err) { return null; };
25493 var completeFn = function () { return null; };
25494 if (generatorOrNext && typeof generatorOrNext === 'object') {
25495 schedulerFn = this.__isAsync ? function (value) {
25496 setTimeout(function () { return generatorOrNext.next(value); });
25497 } : function (value) {
25498 generatorOrNext.next(value);
25499 };
25500 if (generatorOrNext.error) {
25501 errorFn = this.__isAsync ? function (err) {
25502 setTimeout(function () { return generatorOrNext.error(err); });
25503 } : function (err) {
25504 generatorOrNext.error(err);
25505 };
25506 }
25507 if (generatorOrNext.complete) {
25508 completeFn = this.__isAsync ? function () {
25509 setTimeout(function () { return generatorOrNext.complete(); });
25510 } : function () {
25511 generatorOrNext.complete();
25512 };
25513 }
25514 }
25515 else {
25516 schedulerFn = this.__isAsync ? function (value) {
25517 setTimeout(function () { return generatorOrNext(value); });
25518 } : function (value) {
25519 generatorOrNext(value);
25520 };
25521 if (error) {
25522 errorFn = this.__isAsync ? function (err) {
25523 setTimeout(function () { return error(err); });
25524 } : function (err) {
25525 error(err);
25526 };
25527 }
25528 if (complete) {
25529 completeFn = this.__isAsync ? function () {
25530 setTimeout(function () { return complete(); });
25531 } : function () {
25532 complete();
25533 };
25534 }
25535 }
25536 var sink = _super.prototype.subscribe.call(this, schedulerFn, errorFn, completeFn);
25537 if (generatorOrNext instanceof rxjs.Subscription) {
25538 generatorOrNext.add(sink);
25539 }
25540 return sink;
25541 };
25542 return EventEmitter_;
25543 }(rxjs.Subject));
25544 /**
25545 * @publicApi
25546 */
25547 var EventEmitter = EventEmitter_;
25548
25549 /**
25550 * @license
25551 * Copyright Google LLC All Rights Reserved.
25552 *
25553 * Use of this source code is governed by an MIT-style license that can be
25554 * found in the LICENSE file at https://angular.io/license
25555 */
25556 function symbolIterator() {
25557 return this._results[getSymbolIterator()]();
25558 }
25559 /**
25560 * An unmodifiable list of items that Angular keeps up to date when the state
25561 * of the application changes.
25562 *
25563 * The type of object that {@link ViewChildren}, {@link ContentChildren}, and {@link QueryList}
25564 * provide.
25565 *
25566 * Implements an iterable interface, therefore it can be used in both ES6
25567 * javascript `for (var i of items)` loops as well as in Angular templates with
25568 * `*ngFor="let i of myList"`.
25569 *
25570 * Changes can be observed by subscribing to the changes `Observable`.
25571 *
25572 * NOTE: In the future this class will implement an `Observable` interface.
25573 *
25574 * @usageNotes
25575 * ### Example
25576 * ```typescript
25577 * @Component({...})
25578 * class Container {
25579 * @ViewChildren(Item) items:QueryList<Item>;
25580 * }
25581 * ```
25582 *
25583 * @publicApi
25584 */
25585 var QueryList = /** @class */ (function () {
25586 function QueryList() {
25587 this.dirty = true;
25588 this._results = [];
25589 this.changes = new EventEmitter();
25590 this.length = 0;
25591 // This function should be declared on the prototype, but doing so there will cause the class
25592 // declaration to have side-effects and become not tree-shakable. For this reason we do it in
25593 // the constructor.
25594 // [getSymbolIterator()](): Iterator<T> { ... }
25595 var symbol = getSymbolIterator();
25596 var proto = QueryList.prototype;
25597 if (!proto[symbol])
25598 proto[symbol] = symbolIterator;
25599 }
25600 /**
25601 * See
25602 * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
25603 */
25604 QueryList.prototype.map = function (fn) {
25605 return this._results.map(fn);
25606 };
25607 /**
25608 * See
25609 * [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
25610 */
25611 QueryList.prototype.filter = function (fn) {
25612 return this._results.filter(fn);
25613 };
25614 /**
25615 * See
25616 * [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
25617 */
25618 QueryList.prototype.find = function (fn) {
25619 return this._results.find(fn);
25620 };
25621 /**
25622 * See
25623 * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
25624 */
25625 QueryList.prototype.reduce = function (fn, init) {
25626 return this._results.reduce(fn, init);
25627 };
25628 /**
25629 * See
25630 * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
25631 */
25632 QueryList.prototype.forEach = function (fn) {
25633 this._results.forEach(fn);
25634 };
25635 /**
25636 * See
25637 * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
25638 */
25639 QueryList.prototype.some = function (fn) {
25640 return this._results.some(fn);
25641 };
25642 /**
25643 * Returns a copy of the internal results list as an Array.
25644 */
25645 QueryList.prototype.toArray = function () {
25646 return this._results.slice();
25647 };
25648 QueryList.prototype.toString = function () {
25649 return this._results.toString();
25650 };
25651 /**
25652 * Updates the stored data of the query list, and resets the `dirty` flag to `false`, so that
25653 * on change detection, it will not notify of changes to the queries, unless a new change
25654 * occurs.
25655 *
25656 * @param resultsTree The query results to store
25657 */
25658 QueryList.prototype.reset = function (resultsTree) {
25659 this._results = flatten(resultsTree);
25660 this.dirty = false;
25661 this.length = this._results.length;
25662 this.last = this._results[this.length - 1];
25663 this.first = this._results[0];
25664 };
25665 /**
25666 * Triggers a change event by emitting on the `changes` {@link EventEmitter}.
25667 */
25668 QueryList.prototype.notifyOnChanges = function () {
25669 this.changes.emit(this);
25670 };
25671 /** internal */
25672 QueryList.prototype.setDirty = function () {
25673 this.dirty = true;
25674 };
25675 /** internal */
25676 QueryList.prototype.destroy = function () {
25677 this.changes.complete();
25678 this.changes.unsubscribe();
25679 };
25680 return QueryList;
25681 }());
25682
25683 /**
25684 * @license
25685 * Copyright Google LLC All Rights Reserved.
25686 *
25687 * Use of this source code is governed by an MIT-style license that can be
25688 * found in the LICENSE file at https://angular.io/license
25689 */
25690 // Note: This hack is necessary so we don't erroneously get a circular dependency
25691 // failure based on types.
25692 var unusedValueExportToPlacateAjd$7 = 1;
25693
25694 /**
25695 * @license
25696 * Copyright Google LLC All Rights Reserved.
25697 *
25698 * Use of this source code is governed by an MIT-style license that can be
25699 * found in the LICENSE file at https://angular.io/license
25700 */
25701 // Note: This hack is necessary so we don't erroneously get a circular dependency
25702 // failure based on types.
25703 var unusedValueExportToPlacateAjd$8 = 1;
25704
25705 /**
25706 * @license
25707 * Copyright Google LLC All Rights Reserved.
25708 *
25709 * Use of this source code is governed by an MIT-style license that can be
25710 * found in the LICENSE file at https://angular.io/license
25711 */
25712 var unusedValueToPlacateAjd$2 = unusedValueExportToPlacateAjd$7 + unusedValueExportToPlacateAjd$3 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$8;
25713 var LQuery_ = /** @class */ (function () {
25714 function LQuery_(queryList) {
25715 this.queryList = queryList;
25716 this.matches = null;
25717 }
25718 LQuery_.prototype.clone = function () {
25719 return new LQuery_(this.queryList);
25720 };
25721 LQuery_.prototype.setDirty = function () {
25722 this.queryList.setDirty();
25723 };
25724 return LQuery_;
25725 }());
25726 var LQueries_ = /** @class */ (function () {
25727 function LQueries_(queries) {
25728 if (queries === void 0) { queries = []; }
25729 this.queries = queries;
25730 }
25731 LQueries_.prototype.createEmbeddedView = function (tView) {
25732 var tQueries = tView.queries;
25733 if (tQueries !== null) {
25734 var noOfInheritedQueries = tView.contentQueries !== null ? tView.contentQueries[0] : tQueries.length;
25735 var viewLQueries = [];
25736 // An embedded view has queries propagated from a declaration view at the beginning of the
25737 // TQueries collection and up until a first content query declared in the embedded view. Only
25738 // propagated LQueries are created at this point (LQuery corresponding to declared content
25739 // queries will be instantiated from the content query instructions for each directive).
25740 for (var i = 0; i < noOfInheritedQueries; i++) {
25741 var tQuery = tQueries.getByIndex(i);
25742 var parentLQuery = this.queries[tQuery.indexInDeclarationView];
25743 viewLQueries.push(parentLQuery.clone());
25744 }
25745 return new LQueries_(viewLQueries);
25746 }
25747 return null;
25748 };
25749 LQueries_.prototype.insertView = function (tView) {
25750 this.dirtyQueriesWithMatches(tView);
25751 };
25752 LQueries_.prototype.detachView = function (tView) {
25753 this.dirtyQueriesWithMatches(tView);
25754 };
25755 LQueries_.prototype.dirtyQueriesWithMatches = function (tView) {
25756 for (var i = 0; i < this.queries.length; i++) {
25757 if (getTQuery(tView, i).matches !== null) {
25758 this.queries[i].setDirty();
25759 }
25760 }
25761 };
25762 return LQueries_;
25763 }());
25764 var TQueryMetadata_ = /** @class */ (function () {
25765 function TQueryMetadata_(predicate, descendants, isStatic, read) {
25766 if (read === void 0) { read = null; }
25767 this.predicate = predicate;
25768 this.descendants = descendants;
25769 this.isStatic = isStatic;
25770 this.read = read;
25771 }
25772 return TQueryMetadata_;
25773 }());
25774 var TQueries_ = /** @class */ (function () {
25775 function TQueries_(queries) {
25776 if (queries === void 0) { queries = []; }
25777 this.queries = queries;
25778 }
25779 TQueries_.prototype.elementStart = function (tView, tNode) {
25780 ngDevMode &&
25781 assertFirstCreatePass(tView, 'Queries should collect results on the first template pass only');
25782 for (var i = 0; i < this.queries.length; i++) {
25783 this.queries[i].elementStart(tView, tNode);
25784 }
25785 };
25786 TQueries_.prototype.elementEnd = function (tNode) {
25787 for (var i = 0; i < this.queries.length; i++) {
25788 this.queries[i].elementEnd(tNode);
25789 }
25790 };
25791 TQueries_.prototype.embeddedTView = function (tNode) {
25792 var queriesForTemplateRef = null;
25793 for (var i = 0; i < this.length; i++) {
25794 var childQueryIndex = queriesForTemplateRef !== null ? queriesForTemplateRef.length : 0;
25795 var tqueryClone = this.getByIndex(i).embeddedTView(tNode, childQueryIndex);
25796 if (tqueryClone) {
25797 tqueryClone.indexInDeclarationView = i;
25798 if (queriesForTemplateRef !== null) {
25799 queriesForTemplateRef.push(tqueryClone);
25800 }
25801 else {
25802 queriesForTemplateRef = [tqueryClone];
25803 }
25804 }
25805 }
25806 return queriesForTemplateRef !== null ? new TQueries_(queriesForTemplateRef) : null;
25807 };
25808 TQueries_.prototype.template = function (tView, tNode) {
25809 ngDevMode &&
25810 assertFirstCreatePass(tView, 'Queries should collect results on the first template pass only');
25811 for (var i = 0; i < this.queries.length; i++) {
25812 this.queries[i].template(tView, tNode);
25813 }
25814 };
25815 TQueries_.prototype.getByIndex = function (index) {
25816 ngDevMode && assertIndexInRange(this.queries, index);
25817 return this.queries[index];
25818 };
25819 Object.defineProperty(TQueries_.prototype, "length", {
25820 get: function () {
25821 return this.queries.length;
25822 },
25823 enumerable: false,
25824 configurable: true
25825 });
25826 TQueries_.prototype.track = function (tquery) {
25827 this.queries.push(tquery);
25828 };
25829 return TQueries_;
25830 }());
25831 var TQuery_ = /** @class */ (function () {
25832 function TQuery_(metadata, nodeIndex) {
25833 if (nodeIndex === void 0) { nodeIndex = -1; }
25834 this.metadata = metadata;
25835 this.matches = null;
25836 this.indexInDeclarationView = -1;
25837 this.crossesNgTemplate = false;
25838 /**
25839 * A flag indicating if a given query still applies to nodes it is crossing. We use this flag
25840 * (alongside with _declarationNodeIndex) to know when to stop applying content queries to
25841 * elements in a template.
25842 */
25843 this._appliesToNextNode = true;
25844 this._declarationNodeIndex = nodeIndex;
25845 }
25846 TQuery_.prototype.elementStart = function (tView, tNode) {
25847 if (this.isApplyingToNode(tNode)) {
25848 this.matchTNode(tView, tNode);
25849 }
25850 };
25851 TQuery_.prototype.elementEnd = function (tNode) {
25852 if (this._declarationNodeIndex === tNode.index) {
25853 this._appliesToNextNode = false;
25854 }
25855 };
25856 TQuery_.prototype.template = function (tView, tNode) {
25857 this.elementStart(tView, tNode);
25858 };
25859 TQuery_.prototype.embeddedTView = function (tNode, childQueryIndex) {
25860 if (this.isApplyingToNode(tNode)) {
25861 this.crossesNgTemplate = true;
25862 // A marker indicating a `<ng-template>` element (a placeholder for query results from
25863 // embedded views created based on this `<ng-template>`).
25864 this.addMatch(-tNode.index, childQueryIndex);
25865 return new TQuery_(this.metadata);
25866 }
25867 return null;
25868 };
25869 TQuery_.prototype.isApplyingToNode = function (tNode) {
25870 if (this._appliesToNextNode && this.metadata.descendants === false) {
25871 var declarationNodeIdx = this._declarationNodeIndex;
25872 var parent = tNode.parent;
25873 // Determine if a given TNode is a "direct" child of a node on which a content query was
25874 // declared (only direct children of query's host node can match with the descendants: false
25875 // option). There are 3 main use-case / conditions to consider here:
25876 // - <needs-target><i #target></i></needs-target>: here <i #target> parent node is a query
25877 // host node;
25878 // - <needs-target><ng-template [ngIf]="true"><i #target></i></ng-template></needs-target>:
25879 // here <i #target> parent node is null;
25880 // - <needs-target><ng-container><i #target></i></ng-container></needs-target>: here we need
25881 // to go past `<ng-container>` to determine <i #target> parent node (but we shouldn't traverse
25882 // up past the query's host node!).
25883 while (parent !== null && parent.type === 4 /* ElementContainer */ &&
25884 parent.index !== declarationNodeIdx) {
25885 parent = parent.parent;
25886 }
25887 return declarationNodeIdx === (parent !== null ? parent.index : -1);
25888 }
25889 return this._appliesToNextNode;
25890 };
25891 TQuery_.prototype.matchTNode = function (tView, tNode) {
25892 var predicate = this.metadata.predicate;
25893 if (Array.isArray(predicate)) {
25894 for (var i = 0; i < predicate.length; i++) {
25895 var name = predicate[i];
25896 this.matchTNodeWithReadOption(tView, tNode, getIdxOfMatchingSelector(tNode, name));
25897 // Also try matching the name to a provider since strings can be used as DI tokens too.
25898 this.matchTNodeWithReadOption(tView, tNode, locateDirectiveOrProvider(tNode, tView, name, false, false));
25899 }
25900 }
25901 else {
25902 if (predicate === TemplateRef) {
25903 if (tNode.type === 0 /* Container */) {
25904 this.matchTNodeWithReadOption(tView, tNode, -1);
25905 }
25906 }
25907 else {
25908 this.matchTNodeWithReadOption(tView, tNode, locateDirectiveOrProvider(tNode, tView, predicate, false, false));
25909 }
25910 }
25911 };
25912 TQuery_.prototype.matchTNodeWithReadOption = function (tView, tNode, nodeMatchIdx) {
25913 if (nodeMatchIdx !== null) {
25914 var read = this.metadata.read;
25915 if (read !== null) {
25916 if (read === ElementRef || read === ViewContainerRef ||
25917 read === TemplateRef && tNode.type === 0 /* Container */) {
25918 this.addMatch(tNode.index, -2);
25919 }
25920 else {
25921 var directiveOrProviderIdx = locateDirectiveOrProvider(tNode, tView, read, false, false);
25922 if (directiveOrProviderIdx !== null) {
25923 this.addMatch(tNode.index, directiveOrProviderIdx);
25924 }
25925 }
25926 }
25927 else {
25928 this.addMatch(tNode.index, nodeMatchIdx);
25929 }
25930 }
25931 };
25932 TQuery_.prototype.addMatch = function (tNodeIdx, matchIdx) {
25933 if (this.matches === null) {
25934 this.matches = [tNodeIdx, matchIdx];
25935 }
25936 else {
25937 this.matches.push(tNodeIdx, matchIdx);
25938 }
25939 };
25940 return TQuery_;
25941 }());
25942 /**
25943 * Iterates over local names for a given node and returns directive index
25944 * (or -1 if a local name points to an element).
25945 *
25946 * @param tNode static data of a node to check
25947 * @param selector selector to match
25948 * @returns directive index, -1 or null if a selector didn't match any of the local names
25949 */
25950 function getIdxOfMatchingSelector(tNode, selector) {
25951 var localNames = tNode.localNames;
25952 if (localNames !== null) {
25953 for (var i = 0; i < localNames.length; i += 2) {
25954 if (localNames[i] === selector) {
25955 return localNames[i + 1];
25956 }
25957 }
25958 }
25959 return null;
25960 }
25961 function createResultByTNodeType(tNode, currentView) {
25962 if (tNode.type === 3 /* Element */ || tNode.type === 4 /* ElementContainer */) {
25963 return createElementRef(ElementRef, tNode, currentView);
25964 }
25965 else if (tNode.type === 0 /* Container */) {
25966 return createTemplateRef(TemplateRef, ElementRef, tNode, currentView);
25967 }
25968 return null;
25969 }
25970 function createResultForNode(lView, tNode, matchingIdx, read) {
25971 if (matchingIdx === -1) {
25972 // if read token and / or strategy is not specified, detect it using appropriate tNode type
25973 return createResultByTNodeType(tNode, lView);
25974 }
25975 else if (matchingIdx === -2) {
25976 // read a special token from a node injector
25977 return createSpecialToken(lView, tNode, read);
25978 }
25979 else {
25980 // read a token
25981 return getNodeInjectable(lView, lView[TVIEW], matchingIdx, tNode);
25982 }
25983 }
25984 function createSpecialToken(lView, tNode, read) {
25985 if (read === ElementRef) {
25986 return createElementRef(ElementRef, tNode, lView);
25987 }
25988 else if (read === TemplateRef) {
25989 return createTemplateRef(TemplateRef, ElementRef, tNode, lView);
25990 }
25991 else if (read === ViewContainerRef) {
25992 ngDevMode &&
25993 assertNodeOfPossibleTypes(tNode, [3 /* Element */, 0 /* Container */, 4 /* ElementContainer */]);
25994 return createContainerRef(ViewContainerRef, ElementRef, tNode, lView);
25995 }
25996 else {
25997 ngDevMode &&
25998 throwError("Special token to read should be one of ElementRef, TemplateRef or ViewContainerRef but got " + stringify(read) + ".");
25999 }
26000 }
26001 /**
26002 * A helper function that creates query results for a given view. This function is meant to do the
26003 * processing once and only once for a given view instance (a set of results for a given view
26004 * doesn't change).
26005 */
26006 function materializeViewResults(tView, lView, tQuery, queryIndex) {
26007 var lQuery = lView[QUERIES].queries[queryIndex];
26008 if (lQuery.matches === null) {
26009 var tViewData = tView.data;
26010 var tQueryMatches = tQuery.matches;
26011 var result = [];
26012 for (var i = 0; i < tQueryMatches.length; i += 2) {
26013 var matchedNodeIdx = tQueryMatches[i];
26014 if (matchedNodeIdx < 0) {
26015 // we at the <ng-template> marker which might have results in views created based on this
26016 // <ng-template> - those results will be in separate views though, so here we just leave
26017 // null as a placeholder
26018 result.push(null);
26019 }
26020 else {
26021 ngDevMode && assertIndexInRange(tViewData, matchedNodeIdx);
26022 var tNode = tViewData[matchedNodeIdx];
26023 result.push(createResultForNode(lView, tNode, tQueryMatches[i + 1], tQuery.metadata.read));
26024 }
26025 }
26026 lQuery.matches = result;
26027 }
26028 return lQuery.matches;
26029 }
26030 /**
26031 * A helper function that collects (already materialized) query results from a tree of views,
26032 * starting with a provided LView.
26033 */
26034 function collectQueryResults(tView, lView, queryIndex, result) {
26035 var tQuery = tView.queries.getByIndex(queryIndex);
26036 var tQueryMatches = tQuery.matches;
26037 if (tQueryMatches !== null) {
26038 var lViewResults = materializeViewResults(tView, lView, tQuery, queryIndex);
26039 for (var i = 0; i < tQueryMatches.length; i += 2) {
26040 var tNodeIdx = tQueryMatches[i];
26041 if (tNodeIdx > 0) {
26042 result.push(lViewResults[i / 2]);
26043 }
26044 else {
26045 var childQueryIndex = tQueryMatches[i + 1];
26046 var declarationLContainer = lView[-tNodeIdx];
26047 ngDevMode && assertLContainer(declarationLContainer);
26048 // collect matches for views inserted in this container
26049 for (var i_1 = CONTAINER_HEADER_OFFSET; i_1 < declarationLContainer.length; i_1++) {
26050 var embeddedLView = declarationLContainer[i_1];
26051 if (embeddedLView[DECLARATION_LCONTAINER] === embeddedLView[PARENT]) {
26052 collectQueryResults(embeddedLView[TVIEW], embeddedLView, childQueryIndex, result);
26053 }
26054 }
26055 // collect matches for views created from this declaration container and inserted into
26056 // different containers
26057 if (declarationLContainer[MOVED_VIEWS] !== null) {
26058 var embeddedLViews = declarationLContainer[MOVED_VIEWS];
26059 for (var i_2 = 0; i_2 < embeddedLViews.length; i_2++) {
26060 var embeddedLView = embeddedLViews[i_2];
26061 collectQueryResults(embeddedLView[TVIEW], embeddedLView, childQueryIndex, result);
26062 }
26063 }
26064 }
26065 }
26066 }
26067 return result;
26068 }
26069 /**
26070 * Refreshes a query by combining matches from all active views and removing matches from deleted
26071 * views.
26072 *
26073 * @returns `true` if a query got dirty during change detection or if this is a static query
26074 * resolving in creation mode, `false` otherwise.
26075 *
26076 * @codeGenApi
26077 */
26078 function ɵɵqueryRefresh(queryList) {
26079 var lView = getLView();
26080 var tView = getTView();
26081 var queryIndex = getCurrentQueryIndex();
26082 setCurrentQueryIndex(queryIndex + 1);
26083 var tQuery = getTQuery(tView, queryIndex);
26084 if (queryList.dirty && (isCreationMode(lView) === tQuery.metadata.isStatic)) {
26085 if (tQuery.matches === null) {
26086 queryList.reset([]);
26087 }
26088 else {
26089 var result = tQuery.crossesNgTemplate ?
26090 collectQueryResults(tView, lView, queryIndex, []) :
26091 materializeViewResults(tView, lView, tQuery, queryIndex);
26092 queryList.reset(result);
26093 queryList.notifyOnChanges();
26094 }
26095 return true;
26096 }
26097 return false;
26098 }
26099 /**
26100 * Creates new QueryList for a static view query.
26101 *
26102 * @param predicate The type for which the query will search
26103 * @param descend Whether or not to descend into children
26104 * @param read What to save in the query
26105 *
26106 * @codeGenApi
26107 */
26108 function ɵɵstaticViewQuery(predicate, descend, read) {
26109 viewQueryInternal(getTView(), getLView(), predicate, descend, read, true);
26110 }
26111 /**
26112 * Creates new QueryList, stores the reference in LView and returns QueryList.
26113 *
26114 * @param predicate The type for which the query will search
26115 * @param descend Whether or not to descend into children
26116 * @param read What to save in the query
26117 *
26118 * @codeGenApi
26119 */
26120 function ɵɵviewQuery(predicate, descend, read) {
26121 viewQueryInternal(getTView(), getLView(), predicate, descend, read, false);
26122 }
26123 function viewQueryInternal(tView, lView, predicate, descend, read, isStatic) {
26124 if (tView.firstCreatePass) {
26125 createTQuery(tView, new TQueryMetadata_(predicate, descend, isStatic, read), -1);
26126 if (isStatic) {
26127 tView.staticViewQueries = true;
26128 }
26129 }
26130 createLQuery(tView, lView);
26131 }
26132 /**
26133 * Registers a QueryList, associated with a content query, for later refresh (part of a view
26134 * refresh).
26135 *
26136 * @param directiveIndex Current directive index
26137 * @param predicate The type for which the query will search
26138 * @param descend Whether or not to descend into children
26139 * @param read What to save in the query
26140 * @returns QueryList<T>
26141 *
26142 * @codeGenApi
26143 */
26144 function ɵɵcontentQuery(directiveIndex, predicate, descend, read) {
26145 contentQueryInternal(getTView(), getLView(), predicate, descend, read, false, getPreviousOrParentTNode(), directiveIndex);
26146 }
26147 /**
26148 * Registers a QueryList, associated with a static content query, for later refresh
26149 * (part of a view refresh).
26150 *
26151 * @param directiveIndex Current directive index
26152 * @param predicate The type for which the query will search
26153 * @param descend Whether or not to descend into children
26154 * @param read What to save in the query
26155 * @returns QueryList<T>
26156 *
26157 * @codeGenApi
26158 */
26159 function ɵɵstaticContentQuery(directiveIndex, predicate, descend, read) {
26160 contentQueryInternal(getTView(), getLView(), predicate, descend, read, true, getPreviousOrParentTNode(), directiveIndex);
26161 }
26162 function contentQueryInternal(tView, lView, predicate, descend, read, isStatic, tNode, directiveIndex) {
26163 if (tView.firstCreatePass) {
26164 createTQuery(tView, new TQueryMetadata_(predicate, descend, isStatic, read), tNode.index);
26165 saveContentQueryAndDirectiveIndex(tView, directiveIndex);
26166 if (isStatic) {
26167 tView.staticContentQueries = true;
26168 }
26169 }
26170 createLQuery(tView, lView);
26171 }
26172 /**
26173 * Loads a QueryList corresponding to the current view or content query.
26174 *
26175 * @codeGenApi
26176 */
26177 function ɵɵloadQuery() {
26178 return loadQueryInternal(getLView(), getCurrentQueryIndex());
26179 }
26180 function loadQueryInternal(lView, queryIndex) {
26181 ngDevMode &&
26182 assertDefined(lView[QUERIES], 'LQueries should be defined when trying to load a query');
26183 ngDevMode && assertIndexInRange(lView[QUERIES].queries, queryIndex);
26184 return lView[QUERIES].queries[queryIndex].queryList;
26185 }
26186 function createLQuery(tView, lView) {
26187 var queryList = new QueryList();
26188 storeCleanupWithContext(tView, lView, queryList, queryList.destroy);
26189 if (lView[QUERIES] === null)
26190 lView[QUERIES] = new LQueries_();
26191 lView[QUERIES].queries.push(new LQuery_(queryList));
26192 }
26193 function createTQuery(tView, metadata, nodeIndex) {
26194 if (tView.queries === null)
26195 tView.queries = new TQueries_();
26196 tView.queries.track(new TQuery_(metadata, nodeIndex));
26197 }
26198 function saveContentQueryAndDirectiveIndex(tView, directiveIndex) {
26199 var tViewContentQueries = tView.contentQueries || (tView.contentQueries = []);
26200 var lastSavedDirectiveIndex = tView.contentQueries.length ? tViewContentQueries[tViewContentQueries.length - 1] : -1;
26201 if (directiveIndex !== lastSavedDirectiveIndex) {
26202 tViewContentQueries.push(tView.queries.length - 1, directiveIndex);
26203 }
26204 }
26205 function getTQuery(tView, index) {
26206 ngDevMode && assertDefined(tView.queries, 'TQueries must be defined to retrieve a TQuery');
26207 return tView.queries.getByIndex(index);
26208 }
26209
26210 /**
26211 * @license
26212 * Copyright Google LLC All Rights Reserved.
26213 *
26214 * Use of this source code is governed by an MIT-style license that can be
26215 * found in the LICENSE file at https://angular.io/license
26216 */
26217 /**
26218 * Retrieves `TemplateRef` instance from `Injector` when a local reference is placed on the
26219 * `<ng-template>` element.
26220 *
26221 * @codeGenApi
26222 */
26223 function ɵɵtemplateRefExtractor(tNode, currentView) {
26224 return createTemplateRef(TemplateRef, ElementRef, tNode, currentView);
26225 }
26226 /**
26227 * Returns the appropriate `ChangeDetectorRef` for a pipe.
26228 *
26229 * @codeGenApi
26230 */
26231 function ɵɵinjectPipeChangeDetectorRef(flags) {
26232 if (flags === void 0) { flags = exports.InjectFlags.Default; }
26233 var value = injectChangeDetectorRef(true);
26234 if (value == null && !(flags & exports.InjectFlags.Optional)) {
26235 throw new Error("No provider for ChangeDetectorRef!");
26236 }
26237 else {
26238 return value;
26239 }
26240 }
26241
26242 /**
26243 * @license
26244 * Copyright Google LLC All Rights Reserved.
26245 *
26246 * Use of this source code is governed by an MIT-style license that can be
26247 * found in the LICENSE file at https://angular.io/license
26248 */
26249
26250 /**
26251 * @license
26252 * Copyright Google LLC All Rights Reserved.
26253 *
26254 * Use of this source code is governed by an MIT-style license that can be
26255 * found in the LICENSE file at https://angular.io/license
26256 */
26257 var ɵ0$d = function () { return ({
26258 'ɵɵattribute': ɵɵattribute,
26259 'ɵɵattributeInterpolate1': ɵɵattributeInterpolate1,
26260 'ɵɵattributeInterpolate2': ɵɵattributeInterpolate2,
26261 'ɵɵattributeInterpolate3': ɵɵattributeInterpolate3,
26262 'ɵɵattributeInterpolate4': ɵɵattributeInterpolate4,
26263 'ɵɵattributeInterpolate5': ɵɵattributeInterpolate5,
26264 'ɵɵattributeInterpolate6': ɵɵattributeInterpolate6,
26265 'ɵɵattributeInterpolate7': ɵɵattributeInterpolate7,
26266 'ɵɵattributeInterpolate8': ɵɵattributeInterpolate8,
26267 'ɵɵattributeInterpolateV': ɵɵattributeInterpolateV,
26268 'ɵɵdefineComponent': ɵɵdefineComponent,
26269 'ɵɵdefineDirective': ɵɵdefineDirective,
26270 'ɵɵdefineInjectable': ɵɵdefineInjectable,
26271 'ɵɵdefineInjector': ɵɵdefineInjector,
26272 'ɵɵdefineNgModule': ɵɵdefineNgModule,
26273 'ɵɵdefinePipe': ɵɵdefinePipe,
26274 'ɵɵdirectiveInject': ɵɵdirectiveInject,
26275 'ɵɵgetFactoryOf': ɵɵgetFactoryOf,
26276 'ɵɵgetInheritedFactory': ɵɵgetInheritedFactory,
26277 'ɵɵinject': ɵɵinject,
26278 'ɵɵinjectAttribute': ɵɵinjectAttribute,
26279 'ɵɵinvalidFactory': ɵɵinvalidFactory,
26280 'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
26281 'ɵɵinjectPipeChangeDetectorRef': ɵɵinjectPipeChangeDetectorRef,
26282 'ɵɵtemplateRefExtractor': ɵɵtemplateRefExtractor,
26283 'ɵɵNgOnChangesFeature': ɵɵNgOnChangesFeature,
26284 'ɵɵProvidersFeature': ɵɵProvidersFeature,
26285 'ɵɵCopyDefinitionFeature': ɵɵCopyDefinitionFeature,
26286 'ɵɵInheritDefinitionFeature': ɵɵInheritDefinitionFeature,
26287 'ɵɵnextContext': ɵɵnextContext,
26288 'ɵɵnamespaceHTML': ɵɵnamespaceHTML,
26289 'ɵɵnamespaceMathML': ɵɵnamespaceMathML,
26290 'ɵɵnamespaceSVG': ɵɵnamespaceSVG,
26291 'ɵɵenableBindings': ɵɵenableBindings,
26292 'ɵɵdisableBindings': ɵɵdisableBindings,
26293 'ɵɵelementStart': ɵɵelementStart,
26294 'ɵɵelementEnd': ɵɵelementEnd,
26295 'ɵɵelement': ɵɵelement,
26296 'ɵɵelementContainerStart': ɵɵelementContainerStart,
26297 'ɵɵelementContainerEnd': ɵɵelementContainerEnd,
26298 'ɵɵelementContainer': ɵɵelementContainer,
26299 'ɵɵpureFunction0': ɵɵpureFunction0,
26300 'ɵɵpureFunction1': ɵɵpureFunction1,
26301 'ɵɵpureFunction2': ɵɵpureFunction2,
26302 'ɵɵpureFunction3': ɵɵpureFunction3,
26303 'ɵɵpureFunction4': ɵɵpureFunction4,
26304 'ɵɵpureFunction5': ɵɵpureFunction5,
26305 'ɵɵpureFunction6': ɵɵpureFunction6,
26306 'ɵɵpureFunction7': ɵɵpureFunction7,
26307 'ɵɵpureFunction8': ɵɵpureFunction8,
26308 'ɵɵpureFunctionV': ɵɵpureFunctionV,
26309 'ɵɵgetCurrentView': ɵɵgetCurrentView,
26310 'ɵɵrestoreView': ɵɵrestoreView,
26311 'ɵɵlistener': ɵɵlistener,
26312 'ɵɵprojection': ɵɵprojection,
26313 'ɵɵsyntheticHostProperty': ɵɵsyntheticHostProperty,
26314 'ɵɵsyntheticHostListener': ɵɵsyntheticHostListener,
26315 'ɵɵpipeBind1': ɵɵpipeBind1,
26316 'ɵɵpipeBind2': ɵɵpipeBind2,
26317 'ɵɵpipeBind3': ɵɵpipeBind3,
26318 'ɵɵpipeBind4': ɵɵpipeBind4,
26319 'ɵɵpipeBindV': ɵɵpipeBindV,
26320 'ɵɵprojectionDef': ɵɵprojectionDef,
26321 'ɵɵhostProperty': ɵɵhostProperty,
26322 'ɵɵproperty': ɵɵproperty,
26323 'ɵɵpropertyInterpolate': ɵɵpropertyInterpolate,
26324 'ɵɵpropertyInterpolate1': ɵɵpropertyInterpolate1,
26325 'ɵɵpropertyInterpolate2': ɵɵpropertyInterpolate2,
26326 'ɵɵpropertyInterpolate3': ɵɵpropertyInterpolate3,
26327 'ɵɵpropertyInterpolate4': ɵɵpropertyInterpolate4,
26328 'ɵɵpropertyInterpolate5': ɵɵpropertyInterpolate5,
26329 'ɵɵpropertyInterpolate6': ɵɵpropertyInterpolate6,
26330 'ɵɵpropertyInterpolate7': ɵɵpropertyInterpolate7,
26331 'ɵɵpropertyInterpolate8': ɵɵpropertyInterpolate8,
26332 'ɵɵpropertyInterpolateV': ɵɵpropertyInterpolateV,
26333 'ɵɵpipe': ɵɵpipe,
26334 'ɵɵqueryRefresh': ɵɵqueryRefresh,
26335 'ɵɵviewQuery': ɵɵviewQuery,
26336 'ɵɵstaticViewQuery': ɵɵstaticViewQuery,
26337 'ɵɵstaticContentQuery': ɵɵstaticContentQuery,
26338 'ɵɵloadQuery': ɵɵloadQuery,
26339 'ɵɵcontentQuery': ɵɵcontentQuery,
26340 'ɵɵreference': ɵɵreference,
26341 'ɵɵclassMap': ɵɵclassMap,
26342 'ɵɵclassMapInterpolate1': ɵɵclassMapInterpolate1,
26343 'ɵɵclassMapInterpolate2': ɵɵclassMapInterpolate2,
26344 'ɵɵclassMapInterpolate3': ɵɵclassMapInterpolate3,
26345 'ɵɵclassMapInterpolate4': ɵɵclassMapInterpolate4,
26346 'ɵɵclassMapInterpolate5': ɵɵclassMapInterpolate5,
26347 'ɵɵclassMapInterpolate6': ɵɵclassMapInterpolate6,
26348 'ɵɵclassMapInterpolate7': ɵɵclassMapInterpolate7,
26349 'ɵɵclassMapInterpolate8': ɵɵclassMapInterpolate8,
26350 'ɵɵclassMapInterpolateV': ɵɵclassMapInterpolateV,
26351 'ɵɵstyleMap': ɵɵstyleMap,
26352 'ɵɵstyleMapInterpolate1': ɵɵstyleMapInterpolate1,
26353 'ɵɵstyleMapInterpolate2': ɵɵstyleMapInterpolate2,
26354 'ɵɵstyleMapInterpolate3': ɵɵstyleMapInterpolate3,
26355 'ɵɵstyleMapInterpolate4': ɵɵstyleMapInterpolate4,
26356 'ɵɵstyleMapInterpolate5': ɵɵstyleMapInterpolate5,
26357 'ɵɵstyleMapInterpolate6': ɵɵstyleMapInterpolate6,
26358 'ɵɵstyleMapInterpolate7': ɵɵstyleMapInterpolate7,
26359 'ɵɵstyleMapInterpolate8': ɵɵstyleMapInterpolate8,
26360 'ɵɵstyleMapInterpolateV': ɵɵstyleMapInterpolateV,
26361 'ɵɵstyleProp': ɵɵstyleProp,
26362 'ɵɵstylePropInterpolate1': ɵɵstylePropInterpolate1,
26363 'ɵɵstylePropInterpolate2': ɵɵstylePropInterpolate2,
26364 'ɵɵstylePropInterpolate3': ɵɵstylePropInterpolate3,
26365 'ɵɵstylePropInterpolate4': ɵɵstylePropInterpolate4,
26366 'ɵɵstylePropInterpolate5': ɵɵstylePropInterpolate5,
26367 'ɵɵstylePropInterpolate6': ɵɵstylePropInterpolate6,
26368 'ɵɵstylePropInterpolate7': ɵɵstylePropInterpolate7,
26369 'ɵɵstylePropInterpolate8': ɵɵstylePropInterpolate8,
26370 'ɵɵstylePropInterpolateV': ɵɵstylePropInterpolateV,
26371 'ɵɵclassProp': ɵɵclassProp,
26372 'ɵɵselect': ɵɵselect,
26373 'ɵɵadvance': ɵɵadvance,
26374 'ɵɵtemplate': ɵɵtemplate,
26375 'ɵɵtext': ɵɵtext,
26376 'ɵɵtextInterpolate': ɵɵtextInterpolate,
26377 'ɵɵtextInterpolate1': ɵɵtextInterpolate1,
26378 'ɵɵtextInterpolate2': ɵɵtextInterpolate2,
26379 'ɵɵtextInterpolate3': ɵɵtextInterpolate3,
26380 'ɵɵtextInterpolate4': ɵɵtextInterpolate4,
26381 'ɵɵtextInterpolate5': ɵɵtextInterpolate5,
26382 'ɵɵtextInterpolate6': ɵɵtextInterpolate6,
26383 'ɵɵtextInterpolate7': ɵɵtextInterpolate7,
26384 'ɵɵtextInterpolate8': ɵɵtextInterpolate8,
26385 'ɵɵtextInterpolateV': ɵɵtextInterpolateV,
26386 'ɵɵi18n': ɵɵi18n,
26387 'ɵɵi18nAttributes': ɵɵi18nAttributes,
26388 'ɵɵi18nExp': ɵɵi18nExp,
26389 'ɵɵi18nStart': ɵɵi18nStart,
26390 'ɵɵi18nEnd': ɵɵi18nEnd,
26391 'ɵɵi18nApply': ɵɵi18nApply,
26392 'ɵɵi18nPostprocess': ɵɵi18nPostprocess,
26393 'ɵɵresolveWindow': ɵɵresolveWindow,
26394 'ɵɵresolveDocument': ɵɵresolveDocument,
26395 'ɵɵresolveBody': ɵɵresolveBody,
26396 'ɵɵsetComponentScope': ɵɵsetComponentScope,
26397 'ɵɵsetNgModuleScope': ɵɵsetNgModuleScope,
26398 'ɵɵsanitizeHtml': ɵɵsanitizeHtml,
26399 'ɵɵsanitizeStyle': ɵɵsanitizeStyle,
26400 'ɵɵsanitizeResourceUrl': ɵɵsanitizeResourceUrl,
26401 'ɵɵsanitizeScript': ɵɵsanitizeScript,
26402 'ɵɵsanitizeUrl': ɵɵsanitizeUrl,
26403 'ɵɵsanitizeUrlOrResourceUrl': ɵɵsanitizeUrlOrResourceUrl,
26404 }); };
26405 /**
26406 * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
26407 *
26408 * This should be kept up to date with the public exports of @angular/core.
26409 */
26410 var angularCoreEnv = (ɵ0$d)();
26411
26412 var jitOptions = null;
26413 function setJitOptions(options) {
26414 if (jitOptions !== null) {
26415 if (options.defaultEncapsulation !== jitOptions.defaultEncapsulation) {
26416 ngDevMode &&
26417 console.error('Provided value for `defaultEncapsulation` can not be changed once it has been set.');
26418 return;
26419 }
26420 if (options.preserveWhitespaces !== jitOptions.preserveWhitespaces) {
26421 ngDevMode &&
26422 console.error('Provided value for `preserveWhitespaces` can not be changed once it has been set.');
26423 return;
26424 }
26425 }
26426 jitOptions = options;
26427 }
26428 function getJitOptions() {
26429 return jitOptions;
26430 }
26431 function resetJitOptions() {
26432 jitOptions = null;
26433 }
26434
26435 var EMPTY_ARRAY$5 = [];
26436 var moduleQueue = [];
26437 /**
26438 * Enqueues moduleDef to be checked later to see if scope can be set on its
26439 * component declarations.
26440 */
26441 function enqueueModuleForDelayedScoping(moduleType, ngModule) {
26442 moduleQueue.push({ moduleType: moduleType, ngModule: ngModule });
26443 }
26444 var flushingModuleQueue = false;
26445 /**
26446 * Loops over queued module definitions, if a given module definition has all of its
26447 * declarations resolved, it dequeues that module definition and sets the scope on
26448 * its declarations.
26449 */
26450 function flushModuleScopingQueueAsMuchAsPossible() {
26451 if (!flushingModuleQueue) {
26452 flushingModuleQueue = true;
26453 try {
26454 for (var i = moduleQueue.length - 1; i >= 0; i--) {
26455 var _a = moduleQueue[i], moduleType = _a.moduleType, ngModule = _a.ngModule;
26456 if (ngModule.declarations && ngModule.declarations.every(isResolvedDeclaration)) {
26457 // dequeue
26458 moduleQueue.splice(i, 1);
26459 setScopeOnDeclaredComponents(moduleType, ngModule);
26460 }
26461 }
26462 }
26463 finally {
26464 flushingModuleQueue = false;
26465 }
26466 }
26467 }
26468 /**
26469 * Returns truthy if a declaration has resolved. If the declaration happens to be
26470 * an array of declarations, it will recurse to check each declaration in that array
26471 * (which may also be arrays).
26472 */
26473 function isResolvedDeclaration(declaration) {
26474 if (Array.isArray(declaration)) {
26475 return declaration.every(isResolvedDeclaration);
26476 }
26477 return !!resolveForwardRef(declaration);
26478 }
26479 /**
26480 * Compiles a module in JIT mode.
26481 *
26482 * This function automatically gets called when a class has a `@NgModule` decorator.
26483 */
26484 function compileNgModule(moduleType, ngModule) {
26485 if (ngModule === void 0) { ngModule = {}; }
26486 compileNgModuleDefs(moduleType, ngModule);
26487 // Because we don't know if all declarations have resolved yet at the moment the
26488 // NgModule decorator is executing, we're enqueueing the setting of module scope
26489 // on its declarations to be run at a later time when all declarations for the module,
26490 // including forward refs, have resolved.
26491 enqueueModuleForDelayedScoping(moduleType, ngModule);
26492 }
26493 /**
26494 * Compiles and adds the `ɵmod` and `ɵinj` properties to the module class.
26495 *
26496 * It's possible to compile a module via this API which will allow duplicate declarations in its
26497 * root.
26498 */
26499 function compileNgModuleDefs(moduleType, ngModule, allowDuplicateDeclarationsInRoot) {
26500 if (allowDuplicateDeclarationsInRoot === void 0) { allowDuplicateDeclarationsInRoot = false; }
26501 ngDevMode && assertDefined(moduleType, 'Required value moduleType');
26502 ngDevMode && assertDefined(ngModule, 'Required value ngModule');
26503 var declarations = flatten(ngModule.declarations || EMPTY_ARRAY$5);
26504 var ngModuleDef = null;
26505 Object.defineProperty(moduleType, NG_MOD_DEF, {
26506 configurable: true,
26507 get: function () {
26508 if (ngModuleDef === null) {
26509 if (ngDevMode && ngModule.imports && ngModule.imports.indexOf(moduleType) > -1) {
26510 // We need to assert this immediately, because allowing it to continue will cause it to
26511 // go into an infinite loop before we've reached the point where we throw all the errors.
26512 throw new Error("'" + stringifyForError(moduleType) + "' module can't import itself");
26513 }
26514 ngModuleDef = getCompilerFacade().compileNgModule(angularCoreEnv, "ng:///" + moduleType.name + "/\u0275mod.js", {
26515 type: moduleType,
26516 bootstrap: flatten(ngModule.bootstrap || EMPTY_ARRAY$5).map(resolveForwardRef),
26517 declarations: declarations.map(resolveForwardRef),
26518 imports: flatten(ngModule.imports || EMPTY_ARRAY$5)
26519 .map(resolveForwardRef)
26520 .map(expandModuleWithProviders),
26521 exports: flatten(ngModule.exports || EMPTY_ARRAY$5)
26522 .map(resolveForwardRef)
26523 .map(expandModuleWithProviders),
26524 schemas: ngModule.schemas ? flatten(ngModule.schemas) : null,
26525 id: ngModule.id || null,
26526 });
26527 // Set `schemas` on ngModuleDef to an empty array in JIT mode to indicate that runtime
26528 // should verify that there are no unknown elements in a template. In AOT mode, that check
26529 // happens at compile time and `schemas` information is not present on Component and Module
26530 // defs after compilation (so the check doesn't happen the second time at runtime).
26531 if (!ngModuleDef.schemas) {
26532 ngModuleDef.schemas = [];
26533 }
26534 }
26535 return ngModuleDef;
26536 }
26537 });
26538 var ngInjectorDef = null;
26539 Object.defineProperty(moduleType, NG_INJ_DEF, {
26540 get: function () {
26541 if (ngInjectorDef === null) {
26542 ngDevMode &&
26543 verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot);
26544 var meta = {
26545 name: moduleType.name,
26546 type: moduleType,
26547 deps: reflectDependencies(moduleType),
26548 providers: ngModule.providers || EMPTY_ARRAY$5,
26549 imports: [
26550 (ngModule.imports || EMPTY_ARRAY$5).map(resolveForwardRef),
26551 (ngModule.exports || EMPTY_ARRAY$5).map(resolveForwardRef),
26552 ],
26553 };
26554 ngInjectorDef = getCompilerFacade().compileInjector(angularCoreEnv, "ng:///" + moduleType.name + "/\u0275inj.js", meta);
26555 }
26556 return ngInjectorDef;
26557 },
26558 // Make the property configurable in dev mode to allow overriding in tests
26559 configurable: !!ngDevMode,
26560 });
26561 }
26562 function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot, importingModule) {
26563 if (verifiedNgModule.get(moduleType))
26564 return;
26565 verifiedNgModule.set(moduleType, true);
26566 moduleType = resolveForwardRef(moduleType);
26567 var ngModuleDef;
26568 if (importingModule) {
26569 ngModuleDef = getNgModuleDef(moduleType);
26570 if (!ngModuleDef) {
26571 throw new Error("Unexpected value '" + moduleType.name + "' imported by the module '" + importingModule.name + "'. Please add an @NgModule annotation.");
26572 }
26573 }
26574 else {
26575 ngModuleDef = getNgModuleDef(moduleType, true);
26576 }
26577 var errors = [];
26578 var declarations = maybeUnwrapFn(ngModuleDef.declarations);
26579 var imports = maybeUnwrapFn(ngModuleDef.imports);
26580 flatten(imports).map(unwrapModuleWithProvidersImports).forEach(function (mod) {
26581 verifySemanticsOfNgModuleImport(mod, moduleType);
26582 verifySemanticsOfNgModuleDef(mod, false, moduleType);
26583 });
26584 var exports = maybeUnwrapFn(ngModuleDef.exports);
26585 declarations.forEach(verifyDeclarationsHaveDefinitions);
26586 declarations.forEach(verifyDirectivesHaveSelector);
26587 var combinedDeclarations = __spread(declarations.map(resolveForwardRef), flatten(imports.map(computeCombinedExports)).map(resolveForwardRef));
26588 exports.forEach(verifyExportsAreDeclaredOrReExported);
26589 declarations.forEach(function (decl) { return verifyDeclarationIsUnique(decl, allowDuplicateDeclarationsInRoot); });
26590 declarations.forEach(verifyComponentEntryComponentsIsPartOfNgModule);
26591 var ngModule = getAnnotation(moduleType, 'NgModule');
26592 if (ngModule) {
26593 ngModule.imports &&
26594 flatten(ngModule.imports).map(unwrapModuleWithProvidersImports).forEach(function (mod) {
26595 verifySemanticsOfNgModuleImport(mod, moduleType);
26596 verifySemanticsOfNgModuleDef(mod, false, moduleType);
26597 });
26598 ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyCorrectBootstrapType);
26599 ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyComponentIsPartOfNgModule);
26600 ngModule.entryComponents &&
26601 deepForEach(ngModule.entryComponents, verifyComponentIsPartOfNgModule);
26602 }
26603 // Throw Error if any errors were detected.
26604 if (errors.length) {
26605 throw new Error(errors.join('\n'));
26606 }
26607 ////////////////////////////////////////////////////////////////////////////////////////////////
26608 function verifyDeclarationsHaveDefinitions(type) {
26609 type = resolveForwardRef(type);
26610 var def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef(type);
26611 if (!def) {
26612 errors.push("Unexpected value '" + stringifyForError(type) + "' declared by the module '" + stringifyForError(moduleType) + "'. Please add a @Pipe/@Directive/@Component annotation.");
26613 }
26614 }
26615 function verifyDirectivesHaveSelector(type) {
26616 type = resolveForwardRef(type);
26617 var def = getDirectiveDef(type);
26618 if (!getComponentDef(type) && def && def.selectors.length == 0) {
26619 errors.push("Directive " + stringifyForError(type) + " has no selector, please add it!");
26620 }
26621 }
26622 function verifyExportsAreDeclaredOrReExported(type) {
26623 type = resolveForwardRef(type);
26624 var kind = getComponentDef(type) && 'component' || getDirectiveDef(type) && 'directive' ||
26625 getPipeDef(type) && 'pipe';
26626 if (kind) {
26627 // only checked if we are declared as Component, Directive, or Pipe
26628 // Modules don't need to be declared or imported.
26629 if (combinedDeclarations.lastIndexOf(type) === -1) {
26630 // We are exporting something which we don't explicitly declare or import.
26631 errors.push("Can't export " + kind + " " + stringifyForError(type) + " from " + stringifyForError(moduleType) + " as it was neither declared nor imported!");
26632 }
26633 }
26634 }
26635 function verifyDeclarationIsUnique(type, suppressErrors) {
26636 type = resolveForwardRef(type);
26637 var existingModule = ownerNgModule.get(type);
26638 if (existingModule && existingModule !== moduleType) {
26639 if (!suppressErrors) {
26640 var modules = [existingModule, moduleType].map(stringifyForError).sort();
26641 errors.push("Type " + stringifyForError(type) + " is part of the declarations of 2 modules: " + modules[0] + " and " + modules[1] + "! " +
26642 ("Please consider moving " + stringifyForError(type) + " to a higher module that imports " + modules[0] + " and " + modules[1] + ". ") +
26643 ("You can also create a new NgModule that exports and includes " + stringifyForError(type) + " then import that NgModule in " + modules[0] + " and " + modules[1] + "."));
26644 }
26645 }
26646 else {
26647 // Mark type as having owner.
26648 ownerNgModule.set(type, moduleType);
26649 }
26650 }
26651 function verifyComponentIsPartOfNgModule(type) {
26652 type = resolveForwardRef(type);
26653 var existingModule = ownerNgModule.get(type);
26654 if (!existingModule) {
26655 errors.push("Component " + stringifyForError(type) + " is not part of any NgModule or the module has not been imported into your module.");
26656 }
26657 }
26658 function verifyCorrectBootstrapType(type) {
26659 type = resolveForwardRef(type);
26660 if (!getComponentDef(type)) {
26661 errors.push(stringifyForError(type) + " cannot be used as an entry component.");
26662 }
26663 }
26664 function verifyComponentEntryComponentsIsPartOfNgModule(type) {
26665 type = resolveForwardRef(type);
26666 if (getComponentDef(type)) {
26667 // We know we are component
26668 var component = getAnnotation(type, 'Component');
26669 if (component && component.entryComponents) {
26670 deepForEach(component.entryComponents, verifyComponentIsPartOfNgModule);
26671 }
26672 }
26673 }
26674 function verifySemanticsOfNgModuleImport(type, importingModule) {
26675 type = resolveForwardRef(type);
26676 if (getComponentDef(type) || getDirectiveDef(type)) {
26677 throw new Error("Unexpected directive '" + type.name + "' imported by the module '" + importingModule.name + "'. Please add an @NgModule annotation.");
26678 }
26679 if (getPipeDef(type)) {
26680 throw new Error("Unexpected pipe '" + type.name + "' imported by the module '" + importingModule.name + "'. Please add an @NgModule annotation.");
26681 }
26682 }
26683 }
26684 function unwrapModuleWithProvidersImports(typeOrWithProviders) {
26685 typeOrWithProviders = resolveForwardRef(typeOrWithProviders);
26686 return typeOrWithProviders.ngModule || typeOrWithProviders;
26687 }
26688 function getAnnotation(type, name) {
26689 var annotation = null;
26690 collect(type.__annotations__);
26691 collect(type.decorators);
26692 return annotation;
26693 function collect(annotations) {
26694 if (annotations) {
26695 annotations.forEach(readAnnotation);
26696 }
26697 }
26698 function readAnnotation(decorator) {
26699 if (!annotation) {
26700 var proto = Object.getPrototypeOf(decorator);
26701 if (proto.ngMetadataName == name) {
26702 annotation = decorator;
26703 }
26704 else if (decorator.type) {
26705 var proto_1 = Object.getPrototypeOf(decorator.type);
26706 if (proto_1.ngMetadataName == name) {
26707 annotation = decorator.args[0];
26708 }
26709 }
26710 }
26711 }
26712 }
26713 /**
26714 * Keep track of compiled components. This is needed because in tests we often want to compile the
26715 * same component with more than one NgModule. This would cause an error unless we reset which
26716 * NgModule the component belongs to. We keep the list of compiled components here so that the
26717 * TestBed can reset it later.
26718 */
26719 var ownerNgModule = new Map();
26720 var verifiedNgModule = new Map();
26721 function resetCompiledComponents() {
26722 ownerNgModule = new Map();
26723 verifiedNgModule = new Map();
26724 moduleQueue.length = 0;
26725 }
26726 /**
26727 * Computes the combined declarations of explicit declarations, as well as declarations inherited by
26728 * traversing the exports of imported modules.
26729 * @param type
26730 */
26731 function computeCombinedExports(type) {
26732 type = resolveForwardRef(type);
26733 var ngModuleDef = getNgModuleDef(type, true);
26734 return __spread(flatten(maybeUnwrapFn(ngModuleDef.exports).map(function (type) {
26735 var ngModuleDef = getNgModuleDef(type);
26736 if (ngModuleDef) {
26737 verifySemanticsOfNgModuleDef(type, false);
26738 return computeCombinedExports(type);
26739 }
26740 else {
26741 return type;
26742 }
26743 })));
26744 }
26745 /**
26746 * Some declared components may be compiled asynchronously, and thus may not have their
26747 * ɵcmp set yet. If this is the case, then a reference to the module is written into
26748 * the `ngSelectorScope` property of the declared type.
26749 */
26750 function setScopeOnDeclaredComponents(moduleType, ngModule) {
26751 var declarations = flatten(ngModule.declarations || EMPTY_ARRAY$5);
26752 var transitiveScopes = transitiveScopesFor(moduleType);
26753 declarations.forEach(function (declaration) {
26754 if (declaration.hasOwnProperty(NG_COMP_DEF)) {
26755 // A `ɵcmp` field exists - go ahead and patch the component directly.
26756 var component = declaration;
26757 var componentDef = getComponentDef(component);
26758 patchComponentDefWithScope(componentDef, transitiveScopes);
26759 }
26760 else if (!declaration.hasOwnProperty(NG_DIR_DEF) && !declaration.hasOwnProperty(NG_PIPE_DEF)) {
26761 // Set `ngSelectorScope` for future reference when the component compilation finishes.
26762 declaration.ngSelectorScope = moduleType;
26763 }
26764 });
26765 }
26766 /**
26767 * Patch the definition of a component with directives and pipes from the compilation scope of
26768 * a given module.
26769 */
26770 function patchComponentDefWithScope(componentDef, transitiveScopes) {
26771 componentDef.directiveDefs = function () { return Array.from(transitiveScopes.compilation.directives)
26772 .map(function (dir) { return dir.hasOwnProperty(NG_COMP_DEF) ? getComponentDef(dir) : getDirectiveDef(dir); })
26773 .filter(function (def) { return !!def; }); };
26774 componentDef.pipeDefs = function () { return Array.from(transitiveScopes.compilation.pipes).map(function (pipe) { return getPipeDef(pipe); }); };
26775 componentDef.schemas = transitiveScopes.schemas;
26776 // Since we avoid Components/Directives/Pipes recompiling in case there are no overrides, we
26777 // may face a problem where previously compiled defs available to a given Component/Directive
26778 // are cached in TView and may become stale (in case any of these defs gets recompiled). In
26779 // order to avoid this problem, we force fresh TView to be created.
26780 componentDef.tView = null;
26781 }
26782 /**
26783 * Compute the pair of transitive scopes (compilation scope and exported scope) for a given module.
26784 *
26785 * This operation is memoized and the result is cached on the module's definition. This function can
26786 * be called on modules with components that have not fully compiled yet, but the result should not
26787 * be used until they have.
26788 *
26789 * @param moduleType module that transitive scope should be calculated for.
26790 */
26791 function transitiveScopesFor(moduleType) {
26792 if (!isNgModule(moduleType)) {
26793 throw new Error(moduleType.name + " does not have a module def (\u0275mod property)");
26794 }
26795 var def = getNgModuleDef(moduleType);
26796 if (def.transitiveCompileScopes !== null) {
26797 return def.transitiveCompileScopes;
26798 }
26799 var scopes = {
26800 schemas: def.schemas || null,
26801 compilation: {
26802 directives: new Set(),
26803 pipes: new Set(),
26804 },
26805 exported: {
26806 directives: new Set(),
26807 pipes: new Set(),
26808 },
26809 };
26810 maybeUnwrapFn(def.imports).forEach(function (imported) {
26811 var importedType = imported;
26812 if (!isNgModule(importedType)) {
26813 throw new Error("Importing " + importedType.name + " which does not have a \u0275mod property");
26814 }
26815 // When this module imports another, the imported module's exported directives and pipes are
26816 // added to the compilation scope of this module.
26817 var importedScope = transitiveScopesFor(importedType);
26818 importedScope.exported.directives.forEach(function (entry) { return scopes.compilation.directives.add(entry); });
26819 importedScope.exported.pipes.forEach(function (entry) { return scopes.compilation.pipes.add(entry); });
26820 });
26821 maybeUnwrapFn(def.declarations).forEach(function (declared) {
26822 var declaredWithDefs = declared;
26823 if (getPipeDef(declaredWithDefs)) {
26824 scopes.compilation.pipes.add(declared);
26825 }
26826 else {
26827 // Either declared has a ɵcmp or ɵdir, or it's a component which hasn't
26828 // had its template compiled yet. In either case, it gets added to the compilation's
26829 // directives.
26830 scopes.compilation.directives.add(declared);
26831 }
26832 });
26833 maybeUnwrapFn(def.exports).forEach(function (exported) {
26834 var exportedType = exported;
26835 // Either the type is a module, a pipe, or a component/directive (which may not have a
26836 // ɵcmp as it might be compiled asynchronously).
26837 if (isNgModule(exportedType)) {
26838 // When this module exports another, the exported module's exported directives and pipes are
26839 // added to both the compilation and exported scopes of this module.
26840 var exportedScope = transitiveScopesFor(exportedType);
26841 exportedScope.exported.directives.forEach(function (entry) {
26842 scopes.compilation.directives.add(entry);
26843 scopes.exported.directives.add(entry);
26844 });
26845 exportedScope.exported.pipes.forEach(function (entry) {
26846 scopes.compilation.pipes.add(entry);
26847 scopes.exported.pipes.add(entry);
26848 });
26849 }
26850 else if (getPipeDef(exportedType)) {
26851 scopes.exported.pipes.add(exportedType);
26852 }
26853 else {
26854 scopes.exported.directives.add(exportedType);
26855 }
26856 });
26857 def.transitiveCompileScopes = scopes;
26858 return scopes;
26859 }
26860 function expandModuleWithProviders(value) {
26861 if (isModuleWithProviders(value)) {
26862 return value.ngModule;
26863 }
26864 return value;
26865 }
26866 function isModuleWithProviders(value) {
26867 return value.ngModule !== undefined;
26868 }
26869 function isNgModule(value) {
26870 return !!getNgModuleDef(value);
26871 }
26872
26873 /**
26874 * @license
26875 * Copyright Google LLC All Rights Reserved.
26876 *
26877 * Use of this source code is governed by an MIT-style license that can be
26878 * found in the LICENSE file at https://angular.io/license
26879 */
26880 /**
26881 * Keep track of the compilation depth to avoid reentrancy issues during JIT compilation. This
26882 * matters in the following scenario:
26883 *
26884 * Consider a component 'A' that extends component 'B', both declared in module 'M'. During
26885 * the compilation of 'A' the definition of 'B' is requested to capture the inheritance chain,
26886 * potentially triggering compilation of 'B'. If this nested compilation were to trigger
26887 * `flushModuleScopingQueueAsMuchAsPossible` it may happen that module 'M' is still pending in the
26888 * queue, resulting in 'A' and 'B' to be patched with the NgModule scope. As the compilation of
26889 * 'A' is still in progress, this would introduce a circular dependency on its compilation. To avoid
26890 * this issue, the module scope queue is only flushed for compilations at the depth 0, to ensure
26891 * all compilations have finished.
26892 */
26893 var compilationDepth = 0;
26894 /**
26895 * Compile an Angular component according to its decorator metadata, and patch the resulting
26896 * component def (ɵcmp) onto the component type.
26897 *
26898 * Compilation may be asynchronous (due to the need to resolve URLs for the component template or
26899 * other resources, for example). In the event that compilation is not immediate, `compileComponent`
26900 * will enqueue resource resolution into a global queue and will fail to return the `ɵcmp`
26901 * until the global queue has been resolved with a call to `resolveComponentResources`.
26902 */
26903 function compileComponent(type, metadata) {
26904 // Initialize ngDevMode. This must be the first statement in compileComponent.
26905 // See the `initNgDevMode` docstring for more information.
26906 (typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode();
26907 var ngComponentDef = null;
26908 // Metadata may have resources which need to be resolved.
26909 maybeQueueResolutionOfComponentResources(type, metadata);
26910 // Note that we're using the same function as `Directive`, because that's only subset of metadata
26911 // that we need to create the ngFactoryDef. We're avoiding using the component metadata
26912 // because we'd have to resolve the asynchronous templates.
26913 addDirectiveFactoryDef(type, metadata);
26914 Object.defineProperty(type, NG_COMP_DEF, {
26915 get: function () {
26916 if (ngComponentDef === null) {
26917 var compiler = getCompilerFacade();
26918 if (componentNeedsResolution(metadata)) {
26919 var error = ["Component '" + type.name + "' is not resolved:"];
26920 if (metadata.templateUrl) {
26921 error.push(" - templateUrl: " + metadata.templateUrl);
26922 }
26923 if (metadata.styleUrls && metadata.styleUrls.length) {
26924 error.push(" - styleUrls: " + JSON.stringify(metadata.styleUrls));
26925 }
26926 error.push("Did you run and wait for 'resolveComponentResources()'?");
26927 throw new Error(error.join('\n'));
26928 }
26929 // This const was called `jitOptions` previously but had to be renamed to `options` because
26930 // of a bug with Terser that caused optimized JIT builds to throw a `ReferenceError`.
26931 // This bug was investigated in https://github.com/angular/angular-cli/issues/17264.
26932 // We should not rename it back until https://github.com/terser/terser/issues/615 is fixed.
26933 var options = getJitOptions();
26934 var preserveWhitespaces = metadata.preserveWhitespaces;
26935 if (preserveWhitespaces === undefined) {
26936 if (options !== null && options.preserveWhitespaces !== undefined) {
26937 preserveWhitespaces = options.preserveWhitespaces;
26938 }
26939 else {
26940 preserveWhitespaces = false;
26941 }
26942 }
26943 var encapsulation = metadata.encapsulation;
26944 if (encapsulation === undefined) {
26945 if (options !== null && options.defaultEncapsulation !== undefined) {
26946 encapsulation = options.defaultEncapsulation;
26947 }
26948 else {
26949 encapsulation = exports.ViewEncapsulation.Emulated;
26950 }
26951 }
26952 var templateUrl = metadata.templateUrl || "ng:///" + type.name + "/template.html";
26953 var meta = Object.assign(Object.assign({}, directiveMetadata(type, metadata)), { typeSourceSpan: compiler.createParseSourceSpan('Component', type.name, templateUrl), template: metadata.template || '', preserveWhitespaces: preserveWhitespaces, styles: metadata.styles || EMPTY_ARRAY, animations: metadata.animations, directives: [], changeDetection: metadata.changeDetection, pipes: new Map(), encapsulation: encapsulation, interpolation: metadata.interpolation, viewProviders: metadata.viewProviders || null });
26954 compilationDepth++;
26955 try {
26956 if (meta.usesInheritance) {
26957 addDirectiveDefToUndecoratedParents(type);
26958 }
26959 ngComponentDef = compiler.compileComponent(angularCoreEnv, templateUrl, meta);
26960 }
26961 finally {
26962 // Ensure that the compilation depth is decremented even when the compilation failed.
26963 compilationDepth--;
26964 }
26965 if (compilationDepth === 0) {
26966 // When NgModule decorator executed, we enqueued the module definition such that
26967 // it would only dequeue and add itself as module scope to all of its declarations,
26968 // but only if if all of its declarations had resolved. This call runs the check
26969 // to see if any modules that are in the queue can be dequeued and add scope to
26970 // their declarations.
26971 flushModuleScopingQueueAsMuchAsPossible();
26972 }
26973 // If component compilation is async, then the @NgModule annotation which declares the
26974 // component may execute and set an ngSelectorScope property on the component type. This
26975 // allows the component to patch itself with directiveDefs from the module after it
26976 // finishes compiling.
26977 if (hasSelectorScope(type)) {
26978 var scopes = transitiveScopesFor(type.ngSelectorScope);
26979 patchComponentDefWithScope(ngComponentDef, scopes);
26980 }
26981 }
26982 return ngComponentDef;
26983 },
26984 // Make the property configurable in dev mode to allow overriding in tests
26985 configurable: !!ngDevMode,
26986 });
26987 }
26988 function hasSelectorScope(component) {
26989 return component.ngSelectorScope !== undefined;
26990 }
26991 /**
26992 * Compile an Angular directive according to its decorator metadata, and patch the resulting
26993 * directive def onto the component type.
26994 *
26995 * In the event that compilation is not immediate, `compileDirective` will return a `Promise` which
26996 * will resolve when compilation completes and the directive becomes usable.
26997 */
26998 function compileDirective(type, directive) {
26999 var ngDirectiveDef = null;
27000 addDirectiveFactoryDef(type, directive || {});
27001 Object.defineProperty(type, NG_DIR_DEF, {
27002 get: function () {
27003 if (ngDirectiveDef === null) {
27004 // `directive` can be null in the case of abstract directives as a base class
27005 // that use `@Directive()` with no selector. In that case, pass empty object to the
27006 // `directiveMetadata` function instead of null.
27007 var meta = getDirectiveMetadata(type, directive || {});
27008 ngDirectiveDef =
27009 getCompilerFacade().compileDirective(angularCoreEnv, meta.sourceMapUrl, meta.metadata);
27010 }
27011 return ngDirectiveDef;
27012 },
27013 // Make the property configurable in dev mode to allow overriding in tests
27014 configurable: !!ngDevMode,
27015 });
27016 }
27017 function getDirectiveMetadata(type, metadata) {
27018 var name = type && type.name;
27019 var sourceMapUrl = "ng:///" + name + "/\u0275dir.js";
27020 var compiler = getCompilerFacade();
27021 var facade = directiveMetadata(type, metadata);
27022 facade.typeSourceSpan = compiler.createParseSourceSpan('Directive', name, sourceMapUrl);
27023 if (facade.usesInheritance) {
27024 addDirectiveDefToUndecoratedParents(type);
27025 }
27026 return { metadata: facade, sourceMapUrl: sourceMapUrl };
27027 }
27028 function addDirectiveFactoryDef(type, metadata) {
27029 var ngFactoryDef = null;
27030 Object.defineProperty(type, NG_FACTORY_DEF, {
27031 get: function () {
27032 if (ngFactoryDef === null) {
27033 var meta = getDirectiveMetadata(type, metadata);
27034 var compiler = getCompilerFacade();
27035 ngFactoryDef = compiler.compileFactory(angularCoreEnv, "ng:///" + type.name + "/\u0275fac.js", Object.assign(Object.assign({}, meta.metadata), { injectFn: 'directiveInject', target: compiler.R3FactoryTarget.Directive }));
27036 }
27037 return ngFactoryDef;
27038 },
27039 // Make the property configurable in dev mode to allow overriding in tests
27040 configurable: !!ngDevMode,
27041 });
27042 }
27043 function extendsDirectlyFromObject(type) {
27044 return Object.getPrototypeOf(type.prototype) === Object.prototype;
27045 }
27046 /**
27047 * Extract the `R3DirectiveMetadata` for a particular directive (either a `Directive` or a
27048 * `Component`).
27049 */
27050 function directiveMetadata(type, metadata) {
27051 // Reflect inputs and outputs.
27052 var reflect = getReflect();
27053 var propMetadata = reflect.ownPropMetadata(type);
27054 return {
27055 name: type.name,
27056 type: type,
27057 typeArgumentCount: 0,
27058 selector: metadata.selector !== undefined ? metadata.selector : null,
27059 deps: reflectDependencies(type),
27060 host: metadata.host || EMPTY_OBJ,
27061 propMetadata: propMetadata,
27062 inputs: metadata.inputs || EMPTY_ARRAY,
27063 outputs: metadata.outputs || EMPTY_ARRAY,
27064 queries: extractQueriesMetadata(type, propMetadata, isContentQuery),
27065 lifecycle: { usesOnChanges: reflect.hasLifecycleHook(type, 'ngOnChanges') },
27066 typeSourceSpan: null,
27067 usesInheritance: !extendsDirectlyFromObject(type),
27068 exportAs: extractExportAs(metadata.exportAs),
27069 providers: metadata.providers || null,
27070 viewQueries: extractQueriesMetadata(type, propMetadata, isViewQuery)
27071 };
27072 }
27073 /**
27074 * Adds a directive definition to all parent classes of a type that don't have an Angular decorator.
27075 */
27076 function addDirectiveDefToUndecoratedParents(type) {
27077 var objPrototype = Object.prototype;
27078 var parent = Object.getPrototypeOf(type.prototype).constructor;
27079 // Go up the prototype until we hit `Object`.
27080 while (parent && parent !== objPrototype) {
27081 // Since inheritance works if the class was annotated already, we only need to add
27082 // the def if there are no annotations and the def hasn't been created already.
27083 if (!getDirectiveDef(parent) && !getComponentDef(parent) &&
27084 shouldAddAbstractDirective(parent)) {
27085 compileDirective(parent, null);
27086 }
27087 parent = Object.getPrototypeOf(parent);
27088 }
27089 }
27090 function convertToR3QueryPredicate(selector) {
27091 return typeof selector === 'string' ? splitByComma(selector) : resolveForwardRef(selector);
27092 }
27093 function convertToR3QueryMetadata(propertyName, ann) {
27094 return {
27095 propertyName: propertyName,
27096 predicate: convertToR3QueryPredicate(ann.selector),
27097 descendants: ann.descendants,
27098 first: ann.first,
27099 read: ann.read ? ann.read : null,
27100 static: !!ann.static
27101 };
27102 }
27103 function extractQueriesMetadata(type, propMetadata, isQueryAnn) {
27104 var queriesMeta = [];
27105 var _loop_1 = function (field) {
27106 if (propMetadata.hasOwnProperty(field)) {
27107 var annotations_1 = propMetadata[field];
27108 annotations_1.forEach(function (ann) {
27109 if (isQueryAnn(ann)) {
27110 if (!ann.selector) {
27111 throw new Error("Can't construct a query for the property \"" + field + "\" of " +
27112 ("\"" + stringifyForError(type) + "\" since the query selector wasn't defined."));
27113 }
27114 if (annotations_1.some(isInputAnnotation)) {
27115 throw new Error("Cannot combine @Input decorators with query decorators");
27116 }
27117 queriesMeta.push(convertToR3QueryMetadata(field, ann));
27118 }
27119 });
27120 }
27121 };
27122 for (var field in propMetadata) {
27123 _loop_1(field);
27124 }
27125 return queriesMeta;
27126 }
27127 function extractExportAs(exportAs) {
27128 return exportAs === undefined ? null : splitByComma(exportAs);
27129 }
27130 function isContentQuery(value) {
27131 var name = value.ngMetadataName;
27132 return name === 'ContentChild' || name === 'ContentChildren';
27133 }
27134 function isViewQuery(value) {
27135 var name = value.ngMetadataName;
27136 return name === 'ViewChild' || name === 'ViewChildren';
27137 }
27138 function isInputAnnotation(value) {
27139 return value.ngMetadataName === 'Input';
27140 }
27141 function splitByComma(value) {
27142 return value.split(',').map(function (piece) { return piece.trim(); });
27143 }
27144 var LIFECYCLE_HOOKS = [
27145 'ngOnChanges', 'ngOnInit', 'ngOnDestroy', 'ngDoCheck', 'ngAfterViewInit', 'ngAfterViewChecked',
27146 'ngAfterContentInit', 'ngAfterContentChecked'
27147 ];
27148 function shouldAddAbstractDirective(type) {
27149 var reflect = getReflect();
27150 if (LIFECYCLE_HOOKS.some(function (hookName) { return reflect.hasLifecycleHook(type, hookName); })) {
27151 return true;
27152 }
27153 var propMetadata = reflect.propMetadata(type);
27154 for (var field in propMetadata) {
27155 var annotations = propMetadata[field];
27156 for (var i = 0; i < annotations.length; i++) {
27157 var current = annotations[i];
27158 var metadataName = current.ngMetadataName;
27159 if (isInputAnnotation(current) || isContentQuery(current) || isViewQuery(current) ||
27160 metadataName === 'Output' || metadataName === 'HostBinding' ||
27161 metadataName === 'HostListener') {
27162 return true;
27163 }
27164 }
27165 }
27166 return false;
27167 }
27168
27169 /**
27170 * @license
27171 * Copyright Google LLC All Rights Reserved.
27172 *
27173 * Use of this source code is governed by an MIT-style license that can be
27174 * found in the LICENSE file at https://angular.io/license
27175 */
27176 function compilePipe(type, meta) {
27177 var ngPipeDef = null;
27178 var ngFactoryDef = null;
27179 Object.defineProperty(type, NG_FACTORY_DEF, {
27180 get: function () {
27181 if (ngFactoryDef === null) {
27182 var metadata = getPipeMetadata(type, meta);
27183 var compiler = getCompilerFacade();
27184 ngFactoryDef = compiler.compileFactory(angularCoreEnv, "ng:///" + metadata.name + "/\u0275fac.js", Object.assign(Object.assign({}, metadata), { injectFn: 'directiveInject', target: compiler.R3FactoryTarget.Pipe }));
27185 }
27186 return ngFactoryDef;
27187 },
27188 // Make the property configurable in dev mode to allow overriding in tests
27189 configurable: !!ngDevMode,
27190 });
27191 Object.defineProperty(type, NG_PIPE_DEF, {
27192 get: function () {
27193 if (ngPipeDef === null) {
27194 var metadata = getPipeMetadata(type, meta);
27195 ngPipeDef = getCompilerFacade().compilePipe(angularCoreEnv, "ng:///" + metadata.name + "/\u0275pipe.js", metadata);
27196 }
27197 return ngPipeDef;
27198 },
27199 // Make the property configurable in dev mode to allow overriding in tests
27200 configurable: !!ngDevMode,
27201 });
27202 }
27203 function getPipeMetadata(type, meta) {
27204 return {
27205 type: type,
27206 typeArgumentCount: 0,
27207 name: type.name,
27208 deps: reflectDependencies(type),
27209 pipeName: meta.name,
27210 pure: meta.pure !== undefined ? meta.pure : true
27211 };
27212 }
27213
27214 /**
27215 * @license
27216 * Copyright Google LLC All Rights Reserved.
27217 *
27218 * Use of this source code is governed by an MIT-style license that can be
27219 * found in the LICENSE file at https://angular.io/license
27220 */
27221 var ɵ0$e = function (dir) {
27222 if (dir === void 0) { dir = {}; }
27223 return dir;
27224 }, ɵ1$3 = function (type, meta) { return SWITCH_COMPILE_DIRECTIVE(type, meta); };
27225 /**
27226 * Type of the Directive metadata.
27227 *
27228 * @publicApi
27229 */
27230 var Directive = makeDecorator('Directive', ɵ0$e, undefined, undefined, ɵ1$3);
27231 var ɵ2$1 = function (c) {
27232 if (c === void 0) { c = {}; }
27233 return (Object.assign({ changeDetection: exports.ChangeDetectionStrategy.Default }, c));
27234 }, ɵ3$1 = function (type, meta) { return SWITCH_COMPILE_COMPONENT(type, meta); };
27235 /**
27236 * Component decorator and metadata.
27237 *
27238 * @Annotation
27239 * @publicApi
27240 */
27241 var Component = makeDecorator('Component', ɵ2$1, Directive, undefined, ɵ3$1);
27242 var ɵ4 = function (p) { return (Object.assign({ pure: true }, p)); }, ɵ5 = function (type, meta) { return SWITCH_COMPILE_PIPE(type, meta); };
27243 /**
27244 * @Annotation
27245 * @publicApi
27246 */
27247 var Pipe = makeDecorator('Pipe', ɵ4, undefined, undefined, ɵ5);
27248 var ɵ6 = function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); };
27249 /**
27250 * @Annotation
27251 * @publicApi
27252 */
27253 var Input = makePropDecorator('Input', ɵ6);
27254 var ɵ7 = function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); };
27255 /**
27256 * @Annotation
27257 * @publicApi
27258 */
27259 var Output = makePropDecorator('Output', ɵ7);
27260 var ɵ8 = function (hostPropertyName) { return ({ hostPropertyName: hostPropertyName }); };
27261 /**
27262 * @Annotation
27263 * @publicApi
27264 */
27265 var HostBinding = makePropDecorator('HostBinding', ɵ8);
27266 var ɵ9 = function (eventName, args) { return ({ eventName: eventName, args: args }); };
27267 /**
27268 * Decorator that binds a DOM event to a host listener and supplies configuration metadata.
27269 * Angular invokes the supplied handler method when the host element emits the specified event,
27270 * and updates the bound element with the result.
27271 *
27272 * If the handler method returns false, applies `preventDefault` on the bound element.
27273 *
27274 * @usageNotes
27275 *
27276 * The following example declares a directive
27277 * that attaches a click listener to a button and counts clicks.
27278 *
27279 * ```ts
27280 * @Directive({selector: 'button[counting]'})
27281 * class CountClicks {
27282 * numberOfClicks = 0;
27283 *
27284 * @HostListener('click', ['$event.target'])
27285 * onClick(btn) {
27286 * console.log('button', btn, 'number of clicks:', this.numberOfClicks++);
27287 * }
27288 * }
27289 *
27290 * @Component({
27291 * selector: 'app',
27292 * template: '<button counting>Increment</button>',
27293 * })
27294 * class App {}
27295 *
27296 * ```
27297 *
27298 * The following example registers another DOM event handler that listens for key-press events.
27299 * ``` ts
27300 * import { HostListener, Component } from "@angular/core";
27301 *
27302 * @Component({
27303 * selector: 'app',
27304 * template: `<h1>Hello, you have pressed keys {{counter}} number of times!</h1> Press any key to
27305 * increment the counter.
27306 * <button (click)="resetCounter()">Reset Counter</button>`
27307 * })
27308 * class AppComponent {
27309 * counter = 0;
27310 * @HostListener('window:keydown', ['$event'])
27311 * handleKeyDown(event: KeyboardEvent) {
27312 * this.counter++;
27313 * }
27314 * resetCounter() {
27315 * this.counter = 0;
27316 * }
27317 * }
27318 * ```
27319 *
27320 * @Annotation
27321 * @publicApi
27322 */
27323 var HostListener = makePropDecorator('HostListener', ɵ9);
27324 var SWITCH_COMPILE_COMPONENT__POST_R3__ = compileComponent;
27325 var SWITCH_COMPILE_DIRECTIVE__POST_R3__ = compileDirective;
27326 var SWITCH_COMPILE_PIPE__POST_R3__ = compilePipe;
27327 var SWITCH_COMPILE_COMPONENT__PRE_R3__ = noop;
27328 var SWITCH_COMPILE_DIRECTIVE__PRE_R3__ = noop;
27329 var SWITCH_COMPILE_PIPE__PRE_R3__ = noop;
27330 var SWITCH_COMPILE_COMPONENT = SWITCH_COMPILE_COMPONENT__PRE_R3__;
27331 var SWITCH_COMPILE_DIRECTIVE = SWITCH_COMPILE_DIRECTIVE__PRE_R3__;
27332 var SWITCH_COMPILE_PIPE = SWITCH_COMPILE_PIPE__PRE_R3__;
27333
27334 var ɵ0$f = function (ngModule) { return ngModule; }, ɵ1$4 =
27335 /**
27336 * Decorator that marks the following class as an NgModule, and supplies
27337 * configuration metadata for it.
27338 *
27339 * * The `declarations` and `entryComponents` options configure the compiler
27340 * with information about what belongs to the NgModule.
27341 * * The `providers` options configures the NgModule's injector to provide
27342 * dependencies the NgModule members.
27343 * * The `imports` and `exports` options bring in members from other modules, and make
27344 * this module's members available to others.
27345 */
27346 function (type, meta) { return SWITCH_COMPILE_NGMODULE(type, meta); };
27347 /**
27348 * @Annotation
27349 * @publicApi
27350 */
27351 var NgModule = makeDecorator('NgModule', ɵ0$f, undefined, undefined, ɵ1$4);
27352 function preR3NgModuleCompile(moduleType, metadata) {
27353 var imports = (metadata && metadata.imports) || [];
27354 if (metadata && metadata.exports) {
27355 imports = __spread(imports, [metadata.exports]);
27356 }
27357 moduleType.ɵinj = ɵɵdefineInjector({
27358 factory: convertInjectableProviderToFactory(moduleType, { useClass: moduleType }),
27359 providers: metadata && metadata.providers,
27360 imports: imports,
27361 });
27362 }
27363 var SWITCH_COMPILE_NGMODULE__POST_R3__ = compileNgModule;
27364 var SWITCH_COMPILE_NGMODULE__PRE_R3__ = preR3NgModuleCompile;
27365 var SWITCH_COMPILE_NGMODULE = SWITCH_COMPILE_NGMODULE__PRE_R3__;
27366
27367 /**
27368 * @license
27369 * Copyright Google LLC All Rights Reserved.
27370 *
27371 * Use of this source code is governed by an MIT-style license that can be
27372 * found in the LICENSE file at https://angular.io/license
27373 */
27374
27375 /**
27376 * @license
27377 * Copyright Google LLC All Rights Reserved.
27378 *
27379 * Use of this source code is governed by an MIT-style license that can be
27380 * found in the LICENSE file at https://angular.io/license
27381 */
27382
27383 /**
27384 * @license
27385 * Copyright Google LLC All Rights Reserved.
27386 *
27387 * Use of this source code is governed by an MIT-style license that can be
27388 * found in the LICENSE file at https://angular.io/license
27389 */
27390 /**
27391 * A [DI token](guide/glossary#di-token "DI token definition") that you can use to provide
27392 * one or more initialization functions.
27393 *
27394 * The provided functions are injected at application startup and executed during
27395 * app initialization. If any of these functions returns a Promise, initialization
27396 * does not complete until the Promise is resolved.
27397 *
27398 * You can, for example, create a factory function that loads language data
27399 * or an external configuration, and provide that function to the `APP_INITIALIZER` token.
27400 * The function is executed during the application bootstrap process,
27401 * and the needed data is available on startup.
27402 *
27403 * @see `ApplicationInitStatus`
27404 *
27405 * @publicApi
27406 */
27407 var APP_INITIALIZER = new InjectionToken('Application Initializer');
27408 /**
27409 * A class that reflects the state of running {@link APP_INITIALIZER} functions.
27410 *
27411 * @publicApi
27412 */
27413 var ApplicationInitStatus = /** @class */ (function () {
27414 function ApplicationInitStatus(appInits) {
27415 var _this = this;
27416 this.appInits = appInits;
27417 this.initialized = false;
27418 this.done = false;
27419 this.donePromise = new Promise(function (res, rej) {
27420 _this.resolve = res;
27421 _this.reject = rej;
27422 });
27423 }
27424 /** @internal */
27425 ApplicationInitStatus.prototype.runInitializers = function () {
27426 var _this = this;
27427 if (this.initialized) {
27428 return;
27429 }
27430 var asyncInitPromises = [];
27431 var complete = function () {
27432 _this.done = true;
27433 _this.resolve();
27434 };
27435 if (this.appInits) {
27436 for (var i = 0; i < this.appInits.length; i++) {
27437 var initResult = this.appInits[i]();
27438 if (isPromise(initResult)) {
27439 asyncInitPromises.push(initResult);
27440 }
27441 }
27442 }
27443 Promise.all(asyncInitPromises)
27444 .then(function () {
27445 complete();
27446 })
27447 .catch(function (e) {
27448 _this.reject(e);
27449 });
27450 if (asyncInitPromises.length === 0) {
27451 complete();
27452 }
27453 this.initialized = true;
27454 };
27455 return ApplicationInitStatus;
27456 }());
27457 ApplicationInitStatus.decorators = [
27458 { type: Injectable }
27459 ];
27460 ApplicationInitStatus.ctorParameters = function () { return [
27461 { type: Array, decorators: [{ type: Inject, args: [APP_INITIALIZER,] }, { type: Optional }] }
27462 ]; };
27463
27464 /**
27465 * @license
27466 * Copyright Google LLC All Rights Reserved.
27467 *
27468 * Use of this source code is governed by an MIT-style license that can be
27469 * found in the LICENSE file at https://angular.io/license
27470 */
27471 /**
27472 * A [DI token](guide/glossary#di-token "DI token definition") representing a unique string ID, used
27473 * primarily for prefixing application attributes and CSS styles when
27474 * {@link ViewEncapsulation#Emulated ViewEncapsulation.Emulated} is being used.
27475 *
27476 * BY default, the value is randomly generated and assigned to the application by Angular.
27477 * To provide a custom ID value, use a DI provider <!-- TODO: provider --> to configure
27478 * the root {@link Injector} that uses this token.
27479 *
27480 * @publicApi
27481 */
27482 var APP_ID = new InjectionToken('AppId');
27483 function _appIdRandomProviderFactory() {
27484 return "" + _randomChar() + _randomChar() + _randomChar();
27485 }
27486 /**
27487 * Providers that generate a random `APP_ID_TOKEN`.
27488 * @publicApi
27489 */
27490 var APP_ID_RANDOM_PROVIDER = {
27491 provide: APP_ID,
27492 useFactory: _appIdRandomProviderFactory,
27493 deps: [],
27494 };
27495 function _randomChar() {
27496 return String.fromCharCode(97 + Math.floor(Math.random() * 25));
27497 }
27498 /**
27499 * A function that is executed when a platform is initialized.
27500 * @publicApi
27501 */
27502 var PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
27503 /**
27504 * A token that indicates an opaque platform ID.
27505 * @publicApi
27506 */
27507 var PLATFORM_ID = new InjectionToken('Platform ID');
27508 /**
27509 * A [DI token](guide/glossary#di-token "DI token definition") that provides a set of callbacks to
27510 * be called for every component that is bootstrapped.
27511 *
27512 * Each callback must take a `ComponentRef` instance and return nothing.
27513 *
27514 * `(componentRef: ComponentRef) => void`
27515 *
27516 * @publicApi
27517 */
27518 var APP_BOOTSTRAP_LISTENER = new InjectionToken('appBootstrapListener');
27519 /**
27520 * A [DI token](guide/glossary#di-token "DI token definition") that indicates the root directory of
27521 * the application
27522 * @publicApi
27523 */
27524 var PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
27525
27526 /**
27527 * @license
27528 * Copyright Google LLC All Rights Reserved.
27529 *
27530 * Use of this source code is governed by an MIT-style license that can be
27531 * found in the LICENSE file at https://angular.io/license
27532 */
27533 var Console = /** @class */ (function () {
27534 function Console() {
27535 }
27536 Console.prototype.log = function (message) {
27537 // tslint:disable-next-line:no-console
27538 console.log(message);
27539 };
27540 // Note: for reporting errors use `DOM.logError()` as it is platform specific
27541 Console.prototype.warn = function (message) {
27542 // tslint:disable-next-line:no-console
27543 console.warn(message);
27544 };
27545 return Console;
27546 }());
27547 Console.decorators = [
27548 { type: Injectable }
27549 ];
27550
27551 /**
27552 * @license
27553 * Copyright Google LLC All Rights Reserved.
27554 *
27555 * Use of this source code is governed by an MIT-style license that can be
27556 * found in the LICENSE file at https://angular.io/license
27557 */
27558 /**
27559 * Provide this token to set the locale of your application.
27560 * It is used for i18n extraction, by i18n pipes (DatePipe, I18nPluralPipe, CurrencyPipe,
27561 * DecimalPipe and PercentPipe) and by ICU expressions.
27562 *
27563 * See the [i18n guide](guide/i18n#setting-up-locale) for more information.
27564 *
27565 * @usageNotes
27566 * ### Example
27567 *
27568 * ```typescript
27569 * import { LOCALE_ID } from '@angular/core';
27570 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
27571 * import { AppModule } from './app/app.module';
27572 *
27573 * platformBrowserDynamic().bootstrapModule(AppModule, {
27574 * providers: [{provide: LOCALE_ID, useValue: 'en-US' }]
27575 * });
27576 * ```
27577 *
27578 * @publicApi
27579 */
27580 var LOCALE_ID$1 = new InjectionToken('LocaleId');
27581 /**
27582 * Provide this token to set the default currency code your application uses for
27583 * CurrencyPipe when there is no currency code passed into it. This is only used by
27584 * CurrencyPipe and has no relation to locale currency. Defaults to USD if not configured.
27585 *
27586 * See the [i18n guide](guide/i18n#setting-up-locale) for more information.
27587 *
27588 * <div class="alert is-helpful">
27589 *
27590 * **Deprecation notice:**
27591 *
27592 * The default currency code is currently always `USD` but this is deprecated from v9.
27593 *
27594 * **In v10 the default currency code will be taken from the current locale.**
27595 *
27596 * If you need the previous behavior then set it by creating a `DEFAULT_CURRENCY_CODE` provider in
27597 * your application `NgModule`:
27598 *
27599 * ```ts
27600 * {provide: DEFAULT_CURRENCY_CODE, useValue: 'USD'}
27601 * ```
27602 *
27603 * </div>
27604 *
27605 * @usageNotes
27606 * ### Example
27607 *
27608 * ```typescript
27609 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
27610 * import { AppModule } from './app/app.module';
27611 *
27612 * platformBrowserDynamic().bootstrapModule(AppModule, {
27613 * providers: [{provide: DEFAULT_CURRENCY_CODE, useValue: 'EUR' }]
27614 * });
27615 * ```
27616 *
27617 * @publicApi
27618 */
27619 var DEFAULT_CURRENCY_CODE = new InjectionToken('DefaultCurrencyCode');
27620 /**
27621 * Use this token at bootstrap to provide the content of your translation file (`xtb`,
27622 * `xlf` or `xlf2`) when you want to translate your application in another language.
27623 *
27624 * See the [i18n guide](guide/i18n#merge) for more information.
27625 *
27626 * @usageNotes
27627 * ### Example
27628 *
27629 * ```typescript
27630 * import { TRANSLATIONS } from '@angular/core';
27631 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
27632 * import { AppModule } from './app/app.module';
27633 *
27634 * // content of your translation file
27635 * const translations = '....';
27636 *
27637 * platformBrowserDynamic().bootstrapModule(AppModule, {
27638 * providers: [{provide: TRANSLATIONS, useValue: translations }]
27639 * });
27640 * ```
27641 *
27642 * @publicApi
27643 */
27644 var TRANSLATIONS = new InjectionToken('Translations');
27645 /**
27646 * Provide this token at bootstrap to set the format of your {@link TRANSLATIONS}: `xtb`,
27647 * `xlf` or `xlf2`.
27648 *
27649 * See the [i18n guide](guide/i18n#merge) for more information.
27650 *
27651 * @usageNotes
27652 * ### Example
27653 *
27654 * ```typescript
27655 * import { TRANSLATIONS_FORMAT } from '@angular/core';
27656 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
27657 * import { AppModule } from './app/app.module';
27658 *
27659 * platformBrowserDynamic().bootstrapModule(AppModule, {
27660 * providers: [{provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }]
27661 * });
27662 * ```
27663 *
27664 * @publicApi
27665 */
27666 var TRANSLATIONS_FORMAT = new InjectionToken('TranslationsFormat');
27667 (function (MissingTranslationStrategy) {
27668 MissingTranslationStrategy[MissingTranslationStrategy["Error"] = 0] = "Error";
27669 MissingTranslationStrategy[MissingTranslationStrategy["Warning"] = 1] = "Warning";
27670 MissingTranslationStrategy[MissingTranslationStrategy["Ignore"] = 2] = "Ignore";
27671 })(exports.MissingTranslationStrategy || (exports.MissingTranslationStrategy = {}));
27672
27673 /**
27674 * @license
27675 * Copyright Google LLC All Rights Reserved.
27676 *
27677 * Use of this source code is governed by an MIT-style license that can be
27678 * found in the LICENSE file at https://angular.io/license
27679 */
27680 var SWITCH_IVY_ENABLED__POST_R3__ = true;
27681 var SWITCH_IVY_ENABLED__PRE_R3__ = false;
27682 var ivyEnabled = SWITCH_IVY_ENABLED__PRE_R3__;
27683
27684 /**
27685 * @license
27686 * Copyright Google LLC All Rights Reserved.
27687 *
27688 * Use of this source code is governed by an MIT-style license that can be
27689 * found in the LICENSE file at https://angular.io/license
27690 */
27691 /**
27692 * Combination of NgModuleFactory and ComponentFactorys.
27693 *
27694 * @publicApi
27695 */
27696 var ModuleWithComponentFactories = /** @class */ (function () {
27697 function ModuleWithComponentFactories(ngModuleFactory, componentFactories) {
27698 this.ngModuleFactory = ngModuleFactory;
27699 this.componentFactories = componentFactories;
27700 }
27701 return ModuleWithComponentFactories;
27702 }());
27703 function _throwError() {
27704 throw new Error("Runtime compiler is not loaded");
27705 }
27706 var Compiler_compileModuleSync__PRE_R3__ = _throwError;
27707 var Compiler_compileModuleSync__POST_R3__ = function (moduleType) {
27708 return new NgModuleFactory$1(moduleType);
27709 };
27710 var Compiler_compileModuleSync = Compiler_compileModuleSync__PRE_R3__;
27711 var Compiler_compileModuleAsync__PRE_R3__ = _throwError;
27712 var Compiler_compileModuleAsync__POST_R3__ = function (moduleType) {
27713 return Promise.resolve(Compiler_compileModuleSync__POST_R3__(moduleType));
27714 };
27715 var Compiler_compileModuleAsync = Compiler_compileModuleAsync__PRE_R3__;
27716 var Compiler_compileModuleAndAllComponentsSync__PRE_R3__ = _throwError;
27717 var Compiler_compileModuleAndAllComponentsSync__POST_R3__ = function (moduleType) {
27718 var ngModuleFactory = Compiler_compileModuleSync__POST_R3__(moduleType);
27719 var moduleDef = getNgModuleDef(moduleType);
27720 var componentFactories = maybeUnwrapFn(moduleDef.declarations)
27721 .reduce(function (factories, declaration) {
27722 var componentDef = getComponentDef(declaration);
27723 componentDef && factories.push(new ComponentFactory$1(componentDef));
27724 return factories;
27725 }, []);
27726 return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
27727 };
27728 var Compiler_compileModuleAndAllComponentsSync = Compiler_compileModuleAndAllComponentsSync__PRE_R3__;
27729 var Compiler_compileModuleAndAllComponentsAsync__PRE_R3__ = _throwError;
27730 var Compiler_compileModuleAndAllComponentsAsync__POST_R3__ = function (moduleType) {
27731 return Promise.resolve(Compiler_compileModuleAndAllComponentsSync__POST_R3__(moduleType));
27732 };
27733 var Compiler_compileModuleAndAllComponentsAsync = Compiler_compileModuleAndAllComponentsAsync__PRE_R3__;
27734 /**
27735 * Low-level service for running the angular compiler during runtime
27736 * to create {@link ComponentFactory}s, which
27737 * can later be used to create and render a Component instance.
27738 *
27739 * Each `@NgModule` provides an own `Compiler` to its injector,
27740 * that will use the directives/pipes of the ng module for compilation
27741 * of components.
27742 *
27743 * @publicApi
27744 */
27745 var Compiler = /** @class */ (function () {
27746 function Compiler() {
27747 /**
27748 * Compiles the given NgModule and all of its components. All templates of the components listed
27749 * in `entryComponents` have to be inlined.
27750 */
27751 this.compileModuleSync = Compiler_compileModuleSync;
27752 /**
27753 * Compiles the given NgModule and all of its components
27754 */
27755 this.compileModuleAsync = Compiler_compileModuleAsync;
27756 /**
27757 * Same as {@link #compileModuleSync} but also creates ComponentFactories for all components.
27758 */
27759 this.compileModuleAndAllComponentsSync = Compiler_compileModuleAndAllComponentsSync;
27760 /**
27761 * Same as {@link #compileModuleAsync} but also creates ComponentFactories for all components.
27762 */
27763 this.compileModuleAndAllComponentsAsync = Compiler_compileModuleAndAllComponentsAsync;
27764 }
27765 /**
27766 * Clears all caches.
27767 */
27768 Compiler.prototype.clearCache = function () { };
27769 /**
27770 * Clears the cache for the given component/ngModule.
27771 */
27772 Compiler.prototype.clearCacheFor = function (type) { };
27773 /**
27774 * Returns the id for a given NgModule, if one is defined and known to the compiler.
27775 */
27776 Compiler.prototype.getModuleId = function (moduleType) {
27777 return undefined;
27778 };
27779 return Compiler;
27780 }());
27781 Compiler.decorators = [
27782 { type: Injectable }
27783 ];
27784 /**
27785 * Token to provide CompilerOptions in the platform injector.
27786 *
27787 * @publicApi
27788 */
27789 var COMPILER_OPTIONS = new InjectionToken('compilerOptions');
27790 /**
27791 * A factory for creating a Compiler
27792 *
27793 * @publicApi
27794 */
27795 var CompilerFactory = /** @class */ (function () {
27796 function CompilerFactory() {
27797 }
27798 return CompilerFactory;
27799 }());
27800
27801 /**
27802 * @license
27803 * Copyright Google LLC All Rights Reserved.
27804 *
27805 * Use of this source code is governed by an MIT-style license that can be
27806 * found in the LICENSE file at https://angular.io/license
27807 */
27808 var promise = (function () { return Promise.resolve(0); })();
27809 function scheduleMicroTask(fn) {
27810 if (typeof Zone === 'undefined') {
27811 // use promise to schedule microTask instead of use Zone
27812 promise.then(function () {
27813 fn && fn.apply(null, null);
27814 });
27815 }
27816 else {
27817 Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
27818 }
27819 }
27820
27821 /**
27822 * @license
27823 * Copyright Google LLC All Rights Reserved.
27824 *
27825 * Use of this source code is governed by an MIT-style license that can be
27826 * found in the LICENSE file at https://angular.io/license
27827 */
27828 function getNativeRequestAnimationFrame() {
27829 var nativeRequestAnimationFrame = _global['requestAnimationFrame'];
27830 var nativeCancelAnimationFrame = _global['cancelAnimationFrame'];
27831 if (typeof Zone !== 'undefined' && nativeRequestAnimationFrame && nativeCancelAnimationFrame) {
27832 // use unpatched version of requestAnimationFrame(native delegate) if possible
27833 // to avoid another Change detection
27834 var unpatchedRequestAnimationFrame = nativeRequestAnimationFrame[Zone.__symbol__('OriginalDelegate')];
27835 if (unpatchedRequestAnimationFrame) {
27836 nativeRequestAnimationFrame = unpatchedRequestAnimationFrame;
27837 }
27838 var unpatchedCancelAnimationFrame = nativeCancelAnimationFrame[Zone.__symbol__('OriginalDelegate')];
27839 if (unpatchedCancelAnimationFrame) {
27840 nativeCancelAnimationFrame = unpatchedCancelAnimationFrame;
27841 }
27842 }
27843 return { nativeRequestAnimationFrame: nativeRequestAnimationFrame, nativeCancelAnimationFrame: nativeCancelAnimationFrame };
27844 }
27845
27846 /**
27847 * @license
27848 * Copyright Google LLC All Rights Reserved.
27849 *
27850 * Use of this source code is governed by an MIT-style license that can be
27851 * found in the LICENSE file at https://angular.io/license
27852 */
27853 /**
27854 * An injectable service for executing work inside or outside of the Angular zone.
27855 *
27856 * The most common use of this service is to optimize performance when starting a work consisting of
27857 * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
27858 * Angular. Such tasks can be kicked off via {@link #runOutsideAngular} and if needed, these tasks
27859 * can reenter the Angular zone via {@link #run}.
27860 *
27861 * <!-- TODO: add/fix links to:
27862 * - docs explaining zones and the use of zones in Angular and change-detection
27863 * - link to runOutsideAngular/run (throughout this file!)
27864 * -->
27865 *
27866 * @usageNotes
27867 * ### Example
27868 *
27869 * ```
27870 * import {Component, NgZone} from '@angular/core';
27871 * import {NgIf} from '@angular/common';
27872 *
27873 * @Component({
27874 * selector: 'ng-zone-demo',
27875 * template: `
27876 * <h2>Demo: NgZone</h2>
27877 *
27878 * <p>Progress: {{progress}}%</p>
27879 * <p *ngIf="progress >= 100">Done processing {{label}} of Angular zone!</p>
27880 *
27881 * <button (click)="processWithinAngularZone()">Process within Angular zone</button>
27882 * <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
27883 * `,
27884 * })
27885 * export class NgZoneDemo {
27886 * progress: number = 0;
27887 * label: string;
27888 *
27889 * constructor(private _ngZone: NgZone) {}
27890 *
27891 * // Loop inside the Angular zone
27892 * // so the UI DOES refresh after each setTimeout cycle
27893 * processWithinAngularZone() {
27894 * this.label = 'inside';
27895 * this.progress = 0;
27896 * this._increaseProgress(() => console.log('Inside Done!'));
27897 * }
27898 *
27899 * // Loop outside of the Angular zone
27900 * // so the UI DOES NOT refresh after each setTimeout cycle
27901 * processOutsideOfAngularZone() {
27902 * this.label = 'outside';
27903 * this.progress = 0;
27904 * this._ngZone.runOutsideAngular(() => {
27905 * this._increaseProgress(() => {
27906 * // reenter the Angular zone and display done
27907 * this._ngZone.run(() => { console.log('Outside Done!'); });
27908 * });
27909 * });
27910 * }
27911 *
27912 * _increaseProgress(doneCallback: () => void) {
27913 * this.progress += 1;
27914 * console.log(`Current progress: ${this.progress}%`);
27915 *
27916 * if (this.progress < 100) {
27917 * window.setTimeout(() => this._increaseProgress(doneCallback), 10);
27918 * } else {
27919 * doneCallback();
27920 * }
27921 * }
27922 * }
27923 * ```
27924 *
27925 * @publicApi
27926 */
27927 var NgZone = /** @class */ (function () {
27928 function NgZone(_a) {
27929 var _b = _a.enableLongStackTrace, enableLongStackTrace = _b === void 0 ? false : _b, _c = _a.shouldCoalesceEventChangeDetection, shouldCoalesceEventChangeDetection = _c === void 0 ? false : _c;
27930 this.hasPendingMacrotasks = false;
27931 this.hasPendingMicrotasks = false;
27932 /**
27933 * Whether there are no outstanding microtasks or macrotasks.
27934 */
27935 this.isStable = true;
27936 /**
27937 * Notifies when code enters Angular Zone. This gets fired first on VM Turn.
27938 */
27939 this.onUnstable = new EventEmitter(false);
27940 /**
27941 * Notifies when there is no more microtasks enqueued in the current VM Turn.
27942 * This is a hint for Angular to do change detection, which may enqueue more microtasks.
27943 * For this reason this event can fire multiple times per VM Turn.
27944 */
27945 this.onMicrotaskEmpty = new EventEmitter(false);
27946 /**
27947 * Notifies when the last `onMicrotaskEmpty` has run and there are no more microtasks, which
27948 * implies we are about to relinquish VM turn.
27949 * This event gets called just once.
27950 */
27951 this.onStable = new EventEmitter(false);
27952 /**
27953 * Notifies that an error has been delivered.
27954 */
27955 this.onError = new EventEmitter(false);
27956 if (typeof Zone == 'undefined') {
27957 throw new Error("In this configuration Angular requires Zone.js");
27958 }
27959 Zone.assertZonePatched();
27960 var self = this;
27961 self._nesting = 0;
27962 self._outer = self._inner = Zone.current;
27963 if (Zone['wtfZoneSpec']) {
27964 self._inner = self._inner.fork(Zone['wtfZoneSpec']);
27965 }
27966 if (Zone['TaskTrackingZoneSpec']) {
27967 self._inner = self._inner.fork(new Zone['TaskTrackingZoneSpec']);
27968 }
27969 if (enableLongStackTrace && Zone['longStackTraceZoneSpec']) {
27970 self._inner = self._inner.fork(Zone['longStackTraceZoneSpec']);
27971 }
27972 self.shouldCoalesceEventChangeDetection = shouldCoalesceEventChangeDetection;
27973 self.lastRequestAnimationFrameId = -1;
27974 self.nativeRequestAnimationFrame = getNativeRequestAnimationFrame().nativeRequestAnimationFrame;
27975 forkInnerZoneWithAngularBehavior(self);
27976 }
27977 NgZone.isInAngularZone = function () {
27978 return Zone.current.get('isAngularZone') === true;
27979 };
27980 NgZone.assertInAngularZone = function () {
27981 if (!NgZone.isInAngularZone()) {
27982 throw new Error('Expected to be in Angular Zone, but it is not!');
27983 }
27984 };
27985 NgZone.assertNotInAngularZone = function () {
27986 if (NgZone.isInAngularZone()) {
27987 throw new Error('Expected to not be in Angular Zone, but it is!');
27988 }
27989 };
27990 /**
27991 * Executes the `fn` function synchronously within the Angular zone and returns value returned by
27992 * the function.
27993 *
27994 * Running functions via `run` allows you to reenter Angular zone from a task that was executed
27995 * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
27996 *
27997 * Any future tasks or microtasks scheduled from within this function will continue executing from
27998 * within the Angular zone.
27999 *
28000 * If a synchronous error happens it will be rethrown and not reported via `onError`.
28001 */
28002 NgZone.prototype.run = function (fn, applyThis, applyArgs) {
28003 return this._inner.run(fn, applyThis, applyArgs);
28004 };
28005 /**
28006 * Executes the `fn` function synchronously within the Angular zone as a task and returns value
28007 * returned by the function.
28008 *
28009 * Running functions via `run` allows you to reenter Angular zone from a task that was executed
28010 * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
28011 *
28012 * Any future tasks or microtasks scheduled from within this function will continue executing from
28013 * within the Angular zone.
28014 *
28015 * If a synchronous error happens it will be rethrown and not reported via `onError`.
28016 */
28017 NgZone.prototype.runTask = function (fn, applyThis, applyArgs, name) {
28018 var zone = this._inner;
28019 var task = zone.scheduleEventTask('NgZoneEvent: ' + name, fn, EMPTY_PAYLOAD, noop$1, noop$1);
28020 try {
28021 return zone.runTask(task, applyThis, applyArgs);
28022 }
28023 finally {
28024 zone.cancelTask(task);
28025 }
28026 };
28027 /**
28028 * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
28029 * rethrown.
28030 */
28031 NgZone.prototype.runGuarded = function (fn, applyThis, applyArgs) {
28032 return this._inner.runGuarded(fn, applyThis, applyArgs);
28033 };
28034 /**
28035 * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
28036 * the function.
28037 *
28038 * Running functions via {@link #runOutsideAngular} allows you to escape Angular's zone and do
28039 * work that
28040 * doesn't trigger Angular change-detection or is subject to Angular's error handling.
28041 *
28042 * Any future tasks or microtasks scheduled from within this function will continue executing from
28043 * outside of the Angular zone.
28044 *
28045 * Use {@link #run} to reenter the Angular zone and do work that updates the application model.
28046 */
28047 NgZone.prototype.runOutsideAngular = function (fn) {
28048 return this._outer.run(fn);
28049 };
28050 return NgZone;
28051 }());
28052 function noop$1() { }
28053 var EMPTY_PAYLOAD = {};
28054 function checkStable(zone) {
28055 if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) {
28056 try {
28057 zone._nesting++;
28058 zone.onMicrotaskEmpty.emit(null);
28059 }
28060 finally {
28061 zone._nesting--;
28062 if (!zone.hasPendingMicrotasks) {
28063 try {
28064 zone.runOutsideAngular(function () { return zone.onStable.emit(null); });
28065 }
28066 finally {
28067 zone.isStable = true;
28068 }
28069 }
28070 }
28071 }
28072 }
28073 function delayChangeDetectionForEvents(zone) {
28074 if (zone.lastRequestAnimationFrameId !== -1) {
28075 return;
28076 }
28077 zone.lastRequestAnimationFrameId = zone.nativeRequestAnimationFrame.call(_global, function () {
28078 // This is a work around for https://github.com/angular/angular/issues/36839.
28079 // The core issue is that when event coalescing is enabled it is possible for microtasks
28080 // to get flushed too early (As is the case with `Promise.then`) between the
28081 // coalescing eventTasks.
28082 //
28083 // To workaround this we schedule a "fake" eventTask before we process the
28084 // coalescing eventTasks. The benefit of this is that the "fake" container eventTask
28085 // will prevent the microtasks queue from getting drained in between the coalescing
28086 // eventTask execution.
28087 if (!zone.fakeTopEventTask) {
28088 zone.fakeTopEventTask = Zone.root.scheduleEventTask('fakeTopEventTask', function () {
28089 zone.lastRequestAnimationFrameId = -1;
28090 updateMicroTaskStatus(zone);
28091 checkStable(zone);
28092 }, undefined, function () { }, function () { });
28093 }
28094 zone.fakeTopEventTask.invoke();
28095 });
28096 updateMicroTaskStatus(zone);
28097 }
28098 function forkInnerZoneWithAngularBehavior(zone) {
28099 var delayChangeDetectionForEventsDelegate = function () {
28100 delayChangeDetectionForEvents(zone);
28101 };
28102 var maybeDelayChangeDetection = !!zone.shouldCoalesceEventChangeDetection &&
28103 zone.nativeRequestAnimationFrame && delayChangeDetectionForEventsDelegate;
28104 zone._inner = zone._inner.fork({
28105 name: 'angular',
28106 properties: { 'isAngularZone': true, 'maybeDelayChangeDetection': maybeDelayChangeDetection },
28107 onInvokeTask: function (delegate, current, target, task, applyThis, applyArgs) {
28108 try {
28109 onEnter(zone);
28110 return delegate.invokeTask(target, task, applyThis, applyArgs);
28111 }
28112 finally {
28113 if (maybeDelayChangeDetection && task.type === 'eventTask') {
28114 maybeDelayChangeDetection();
28115 }
28116 onLeave(zone);
28117 }
28118 },
28119 onInvoke: function (delegate, current, target, callback, applyThis, applyArgs, source) {
28120 try {
28121 onEnter(zone);
28122 return delegate.invoke(target, callback, applyThis, applyArgs, source);
28123 }
28124 finally {
28125 onLeave(zone);
28126 }
28127 },
28128 onHasTask: function (delegate, current, target, hasTaskState) {
28129 delegate.hasTask(target, hasTaskState);
28130 if (current === target) {
28131 // We are only interested in hasTask events which originate from our zone
28132 // (A child hasTask event is not interesting to us)
28133 if (hasTaskState.change == 'microTask') {
28134 zone._hasPendingMicrotasks = hasTaskState.microTask;
28135 updateMicroTaskStatus(zone);
28136 checkStable(zone);
28137 }
28138 else if (hasTaskState.change == 'macroTask') {
28139 zone.hasPendingMacrotasks = hasTaskState.macroTask;
28140 }
28141 }
28142 },
28143 onHandleError: function (delegate, current, target, error) {
28144 delegate.handleError(target, error);
28145 zone.runOutsideAngular(function () { return zone.onError.emit(error); });
28146 return false;
28147 }
28148 });
28149 }
28150 function updateMicroTaskStatus(zone) {
28151 if (zone._hasPendingMicrotasks ||
28152 (zone.shouldCoalesceEventChangeDetection && zone.lastRequestAnimationFrameId !== -1)) {
28153 zone.hasPendingMicrotasks = true;
28154 }
28155 else {
28156 zone.hasPendingMicrotasks = false;
28157 }
28158 }
28159 function onEnter(zone) {
28160 zone._nesting++;
28161 if (zone.isStable) {
28162 zone.isStable = false;
28163 zone.onUnstable.emit(null);
28164 }
28165 }
28166 function onLeave(zone) {
28167 zone._nesting--;
28168 checkStable(zone);
28169 }
28170 /**
28171 * Provides a noop implementation of `NgZone` which does nothing. This zone requires explicit calls
28172 * to framework to perform rendering.
28173 */
28174 var NoopNgZone = /** @class */ (function () {
28175 function NoopNgZone() {
28176 this.hasPendingMicrotasks = false;
28177 this.hasPendingMacrotasks = false;
28178 this.isStable = true;
28179 this.onUnstable = new EventEmitter();
28180 this.onMicrotaskEmpty = new EventEmitter();
28181 this.onStable = new EventEmitter();
28182 this.onError = new EventEmitter();
28183 }
28184 NoopNgZone.prototype.run = function (fn, applyThis, applyArgs) {
28185 return fn.apply(applyThis, applyArgs);
28186 };
28187 NoopNgZone.prototype.runGuarded = function (fn, applyThis, applyArgs) {
28188 return fn.apply(applyThis, applyArgs);
28189 };
28190 NoopNgZone.prototype.runOutsideAngular = function (fn) {
28191 return fn();
28192 };
28193 NoopNgZone.prototype.runTask = function (fn, applyThis, applyArgs, name) {
28194 return fn.apply(applyThis, applyArgs);
28195 };
28196 return NoopNgZone;
28197 }());
28198
28199 /**
28200 * @license
28201 * Copyright Google LLC All Rights Reserved.
28202 *
28203 * Use of this source code is governed by an MIT-style license that can be
28204 * found in the LICENSE file at https://angular.io/license
28205 */
28206 /**
28207 * The Testability service provides testing hooks that can be accessed from
28208 * the browser and by services such as Protractor. Each bootstrapped Angular
28209 * application on the page will have an instance of Testability.
28210 * @publicApi
28211 */
28212 var Testability = /** @class */ (function () {
28213 function Testability(_ngZone) {
28214 var _this = this;
28215 this._ngZone = _ngZone;
28216 this._pendingCount = 0;
28217 this._isZoneStable = true;
28218 /**
28219 * Whether any work was done since the last 'whenStable' callback. This is
28220 * useful to detect if this could have potentially destabilized another
28221 * component while it is stabilizing.
28222 * @internal
28223 */
28224 this._didWork = false;
28225 this._callbacks = [];
28226 this.taskTrackingZone = null;
28227 this._watchAngularEvents();
28228 _ngZone.run(function () {
28229 _this.taskTrackingZone =
28230 typeof Zone == 'undefined' ? null : Zone.current.get('TaskTrackingZone');
28231 });
28232 }
28233 Testability.prototype._watchAngularEvents = function () {
28234 var _this = this;
28235 this._ngZone.onUnstable.subscribe({
28236 next: function () {
28237 _this._didWork = true;
28238 _this._isZoneStable = false;
28239 }
28240 });
28241 this._ngZone.runOutsideAngular(function () {
28242 _this._ngZone.onStable.subscribe({
28243 next: function () {
28244 NgZone.assertNotInAngularZone();
28245 scheduleMicroTask(function () {
28246 _this._isZoneStable = true;
28247 _this._runCallbacksIfReady();
28248 });
28249 }
28250 });
28251 });
28252 };
28253 /**
28254 * Increases the number of pending request
28255 * @deprecated pending requests are now tracked with zones.
28256 */
28257 Testability.prototype.increasePendingRequestCount = function () {
28258 this._pendingCount += 1;
28259 this._didWork = true;
28260 return this._pendingCount;
28261 };
28262 /**
28263 * Decreases the number of pending request
28264 * @deprecated pending requests are now tracked with zones
28265 */
28266 Testability.prototype.decreasePendingRequestCount = function () {
28267 this._pendingCount -= 1;
28268 if (this._pendingCount < 0) {
28269 throw new Error('pending async requests below zero');
28270 }
28271 this._runCallbacksIfReady();
28272 return this._pendingCount;
28273 };
28274 /**
28275 * Whether an associated application is stable
28276 */
28277 Testability.prototype.isStable = function () {
28278 return this._isZoneStable && this._pendingCount === 0 && !this._ngZone.hasPendingMacrotasks;
28279 };
28280 Testability.prototype._runCallbacksIfReady = function () {
28281 var _this = this;
28282 if (this.isStable()) {
28283 // Schedules the call backs in a new frame so that it is always async.
28284 scheduleMicroTask(function () {
28285 while (_this._callbacks.length !== 0) {
28286 var cb = _this._callbacks.pop();
28287 clearTimeout(cb.timeoutId);
28288 cb.doneCb(_this._didWork);
28289 }
28290 _this._didWork = false;
28291 });
28292 }
28293 else {
28294 // Still not stable, send updates.
28295 var pending_1 = this.getPendingTasks();
28296 this._callbacks = this._callbacks.filter(function (cb) {
28297 if (cb.updateCb && cb.updateCb(pending_1)) {
28298 clearTimeout(cb.timeoutId);
28299 return false;
28300 }
28301 return true;
28302 });
28303 this._didWork = true;
28304 }
28305 };
28306 Testability.prototype.getPendingTasks = function () {
28307 if (!this.taskTrackingZone) {
28308 return [];
28309 }
28310 // Copy the tasks data so that we don't leak tasks.
28311 return this.taskTrackingZone.macroTasks.map(function (t) {
28312 return {
28313 source: t.source,
28314 // From TaskTrackingZone:
28315 // https://github.com/angular/zone.js/blob/master/lib/zone-spec/task-tracking.ts#L40
28316 creationLocation: t.creationLocation,
28317 data: t.data
28318 };
28319 });
28320 };
28321 Testability.prototype.addCallback = function (cb, timeout, updateCb) {
28322 var _this = this;
28323 var timeoutId = -1;
28324 if (timeout && timeout > 0) {
28325 timeoutId = setTimeout(function () {
28326 _this._callbacks = _this._callbacks.filter(function (cb) { return cb.timeoutId !== timeoutId; });
28327 cb(_this._didWork, _this.getPendingTasks());
28328 }, timeout);
28329 }
28330 this._callbacks.push({ doneCb: cb, timeoutId: timeoutId, updateCb: updateCb });
28331 };
28332 /**
28333 * Wait for the application to be stable with a timeout. If the timeout is reached before that
28334 * happens, the callback receives a list of the macro tasks that were pending, otherwise null.
28335 *
28336 * @param doneCb The callback to invoke when Angular is stable or the timeout expires
28337 * whichever comes first.
28338 * @param timeout Optional. The maximum time to wait for Angular to become stable. If not
28339 * specified, whenStable() will wait forever.
28340 * @param updateCb Optional. If specified, this callback will be invoked whenever the set of
28341 * pending macrotasks changes. If this callback returns true doneCb will not be invoked
28342 * and no further updates will be issued.
28343 */
28344 Testability.prototype.whenStable = function (doneCb, timeout, updateCb) {
28345 if (updateCb && !this.taskTrackingZone) {
28346 throw new Error('Task tracking zone is required when passing an update callback to ' +
28347 'whenStable(). Is "zone.js/dist/task-tracking.js" loaded?');
28348 }
28349 // These arguments are 'Function' above to keep the public API simple.
28350 this.addCallback(doneCb, timeout, updateCb);
28351 this._runCallbacksIfReady();
28352 };
28353 /**
28354 * Get the number of pending requests
28355 * @deprecated pending requests are now tracked with zones
28356 */
28357 Testability.prototype.getPendingRequestCount = function () {
28358 return this._pendingCount;
28359 };
28360 /**
28361 * Find providers by name
28362 * @param using The root element to search from
28363 * @param provider The name of binding variable
28364 * @param exactMatch Whether using exactMatch
28365 */
28366 Testability.prototype.findProviders = function (using, provider, exactMatch) {
28367 // TODO(juliemr): implement.
28368 return [];
28369 };
28370 return Testability;
28371 }());
28372 Testability.decorators = [
28373 { type: Injectable }
28374 ];
28375 Testability.ctorParameters = function () { return [
28376 { type: NgZone }
28377 ]; };
28378 /**
28379 * A global registry of {@link Testability} instances for specific elements.
28380 * @publicApi
28381 */
28382 var TestabilityRegistry = /** @class */ (function () {
28383 function TestabilityRegistry() {
28384 /** @internal */
28385 this._applications = new Map();
28386 _testabilityGetter.addToWindow(this);
28387 }
28388 /**
28389 * Registers an application with a testability hook so that it can be tracked
28390 * @param token token of application, root element
28391 * @param testability Testability hook
28392 */
28393 TestabilityRegistry.prototype.registerApplication = function (token, testability) {
28394 this._applications.set(token, testability);
28395 };
28396 /**
28397 * Unregisters an application.
28398 * @param token token of application, root element
28399 */
28400 TestabilityRegistry.prototype.unregisterApplication = function (token) {
28401 this._applications.delete(token);
28402 };
28403 /**
28404 * Unregisters all applications
28405 */
28406 TestabilityRegistry.prototype.unregisterAllApplications = function () {
28407 this._applications.clear();
28408 };
28409 /**
28410 * Get a testability hook associated with the application
28411 * @param elem root element
28412 */
28413 TestabilityRegistry.prototype.getTestability = function (elem) {
28414 return this._applications.get(elem) || null;
28415 };
28416 /**
28417 * Get all registered testabilities
28418 */
28419 TestabilityRegistry.prototype.getAllTestabilities = function () {
28420 return Array.from(this._applications.values());
28421 };
28422 /**
28423 * Get all registered applications(root elements)
28424 */
28425 TestabilityRegistry.prototype.getAllRootElements = function () {
28426 return Array.from(this._applications.keys());
28427 };
28428 /**
28429 * Find testability of a node in the Tree
28430 * @param elem node
28431 * @param findInAncestors whether finding testability in ancestors if testability was not found in
28432 * current node
28433 */
28434 TestabilityRegistry.prototype.findTestabilityInTree = function (elem, findInAncestors) {
28435 if (findInAncestors === void 0) { findInAncestors = true; }
28436 return _testabilityGetter.findTestabilityInTree(this, elem, findInAncestors);
28437 };
28438 return TestabilityRegistry;
28439 }());
28440 TestabilityRegistry.decorators = [
28441 { type: Injectable }
28442 ];
28443 TestabilityRegistry.ctorParameters = function () { return []; };
28444 var _NoopGetTestability = /** @class */ (function () {
28445 function _NoopGetTestability() {
28446 }
28447 _NoopGetTestability.prototype.addToWindow = function (registry) { };
28448 _NoopGetTestability.prototype.findTestabilityInTree = function (registry, elem, findInAncestors) {
28449 return null;
28450 };
28451 return _NoopGetTestability;
28452 }());
28453 /**
28454 * Set the {@link GetTestability} implementation used by the Angular testing framework.
28455 * @publicApi
28456 */
28457 function setTestabilityGetter(getter) {
28458 _testabilityGetter = getter;
28459 }
28460 var _testabilityGetter = new _NoopGetTestability();
28461
28462 var _platform;
28463 var compileNgModuleFactory = compileNgModuleFactory__PRE_R3__;
28464 function compileNgModuleFactory__PRE_R3__(injector, options, moduleType) {
28465 var compilerFactory = injector.get(CompilerFactory);
28466 var compiler = compilerFactory.createCompiler([options]);
28467 return compiler.compileModuleAsync(moduleType);
28468 }
28469 function compileNgModuleFactory__POST_R3__(injector, options, moduleType) {
28470 ngDevMode && assertNgModuleType(moduleType);
28471 var moduleFactory = new NgModuleFactory$1(moduleType);
28472 // All of the logic below is irrelevant for AOT-compiled code.
28473 if (typeof ngJitMode !== 'undefined' && !ngJitMode) {
28474 return Promise.resolve(moduleFactory);
28475 }
28476 var compilerOptions = injector.get(COMPILER_OPTIONS, []).concat(options);
28477 // Configure the compiler to use the provided options. This call may fail when multiple modules
28478 // are bootstrapped with incompatible options, as a component can only be compiled according to
28479 // a single set of options.
28480 setJitOptions({
28481 defaultEncapsulation: _lastDefined(compilerOptions.map(function (opts) { return opts.defaultEncapsulation; })),
28482 preserveWhitespaces: _lastDefined(compilerOptions.map(function (opts) { return opts.preserveWhitespaces; })),
28483 });
28484 if (isComponentResourceResolutionQueueEmpty()) {
28485 return Promise.resolve(moduleFactory);
28486 }
28487 var compilerProviders = _mergeArrays(compilerOptions.map(function (o) { return o.providers; }));
28488 // In case there are no compiler providers, we just return the module factory as
28489 // there won't be any resource loader. This can happen with Ivy, because AOT compiled
28490 // modules can be still passed through "bootstrapModule". In that case we shouldn't
28491 // unnecessarily require the JIT compiler.
28492 if (compilerProviders.length === 0) {
28493 return Promise.resolve(moduleFactory);
28494 }
28495 var compiler = getCompilerFacade();
28496 var compilerInjector = Injector.create({ providers: compilerProviders });
28497 var resourceLoader = compilerInjector.get(compiler.ResourceLoader);
28498 // The resource loader can also return a string while the "resolveComponentResources"
28499 // always expects a promise. Therefore we need to wrap the returned value in a promise.
28500 return resolveComponentResources(function (url) { return Promise.resolve(resourceLoader.get(url)); })
28501 .then(function () { return moduleFactory; });
28502 }
28503 // the `window.ng` global utilities are only available in non-VE versions of
28504 // Angular. The function switch below will make sure that the code is not
28505 // included into Angular when PRE mode is active.
28506 function publishDefaultGlobalUtils__PRE_R3__() { }
28507 function publishDefaultGlobalUtils__POST_R3__() {
28508 ngDevMode && publishDefaultGlobalUtils();
28509 }
28510 var publishDefaultGlobalUtils$1 = publishDefaultGlobalUtils__PRE_R3__;
28511 var isBoundToModule = isBoundToModule__PRE_R3__;
28512 function isBoundToModule__PRE_R3__(cf) {
28513 return cf instanceof ComponentFactoryBoundToModule;
28514 }
28515 function isBoundToModule__POST_R3__(cf) {
28516 return cf.isBoundToModule;
28517 }
28518 var ALLOW_MULTIPLE_PLATFORMS = new InjectionToken('AllowMultipleToken');
28519 /**
28520 * A token for third-party components that can register themselves with NgProbe.
28521 *
28522 * @publicApi
28523 */
28524 var NgProbeToken = /** @class */ (function () {
28525 function NgProbeToken(name, token) {
28526 this.name = name;
28527 this.token = token;
28528 }
28529 return NgProbeToken;
28530 }());
28531 /**
28532 * Creates a platform.
28533 * Platforms must be created on launch using this function.
28534 *
28535 * @publicApi
28536 */
28537 function createPlatform(injector) {
28538 if (_platform && !_platform.destroyed &&
28539 !_platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
28540 throw new Error('There can be only one platform. Destroy the previous one to create a new one.');
28541 }
28542 publishDefaultGlobalUtils$1();
28543 _platform = injector.get(PlatformRef);
28544 var inits = injector.get(PLATFORM_INITIALIZER, null);
28545 if (inits)
28546 inits.forEach(function (init) { return init(); });
28547 return _platform;
28548 }
28549 /**
28550 * Creates a factory for a platform. Can be used to provide or override `Providers` specific to
28551 * your applciation's runtime needs, such as `PLATFORM_INITIALIZER` and `PLATFORM_ID`.
28552 * @param parentPlatformFactory Another platform factory to modify. Allows you to compose factories
28553 * to build up configurations that might be required by different libraries or parts of the
28554 * application.
28555 * @param name Identifies the new platform factory.
28556 * @param providers A set of dependency providers for platforms created with the new factory.
28557 *
28558 * @publicApi
28559 */
28560 function createPlatformFactory(parentPlatformFactory, name, providers) {
28561 if (providers === void 0) { providers = []; }
28562 var desc = "Platform: " + name;
28563 var marker = new InjectionToken(desc);
28564 return function (extraProviders) {
28565 if (extraProviders === void 0) { extraProviders = []; }
28566 var platform = getPlatform();
28567 if (!platform || platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
28568 if (parentPlatformFactory) {
28569 parentPlatformFactory(providers.concat(extraProviders).concat({ provide: marker, useValue: true }));
28570 }
28571 else {
28572 var injectedProviders = providers.concat(extraProviders).concat({ provide: marker, useValue: true }, {
28573 provide: INJECTOR_SCOPE,
28574 useValue: 'platform'
28575 });
28576 createPlatform(Injector.create({ providers: injectedProviders, name: desc }));
28577 }
28578 }
28579 return assertPlatform(marker);
28580 };
28581 }
28582 /**
28583 * Checks that there is currently a platform that contains the given token as a provider.
28584 *
28585 * @publicApi
28586 */
28587 function assertPlatform(requiredToken) {
28588 var platform = getPlatform();
28589 if (!platform) {
28590 throw new Error('No platform exists!');
28591 }
28592 if (!platform.injector.get(requiredToken, null)) {
28593 throw new Error('A platform with a different configuration has been created. Please destroy it first.');
28594 }
28595 return platform;
28596 }
28597 /**
28598 * Destroys the current Angular platform and all Angular applications on the page.
28599 * Destroys all modules and listeners registered with the platform.
28600 *
28601 * @publicApi
28602 */
28603 function destroyPlatform() {
28604 if (_platform && !_platform.destroyed) {
28605 _platform.destroy();
28606 }
28607 }
28608 /**
28609 * Returns the current platform.
28610 *
28611 * @publicApi
28612 */
28613 function getPlatform() {
28614 return _platform && !_platform.destroyed ? _platform : null;
28615 }
28616 /**
28617 * The Angular platform is the entry point for Angular on a web page.
28618 * Each page has exactly one platform. Services (such as reflection) which are common
28619 * to every Angular application running on the page are bound in its scope.
28620 * A page's platform is initialized implicitly when a platform is created using a platform
28621 * factory such as `PlatformBrowser`, or explicitly by calling the `createPlatform()` function.
28622 *
28623 * @publicApi
28624 */
28625 var PlatformRef = /** @class */ (function () {
28626 /** @internal */
28627 function PlatformRef(_injector) {
28628 this._injector = _injector;
28629 this._modules = [];
28630 this._destroyListeners = [];
28631 this._destroyed = false;
28632 }
28633 /**
28634 * Creates an instance of an `@NgModule` for the given platform for offline compilation.
28635 *
28636 * @usageNotes
28637 *
28638 * The following example creates the NgModule for a browser platform.
28639 *
28640 * ```typescript
28641 * my_module.ts:
28642 *
28643 * @NgModule({
28644 * imports: [BrowserModule]
28645 * })
28646 * class MyModule {}
28647 *
28648 * main.ts:
28649 * import {MyModuleNgFactory} from './my_module.ngfactory';
28650 * import {platformBrowser} from '@angular/platform-browser';
28651 *
28652 * let moduleRef = platformBrowser().bootstrapModuleFactory(MyModuleNgFactory);
28653 * ```
28654 */
28655 PlatformRef.prototype.bootstrapModuleFactory = function (moduleFactory, options) {
28656 var _this = this;
28657 // Note: We need to create the NgZone _before_ we instantiate the module,
28658 // as instantiating the module creates some providers eagerly.
28659 // So we create a mini parent injector that just contains the new NgZone and
28660 // pass that as parent to the NgModuleFactory.
28661 var ngZoneOption = options ? options.ngZone : undefined;
28662 var ngZoneEventCoalescing = (options && options.ngZoneEventCoalescing) || false;
28663 var ngZone = getNgZone(ngZoneOption, ngZoneEventCoalescing);
28664 var providers = [{ provide: NgZone, useValue: ngZone }];
28665 // Attention: Don't use ApplicationRef.run here,
28666 // as we want to be sure that all possible constructor calls are inside `ngZone.run`!
28667 return ngZone.run(function () {
28668 var ngZoneInjector = Injector.create({ providers: providers, parent: _this.injector, name: moduleFactory.moduleType.name });
28669 var moduleRef = moduleFactory.create(ngZoneInjector);
28670 var exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
28671 if (!exceptionHandler) {
28672 throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
28673 }
28674 moduleRef.onDestroy(function () { return remove(_this._modules, moduleRef); });
28675 ngZone.runOutsideAngular(function () { return ngZone.onError.subscribe({
28676 next: function (error) {
28677 exceptionHandler.handleError(error);
28678 }
28679 }); });
28680 return _callAndReportToErrorHandler(exceptionHandler, ngZone, function () {
28681 var initStatus = moduleRef.injector.get(ApplicationInitStatus);
28682 initStatus.runInitializers();
28683 return initStatus.donePromise.then(function () {
28684 if (ivyEnabled) {
28685 // If the `LOCALE_ID` provider is defined at bootstrap then we set the value for ivy
28686 var localeId = moduleRef.injector.get(LOCALE_ID$1, DEFAULT_LOCALE_ID);
28687 setLocaleId(localeId || DEFAULT_LOCALE_ID);
28688 }
28689 _this._moduleDoBootstrap(moduleRef);
28690 return moduleRef;
28691 });
28692 });
28693 });
28694 };
28695 /**
28696 * Creates an instance of an `@NgModule` for a given platform using the given runtime compiler.
28697 *
28698 * @usageNotes
28699 * ### Simple Example
28700 *
28701 * ```typescript
28702 * @NgModule({
28703 * imports: [BrowserModule]
28704 * })
28705 * class MyModule {}
28706 *
28707 * let moduleRef = platformBrowser().bootstrapModule(MyModule);
28708 * ```
28709 *
28710 */
28711 PlatformRef.prototype.bootstrapModule = function (moduleType, compilerOptions) {
28712 var _this = this;
28713 if (compilerOptions === void 0) { compilerOptions = []; }
28714 var options = optionsReducer({}, compilerOptions);
28715 return compileNgModuleFactory(this.injector, options, moduleType)
28716 .then(function (moduleFactory) { return _this.bootstrapModuleFactory(moduleFactory, options); });
28717 };
28718 PlatformRef.prototype._moduleDoBootstrap = function (moduleRef) {
28719 var appRef = moduleRef.injector.get(ApplicationRef);
28720 if (moduleRef._bootstrapComponents.length > 0) {
28721 moduleRef._bootstrapComponents.forEach(function (f) { return appRef.bootstrap(f); });
28722 }
28723 else if (moduleRef.instance.ngDoBootstrap) {
28724 moduleRef.instance.ngDoBootstrap(appRef);
28725 }
28726 else {
28727 throw new Error("The module " + stringify(moduleRef.instance
28728 .constructor) + " was bootstrapped, but it does not declare \"@NgModule.bootstrap\" components nor a \"ngDoBootstrap\" method. " +
28729 "Please define one of these.");
28730 }
28731 this._modules.push(moduleRef);
28732 };
28733 /**
28734 * Registers a listener to be called when the platform is destroyed.
28735 */
28736 PlatformRef.prototype.onDestroy = function (callback) {
28737 this._destroyListeners.push(callback);
28738 };
28739 Object.defineProperty(PlatformRef.prototype, "injector", {
28740 /**
28741 * Retrieves the platform {@link Injector}, which is the parent injector for
28742 * every Angular application on the page and provides singleton providers.
28743 */
28744 get: function () {
28745 return this._injector;
28746 },
28747 enumerable: false,
28748 configurable: true
28749 });
28750 /**
28751 * Destroys the current Angular platform and all Angular applications on the page.
28752 * Destroys all modules and listeners registered with the platform.
28753 */
28754 PlatformRef.prototype.destroy = function () {
28755 if (this._destroyed) {
28756 throw new Error('The platform has already been destroyed!');
28757 }
28758 this._modules.slice().forEach(function (module) { return module.destroy(); });
28759 this._destroyListeners.forEach(function (listener) { return listener(); });
28760 this._destroyed = true;
28761 };
28762 Object.defineProperty(PlatformRef.prototype, "destroyed", {
28763 get: function () {
28764 return this._destroyed;
28765 },
28766 enumerable: false,
28767 configurable: true
28768 });
28769 return PlatformRef;
28770 }());
28771 PlatformRef.decorators = [
28772 { type: Injectable }
28773 ];
28774 PlatformRef.ctorParameters = function () { return [
28775 { type: Injector }
28776 ]; };
28777 function getNgZone(ngZoneOption, ngZoneEventCoalescing) {
28778 var ngZone;
28779 if (ngZoneOption === 'noop') {
28780 ngZone = new NoopNgZone();
28781 }
28782 else {
28783 ngZone = (ngZoneOption === 'zone.js' ? undefined : ngZoneOption) || new NgZone({
28784 enableLongStackTrace: isDevMode(),
28785 shouldCoalesceEventChangeDetection: ngZoneEventCoalescing
28786 });
28787 }
28788 return ngZone;
28789 }
28790 function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
28791 try {
28792 var result = callback();
28793 if (isPromise(result)) {
28794 return result.catch(function (e) {
28795 ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
28796 // rethrow as the exception handler might not do it
28797 throw e;
28798 });
28799 }
28800 return result;
28801 }
28802 catch (e) {
28803 ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
28804 // rethrow as the exception handler might not do it
28805 throw e;
28806 }
28807 }
28808 function optionsReducer(dst, objs) {
28809 if (Array.isArray(objs)) {
28810 dst = objs.reduce(optionsReducer, dst);
28811 }
28812 else {
28813 dst = Object.assign(Object.assign({}, dst), objs);
28814 }
28815 return dst;
28816 }
28817 /**
28818 * A reference to an Angular application running on a page.
28819 *
28820 * @usageNotes
28821 *
28822 * {@a is-stable-examples}
28823 * ### isStable examples and caveats
28824 *
28825 * Note two important points about `isStable`, demonstrated in the examples below:
28826 * - the application will never be stable if you start any kind
28827 * of recurrent asynchronous task when the application starts
28828 * (for example for a polling process, started with a `setInterval`, a `setTimeout`
28829 * or using RxJS operators like `interval`);
28830 * - the `isStable` Observable runs outside of the Angular zone.
28831 *
28832 * Let's imagine that you start a recurrent task
28833 * (here incrementing a counter, using RxJS `interval`),
28834 * and at the same time subscribe to `isStable`.
28835 *
28836 * ```
28837 * constructor(appRef: ApplicationRef) {
28838 * appRef.isStable.pipe(
28839 * filter(stable => stable)
28840 * ).subscribe(() => console.log('App is stable now');
28841 * interval(1000).subscribe(counter => console.log(counter));
28842 * }
28843 * ```
28844 * In this example, `isStable` will never emit `true`,
28845 * and the trace "App is stable now" will never get logged.
28846 *
28847 * If you want to execute something when the app is stable,
28848 * you have to wait for the application to be stable
28849 * before starting your polling process.
28850 *
28851 * ```
28852 * constructor(appRef: ApplicationRef) {
28853 * appRef.isStable.pipe(
28854 * first(stable => stable),
28855 * tap(stable => console.log('App is stable now')),
28856 * switchMap(() => interval(1000))
28857 * ).subscribe(counter => console.log(counter));
28858 * }
28859 * ```
28860 * In this example, the trace "App is stable now" will be logged
28861 * and then the counter starts incrementing every second.
28862 *
28863 * Note also that this Observable runs outside of the Angular zone,
28864 * which means that the code in the subscription
28865 * to this Observable will not trigger the change detection.
28866 *
28867 * Let's imagine that instead of logging the counter value,
28868 * you update a field of your component
28869 * and display it in its template.
28870 *
28871 * ```
28872 * constructor(appRef: ApplicationRef) {
28873 * appRef.isStable.pipe(
28874 * first(stable => stable),
28875 * switchMap(() => interval(1000))
28876 * ).subscribe(counter => this.value = counter);
28877 * }
28878 * ```
28879 * As the `isStable` Observable runs outside the zone,
28880 * the `value` field will be updated properly,
28881 * but the template will not be refreshed!
28882 *
28883 * You'll have to manually trigger the change detection to update the template.
28884 *
28885 * ```
28886 * constructor(appRef: ApplicationRef, cd: ChangeDetectorRef) {
28887 * appRef.isStable.pipe(
28888 * first(stable => stable),
28889 * switchMap(() => interval(1000))
28890 * ).subscribe(counter => {
28891 * this.value = counter;
28892 * cd.detectChanges();
28893 * });
28894 * }
28895 * ```
28896 *
28897 * Or make the subscription callback run inside the zone.
28898 *
28899 * ```
28900 * constructor(appRef: ApplicationRef, zone: NgZone) {
28901 * appRef.isStable.pipe(
28902 * first(stable => stable),
28903 * switchMap(() => interval(1000))
28904 * ).subscribe(counter => zone.run(() => this.value = counter));
28905 * }
28906 * ```
28907 *
28908 * @publicApi
28909 */
28910 var ApplicationRef = /** @class */ (function () {
28911 /** @internal */
28912 function ApplicationRef(_zone, _console, _injector, _exceptionHandler, _componentFactoryResolver, _initStatus) {
28913 var _this = this;
28914 this._zone = _zone;
28915 this._console = _console;
28916 this._injector = _injector;
28917 this._exceptionHandler = _exceptionHandler;
28918 this._componentFactoryResolver = _componentFactoryResolver;
28919 this._initStatus = _initStatus;
28920 /** @internal */
28921 this._bootstrapListeners = [];
28922 this._views = [];
28923 this._runningTick = false;
28924 this._enforceNoNewChanges = false;
28925 this._stable = true;
28926 /**
28927 * Get a list of component types registered to this application.
28928 * This list is populated even before the component is created.
28929 */
28930 this.componentTypes = [];
28931 /**
28932 * Get a list of components registered to this application.
28933 */
28934 this.components = [];
28935 this._enforceNoNewChanges = isDevMode();
28936 this._zone.onMicrotaskEmpty.subscribe({
28937 next: function () {
28938 _this._zone.run(function () {
28939 _this.tick();
28940 });
28941 }
28942 });
28943 var isCurrentlyStable = new rxjs.Observable(function (observer) {
28944 _this._stable = _this._zone.isStable && !_this._zone.hasPendingMacrotasks &&
28945 !_this._zone.hasPendingMicrotasks;
28946 _this._zone.runOutsideAngular(function () {
28947 observer.next(_this._stable);
28948 observer.complete();
28949 });
28950 });
28951 var isStable = new rxjs.Observable(function (observer) {
28952 // Create the subscription to onStable outside the Angular Zone so that
28953 // the callback is run outside the Angular Zone.
28954 var stableSub;
28955 _this._zone.runOutsideAngular(function () {
28956 stableSub = _this._zone.onStable.subscribe(function () {
28957 NgZone.assertNotInAngularZone();
28958 // Check whether there are no pending macro/micro tasks in the next tick
28959 // to allow for NgZone to update the state.
28960 scheduleMicroTask(function () {
28961 if (!_this._stable && !_this._zone.hasPendingMacrotasks &&
28962 !_this._zone.hasPendingMicrotasks) {
28963 _this._stable = true;
28964 observer.next(true);
28965 }
28966 });
28967 });
28968 });
28969 var unstableSub = _this._zone.onUnstable.subscribe(function () {
28970 NgZone.assertInAngularZone();
28971 if (_this._stable) {
28972 _this._stable = false;
28973 _this._zone.runOutsideAngular(function () {
28974 observer.next(false);
28975 });
28976 }
28977 });
28978 return function () {
28979 stableSub.unsubscribe();
28980 unstableSub.unsubscribe();
28981 };
28982 });
28983 this.isStable =
28984 rxjs.merge(isCurrentlyStable, isStable.pipe(operators.share()));
28985 }
28986 /**
28987 * Bootstrap a new component at the root level of the application.
28988 *
28989 * @usageNotes
28990 * ### Bootstrap process
28991 *
28992 * When bootstrapping a new root component into an application, Angular mounts the
28993 * specified application component onto DOM elements identified by the componentType's
28994 * selector and kicks off automatic change detection to finish initializing the component.
28995 *
28996 * Optionally, a component can be mounted onto a DOM element that does not match the
28997 * componentType's selector.
28998 *
28999 * ### Example
29000 * {@example core/ts/platform/platform.ts region='longform'}
29001 */
29002 ApplicationRef.prototype.bootstrap = function (componentOrFactory, rootSelectorOrNode) {
29003 var _this = this;
29004 if (!this._initStatus.done) {
29005 throw new Error('Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
29006 }
29007 var componentFactory;
29008 if (componentOrFactory instanceof ComponentFactory) {
29009 componentFactory = componentOrFactory;
29010 }
29011 else {
29012 componentFactory =
29013 this._componentFactoryResolver.resolveComponentFactory(componentOrFactory);
29014 }
29015 this.componentTypes.push(componentFactory.componentType);
29016 // Create a factory associated with the current module if it's not bound to some other
29017 var ngModule = isBoundToModule(componentFactory) ? undefined : this._injector.get(NgModuleRef);
29018 var selectorOrNode = rootSelectorOrNode || componentFactory.selector;
29019 var compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
29020 compRef.onDestroy(function () {
29021 _this._unloadComponent(compRef);
29022 });
29023 var testability = compRef.injector.get(Testability, null);
29024 if (testability) {
29025 compRef.injector.get(TestabilityRegistry)
29026 .registerApplication(compRef.location.nativeElement, testability);
29027 }
29028 this._loadComponent(compRef);
29029 if (isDevMode()) {
29030 this._console.log("Angular is running in development mode. Call enableProdMode() to enable production mode.");
29031 }
29032 return compRef;
29033 };
29034 /**
29035 * Invoke this method to explicitly process change detection and its side-effects.
29036 *
29037 * In development mode, `tick()` also performs a second change detection cycle to ensure that no
29038 * further changes are detected. If additional changes are picked up during this second cycle,
29039 * bindings in the app have side-effects that cannot be resolved in a single change detection
29040 * pass.
29041 * In this case, Angular throws an error, since an Angular application can only have one change
29042 * detection pass during which all change detection must complete.
29043 */
29044 ApplicationRef.prototype.tick = function () {
29045 var e_1, _a, e_2, _b;
29046 var _this = this;
29047 if (this._runningTick) {
29048 throw new Error('ApplicationRef.tick is called recursively');
29049 }
29050 try {
29051 this._runningTick = true;
29052 try {
29053 for (var _c = __values(this._views), _d = _c.next(); !_d.done; _d = _c.next()) {
29054 var view = _d.value;
29055 view.detectChanges();
29056 }
29057 }
29058 catch (e_1_1) { e_1 = { error: e_1_1 }; }
29059 finally {
29060 try {
29061 if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
29062 }
29063 finally { if (e_1) throw e_1.error; }
29064 }
29065 if (this._enforceNoNewChanges) {
29066 try {
29067 for (var _e = __values(this._views), _f = _e.next(); !_f.done; _f = _e.next()) {
29068 var view = _f.value;
29069 view.checkNoChanges();
29070 }
29071 }
29072 catch (e_2_1) { e_2 = { error: e_2_1 }; }
29073 finally {
29074 try {
29075 if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
29076 }
29077 finally { if (e_2) throw e_2.error; }
29078 }
29079 }
29080 }
29081 catch (e) {
29082 // Attention: Don't rethrow as it could cancel subscriptions to Observables!
29083 this._zone.runOutsideAngular(function () { return _this._exceptionHandler.handleError(e); });
29084 }
29085 finally {
29086 this._runningTick = false;
29087 }
29088 };
29089 /**
29090 * Attaches a view so that it will be dirty checked.
29091 * The view will be automatically detached when it is destroyed.
29092 * This will throw if the view is already attached to a ViewContainer.
29093 */
29094 ApplicationRef.prototype.attachView = function (viewRef) {
29095 var view = viewRef;
29096 this._views.push(view);
29097 view.attachToAppRef(this);
29098 };
29099 /**
29100 * Detaches a view from dirty checking again.
29101 */
29102 ApplicationRef.prototype.detachView = function (viewRef) {
29103 var view = viewRef;
29104 remove(this._views, view);
29105 view.detachFromAppRef();
29106 };
29107 ApplicationRef.prototype._loadComponent = function (componentRef) {
29108 this.attachView(componentRef.hostView);
29109 this.tick();
29110 this.components.push(componentRef);
29111 // Get the listeners lazily to prevent DI cycles.
29112 var listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners);
29113 listeners.forEach(function (listener) { return listener(componentRef); });
29114 };
29115 ApplicationRef.prototype._unloadComponent = function (componentRef) {
29116 this.detachView(componentRef.hostView);
29117 remove(this.components, componentRef);
29118 };
29119 /** @internal */
29120 ApplicationRef.prototype.ngOnDestroy = function () {
29121 // TODO(alxhub): Dispose of the NgZone.
29122 this._views.slice().forEach(function (view) { return view.destroy(); });
29123 };
29124 Object.defineProperty(ApplicationRef.prototype, "viewCount", {
29125 /**
29126 * Returns the number of attached views.
29127 */
29128 get: function () {
29129 return this._views.length;
29130 },
29131 enumerable: false,
29132 configurable: true
29133 });
29134 return ApplicationRef;
29135 }());
29136 ApplicationRef.decorators = [
29137 { type: Injectable }
29138 ];
29139 ApplicationRef.ctorParameters = function () { return [
29140 { type: NgZone },
29141 { type: Console },
29142 { type: Injector },
29143 { type: ErrorHandler },
29144 { type: ComponentFactoryResolver },
29145 { type: ApplicationInitStatus }
29146 ]; };
29147 function remove(list, el) {
29148 var index = list.indexOf(el);
29149 if (index > -1) {
29150 list.splice(index, 1);
29151 }
29152 }
29153 function _lastDefined(args) {
29154 for (var i = args.length - 1; i >= 0; i--) {
29155 if (args[i] !== undefined) {
29156 return args[i];
29157 }
29158 }
29159 return undefined;
29160 }
29161 function _mergeArrays(parts) {
29162 var result = [];
29163 parts.forEach(function (part) { return part && result.push.apply(result, __spread(part)); });
29164 return result;
29165 }
29166
29167 /**
29168 * @license
29169 * Copyright Google LLC All Rights Reserved.
29170 *
29171 * Use of this source code is governed by an MIT-style license that can be
29172 * found in the LICENSE file at https://angular.io/license
29173 */
29174
29175 /**
29176 * @license
29177 * Copyright Google LLC All Rights Reserved.
29178 *
29179 * Use of this source code is governed by an MIT-style license that can be
29180 * found in the LICENSE file at https://angular.io/license
29181 */
29182
29183 /**
29184 * @license
29185 * Copyright Google LLC All Rights Reserved.
29186 *
29187 * Use of this source code is governed by an MIT-style license that can be
29188 * found in the LICENSE file at https://angular.io/license
29189 */
29190 /**
29191 * Used to load ng module factories.
29192 *
29193 * @publicApi
29194 * @deprecated the `string` form of `loadChildren` is deprecated, and `NgModuleFactoryLoader` is
29195 * part of its implementation. See `LoadChildren` for more details.
29196 */
29197 var NgModuleFactoryLoader = /** @class */ (function () {
29198 function NgModuleFactoryLoader() {
29199 }
29200 return NgModuleFactoryLoader;
29201 }());
29202 function getModuleFactory__PRE_R3__(id) {
29203 var factory = getRegisteredNgModuleType(id);
29204 if (!factory)
29205 throw noModuleError(id);
29206 return factory;
29207 }
29208 function getModuleFactory__POST_R3__(id) {
29209 var type = getRegisteredNgModuleType(id);
29210 if (!type)
29211 throw noModuleError(id);
29212 return new NgModuleFactory$1(type);
29213 }
29214 /**
29215 * Returns the NgModuleFactory with the given id, if it exists and has been loaded.
29216 * Factories for modules that do not specify an `id` cannot be retrieved. Throws if the module
29217 * cannot be found.
29218 * @publicApi
29219 */
29220 var getModuleFactory = getModuleFactory__PRE_R3__;
29221 function noModuleError(id) {
29222 return new Error("No module with ID " + id + " loaded");
29223 }
29224
29225 var _SEPARATOR = '#';
29226 var FACTORY_CLASS_SUFFIX = 'NgFactory';
29227 /**
29228 * Configuration for SystemJsNgModuleLoader.
29229 * token.
29230 *
29231 * @publicApi
29232 * @deprecated the `string` form of `loadChildren` is deprecated, and `SystemJsNgModuleLoaderConfig`
29233 * is part of its implementation. See `LoadChildren` for more details.
29234 */
29235 var SystemJsNgModuleLoaderConfig = /** @class */ (function () {
29236 function SystemJsNgModuleLoaderConfig() {
29237 }
29238 return SystemJsNgModuleLoaderConfig;
29239 }());
29240 var DEFAULT_CONFIG = {
29241 factoryPathPrefix: '',
29242 factoryPathSuffix: '.ngfactory',
29243 };
29244 /**
29245 * NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
29246 * @publicApi
29247 * @deprecated the `string` form of `loadChildren` is deprecated, and `SystemJsNgModuleLoader` is
29248 * part of its implementation. See `LoadChildren` for more details.
29249 */
29250 var SystemJsNgModuleLoader = /** @class */ (function () {
29251 function SystemJsNgModuleLoader(_compiler, config) {
29252 this._compiler = _compiler;
29253 this._config = config || DEFAULT_CONFIG;
29254 }
29255 SystemJsNgModuleLoader.prototype.load = function (path) {
29256 var legacyOfflineMode = !ivyEnabled && this._compiler instanceof Compiler;
29257 return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
29258 };
29259 SystemJsNgModuleLoader.prototype.loadAndCompile = function (path) {
29260 var _this = this;
29261 var _a = __read(path.split(_SEPARATOR), 2), module = _a[0], exportName = _a[1];
29262 if (exportName === undefined) {
29263 exportName = 'default';
29264 }
29265 return System.import(module)
29266 .then(function (module) { return module[exportName]; })
29267 .then(function (type) { return checkNotEmpty(type, module, exportName); })
29268 .then(function (type) { return _this._compiler.compileModuleAsync(type); });
29269 };
29270 SystemJsNgModuleLoader.prototype.loadFactory = function (path) {
29271 var _a = __read(path.split(_SEPARATOR), 2), module = _a[0], exportName = _a[1];
29272 var factoryClassSuffix = FACTORY_CLASS_SUFFIX;
29273 if (exportName === undefined) {
29274 exportName = 'default';
29275 factoryClassSuffix = '';
29276 }
29277 return System.import(this._config.factoryPathPrefix + module + this._config.factoryPathSuffix)
29278 .then(function (module) { return module[exportName + factoryClassSuffix]; })
29279 .then(function (factory) { return checkNotEmpty(factory, module, exportName); });
29280 };
29281 return SystemJsNgModuleLoader;
29282 }());
29283 SystemJsNgModuleLoader.decorators = [
29284 { type: Injectable }
29285 ];
29286 SystemJsNgModuleLoader.ctorParameters = function () { return [
29287 { type: Compiler },
29288 { type: SystemJsNgModuleLoaderConfig, decorators: [{ type: Optional }] }
29289 ]; };
29290 function checkNotEmpty(value, modulePath, exportName) {
29291 if (!value) {
29292 throw new Error("Cannot find '" + exportName + "' in '" + modulePath + "'");
29293 }
29294 return value;
29295 }
29296
29297 /**
29298 * Represents an Angular [view](guide/glossary#view "Definition").
29299 *
29300 * @see {@link ChangeDetectorRef#usage-notes Change detection usage}
29301 *
29302 * @publicApi
29303 */
29304 var ViewRef$1 = /** @class */ (function (_super) {
29305 __extends(ViewRef, _super);
29306 function ViewRef() {
29307 return _super !== null && _super.apply(this, arguments) || this;
29308 }
29309 return ViewRef;
29310 }(ChangeDetectorRef));
29311 /**
29312 * Represents an Angular [view](guide/glossary#view) in a view container.
29313 * An [embedded view](guide/glossary#view-tree) can be referenced from a component
29314 * other than the hosting component whose template defines it, or it can be defined
29315 * independently by a `TemplateRef`.
29316 *
29317 * Properties of elements in a view can change, but the structure (number and order) of elements in
29318 * a view cannot. Change the structure of elements by inserting, moving, or
29319 * removing nested views in a view container.
29320 *
29321 * @see `ViewContainerRef`
29322 *
29323 * @usageNotes
29324 *
29325 * The following template breaks down into two separate `TemplateRef` instances,
29326 * an outer one and an inner one.
29327 *
29328 * ```
29329 * Count: {{items.length}}
29330 * <ul>
29331 * <li *ngFor="let item of items">{{item}}</li>
29332 * </ul>
29333 * ```
29334 *
29335 * This is the outer `TemplateRef`:
29336 *
29337 * ```
29338 * Count: {{items.length}}
29339 * <ul>
29340 * <ng-template ngFor let-item [ngForOf]="items"></ng-template>
29341 * </ul>
29342 * ```
29343 *
29344 * This is the inner `TemplateRef`:
29345 *
29346 * ```
29347 * <li>{{item}}</li>
29348 * ```
29349 *
29350 * The outer and inner `TemplateRef` instances are assembled into views as follows:
29351 *
29352 * ```
29353 * <!-- ViewRef: outer-0 -->
29354 * Count: 2
29355 * <ul>
29356 * <ng-template view-container-ref></ng-template>
29357 * <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
29358 * <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
29359 * </ul>
29360 * <!-- /ViewRef: outer-0 -->
29361 * ```
29362 * @publicApi
29363 */
29364 var EmbeddedViewRef = /** @class */ (function (_super) {
29365 __extends(EmbeddedViewRef, _super);
29366 function EmbeddedViewRef() {
29367 return _super !== null && _super.apply(this, arguments) || this;
29368 }
29369 return EmbeddedViewRef;
29370 }(ViewRef$1));
29371
29372 /**
29373 * @license
29374 * Copyright Google LLC All Rights Reserved.
29375 *
29376 * Use of this source code is governed by an MIT-style license that can be
29377 * found in the LICENSE file at https://angular.io/license
29378 */
29379
29380 /**
29381 * @publicApi
29382 */
29383 var DebugEventListener = /** @class */ (function () {
29384 function DebugEventListener(name, callback) {
29385 this.name = name;
29386 this.callback = callback;
29387 }
29388 return DebugEventListener;
29389 }());
29390 var DebugNode__PRE_R3__ = /** @class */ (function () {
29391 function DebugNode__PRE_R3__(nativeNode, parent, _debugContext) {
29392 this.listeners = [];
29393 this.parent = null;
29394 this._debugContext = _debugContext;
29395 this.nativeNode = nativeNode;
29396 if (parent && parent instanceof DebugElement__PRE_R3__) {
29397 parent.addChild(this);
29398 }
29399 }
29400 Object.defineProperty(DebugNode__PRE_R3__.prototype, "injector", {
29401 get: function () {
29402 return this._debugContext.injector;
29403 },
29404 enumerable: false,
29405 configurable: true
29406 });
29407 Object.defineProperty(DebugNode__PRE_R3__.prototype, "componentInstance", {
29408 get: function () {
29409 return this._debugContext.component;
29410 },
29411 enumerable: false,
29412 configurable: true
29413 });
29414 Object.defineProperty(DebugNode__PRE_R3__.prototype, "context", {
29415 get: function () {
29416 return this._debugContext.context;
29417 },
29418 enumerable: false,
29419 configurable: true
29420 });
29421 Object.defineProperty(DebugNode__PRE_R3__.prototype, "references", {
29422 get: function () {
29423 return this._debugContext.references;
29424 },
29425 enumerable: false,
29426 configurable: true
29427 });
29428 Object.defineProperty(DebugNode__PRE_R3__.prototype, "providerTokens", {
29429 get: function () {
29430 return this._debugContext.providerTokens;
29431 },
29432 enumerable: false,
29433 configurable: true
29434 });
29435 return DebugNode__PRE_R3__;
29436 }());
29437 var DebugElement__PRE_R3__ = /** @class */ (function (_super) {
29438 __extends(DebugElement__PRE_R3__, _super);
29439 function DebugElement__PRE_R3__(nativeNode, parent, _debugContext) {
29440 var _this = _super.call(this, nativeNode, parent, _debugContext) || this;
29441 _this.properties = {};
29442 _this.attributes = {};
29443 _this.classes = {};
29444 _this.styles = {};
29445 _this.childNodes = [];
29446 _this.nativeElement = nativeNode;
29447 return _this;
29448 }
29449 DebugElement__PRE_R3__.prototype.addChild = function (child) {
29450 if (child) {
29451 this.childNodes.push(child);
29452 child.parent = this;
29453 }
29454 };
29455 DebugElement__PRE_R3__.prototype.removeChild = function (child) {
29456 var childIndex = this.childNodes.indexOf(child);
29457 if (childIndex !== -1) {
29458 child.parent = null;
29459 this.childNodes.splice(childIndex, 1);
29460 }
29461 };
29462 DebugElement__PRE_R3__.prototype.insertChildrenAfter = function (child, newChildren) {
29463 var _a;
29464 var _this = this;
29465 var siblingIndex = this.childNodes.indexOf(child);
29466 if (siblingIndex !== -1) {
29467 (_a = this.childNodes).splice.apply(_a, __spread([siblingIndex + 1, 0], newChildren));
29468 newChildren.forEach(function (c) {
29469 if (c.parent) {
29470 c.parent.removeChild(c);
29471 }
29472 child.parent = _this;
29473 });
29474 }
29475 };
29476 DebugElement__PRE_R3__.prototype.insertBefore = function (refChild, newChild) {
29477 var refIndex = this.childNodes.indexOf(refChild);
29478 if (refIndex === -1) {
29479 this.addChild(newChild);
29480 }
29481 else {
29482 if (newChild.parent) {
29483 newChild.parent.removeChild(newChild);
29484 }
29485 newChild.parent = this;
29486 this.childNodes.splice(refIndex, 0, newChild);
29487 }
29488 };
29489 DebugElement__PRE_R3__.prototype.query = function (predicate) {
29490 var results = this.queryAll(predicate);
29491 return results[0] || null;
29492 };
29493 DebugElement__PRE_R3__.prototype.queryAll = function (predicate) {
29494 var matches = [];
29495 _queryElementChildren(this, predicate, matches);
29496 return matches;
29497 };
29498 DebugElement__PRE_R3__.prototype.queryAllNodes = function (predicate) {
29499 var matches = [];
29500 _queryNodeChildren(this, predicate, matches);
29501 return matches;
29502 };
29503 Object.defineProperty(DebugElement__PRE_R3__.prototype, "children", {
29504 get: function () {
29505 return this.childNodes //
29506 .filter(function (node) { return node instanceof DebugElement__PRE_R3__; });
29507 },
29508 enumerable: false,
29509 configurable: true
29510 });
29511 DebugElement__PRE_R3__.prototype.triggerEventHandler = function (eventName, eventObj) {
29512 this.listeners.forEach(function (listener) {
29513 if (listener.name == eventName) {
29514 listener.callback(eventObj);
29515 }
29516 });
29517 };
29518 return DebugElement__PRE_R3__;
29519 }(DebugNode__PRE_R3__));
29520 /**
29521 * @publicApi
29522 */
29523 function asNativeElements(debugEls) {
29524 return debugEls.map(function (el) { return el.nativeElement; });
29525 }
29526 function _queryElementChildren(element, predicate, matches) {
29527 element.childNodes.forEach(function (node) {
29528 if (node instanceof DebugElement__PRE_R3__) {
29529 if (predicate(node)) {
29530 matches.push(node);
29531 }
29532 _queryElementChildren(node, predicate, matches);
29533 }
29534 });
29535 }
29536 function _queryNodeChildren(parentNode, predicate, matches) {
29537 if (parentNode instanceof DebugElement__PRE_R3__) {
29538 parentNode.childNodes.forEach(function (node) {
29539 if (predicate(node)) {
29540 matches.push(node);
29541 }
29542 if (node instanceof DebugElement__PRE_R3__) {
29543 _queryNodeChildren(node, predicate, matches);
29544 }
29545 });
29546 }
29547 }
29548 var DebugNode__POST_R3__ = /** @class */ (function () {
29549 function DebugNode__POST_R3__(nativeNode) {
29550 this.nativeNode = nativeNode;
29551 }
29552 Object.defineProperty(DebugNode__POST_R3__.prototype, "parent", {
29553 get: function () {
29554 var parent = this.nativeNode.parentNode;
29555 return parent ? new DebugElement__POST_R3__(parent) : null;
29556 },
29557 enumerable: false,
29558 configurable: true
29559 });
29560 Object.defineProperty(DebugNode__POST_R3__.prototype, "injector", {
29561 get: function () {
29562 return getInjector(this.nativeNode);
29563 },
29564 enumerable: false,
29565 configurable: true
29566 });
29567 Object.defineProperty(DebugNode__POST_R3__.prototype, "componentInstance", {
29568 get: function () {
29569 var nativeElement = this.nativeNode;
29570 return nativeElement &&
29571 (getComponent(nativeElement) || getOwningComponent(nativeElement));
29572 },
29573 enumerable: false,
29574 configurable: true
29575 });
29576 Object.defineProperty(DebugNode__POST_R3__.prototype, "context", {
29577 get: function () {
29578 return getComponent(this.nativeNode) || getContext(this.nativeNode);
29579 },
29580 enumerable: false,
29581 configurable: true
29582 });
29583 Object.defineProperty(DebugNode__POST_R3__.prototype, "listeners", {
29584 get: function () {
29585 return getListeners(this.nativeNode).filter(function (listener) { return listener.type === 'dom'; });
29586 },
29587 enumerable: false,
29588 configurable: true
29589 });
29590 Object.defineProperty(DebugNode__POST_R3__.prototype, "references", {
29591 get: function () {
29592 return getLocalRefs(this.nativeNode);
29593 },
29594 enumerable: false,
29595 configurable: true
29596 });
29597 Object.defineProperty(DebugNode__POST_R3__.prototype, "providerTokens", {
29598 get: function () {
29599 return getInjectionTokens(this.nativeNode);
29600 },
29601 enumerable: false,
29602 configurable: true
29603 });
29604 return DebugNode__POST_R3__;
29605 }());
29606 var DebugElement__POST_R3__ = /** @class */ (function (_super) {
29607 __extends(DebugElement__POST_R3__, _super);
29608 function DebugElement__POST_R3__(nativeNode) {
29609 var _this = this;
29610 ngDevMode && assertDomNode(nativeNode);
29611 _this = _super.call(this, nativeNode) || this;
29612 return _this;
29613 }
29614 Object.defineProperty(DebugElement__POST_R3__.prototype, "nativeElement", {
29615 get: function () {
29616 return this.nativeNode.nodeType == Node.ELEMENT_NODE ? this.nativeNode : null;
29617 },
29618 enumerable: false,
29619 configurable: true
29620 });
29621 Object.defineProperty(DebugElement__POST_R3__.prototype, "name", {
29622 get: function () {
29623 try {
29624 var context = loadLContext(this.nativeNode);
29625 var lView = context.lView;
29626 var tData = lView[TVIEW].data;
29627 var tNode = tData[context.nodeIndex];
29628 return tNode.tagName;
29629 }
29630 catch (e) {
29631 return this.nativeNode.nodeName;
29632 }
29633 },
29634 enumerable: false,
29635 configurable: true
29636 });
29637 Object.defineProperty(DebugElement__POST_R3__.prototype, "properties", {
29638 /**
29639 * Gets a map of property names to property values for an element.
29640 *
29641 * This map includes:
29642 * - Regular property bindings (e.g. `[id]="id"`)
29643 * - Host property bindings (e.g. `host: { '[id]': "id" }`)
29644 * - Interpolated property bindings (e.g. `id="{{ value }}")
29645 *
29646 * It does not include:
29647 * - input property bindings (e.g. `[myCustomInput]="value"`)
29648 * - attribute bindings (e.g. `[attr.role]="menu"`)
29649 */
29650 get: function () {
29651 var context = loadLContext(this.nativeNode, false);
29652 if (context == null) {
29653 return {};
29654 }
29655 var lView = context.lView;
29656 var tData = lView[TVIEW].data;
29657 var tNode = tData[context.nodeIndex];
29658 var properties = {};
29659 // Collect properties from the DOM.
29660 copyDomProperties(this.nativeElement, properties);
29661 // Collect properties from the bindings. This is needed for animation renderer which has
29662 // synthetic properties which don't get reflected into the DOM.
29663 collectPropertyBindings(properties, tNode, lView, tData);
29664 return properties;
29665 },
29666 enumerable: false,
29667 configurable: true
29668 });
29669 Object.defineProperty(DebugElement__POST_R3__.prototype, "attributes", {
29670 get: function () {
29671 var attributes = {};
29672 var element = this.nativeElement;
29673 if (!element) {
29674 return attributes;
29675 }
29676 var context = loadLContext(element, false);
29677 if (context == null) {
29678 return {};
29679 }
29680 var lView = context.lView;
29681 var tNodeAttrs = lView[TVIEW].data[context.nodeIndex].attrs;
29682 var lowercaseTNodeAttrs = [];
29683 // For debug nodes we take the element's attribute directly from the DOM since it allows us
29684 // to account for ones that weren't set via bindings (e.g. ViewEngine keeps track of the ones
29685 // that are set through `Renderer2`). The problem is that the browser will lowercase all names,
29686 // however since we have the attributes already on the TNode, we can preserve the case by going
29687 // through them once, adding them to the `attributes` map and putting their lower-cased name
29688 // into an array. Afterwards when we're going through the native DOM attributes, we can check
29689 // whether we haven't run into an attribute already through the TNode.
29690 if (tNodeAttrs) {
29691 var i = 0;
29692 while (i < tNodeAttrs.length) {
29693 var attrName = tNodeAttrs[i];
29694 // Stop as soon as we hit a marker. We only care about the regular attributes. Everything
29695 // else will be handled below when we read the final attributes off the DOM.
29696 if (typeof attrName !== 'string')
29697 break;
29698 var attrValue = tNodeAttrs[i + 1];
29699 attributes[attrName] = attrValue;
29700 lowercaseTNodeAttrs.push(attrName.toLowerCase());
29701 i += 2;
29702 }
29703 }
29704 var eAttrs = element.attributes;
29705 for (var i = 0; i < eAttrs.length; i++) {
29706 var attr = eAttrs[i];
29707 var lowercaseName = attr.name.toLowerCase();
29708 // Make sure that we don't assign the same attribute both in its
29709 // case-sensitive form and the lower-cased one from the browser.
29710 if (lowercaseTNodeAttrs.indexOf(lowercaseName) === -1) {
29711 // Save the lowercase name to align the behavior between browsers.
29712 // IE preserves the case, while all other browser convert it to lower case.
29713 attributes[lowercaseName] = attr.value;
29714 }
29715 }
29716 return attributes;
29717 },
29718 enumerable: false,
29719 configurable: true
29720 });
29721 Object.defineProperty(DebugElement__POST_R3__.prototype, "styles", {
29722 get: function () {
29723 if (this.nativeElement && this.nativeElement.style) {
29724 return this.nativeElement.style;
29725 }
29726 return {};
29727 },
29728 enumerable: false,
29729 configurable: true
29730 });
29731 Object.defineProperty(DebugElement__POST_R3__.prototype, "classes", {
29732 get: function () {
29733 var result = {};
29734 var element = this.nativeElement;
29735 // SVG elements return an `SVGAnimatedString` instead of a plain string for the `className`.
29736 var className = element.className;
29737 var classes = className && typeof className !== 'string' ? className.baseVal.split(' ') :
29738 className.split(' ');
29739 classes.forEach(function (value) { return result[value] = true; });
29740 return result;
29741 },
29742 enumerable: false,
29743 configurable: true
29744 });
29745 Object.defineProperty(DebugElement__POST_R3__.prototype, "childNodes", {
29746 get: function () {
29747 var childNodes = this.nativeNode.childNodes;
29748 var children = [];
29749 for (var i = 0; i < childNodes.length; i++) {
29750 var element = childNodes[i];
29751 children.push(getDebugNode__POST_R3__(element));
29752 }
29753 return children;
29754 },
29755 enumerable: false,
29756 configurable: true
29757 });
29758 Object.defineProperty(DebugElement__POST_R3__.prototype, "children", {
29759 get: function () {
29760 var nativeElement = this.nativeElement;
29761 if (!nativeElement)
29762 return [];
29763 var childNodes = nativeElement.children;
29764 var children = [];
29765 for (var i = 0; i < childNodes.length; i++) {
29766 var element = childNodes[i];
29767 children.push(getDebugNode__POST_R3__(element));
29768 }
29769 return children;
29770 },
29771 enumerable: false,
29772 configurable: true
29773 });
29774 DebugElement__POST_R3__.prototype.query = function (predicate) {
29775 var results = this.queryAll(predicate);
29776 return results[0] || null;
29777 };
29778 DebugElement__POST_R3__.prototype.queryAll = function (predicate) {
29779 var matches = [];
29780 _queryAllR3(this, predicate, matches, true);
29781 return matches;
29782 };
29783 DebugElement__POST_R3__.prototype.queryAllNodes = function (predicate) {
29784 var matches = [];
29785 _queryAllR3(this, predicate, matches, false);
29786 return matches;
29787 };
29788 DebugElement__POST_R3__.prototype.triggerEventHandler = function (eventName, eventObj) {
29789 var node = this.nativeNode;
29790 var invokedListeners = [];
29791 this.listeners.forEach(function (listener) {
29792 if (listener.name === eventName) {
29793 var callback = listener.callback;
29794 callback.call(node, eventObj);
29795 invokedListeners.push(callback);
29796 }
29797 });
29798 // We need to check whether `eventListeners` exists, because it's something
29799 // that Zone.js only adds to `EventTarget` in browser environments.
29800 if (typeof node.eventListeners === 'function') {
29801 // Note that in Ivy we wrap event listeners with a call to `event.preventDefault` in some
29802 // cases. We use '__ngUnwrap__' as a special token that gives us access to the actual event
29803 // listener.
29804 node.eventListeners(eventName).forEach(function (listener) {
29805 // In order to ensure that we can detect the special __ngUnwrap__ token described above, we
29806 // use `toString` on the listener and see if it contains the token. We use this approach to
29807 // ensure that it still worked with compiled code since it cannot remove or rename string
29808 // literals. We also considered using a special function name (i.e. if(listener.name ===
29809 // special)) but that was more cumbersome and we were also concerned the compiled code could
29810 // strip the name, turning the condition in to ("" === "") and always returning true.
29811 if (listener.toString().indexOf('__ngUnwrap__') !== -1) {
29812 var unwrappedListener = listener('__ngUnwrap__');
29813 return invokedListeners.indexOf(unwrappedListener) === -1 &&
29814 unwrappedListener.call(node, eventObj);
29815 }
29816 });
29817 }
29818 };
29819 return DebugElement__POST_R3__;
29820 }(DebugNode__POST_R3__));
29821 function copyDomProperties(element, properties) {
29822 if (element) {
29823 // Skip own properties (as those are patched)
29824 var obj = Object.getPrototypeOf(element);
29825 var NodePrototype = Node.prototype;
29826 while (obj !== null && obj !== NodePrototype) {
29827 var descriptors = Object.getOwnPropertyDescriptors(obj);
29828 for (var key in descriptors) {
29829 if (!key.startsWith('__') && !key.startsWith('on')) {
29830 // don't include properties starting with `__` and `on`.
29831 // `__` are patched values which should not be included.
29832 // `on` are listeners which also should not be included.
29833 var value = element[key];
29834 if (isPrimitiveValue(value)) {
29835 properties[key] = value;
29836 }
29837 }
29838 }
29839 obj = Object.getPrototypeOf(obj);
29840 }
29841 }
29842 }
29843 function isPrimitiveValue(value) {
29844 return typeof value === 'string' || typeof value === 'boolean' || typeof value === 'number' ||
29845 value === null;
29846 }
29847 function _queryAllR3(parentElement, predicate, matches, elementsOnly) {
29848 var context = loadLContext(parentElement.nativeNode, false);
29849 if (context !== null) {
29850 var parentTNode = context.lView[TVIEW].data[context.nodeIndex];
29851 _queryNodeChildrenR3(parentTNode, context.lView, predicate, matches, elementsOnly, parentElement.nativeNode);
29852 }
29853 else {
29854 // If the context is null, then `parentElement` was either created with Renderer2 or native DOM
29855 // APIs.
29856 _queryNativeNodeDescendants(parentElement.nativeNode, predicate, matches, elementsOnly);
29857 }
29858 }
29859 /**
29860 * Recursively match the current TNode against the predicate, and goes on with the next ones.
29861 *
29862 * @param tNode the current TNode
29863 * @param lView the LView of this TNode
29864 * @param predicate the predicate to match
29865 * @param matches the list of positive matches
29866 * @param elementsOnly whether only elements should be searched
29867 * @param rootNativeNode the root native node on which predicate should not be matched
29868 */
29869 function _queryNodeChildrenR3(tNode, lView, predicate, matches, elementsOnly, rootNativeNode) {
29870 var e_1, _a;
29871 var nativeNode = getNativeByTNodeOrNull(tNode, lView);
29872 // For each type of TNode, specific logic is executed.
29873 if (tNode.type === 3 /* Element */ || tNode.type === 4 /* ElementContainer */) {
29874 // Case 1: the TNode is an element
29875 // The native node has to be checked.
29876 _addQueryMatchR3(nativeNode, predicate, matches, elementsOnly, rootNativeNode);
29877 if (isComponentHost(tNode)) {
29878 // If the element is the host of a component, then all nodes in its view have to be processed.
29879 // Note: the component's content (tNode.child) will be processed from the insertion points.
29880 var componentView = getComponentLViewByIndex(tNode.index, lView);
29881 if (componentView && componentView[TVIEW].firstChild) {
29882 _queryNodeChildrenR3(componentView[TVIEW].firstChild, componentView, predicate, matches, elementsOnly, rootNativeNode);
29883 }
29884 }
29885 else {
29886 if (tNode.child) {
29887 // Otherwise, its children have to be processed.
29888 _queryNodeChildrenR3(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
29889 }
29890 // We also have to query the DOM directly in order to catch elements inserted through
29891 // Renderer2. Note that this is __not__ optimal, because we're walking similar trees multiple
29892 // times. ViewEngine could do it more efficiently, because all the insertions go through
29893 // Renderer2, however that's not the case in Ivy. This approach is being used because:
29894 // 1. Matching the ViewEngine behavior would mean potentially introducing a depedency
29895 // from `Renderer2` to Ivy which could bring Ivy code into ViewEngine.
29896 // 2. We would have to make `Renderer3` "know" about debug nodes.
29897 // 3. It allows us to capture nodes that were inserted directly via the DOM.
29898 nativeNode && _queryNativeNodeDescendants(nativeNode, predicate, matches, elementsOnly);
29899 }
29900 // In all cases, if a dynamic container exists for this node, each view inside it has to be
29901 // processed.
29902 var nodeOrContainer = lView[tNode.index];
29903 if (isLContainer(nodeOrContainer)) {
29904 _queryNodeChildrenInContainerR3(nodeOrContainer, predicate, matches, elementsOnly, rootNativeNode);
29905 }
29906 }
29907 else if (tNode.type === 0 /* Container */) {
29908 // Case 2: the TNode is a container
29909 // The native node has to be checked.
29910 var lContainer = lView[tNode.index];
29911 _addQueryMatchR3(lContainer[NATIVE], predicate, matches, elementsOnly, rootNativeNode);
29912 // Each view inside the container has to be processed.
29913 _queryNodeChildrenInContainerR3(lContainer, predicate, matches, elementsOnly, rootNativeNode);
29914 }
29915 else if (tNode.type === 1 /* Projection */) {
29916 // Case 3: the TNode is a projection insertion point (i.e. a <ng-content>).
29917 // The nodes projected at this location all need to be processed.
29918 var componentView = lView[DECLARATION_COMPONENT_VIEW];
29919 var componentHost = componentView[T_HOST];
29920 var head = componentHost.projection[tNode.projection];
29921 if (Array.isArray(head)) {
29922 try {
29923 for (var head_1 = __values(head), head_1_1 = head_1.next(); !head_1_1.done; head_1_1 = head_1.next()) {
29924 var nativeNode_1 = head_1_1.value;
29925 _addQueryMatchR3(nativeNode_1, predicate, matches, elementsOnly, rootNativeNode);
29926 }
29927 }
29928 catch (e_1_1) { e_1 = { error: e_1_1 }; }
29929 finally {
29930 try {
29931 if (head_1_1 && !head_1_1.done && (_a = head_1.return)) _a.call(head_1);
29932 }
29933 finally { if (e_1) throw e_1.error; }
29934 }
29935 }
29936 else if (head) {
29937 var nextLView = componentView[PARENT];
29938 var nextTNode = nextLView[TVIEW].data[head.index];
29939 _queryNodeChildrenR3(nextTNode, nextLView, predicate, matches, elementsOnly, rootNativeNode);
29940 }
29941 }
29942 else if (tNode.child) {
29943 // Case 4: the TNode is a view.
29944 _queryNodeChildrenR3(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
29945 }
29946 // We don't want to go to the next sibling of the root node.
29947 if (rootNativeNode !== nativeNode) {
29948 // To determine the next node to be processed, we need to use the next or the projectionNext
29949 // link, depending on whether the current node has been projected.
29950 var nextTNode = (tNode.flags & 4 /* isProjected */) ? tNode.projectionNext : tNode.next;
29951 if (nextTNode) {
29952 _queryNodeChildrenR3(nextTNode, lView, predicate, matches, elementsOnly, rootNativeNode);
29953 }
29954 }
29955 }
29956 /**
29957 * Process all TNodes in a given container.
29958 *
29959 * @param lContainer the container to be processed
29960 * @param predicate the predicate to match
29961 * @param matches the list of positive matches
29962 * @param elementsOnly whether only elements should be searched
29963 * @param rootNativeNode the root native node on which predicate should not be matched
29964 */
29965 function _queryNodeChildrenInContainerR3(lContainer, predicate, matches, elementsOnly, rootNativeNode) {
29966 for (var i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
29967 var childView = lContainer[i];
29968 _queryNodeChildrenR3(childView[TVIEW].node, childView, predicate, matches, elementsOnly, rootNativeNode);
29969 }
29970 }
29971 /**
29972 * Match the current native node against the predicate.
29973 *
29974 * @param nativeNode the current native node
29975 * @param predicate the predicate to match
29976 * @param matches the list of positive matches
29977 * @param elementsOnly whether only elements should be searched
29978 * @param rootNativeNode the root native node on which predicate should not be matched
29979 */
29980 function _addQueryMatchR3(nativeNode, predicate, matches, elementsOnly, rootNativeNode) {
29981 if (rootNativeNode !== nativeNode) {
29982 var debugNode = getDebugNode$1(nativeNode);
29983 if (!debugNode) {
29984 return;
29985 }
29986 // Type of the "predicate and "matches" array are set based on the value of
29987 // the "elementsOnly" parameter. TypeScript is not able to properly infer these
29988 // types with generics, so we manually cast the parameters accordingly.
29989 if (elementsOnly && debugNode instanceof DebugElement__POST_R3__ && predicate(debugNode) &&
29990 matches.indexOf(debugNode) === -1) {
29991 matches.push(debugNode);
29992 }
29993 else if (!elementsOnly && predicate(debugNode) &&
29994 matches.indexOf(debugNode) === -1) {
29995 matches.push(debugNode);
29996 }
29997 }
29998 }
29999 /**
30000 * Match all the descendants of a DOM node against a predicate.
30001 *
30002 * @param nativeNode the current native node
30003 * @param predicate the predicate to match
30004 * @param matches the list of positive matches
30005 * @param elementsOnly whether only elements should be searched
30006 */
30007 function _queryNativeNodeDescendants(parentNode, predicate, matches, elementsOnly) {
30008 var nodes = parentNode.childNodes;
30009 var length = nodes.length;
30010 for (var i = 0; i < length; i++) {
30011 var node = nodes[i];
30012 var debugNode = getDebugNode$1(node);
30013 if (debugNode) {
30014 if (elementsOnly && debugNode instanceof DebugElement__POST_R3__ && predicate(debugNode) &&
30015 matches.indexOf(debugNode) === -1) {
30016 matches.push(debugNode);
30017 }
30018 else if (!elementsOnly && predicate(debugNode) &&
30019 matches.indexOf(debugNode) === -1) {
30020 matches.push(debugNode);
30021 }
30022 _queryNativeNodeDescendants(node, predicate, matches, elementsOnly);
30023 }
30024 }
30025 }
30026 /**
30027 * Iterates through the property bindings for a given node and generates
30028 * a map of property names to values. This map only contains property bindings
30029 * defined in templates, not in host bindings.
30030 */
30031 function collectPropertyBindings(properties, tNode, lView, tData) {
30032 var bindingIndexes = tNode.propertyBindings;
30033 if (bindingIndexes !== null) {
30034 for (var i = 0; i < bindingIndexes.length; i++) {
30035 var bindingIndex = bindingIndexes[i];
30036 var propMetadata = tData[bindingIndex];
30037 var metadataParts = propMetadata.split(INTERPOLATION_DELIMITER);
30038 var propertyName = metadataParts[0];
30039 if (metadataParts.length > 1) {
30040 var value = metadataParts[1];
30041 for (var j = 1; j < metadataParts.length - 1; j++) {
30042 value += renderStringify(lView[bindingIndex + j - 1]) + metadataParts[j + 1];
30043 }
30044 properties[propertyName] = value;
30045 }
30046 else {
30047 properties[propertyName] = lView[bindingIndex];
30048 }
30049 }
30050 }
30051 }
30052 // Need to keep the nodes in a global Map so that multiple angular apps are supported.
30053 var _nativeNodeToDebugNode = new Map();
30054 function getDebugNode__PRE_R3__(nativeNode) {
30055 return _nativeNodeToDebugNode.get(nativeNode) || null;
30056 }
30057 var NG_DEBUG_PROPERTY = '__ng_debug__';
30058 function getDebugNode__POST_R3__(nativeNode) {
30059 if (nativeNode instanceof Node) {
30060 if (!(nativeNode.hasOwnProperty(NG_DEBUG_PROPERTY))) {
30061 nativeNode[NG_DEBUG_PROPERTY] = nativeNode.nodeType == Node.ELEMENT_NODE ?
30062 new DebugElement__POST_R3__(nativeNode) :
30063 new DebugNode__POST_R3__(nativeNode);
30064 }
30065 return nativeNode[NG_DEBUG_PROPERTY];
30066 }
30067 return null;
30068 }
30069 /**
30070 * @publicApi
30071 */
30072 var getDebugNode$1 = getDebugNode__PRE_R3__;
30073 function getDebugNodeR2__PRE_R3__(nativeNode) {
30074 return getDebugNode__PRE_R3__(nativeNode);
30075 }
30076 function getDebugNodeR2__POST_R3__(_nativeNode) {
30077 return null;
30078 }
30079 var getDebugNodeR2 = getDebugNodeR2__PRE_R3__;
30080 function getAllDebugNodes() {
30081 return Array.from(_nativeNodeToDebugNode.values());
30082 }
30083 function indexDebugNode(node) {
30084 _nativeNodeToDebugNode.set(node.nativeNode, node);
30085 }
30086 function removeDebugNodeFromIndex(node) {
30087 _nativeNodeToDebugNode.delete(node.nativeNode);
30088 }
30089 /**
30090 * @publicApi
30091 */
30092 var DebugNode = DebugNode__PRE_R3__;
30093 /**
30094 * @publicApi
30095 */
30096 var DebugElement = DebugElement__PRE_R3__;
30097
30098 /**
30099 * @license
30100 * Copyright Google LLC All Rights Reserved.
30101 *
30102 * Use of this source code is governed by an MIT-style license that can be
30103 * found in the LICENSE file at https://angular.io/license
30104 */
30105
30106 /**
30107 * @license
30108 * Copyright Google LLC All Rights Reserved.
30109 *
30110 * Use of this source code is governed by an MIT-style license that can be
30111 * found in the LICENSE file at https://angular.io/license
30112 */
30113 var _CORE_PLATFORM_PROVIDERS = [
30114 // Set a default platform name for platforms that don't set it explicitly.
30115 { provide: PLATFORM_ID, useValue: 'unknown' },
30116 { provide: PlatformRef, deps: [Injector] },
30117 { provide: TestabilityRegistry, deps: [] },
30118 { provide: Console, deps: [] },
30119 ];
30120 /**
30121 * This platform has to be included in any other platform
30122 *
30123 * @publicApi
30124 */
30125 var platformCore = createPlatformFactory(null, 'core', _CORE_PLATFORM_PROVIDERS);
30126
30127 /**
30128 * @license
30129 * Copyright Google LLC All Rights Reserved.
30130 *
30131 * Use of this source code is governed by an MIT-style license that can be
30132 * found in the LICENSE file at https://angular.io/license
30133 */
30134 function _iterableDiffersFactory() {
30135 return defaultIterableDiffers;
30136 }
30137 function _keyValueDiffersFactory() {
30138 return defaultKeyValueDiffers;
30139 }
30140 function _localeFactory(locale) {
30141 locale = locale || getGlobalLocale();
30142 if (ivyEnabled) {
30143 setLocaleId(locale);
30144 }
30145 return locale;
30146 }
30147 /**
30148 * Work out the locale from the potential global properties.
30149 *
30150 * * Closure Compiler: use `goog.LOCALE`.
30151 * * Ivy enabled: use `$localize.locale`
30152 */
30153 function getGlobalLocale() {
30154 if (typeof ngI18nClosureMode !== 'undefined' && ngI18nClosureMode &&
30155 typeof goog !== 'undefined' && goog.LOCALE !== 'en') {
30156 // * The default `goog.LOCALE` value is `en`, while Angular used `en-US`.
30157 // * In order to preserve backwards compatibility, we use Angular default value over
30158 // Closure Compiler's one.
30159 return goog.LOCALE;
30160 }
30161 else {
30162 // KEEP `typeof $localize !== 'undefined' && $localize.locale` IN SYNC WITH THE LOCALIZE
30163 // COMPILE-TIME INLINER.
30164 //
30165 // * During compile time inlining of translations the expression will be replaced
30166 // with a string literal that is the current locale. Other forms of this expression are not
30167 // guaranteed to be replaced.
30168 //
30169 // * During runtime translation evaluation, the developer is required to set `$localize.locale`
30170 // if required, or just to provide their own `LOCALE_ID` provider.
30171 return (ivyEnabled && typeof $localize !== 'undefined' && $localize.locale) ||
30172 DEFAULT_LOCALE_ID;
30173 }
30174 }
30175 var ɵ0$g = USD_CURRENCY_CODE;
30176 /**
30177 * A built-in [dependency injection token](guide/glossary#di-token)
30178 * that is used to configure the root injector for bootstrapping.
30179 */
30180 var APPLICATION_MODULE_PROVIDERS = [
30181 {
30182 provide: ApplicationRef,
30183 useClass: ApplicationRef,
30184 deps: [NgZone, Console, Injector, ErrorHandler, ComponentFactoryResolver, ApplicationInitStatus]
30185 },
30186 { provide: SCHEDULER, deps: [NgZone], useFactory: zoneSchedulerFactory },
30187 {
30188 provide: ApplicationInitStatus,
30189 useClass: ApplicationInitStatus,
30190 deps: [[new Optional(), APP_INITIALIZER]]
30191 },
30192 { provide: Compiler, useClass: Compiler, deps: [] },
30193 APP_ID_RANDOM_PROVIDER,
30194 { provide: IterableDiffers, useFactory: _iterableDiffersFactory, deps: [] },
30195 { provide: KeyValueDiffers, useFactory: _keyValueDiffersFactory, deps: [] },
30196 {
30197 provide: LOCALE_ID$1,
30198 useFactory: _localeFactory,
30199 deps: [[new Inject(LOCALE_ID$1), new Optional(), new SkipSelf()]]
30200 },
30201 { provide: DEFAULT_CURRENCY_CODE, useValue: ɵ0$g },
30202 ];
30203 /**
30204 * Schedule work at next available slot.
30205 *
30206 * In Ivy this is just `requestAnimationFrame`. For compatibility reasons when bootstrapped
30207 * using `platformRef.bootstrap` we need to use `NgZone.onStable` as the scheduling mechanism.
30208 * This overrides the scheduling mechanism in Ivy to `NgZone.onStable`.
30209 *
30210 * @param ngZone NgZone to use for scheduling.
30211 */
30212 function zoneSchedulerFactory(ngZone) {
30213 var queue = [];
30214 ngZone.onStable.subscribe(function () {
30215 while (queue.length) {
30216 queue.pop()();
30217 }
30218 });
30219 return function (fn) {
30220 queue.push(fn);
30221 };
30222 }
30223 /**
30224 * Configures the root injector for an app with
30225 * providers of `@angular/core` dependencies that `ApplicationRef` needs
30226 * to bootstrap components.
30227 *
30228 * Re-exported by `BrowserModule`, which is included automatically in the root
30229 * `AppModule` when you create a new app with the CLI `new` command.
30230 *
30231 * @publicApi
30232 */
30233 var ApplicationModule = /** @class */ (function () {
30234 // Inject ApplicationRef to make it eager...
30235 function ApplicationModule(appRef) {
30236 }
30237 return ApplicationModule;
30238 }());
30239 ApplicationModule.decorators = [
30240 { type: NgModule, args: [{ providers: APPLICATION_MODULE_PROVIDERS },] }
30241 ];
30242 ApplicationModule.ctorParameters = function () { return [
30243 { type: ApplicationRef }
30244 ]; };
30245
30246 function anchorDef(flags, matchedQueriesDsl, ngContentIndex, childCount, handleEvent, templateFactory) {
30247 flags |= 1 /* TypeElement */;
30248 var _a = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _a.matchedQueries, references = _a.references, matchedQueryIds = _a.matchedQueryIds;
30249 var template = templateFactory ? resolveDefinition(templateFactory) : null;
30250 return {
30251 // will bet set by the view definition
30252 nodeIndex: -1,
30253 parent: null,
30254 renderParent: null,
30255 bindingIndex: -1,
30256 outputIndex: -1,
30257 // regular values
30258 flags: flags,
30259 checkIndex: -1,
30260 childFlags: 0,
30261 directChildFlags: 0,
30262 childMatchedQueries: 0,
30263 matchedQueries: matchedQueries,
30264 matchedQueryIds: matchedQueryIds,
30265 references: references,
30266 ngContentIndex: ngContentIndex,
30267 childCount: childCount,
30268 bindings: [],
30269 bindingFlags: 0,
30270 outputs: [],
30271 element: {
30272 ns: null,
30273 name: null,
30274 attrs: null,
30275 template: template,
30276 componentProvider: null,
30277 componentView: null,
30278 componentRendererType: null,
30279 publicProviders: null,
30280 allProviders: null,
30281 handleEvent: handleEvent || NOOP
30282 },
30283 provider: null,
30284 text: null,
30285 query: null,
30286 ngContent: null
30287 };
30288 }
30289 function elementDef(checkIndex, flags, matchedQueriesDsl, ngContentIndex, childCount, namespaceAndName, fixedAttrs, bindings, outputs, handleEvent, componentView, componentRendererType) {
30290 var _a;
30291 if (fixedAttrs === void 0) { fixedAttrs = []; }
30292 if (!handleEvent) {
30293 handleEvent = NOOP;
30294 }
30295 var _b = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _b.matchedQueries, references = _b.references, matchedQueryIds = _b.matchedQueryIds;
30296 var ns = null;
30297 var name = null;
30298 if (namespaceAndName) {
30299 _a = __read(splitNamespace(namespaceAndName), 2), ns = _a[0], name = _a[1];
30300 }
30301 bindings = bindings || [];
30302 var bindingDefs = [];
30303 for (var i = 0; i < bindings.length; i++) {
30304 var _c = __read(bindings[i], 3), bindingFlags = _c[0], namespaceAndName_1 = _c[1], suffixOrSecurityContext = _c[2];
30305 var _d = __read(splitNamespace(namespaceAndName_1), 2), ns_1 = _d[0], name_1 = _d[1];
30306 var securityContext = undefined;
30307 var suffix = undefined;
30308 switch (bindingFlags & 15 /* Types */) {
30309 case 4 /* TypeElementStyle */:
30310 suffix = suffixOrSecurityContext;
30311 break;
30312 case 1 /* TypeElementAttribute */:
30313 case 8 /* TypeProperty */:
30314 securityContext = suffixOrSecurityContext;
30315 break;
30316 }
30317 bindingDefs[i] =
30318 { flags: bindingFlags, ns: ns_1, name: name_1, nonMinifiedName: name_1, securityContext: securityContext, suffix: suffix };
30319 }
30320 outputs = outputs || [];
30321 var outputDefs = [];
30322 for (var i = 0; i < outputs.length; i++) {
30323 var _e = __read(outputs[i], 2), target = _e[0], eventName = _e[1];
30324 outputDefs[i] =
30325 { type: 0 /* ElementOutput */, target: target, eventName: eventName, propName: null };
30326 }
30327 fixedAttrs = fixedAttrs || [];
30328 var attrs = fixedAttrs.map(function (_a) {
30329 var _b = __read(_a, 2), namespaceAndName = _b[0], value = _b[1];
30330 var _c = __read(splitNamespace(namespaceAndName), 2), ns = _c[0], name = _c[1];
30331 return [ns, name, value];
30332 });
30333 componentRendererType = resolveRendererType2(componentRendererType);
30334 if (componentView) {
30335 flags |= 33554432 /* ComponentView */;
30336 }
30337 flags |= 1 /* TypeElement */;
30338 return {
30339 // will bet set by the view definition
30340 nodeIndex: -1,
30341 parent: null,
30342 renderParent: null,
30343 bindingIndex: -1,
30344 outputIndex: -1,
30345 // regular values
30346 checkIndex: checkIndex,
30347 flags: flags,
30348 childFlags: 0,
30349 directChildFlags: 0,
30350 childMatchedQueries: 0,
30351 matchedQueries: matchedQueries,
30352 matchedQueryIds: matchedQueryIds,
30353 references: references,
30354 ngContentIndex: ngContentIndex,
30355 childCount: childCount,
30356 bindings: bindingDefs,
30357 bindingFlags: calcBindingFlags(bindingDefs),
30358 outputs: outputDefs,
30359 element: {
30360 ns: ns,
30361 name: name,
30362 attrs: attrs,
30363 template: null,
30364 // will bet set by the view definition
30365 componentProvider: null,
30366 componentView: componentView || null,
30367 componentRendererType: componentRendererType,
30368 publicProviders: null,
30369 allProviders: null,
30370 handleEvent: handleEvent || NOOP,
30371 },
30372 provider: null,
30373 text: null,
30374 query: null,
30375 ngContent: null
30376 };
30377 }
30378 function createElement(view, renderHost, def) {
30379 var elDef = def.element;
30380 var rootSelectorOrNode = view.root.selectorOrNode;
30381 var renderer = view.renderer;
30382 var el;
30383 if (view.parent || !rootSelectorOrNode) {
30384 if (elDef.name) {
30385 el = renderer.createElement(elDef.name, elDef.ns);
30386 }
30387 else {
30388 el = renderer.createComment('');
30389 }
30390 var parentEl = getParentRenderElement(view, renderHost, def);
30391 if (parentEl) {
30392 renderer.appendChild(parentEl, el);
30393 }
30394 }
30395 else {
30396 // when using native Shadow DOM, do not clear the root element contents to allow slot projection
30397 var preserveContent = (!!elDef.componentRendererType &&
30398 elDef.componentRendererType.encapsulation === exports.ViewEncapsulation.ShadowDom);
30399 el = renderer.selectRootElement(rootSelectorOrNode, preserveContent);
30400 }
30401 if (elDef.attrs) {
30402 for (var i = 0; i < elDef.attrs.length; i++) {
30403 var _a = __read(elDef.attrs[i], 3), ns = _a[0], name = _a[1], value = _a[2];
30404 renderer.setAttribute(el, name, value, ns);
30405 }
30406 }
30407 return el;
30408 }
30409 function listenToElementOutputs(view, compView, def, el) {
30410 for (var i = 0; i < def.outputs.length; i++) {
30411 var output = def.outputs[i];
30412 var handleEventClosure = renderEventHandlerClosure(view, def.nodeIndex, elementEventFullName(output.target, output.eventName));
30413 var listenTarget = output.target;
30414 var listenerView = view;
30415 if (output.target === 'component') {
30416 listenTarget = null;
30417 listenerView = compView;
30418 }
30419 var disposable = listenerView.renderer.listen(listenTarget || el, output.eventName, handleEventClosure);
30420 view.disposables[def.outputIndex + i] = disposable;
30421 }
30422 }
30423 function renderEventHandlerClosure(view, index, eventName) {
30424 return function (event) { return dispatchEvent(view, index, eventName, event); };
30425 }
30426 function checkAndUpdateElementInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
30427 var bindLen = def.bindings.length;
30428 var changed = false;
30429 if (bindLen > 0 && checkAndUpdateElementValue(view, def, 0, v0))
30430 changed = true;
30431 if (bindLen > 1 && checkAndUpdateElementValue(view, def, 1, v1))
30432 changed = true;
30433 if (bindLen > 2 && checkAndUpdateElementValue(view, def, 2, v2))
30434 changed = true;
30435 if (bindLen > 3 && checkAndUpdateElementValue(view, def, 3, v3))
30436 changed = true;
30437 if (bindLen > 4 && checkAndUpdateElementValue(view, def, 4, v4))
30438 changed = true;
30439 if (bindLen > 5 && checkAndUpdateElementValue(view, def, 5, v5))
30440 changed = true;
30441 if (bindLen > 6 && checkAndUpdateElementValue(view, def, 6, v6))
30442 changed = true;
30443 if (bindLen > 7 && checkAndUpdateElementValue(view, def, 7, v7))
30444 changed = true;
30445 if (bindLen > 8 && checkAndUpdateElementValue(view, def, 8, v8))
30446 changed = true;
30447 if (bindLen > 9 && checkAndUpdateElementValue(view, def, 9, v9))
30448 changed = true;
30449 return changed;
30450 }
30451 function checkAndUpdateElementDynamic(view, def, values) {
30452 var changed = false;
30453 for (var i = 0; i < values.length; i++) {
30454 if (checkAndUpdateElementValue(view, def, i, values[i]))
30455 changed = true;
30456 }
30457 return changed;
30458 }
30459 function checkAndUpdateElementValue(view, def, bindingIdx, value) {
30460 if (!checkAndUpdateBinding(view, def, bindingIdx, value)) {
30461 return false;
30462 }
30463 var binding = def.bindings[bindingIdx];
30464 var elData = asElementData(view, def.nodeIndex);
30465 var renderNode = elData.renderElement;
30466 var name = binding.name;
30467 switch (binding.flags & 15 /* Types */) {
30468 case 1 /* TypeElementAttribute */:
30469 setElementAttribute(view, binding, renderNode, binding.ns, name, value);
30470 break;
30471 case 2 /* TypeElementClass */:
30472 setElementClass(view, renderNode, name, value);
30473 break;
30474 case 4 /* TypeElementStyle */:
30475 setElementStyle(view, binding, renderNode, name, value);
30476 break;
30477 case 8 /* TypeProperty */:
30478 var bindView = (def.flags & 33554432 /* ComponentView */ &&
30479 binding.flags & 32 /* SyntheticHostProperty */) ?
30480 elData.componentView :
30481 view;
30482 setElementProperty(bindView, binding, renderNode, name, value);
30483 break;
30484 }
30485 return true;
30486 }
30487 function setElementAttribute(view, binding, renderNode, ns, name, value) {
30488 var securityContext = binding.securityContext;
30489 var renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
30490 renderValue = renderValue != null ? renderValue.toString() : null;
30491 var renderer = view.renderer;
30492 if (value != null) {
30493 renderer.setAttribute(renderNode, name, renderValue, ns);
30494 }
30495 else {
30496 renderer.removeAttribute(renderNode, name, ns);
30497 }
30498 }
30499 function setElementClass(view, renderNode, name, value) {
30500 var renderer = view.renderer;
30501 if (value) {
30502 renderer.addClass(renderNode, name);
30503 }
30504 else {
30505 renderer.removeClass(renderNode, name);
30506 }
30507 }
30508 function setElementStyle(view, binding, renderNode, name, value) {
30509 var renderValue = view.root.sanitizer.sanitize(exports.SecurityContext.STYLE, value);
30510 if (renderValue != null) {
30511 renderValue = renderValue.toString();
30512 var unit = binding.suffix;
30513 if (unit != null) {
30514 renderValue = renderValue + unit;
30515 }
30516 }
30517 else {
30518 renderValue = null;
30519 }
30520 var renderer = view.renderer;
30521 if (renderValue != null) {
30522 renderer.setStyle(renderNode, name, renderValue);
30523 }
30524 else {
30525 renderer.removeStyle(renderNode, name);
30526 }
30527 }
30528 function setElementProperty(view, binding, renderNode, name, value) {
30529 var securityContext = binding.securityContext;
30530 var renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
30531 view.renderer.setProperty(renderNode, name, renderValue);
30532 }
30533
30534 /**
30535 * @license
30536 * Copyright Google LLC All Rights Reserved.
30537 *
30538 * Use of this source code is governed by an MIT-style license that can be
30539 * found in the LICENSE file at https://angular.io/license
30540 */
30541 function queryDef(flags, id, bindings) {
30542 var bindingDefs = [];
30543 for (var propName in bindings) {
30544 var bindingType = bindings[propName];
30545 bindingDefs.push({ propName: propName, bindingType: bindingType });
30546 }
30547 return {
30548 // will bet set by the view definition
30549 nodeIndex: -1,
30550 parent: null,
30551 renderParent: null,
30552 bindingIndex: -1,
30553 outputIndex: -1,
30554 // regular values
30555 // TODO(vicb): check
30556 checkIndex: -1,
30557 flags: flags,
30558 childFlags: 0,
30559 directChildFlags: 0,
30560 childMatchedQueries: 0,
30561 ngContentIndex: -1,
30562 matchedQueries: {},
30563 matchedQueryIds: 0,
30564 references: {},
30565 childCount: 0,
30566 bindings: [],
30567 bindingFlags: 0,
30568 outputs: [],
30569 element: null,
30570 provider: null,
30571 text: null,
30572 query: { id: id, filterId: filterQueryId(id), bindings: bindingDefs },
30573 ngContent: null
30574 };
30575 }
30576 function createQuery() {
30577 return new QueryList();
30578 }
30579 function dirtyParentQueries(view) {
30580 var queryIds = view.def.nodeMatchedQueries;
30581 while (view.parent && isEmbeddedView(view)) {
30582 var tplDef = view.parentNodeDef;
30583 view = view.parent;
30584 // content queries
30585 var end = tplDef.nodeIndex + tplDef.childCount;
30586 for (var i = 0; i <= end; i++) {
30587 var nodeDef = view.def.nodes[i];
30588 if ((nodeDef.flags & 67108864 /* TypeContentQuery */) &&
30589 (nodeDef.flags & 536870912 /* DynamicQuery */) &&
30590 (nodeDef.query.filterId & queryIds) === nodeDef.query.filterId) {
30591 asQueryList(view, i).setDirty();
30592 }
30593 if ((nodeDef.flags & 1 /* TypeElement */ && i + nodeDef.childCount < tplDef.nodeIndex) ||
30594 !(nodeDef.childFlags & 67108864 /* TypeContentQuery */) ||
30595 !(nodeDef.childFlags & 536870912 /* DynamicQuery */)) {
30596 // skip elements that don't contain the template element or no query.
30597 i += nodeDef.childCount;
30598 }
30599 }
30600 }
30601 // view queries
30602 if (view.def.nodeFlags & 134217728 /* TypeViewQuery */) {
30603 for (var i = 0; i < view.def.nodes.length; i++) {
30604 var nodeDef = view.def.nodes[i];
30605 if ((nodeDef.flags & 134217728 /* TypeViewQuery */) && (nodeDef.flags & 536870912 /* DynamicQuery */)) {
30606 asQueryList(view, i).setDirty();
30607 }
30608 // only visit the root nodes
30609 i += nodeDef.childCount;
30610 }
30611 }
30612 }
30613 function checkAndUpdateQuery(view, nodeDef) {
30614 var queryList = asQueryList(view, nodeDef.nodeIndex);
30615 if (!queryList.dirty) {
30616 return;
30617 }
30618 var directiveInstance;
30619 var newValues = undefined;
30620 if (nodeDef.flags & 67108864 /* TypeContentQuery */) {
30621 var elementDef = nodeDef.parent.parent;
30622 newValues = calcQueryValues(view, elementDef.nodeIndex, elementDef.nodeIndex + elementDef.childCount, nodeDef.query, []);
30623 directiveInstance = asProviderData(view, nodeDef.parent.nodeIndex).instance;
30624 }
30625 else if (nodeDef.flags & 134217728 /* TypeViewQuery */) {
30626 newValues = calcQueryValues(view, 0, view.def.nodes.length - 1, nodeDef.query, []);
30627 directiveInstance = view.component;
30628 }
30629 queryList.reset(newValues);
30630 var bindings = nodeDef.query.bindings;
30631 var notify = false;
30632 for (var i = 0; i < bindings.length; i++) {
30633 var binding = bindings[i];
30634 var boundValue = void 0;
30635 switch (binding.bindingType) {
30636 case 0 /* First */:
30637 boundValue = queryList.first;
30638 break;
30639 case 1 /* All */:
30640 boundValue = queryList;
30641 notify = true;
30642 break;
30643 }
30644 directiveInstance[binding.propName] = boundValue;
30645 }
30646 if (notify) {
30647 queryList.notifyOnChanges();
30648 }
30649 }
30650 function calcQueryValues(view, startIndex, endIndex, queryDef, values) {
30651 for (var i = startIndex; i <= endIndex; i++) {
30652 var nodeDef = view.def.nodes[i];
30653 var valueType = nodeDef.matchedQueries[queryDef.id];
30654 if (valueType != null) {
30655 values.push(getQueryValue(view, nodeDef, valueType));
30656 }
30657 if (nodeDef.flags & 1 /* TypeElement */ && nodeDef.element.template &&
30658 (nodeDef.element.template.nodeMatchedQueries & queryDef.filterId) ===
30659 queryDef.filterId) {
30660 var elementData = asElementData(view, i);
30661 // check embedded views that were attached at the place of their template,
30662 // but process child nodes first if some match the query (see issue #16568)
30663 if ((nodeDef.childMatchedQueries & queryDef.filterId) === queryDef.filterId) {
30664 calcQueryValues(view, i + 1, i + nodeDef.childCount, queryDef, values);
30665 i += nodeDef.childCount;
30666 }
30667 if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
30668 var embeddedViews = elementData.viewContainer._embeddedViews;
30669 for (var k = 0; k < embeddedViews.length; k++) {
30670 var embeddedView = embeddedViews[k];
30671 var dvc = declaredViewContainer(embeddedView);
30672 if (dvc && dvc === elementData) {
30673 calcQueryValues(embeddedView, 0, embeddedView.def.nodes.length - 1, queryDef, values);
30674 }
30675 }
30676 }
30677 var projectedViews = elementData.template._projectedViews;
30678 if (projectedViews) {
30679 for (var k = 0; k < projectedViews.length; k++) {
30680 var projectedView = projectedViews[k];
30681 calcQueryValues(projectedView, 0, projectedView.def.nodes.length - 1, queryDef, values);
30682 }
30683 }
30684 }
30685 if ((nodeDef.childMatchedQueries & queryDef.filterId) !== queryDef.filterId) {
30686 // if no child matches the query, skip the children.
30687 i += nodeDef.childCount;
30688 }
30689 }
30690 return values;
30691 }
30692 function getQueryValue(view, nodeDef, queryValueType) {
30693 if (queryValueType != null) {
30694 // a match
30695 switch (queryValueType) {
30696 case 1 /* RenderElement */:
30697 return asElementData(view, nodeDef.nodeIndex).renderElement;
30698 case 0 /* ElementRef */:
30699 return new ElementRef(asElementData(view, nodeDef.nodeIndex).renderElement);
30700 case 2 /* TemplateRef */:
30701 return asElementData(view, nodeDef.nodeIndex).template;
30702 case 3 /* ViewContainerRef */:
30703 return asElementData(view, nodeDef.nodeIndex).viewContainer;
30704 case 4 /* Provider */:
30705 return asProviderData(view, nodeDef.nodeIndex).instance;
30706 }
30707 }
30708 }
30709
30710 /**
30711 * @license
30712 * Copyright Google LLC All Rights Reserved.
30713 *
30714 * Use of this source code is governed by an MIT-style license that can be
30715 * found in the LICENSE file at https://angular.io/license
30716 */
30717 function ngContentDef(ngContentIndex, index) {
30718 return {
30719 // will bet set by the view definition
30720 nodeIndex: -1,
30721 parent: null,
30722 renderParent: null,
30723 bindingIndex: -1,
30724 outputIndex: -1,
30725 // regular values
30726 checkIndex: -1,
30727 flags: 8 /* TypeNgContent */,
30728 childFlags: 0,
30729 directChildFlags: 0,
30730 childMatchedQueries: 0,
30731 matchedQueries: {},
30732 matchedQueryIds: 0,
30733 references: {},
30734 ngContentIndex: ngContentIndex,
30735 childCount: 0,
30736 bindings: [],
30737 bindingFlags: 0,
30738 outputs: [],
30739 element: null,
30740 provider: null,
30741 text: null,
30742 query: null,
30743 ngContent: { index: index }
30744 };
30745 }
30746 function appendNgContent(view, renderHost, def) {
30747 var parentEl = getParentRenderElement(view, renderHost, def);
30748 if (!parentEl) {
30749 // Nothing to do if there is no parent element.
30750 return;
30751 }
30752 var ngContentIndex = def.ngContent.index;
30753 visitProjectedRenderNodes(view, ngContentIndex, 1 /* AppendChild */, parentEl, null, undefined);
30754 }
30755
30756 function purePipeDef(checkIndex, argCount) {
30757 // argCount + 1 to include the pipe as first arg
30758 return _pureExpressionDef(128 /* TypePurePipe */, checkIndex, newArray(argCount + 1));
30759 }
30760 function pureArrayDef(checkIndex, argCount) {
30761 return _pureExpressionDef(32 /* TypePureArray */, checkIndex, newArray(argCount));
30762 }
30763 function pureObjectDef(checkIndex, propToIndex) {
30764 var keys = Object.keys(propToIndex);
30765 var nbKeys = keys.length;
30766 var propertyNames = [];
30767 for (var i = 0; i < nbKeys; i++) {
30768 var key = keys[i];
30769 var index = propToIndex[key];
30770 propertyNames.push(key);
30771 }
30772 return _pureExpressionDef(64 /* TypePureObject */, checkIndex, propertyNames);
30773 }
30774 function _pureExpressionDef(flags, checkIndex, propertyNames) {
30775 var bindings = [];
30776 for (var i = 0; i < propertyNames.length; i++) {
30777 var prop = propertyNames[i];
30778 bindings.push({
30779 flags: 8 /* TypeProperty */,
30780 name: prop,
30781 ns: null,
30782 nonMinifiedName: prop,
30783 securityContext: null,
30784 suffix: null
30785 });
30786 }
30787 return {
30788 // will bet set by the view definition
30789 nodeIndex: -1,
30790 parent: null,
30791 renderParent: null,
30792 bindingIndex: -1,
30793 outputIndex: -1,
30794 // regular values
30795 checkIndex: checkIndex,
30796 flags: flags,
30797 childFlags: 0,
30798 directChildFlags: 0,
30799 childMatchedQueries: 0,
30800 matchedQueries: {},
30801 matchedQueryIds: 0,
30802 references: {},
30803 ngContentIndex: -1,
30804 childCount: 0,
30805 bindings: bindings,
30806 bindingFlags: calcBindingFlags(bindings),
30807 outputs: [],
30808 element: null,
30809 provider: null,
30810 text: null,
30811 query: null,
30812 ngContent: null
30813 };
30814 }
30815 function createPureExpression(view, def) {
30816 return { value: undefined };
30817 }
30818 function checkAndUpdatePureExpressionInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
30819 var bindings = def.bindings;
30820 var changed = false;
30821 var bindLen = bindings.length;
30822 if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
30823 changed = true;
30824 if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
30825 changed = true;
30826 if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
30827 changed = true;
30828 if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
30829 changed = true;
30830 if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
30831 changed = true;
30832 if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
30833 changed = true;
30834 if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
30835 changed = true;
30836 if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
30837 changed = true;
30838 if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
30839 changed = true;
30840 if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
30841 changed = true;
30842 if (changed) {
30843 var data = asPureExpressionData(view, def.nodeIndex);
30844 var value = void 0;
30845 switch (def.flags & 201347067 /* Types */) {
30846 case 32 /* TypePureArray */:
30847 value = [];
30848 if (bindLen > 0)
30849 value.push(v0);
30850 if (bindLen > 1)
30851 value.push(v1);
30852 if (bindLen > 2)
30853 value.push(v2);
30854 if (bindLen > 3)
30855 value.push(v3);
30856 if (bindLen > 4)
30857 value.push(v4);
30858 if (bindLen > 5)
30859 value.push(v5);
30860 if (bindLen > 6)
30861 value.push(v6);
30862 if (bindLen > 7)
30863 value.push(v7);
30864 if (bindLen > 8)
30865 value.push(v8);
30866 if (bindLen > 9)
30867 value.push(v9);
30868 break;
30869 case 64 /* TypePureObject */:
30870 value = {};
30871 if (bindLen > 0)
30872 value[bindings[0].name] = v0;
30873 if (bindLen > 1)
30874 value[bindings[1].name] = v1;
30875 if (bindLen > 2)
30876 value[bindings[2].name] = v2;
30877 if (bindLen > 3)
30878 value[bindings[3].name] = v3;
30879 if (bindLen > 4)
30880 value[bindings[4].name] = v4;
30881 if (bindLen > 5)
30882 value[bindings[5].name] = v5;
30883 if (bindLen > 6)
30884 value[bindings[6].name] = v6;
30885 if (bindLen > 7)
30886 value[bindings[7].name] = v7;
30887 if (bindLen > 8)
30888 value[bindings[8].name] = v8;
30889 if (bindLen > 9)
30890 value[bindings[9].name] = v9;
30891 break;
30892 case 128 /* TypePurePipe */:
30893 var pipe = v0;
30894 switch (bindLen) {
30895 case 1:
30896 value = pipe.transform(v0);
30897 break;
30898 case 2:
30899 value = pipe.transform(v1);
30900 break;
30901 case 3:
30902 value = pipe.transform(v1, v2);
30903 break;
30904 case 4:
30905 value = pipe.transform(v1, v2, v3);
30906 break;
30907 case 5:
30908 value = pipe.transform(v1, v2, v3, v4);
30909 break;
30910 case 6:
30911 value = pipe.transform(v1, v2, v3, v4, v5);
30912 break;
30913 case 7:
30914 value = pipe.transform(v1, v2, v3, v4, v5, v6);
30915 break;
30916 case 8:
30917 value = pipe.transform(v1, v2, v3, v4, v5, v6, v7);
30918 break;
30919 case 9:
30920 value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8);
30921 break;
30922 case 10:
30923 value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8, v9);
30924 break;
30925 }
30926 break;
30927 }
30928 data.value = value;
30929 }
30930 return changed;
30931 }
30932 function checkAndUpdatePureExpressionDynamic(view, def, values) {
30933 var bindings = def.bindings;
30934 var changed = false;
30935 for (var i = 0; i < values.length; i++) {
30936 // Note: We need to loop over all values, so that
30937 // the old values are updates as well!
30938 if (checkAndUpdateBinding(view, def, i, values[i])) {
30939 changed = true;
30940 }
30941 }
30942 if (changed) {
30943 var data = asPureExpressionData(view, def.nodeIndex);
30944 var value = void 0;
30945 switch (def.flags & 201347067 /* Types */) {
30946 case 32 /* TypePureArray */:
30947 value = values;
30948 break;
30949 case 64 /* TypePureObject */:
30950 value = {};
30951 for (var i = 0; i < values.length; i++) {
30952 value[bindings[i].name] = values[i];
30953 }
30954 break;
30955 case 128 /* TypePurePipe */:
30956 var pipe = values[0];
30957 var params = values.slice(1);
30958 value = pipe.transform.apply(pipe, __spread(params));
30959 break;
30960 }
30961 data.value = value;
30962 }
30963 return changed;
30964 }
30965
30966 /**
30967 * @license
30968 * Copyright Google LLC All Rights Reserved.
30969 *
30970 * Use of this source code is governed by an MIT-style license that can be
30971 * found in the LICENSE file at https://angular.io/license
30972 */
30973 function textDef(checkIndex, ngContentIndex, staticText) {
30974 var bindings = [];
30975 for (var i = 1; i < staticText.length; i++) {
30976 bindings[i - 1] = {
30977 flags: 8 /* TypeProperty */,
30978 name: null,
30979 ns: null,
30980 nonMinifiedName: null,
30981 securityContext: null,
30982 suffix: staticText[i],
30983 };
30984 }
30985 return {
30986 // will bet set by the view definition
30987 nodeIndex: -1,
30988 parent: null,
30989 renderParent: null,
30990 bindingIndex: -1,
30991 outputIndex: -1,
30992 // regular values
30993 checkIndex: checkIndex,
30994 flags: 2 /* TypeText */,
30995 childFlags: 0,
30996 directChildFlags: 0,
30997 childMatchedQueries: 0,
30998 matchedQueries: {},
30999 matchedQueryIds: 0,
31000 references: {},
31001 ngContentIndex: ngContentIndex,
31002 childCount: 0,
31003 bindings: bindings,
31004 bindingFlags: 8 /* TypeProperty */,
31005 outputs: [],
31006 element: null,
31007 provider: null,
31008 text: { prefix: staticText[0] },
31009 query: null,
31010 ngContent: null,
31011 };
31012 }
31013 function createText(view, renderHost, def) {
31014 var renderNode;
31015 var renderer = view.renderer;
31016 renderNode = renderer.createText(def.text.prefix);
31017 var parentEl = getParentRenderElement(view, renderHost, def);
31018 if (parentEl) {
31019 renderer.appendChild(parentEl, renderNode);
31020 }
31021 return { renderText: renderNode };
31022 }
31023 function checkAndUpdateTextInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
31024 var changed = false;
31025 var bindings = def.bindings;
31026 var bindLen = bindings.length;
31027 if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
31028 changed = true;
31029 if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
31030 changed = true;
31031 if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
31032 changed = true;
31033 if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
31034 changed = true;
31035 if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
31036 changed = true;
31037 if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
31038 changed = true;
31039 if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
31040 changed = true;
31041 if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
31042 changed = true;
31043 if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
31044 changed = true;
31045 if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
31046 changed = true;
31047 if (changed) {
31048 var value = def.text.prefix;
31049 if (bindLen > 0)
31050 value += _addInterpolationPart(v0, bindings[0]);
31051 if (bindLen > 1)
31052 value += _addInterpolationPart(v1, bindings[1]);
31053 if (bindLen > 2)
31054 value += _addInterpolationPart(v2, bindings[2]);
31055 if (bindLen > 3)
31056 value += _addInterpolationPart(v3, bindings[3]);
31057 if (bindLen > 4)
31058 value += _addInterpolationPart(v4, bindings[4]);
31059 if (bindLen > 5)
31060 value += _addInterpolationPart(v5, bindings[5]);
31061 if (bindLen > 6)
31062 value += _addInterpolationPart(v6, bindings[6]);
31063 if (bindLen > 7)
31064 value += _addInterpolationPart(v7, bindings[7]);
31065 if (bindLen > 8)
31066 value += _addInterpolationPart(v8, bindings[8]);
31067 if (bindLen > 9)
31068 value += _addInterpolationPart(v9, bindings[9]);
31069 var renderNode = asTextData(view, def.nodeIndex).renderText;
31070 view.renderer.setValue(renderNode, value);
31071 }
31072 return changed;
31073 }
31074 function checkAndUpdateTextDynamic(view, def, values) {
31075 var bindings = def.bindings;
31076 var changed = false;
31077 for (var i = 0; i < values.length; i++) {
31078 // Note: We need to loop over all values, so that
31079 // the old values are updates as well!
31080 if (checkAndUpdateBinding(view, def, i, values[i])) {
31081 changed = true;
31082 }
31083 }
31084 if (changed) {
31085 var value = '';
31086 for (var i = 0; i < values.length; i++) {
31087 value = value + _addInterpolationPart(values[i], bindings[i]);
31088 }
31089 value = def.text.prefix + value;
31090 var renderNode = asTextData(view, def.nodeIndex).renderText;
31091 view.renderer.setValue(renderNode, value);
31092 }
31093 return changed;
31094 }
31095 function _addInterpolationPart(value, binding) {
31096 var valueStr = value != null ? value.toString() : '';
31097 return valueStr + binding.suffix;
31098 }
31099
31100 /**
31101 * @license
31102 * Copyright Google LLC All Rights Reserved.
31103 *
31104 * Use of this source code is governed by an MIT-style license that can be
31105 * found in the LICENSE file at https://angular.io/license
31106 */
31107 function viewDef(flags, nodes, updateDirectives, updateRenderer) {
31108 // clone nodes and set auto calculated values
31109 var viewBindingCount = 0;
31110 var viewDisposableCount = 0;
31111 var viewNodeFlags = 0;
31112 var viewRootNodeFlags = 0;
31113 var viewMatchedQueries = 0;
31114 var currentParent = null;
31115 var currentRenderParent = null;
31116 var currentElementHasPublicProviders = false;
31117 var currentElementHasPrivateProviders = false;
31118 var lastRenderRootNode = null;
31119 for (var i = 0; i < nodes.length; i++) {
31120 var node = nodes[i];
31121 node.nodeIndex = i;
31122 node.parent = currentParent;
31123 node.bindingIndex = viewBindingCount;
31124 node.outputIndex = viewDisposableCount;
31125 node.renderParent = currentRenderParent;
31126 viewNodeFlags |= node.flags;
31127 viewMatchedQueries |= node.matchedQueryIds;
31128 if (node.element) {
31129 var elDef = node.element;
31130 elDef.publicProviders =
31131 currentParent ? currentParent.element.publicProviders : Object.create(null);
31132 elDef.allProviders = elDef.publicProviders;
31133 // Note: We assume that all providers of an element are before any child element!
31134 currentElementHasPublicProviders = false;
31135 currentElementHasPrivateProviders = false;
31136 if (node.element.template) {
31137 viewMatchedQueries |= node.element.template.nodeMatchedQueries;
31138 }
31139 }
31140 validateNode(currentParent, node, nodes.length);
31141 viewBindingCount += node.bindings.length;
31142 viewDisposableCount += node.outputs.length;
31143 if (!currentRenderParent && (node.flags & 3 /* CatRenderNode */)) {
31144 lastRenderRootNode = node;
31145 }
31146 if (node.flags & 20224 /* CatProvider */) {
31147 if (!currentElementHasPublicProviders) {
31148 currentElementHasPublicProviders = true;
31149 // Use prototypical inheritance to not get O(n^2) complexity...
31150 currentParent.element.publicProviders =
31151 Object.create(currentParent.element.publicProviders);
31152 currentParent.element.allProviders = currentParent.element.publicProviders;
31153 }
31154 var isPrivateService = (node.flags & 8192 /* PrivateProvider */) !== 0;
31155 var isComponent = (node.flags & 32768 /* Component */) !== 0;
31156 if (!isPrivateService || isComponent) {
31157 currentParent.element.publicProviders[tokenKey(node.provider.token)] = node;
31158 }
31159 else {
31160 if (!currentElementHasPrivateProviders) {
31161 currentElementHasPrivateProviders = true;
31162 // Use prototypical inheritance to not get O(n^2) complexity...
31163 currentParent.element.allProviders =
31164 Object.create(currentParent.element.publicProviders);
31165 }
31166 currentParent.element.allProviders[tokenKey(node.provider.token)] = node;
31167 }
31168 if (isComponent) {
31169 currentParent.element.componentProvider = node;
31170 }
31171 }
31172 if (currentParent) {
31173 currentParent.childFlags |= node.flags;
31174 currentParent.directChildFlags |= node.flags;
31175 currentParent.childMatchedQueries |= node.matchedQueryIds;
31176 if (node.element && node.element.template) {
31177 currentParent.childMatchedQueries |= node.element.template.nodeMatchedQueries;
31178 }
31179 }
31180 else {
31181 viewRootNodeFlags |= node.flags;
31182 }
31183 if (node.childCount > 0) {
31184 currentParent = node;
31185 if (!isNgContainer(node)) {
31186 currentRenderParent = node;
31187 }
31188 }
31189 else {
31190 // When the current node has no children, check if it is the last children of its parent.
31191 // When it is, propagate the flags up.
31192 // The loop is required because an element could be the last transitive children of several
31193 // elements. We loop to either the root or the highest opened element (= with remaining
31194 // children)
31195 while (currentParent && i === currentParent.nodeIndex + currentParent.childCount) {
31196 var newParent = currentParent.parent;
31197 if (newParent) {
31198 newParent.childFlags |= currentParent.childFlags;
31199 newParent.childMatchedQueries |= currentParent.childMatchedQueries;
31200 }
31201 currentParent = newParent;
31202 // We also need to update the render parent & account for ng-container
31203 if (currentParent && isNgContainer(currentParent)) {
31204 currentRenderParent = currentParent.renderParent;
31205 }
31206 else {
31207 currentRenderParent = currentParent;
31208 }
31209 }
31210 }
31211 }
31212 var handleEvent = function (view, nodeIndex, eventName, event) { return nodes[nodeIndex].element.handleEvent(view, eventName, event); };
31213 return {
31214 // Will be filled later...
31215 factory: null,
31216 nodeFlags: viewNodeFlags,
31217 rootNodeFlags: viewRootNodeFlags,
31218 nodeMatchedQueries: viewMatchedQueries,
31219 flags: flags,
31220 nodes: nodes,
31221 updateDirectives: updateDirectives || NOOP,
31222 updateRenderer: updateRenderer || NOOP,
31223 handleEvent: handleEvent,
31224 bindingCount: viewBindingCount,
31225 outputCount: viewDisposableCount,
31226 lastRenderRootNode: lastRenderRootNode
31227 };
31228 }
31229 function isNgContainer(node) {
31230 return (node.flags & 1 /* TypeElement */) !== 0 && node.element.name === null;
31231 }
31232 function validateNode(parent, node, nodeCount) {
31233 var template = node.element && node.element.template;
31234 if (template) {
31235 if (!template.lastRenderRootNode) {
31236 throw new Error("Illegal State: Embedded templates without nodes are not allowed!");
31237 }
31238 if (template.lastRenderRootNode &&
31239 template.lastRenderRootNode.flags & 16777216 /* EmbeddedViews */) {
31240 throw new Error("Illegal State: Last root node of a template can't have embedded views, at index " + node.nodeIndex + "!");
31241 }
31242 }
31243 if (node.flags & 20224 /* CatProvider */) {
31244 var parentFlags = parent ? parent.flags : 0;
31245 if ((parentFlags & 1 /* TypeElement */) === 0) {
31246 throw new Error("Illegal State: StaticProvider/Directive nodes need to be children of elements or anchors, at index " + node.nodeIndex + "!");
31247 }
31248 }
31249 if (node.query) {
31250 if (node.flags & 67108864 /* TypeContentQuery */ &&
31251 (!parent || (parent.flags & 16384 /* TypeDirective */) === 0)) {
31252 throw new Error("Illegal State: Content Query nodes need to be children of directives, at index " + node.nodeIndex + "!");
31253 }
31254 if (node.flags & 134217728 /* TypeViewQuery */ && parent) {
31255 throw new Error("Illegal State: View Query nodes have to be top level nodes, at index " + node.nodeIndex + "!");
31256 }
31257 }
31258 if (node.childCount) {
31259 var parentEnd = parent ? parent.nodeIndex + parent.childCount : nodeCount - 1;
31260 if (node.nodeIndex <= parentEnd && node.nodeIndex + node.childCount > parentEnd) {
31261 throw new Error("Illegal State: childCount of node leads outside of parent, at index " + node.nodeIndex + "!");
31262 }
31263 }
31264 }
31265 function createEmbeddedView(parent, anchorDef, viewDef, context) {
31266 // embedded views are seen as siblings to the anchor, so we need
31267 // to get the parent of the anchor and use it as parentIndex.
31268 var view = createView(parent.root, parent.renderer, parent, anchorDef, viewDef);
31269 initView(view, parent.component, context);
31270 createViewNodes(view);
31271 return view;
31272 }
31273 function createRootView(root, def, context) {
31274 var view = createView(root, root.renderer, null, null, def);
31275 initView(view, context, context);
31276 createViewNodes(view);
31277 return view;
31278 }
31279 function createComponentView(parentView, nodeDef, viewDef, hostElement) {
31280 var rendererType = nodeDef.element.componentRendererType;
31281 var compRenderer;
31282 if (!rendererType) {
31283 compRenderer = parentView.root.renderer;
31284 }
31285 else {
31286 compRenderer = parentView.root.rendererFactory.createRenderer(hostElement, rendererType);
31287 }
31288 return createView(parentView.root, compRenderer, parentView, nodeDef.element.componentProvider, viewDef);
31289 }
31290 function createView(root, renderer, parent, parentNodeDef, def) {
31291 var nodes = new Array(def.nodes.length);
31292 var disposables = def.outputCount ? new Array(def.outputCount) : null;
31293 var view = {
31294 def: def,
31295 parent: parent,
31296 viewContainerParent: null,
31297 parentNodeDef: parentNodeDef,
31298 context: null,
31299 component: null,
31300 nodes: nodes,
31301 state: 13 /* CatInit */,
31302 root: root,
31303 renderer: renderer,
31304 oldValues: new Array(def.bindingCount),
31305 disposables: disposables,
31306 initIndex: -1
31307 };
31308 return view;
31309 }
31310 function initView(view, component, context) {
31311 view.component = component;
31312 view.context = context;
31313 }
31314 function createViewNodes(view) {
31315 var renderHost;
31316 if (isComponentView(view)) {
31317 var hostDef = view.parentNodeDef;
31318 renderHost = asElementData(view.parent, hostDef.parent.nodeIndex).renderElement;
31319 }
31320 var def = view.def;
31321 var nodes = view.nodes;
31322 for (var i = 0; i < def.nodes.length; i++) {
31323 var nodeDef = def.nodes[i];
31324 Services.setCurrentNode(view, i);
31325 var nodeData = void 0;
31326 switch (nodeDef.flags & 201347067 /* Types */) {
31327 case 1 /* TypeElement */:
31328 var el = createElement(view, renderHost, nodeDef);
31329 var componentView = undefined;
31330 if (nodeDef.flags & 33554432 /* ComponentView */) {
31331 var compViewDef = resolveDefinition(nodeDef.element.componentView);
31332 componentView = Services.createComponentView(view, nodeDef, compViewDef, el);
31333 }
31334 listenToElementOutputs(view, componentView, nodeDef, el);
31335 nodeData = {
31336 renderElement: el,
31337 componentView: componentView,
31338 viewContainer: null,
31339 template: nodeDef.element.template ? createTemplateData(view, nodeDef) : undefined
31340 };
31341 if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
31342 nodeData.viewContainer = createViewContainerData(view, nodeDef, nodeData);
31343 }
31344 break;
31345 case 2 /* TypeText */:
31346 nodeData = createText(view, renderHost, nodeDef);
31347 break;
31348 case 512 /* TypeClassProvider */:
31349 case 1024 /* TypeFactoryProvider */:
31350 case 2048 /* TypeUseExistingProvider */:
31351 case 256 /* TypeValueProvider */: {
31352 nodeData = nodes[i];
31353 if (!nodeData && !(nodeDef.flags & 4096 /* LazyProvider */)) {
31354 var instance = createProviderInstance(view, nodeDef);
31355 nodeData = { instance: instance };
31356 }
31357 break;
31358 }
31359 case 16 /* TypePipe */: {
31360 var instance = createPipeInstance(view, nodeDef);
31361 nodeData = { instance: instance };
31362 break;
31363 }
31364 case 16384 /* TypeDirective */: {
31365 nodeData = nodes[i];
31366 if (!nodeData) {
31367 var instance = createDirectiveInstance(view, nodeDef);
31368 nodeData = { instance: instance };
31369 }
31370 if (nodeDef.flags & 32768 /* Component */) {
31371 var compView = asElementData(view, nodeDef.parent.nodeIndex).componentView;
31372 initView(compView, nodeData.instance, nodeData.instance);
31373 }
31374 break;
31375 }
31376 case 32 /* TypePureArray */:
31377 case 64 /* TypePureObject */:
31378 case 128 /* TypePurePipe */:
31379 nodeData = createPureExpression(view, nodeDef);
31380 break;
31381 case 67108864 /* TypeContentQuery */:
31382 case 134217728 /* TypeViewQuery */:
31383 nodeData = createQuery();
31384 break;
31385 case 8 /* TypeNgContent */:
31386 appendNgContent(view, renderHost, nodeDef);
31387 // no runtime data needed for NgContent...
31388 nodeData = undefined;
31389 break;
31390 }
31391 nodes[i] = nodeData;
31392 }
31393 // Create the ViewData.nodes of component views after we created everything else,
31394 // so that e.g. ng-content works
31395 execComponentViewsAction(view, ViewAction.CreateViewNodes);
31396 // fill static content and view queries
31397 execQueriesAction(view, 67108864 /* TypeContentQuery */ | 134217728 /* TypeViewQuery */, 268435456 /* StaticQuery */, 0 /* CheckAndUpdate */);
31398 }
31399 function checkNoChangesView(view) {
31400 markProjectedViewsForCheck(view);
31401 Services.updateDirectives(view, 1 /* CheckNoChanges */);
31402 execEmbeddedViewsAction(view, ViewAction.CheckNoChanges);
31403 Services.updateRenderer(view, 1 /* CheckNoChanges */);
31404 execComponentViewsAction(view, ViewAction.CheckNoChanges);
31405 // Note: We don't check queries for changes as we didn't do this in v2.x.
31406 // TODO(tbosch): investigate if we can enable the check again in v5.x with a nicer error message.
31407 view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
31408 }
31409 function checkAndUpdateView(view) {
31410 if (view.state & 1 /* BeforeFirstCheck */) {
31411 view.state &= ~1 /* BeforeFirstCheck */;
31412 view.state |= 2 /* FirstCheck */;
31413 }
31414 else {
31415 view.state &= ~2 /* FirstCheck */;
31416 }
31417 shiftInitState(view, 0 /* InitState_BeforeInit */, 256 /* InitState_CallingOnInit */);
31418 markProjectedViewsForCheck(view);
31419 Services.updateDirectives(view, 0 /* CheckAndUpdate */);
31420 execEmbeddedViewsAction(view, ViewAction.CheckAndUpdate);
31421 execQueriesAction(view, 67108864 /* TypeContentQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
31422 var callInit = shiftInitState(view, 256 /* InitState_CallingOnInit */, 512 /* InitState_CallingAfterContentInit */);
31423 callLifecycleHooksChildrenFirst(view, 2097152 /* AfterContentChecked */ | (callInit ? 1048576 /* AfterContentInit */ : 0));
31424 Services.updateRenderer(view, 0 /* CheckAndUpdate */);
31425 execComponentViewsAction(view, ViewAction.CheckAndUpdate);
31426 execQueriesAction(view, 134217728 /* TypeViewQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
31427 callInit = shiftInitState(view, 512 /* InitState_CallingAfterContentInit */, 768 /* InitState_CallingAfterViewInit */);
31428 callLifecycleHooksChildrenFirst(view, 8388608 /* AfterViewChecked */ | (callInit ? 4194304 /* AfterViewInit */ : 0));
31429 if (view.def.flags & 2 /* OnPush */) {
31430 view.state &= ~8 /* ChecksEnabled */;
31431 }
31432 view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
31433 shiftInitState(view, 768 /* InitState_CallingAfterViewInit */, 1024 /* InitState_AfterInit */);
31434 }
31435 function checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
31436 if (argStyle === 0 /* Inline */) {
31437 return checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
31438 }
31439 else {
31440 return checkAndUpdateNodeDynamic(view, nodeDef, v0);
31441 }
31442 }
31443 function markProjectedViewsForCheck(view) {
31444 var def = view.def;
31445 if (!(def.nodeFlags & 4 /* ProjectedTemplate */)) {
31446 return;
31447 }
31448 for (var i = 0; i < def.nodes.length; i++) {
31449 var nodeDef = def.nodes[i];
31450 if (nodeDef.flags & 4 /* ProjectedTemplate */) {
31451 var projectedViews = asElementData(view, i).template._projectedViews;
31452 if (projectedViews) {
31453 for (var i_1 = 0; i_1 < projectedViews.length; i_1++) {
31454 var projectedView = projectedViews[i_1];
31455 projectedView.state |= 32 /* CheckProjectedView */;
31456 markParentViewsForCheckProjectedViews(projectedView, view);
31457 }
31458 }
31459 }
31460 else if ((nodeDef.childFlags & 4 /* ProjectedTemplate */) === 0) {
31461 // a parent with leafs
31462 // no child is a component,
31463 // then skip the children
31464 i += nodeDef.childCount;
31465 }
31466 }
31467 }
31468 function checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
31469 switch (nodeDef.flags & 201347067 /* Types */) {
31470 case 1 /* TypeElement */:
31471 return checkAndUpdateElementInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
31472 case 2 /* TypeText */:
31473 return checkAndUpdateTextInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
31474 case 16384 /* TypeDirective */:
31475 return checkAndUpdateDirectiveInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
31476 case 32 /* TypePureArray */:
31477 case 64 /* TypePureObject */:
31478 case 128 /* TypePurePipe */:
31479 return checkAndUpdatePureExpressionInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
31480 default:
31481 throw 'unreachable';
31482 }
31483 }
31484 function checkAndUpdateNodeDynamic(view, nodeDef, values) {
31485 switch (nodeDef.flags & 201347067 /* Types */) {
31486 case 1 /* TypeElement */:
31487 return checkAndUpdateElementDynamic(view, nodeDef, values);
31488 case 2 /* TypeText */:
31489 return checkAndUpdateTextDynamic(view, nodeDef, values);
31490 case 16384 /* TypeDirective */:
31491 return checkAndUpdateDirectiveDynamic(view, nodeDef, values);
31492 case 32 /* TypePureArray */:
31493 case 64 /* TypePureObject */:
31494 case 128 /* TypePurePipe */:
31495 return checkAndUpdatePureExpressionDynamic(view, nodeDef, values);
31496 default:
31497 throw 'unreachable';
31498 }
31499 }
31500 function checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
31501 if (argStyle === 0 /* Inline */) {
31502 checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
31503 }
31504 else {
31505 checkNoChangesNodeDynamic(view, nodeDef, v0);
31506 }
31507 // Returning false is ok here as we would have thrown in case of a change.
31508 return false;
31509 }
31510 function checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
31511 var bindLen = nodeDef.bindings.length;
31512 if (bindLen > 0)
31513 checkBindingNoChanges(view, nodeDef, 0, v0);
31514 if (bindLen > 1)
31515 checkBindingNoChanges(view, nodeDef, 1, v1);
31516 if (bindLen > 2)
31517 checkBindingNoChanges(view, nodeDef, 2, v2);
31518 if (bindLen > 3)
31519 checkBindingNoChanges(view, nodeDef, 3, v3);
31520 if (bindLen > 4)
31521 checkBindingNoChanges(view, nodeDef, 4, v4);
31522 if (bindLen > 5)
31523 checkBindingNoChanges(view, nodeDef, 5, v5);
31524 if (bindLen > 6)
31525 checkBindingNoChanges(view, nodeDef, 6, v6);
31526 if (bindLen > 7)
31527 checkBindingNoChanges(view, nodeDef, 7, v7);
31528 if (bindLen > 8)
31529 checkBindingNoChanges(view, nodeDef, 8, v8);
31530 if (bindLen > 9)
31531 checkBindingNoChanges(view, nodeDef, 9, v9);
31532 }
31533 function checkNoChangesNodeDynamic(view, nodeDef, values) {
31534 for (var i = 0; i < values.length; i++) {
31535 checkBindingNoChanges(view, nodeDef, i, values[i]);
31536 }
31537 }
31538 /**
31539 * Workaround https://github.com/angular/tsickle/issues/497
31540 * @suppress {misplacedTypeAnnotation}
31541 */
31542 function checkNoChangesQuery(view, nodeDef) {
31543 var queryList = asQueryList(view, nodeDef.nodeIndex);
31544 if (queryList.dirty) {
31545 throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, nodeDef.nodeIndex), "Query " + nodeDef.query.id + " not dirty", "Query " + nodeDef.query.id + " dirty", (view.state & 1 /* BeforeFirstCheck */) !== 0);
31546 }
31547 }
31548 function destroyView(view) {
31549 if (view.state & 128 /* Destroyed */) {
31550 return;
31551 }
31552 execEmbeddedViewsAction(view, ViewAction.Destroy);
31553 execComponentViewsAction(view, ViewAction.Destroy);
31554 callLifecycleHooksChildrenFirst(view, 131072 /* OnDestroy */);
31555 if (view.disposables) {
31556 for (var i = 0; i < view.disposables.length; i++) {
31557 view.disposables[i]();
31558 }
31559 }
31560 detachProjectedView(view);
31561 if (view.renderer.destroyNode) {
31562 destroyViewNodes(view);
31563 }
31564 if (isComponentView(view)) {
31565 view.renderer.destroy();
31566 }
31567 view.state |= 128 /* Destroyed */;
31568 }
31569 function destroyViewNodes(view) {
31570 var len = view.def.nodes.length;
31571 for (var i = 0; i < len; i++) {
31572 var def = view.def.nodes[i];
31573 if (def.flags & 1 /* TypeElement */) {
31574 view.renderer.destroyNode(asElementData(view, i).renderElement);
31575 }
31576 else if (def.flags & 2 /* TypeText */) {
31577 view.renderer.destroyNode(asTextData(view, i).renderText);
31578 }
31579 else if (def.flags & 67108864 /* TypeContentQuery */ || def.flags & 134217728 /* TypeViewQuery */) {
31580 asQueryList(view, i).destroy();
31581 }
31582 }
31583 }
31584 var ViewAction;
31585 (function (ViewAction) {
31586 ViewAction[ViewAction["CreateViewNodes"] = 0] = "CreateViewNodes";
31587 ViewAction[ViewAction["CheckNoChanges"] = 1] = "CheckNoChanges";
31588 ViewAction[ViewAction["CheckNoChangesProjectedViews"] = 2] = "CheckNoChangesProjectedViews";
31589 ViewAction[ViewAction["CheckAndUpdate"] = 3] = "CheckAndUpdate";
31590 ViewAction[ViewAction["CheckAndUpdateProjectedViews"] = 4] = "CheckAndUpdateProjectedViews";
31591 ViewAction[ViewAction["Destroy"] = 5] = "Destroy";
31592 })(ViewAction || (ViewAction = {}));
31593 function execComponentViewsAction(view, action) {
31594 var def = view.def;
31595 if (!(def.nodeFlags & 33554432 /* ComponentView */)) {
31596 return;
31597 }
31598 for (var i = 0; i < def.nodes.length; i++) {
31599 var nodeDef = def.nodes[i];
31600 if (nodeDef.flags & 33554432 /* ComponentView */) {
31601 // a leaf
31602 callViewAction(asElementData(view, i).componentView, action);
31603 }
31604 else if ((nodeDef.childFlags & 33554432 /* ComponentView */) === 0) {
31605 // a parent with leafs
31606 // no child is a component,
31607 // then skip the children
31608 i += nodeDef.childCount;
31609 }
31610 }
31611 }
31612 function execEmbeddedViewsAction(view, action) {
31613 var def = view.def;
31614 if (!(def.nodeFlags & 16777216 /* EmbeddedViews */)) {
31615 return;
31616 }
31617 for (var i = 0; i < def.nodes.length; i++) {
31618 var nodeDef = def.nodes[i];
31619 if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
31620 // a leaf
31621 var embeddedViews = asElementData(view, i).viewContainer._embeddedViews;
31622 for (var k = 0; k < embeddedViews.length; k++) {
31623 callViewAction(embeddedViews[k], action);
31624 }
31625 }
31626 else if ((nodeDef.childFlags & 16777216 /* EmbeddedViews */) === 0) {
31627 // a parent with leafs
31628 // no child is a component,
31629 // then skip the children
31630 i += nodeDef.childCount;
31631 }
31632 }
31633 }
31634 function callViewAction(view, action) {
31635 var viewState = view.state;
31636 switch (action) {
31637 case ViewAction.CheckNoChanges:
31638 if ((viewState & 128 /* Destroyed */) === 0) {
31639 if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
31640 checkNoChangesView(view);
31641 }
31642 else if (viewState & 64 /* CheckProjectedViews */) {
31643 execProjectedViewsAction(view, ViewAction.CheckNoChangesProjectedViews);
31644 }
31645 }
31646 break;
31647 case ViewAction.CheckNoChangesProjectedViews:
31648 if ((viewState & 128 /* Destroyed */) === 0) {
31649 if (viewState & 32 /* CheckProjectedView */) {
31650 checkNoChangesView(view);
31651 }
31652 else if (viewState & 64 /* CheckProjectedViews */) {
31653 execProjectedViewsAction(view, action);
31654 }
31655 }
31656 break;
31657 case ViewAction.CheckAndUpdate:
31658 if ((viewState & 128 /* Destroyed */) === 0) {
31659 if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
31660 checkAndUpdateView(view);
31661 }
31662 else if (viewState & 64 /* CheckProjectedViews */) {
31663 execProjectedViewsAction(view, ViewAction.CheckAndUpdateProjectedViews);
31664 }
31665 }
31666 break;
31667 case ViewAction.CheckAndUpdateProjectedViews:
31668 if ((viewState & 128 /* Destroyed */) === 0) {
31669 if (viewState & 32 /* CheckProjectedView */) {
31670 checkAndUpdateView(view);
31671 }
31672 else if (viewState & 64 /* CheckProjectedViews */) {
31673 execProjectedViewsAction(view, action);
31674 }
31675 }
31676 break;
31677 case ViewAction.Destroy:
31678 // Note: destroyView recurses over all views,
31679 // so we don't need to special case projected views here.
31680 destroyView(view);
31681 break;
31682 case ViewAction.CreateViewNodes:
31683 createViewNodes(view);
31684 break;
31685 }
31686 }
31687 function execProjectedViewsAction(view, action) {
31688 execEmbeddedViewsAction(view, action);
31689 execComponentViewsAction(view, action);
31690 }
31691 function execQueriesAction(view, queryFlags, staticDynamicQueryFlag, checkType) {
31692 if (!(view.def.nodeFlags & queryFlags) || !(view.def.nodeFlags & staticDynamicQueryFlag)) {
31693 return;
31694 }
31695 var nodeCount = view.def.nodes.length;
31696 for (var i = 0; i < nodeCount; i++) {
31697 var nodeDef = view.def.nodes[i];
31698 if ((nodeDef.flags & queryFlags) && (nodeDef.flags & staticDynamicQueryFlag)) {
31699 Services.setCurrentNode(view, nodeDef.nodeIndex);
31700 switch (checkType) {
31701 case 0 /* CheckAndUpdate */:
31702 checkAndUpdateQuery(view, nodeDef);
31703 break;
31704 case 1 /* CheckNoChanges */:
31705 checkNoChangesQuery(view, nodeDef);
31706 break;
31707 }
31708 }
31709 if (!(nodeDef.childFlags & queryFlags) || !(nodeDef.childFlags & staticDynamicQueryFlag)) {
31710 // no child has a matching query
31711 // then skip the children
31712 i += nodeDef.childCount;
31713 }
31714 }
31715 }
31716
31717 var initialized = false;
31718 function initServicesIfNeeded() {
31719 if (initialized) {
31720 return;
31721 }
31722 initialized = true;
31723 var services = isDevMode() ? createDebugServices() : createProdServices();
31724 Services.setCurrentNode = services.setCurrentNode;
31725 Services.createRootView = services.createRootView;
31726 Services.createEmbeddedView = services.createEmbeddedView;
31727 Services.createComponentView = services.createComponentView;
31728 Services.createNgModuleRef = services.createNgModuleRef;
31729 Services.overrideProvider = services.overrideProvider;
31730 Services.overrideComponentView = services.overrideComponentView;
31731 Services.clearOverrides = services.clearOverrides;
31732 Services.checkAndUpdateView = services.checkAndUpdateView;
31733 Services.checkNoChangesView = services.checkNoChangesView;
31734 Services.destroyView = services.destroyView;
31735 Services.resolveDep = resolveDep;
31736 Services.createDebugContext = services.createDebugContext;
31737 Services.handleEvent = services.handleEvent;
31738 Services.updateDirectives = services.updateDirectives;
31739 Services.updateRenderer = services.updateRenderer;
31740 Services.dirtyParentQueries = dirtyParentQueries;
31741 }
31742 function createProdServices() {
31743 return {
31744 setCurrentNode: function () { },
31745 createRootView: createProdRootView,
31746 createEmbeddedView: createEmbeddedView,
31747 createComponentView: createComponentView,
31748 createNgModuleRef: createNgModuleRef,
31749 overrideProvider: NOOP,
31750 overrideComponentView: NOOP,
31751 clearOverrides: NOOP,
31752 checkAndUpdateView: checkAndUpdateView,
31753 checkNoChangesView: checkNoChangesView,
31754 destroyView: destroyView,
31755 createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
31756 handleEvent: function (view, nodeIndex, eventName, event) { return view.def.handleEvent(view, nodeIndex, eventName, event); },
31757 updateDirectives: function (view, checkType) { return view.def.updateDirectives(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode : prodCheckNoChangesNode, view); },
31758 updateRenderer: function (view, checkType) { return view.def.updateRenderer(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode : prodCheckNoChangesNode, view); },
31759 };
31760 }
31761 function createDebugServices() {
31762 return {
31763 setCurrentNode: debugSetCurrentNode,
31764 createRootView: debugCreateRootView,
31765 createEmbeddedView: debugCreateEmbeddedView,
31766 createComponentView: debugCreateComponentView,
31767 createNgModuleRef: debugCreateNgModuleRef,
31768 overrideProvider: debugOverrideProvider,
31769 overrideComponentView: debugOverrideComponentView,
31770 clearOverrides: debugClearOverrides,
31771 checkAndUpdateView: debugCheckAndUpdateView,
31772 checkNoChangesView: debugCheckNoChangesView,
31773 destroyView: debugDestroyView,
31774 createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
31775 handleEvent: debugHandleEvent,
31776 updateDirectives: debugUpdateDirectives,
31777 updateRenderer: debugUpdateRenderer,
31778 };
31779 }
31780 function createProdRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
31781 var rendererFactory = ngModule.injector.get(RendererFactory2);
31782 return createRootView(createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode), def, context);
31783 }
31784 function debugCreateRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
31785 var rendererFactory = ngModule.injector.get(RendererFactory2);
31786 var root = createRootData(elInjector, ngModule, new DebugRendererFactory2(rendererFactory), projectableNodes, rootSelectorOrNode);
31787 var defWithOverride = applyProviderOverridesToView(def);
31788 return callWithDebugContext(DebugAction.create, createRootView, null, [root, defWithOverride, context]);
31789 }
31790 function createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode) {
31791 var sanitizer = ngModule.injector.get(Sanitizer);
31792 var errorHandler = ngModule.injector.get(ErrorHandler);
31793 var renderer = rendererFactory.createRenderer(null, null);
31794 return {
31795 ngModule: ngModule,
31796 injector: elInjector,
31797 projectableNodes: projectableNodes,
31798 selectorOrNode: rootSelectorOrNode,
31799 sanitizer: sanitizer,
31800 rendererFactory: rendererFactory,
31801 renderer: renderer,
31802 errorHandler: errorHandler
31803 };
31804 }
31805 function debugCreateEmbeddedView(parentView, anchorDef, viewDef, context) {
31806 var defWithOverride = applyProviderOverridesToView(viewDef);
31807 return callWithDebugContext(DebugAction.create, createEmbeddedView, null, [parentView, anchorDef, defWithOverride, context]);
31808 }
31809 function debugCreateComponentView(parentView, nodeDef, viewDef, hostElement) {
31810 var overrideComponentView = viewDefOverrides.get(nodeDef.element.componentProvider.provider.token);
31811 if (overrideComponentView) {
31812 viewDef = overrideComponentView;
31813 }
31814 else {
31815 viewDef = applyProviderOverridesToView(viewDef);
31816 }
31817 return callWithDebugContext(DebugAction.create, createComponentView, null, [parentView, nodeDef, viewDef, hostElement]);
31818 }
31819 function debugCreateNgModuleRef(moduleType, parentInjector, bootstrapComponents, def) {
31820 var defWithOverride = applyProviderOverridesToNgModule(def);
31821 return createNgModuleRef(moduleType, parentInjector, bootstrapComponents, defWithOverride);
31822 }
31823 var providerOverrides = new Map();
31824 var providerOverridesWithScope = new Map();
31825 var viewDefOverrides = new Map();
31826 function debugOverrideProvider(override) {
31827 providerOverrides.set(override.token, override);
31828 var injectableDef;
31829 if (typeof override.token === 'function' && (injectableDef = getInjectableDef(override.token)) &&
31830 typeof injectableDef.providedIn === 'function') {
31831 providerOverridesWithScope.set(override.token, override);
31832 }
31833 }
31834 function debugOverrideComponentView(comp, compFactory) {
31835 var hostViewDef = resolveDefinition(getComponentViewDefinitionFactory(compFactory));
31836 var compViewDef = resolveDefinition(hostViewDef.nodes[0].element.componentView);
31837 viewDefOverrides.set(comp, compViewDef);
31838 }
31839 function debugClearOverrides() {
31840 providerOverrides.clear();
31841 providerOverridesWithScope.clear();
31842 viewDefOverrides.clear();
31843 }
31844 // Notes about the algorithm:
31845 // 1) Locate the providers of an element and check if one of them was overwritten
31846 // 2) Change the providers of that element
31847 //
31848 // We only create new datastructures if we need to, to keep perf impact
31849 // reasonable.
31850 function applyProviderOverridesToView(def) {
31851 if (providerOverrides.size === 0) {
31852 return def;
31853 }
31854 var elementIndicesWithOverwrittenProviders = findElementIndicesWithOverwrittenProviders(def);
31855 if (elementIndicesWithOverwrittenProviders.length === 0) {
31856 return def;
31857 }
31858 // clone the whole view definition,
31859 // as it maintains references between the nodes that are hard to update.
31860 def = def.factory(function () { return NOOP; });
31861 for (var i = 0; i < elementIndicesWithOverwrittenProviders.length; i++) {
31862 applyProviderOverridesToElement(def, elementIndicesWithOverwrittenProviders[i]);
31863 }
31864 return def;
31865 function findElementIndicesWithOverwrittenProviders(def) {
31866 var elIndicesWithOverwrittenProviders = [];
31867 var lastElementDef = null;
31868 for (var i = 0; i < def.nodes.length; i++) {
31869 var nodeDef = def.nodes[i];
31870 if (nodeDef.flags & 1 /* TypeElement */) {
31871 lastElementDef = nodeDef;
31872 }
31873 if (lastElementDef && nodeDef.flags & 3840 /* CatProviderNoDirective */ &&
31874 providerOverrides.has(nodeDef.provider.token)) {
31875 elIndicesWithOverwrittenProviders.push(lastElementDef.nodeIndex);
31876 lastElementDef = null;
31877 }
31878 }
31879 return elIndicesWithOverwrittenProviders;
31880 }
31881 function applyProviderOverridesToElement(viewDef, elIndex) {
31882 for (var i = elIndex + 1; i < viewDef.nodes.length; i++) {
31883 var nodeDef = viewDef.nodes[i];
31884 if (nodeDef.flags & 1 /* TypeElement */) {
31885 // stop at the next element
31886 return;
31887 }
31888 if (nodeDef.flags & 3840 /* CatProviderNoDirective */) {
31889 var provider = nodeDef.provider;
31890 var override = providerOverrides.get(provider.token);
31891 if (override) {
31892 nodeDef.flags = (nodeDef.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
31893 provider.deps = splitDepsDsl(override.deps);
31894 provider.value = override.value;
31895 }
31896 }
31897 }
31898 }
31899 }
31900 // Notes about the algorithm:
31901 // We only create new datastructures if we need to, to keep perf impact
31902 // reasonable.
31903 function applyProviderOverridesToNgModule(def) {
31904 var _a = calcHasOverrides(def), hasOverrides = _a.hasOverrides, hasDeprecatedOverrides = _a.hasDeprecatedOverrides;
31905 if (!hasOverrides) {
31906 return def;
31907 }
31908 // clone the whole view definition,
31909 // as it maintains references between the nodes that are hard to update.
31910 def = def.factory(function () { return NOOP; });
31911 applyProviderOverrides(def);
31912 return def;
31913 function calcHasOverrides(def) {
31914 var hasOverrides = false;
31915 var hasDeprecatedOverrides = false;
31916 if (providerOverrides.size === 0) {
31917 return { hasOverrides: hasOverrides, hasDeprecatedOverrides: hasDeprecatedOverrides };
31918 }
31919 def.providers.forEach(function (node) {
31920 var override = providerOverrides.get(node.token);
31921 if ((node.flags & 3840 /* CatProviderNoDirective */) && override) {
31922 hasOverrides = true;
31923 hasDeprecatedOverrides = hasDeprecatedOverrides || override.deprecatedBehavior;
31924 }
31925 });
31926 def.modules.forEach(function (module) {
31927 providerOverridesWithScope.forEach(function (override, token) {
31928 if (getInjectableDef(token).providedIn === module) {
31929 hasOverrides = true;
31930 hasDeprecatedOverrides = hasDeprecatedOverrides || override.deprecatedBehavior;
31931 }
31932 });
31933 });
31934 return { hasOverrides: hasOverrides, hasDeprecatedOverrides: hasDeprecatedOverrides };
31935 }
31936 function applyProviderOverrides(def) {
31937 for (var i = 0; i < def.providers.length; i++) {
31938 var provider = def.providers[i];
31939 if (hasDeprecatedOverrides) {
31940 // We had a bug where me made
31941 // all providers lazy. Keep this logic behind a flag
31942 // for migrating existing users.
31943 provider.flags |= 4096 /* LazyProvider */;
31944 }
31945 var override = providerOverrides.get(provider.token);
31946 if (override) {
31947 provider.flags = (provider.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
31948 provider.deps = splitDepsDsl(override.deps);
31949 provider.value = override.value;
31950 }
31951 }
31952 if (providerOverridesWithScope.size > 0) {
31953 var moduleSet_1 = new Set(def.modules);
31954 providerOverridesWithScope.forEach(function (override, token) {
31955 if (moduleSet_1.has(getInjectableDef(token).providedIn)) {
31956 var provider = {
31957 token: token,
31958 flags: override.flags | (hasDeprecatedOverrides ? 4096 /* LazyProvider */ : 0 /* None */),
31959 deps: splitDepsDsl(override.deps),
31960 value: override.value,
31961 index: def.providers.length,
31962 };
31963 def.providers.push(provider);
31964 def.providersByKey[tokenKey(token)] = provider;
31965 }
31966 });
31967 }
31968 }
31969 }
31970 function prodCheckAndUpdateNode(view, checkIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
31971 var nodeDef = view.def.nodes[checkIndex];
31972 checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
31973 return (nodeDef.flags & 224 /* CatPureExpression */) ?
31974 asPureExpressionData(view, checkIndex).value :
31975 undefined;
31976 }
31977 function prodCheckNoChangesNode(view, checkIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
31978 var nodeDef = view.def.nodes[checkIndex];
31979 checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
31980 return (nodeDef.flags & 224 /* CatPureExpression */) ?
31981 asPureExpressionData(view, checkIndex).value :
31982 undefined;
31983 }
31984 function debugCheckAndUpdateView(view) {
31985 return callWithDebugContext(DebugAction.detectChanges, checkAndUpdateView, null, [view]);
31986 }
31987 function debugCheckNoChangesView(view) {
31988 return callWithDebugContext(DebugAction.checkNoChanges, checkNoChangesView, null, [view]);
31989 }
31990 function debugDestroyView(view) {
31991 return callWithDebugContext(DebugAction.destroy, destroyView, null, [view]);
31992 }
31993 var DebugAction;
31994 (function (DebugAction) {
31995 DebugAction[DebugAction["create"] = 0] = "create";
31996 DebugAction[DebugAction["detectChanges"] = 1] = "detectChanges";
31997 DebugAction[DebugAction["checkNoChanges"] = 2] = "checkNoChanges";
31998 DebugAction[DebugAction["destroy"] = 3] = "destroy";
31999 DebugAction[DebugAction["handleEvent"] = 4] = "handleEvent";
32000 })(DebugAction || (DebugAction = {}));
32001 var _currentAction;
32002 var _currentView;
32003 var _currentNodeIndex;
32004 function debugSetCurrentNode(view, nodeIndex) {
32005 _currentView = view;
32006 _currentNodeIndex = nodeIndex;
32007 }
32008 function debugHandleEvent(view, nodeIndex, eventName, event) {
32009 debugSetCurrentNode(view, nodeIndex);
32010 return callWithDebugContext(DebugAction.handleEvent, view.def.handleEvent, null, [view, nodeIndex, eventName, event]);
32011 }
32012 function debugUpdateDirectives(view, checkType) {
32013 if (view.state & 128 /* Destroyed */) {
32014 throw viewDestroyedError(DebugAction[_currentAction]);
32015 }
32016 debugSetCurrentNode(view, nextDirectiveWithBinding(view, 0));
32017 return view.def.updateDirectives(debugCheckDirectivesFn, view);
32018 function debugCheckDirectivesFn(view, nodeIndex, argStyle) {
32019 var values = [];
32020 for (var _i = 3; _i < arguments.length; _i++) {
32021 values[_i - 3] = arguments[_i];
32022 }
32023 var nodeDef = view.def.nodes[nodeIndex];
32024 if (checkType === 0 /* CheckAndUpdate */) {
32025 debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
32026 }
32027 else {
32028 debugCheckNoChangesNode(view, nodeDef, argStyle, values);
32029 }
32030 if (nodeDef.flags & 16384 /* TypeDirective */) {
32031 debugSetCurrentNode(view, nextDirectiveWithBinding(view, nodeIndex));
32032 }
32033 return (nodeDef.flags & 224 /* CatPureExpression */) ?
32034 asPureExpressionData(view, nodeDef.nodeIndex).value :
32035 undefined;
32036 }
32037 }
32038 function debugUpdateRenderer(view, checkType) {
32039 if (view.state & 128 /* Destroyed */) {
32040 throw viewDestroyedError(DebugAction[_currentAction]);
32041 }
32042 debugSetCurrentNode(view, nextRenderNodeWithBinding(view, 0));
32043 return view.def.updateRenderer(debugCheckRenderNodeFn, view);
32044 function debugCheckRenderNodeFn(view, nodeIndex, argStyle) {
32045 var values = [];
32046 for (var _i = 3; _i < arguments.length; _i++) {
32047 values[_i - 3] = arguments[_i];
32048 }
32049 var nodeDef = view.def.nodes[nodeIndex];
32050 if (checkType === 0 /* CheckAndUpdate */) {
32051 debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
32052 }
32053 else {
32054 debugCheckNoChangesNode(view, nodeDef, argStyle, values);
32055 }
32056 if (nodeDef.flags & 3 /* CatRenderNode */) {
32057 debugSetCurrentNode(view, nextRenderNodeWithBinding(view, nodeIndex));
32058 }
32059 return (nodeDef.flags & 224 /* CatPureExpression */) ?
32060 asPureExpressionData(view, nodeDef.nodeIndex).value :
32061 undefined;
32062 }
32063 }
32064 function debugCheckAndUpdateNode(view, nodeDef, argStyle, givenValues) {
32065 var changed = checkAndUpdateNode.apply(void 0, __spread([view, nodeDef, argStyle], givenValues));
32066 if (changed) {
32067 var values = argStyle === 1 /* Dynamic */ ? givenValues[0] : givenValues;
32068 if (nodeDef.flags & 16384 /* TypeDirective */) {
32069 var bindingValues = {};
32070 for (var i = 0; i < nodeDef.bindings.length; i++) {
32071 var binding = nodeDef.bindings[i];
32072 var value = values[i];
32073 if (binding.flags & 8 /* TypeProperty */) {
32074 bindingValues[normalizeDebugBindingName(binding.nonMinifiedName)] =
32075 normalizeDebugBindingValue(value);
32076 }
32077 }
32078 var elDef = nodeDef.parent;
32079 var el = asElementData(view, elDef.nodeIndex).renderElement;
32080 if (!elDef.element.name) {
32081 // a comment.
32082 view.renderer.setValue(el, "bindings=" + JSON.stringify(bindingValues, null, 2));
32083 }
32084 else {
32085 // a regular element.
32086 for (var attr in bindingValues) {
32087 var value = bindingValues[attr];
32088 if (value != null) {
32089 view.renderer.setAttribute(el, attr, value);
32090 }
32091 else {
32092 view.renderer.removeAttribute(el, attr);
32093 }
32094 }
32095 }
32096 }
32097 }
32098 }
32099 function debugCheckNoChangesNode(view, nodeDef, argStyle, values) {
32100 checkNoChangesNode.apply(void 0, __spread([view, nodeDef, argStyle], values));
32101 }
32102 function nextDirectiveWithBinding(view, nodeIndex) {
32103 for (var i = nodeIndex; i < view.def.nodes.length; i++) {
32104 var nodeDef = view.def.nodes[i];
32105 if (nodeDef.flags & 16384 /* TypeDirective */ && nodeDef.bindings && nodeDef.bindings.length) {
32106 return i;
32107 }
32108 }
32109 return null;
32110 }
32111 function nextRenderNodeWithBinding(view, nodeIndex) {
32112 for (var i = nodeIndex; i < view.def.nodes.length; i++) {
32113 var nodeDef = view.def.nodes[i];
32114 if ((nodeDef.flags & 3 /* CatRenderNode */) && nodeDef.bindings && nodeDef.bindings.length) {
32115 return i;
32116 }
32117 }
32118 return null;
32119 }
32120 var DebugContext_ = /** @class */ (function () {
32121 function DebugContext_(view, nodeIndex) {
32122 this.view = view;
32123 this.nodeIndex = nodeIndex;
32124 if (nodeIndex == null) {
32125 this.nodeIndex = nodeIndex = 0;
32126 }
32127 this.nodeDef = view.def.nodes[nodeIndex];
32128 var elDef = this.nodeDef;
32129 var elView = view;
32130 while (elDef && (elDef.flags & 1 /* TypeElement */) === 0) {
32131 elDef = elDef.parent;
32132 }
32133 if (!elDef) {
32134 while (!elDef && elView) {
32135 elDef = viewParentEl(elView);
32136 elView = elView.parent;
32137 }
32138 }
32139 this.elDef = elDef;
32140 this.elView = elView;
32141 }
32142 Object.defineProperty(DebugContext_.prototype, "elOrCompView", {
32143 get: function () {
32144 // Has to be done lazily as we use the DebugContext also during creation of elements...
32145 return asElementData(this.elView, this.elDef.nodeIndex).componentView || this.view;
32146 },
32147 enumerable: false,
32148 configurable: true
32149 });
32150 Object.defineProperty(DebugContext_.prototype, "injector", {
32151 get: function () {
32152 return createInjector$1(this.elView, this.elDef);
32153 },
32154 enumerable: false,
32155 configurable: true
32156 });
32157 Object.defineProperty(DebugContext_.prototype, "component", {
32158 get: function () {
32159 return this.elOrCompView.component;
32160 },
32161 enumerable: false,
32162 configurable: true
32163 });
32164 Object.defineProperty(DebugContext_.prototype, "context", {
32165 get: function () {
32166 return this.elOrCompView.context;
32167 },
32168 enumerable: false,
32169 configurable: true
32170 });
32171 Object.defineProperty(DebugContext_.prototype, "providerTokens", {
32172 get: function () {
32173 var tokens = [];
32174 if (this.elDef) {
32175 for (var i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount; i++) {
32176 var childDef = this.elView.def.nodes[i];
32177 if (childDef.flags & 20224 /* CatProvider */) {
32178 tokens.push(childDef.provider.token);
32179 }
32180 i += childDef.childCount;
32181 }
32182 }
32183 return tokens;
32184 },
32185 enumerable: false,
32186 configurable: true
32187 });
32188 Object.defineProperty(DebugContext_.prototype, "references", {
32189 get: function () {
32190 var references = {};
32191 if (this.elDef) {
32192 collectReferences(this.elView, this.elDef, references);
32193 for (var i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount; i++) {
32194 var childDef = this.elView.def.nodes[i];
32195 if (childDef.flags & 20224 /* CatProvider */) {
32196 collectReferences(this.elView, childDef, references);
32197 }
32198 i += childDef.childCount;
32199 }
32200 }
32201 return references;
32202 },
32203 enumerable: false,
32204 configurable: true
32205 });
32206 Object.defineProperty(DebugContext_.prototype, "componentRenderElement", {
32207 get: function () {
32208 var elData = findHostElement(this.elOrCompView);
32209 return elData ? elData.renderElement : undefined;
32210 },
32211 enumerable: false,
32212 configurable: true
32213 });
32214 Object.defineProperty(DebugContext_.prototype, "renderNode", {
32215 get: function () {
32216 return this.nodeDef.flags & 2 /* TypeText */ ? renderNode(this.view, this.nodeDef) :
32217 renderNode(this.elView, this.elDef);
32218 },
32219 enumerable: false,
32220 configurable: true
32221 });
32222 DebugContext_.prototype.logError = function (console) {
32223 var values = [];
32224 for (var _i = 1; _i < arguments.length; _i++) {
32225 values[_i - 1] = arguments[_i];
32226 }
32227 var logViewDef;
32228 var logNodeIndex;
32229 if (this.nodeDef.flags & 2 /* TypeText */) {
32230 logViewDef = this.view.def;
32231 logNodeIndex = this.nodeDef.nodeIndex;
32232 }
32233 else {
32234 logViewDef = this.elView.def;
32235 logNodeIndex = this.elDef.nodeIndex;
32236 }
32237 // Note: we only generate a log function for text and element nodes
32238 // to make the generated code as small as possible.
32239 var renderNodeIndex = getRenderNodeIndex(logViewDef, logNodeIndex);
32240 var currRenderNodeIndex = -1;
32241 var nodeLogger = function () {
32242 var _a;
32243 currRenderNodeIndex++;
32244 if (currRenderNodeIndex === renderNodeIndex) {
32245 return (_a = console.error).bind.apply(_a, __spread([console], values));
32246 }
32247 else {
32248 return NOOP;
32249 }
32250 };
32251 logViewDef.factory(nodeLogger);
32252 if (currRenderNodeIndex < renderNodeIndex) {
32253 console.error('Illegal state: the ViewDefinitionFactory did not call the logger!');
32254 console.error.apply(console, __spread(values));
32255 }
32256 };
32257 return DebugContext_;
32258 }());
32259 function getRenderNodeIndex(viewDef, nodeIndex) {
32260 var renderNodeIndex = -1;
32261 for (var i = 0; i <= nodeIndex; i++) {
32262 var nodeDef = viewDef.nodes[i];
32263 if (nodeDef.flags & 3 /* CatRenderNode */) {
32264 renderNodeIndex++;
32265 }
32266 }
32267 return renderNodeIndex;
32268 }
32269 function findHostElement(view) {
32270 while (view && !isComponentView(view)) {
32271 view = view.parent;
32272 }
32273 if (view.parent) {
32274 return asElementData(view.parent, viewParentEl(view).nodeIndex);
32275 }
32276 return null;
32277 }
32278 function collectReferences(view, nodeDef, references) {
32279 for (var refName in nodeDef.references) {
32280 references[refName] = getQueryValue(view, nodeDef, nodeDef.references[refName]);
32281 }
32282 }
32283 function callWithDebugContext(action, fn, self, args) {
32284 var oldAction = _currentAction;
32285 var oldView = _currentView;
32286 var oldNodeIndex = _currentNodeIndex;
32287 try {
32288 _currentAction = action;
32289 var result = fn.apply(self, args);
32290 _currentView = oldView;
32291 _currentNodeIndex = oldNodeIndex;
32292 _currentAction = oldAction;
32293 return result;
32294 }
32295 catch (e) {
32296 if (isViewDebugError(e) || !_currentView) {
32297 throw e;
32298 }
32299 throw viewWrappedDebugError(e, getCurrentDebugContext());
32300 }
32301 }
32302 function getCurrentDebugContext() {
32303 return _currentView ? new DebugContext_(_currentView, _currentNodeIndex) : null;
32304 }
32305 var DebugRendererFactory2 = /** @class */ (function () {
32306 function DebugRendererFactory2(delegate) {
32307 this.delegate = delegate;
32308 }
32309 DebugRendererFactory2.prototype.createRenderer = function (element, renderData) {
32310 return new DebugRenderer2(this.delegate.createRenderer(element, renderData));
32311 };
32312 DebugRendererFactory2.prototype.begin = function () {
32313 if (this.delegate.begin) {
32314 this.delegate.begin();
32315 }
32316 };
32317 DebugRendererFactory2.prototype.end = function () {
32318 if (this.delegate.end) {
32319 this.delegate.end();
32320 }
32321 };
32322 DebugRendererFactory2.prototype.whenRenderingDone = function () {
32323 if (this.delegate.whenRenderingDone) {
32324 return this.delegate.whenRenderingDone();
32325 }
32326 return Promise.resolve(null);
32327 };
32328 return DebugRendererFactory2;
32329 }());
32330 var DebugRenderer2 = /** @class */ (function () {
32331 function DebugRenderer2(delegate) {
32332 this.delegate = delegate;
32333 /**
32334 * Factory function used to create a `DebugContext` when a node is created.
32335 *
32336 * The `DebugContext` allows to retrieve information about the nodes that are useful in tests.
32337 *
32338 * The factory is configurable so that the `DebugRenderer2` could instantiate either a View Engine
32339 * or a Render context.
32340 */
32341 this.debugContextFactory = getCurrentDebugContext;
32342 this.data = this.delegate.data;
32343 }
32344 DebugRenderer2.prototype.createDebugContext = function (nativeElement) {
32345 return this.debugContextFactory(nativeElement);
32346 };
32347 DebugRenderer2.prototype.destroyNode = function (node) {
32348 var debugNode = getDebugNode$1(node);
32349 removeDebugNodeFromIndex(debugNode);
32350 if (debugNode instanceof DebugNode__PRE_R3__) {
32351 debugNode.listeners.length = 0;
32352 }
32353 if (this.delegate.destroyNode) {
32354 this.delegate.destroyNode(node);
32355 }
32356 };
32357 DebugRenderer2.prototype.destroy = function () {
32358 this.delegate.destroy();
32359 };
32360 DebugRenderer2.prototype.createElement = function (name, namespace) {
32361 var el = this.delegate.createElement(name, namespace);
32362 var debugCtx = this.createDebugContext(el);
32363 if (debugCtx) {
32364 var debugEl = new DebugElement__PRE_R3__(el, null, debugCtx);
32365 debugEl.name = name;
32366 indexDebugNode(debugEl);
32367 }
32368 return el;
32369 };
32370 DebugRenderer2.prototype.createComment = function (value) {
32371 var comment = this.delegate.createComment(value);
32372 var debugCtx = this.createDebugContext(comment);
32373 if (debugCtx) {
32374 indexDebugNode(new DebugNode__PRE_R3__(comment, null, debugCtx));
32375 }
32376 return comment;
32377 };
32378 DebugRenderer2.prototype.createText = function (value) {
32379 var text = this.delegate.createText(value);
32380 var debugCtx = this.createDebugContext(text);
32381 if (debugCtx) {
32382 indexDebugNode(new DebugNode__PRE_R3__(text, null, debugCtx));
32383 }
32384 return text;
32385 };
32386 DebugRenderer2.prototype.appendChild = function (parent, newChild) {
32387 var debugEl = getDebugNode$1(parent);
32388 var debugChildEl = getDebugNode$1(newChild);
32389 if (debugEl && debugChildEl && debugEl instanceof DebugElement__PRE_R3__) {
32390 debugEl.addChild(debugChildEl);
32391 }
32392 this.delegate.appendChild(parent, newChild);
32393 };
32394 DebugRenderer2.prototype.insertBefore = function (parent, newChild, refChild) {
32395 var debugEl = getDebugNode$1(parent);
32396 var debugChildEl = getDebugNode$1(newChild);
32397 var debugRefEl = getDebugNode$1(refChild);
32398 if (debugEl && debugChildEl && debugEl instanceof DebugElement__PRE_R3__) {
32399 debugEl.insertBefore(debugRefEl, debugChildEl);
32400 }
32401 this.delegate.insertBefore(parent, newChild, refChild);
32402 };
32403 DebugRenderer2.prototype.removeChild = function (parent, oldChild) {
32404 var debugEl = getDebugNode$1(parent);
32405 var debugChildEl = getDebugNode$1(oldChild);
32406 if (debugEl && debugChildEl && debugEl instanceof DebugElement__PRE_R3__) {
32407 debugEl.removeChild(debugChildEl);
32408 }
32409 this.delegate.removeChild(parent, oldChild);
32410 };
32411 DebugRenderer2.prototype.selectRootElement = function (selectorOrNode, preserveContent) {
32412 var el = this.delegate.selectRootElement(selectorOrNode, preserveContent);
32413 var debugCtx = getCurrentDebugContext();
32414 if (debugCtx) {
32415 indexDebugNode(new DebugElement__PRE_R3__(el, null, debugCtx));
32416 }
32417 return el;
32418 };
32419 DebugRenderer2.prototype.setAttribute = function (el, name, value, namespace) {
32420 var debugEl = getDebugNode$1(el);
32421 if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
32422 var fullName = namespace ? namespace + ':' + name : name;
32423 debugEl.attributes[fullName] = value;
32424 }
32425 this.delegate.setAttribute(el, name, value, namespace);
32426 };
32427 DebugRenderer2.prototype.removeAttribute = function (el, name, namespace) {
32428 var debugEl = getDebugNode$1(el);
32429 if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
32430 var fullName = namespace ? namespace + ':' + name : name;
32431 debugEl.attributes[fullName] = null;
32432 }
32433 this.delegate.removeAttribute(el, name, namespace);
32434 };
32435 DebugRenderer2.prototype.addClass = function (el, name) {
32436 var debugEl = getDebugNode$1(el);
32437 if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
32438 debugEl.classes[name] = true;
32439 }
32440 this.delegate.addClass(el, name);
32441 };
32442 DebugRenderer2.prototype.removeClass = function (el, name) {
32443 var debugEl = getDebugNode$1(el);
32444 if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
32445 debugEl.classes[name] = false;
32446 }
32447 this.delegate.removeClass(el, name);
32448 };
32449 DebugRenderer2.prototype.setStyle = function (el, style, value, flags) {
32450 var debugEl = getDebugNode$1(el);
32451 if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
32452 debugEl.styles[style] = value;
32453 }
32454 this.delegate.setStyle(el, style, value, flags);
32455 };
32456 DebugRenderer2.prototype.removeStyle = function (el, style, flags) {
32457 var debugEl = getDebugNode$1(el);
32458 if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
32459 debugEl.styles[style] = null;
32460 }
32461 this.delegate.removeStyle(el, style, flags);
32462 };
32463 DebugRenderer2.prototype.setProperty = function (el, name, value) {
32464 var debugEl = getDebugNode$1(el);
32465 if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
32466 debugEl.properties[name] = value;
32467 }
32468 this.delegate.setProperty(el, name, value);
32469 };
32470 DebugRenderer2.prototype.listen = function (target, eventName, callback) {
32471 if (typeof target !== 'string') {
32472 var debugEl = getDebugNode$1(target);
32473 if (debugEl) {
32474 debugEl.listeners.push(new DebugEventListener(eventName, callback));
32475 }
32476 }
32477 return this.delegate.listen(target, eventName, callback);
32478 };
32479 DebugRenderer2.prototype.parentNode = function (node) {
32480 return this.delegate.parentNode(node);
32481 };
32482 DebugRenderer2.prototype.nextSibling = function (node) {
32483 return this.delegate.nextSibling(node);
32484 };
32485 DebugRenderer2.prototype.setValue = function (node, value) {
32486 return this.delegate.setValue(node, value);
32487 };
32488 return DebugRenderer2;
32489 }());
32490
32491 function overrideProvider(override) {
32492 initServicesIfNeeded();
32493 return Services.overrideProvider(override);
32494 }
32495 function overrideComponentView(comp, componentFactory) {
32496 initServicesIfNeeded();
32497 return Services.overrideComponentView(comp, componentFactory);
32498 }
32499 function clearOverrides() {
32500 initServicesIfNeeded();
32501 return Services.clearOverrides();
32502 }
32503 // Attention: this function is called as top level function.
32504 // Putting any logic in here will destroy closure tree shaking!
32505 function createNgModuleFactory(ngModuleType, bootstrapComponents, defFactory) {
32506 return new NgModuleFactory_(ngModuleType, bootstrapComponents, defFactory);
32507 }
32508 function cloneNgModuleDefinition(def) {
32509 var providers = Array.from(def.providers);
32510 var modules = Array.from(def.modules);
32511 var providersByKey = {};
32512 for (var key in def.providersByKey) {
32513 providersByKey[key] = def.providersByKey[key];
32514 }
32515 return {
32516 factory: def.factory,
32517 scope: def.scope,
32518 providers: providers,
32519 modules: modules,
32520 providersByKey: providersByKey,
32521 };
32522 }
32523 var NgModuleFactory_ = /** @class */ (function (_super) {
32524 __extends(NgModuleFactory_, _super);
32525 function NgModuleFactory_(moduleType, _bootstrapComponents, _ngModuleDefFactory) {
32526 var _this =
32527 // Attention: this ctor is called as top level function.
32528 // Putting any logic in here will destroy closure tree shaking!
32529 _super.call(this) || this;
32530 _this.moduleType = moduleType;
32531 _this._bootstrapComponents = _bootstrapComponents;
32532 _this._ngModuleDefFactory = _ngModuleDefFactory;
32533 return _this;
32534 }
32535 NgModuleFactory_.prototype.create = function (parentInjector) {
32536 initServicesIfNeeded();
32537 // Clone the NgModuleDefinition so that any tree shakeable provider definition
32538 // added to this instance of the NgModuleRef doesn't affect the cached copy.
32539 // See https://github.com/angular/angular/issues/25018.
32540 var def = cloneNgModuleDefinition(resolveDefinition(this._ngModuleDefFactory));
32541 return Services.createNgModuleRef(this.moduleType, parentInjector || Injector.NULL, this._bootstrapComponents, def);
32542 };
32543 return NgModuleFactory_;
32544 }(NgModuleFactory));
32545
32546 /**
32547 * @license
32548 * Copyright Google LLC All Rights Reserved.
32549 *
32550 * Use of this source code is governed by an MIT-style license that can be
32551 * found in the LICENSE file at https://angular.io/license
32552 */
32553
32554 /**
32555 * @license
32556 * Copyright Google LLC All Rights Reserved.
32557 *
32558 * Use of this source code is governed by an MIT-style license that can be
32559 * found in the LICENSE file at https://angular.io/license
32560 */
32561
32562 /**
32563 * @license
32564 * Copyright Google LLC All Rights Reserved.
32565 *
32566 * Use of this source code is governed by an MIT-style license that can be
32567 * found in the LICENSE file at https://angular.io/license
32568 */
32569 // clang-format on
32570
32571 /**
32572 * @license
32573 * Copyright Google LLC All Rights Reserved.
32574 *
32575 * Use of this source code is governed by an MIT-style license that can be
32576 * found in the LICENSE file at https://angular.io/license
32577 */
32578
32579 /**
32580 * @license
32581 * Copyright Google LLC All Rights Reserved.
32582 *
32583 * Use of this source code is governed by an MIT-style license that can be
32584 * found in the LICENSE file at https://angular.io/license
32585 */
32586 if (ngDevMode) {
32587 // This helper is to give a reasonable error message to people upgrading to v9 that have not yet
32588 // installed `@angular/localize` in their app.
32589 // tslint:disable-next-line: no-toplevel-property-access
32590 _global.$localize = _global.$localize || function () {
32591 throw new Error('It looks like your application or one of its dependencies is using i18n.\n' +
32592 'Angular 9 introduced a global `$localize()` function that needs to be loaded.\n' +
32593 'Please run `ng add @angular/localize` from the Angular CLI.\n' +
32594 '(For non-CLI projects, add `import \'@angular/localize/init\';` to your `polyfills.ts` file.\n' +
32595 'For server-side rendering applications add the import to your `main.server.ts` file.)');
32596 };
32597 }
32598
32599 /**
32600 * @license
32601 * Copyright Google LLC All Rights Reserved.
32602 *
32603 * Use of this source code is governed by an MIT-style license that can be
32604 * found in the LICENSE file at https://angular.io/license
32605 */
32606 // This file only reexports content of the `src` folder. Keep it that way.
32607
32608 /**
32609 * @license
32610 * Copyright Google LLC All Rights Reserved.
32611 *
32612 * Use of this source code is governed by an MIT-style license that can be
32613 * found in the LICENSE file at https://angular.io/license
32614 */
32615
32616 /**
32617 * Generated bundle index. Do not edit.
32618 */
32619
32620 exports.ANALYZE_FOR_ENTRY_COMPONENTS = ANALYZE_FOR_ENTRY_COMPONENTS;
32621 exports.APP_BOOTSTRAP_LISTENER = APP_BOOTSTRAP_LISTENER;
32622 exports.APP_ID = APP_ID;
32623 exports.APP_INITIALIZER = APP_INITIALIZER;
32624 exports.ApplicationInitStatus = ApplicationInitStatus;
32625 exports.ApplicationModule = ApplicationModule;
32626 exports.ApplicationRef = ApplicationRef;
32627 exports.Attribute = Attribute;
32628 exports.COMPILER_OPTIONS = COMPILER_OPTIONS;
32629 exports.CUSTOM_ELEMENTS_SCHEMA = CUSTOM_ELEMENTS_SCHEMA;
32630 exports.ChangeDetectorRef = ChangeDetectorRef;
32631 exports.Compiler = Compiler;
32632 exports.CompilerFactory = CompilerFactory;
32633 exports.Component = Component;
32634 exports.ComponentFactory = ComponentFactory;
32635 exports.ComponentFactoryResolver = ComponentFactoryResolver;
32636 exports.ComponentRef = ComponentRef;
32637 exports.ContentChild = ContentChild;
32638 exports.ContentChildren = ContentChildren;
32639 exports.DEFAULT_CURRENCY_CODE = DEFAULT_CURRENCY_CODE;
32640 exports.DebugElement = DebugElement;
32641 exports.DebugEventListener = DebugEventListener;
32642 exports.DebugNode = DebugNode;
32643 exports.DefaultIterableDiffer = DefaultIterableDiffer;
32644 exports.Directive = Directive;
32645 exports.ElementRef = ElementRef;
32646 exports.EmbeddedViewRef = EmbeddedViewRef;
32647 exports.ErrorHandler = ErrorHandler;
32648 exports.EventEmitter = EventEmitter;
32649 exports.Host = Host;
32650 exports.HostBinding = HostBinding;
32651 exports.HostListener = HostListener;
32652 exports.INJECTOR = INJECTOR;
32653 exports.Inject = Inject;
32654 exports.Injectable = Injectable;
32655 exports.InjectionToken = InjectionToken;
32656 exports.Injector = Injector;
32657 exports.Input = Input;
32658 exports.IterableDiffers = IterableDiffers;
32659 exports.KeyValueDiffers = KeyValueDiffers;
32660 exports.LOCALE_ID = LOCALE_ID$1;
32661 exports.ModuleWithComponentFactories = ModuleWithComponentFactories;
32662 exports.NO_ERRORS_SCHEMA = NO_ERRORS_SCHEMA;
32663 exports.NgModule = NgModule;
32664 exports.NgModuleFactory = NgModuleFactory;
32665 exports.NgModuleFactoryLoader = NgModuleFactoryLoader;
32666 exports.NgModuleRef = NgModuleRef;
32667 exports.NgProbeToken = NgProbeToken;
32668 exports.NgZone = NgZone;
32669 exports.Optional = Optional;
32670 exports.Output = Output;
32671 exports.PACKAGE_ROOT_URL = PACKAGE_ROOT_URL;
32672 exports.PLATFORM_ID = PLATFORM_ID;
32673 exports.PLATFORM_INITIALIZER = PLATFORM_INITIALIZER;
32674 exports.Pipe = Pipe;
32675 exports.PlatformRef = PlatformRef;
32676 exports.Query = Query;
32677 exports.QueryList = QueryList;
32678 exports.ReflectiveInjector = ReflectiveInjector;
32679 exports.ReflectiveKey = ReflectiveKey;
32680 exports.Renderer2 = Renderer2;
32681 exports.RendererFactory2 = RendererFactory2;
32682 exports.ResolvedReflectiveFactory = ResolvedReflectiveFactory;
32683 exports.Sanitizer = Sanitizer;
32684 exports.Self = Self;
32685 exports.SimpleChange = SimpleChange;
32686 exports.SkipSelf = SkipSelf;
32687 exports.SystemJsNgModuleLoader = SystemJsNgModuleLoader;
32688 exports.SystemJsNgModuleLoaderConfig = SystemJsNgModuleLoaderConfig;
32689 exports.TRANSLATIONS = TRANSLATIONS;
32690 exports.TRANSLATIONS_FORMAT = TRANSLATIONS_FORMAT;
32691 exports.TemplateRef = TemplateRef;
32692 exports.Testability = Testability;
32693 exports.TestabilityRegistry = TestabilityRegistry;
32694 exports.Type = Type;
32695 exports.VERSION = VERSION;
32696 exports.Version = Version;
32697 exports.ViewChild = ViewChild;
32698 exports.ViewChildren = ViewChildren;
32699 exports.ViewContainerRef = ViewContainerRef;
32700 exports.ViewRef = ViewRef$1;
32701 exports.WrappedValue = WrappedValue;
32702 exports.asNativeElements = asNativeElements;
32703 exports.assertPlatform = assertPlatform;
32704 exports.createPlatform = createPlatform;
32705 exports.createPlatformFactory = createPlatformFactory;
32706 exports.defineInjectable = defineInjectable;
32707 exports.destroyPlatform = destroyPlatform;
32708 exports.enableProdMode = enableProdMode;
32709 exports.forwardRef = forwardRef;
32710 exports.getDebugNode = getDebugNode$1;
32711 exports.getModuleFactory = getModuleFactory;
32712 exports.getPlatform = getPlatform;
32713 exports.inject = inject;
32714 exports.isDevMode = isDevMode;
32715 exports.platformCore = platformCore;
32716 exports.resolveForwardRef = resolveForwardRef;
32717 exports.setTestabilityGetter = setTestabilityGetter;
32718 exports.ɵ0 = ɵ0;
32719 exports.ɵ1 = ɵ1;
32720 exports.ɵALLOW_MULTIPLE_PLATFORMS = ALLOW_MULTIPLE_PLATFORMS;
32721 exports.ɵAPP_ID_RANDOM_PROVIDER = APP_ID_RANDOM_PROVIDER;
32722 exports.ɵCodegenComponentFactoryResolver = CodegenComponentFactoryResolver;
32723 exports.ɵCompiler_compileModuleAndAllComponentsAsync__POST_R3__ = Compiler_compileModuleAndAllComponentsAsync__POST_R3__;
32724 exports.ɵCompiler_compileModuleAndAllComponentsSync__POST_R3__ = Compiler_compileModuleAndAllComponentsSync__POST_R3__;
32725 exports.ɵCompiler_compileModuleAsync__POST_R3__ = Compiler_compileModuleAsync__POST_R3__;
32726 exports.ɵCompiler_compileModuleSync__POST_R3__ = Compiler_compileModuleSync__POST_R3__;
32727 exports.ɵComponentFactory = ComponentFactory;
32728 exports.ɵConsole = Console;
32729 exports.ɵDEFAULT_LOCALE_ID = DEFAULT_LOCALE_ID;
32730 exports.ɵEMPTY_ARRAY = EMPTY_ARRAY$4;
32731 exports.ɵEMPTY_MAP = EMPTY_MAP;
32732 exports.ɵINJECTOR_IMPL__POST_R3__ = INJECTOR_IMPL__POST_R3__;
32733 exports.ɵINJECTOR_SCOPE = INJECTOR_SCOPE;
32734 exports.ɵLifecycleHooksFeature = LifecycleHooksFeature;
32735 exports.ɵNG_COMP_DEF = NG_COMP_DEF;
32736 exports.ɵNG_DIR_DEF = NG_DIR_DEF;
32737 exports.ɵNG_ELEMENT_ID = NG_ELEMENT_ID;
32738 exports.ɵNG_INJ_DEF = NG_INJ_DEF;
32739 exports.ɵNG_MOD_DEF = NG_MOD_DEF;
32740 exports.ɵNG_PIPE_DEF = NG_PIPE_DEF;
32741 exports.ɵNG_PROV_DEF = NG_PROV_DEF;
32742 exports.ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR;
32743 exports.ɵNO_CHANGE = NO_CHANGE;
32744 exports.ɵNgModuleFactory = NgModuleFactory$1;
32745 exports.ɵNoopNgZone = NoopNgZone;
32746 exports.ɵReflectionCapabilities = ReflectionCapabilities;
32747 exports.ɵRender3ComponentFactory = ComponentFactory$1;
32748 exports.ɵRender3ComponentRef = ComponentRef$1;
32749 exports.ɵRender3NgModuleRef = NgModuleRef$1;
32750 exports.ɵSWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__ = SWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__;
32751 exports.ɵSWITCH_COMPILE_COMPONENT__POST_R3__ = SWITCH_COMPILE_COMPONENT__POST_R3__;
32752 exports.ɵSWITCH_COMPILE_DIRECTIVE__POST_R3__ = SWITCH_COMPILE_DIRECTIVE__POST_R3__;
32753 exports.ɵSWITCH_COMPILE_INJECTABLE__POST_R3__ = SWITCH_COMPILE_INJECTABLE__POST_R3__;
32754 exports.ɵSWITCH_COMPILE_NGMODULE__POST_R3__ = SWITCH_COMPILE_NGMODULE__POST_R3__;
32755 exports.ɵSWITCH_COMPILE_PIPE__POST_R3__ = SWITCH_COMPILE_PIPE__POST_R3__;
32756 exports.ɵSWITCH_ELEMENT_REF_FACTORY__POST_R3__ = SWITCH_ELEMENT_REF_FACTORY__POST_R3__;
32757 exports.ɵSWITCH_IVY_ENABLED__POST_R3__ = SWITCH_IVY_ENABLED__POST_R3__;
32758 exports.ɵSWITCH_RENDERER2_FACTORY__POST_R3__ = SWITCH_RENDERER2_FACTORY__POST_R3__;
32759 exports.ɵSWITCH_TEMPLATE_REF_FACTORY__POST_R3__ = SWITCH_TEMPLATE_REF_FACTORY__POST_R3__;
32760 exports.ɵSWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__ = SWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__;
32761 exports.ɵ_sanitizeHtml = _sanitizeHtml;
32762 exports.ɵ_sanitizeUrl = _sanitizeUrl;
32763 exports.ɵallowSanitizationBypassAndThrow = allowSanitizationBypassAndThrow;
32764 exports.ɵand = anchorDef;
32765 exports.ɵangular_packages_core_core_a = isForwardRef;
32766 exports.ɵangular_packages_core_core_b = injectInjectorOnly;
32767 exports.ɵangular_packages_core_core_ba = instructionState;
32768 exports.ɵangular_packages_core_core_bb = getLView;
32769 exports.ɵangular_packages_core_core_bc = getPreviousOrParentTNode;
32770 exports.ɵangular_packages_core_core_bd = getBindingRoot;
32771 exports.ɵangular_packages_core_core_be = nextContextImpl;
32772 exports.ɵangular_packages_core_core_bg = pureFunction1Internal;
32773 exports.ɵangular_packages_core_core_bh = pureFunction2Internal;
32774 exports.ɵangular_packages_core_core_bi = pureFunction3Internal;
32775 exports.ɵangular_packages_core_core_bj = pureFunction4Internal;
32776 exports.ɵangular_packages_core_core_bk = pureFunctionVInternal;
32777 exports.ɵangular_packages_core_core_bl = getUrlSanitizer;
32778 exports.ɵangular_packages_core_core_bm = makeParamDecorator;
32779 exports.ɵangular_packages_core_core_bn = makePropDecorator;
32780 exports.ɵangular_packages_core_core_bo = getClosureSafeProperty;
32781 exports.ɵangular_packages_core_core_bq = getRootContext;
32782 exports.ɵangular_packages_core_core_br = i18nPostprocess;
32783 exports.ɵangular_packages_core_core_c = NullInjector;
32784 exports.ɵangular_packages_core_core_d = ReflectiveInjector_;
32785 exports.ɵangular_packages_core_core_e = ReflectiveDependency;
32786 exports.ɵangular_packages_core_core_f = resolveReflectiveProviders;
32787 exports.ɵangular_packages_core_core_g = _appIdRandomProviderFactory;
32788 exports.ɵangular_packages_core_core_h = createElementRef;
32789 exports.ɵangular_packages_core_core_i = createTemplateRef;
32790 exports.ɵangular_packages_core_core_j = getModuleFactory__PRE_R3__;
32791 exports.ɵangular_packages_core_core_k = DebugNode__PRE_R3__;
32792 exports.ɵangular_packages_core_core_l = DebugElement__PRE_R3__;
32793 exports.ɵangular_packages_core_core_m = getDebugNodeR2__PRE_R3__;
32794 exports.ɵangular_packages_core_core_n = DefaultIterableDifferFactory;
32795 exports.ɵangular_packages_core_core_o = DefaultKeyValueDifferFactory;
32796 exports.ɵangular_packages_core_core_p = _iterableDiffersFactory;
32797 exports.ɵangular_packages_core_core_q = _keyValueDiffersFactory;
32798 exports.ɵangular_packages_core_core_r = _localeFactory;
32799 exports.ɵangular_packages_core_core_s = APPLICATION_MODULE_PROVIDERS;
32800 exports.ɵangular_packages_core_core_t = zoneSchedulerFactory;
32801 exports.ɵangular_packages_core_core_u = USD_CURRENCY_CODE;
32802 exports.ɵangular_packages_core_core_v = _def;
32803 exports.ɵangular_packages_core_core_w = DebugContext;
32804 exports.ɵangular_packages_core_core_x = NgOnChangesFeatureImpl;
32805 exports.ɵangular_packages_core_core_y = SCHEDULER;
32806 exports.ɵangular_packages_core_core_z = injectAttributeImpl;
32807 exports.ɵbypassSanitizationTrustHtml = bypassSanitizationTrustHtml;
32808 exports.ɵbypassSanitizationTrustResourceUrl = bypassSanitizationTrustResourceUrl;
32809 exports.ɵbypassSanitizationTrustScript = bypassSanitizationTrustScript;
32810 exports.ɵbypassSanitizationTrustStyle = bypassSanitizationTrustStyle;
32811 exports.ɵbypassSanitizationTrustUrl = bypassSanitizationTrustUrl;
32812 exports.ɵccf = createComponentFactory;
32813 exports.ɵclearOverrides = clearOverrides;
32814 exports.ɵclearResolutionOfComponentResourcesQueue = clearResolutionOfComponentResourcesQueue;
32815 exports.ɵcmf = createNgModuleFactory;
32816 exports.ɵcompileComponent = compileComponent;
32817 exports.ɵcompileDirective = compileDirective;
32818 exports.ɵcompileNgModule = compileNgModule;
32819 exports.ɵcompileNgModuleDefs = compileNgModuleDefs;
32820 exports.ɵcompileNgModuleFactory__POST_R3__ = compileNgModuleFactory__POST_R3__;
32821 exports.ɵcompilePipe = compilePipe;
32822 exports.ɵcreateInjector = createInjector;
32823 exports.ɵcrt = createRendererType2;
32824 exports.ɵdefaultIterableDiffers = defaultIterableDiffers;
32825 exports.ɵdefaultKeyValueDiffers = defaultKeyValueDiffers;
32826 exports.ɵdetectChanges = detectChanges;
32827 exports.ɵdevModeEqual = devModeEqual;
32828 exports.ɵdid = directiveDef;
32829 exports.ɵeld = elementDef;
32830 exports.ɵfindLocaleData = findLocaleData;
32831 exports.ɵflushModuleScopingQueueAsMuchAsPossible = flushModuleScopingQueueAsMuchAsPossible;
32832 exports.ɵgetComponentViewDefinitionFactory = getComponentViewDefinitionFactory;
32833 exports.ɵgetDebugNodeR2 = getDebugNodeR2;
32834 exports.ɵgetDebugNode__POST_R3__ = getDebugNode__POST_R3__;
32835 exports.ɵgetDirectives = getDirectives;
32836 exports.ɵgetHostElement = getHostElement;
32837 exports.ɵgetInjectableDef = getInjectableDef;
32838 exports.ɵgetLContext = getLContext;
32839 exports.ɵgetLocaleCurrencyCode = getLocaleCurrencyCode;
32840 exports.ɵgetLocalePluralCase = getLocalePluralCase;
32841 exports.ɵgetModuleFactory__POST_R3__ = getModuleFactory__POST_R3__;
32842 exports.ɵgetSanitizationBypassType = getSanitizationBypassType;
32843 exports.ɵglobal = _global;
32844 exports.ɵinitServicesIfNeeded = initServicesIfNeeded;
32845 exports.ɵinlineInterpolate = inlineInterpolate;
32846 exports.ɵinterpolate = interpolate;
32847 exports.ɵisBoundToModule__POST_R3__ = isBoundToModule__POST_R3__;
32848 exports.ɵisDefaultChangeDetectionStrategy = isDefaultChangeDetectionStrategy;
32849 exports.ɵisListLikeIterable = isListLikeIterable;
32850 exports.ɵisObservable = isObservable;
32851 exports.ɵisPromise = isPromise;
32852 exports.ɵivyEnabled = ivyEnabled;
32853 exports.ɵmakeDecorator = makeDecorator;
32854 exports.ɵmarkDirty = markDirty;
32855 exports.ɵmod = moduleDef;
32856 exports.ɵmpd = moduleProvideDef;
32857 exports.ɵncd = ngContentDef;
32858 exports.ɵnoSideEffects = noSideEffects;
32859 exports.ɵnov = nodeValue;
32860 exports.ɵoverrideComponentView = overrideComponentView;
32861 exports.ɵoverrideProvider = overrideProvider;
32862 exports.ɵpad = pureArrayDef;
32863 exports.ɵpatchComponentDefWithScope = patchComponentDefWithScope;
32864 exports.ɵpid = pipeDef;
32865 exports.ɵpod = pureObjectDef;
32866 exports.ɵppd = purePipeDef;
32867 exports.ɵprd = providerDef;
32868 exports.ɵpublishDefaultGlobalUtils = publishDefaultGlobalUtils;
32869 exports.ɵpublishGlobalUtil = publishGlobalUtil;
32870 exports.ɵqud = queryDef;
32871 exports.ɵregisterLocaleData = registerLocaleData;
32872 exports.ɵregisterModuleFactory = registerModuleFactory;
32873 exports.ɵregisterNgModuleType = registerNgModuleType;
32874 exports.ɵrenderComponent = renderComponent$1;
32875 exports.ɵresetCompiledComponents = resetCompiledComponents;
32876 exports.ɵresetJitOptions = resetJitOptions;
32877 exports.ɵresolveComponentResources = resolveComponentResources;
32878 exports.ɵsetClassMetadata = setClassMetadata;
32879 exports.ɵsetCurrentInjector = setCurrentInjector;
32880 exports.ɵsetDocument = setDocument;
32881 exports.ɵsetLocaleId = setLocaleId;
32882 exports.ɵstore = store;
32883 exports.ɵstringify = stringify;
32884 exports.ɵted = textDef;
32885 exports.ɵtransitiveScopesFor = transitiveScopesFor;
32886 exports.ɵunregisterLocaleData = unregisterAllLocaleData;
32887 exports.ɵunv = unwrapValue;
32888 exports.ɵunwrapSafeValue = unwrapSafeValue;
32889 exports.ɵvid = viewDef;
32890 exports.ɵwhenRendered = whenRendered;
32891 exports.ɵɵCopyDefinitionFeature = ɵɵCopyDefinitionFeature;
32892 exports.ɵɵInheritDefinitionFeature = ɵɵInheritDefinitionFeature;
32893 exports.ɵɵNgOnChangesFeature = ɵɵNgOnChangesFeature;
32894 exports.ɵɵProvidersFeature = ɵɵProvidersFeature;
32895 exports.ɵɵadvance = ɵɵadvance;
32896 exports.ɵɵattribute = ɵɵattribute;
32897 exports.ɵɵattributeInterpolate1 = ɵɵattributeInterpolate1;
32898 exports.ɵɵattributeInterpolate2 = ɵɵattributeInterpolate2;
32899 exports.ɵɵattributeInterpolate3 = ɵɵattributeInterpolate3;
32900 exports.ɵɵattributeInterpolate4 = ɵɵattributeInterpolate4;
32901 exports.ɵɵattributeInterpolate5 = ɵɵattributeInterpolate5;
32902 exports.ɵɵattributeInterpolate6 = ɵɵattributeInterpolate6;
32903 exports.ɵɵattributeInterpolate7 = ɵɵattributeInterpolate7;
32904 exports.ɵɵattributeInterpolate8 = ɵɵattributeInterpolate8;
32905 exports.ɵɵattributeInterpolateV = ɵɵattributeInterpolateV;
32906 exports.ɵɵclassMap = ɵɵclassMap;
32907 exports.ɵɵclassMapInterpolate1 = ɵɵclassMapInterpolate1;
32908 exports.ɵɵclassMapInterpolate2 = ɵɵclassMapInterpolate2;
32909 exports.ɵɵclassMapInterpolate3 = ɵɵclassMapInterpolate3;
32910 exports.ɵɵclassMapInterpolate4 = ɵɵclassMapInterpolate4;
32911 exports.ɵɵclassMapInterpolate5 = ɵɵclassMapInterpolate5;
32912 exports.ɵɵclassMapInterpolate6 = ɵɵclassMapInterpolate6;
32913 exports.ɵɵclassMapInterpolate7 = ɵɵclassMapInterpolate7;
32914 exports.ɵɵclassMapInterpolate8 = ɵɵclassMapInterpolate8;
32915 exports.ɵɵclassMapInterpolateV = ɵɵclassMapInterpolateV;
32916 exports.ɵɵclassProp = ɵɵclassProp;
32917 exports.ɵɵcontentQuery = ɵɵcontentQuery;
32918 exports.ɵɵdefineComponent = ɵɵdefineComponent;
32919 exports.ɵɵdefineDirective = ɵɵdefineDirective;
32920 exports.ɵɵdefineInjectable = ɵɵdefineInjectable;
32921 exports.ɵɵdefineInjector = ɵɵdefineInjector;
32922 exports.ɵɵdefineNgModule = ɵɵdefineNgModule;
32923 exports.ɵɵdefinePipe = ɵɵdefinePipe;
32924 exports.ɵɵdirectiveInject = ɵɵdirectiveInject;
32925 exports.ɵɵdisableBindings = ɵɵdisableBindings;
32926 exports.ɵɵelement = ɵɵelement;
32927 exports.ɵɵelementContainer = ɵɵelementContainer;
32928 exports.ɵɵelementContainerEnd = ɵɵelementContainerEnd;
32929 exports.ɵɵelementContainerStart = ɵɵelementContainerStart;
32930 exports.ɵɵelementEnd = ɵɵelementEnd;
32931 exports.ɵɵelementStart = ɵɵelementStart;
32932 exports.ɵɵenableBindings = ɵɵenableBindings;
32933 exports.ɵɵgetCurrentView = ɵɵgetCurrentView;
32934 exports.ɵɵgetFactoryOf = ɵɵgetFactoryOf;
32935 exports.ɵɵgetInheritedFactory = ɵɵgetInheritedFactory;
32936 exports.ɵɵhostProperty = ɵɵhostProperty;
32937 exports.ɵɵi18n = ɵɵi18n;
32938 exports.ɵɵi18nApply = ɵɵi18nApply;
32939 exports.ɵɵi18nAttributes = ɵɵi18nAttributes;
32940 exports.ɵɵi18nEnd = ɵɵi18nEnd;
32941 exports.ɵɵi18nExp = ɵɵi18nExp;
32942 exports.ɵɵi18nPostprocess = ɵɵi18nPostprocess;
32943 exports.ɵɵi18nStart = ɵɵi18nStart;
32944 exports.ɵɵinject = ɵɵinject;
32945 exports.ɵɵinjectAttribute = ɵɵinjectAttribute;
32946 exports.ɵɵinjectPipeChangeDetectorRef = ɵɵinjectPipeChangeDetectorRef;
32947 exports.ɵɵinvalidFactory = ɵɵinvalidFactory;
32948 exports.ɵɵinvalidFactoryDep = ɵɵinvalidFactoryDep;
32949 exports.ɵɵlistener = ɵɵlistener;
32950 exports.ɵɵloadQuery = ɵɵloadQuery;
32951 exports.ɵɵnamespaceHTML = ɵɵnamespaceHTML;
32952 exports.ɵɵnamespaceMathML = ɵɵnamespaceMathML;
32953 exports.ɵɵnamespaceSVG = ɵɵnamespaceSVG;
32954 exports.ɵɵnextContext = ɵɵnextContext;
32955 exports.ɵɵpipe = ɵɵpipe;
32956 exports.ɵɵpipeBind1 = ɵɵpipeBind1;
32957 exports.ɵɵpipeBind2 = ɵɵpipeBind2;
32958 exports.ɵɵpipeBind3 = ɵɵpipeBind3;
32959 exports.ɵɵpipeBind4 = ɵɵpipeBind4;
32960 exports.ɵɵpipeBindV = ɵɵpipeBindV;
32961 exports.ɵɵprojection = ɵɵprojection;
32962 exports.ɵɵprojectionDef = ɵɵprojectionDef;
32963 exports.ɵɵproperty = ɵɵproperty;
32964 exports.ɵɵpropertyInterpolate = ɵɵpropertyInterpolate;
32965 exports.ɵɵpropertyInterpolate1 = ɵɵpropertyInterpolate1;
32966 exports.ɵɵpropertyInterpolate2 = ɵɵpropertyInterpolate2;
32967 exports.ɵɵpropertyInterpolate3 = ɵɵpropertyInterpolate3;
32968 exports.ɵɵpropertyInterpolate4 = ɵɵpropertyInterpolate4;
32969 exports.ɵɵpropertyInterpolate5 = ɵɵpropertyInterpolate5;
32970 exports.ɵɵpropertyInterpolate6 = ɵɵpropertyInterpolate6;
32971 exports.ɵɵpropertyInterpolate7 = ɵɵpropertyInterpolate7;
32972 exports.ɵɵpropertyInterpolate8 = ɵɵpropertyInterpolate8;
32973 exports.ɵɵpropertyInterpolateV = ɵɵpropertyInterpolateV;
32974 exports.ɵɵpureFunction0 = ɵɵpureFunction0;
32975 exports.ɵɵpureFunction1 = ɵɵpureFunction1;
32976 exports.ɵɵpureFunction2 = ɵɵpureFunction2;
32977 exports.ɵɵpureFunction3 = ɵɵpureFunction3;
32978 exports.ɵɵpureFunction4 = ɵɵpureFunction4;
32979 exports.ɵɵpureFunction5 = ɵɵpureFunction5;
32980 exports.ɵɵpureFunction6 = ɵɵpureFunction6;
32981 exports.ɵɵpureFunction7 = ɵɵpureFunction7;
32982 exports.ɵɵpureFunction8 = ɵɵpureFunction8;
32983 exports.ɵɵpureFunctionV = ɵɵpureFunctionV;
32984 exports.ɵɵqueryRefresh = ɵɵqueryRefresh;
32985 exports.ɵɵreference = ɵɵreference;
32986 exports.ɵɵresolveBody = ɵɵresolveBody;
32987 exports.ɵɵresolveDocument = ɵɵresolveDocument;
32988 exports.ɵɵresolveWindow = ɵɵresolveWindow;
32989 exports.ɵɵrestoreView = ɵɵrestoreView;
32990 exports.ɵɵsanitizeHtml = ɵɵsanitizeHtml;
32991 exports.ɵɵsanitizeResourceUrl = ɵɵsanitizeResourceUrl;
32992 exports.ɵɵsanitizeScript = ɵɵsanitizeScript;
32993 exports.ɵɵsanitizeStyle = ɵɵsanitizeStyle;
32994 exports.ɵɵsanitizeUrl = ɵɵsanitizeUrl;
32995 exports.ɵɵsanitizeUrlOrResourceUrl = ɵɵsanitizeUrlOrResourceUrl;
32996 exports.ɵɵselect = ɵɵselect;
32997 exports.ɵɵsetComponentScope = ɵɵsetComponentScope;
32998 exports.ɵɵsetNgModuleScope = ɵɵsetNgModuleScope;
32999 exports.ɵɵstaticContentQuery = ɵɵstaticContentQuery;
33000 exports.ɵɵstaticViewQuery = ɵɵstaticViewQuery;
33001 exports.ɵɵstyleMap = ɵɵstyleMap;
33002 exports.ɵɵstyleMapInterpolate1 = ɵɵstyleMapInterpolate1;
33003 exports.ɵɵstyleMapInterpolate2 = ɵɵstyleMapInterpolate2;
33004 exports.ɵɵstyleMapInterpolate3 = ɵɵstyleMapInterpolate3;
33005 exports.ɵɵstyleMapInterpolate4 = ɵɵstyleMapInterpolate4;
33006 exports.ɵɵstyleMapInterpolate5 = ɵɵstyleMapInterpolate5;
33007 exports.ɵɵstyleMapInterpolate6 = ɵɵstyleMapInterpolate6;
33008 exports.ɵɵstyleMapInterpolate7 = ɵɵstyleMapInterpolate7;
33009 exports.ɵɵstyleMapInterpolate8 = ɵɵstyleMapInterpolate8;
33010 exports.ɵɵstyleMapInterpolateV = ɵɵstyleMapInterpolateV;
33011 exports.ɵɵstyleProp = ɵɵstyleProp;
33012 exports.ɵɵstylePropInterpolate1 = ɵɵstylePropInterpolate1;
33013 exports.ɵɵstylePropInterpolate2 = ɵɵstylePropInterpolate2;
33014 exports.ɵɵstylePropInterpolate3 = ɵɵstylePropInterpolate3;
33015 exports.ɵɵstylePropInterpolate4 = ɵɵstylePropInterpolate4;
33016 exports.ɵɵstylePropInterpolate5 = ɵɵstylePropInterpolate5;
33017 exports.ɵɵstylePropInterpolate6 = ɵɵstylePropInterpolate6;
33018 exports.ɵɵstylePropInterpolate7 = ɵɵstylePropInterpolate7;
33019 exports.ɵɵstylePropInterpolate8 = ɵɵstylePropInterpolate8;
33020 exports.ɵɵstylePropInterpolateV = ɵɵstylePropInterpolateV;
33021 exports.ɵɵsyntheticHostListener = ɵɵsyntheticHostListener;
33022 exports.ɵɵsyntheticHostProperty = ɵɵsyntheticHostProperty;
33023 exports.ɵɵtemplate = ɵɵtemplate;
33024 exports.ɵɵtemplateRefExtractor = ɵɵtemplateRefExtractor;
33025 exports.ɵɵtext = ɵɵtext;
33026 exports.ɵɵtextInterpolate = ɵɵtextInterpolate;
33027 exports.ɵɵtextInterpolate1 = ɵɵtextInterpolate1;
33028 exports.ɵɵtextInterpolate2 = ɵɵtextInterpolate2;
33029 exports.ɵɵtextInterpolate3 = ɵɵtextInterpolate3;
33030 exports.ɵɵtextInterpolate4 = ɵɵtextInterpolate4;
33031 exports.ɵɵtextInterpolate5 = ɵɵtextInterpolate5;
33032 exports.ɵɵtextInterpolate6 = ɵɵtextInterpolate6;
33033 exports.ɵɵtextInterpolate7 = ɵɵtextInterpolate7;
33034 exports.ɵɵtextInterpolate8 = ɵɵtextInterpolate8;
33035 exports.ɵɵtextInterpolateV = ɵɵtextInterpolateV;
33036 exports.ɵɵviewQuery = ɵɵviewQuery;
33037
33038 Object.defineProperty(exports, '__esModule', { value: true });
33039
33040})));
33041//# sourceMappingURL=core.umd.js.map