UNPKG

256 kBJavaScriptView Raw
1/**
2 * @license Angular v8.0.2
3 * (c) 2010-2019 Google LLC. https://angular.io/
4 * License: MIT
5 */
6
7import { LocationStrategy, Location, PlatformLocation, APP_BASE_HREF, ViewportScroller, HashLocationStrategy, PathLocationStrategy, LOCATION_INITIALIZED } from '@angular/common';
8import { Component, ɵisObservable, ɵisPromise, NgModuleRef, InjectionToken, NgModuleFactory, ɵConsole, NgZone, isDevMode, Directive, Attribute, Renderer2, ElementRef, Input, HostListener, HostBinding, Optional, ContentChildren, EventEmitter, ViewContainerRef, ComponentFactoryResolver, ChangeDetectorRef, Output, Injectable, NgModuleFactoryLoader, Compiler, Injector, ApplicationRef, SystemJsNgModuleLoader, NgProbeToken, ANALYZE_FOR_ENTRY_COMPONENTS, SkipSelf, Inject, APP_INITIALIZER, APP_BOOTSTRAP_LISTENER, NgModule, Version } from '@angular/core';
9import { of, from, BehaviorSubject, EmptyError, Observable, combineLatest, defer, Subject, EMPTY } from 'rxjs';
10import { map, concatAll, last as last$1, catchError, first, mergeMap, every, switchMap, take, startWith, scan, filter, concatMap, reduce, tap, finalize, mergeAll } from 'rxjs/operators';
11import { ɵgetDOM } from '@angular/platform-browser';
12
13/**
14 * @fileoverview added by tsickle
15 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
16 */
17/**
18 * @license
19 * Copyright Google Inc. All Rights Reserved.
20 *
21 * Use of this source code is governed by an MIT-style license that can be
22 * found in the LICENSE file at https://angular.io/license
23 */
24/**
25 * \@description
26 *
27 * Base for events the Router goes through, as opposed to events tied to a specific
28 * Route. `RouterEvent`s will only be fired one time for any given navigation.
29 *
30 * Example:
31 *
32 * ```
33 * class MyService {
34 * constructor(public router: Router, logger: Logger) {
35 * router.events.pipe(
36 * filter(e => e instanceof RouterEvent)
37 * ).subscribe(e => {
38 * logger.log(e.id, e.url);
39 * });
40 * }
41 * }
42 * ```
43 *
44 * \@publicApi
45 */
46class RouterEvent {
47 /**
48 * @param {?} id
49 * @param {?} url
50 */
51 constructor(id, url) {
52 this.id = id;
53 this.url = url;
54 }
55}
56/**
57 * \@description
58 *
59 * Represents an event triggered when a navigation starts.
60 *
61 * \@publicApi
62 */
63class NavigationStart extends RouterEvent {
64 /**
65 * @param {?} id
66 * @param {?} url
67 * @param {?=} navigationTrigger
68 * @param {?=} restoredState
69 */
70 constructor(
71 /** @docsNotRequired */
72 id,
73 /** @docsNotRequired */
74 url,
75 /** @docsNotRequired */
76 navigationTrigger = 'imperative',
77 /** @docsNotRequired */
78 restoredState = null) {
79 super(id, url);
80 this.navigationTrigger = navigationTrigger;
81 this.restoredState = restoredState;
82 }
83 /**
84 * \@docsNotRequired
85 * @return {?}
86 */
87 toString() { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; }
88}
89/**
90 * \@description
91 *
92 * Represents an event triggered when a navigation ends successfully.
93 *
94 * \@publicApi
95 */
96class NavigationEnd extends RouterEvent {
97 /**
98 * @param {?} id
99 * @param {?} url
100 * @param {?} urlAfterRedirects
101 */
102 constructor(
103 /** @docsNotRequired */
104 id,
105 /** @docsNotRequired */
106 url, urlAfterRedirects) {
107 super(id, url);
108 this.urlAfterRedirects = urlAfterRedirects;
109 }
110 /**
111 * \@docsNotRequired
112 * @return {?}
113 */
114 toString() {
115 return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
116 }
117}
118/**
119 * \@description
120 *
121 * Represents an event triggered when a navigation is canceled.
122 *
123 * \@publicApi
124 */
125class NavigationCancel extends RouterEvent {
126 /**
127 * @param {?} id
128 * @param {?} url
129 * @param {?} reason
130 */
131 constructor(
132 /** @docsNotRequired */
133 id,
134 /** @docsNotRequired */
135 url, reason) {
136 super(id, url);
137 this.reason = reason;
138 }
139 /**
140 * \@docsNotRequired
141 * @return {?}
142 */
143 toString() { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; }
144}
145/**
146 * \@description
147 *
148 * Represents an event triggered when a navigation fails due to an unexpected error.
149 *
150 * \@publicApi
151 */
152class NavigationError extends RouterEvent {
153 /**
154 * @param {?} id
155 * @param {?} url
156 * @param {?} error
157 */
158 constructor(
159 /** @docsNotRequired */
160 id,
161 /** @docsNotRequired */
162 url, error) {
163 super(id, url);
164 this.error = error;
165 }
166 /**
167 * \@docsNotRequired
168 * @return {?}
169 */
170 toString() {
171 return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
172 }
173}
174/**
175 * \@description
176 *
177 * Represents an event triggered when routes are recognized.
178 *
179 * \@publicApi
180 */
181class RoutesRecognized extends RouterEvent {
182 /**
183 * @param {?} id
184 * @param {?} url
185 * @param {?} urlAfterRedirects
186 * @param {?} state
187 */
188 constructor(
189 /** @docsNotRequired */
190 id,
191 /** @docsNotRequired */
192 url, urlAfterRedirects, state) {
193 super(id, url);
194 this.urlAfterRedirects = urlAfterRedirects;
195 this.state = state;
196 }
197 /**
198 * \@docsNotRequired
199 * @return {?}
200 */
201 toString() {
202 return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
203 }
204}
205/**
206 * \@description
207 *
208 * Represents the start of the Guard phase of routing.
209 *
210 * \@publicApi
211 */
212class GuardsCheckStart extends RouterEvent {
213 /**
214 * @param {?} id
215 * @param {?} url
216 * @param {?} urlAfterRedirects
217 * @param {?} state
218 */
219 constructor(
220 /** @docsNotRequired */
221 id,
222 /** @docsNotRequired */
223 url, urlAfterRedirects, state) {
224 super(id, url);
225 this.urlAfterRedirects = urlAfterRedirects;
226 this.state = state;
227 }
228 /**
229 * @return {?}
230 */
231 toString() {
232 return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
233 }
234}
235/**
236 * \@description
237 *
238 * Represents the end of the Guard phase of routing.
239 *
240 * \@publicApi
241 */
242class GuardsCheckEnd extends RouterEvent {
243 /**
244 * @param {?} id
245 * @param {?} url
246 * @param {?} urlAfterRedirects
247 * @param {?} state
248 * @param {?} shouldActivate
249 */
250 constructor(
251 /** @docsNotRequired */
252 id,
253 /** @docsNotRequired */
254 url, urlAfterRedirects, state, shouldActivate) {
255 super(id, url);
256 this.urlAfterRedirects = urlAfterRedirects;
257 this.state = state;
258 this.shouldActivate = shouldActivate;
259 }
260 /**
261 * @return {?}
262 */
263 toString() {
264 return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`;
265 }
266}
267/**
268 * \@description
269 *
270 * Represents the start of the Resolve phase of routing. The timing of this
271 * event may change, thus it's experimental. In the current iteration it will run
272 * in the "resolve" phase whether there's things to resolve or not. In the future this
273 * behavior may change to only run when there are things to be resolved.
274 *
275 * \@publicApi
276 */
277class ResolveStart extends RouterEvent {
278 /**
279 * @param {?} id
280 * @param {?} url
281 * @param {?} urlAfterRedirects
282 * @param {?} state
283 */
284 constructor(
285 /** @docsNotRequired */
286 id,
287 /** @docsNotRequired */
288 url, urlAfterRedirects, state) {
289 super(id, url);
290 this.urlAfterRedirects = urlAfterRedirects;
291 this.state = state;
292 }
293 /**
294 * @return {?}
295 */
296 toString() {
297 return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
298 }
299}
300/**
301 * \@description
302 *
303 * Represents the end of the Resolve phase of routing. See note on
304 * `ResolveStart` for use of this experimental API.
305 *
306 * \@publicApi
307 */
308class ResolveEnd extends RouterEvent {
309 /**
310 * @param {?} id
311 * @param {?} url
312 * @param {?} urlAfterRedirects
313 * @param {?} state
314 */
315 constructor(
316 /** @docsNotRequired */
317 id,
318 /** @docsNotRequired */
319 url, urlAfterRedirects, state) {
320 super(id, url);
321 this.urlAfterRedirects = urlAfterRedirects;
322 this.state = state;
323 }
324 /**
325 * @return {?}
326 */
327 toString() {
328 return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
329 }
330}
331/**
332 * \@description
333 *
334 * Represents an event triggered before lazy loading a route config.
335 *
336 * \@publicApi
337 */
338class RouteConfigLoadStart {
339 /**
340 * @param {?} route
341 */
342 constructor(route) {
343 this.route = route;
344 }
345 /**
346 * @return {?}
347 */
348 toString() { return `RouteConfigLoadStart(path: ${this.route.path})`; }
349}
350/**
351 * \@description
352 *
353 * Represents an event triggered when a route has been lazy loaded.
354 *
355 * \@publicApi
356 */
357class RouteConfigLoadEnd {
358 /**
359 * @param {?} route
360 */
361 constructor(route) {
362 this.route = route;
363 }
364 /**
365 * @return {?}
366 */
367 toString() { return `RouteConfigLoadEnd(path: ${this.route.path})`; }
368}
369/**
370 * \@description
371 *
372 * Represents the start of end of the Resolve phase of routing. See note on
373 * `ChildActivationEnd` for use of this experimental API.
374 *
375 * \@publicApi
376 */
377class ChildActivationStart {
378 /**
379 * @param {?} snapshot
380 */
381 constructor(snapshot) {
382 this.snapshot = snapshot;
383 }
384 /**
385 * @return {?}
386 */
387 toString() {
388 /** @type {?} */
389 const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
390 return `ChildActivationStart(path: '${path}')`;
391 }
392}
393/**
394 * \@description
395 *
396 * Represents the start of end of the Resolve phase of routing. See note on
397 * `ChildActivationStart` for use of this experimental API.
398 *
399 * \@publicApi
400 */
401class ChildActivationEnd {
402 /**
403 * @param {?} snapshot
404 */
405 constructor(snapshot) {
406 this.snapshot = snapshot;
407 }
408 /**
409 * @return {?}
410 */
411 toString() {
412 /** @type {?} */
413 const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
414 return `ChildActivationEnd(path: '${path}')`;
415 }
416}
417/**
418 * \@description
419 *
420 * Represents the start of end of the Resolve phase of routing. See note on
421 * `ActivationEnd` for use of this experimental API.
422 *
423 * \@publicApi
424 */
425class ActivationStart {
426 /**
427 * @param {?} snapshot
428 */
429 constructor(snapshot) {
430 this.snapshot = snapshot;
431 }
432 /**
433 * @return {?}
434 */
435 toString() {
436 /** @type {?} */
437 const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
438 return `ActivationStart(path: '${path}')`;
439 }
440}
441/**
442 * \@description
443 *
444 * Represents the start of end of the Resolve phase of routing. See note on
445 * `ActivationStart` for use of this experimental API.
446 *
447 * \@publicApi
448 */
449class ActivationEnd {
450 /**
451 * @param {?} snapshot
452 */
453 constructor(snapshot) {
454 this.snapshot = snapshot;
455 }
456 /**
457 * @return {?}
458 */
459 toString() {
460 /** @type {?} */
461 const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
462 return `ActivationEnd(path: '${path}')`;
463 }
464}
465/**
466 * \@description
467 *
468 * Represents a scrolling event.
469 *
470 * \@publicApi
471 */
472class Scroll {
473 /**
474 * @param {?} routerEvent
475 * @param {?} position
476 * @param {?} anchor
477 */
478 constructor(routerEvent, position, anchor) {
479 this.routerEvent = routerEvent;
480 this.position = position;
481 this.anchor = anchor;
482 }
483 /**
484 * @return {?}
485 */
486 toString() {
487 /** @type {?} */
488 const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null;
489 return `Scroll(anchor: '${this.anchor}', position: '${pos}')`;
490 }
491}
492
493/**
494 * @fileoverview added by tsickle
495 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
496 */
497/**
498 * This component is used internally within the router to be a placeholder when an empty
499 * router-outlet is needed. For example, with a config such as:
500 *
501 * `{path: 'parent', outlet: 'nav', children: [...]}`
502 *
503 * In order to render, there needs to be a component on this config, which will default
504 * to this `EmptyOutletComponent`.
505 */
506class ɵEmptyOutletComponent {
507}
508ɵEmptyOutletComponent.decorators = [
509 { type: Component, args: [{ template: `<router-outlet></router-outlet>` }] }
510];
511
512/**
513 * @fileoverview added by tsickle
514 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
515 */
516/**
517 * @license
518 * Copyright Google Inc. All Rights Reserved.
519 *
520 * Use of this source code is governed by an MIT-style license that can be
521 * found in the LICENSE file at https://angular.io/license
522 */
523/**
524 * \@description
525 *
526 * Name of the primary outlet.
527 *
528 * \@publicApi
529 * @type {?}
530 */
531const PRIMARY_OUTLET = 'primary';
532class ParamsAsMap {
533 /**
534 * @param {?} params
535 */
536 constructor(params) { this.params = params || {}; }
537 /**
538 * @param {?} name
539 * @return {?}
540 */
541 has(name) { return this.params.hasOwnProperty(name); }
542 /**
543 * @param {?} name
544 * @return {?}
545 */
546 get(name) {
547 if (this.has(name)) {
548 /** @type {?} */
549 const v = this.params[name];
550 return Array.isArray(v) ? v[0] : v;
551 }
552 return null;
553 }
554 /**
555 * @param {?} name
556 * @return {?}
557 */
558 getAll(name) {
559 if (this.has(name)) {
560 /** @type {?} */
561 const v = this.params[name];
562 return Array.isArray(v) ? v : [v];
563 }
564 return [];
565 }
566 /**
567 * @return {?}
568 */
569 get keys() { return Object.keys(this.params); }
570}
571/**
572 * Convert a `Params` instance to a `ParamMap`.
573 *
574 * \@publicApi
575 * @param {?} params
576 * @return {?}
577 */
578function convertToParamMap(params) {
579 return new ParamsAsMap(params);
580}
581/** @type {?} */
582const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
583/**
584 * @param {?} message
585 * @return {?}
586 */
587function navigationCancelingError(message) {
588 /** @type {?} */
589 const error = Error('NavigationCancelingError: ' + message);
590 ((/** @type {?} */ (error)))[NAVIGATION_CANCELING_ERROR] = true;
591 return error;
592}
593/**
594 * @param {?} error
595 * @return {?}
596 */
597function isNavigationCancelingError(error) {
598 return error && ((/** @type {?} */ (error)))[NAVIGATION_CANCELING_ERROR];
599}
600// Matches the route configuration (`route`) against the actual URL (`segments`).
601/**
602 * @param {?} segments
603 * @param {?} segmentGroup
604 * @param {?} route
605 * @return {?}
606 */
607function defaultUrlMatcher(segments, segmentGroup, route) {
608 /** @type {?} */
609 const parts = (/** @type {?} */ (route.path)).split('/');
610 if (parts.length > segments.length) {
611 // The actual URL is shorter than the config, no match
612 return null;
613 }
614 if (route.pathMatch === 'full' &&
615 (segmentGroup.hasChildren() || parts.length < segments.length)) {
616 // The config is longer than the actual URL but we are looking for a full match, return null
617 return null;
618 }
619 /** @type {?} */
620 const posParams = {};
621 // Check each config part against the actual URL
622 for (let index = 0; index < parts.length; index++) {
623 /** @type {?} */
624 const part = parts[index];
625 /** @type {?} */
626 const segment = segments[index];
627 /** @type {?} */
628 const isParameter = part.startsWith(':');
629 if (isParameter) {
630 posParams[part.substring(1)] = segment;
631 }
632 else if (part !== segment.path) {
633 // The actual URL part does not match the config, no match
634 return null;
635 }
636 }
637 return { consumed: segments.slice(0, parts.length), posParams };
638}
639
640/**
641 * @fileoverview added by tsickle
642 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
643 */
644class LoadedRouterConfig {
645 /**
646 * @param {?} routes
647 * @param {?} module
648 */
649 constructor(routes, module) {
650 this.routes = routes;
651 this.module = module;
652 }
653}
654/**
655 * @param {?} config
656 * @param {?=} parentPath
657 * @return {?}
658 */
659function validateConfig(config, parentPath = '') {
660 // forEach doesn't iterate undefined values
661 for (let i = 0; i < config.length; i++) {
662 /** @type {?} */
663 const route = config[i];
664 /** @type {?} */
665 const fullPath = getFullPath(parentPath, route);
666 validateNode(route, fullPath);
667 }
668}
669/**
670 * @param {?} route
671 * @param {?} fullPath
672 * @return {?}
673 */
674function validateNode(route, fullPath) {
675 if (!route) {
676 throw new Error(`
677 Invalid configuration of route '${fullPath}': Encountered undefined route.
678 The reason might be an extra comma.
679
680 Example:
681 const routes: Routes = [
682 { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
683 { path: 'dashboard', component: DashboardComponent },, << two commas
684 { path: 'detail/:id', component: HeroDetailComponent }
685 ];
686 `);
687 }
688 if (Array.isArray(route)) {
689 throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
690 }
691 if (!route.component && !route.children && !route.loadChildren &&
692 (route.outlet && route.outlet !== PRIMARY_OUTLET)) {
693 throw new Error(`Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
694 }
695 if (route.redirectTo && route.children) {
696 throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
697 }
698 if (route.redirectTo && route.loadChildren) {
699 throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
700 }
701 if (route.children && route.loadChildren) {
702 throw new Error(`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
703 }
704 if (route.redirectTo && route.component) {
705 throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and component cannot be used together`);
706 }
707 if (route.path && route.matcher) {
708 throw new Error(`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
709 }
710 if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
711 throw new Error(`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, redirectTo, children or loadChildren`);
712 }
713 if (route.path === void 0 && route.matcher === void 0) {
714 throw new Error(`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
715 }
716 if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
717 throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
718 }
719 if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
720 /** @type {?} */
721 const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
722 throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
723 }
724 if (route.pathMatch !== void 0 && route.pathMatch !== 'full' && route.pathMatch !== 'prefix') {
725 throw new Error(`Invalid configuration of route '${fullPath}': pathMatch can only be set to 'prefix' or 'full'`);
726 }
727 if (route.children) {
728 validateConfig(route.children, fullPath);
729 }
730}
731/**
732 * @param {?} parentPath
733 * @param {?} currentRoute
734 * @return {?}
735 */
736function getFullPath(parentPath, currentRoute) {
737 if (!currentRoute) {
738 return parentPath;
739 }
740 if (!parentPath && !currentRoute.path) {
741 return '';
742 }
743 else if (parentPath && !currentRoute.path) {
744 return `${parentPath}/`;
745 }
746 else if (!parentPath && currentRoute.path) {
747 return currentRoute.path;
748 }
749 else {
750 return `${parentPath}/${currentRoute.path}`;
751 }
752}
753/**
754 * Makes a copy of the config and adds any default required properties.
755 * @param {?} r
756 * @return {?}
757 */
758function standardizeConfig(r) {
759 /** @type {?} */
760 const children = r.children && r.children.map(standardizeConfig);
761 /** @type {?} */
762 const c = children ? Object.assign({}, r, { children }) : Object.assign({}, r);
763 if (!c.component && (children || c.loadChildren) && (c.outlet && c.outlet !== PRIMARY_OUTLET)) {
764 c.component = ɵEmptyOutletComponent;
765 }
766 return c;
767}
768
769/**
770 * @fileoverview added by tsickle
771 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
772 */
773/**
774 * @param {?} a
775 * @param {?} b
776 * @return {?}
777 */
778function shallowEqualArrays(a, b) {
779 if (a.length !== b.length)
780 return false;
781 for (let i = 0; i < a.length; ++i) {
782 if (!shallowEqual(a[i], b[i]))
783 return false;
784 }
785 return true;
786}
787/**
788 * @param {?} a
789 * @param {?} b
790 * @return {?}
791 */
792function shallowEqual(a, b) {
793 // Casting Object.keys return values to include `undefined` as there are some cases
794 // in IE 11 where this can happen. Cannot provide a test because the behavior only
795 // exists in certain circumstances in IE 11, therefore doing this cast ensures the
796 // logic is correct for when this edge case is hit.
797 /** @type {?} */
798 const k1 = (/** @type {?} */ (Object.keys(a)));
799 /** @type {?} */
800 const k2 = (/** @type {?} */ (Object.keys(b)));
801 if (!k1 || !k2 || k1.length != k2.length) {
802 return false;
803 }
804 /** @type {?} */
805 let key;
806 for (let i = 0; i < k1.length; i++) {
807 key = k1[i];
808 if (a[key] !== b[key]) {
809 return false;
810 }
811 }
812 return true;
813}
814/**
815 * Flattens single-level nested arrays.
816 * @template T
817 * @param {?} arr
818 * @return {?}
819 */
820function flatten(arr) {
821 return Array.prototype.concat.apply([], arr);
822}
823/**
824 * Return the last element of an array.
825 * @template T
826 * @param {?} a
827 * @return {?}
828 */
829function last(a) {
830 return a.length > 0 ? a[a.length - 1] : null;
831}
832/**
833 * @template K, V
834 * @param {?} map
835 * @param {?} callback
836 * @return {?}
837 */
838function forEach(map, callback) {
839 for (const prop in map) {
840 if (map.hasOwnProperty(prop)) {
841 callback(map[prop], prop);
842 }
843 }
844}
845/**
846 * @template A, B
847 * @param {?} obj
848 * @param {?} fn
849 * @return {?}
850 */
851function waitForMap(obj, fn) {
852 if (Object.keys(obj).length === 0) {
853 return of({});
854 }
855 /** @type {?} */
856 const waitHead = [];
857 /** @type {?} */
858 const waitTail = [];
859 /** @type {?} */
860 const res = {};
861 forEach(obj, (/**
862 * @param {?} a
863 * @param {?} k
864 * @return {?}
865 */
866 (a, k) => {
867 /** @type {?} */
868 const mapped = fn(k, a).pipe(map((/**
869 * @param {?} r
870 * @return {?}
871 */
872 (r) => res[k] = r)));
873 if (k === PRIMARY_OUTLET) {
874 waitHead.push(mapped);
875 }
876 else {
877 waitTail.push(mapped);
878 }
879 }));
880 // Closure compiler has problem with using spread operator here. So just using Array.concat.
881 return of.apply(null, waitHead.concat(waitTail)).pipe(concatAll(), last$1(), map((/**
882 * @return {?}
883 */
884 () => res)));
885}
886/**
887 * @template T
888 * @param {?} value
889 * @return {?}
890 */
891function wrapIntoObservable(value) {
892 if (ɵisObservable(value)) {
893 return value;
894 }
895 if (ɵisPromise(value)) {
896 // Use `Promise.resolve()` to wrap promise-like instances.
897 // Required ie when a Resolver returns a AngularJS `$q` promise to correctly trigger the
898 // change detection.
899 return from(Promise.resolve(value));
900 }
901 return of(value);
902}
903
904/**
905 * @fileoverview added by tsickle
906 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
907 */
908/**
909 * @return {?}
910 */
911function createEmptyUrlTree() {
912 return new UrlTree(new UrlSegmentGroup([], {}), {}, null);
913}
914/**
915 * @param {?} container
916 * @param {?} containee
917 * @param {?} exact
918 * @return {?}
919 */
920function containsTree(container, containee, exact) {
921 if (exact) {
922 return equalQueryParams(container.queryParams, containee.queryParams) &&
923 equalSegmentGroups(container.root, containee.root);
924 }
925 return containsQueryParams(container.queryParams, containee.queryParams) &&
926 containsSegmentGroup(container.root, containee.root);
927}
928/**
929 * @param {?} container
930 * @param {?} containee
931 * @return {?}
932 */
933function equalQueryParams(container, containee) {
934 // TODO: This does not handle array params correctly.
935 return shallowEqual(container, containee);
936}
937/**
938 * @param {?} container
939 * @param {?} containee
940 * @return {?}
941 */
942function equalSegmentGroups(container, containee) {
943 if (!equalPath(container.segments, containee.segments))
944 return false;
945 if (container.numberOfChildren !== containee.numberOfChildren)
946 return false;
947 for (const c in containee.children) {
948 if (!container.children[c])
949 return false;
950 if (!equalSegmentGroups(container.children[c], containee.children[c]))
951 return false;
952 }
953 return true;
954}
955/**
956 * @param {?} container
957 * @param {?} containee
958 * @return {?}
959 */
960function containsQueryParams(container, containee) {
961 // TODO: This does not handle array params correctly.
962 return Object.keys(containee).length <= Object.keys(container).length &&
963 Object.keys(containee).every((/**
964 * @param {?} key
965 * @return {?}
966 */
967 key => containee[key] === container[key]));
968}
969/**
970 * @param {?} container
971 * @param {?} containee
972 * @return {?}
973 */
974function containsSegmentGroup(container, containee) {
975 return containsSegmentGroupHelper(container, containee, containee.segments);
976}
977/**
978 * @param {?} container
979 * @param {?} containee
980 * @param {?} containeePaths
981 * @return {?}
982 */
983function containsSegmentGroupHelper(container, containee, containeePaths) {
984 if (container.segments.length > containeePaths.length) {
985 /** @type {?} */
986 const current = container.segments.slice(0, containeePaths.length);
987 if (!equalPath(current, containeePaths))
988 return false;
989 if (containee.hasChildren())
990 return false;
991 return true;
992 }
993 else if (container.segments.length === containeePaths.length) {
994 if (!equalPath(container.segments, containeePaths))
995 return false;
996 for (const c in containee.children) {
997 if (!container.children[c])
998 return false;
999 if (!containsSegmentGroup(container.children[c], containee.children[c]))
1000 return false;
1001 }
1002 return true;
1003 }
1004 else {
1005 /** @type {?} */
1006 const current = containeePaths.slice(0, container.segments.length);
1007 /** @type {?} */
1008 const next = containeePaths.slice(container.segments.length);
1009 if (!equalPath(container.segments, current))
1010 return false;
1011 if (!container.children[PRIMARY_OUTLET])
1012 return false;
1013 return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next);
1014 }
1015}
1016/**
1017 * \@description
1018 *
1019 * Represents the parsed URL.
1020 *
1021 * Since a router state is a tree, and the URL is nothing but a serialized state, the URL is a
1022 * serialized tree.
1023 * UrlTree is a data structure that provides a lot of affordances in dealing with URLs
1024 *
1025 * \@usageNotes
1026 * ### Example
1027 *
1028 * ```
1029 * \@Component({templateUrl:'template.html'})
1030 * class MyComponent {
1031 * constructor(router: Router) {
1032 * const tree: UrlTree =
1033 * router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment');
1034 * const f = tree.fragment; // return 'fragment'
1035 * const q = tree.queryParams; // returns {debug: 'true'}
1036 * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
1037 * const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33'
1038 * g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor'
1039 * g.children['support'].segments; // return 1 segment 'help'
1040 * }
1041 * }
1042 * ```
1043 *
1044 * \@publicApi
1045 */
1046class UrlTree {
1047 /**
1048 * \@internal
1049 * @param {?} root
1050 * @param {?} queryParams
1051 * @param {?} fragment
1052 */
1053 constructor(root, queryParams, fragment) {
1054 this.root = root;
1055 this.queryParams = queryParams;
1056 this.fragment = fragment;
1057 }
1058 /**
1059 * @return {?}
1060 */
1061 get queryParamMap() {
1062 if (!this._queryParamMap) {
1063 this._queryParamMap = convertToParamMap(this.queryParams);
1064 }
1065 return this._queryParamMap;
1066 }
1067 /**
1068 * \@docsNotRequired
1069 * @return {?}
1070 */
1071 toString() { return DEFAULT_SERIALIZER.serialize(this); }
1072}
1073/**
1074 * \@description
1075 *
1076 * Represents the parsed URL segment group.
1077 *
1078 * See `UrlTree` for more information.
1079 *
1080 * \@publicApi
1081 */
1082class UrlSegmentGroup {
1083 /**
1084 * @param {?} segments
1085 * @param {?} children
1086 */
1087 constructor(segments, children) {
1088 this.segments = segments;
1089 this.children = children;
1090 /**
1091 * The parent node in the url tree
1092 */
1093 this.parent = null;
1094 forEach(children, (/**
1095 * @template THIS
1096 * @this {THIS}
1097 * @param {?} v
1098 * @param {?} k
1099 * @return {THIS}
1100 */
1101 (v, k) => v.parent = this));
1102 }
1103 /**
1104 * Whether the segment has child segments
1105 * @return {?}
1106 */
1107 hasChildren() { return this.numberOfChildren > 0; }
1108 /**
1109 * Number of child segments
1110 * @return {?}
1111 */
1112 get numberOfChildren() { return Object.keys(this.children).length; }
1113 /**
1114 * \@docsNotRequired
1115 * @return {?}
1116 */
1117 toString() { return serializePaths(this); }
1118}
1119/**
1120 * \@description
1121 *
1122 * Represents a single URL segment.
1123 *
1124 * A UrlSegment is a part of a URL between the two slashes. It contains a path and the matrix
1125 * parameters associated with the segment.
1126 *
1127 * \@usageNotes
1128 *  ### Example
1129 *
1130 * ```
1131 * \@Component({templateUrl:'template.html'})
1132 * class MyComponent {
1133 * constructor(router: Router) {
1134 * const tree: UrlTree = router.parseUrl('/team;id=33');
1135 * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
1136 * const s: UrlSegment[] = g.segments;
1137 * s[0].path; // returns 'team'
1138 * s[0].parameters; // returns {id: 33}
1139 * }
1140 * }
1141 * ```
1142 *
1143 * \@publicApi
1144 */
1145class UrlSegment {
1146 /**
1147 * @param {?} path
1148 * @param {?} parameters
1149 */
1150 constructor(path, parameters) {
1151 this.path = path;
1152 this.parameters = parameters;
1153 }
1154 /**
1155 * @return {?}
1156 */
1157 get parameterMap() {
1158 if (!this._parameterMap) {
1159 this._parameterMap = convertToParamMap(this.parameters);
1160 }
1161 return this._parameterMap;
1162 }
1163 /**
1164 * \@docsNotRequired
1165 * @return {?}
1166 */
1167 toString() { return serializePath(this); }
1168}
1169/**
1170 * @param {?} as
1171 * @param {?} bs
1172 * @return {?}
1173 */
1174function equalSegments(as, bs) {
1175 return equalPath(as, bs) && as.every((/**
1176 * @param {?} a
1177 * @param {?} i
1178 * @return {?}
1179 */
1180 (a, i) => shallowEqual(a.parameters, bs[i].parameters)));
1181}
1182/**
1183 * @param {?} as
1184 * @param {?} bs
1185 * @return {?}
1186 */
1187function equalPath(as, bs) {
1188 if (as.length !== bs.length)
1189 return false;
1190 return as.every((/**
1191 * @param {?} a
1192 * @param {?} i
1193 * @return {?}
1194 */
1195 (a, i) => a.path === bs[i].path));
1196}
1197/**
1198 * @template T
1199 * @param {?} segment
1200 * @param {?} fn
1201 * @return {?}
1202 */
1203function mapChildrenIntoArray(segment, fn) {
1204 /** @type {?} */
1205 let res = [];
1206 forEach(segment.children, (/**
1207 * @param {?} child
1208 * @param {?} childOutlet
1209 * @return {?}
1210 */
1211 (child, childOutlet) => {
1212 if (childOutlet === PRIMARY_OUTLET) {
1213 res = res.concat(fn(child, childOutlet));
1214 }
1215 }));
1216 forEach(segment.children, (/**
1217 * @param {?} child
1218 * @param {?} childOutlet
1219 * @return {?}
1220 */
1221 (child, childOutlet) => {
1222 if (childOutlet !== PRIMARY_OUTLET) {
1223 res = res.concat(fn(child, childOutlet));
1224 }
1225 }));
1226 return res;
1227}
1228/**
1229 * \@description
1230 *
1231 * Serializes and deserializes a URL string into a URL tree.
1232 *
1233 * The url serialization strategy is customizable. You can
1234 * make all URLs case insensitive by providing a custom UrlSerializer.
1235 *
1236 * See `DefaultUrlSerializer` for an example of a URL serializer.
1237 *
1238 * \@publicApi
1239 * @abstract
1240 */
1241class UrlSerializer {
1242}
1243/**
1244 * \@description
1245 *
1246 * A default implementation of the `UrlSerializer`.
1247 *
1248 * Example URLs:
1249 *
1250 * ```
1251 * /inbox/33(popup:compose)
1252 * /inbox/33;open=true/messages/44
1253 * ```
1254 *
1255 * DefaultUrlSerializer uses parentheses to serialize secondary segments (e.g., popup:compose), the
1256 * colon syntax to specify the outlet, and the ';parameter=value' syntax (e.g., open=true) to
1257 * specify route specific parameters.
1258 *
1259 * \@publicApi
1260 */
1261class DefaultUrlSerializer {
1262 /**
1263 * Parses a url into a `UrlTree`
1264 * @param {?} url
1265 * @return {?}
1266 */
1267 parse(url) {
1268 /** @type {?} */
1269 const p = new UrlParser(url);
1270 return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
1271 }
1272 /**
1273 * Converts a `UrlTree` into a url
1274 * @param {?} tree
1275 * @return {?}
1276 */
1277 serialize(tree) {
1278 /** @type {?} */
1279 const segment = `/${serializeSegment(tree.root, true)}`;
1280 /** @type {?} */
1281 const query = serializeQueryParams(tree.queryParams);
1282 /** @type {?} */
1283 const fragment = typeof tree.fragment === `string` ? `#${encodeUriFragment((/** @type {?} */ (tree.fragment)))}` : '';
1284 return `${segment}${query}${fragment}`;
1285 }
1286}
1287/** @type {?} */
1288const DEFAULT_SERIALIZER = new DefaultUrlSerializer();
1289/**
1290 * @param {?} segment
1291 * @return {?}
1292 */
1293function serializePaths(segment) {
1294 return segment.segments.map((/**
1295 * @param {?} p
1296 * @return {?}
1297 */
1298 p => serializePath(p))).join('/');
1299}
1300/**
1301 * @param {?} segment
1302 * @param {?} root
1303 * @return {?}
1304 */
1305function serializeSegment(segment, root) {
1306 if (!segment.hasChildren()) {
1307 return serializePaths(segment);
1308 }
1309 if (root) {
1310 /** @type {?} */
1311 const primary = segment.children[PRIMARY_OUTLET] ?
1312 serializeSegment(segment.children[PRIMARY_OUTLET], false) :
1313 '';
1314 /** @type {?} */
1315 const children = [];
1316 forEach(segment.children, (/**
1317 * @param {?} v
1318 * @param {?} k
1319 * @return {?}
1320 */
1321 (v, k) => {
1322 if (k !== PRIMARY_OUTLET) {
1323 children.push(`${k}:${serializeSegment(v, false)}`);
1324 }
1325 }));
1326 return children.length > 0 ? `${primary}(${children.join('//')})` : primary;
1327 }
1328 else {
1329 /** @type {?} */
1330 const children = mapChildrenIntoArray(segment, (/**
1331 * @param {?} v
1332 * @param {?} k
1333 * @return {?}
1334 */
1335 (v, k) => {
1336 if (k === PRIMARY_OUTLET) {
1337 return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
1338 }
1339 return [`${k}:${serializeSegment(v, false)}`];
1340 }));
1341 return `${serializePaths(segment)}/(${children.join('//')})`;
1342 }
1343}
1344/**
1345 * Encodes a URI string with the default encoding. This function will only ever be called from
1346 * `encodeUriQuery` or `encodeUriSegment` as it's the base set of encodings to be used. We need
1347 * a custom encoding because encodeURIComponent is too aggressive and encodes stuff that doesn't
1348 * have to be encoded per https://url.spec.whatwg.org.
1349 * @param {?} s
1350 * @return {?}
1351 */
1352function encodeUriString(s) {
1353 return encodeURIComponent(s)
1354 .replace(/%40/g, '@')
1355 .replace(/%3A/gi, ':')
1356 .replace(/%24/g, '$')
1357 .replace(/%2C/gi, ',');
1358}
1359/**
1360 * This function should be used to encode both keys and values in a query string key/value. In
1361 * the following URL, you need to call encodeUriQuery on "k" and "v":
1362 *
1363 * http://www.site.org/html;mk=mv?k=v#f
1364 * @param {?} s
1365 * @return {?}
1366 */
1367function encodeUriQuery(s) {
1368 return encodeUriString(s).replace(/%3B/gi, ';');
1369}
1370/**
1371 * This function should be used to encode a URL fragment. In the following URL, you need to call
1372 * encodeUriFragment on "f":
1373 *
1374 * http://www.site.org/html;mk=mv?k=v#f
1375 * @param {?} s
1376 * @return {?}
1377 */
1378function encodeUriFragment(s) {
1379 return encodeURI(s);
1380}
1381/**
1382 * This function should be run on any URI segment as well as the key and value in a key/value
1383 * pair for matrix params. In the following URL, you need to call encodeUriSegment on "html",
1384 * "mk", and "mv":
1385 *
1386 * http://www.site.org/html;mk=mv?k=v#f
1387 * @param {?} s
1388 * @return {?}
1389 */
1390function encodeUriSegment(s) {
1391 return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&');
1392}
1393/**
1394 * @param {?} s
1395 * @return {?}
1396 */
1397function decode(s) {
1398 return decodeURIComponent(s);
1399}
1400// Query keys/values should have the "+" replaced first, as "+" in a query string is " ".
1401// decodeURIComponent function will not decode "+" as a space.
1402/**
1403 * @param {?} s
1404 * @return {?}
1405 */
1406function decodeQuery(s) {
1407 return decode(s.replace(/\+/g, '%20'));
1408}
1409/**
1410 * @param {?} path
1411 * @return {?}
1412 */
1413function serializePath(path) {
1414 return `${encodeUriSegment(path.path)}${serializeMatrixParams(path.parameters)}`;
1415}
1416/**
1417 * @param {?} params
1418 * @return {?}
1419 */
1420function serializeMatrixParams(params) {
1421 return Object.keys(params)
1422 .map((/**
1423 * @param {?} key
1424 * @return {?}
1425 */
1426 key => `;${encodeUriSegment(key)}=${encodeUriSegment(params[key])}`))
1427 .join('');
1428}
1429/**
1430 * @param {?} params
1431 * @return {?}
1432 */
1433function serializeQueryParams(params) {
1434 /** @type {?} */
1435 const strParams = Object.keys(params).map((/**
1436 * @param {?} name
1437 * @return {?}
1438 */
1439 (name) => {
1440 /** @type {?} */
1441 const value = params[name];
1442 return Array.isArray(value) ?
1443 value.map((/**
1444 * @param {?} v
1445 * @return {?}
1446 */
1447 v => `${encodeUriQuery(name)}=${encodeUriQuery(v)}`)).join('&') :
1448 `${encodeUriQuery(name)}=${encodeUriQuery(value)}`;
1449 }));
1450 return strParams.length ? `?${strParams.join("&")}` : '';
1451}
1452/** @type {?} */
1453const SEGMENT_RE = /^[^\/()?;=#]+/;
1454/**
1455 * @param {?} str
1456 * @return {?}
1457 */
1458function matchSegments(str) {
1459 /** @type {?} */
1460 const match = str.match(SEGMENT_RE);
1461 return match ? match[0] : '';
1462}
1463/** @type {?} */
1464const QUERY_PARAM_RE = /^[^=?&#]+/;
1465// Return the name of the query param at the start of the string or an empty string
1466/**
1467 * @param {?} str
1468 * @return {?}
1469 */
1470function matchQueryParams(str) {
1471 /** @type {?} */
1472 const match = str.match(QUERY_PARAM_RE);
1473 return match ? match[0] : '';
1474}
1475/** @type {?} */
1476const QUERY_PARAM_VALUE_RE = /^[^?&#]+/;
1477// Return the value of the query param at the start of the string or an empty string
1478/**
1479 * @param {?} str
1480 * @return {?}
1481 */
1482function matchUrlQueryParamValue(str) {
1483 /** @type {?} */
1484 const match = str.match(QUERY_PARAM_VALUE_RE);
1485 return match ? match[0] : '';
1486}
1487class UrlParser {
1488 /**
1489 * @param {?} url
1490 */
1491 constructor(url) {
1492 this.url = url;
1493 this.remaining = url;
1494 }
1495 /**
1496 * @return {?}
1497 */
1498 parseRootSegment() {
1499 this.consumeOptional('/');
1500 if (this.remaining === '' || this.peekStartsWith('?') || this.peekStartsWith('#')) {
1501 return new UrlSegmentGroup([], {});
1502 }
1503 // The root segment group never has segments
1504 return new UrlSegmentGroup([], this.parseChildren());
1505 }
1506 /**
1507 * @return {?}
1508 */
1509 parseQueryParams() {
1510 /** @type {?} */
1511 const params = {};
1512 if (this.consumeOptional('?')) {
1513 do {
1514 this.parseQueryParam(params);
1515 } while (this.consumeOptional('&'));
1516 }
1517 return params;
1518 }
1519 /**
1520 * @return {?}
1521 */
1522 parseFragment() {
1523 return this.consumeOptional('#') ? decodeURIComponent(this.remaining) : null;
1524 }
1525 /**
1526 * @private
1527 * @return {?}
1528 */
1529 parseChildren() {
1530 if (this.remaining === '') {
1531 return {};
1532 }
1533 this.consumeOptional('/');
1534 /** @type {?} */
1535 const segments = [];
1536 if (!this.peekStartsWith('(')) {
1537 segments.push(this.parseSegment());
1538 }
1539 while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) {
1540 this.capture('/');
1541 segments.push(this.parseSegment());
1542 }
1543 /** @type {?} */
1544 let children = {};
1545 if (this.peekStartsWith('/(')) {
1546 this.capture('/');
1547 children = this.parseParens(true);
1548 }
1549 /** @type {?} */
1550 let res = {};
1551 if (this.peekStartsWith('(')) {
1552 res = this.parseParens(false);
1553 }
1554 if (segments.length > 0 || Object.keys(children).length > 0) {
1555 res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children);
1556 }
1557 return res;
1558 }
1559 // parse a segment with its matrix parameters
1560 // ie `name;k1=v1;k2`
1561 /**
1562 * @private
1563 * @return {?}
1564 */
1565 parseSegment() {
1566 /** @type {?} */
1567 const path = matchSegments(this.remaining);
1568 if (path === '' && this.peekStartsWith(';')) {
1569 throw new Error(`Empty path url segment cannot have parameters: '${this.remaining}'.`);
1570 }
1571 this.capture(path);
1572 return new UrlSegment(decode(path), this.parseMatrixParams());
1573 }
1574 /**
1575 * @private
1576 * @return {?}
1577 */
1578 parseMatrixParams() {
1579 /** @type {?} */
1580 const params = {};
1581 while (this.consumeOptional(';')) {
1582 this.parseParam(params);
1583 }
1584 return params;
1585 }
1586 /**
1587 * @private
1588 * @param {?} params
1589 * @return {?}
1590 */
1591 parseParam(params) {
1592 /** @type {?} */
1593 const key = matchSegments(this.remaining);
1594 if (!key) {
1595 return;
1596 }
1597 this.capture(key);
1598 /** @type {?} */
1599 let value = '';
1600 if (this.consumeOptional('=')) {
1601 /** @type {?} */
1602 const valueMatch = matchSegments(this.remaining);
1603 if (valueMatch) {
1604 value = valueMatch;
1605 this.capture(value);
1606 }
1607 }
1608 params[decode(key)] = decode(value);
1609 }
1610 // Parse a single query parameter `name[=value]`
1611 /**
1612 * @private
1613 * @param {?} params
1614 * @return {?}
1615 */
1616 parseQueryParam(params) {
1617 /** @type {?} */
1618 const key = matchQueryParams(this.remaining);
1619 if (!key) {
1620 return;
1621 }
1622 this.capture(key);
1623 /** @type {?} */
1624 let value = '';
1625 if (this.consumeOptional('=')) {
1626 /** @type {?} */
1627 const valueMatch = matchUrlQueryParamValue(this.remaining);
1628 if (valueMatch) {
1629 value = valueMatch;
1630 this.capture(value);
1631 }
1632 }
1633 /** @type {?} */
1634 const decodedKey = decodeQuery(key);
1635 /** @type {?} */
1636 const decodedVal = decodeQuery(value);
1637 if (params.hasOwnProperty(decodedKey)) {
1638 // Append to existing values
1639 /** @type {?} */
1640 let currentVal = params[decodedKey];
1641 if (!Array.isArray(currentVal)) {
1642 currentVal = [currentVal];
1643 params[decodedKey] = currentVal;
1644 }
1645 currentVal.push(decodedVal);
1646 }
1647 else {
1648 // Create a new value
1649 params[decodedKey] = decodedVal;
1650 }
1651 }
1652 // parse `(a/b//outlet_name:c/d)`
1653 /**
1654 * @private
1655 * @param {?} allowPrimary
1656 * @return {?}
1657 */
1658 parseParens(allowPrimary) {
1659 /** @type {?} */
1660 const segments = {};
1661 this.capture('(');
1662 while (!this.consumeOptional(')') && this.remaining.length > 0) {
1663 /** @type {?} */
1664 const path = matchSegments(this.remaining);
1665 /** @type {?} */
1666 const next = this.remaining[path.length];
1667 // if is is not one of these characters, then the segment was unescaped
1668 // or the group was not closed
1669 if (next !== '/' && next !== ')' && next !== ';') {
1670 throw new Error(`Cannot parse url '${this.url}'`);
1671 }
1672 /** @type {?} */
1673 let outletName = (/** @type {?} */ (undefined));
1674 if (path.indexOf(':') > -1) {
1675 outletName = path.substr(0, path.indexOf(':'));
1676 this.capture(outletName);
1677 this.capture(':');
1678 }
1679 else if (allowPrimary) {
1680 outletName = PRIMARY_OUTLET;
1681 }
1682 /** @type {?} */
1683 const children = this.parseChildren();
1684 segments[outletName] = Object.keys(children).length === 1 ? children[PRIMARY_OUTLET] :
1685 new UrlSegmentGroup([], children);
1686 this.consumeOptional('//');
1687 }
1688 return segments;
1689 }
1690 /**
1691 * @private
1692 * @param {?} str
1693 * @return {?}
1694 */
1695 peekStartsWith(str) { return this.remaining.startsWith(str); }
1696 // Consumes the prefix when it is present and returns whether it has been consumed
1697 /**
1698 * @private
1699 * @param {?} str
1700 * @return {?}
1701 */
1702 consumeOptional(str) {
1703 if (this.peekStartsWith(str)) {
1704 this.remaining = this.remaining.substring(str.length);
1705 return true;
1706 }
1707 return false;
1708 }
1709 /**
1710 * @private
1711 * @param {?} str
1712 * @return {?}
1713 */
1714 capture(str) {
1715 if (!this.consumeOptional(str)) {
1716 throw new Error(`Expected "${str}".`);
1717 }
1718 }
1719}
1720
1721/**
1722 * @fileoverview added by tsickle
1723 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1724 */
1725/**
1726 * @license
1727 * Copyright Google Inc. All Rights Reserved.
1728 *
1729 * Use of this source code is governed by an MIT-style license that can be
1730 * found in the LICENSE file at https://angular.io/license
1731 */
1732/**
1733 * @template T
1734 */
1735class Tree {
1736 /**
1737 * @param {?} root
1738 */
1739 constructor(root) { this._root = root; }
1740 /**
1741 * @return {?}
1742 */
1743 get root() { return this._root.value; }
1744 /**
1745 * \@internal
1746 * @param {?} t
1747 * @return {?}
1748 */
1749 parent(t) {
1750 /** @type {?} */
1751 const p = this.pathFromRoot(t);
1752 return p.length > 1 ? p[p.length - 2] : null;
1753 }
1754 /**
1755 * \@internal
1756 * @param {?} t
1757 * @return {?}
1758 */
1759 children(t) {
1760 /** @type {?} */
1761 const n = findNode(t, this._root);
1762 return n ? n.children.map((/**
1763 * @param {?} t
1764 * @return {?}
1765 */
1766 t => t.value)) : [];
1767 }
1768 /**
1769 * \@internal
1770 * @param {?} t
1771 * @return {?}
1772 */
1773 firstChild(t) {
1774 /** @type {?} */
1775 const n = findNode(t, this._root);
1776 return n && n.children.length > 0 ? n.children[0].value : null;
1777 }
1778 /**
1779 * \@internal
1780 * @param {?} t
1781 * @return {?}
1782 */
1783 siblings(t) {
1784 /** @type {?} */
1785 const p = findPath(t, this._root);
1786 if (p.length < 2)
1787 return [];
1788 /** @type {?} */
1789 const c = p[p.length - 2].children.map((/**
1790 * @param {?} c
1791 * @return {?}
1792 */
1793 c => c.value));
1794 return c.filter((/**
1795 * @param {?} cc
1796 * @return {?}
1797 */
1798 cc => cc !== t));
1799 }
1800 /**
1801 * \@internal
1802 * @param {?} t
1803 * @return {?}
1804 */
1805 pathFromRoot(t) { return findPath(t, this._root).map((/**
1806 * @param {?} s
1807 * @return {?}
1808 */
1809 s => s.value)); }
1810}
1811// DFS for the node matching the value
1812/**
1813 * @template T
1814 * @param {?} value
1815 * @param {?} node
1816 * @return {?}
1817 */
1818function findNode(value, node) {
1819 if (value === node.value)
1820 return node;
1821 for (const child of node.children) {
1822 /** @type {?} */
1823 const node = findNode(value, child);
1824 if (node)
1825 return node;
1826 }
1827 return null;
1828}
1829// Return the path to the node with the given value using DFS
1830/**
1831 * @template T
1832 * @param {?} value
1833 * @param {?} node
1834 * @return {?}
1835 */
1836function findPath(value, node) {
1837 if (value === node.value)
1838 return [node];
1839 for (const child of node.children) {
1840 /** @type {?} */
1841 const path = findPath(value, child);
1842 if (path.length) {
1843 path.unshift(node);
1844 return path;
1845 }
1846 }
1847 return [];
1848}
1849/**
1850 * @template T
1851 */
1852class TreeNode {
1853 /**
1854 * @param {?} value
1855 * @param {?} children
1856 */
1857 constructor(value, children) {
1858 this.value = value;
1859 this.children = children;
1860 }
1861 /**
1862 * @return {?}
1863 */
1864 toString() { return `TreeNode(${this.value})`; }
1865}
1866// Return the list of T indexed by outlet name
1867/**
1868 * @template T
1869 * @param {?} node
1870 * @return {?}
1871 */
1872function nodeChildrenAsMap(node) {
1873 /** @type {?} */
1874 const map = {};
1875 if (node) {
1876 node.children.forEach((/**
1877 * @param {?} child
1878 * @return {?}
1879 */
1880 child => map[child.value.outlet] = child));
1881 }
1882 return map;
1883}
1884
1885/**
1886 * @fileoverview added by tsickle
1887 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1888 */
1889/**
1890 * \@description
1891 *
1892 * Represents the state of the router.
1893 *
1894 * RouterState is a tree of activated routes. Every node in this tree knows about the "consumed" URL
1895 * segments, the extracted parameters, and the resolved data.
1896 *
1897 * \@usageNotes
1898 * ### Example
1899 *
1900 * ```
1901 * \@Component({templateUrl:'template.html'})
1902 * class MyComponent {
1903 * constructor(router: Router) {
1904 * const state: RouterState = router.routerState;
1905 * const root: ActivatedRoute = state.root;
1906 * const child = root.firstChild;
1907 * const id: Observable<string> = child.params.map(p => p.id);
1908 * //...
1909 * }
1910 * }
1911 * ```
1912 *
1913 * See `ActivatedRoute` for more information.
1914 *
1915 * \@publicApi
1916 */
1917class RouterState extends Tree {
1918 /**
1919 * \@internal
1920 * @param {?} root
1921 * @param {?} snapshot
1922 */
1923 constructor(root, snapshot) {
1924 super(root);
1925 this.snapshot = snapshot;
1926 setRouterState((/** @type {?} */ (this)), root);
1927 }
1928 /**
1929 * @return {?}
1930 */
1931 toString() { return this.snapshot.toString(); }
1932}
1933/**
1934 * @param {?} urlTree
1935 * @param {?} rootComponent
1936 * @return {?}
1937 */
1938function createEmptyState(urlTree, rootComponent) {
1939 /** @type {?} */
1940 const snapshot = createEmptyStateSnapshot(urlTree, rootComponent);
1941 /** @type {?} */
1942 const emptyUrl = new BehaviorSubject([new UrlSegment('', {})]);
1943 /** @type {?} */
1944 const emptyParams = new BehaviorSubject({});
1945 /** @type {?} */
1946 const emptyData = new BehaviorSubject({});
1947 /** @type {?} */
1948 const emptyQueryParams = new BehaviorSubject({});
1949 /** @type {?} */
1950 const fragment = new BehaviorSubject('');
1951 /** @type {?} */
1952 const activated = new ActivatedRoute(emptyUrl, emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, snapshot.root);
1953 activated.snapshot = snapshot.root;
1954 return new RouterState(new TreeNode(activated, []), snapshot);
1955}
1956/**
1957 * @param {?} urlTree
1958 * @param {?} rootComponent
1959 * @return {?}
1960 */
1961function createEmptyStateSnapshot(urlTree, rootComponent) {
1962 /** @type {?} */
1963 const emptyParams = {};
1964 /** @type {?} */
1965 const emptyData = {};
1966 /** @type {?} */
1967 const emptyQueryParams = {};
1968 /** @type {?} */
1969 const fragment = '';
1970 /** @type {?} */
1971 const activated = new ActivatedRouteSnapshot([], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null, urlTree.root, -1, {});
1972 return new RouterStateSnapshot('', new TreeNode(activated, []));
1973}
1974/**
1975 * \@description
1976 *
1977 * Contains the information about a route associated with a component loaded in an
1978 * outlet. An `ActivatedRoute` can also be used to traverse the router state tree.
1979 *
1980 * {\@example router/activated-route/module.ts region="activated-route"
1981 * header="activated-route.component.ts" linenums="false"}
1982 *
1983 * \@publicApi
1984 */
1985class ActivatedRoute {
1986 /**
1987 * \@internal
1988 * @param {?} url
1989 * @param {?} params
1990 * @param {?} queryParams
1991 * @param {?} fragment
1992 * @param {?} data
1993 * @param {?} outlet
1994 * @param {?} component
1995 * @param {?} futureSnapshot
1996 */
1997 constructor(url, params, queryParams, fragment, data, outlet, component, futureSnapshot) {
1998 this.url = url;
1999 this.params = params;
2000 this.queryParams = queryParams;
2001 this.fragment = fragment;
2002 this.data = data;
2003 this.outlet = outlet;
2004 this.component = component;
2005 this._futureSnapshot = futureSnapshot;
2006 }
2007 /**
2008 * The configuration used to match this route
2009 * @return {?}
2010 */
2011 get routeConfig() { return this._futureSnapshot.routeConfig; }
2012 /**
2013 * The root of the router state
2014 * @return {?}
2015 */
2016 get root() { return this._routerState.root; }
2017 /**
2018 * The parent of this route in the router state tree
2019 * @return {?}
2020 */
2021 get parent() { return this._routerState.parent(this); }
2022 /**
2023 * The first child of this route in the router state tree
2024 * @return {?}
2025 */
2026 get firstChild() { return this._routerState.firstChild(this); }
2027 /**
2028 * The children of this route in the router state tree
2029 * @return {?}
2030 */
2031 get children() { return this._routerState.children(this); }
2032 /**
2033 * The path from the root of the router state tree to this route
2034 * @return {?}
2035 */
2036 get pathFromRoot() { return this._routerState.pathFromRoot(this); }
2037 /**
2038 * @return {?}
2039 */
2040 get paramMap() {
2041 if (!this._paramMap) {
2042 this._paramMap = this.params.pipe(map((/**
2043 * @param {?} p
2044 * @return {?}
2045 */
2046 (p) => convertToParamMap(p))));
2047 }
2048 return this._paramMap;
2049 }
2050 /**
2051 * @return {?}
2052 */
2053 get queryParamMap() {
2054 if (!this._queryParamMap) {
2055 this._queryParamMap =
2056 this.queryParams.pipe(map((/**
2057 * @param {?} p
2058 * @return {?}
2059 */
2060 (p) => convertToParamMap(p))));
2061 }
2062 return this._queryParamMap;
2063 }
2064 /**
2065 * @return {?}
2066 */
2067 toString() {
2068 return this.snapshot ? this.snapshot.toString() : `Future(${this._futureSnapshot})`;
2069 }
2070}
2071/**
2072 * Returns the inherited params, data, and resolve for a given route.
2073 * By default, this only inherits values up to the nearest path-less or component-less route.
2074 * \@internal
2075 * @param {?} route
2076 * @param {?=} paramsInheritanceStrategy
2077 * @return {?}
2078 */
2079function inheritedParamsDataResolve(route, paramsInheritanceStrategy = 'emptyOnly') {
2080 /** @type {?} */
2081 const pathFromRoot = route.pathFromRoot;
2082 /** @type {?} */
2083 let inheritingStartingFrom = 0;
2084 if (paramsInheritanceStrategy !== 'always') {
2085 inheritingStartingFrom = pathFromRoot.length - 1;
2086 while (inheritingStartingFrom >= 1) {
2087 /** @type {?} */
2088 const current = pathFromRoot[inheritingStartingFrom];
2089 /** @type {?} */
2090 const parent = pathFromRoot[inheritingStartingFrom - 1];
2091 // current route is an empty path => inherits its parent's params and data
2092 if (current.routeConfig && current.routeConfig.path === '') {
2093 inheritingStartingFrom--;
2094 // parent is componentless => current route should inherit its params and data
2095 }
2096 else if (!parent.component) {
2097 inheritingStartingFrom--;
2098 }
2099 else {
2100 break;
2101 }
2102 }
2103 }
2104 return flattenInherited(pathFromRoot.slice(inheritingStartingFrom));
2105}
2106/**
2107 * \@internal
2108 * @param {?} pathFromRoot
2109 * @return {?}
2110 */
2111function flattenInherited(pathFromRoot) {
2112 return pathFromRoot.reduce((/**
2113 * @param {?} res
2114 * @param {?} curr
2115 * @return {?}
2116 */
2117 (res, curr) => {
2118 /** @type {?} */
2119 const params = Object.assign({}, res.params, curr.params);
2120 /** @type {?} */
2121 const data = Object.assign({}, res.data, curr.data);
2122 /** @type {?} */
2123 const resolve = Object.assign({}, res.resolve, curr._resolvedData);
2124 return { params, data, resolve };
2125 }), (/** @type {?} */ ({ params: {}, data: {}, resolve: {} })));
2126}
2127/**
2128 * \@description
2129 *
2130 * Contains the information about a route associated with a component loaded in an
2131 * outlet at a particular moment in time. ActivatedRouteSnapshot can also be used to
2132 * traverse the router state tree.
2133 *
2134 * ```
2135 * \@Component({templateUrl:'./my-component.html'})
2136 * class MyComponent {
2137 * constructor(route: ActivatedRoute) {
2138 * const id: string = route.snapshot.params.id;
2139 * const url: string = route.snapshot.url.join('');
2140 * const user = route.snapshot.data.user;
2141 * }
2142 * }
2143 * ```
2144 *
2145 * \@publicApi
2146 */
2147class ActivatedRouteSnapshot {
2148 /**
2149 * \@internal
2150 * @param {?} url
2151 * @param {?} params
2152 * @param {?} queryParams
2153 * @param {?} fragment
2154 * @param {?} data
2155 * @param {?} outlet
2156 * @param {?} component
2157 * @param {?} routeConfig
2158 * @param {?} urlSegment
2159 * @param {?} lastPathIndex
2160 * @param {?} resolve
2161 */
2162 constructor(url, params, queryParams, fragment, data, outlet, component, routeConfig, urlSegment, lastPathIndex, resolve) {
2163 this.url = url;
2164 this.params = params;
2165 this.queryParams = queryParams;
2166 this.fragment = fragment;
2167 this.data = data;
2168 this.outlet = outlet;
2169 this.component = component;
2170 this.routeConfig = routeConfig;
2171 this._urlSegment = urlSegment;
2172 this._lastPathIndex = lastPathIndex;
2173 this._resolve = resolve;
2174 }
2175 /**
2176 * The root of the router state
2177 * @return {?}
2178 */
2179 get root() { return this._routerState.root; }
2180 /**
2181 * The parent of this route in the router state tree
2182 * @return {?}
2183 */
2184 get parent() { return this._routerState.parent(this); }
2185 /**
2186 * The first child of this route in the router state tree
2187 * @return {?}
2188 */
2189 get firstChild() { return this._routerState.firstChild(this); }
2190 /**
2191 * The children of this route in the router state tree
2192 * @return {?}
2193 */
2194 get children() { return this._routerState.children(this); }
2195 /**
2196 * The path from the root of the router state tree to this route
2197 * @return {?}
2198 */
2199 get pathFromRoot() { return this._routerState.pathFromRoot(this); }
2200 /**
2201 * @return {?}
2202 */
2203 get paramMap() {
2204 if (!this._paramMap) {
2205 this._paramMap = convertToParamMap(this.params);
2206 }
2207 return this._paramMap;
2208 }
2209 /**
2210 * @return {?}
2211 */
2212 get queryParamMap() {
2213 if (!this._queryParamMap) {
2214 this._queryParamMap = convertToParamMap(this.queryParams);
2215 }
2216 return this._queryParamMap;
2217 }
2218 /**
2219 * @return {?}
2220 */
2221 toString() {
2222 /** @type {?} */
2223 const url = this.url.map((/**
2224 * @param {?} segment
2225 * @return {?}
2226 */
2227 segment => segment.toString())).join('/');
2228 /** @type {?} */
2229 const matched = this.routeConfig ? this.routeConfig.path : '';
2230 return `Route(url:'${url}', path:'${matched}')`;
2231 }
2232}
2233/**
2234 * \@description
2235 *
2236 * Represents the state of the router at a moment in time.
2237 *
2238 * This is a tree of activated route snapshots. Every node in this tree knows about
2239 * the "consumed" URL segments, the extracted parameters, and the resolved data.
2240 *
2241 * \@usageNotes
2242 * ### Example
2243 *
2244 * ```
2245 * \@Component({templateUrl:'template.html'})
2246 * class MyComponent {
2247 * constructor(router: Router) {
2248 * const state: RouterState = router.routerState;
2249 * const snapshot: RouterStateSnapshot = state.snapshot;
2250 * const root: ActivatedRouteSnapshot = snapshot.root;
2251 * const child = root.firstChild;
2252 * const id: Observable<string> = child.params.map(p => p.id);
2253 * //...
2254 * }
2255 * }
2256 * ```
2257 *
2258 * \@publicApi
2259 */
2260class RouterStateSnapshot extends Tree {
2261 /**
2262 * \@internal
2263 * @param {?} url
2264 * @param {?} root
2265 */
2266 constructor(url, root) {
2267 super(root);
2268 this.url = url;
2269 setRouterState((/** @type {?} */ (this)), root);
2270 }
2271 /**
2272 * @return {?}
2273 */
2274 toString() { return serializeNode(this._root); }
2275}
2276/**
2277 * @template U, T
2278 * @param {?} state
2279 * @param {?} node
2280 * @return {?}
2281 */
2282function setRouterState(state, node) {
2283 node.value._routerState = state;
2284 node.children.forEach((/**
2285 * @param {?} c
2286 * @return {?}
2287 */
2288 c => setRouterState(state, c)));
2289}
2290/**
2291 * @param {?} node
2292 * @return {?}
2293 */
2294function serializeNode(node) {
2295 /** @type {?} */
2296 const c = node.children.length > 0 ? ` { ${node.children.map(serializeNode).join(', ')} } ` : '';
2297 return `${node.value}${c}`;
2298}
2299/**
2300 * The expectation is that the activate route is created with the right set of parameters.
2301 * So we push new values into the observables only when they are not the initial values.
2302 * And we detect that by checking if the snapshot field is set.
2303 * @param {?} route
2304 * @return {?}
2305 */
2306function advanceActivatedRoute(route) {
2307 if (route.snapshot) {
2308 /** @type {?} */
2309 const currentSnapshot = route.snapshot;
2310 /** @type {?} */
2311 const nextSnapshot = route._futureSnapshot;
2312 route.snapshot = nextSnapshot;
2313 if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) {
2314 ((/** @type {?} */ (route.queryParams))).next(nextSnapshot.queryParams);
2315 }
2316 if (currentSnapshot.fragment !== nextSnapshot.fragment) {
2317 ((/** @type {?} */ (route.fragment))).next(nextSnapshot.fragment);
2318 }
2319 if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
2320 ((/** @type {?} */ (route.params))).next(nextSnapshot.params);
2321 }
2322 if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) {
2323 ((/** @type {?} */ (route.url))).next(nextSnapshot.url);
2324 }
2325 if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) {
2326 ((/** @type {?} */ (route.data))).next(nextSnapshot.data);
2327 }
2328 }
2329 else {
2330 route.snapshot = route._futureSnapshot;
2331 // this is for resolved data
2332 ((/** @type {?} */ (route.data))).next(route._futureSnapshot.data);
2333 }
2334}
2335/**
2336 * @param {?} a
2337 * @param {?} b
2338 * @return {?}
2339 */
2340function equalParamsAndUrlSegments(a, b) {
2341 /** @type {?} */
2342 const equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url);
2343 /** @type {?} */
2344 const parentsMismatch = !a.parent !== !b.parent;
2345 return equalUrlParams && !parentsMismatch &&
2346 (!a.parent || equalParamsAndUrlSegments(a.parent, (/** @type {?} */ (b.parent))));
2347}
2348
2349/**
2350 * @fileoverview added by tsickle
2351 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2352 */
2353/**
2354 * @param {?} routeReuseStrategy
2355 * @param {?} curr
2356 * @param {?} prevState
2357 * @return {?}
2358 */
2359function createRouterState(routeReuseStrategy, curr, prevState) {
2360 /** @type {?} */
2361 const root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : undefined);
2362 return new RouterState(root, curr);
2363}
2364/**
2365 * @param {?} routeReuseStrategy
2366 * @param {?} curr
2367 * @param {?=} prevState
2368 * @return {?}
2369 */
2370function createNode(routeReuseStrategy, curr, prevState) {
2371 // reuse an activated route that is currently displayed on the screen
2372 if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) {
2373 /** @type {?} */
2374 const value = prevState.value;
2375 value._futureSnapshot = curr.value;
2376 /** @type {?} */
2377 const children = createOrReuseChildren(routeReuseStrategy, curr, prevState);
2378 return new TreeNode(value, children);
2379 // retrieve an activated route that is used to be displayed, but is not currently displayed
2380 }
2381 else {
2382 /** @type {?} */
2383 const detachedRouteHandle = (/** @type {?} */ (routeReuseStrategy.retrieve(curr.value)));
2384 if (detachedRouteHandle) {
2385 /** @type {?} */
2386 const tree = detachedRouteHandle.route;
2387 setFutureSnapshotsOfActivatedRoutes(curr, tree);
2388 return tree;
2389 }
2390 else {
2391 /** @type {?} */
2392 const value = createActivatedRoute(curr.value);
2393 /** @type {?} */
2394 const children = curr.children.map((/**
2395 * @param {?} c
2396 * @return {?}
2397 */
2398 c => createNode(routeReuseStrategy, c)));
2399 return new TreeNode(value, children);
2400 }
2401 }
2402}
2403/**
2404 * @param {?} curr
2405 * @param {?} result
2406 * @return {?}
2407 */
2408function setFutureSnapshotsOfActivatedRoutes(curr, result) {
2409 if (curr.value.routeConfig !== result.value.routeConfig) {
2410 throw new Error('Cannot reattach ActivatedRouteSnapshot created from a different route');
2411 }
2412 if (curr.children.length !== result.children.length) {
2413 throw new Error('Cannot reattach ActivatedRouteSnapshot with a different number of children');
2414 }
2415 result.value._futureSnapshot = curr.value;
2416 for (let i = 0; i < curr.children.length; ++i) {
2417 setFutureSnapshotsOfActivatedRoutes(curr.children[i], result.children[i]);
2418 }
2419}
2420/**
2421 * @param {?} routeReuseStrategy
2422 * @param {?} curr
2423 * @param {?} prevState
2424 * @return {?}
2425 */
2426function createOrReuseChildren(routeReuseStrategy, curr, prevState) {
2427 return curr.children.map((/**
2428 * @param {?} child
2429 * @return {?}
2430 */
2431 child => {
2432 for (const p of prevState.children) {
2433 if (routeReuseStrategy.shouldReuseRoute(p.value.snapshot, child.value)) {
2434 return createNode(routeReuseStrategy, child, p);
2435 }
2436 }
2437 return createNode(routeReuseStrategy, child);
2438 }));
2439}
2440/**
2441 * @param {?} c
2442 * @return {?}
2443 */
2444function createActivatedRoute(c) {
2445 return new ActivatedRoute(new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams), new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
2446}
2447
2448/**
2449 * @fileoverview added by tsickle
2450 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2451 */
2452/**
2453 * @param {?} route
2454 * @param {?} urlTree
2455 * @param {?} commands
2456 * @param {?} queryParams
2457 * @param {?} fragment
2458 * @return {?}
2459 */
2460function createUrlTree(route, urlTree, commands, queryParams, fragment) {
2461 if (commands.length === 0) {
2462 return tree(urlTree.root, urlTree.root, urlTree, queryParams, fragment);
2463 }
2464 /** @type {?} */
2465 const nav = computeNavigation(commands);
2466 if (nav.toRoot()) {
2467 return tree(urlTree.root, new UrlSegmentGroup([], {}), urlTree, queryParams, fragment);
2468 }
2469 /** @type {?} */
2470 const startingPosition = findStartingPosition(nav, urlTree, route);
2471 /** @type {?} */
2472 const segmentGroup = startingPosition.processChildren ?
2473 updateSegmentGroupChildren(startingPosition.segmentGroup, startingPosition.index, nav.commands) :
2474 updateSegmentGroup(startingPosition.segmentGroup, startingPosition.index, nav.commands);
2475 return tree(startingPosition.segmentGroup, segmentGroup, urlTree, queryParams, fragment);
2476}
2477/**
2478 * @param {?} command
2479 * @return {?}
2480 */
2481function isMatrixParams(command) {
2482 return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
2483}
2484/**
2485 * @param {?} oldSegmentGroup
2486 * @param {?} newSegmentGroup
2487 * @param {?} urlTree
2488 * @param {?} queryParams
2489 * @param {?} fragment
2490 * @return {?}
2491 */
2492function tree(oldSegmentGroup, newSegmentGroup, urlTree, queryParams, fragment) {
2493 /** @type {?} */
2494 let qp = {};
2495 if (queryParams) {
2496 forEach(queryParams, (/**
2497 * @param {?} value
2498 * @param {?} name
2499 * @return {?}
2500 */
2501 (value, name) => {
2502 qp[name] = Array.isArray(value) ? value.map((/**
2503 * @param {?} v
2504 * @return {?}
2505 */
2506 (v) => `${v}`)) : `${value}`;
2507 }));
2508 }
2509 if (urlTree.root === oldSegmentGroup) {
2510 return new UrlTree(newSegmentGroup, qp, fragment);
2511 }
2512 return new UrlTree(replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), qp, fragment);
2513}
2514/**
2515 * @param {?} current
2516 * @param {?} oldSegment
2517 * @param {?} newSegment
2518 * @return {?}
2519 */
2520function replaceSegment(current, oldSegment, newSegment) {
2521 /** @type {?} */
2522 const children = {};
2523 forEach(current.children, (/**
2524 * @param {?} c
2525 * @param {?} outletName
2526 * @return {?}
2527 */
2528 (c, outletName) => {
2529 if (c === oldSegment) {
2530 children[outletName] = newSegment;
2531 }
2532 else {
2533 children[outletName] = replaceSegment(c, oldSegment, newSegment);
2534 }
2535 }));
2536 return new UrlSegmentGroup(current.segments, children);
2537}
2538class Navigation {
2539 /**
2540 * @param {?} isAbsolute
2541 * @param {?} numberOfDoubleDots
2542 * @param {?} commands
2543 */
2544 constructor(isAbsolute, numberOfDoubleDots, commands) {
2545 this.isAbsolute = isAbsolute;
2546 this.numberOfDoubleDots = numberOfDoubleDots;
2547 this.commands = commands;
2548 if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
2549 throw new Error('Root segment cannot have matrix parameters');
2550 }
2551 /** @type {?} */
2552 const cmdWithOutlet = commands.find((/**
2553 * @param {?} c
2554 * @return {?}
2555 */
2556 c => typeof c === 'object' && c != null && c.outlets));
2557 if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
2558 throw new Error('{outlets:{}} has to be the last command');
2559 }
2560 }
2561 /**
2562 * @return {?}
2563 */
2564 toRoot() {
2565 return this.isAbsolute && this.commands.length === 1 && this.commands[0] == '/';
2566 }
2567}
2568/**
2569 * Transforms commands to a normalized `Navigation`
2570 * @param {?} commands
2571 * @return {?}
2572 */
2573function computeNavigation(commands) {
2574 if ((typeof commands[0] === 'string') && commands.length === 1 && commands[0] === '/') {
2575 return new Navigation(true, 0, commands);
2576 }
2577 /** @type {?} */
2578 let numberOfDoubleDots = 0;
2579 /** @type {?} */
2580 let isAbsolute = false;
2581 /** @type {?} */
2582 const res = commands.reduce((/**
2583 * @param {?} res
2584 * @param {?} cmd
2585 * @param {?} cmdIdx
2586 * @return {?}
2587 */
2588 (res, cmd, cmdIdx) => {
2589 if (typeof cmd === 'object' && cmd != null) {
2590 if (cmd.outlets) {
2591 /** @type {?} */
2592 const outlets = {};
2593 forEach(cmd.outlets, (/**
2594 * @param {?} commands
2595 * @param {?} name
2596 * @return {?}
2597 */
2598 (commands, name) => {
2599 outlets[name] = typeof commands === 'string' ? commands.split('/') : commands;
2600 }));
2601 return [...res, { outlets }];
2602 }
2603 if (cmd.segmentPath) {
2604 return [...res, cmd.segmentPath];
2605 }
2606 }
2607 if (!(typeof cmd === 'string')) {
2608 return [...res, cmd];
2609 }
2610 if (cmdIdx === 0) {
2611 cmd.split('/').forEach((/**
2612 * @param {?} urlPart
2613 * @param {?} partIndex
2614 * @return {?}
2615 */
2616 (urlPart, partIndex) => {
2617 if (partIndex == 0 && urlPart === '.') ;
2618 else if (partIndex == 0 && urlPart === '') { // '/a'
2619 isAbsolute = true;
2620 }
2621 else if (urlPart === '..') { // '../a'
2622 numberOfDoubleDots++;
2623 }
2624 else if (urlPart != '') {
2625 res.push(urlPart);
2626 }
2627 }));
2628 return res;
2629 }
2630 return [...res, cmd];
2631 }), []);
2632 return new Navigation(isAbsolute, numberOfDoubleDots, res);
2633}
2634class Position {
2635 /**
2636 * @param {?} segmentGroup
2637 * @param {?} processChildren
2638 * @param {?} index
2639 */
2640 constructor(segmentGroup, processChildren, index) {
2641 this.segmentGroup = segmentGroup;
2642 this.processChildren = processChildren;
2643 this.index = index;
2644 }
2645}
2646/**
2647 * @param {?} nav
2648 * @param {?} tree
2649 * @param {?} route
2650 * @return {?}
2651 */
2652function findStartingPosition(nav, tree, route) {
2653 if (nav.isAbsolute) {
2654 return new Position(tree.root, true, 0);
2655 }
2656 if (route.snapshot._lastPathIndex === -1) {
2657 return new Position(route.snapshot._urlSegment, true, 0);
2658 }
2659 /** @type {?} */
2660 const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
2661 /** @type {?} */
2662 const index = route.snapshot._lastPathIndex + modifier;
2663 return createPositionApplyingDoubleDots(route.snapshot._urlSegment, index, nav.numberOfDoubleDots);
2664}
2665/**
2666 * @param {?} group
2667 * @param {?} index
2668 * @param {?} numberOfDoubleDots
2669 * @return {?}
2670 */
2671function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
2672 /** @type {?} */
2673 let g = group;
2674 /** @type {?} */
2675 let ci = index;
2676 /** @type {?} */
2677 let dd = numberOfDoubleDots;
2678 while (dd > ci) {
2679 dd -= ci;
2680 g = (/** @type {?} */ (g.parent));
2681 if (!g) {
2682 throw new Error('Invalid number of \'../\'');
2683 }
2684 ci = g.segments.length;
2685 }
2686 return new Position(g, false, ci - dd);
2687}
2688/**
2689 * @param {?} command
2690 * @return {?}
2691 */
2692function getPath(command) {
2693 if (typeof command === 'object' && command != null && command.outlets) {
2694 return command.outlets[PRIMARY_OUTLET];
2695 }
2696 return `${command}`;
2697}
2698/**
2699 * @param {?} commands
2700 * @return {?}
2701 */
2702function getOutlets(commands) {
2703 if (!(typeof commands[0] === 'object'))
2704 return { [PRIMARY_OUTLET]: commands };
2705 if (commands[0].outlets === undefined)
2706 return { [PRIMARY_OUTLET]: commands };
2707 return commands[0].outlets;
2708}
2709/**
2710 * @param {?} segmentGroup
2711 * @param {?} startIndex
2712 * @param {?} commands
2713 * @return {?}
2714 */
2715function updateSegmentGroup(segmentGroup, startIndex, commands) {
2716 if (!segmentGroup) {
2717 segmentGroup = new UrlSegmentGroup([], {});
2718 }
2719 if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
2720 return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
2721 }
2722 /** @type {?} */
2723 const m = prefixedWith(segmentGroup, startIndex, commands);
2724 /** @type {?} */
2725 const slicedCommands = commands.slice(m.commandIndex);
2726 if (m.match && m.pathIndex < segmentGroup.segments.length) {
2727 /** @type {?} */
2728 const g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {});
2729 g.children[PRIMARY_OUTLET] =
2730 new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children);
2731 return updateSegmentGroupChildren(g, 0, slicedCommands);
2732 }
2733 else if (m.match && slicedCommands.length === 0) {
2734 return new UrlSegmentGroup(segmentGroup.segments, {});
2735 }
2736 else if (m.match && !segmentGroup.hasChildren()) {
2737 return createNewSegmentGroup(segmentGroup, startIndex, commands);
2738 }
2739 else if (m.match) {
2740 return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands);
2741 }
2742 else {
2743 return createNewSegmentGroup(segmentGroup, startIndex, commands);
2744 }
2745}
2746/**
2747 * @param {?} segmentGroup
2748 * @param {?} startIndex
2749 * @param {?} commands
2750 * @return {?}
2751 */
2752function updateSegmentGroupChildren(segmentGroup, startIndex, commands) {
2753 if (commands.length === 0) {
2754 return new UrlSegmentGroup(segmentGroup.segments, {});
2755 }
2756 else {
2757 /** @type {?} */
2758 const outlets = getOutlets(commands);
2759 /** @type {?} */
2760 const children = {};
2761 forEach(outlets, (/**
2762 * @param {?} commands
2763 * @param {?} outlet
2764 * @return {?}
2765 */
2766 (commands, outlet) => {
2767 if (commands !== null) {
2768 children[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands);
2769 }
2770 }));
2771 forEach(segmentGroup.children, (/**
2772 * @param {?} child
2773 * @param {?} childOutlet
2774 * @return {?}
2775 */
2776 (child, childOutlet) => {
2777 if (outlets[childOutlet] === undefined) {
2778 children[childOutlet] = child;
2779 }
2780 }));
2781 return new UrlSegmentGroup(segmentGroup.segments, children);
2782 }
2783}
2784/**
2785 * @param {?} segmentGroup
2786 * @param {?} startIndex
2787 * @param {?} commands
2788 * @return {?}
2789 */
2790function prefixedWith(segmentGroup, startIndex, commands) {
2791 /** @type {?} */
2792 let currentCommandIndex = 0;
2793 /** @type {?} */
2794 let currentPathIndex = startIndex;
2795 /** @type {?} */
2796 const noMatch = { match: false, pathIndex: 0, commandIndex: 0 };
2797 while (currentPathIndex < segmentGroup.segments.length) {
2798 if (currentCommandIndex >= commands.length)
2799 return noMatch;
2800 /** @type {?} */
2801 const path = segmentGroup.segments[currentPathIndex];
2802 /** @type {?} */
2803 const curr = getPath(commands[currentCommandIndex]);
2804 /** @type {?} */
2805 const next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
2806 if (currentPathIndex > 0 && curr === undefined)
2807 break;
2808 if (curr && next && (typeof next === 'object') && next.outlets === undefined) {
2809 if (!compare(curr, next, path))
2810 return noMatch;
2811 currentCommandIndex += 2;
2812 }
2813 else {
2814 if (!compare(curr, {}, path))
2815 return noMatch;
2816 currentCommandIndex++;
2817 }
2818 currentPathIndex++;
2819 }
2820 return { match: true, pathIndex: currentPathIndex, commandIndex: currentCommandIndex };
2821}
2822/**
2823 * @param {?} segmentGroup
2824 * @param {?} startIndex
2825 * @param {?} commands
2826 * @return {?}
2827 */
2828function createNewSegmentGroup(segmentGroup, startIndex, commands) {
2829 /** @type {?} */
2830 const paths = segmentGroup.segments.slice(0, startIndex);
2831 /** @type {?} */
2832 let i = 0;
2833 while (i < commands.length) {
2834 if (typeof commands[i] === 'object' && commands[i].outlets !== undefined) {
2835 /** @type {?} */
2836 const children = createNewSegmentChildren(commands[i].outlets);
2837 return new UrlSegmentGroup(paths, children);
2838 }
2839 // if we start with an object literal, we need to reuse the path part from the segment
2840 if (i === 0 && isMatrixParams(commands[0])) {
2841 /** @type {?} */
2842 const p = segmentGroup.segments[startIndex];
2843 paths.push(new UrlSegment(p.path, commands[0]));
2844 i++;
2845 continue;
2846 }
2847 /** @type {?} */
2848 const curr = getPath(commands[i]);
2849 /** @type {?} */
2850 const next = (i < commands.length - 1) ? commands[i + 1] : null;
2851 if (curr && next && isMatrixParams(next)) {
2852 paths.push(new UrlSegment(curr, stringify(next)));
2853 i += 2;
2854 }
2855 else {
2856 paths.push(new UrlSegment(curr, {}));
2857 i++;
2858 }
2859 }
2860 return new UrlSegmentGroup(paths, {});
2861}
2862/**
2863 * @param {?} outlets
2864 * @return {?}
2865 */
2866function createNewSegmentChildren(outlets) {
2867 /** @type {?} */
2868 const children = {};
2869 forEach(outlets, (/**
2870 * @param {?} commands
2871 * @param {?} outlet
2872 * @return {?}
2873 */
2874 (commands, outlet) => {
2875 if (commands !== null) {
2876 children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands);
2877 }
2878 }));
2879 return children;
2880}
2881/**
2882 * @param {?} params
2883 * @return {?}
2884 */
2885function stringify(params) {
2886 /** @type {?} */
2887 const res = {};
2888 forEach(params, (/**
2889 * @param {?} v
2890 * @param {?} k
2891 * @return {?}
2892 */
2893 (v, k) => res[k] = `${v}`));
2894 return res;
2895}
2896/**
2897 * @param {?} path
2898 * @param {?} params
2899 * @param {?} segment
2900 * @return {?}
2901 */
2902function compare(path, params, segment) {
2903 return path == segment.path && shallowEqual(params, segment.parameters);
2904}
2905
2906/**
2907 * @fileoverview added by tsickle
2908 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2909 */
2910/** @type {?} */
2911const activateRoutes = (/**
2912 * @param {?} rootContexts
2913 * @param {?} routeReuseStrategy
2914 * @param {?} forwardEvent
2915 * @return {?}
2916 */
2917(rootContexts, routeReuseStrategy, forwardEvent) => map((/**
2918 * @param {?} t
2919 * @return {?}
2920 */
2921t => {
2922 new ActivateRoutes(routeReuseStrategy, (/** @type {?} */ (t.targetRouterState)), t.currentRouterState, forwardEvent)
2923 .activate(rootContexts);
2924 return t;
2925})));
2926class ActivateRoutes {
2927 /**
2928 * @param {?} routeReuseStrategy
2929 * @param {?} futureState
2930 * @param {?} currState
2931 * @param {?} forwardEvent
2932 */
2933 constructor(routeReuseStrategy, futureState, currState, forwardEvent) {
2934 this.routeReuseStrategy = routeReuseStrategy;
2935 this.futureState = futureState;
2936 this.currState = currState;
2937 this.forwardEvent = forwardEvent;
2938 }
2939 /**
2940 * @param {?} parentContexts
2941 * @return {?}
2942 */
2943 activate(parentContexts) {
2944 /** @type {?} */
2945 const futureRoot = this.futureState._root;
2946 /** @type {?} */
2947 const currRoot = this.currState ? this.currState._root : null;
2948 this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
2949 advanceActivatedRoute(this.futureState.root);
2950 this.activateChildRoutes(futureRoot, currRoot, parentContexts);
2951 }
2952 // De-activate the child route that are not re-used for the future state
2953 /**
2954 * @private
2955 * @param {?} futureNode
2956 * @param {?} currNode
2957 * @param {?} contexts
2958 * @return {?}
2959 */
2960 deactivateChildRoutes(futureNode, currNode, contexts) {
2961 /** @type {?} */
2962 const children = nodeChildrenAsMap(currNode);
2963 // Recurse on the routes active in the future state to de-activate deeper children
2964 futureNode.children.forEach((/**
2965 * @param {?} futureChild
2966 * @return {?}
2967 */
2968 futureChild => {
2969 /** @type {?} */
2970 const childOutletName = futureChild.value.outlet;
2971 this.deactivateRoutes(futureChild, children[childOutletName], contexts);
2972 delete children[childOutletName];
2973 }));
2974 // De-activate the routes that will not be re-used
2975 forEach(children, (/**
2976 * @param {?} v
2977 * @param {?} childName
2978 * @return {?}
2979 */
2980 (v, childName) => {
2981 this.deactivateRouteAndItsChildren(v, contexts);
2982 }));
2983 }
2984 /**
2985 * @private
2986 * @param {?} futureNode
2987 * @param {?} currNode
2988 * @param {?} parentContext
2989 * @return {?}
2990 */
2991 deactivateRoutes(futureNode, currNode, parentContext) {
2992 /** @type {?} */
2993 const future = futureNode.value;
2994 /** @type {?} */
2995 const curr = currNode ? currNode.value : null;
2996 if (future === curr) {
2997 // Reusing the node, check to see if the children need to be de-activated
2998 if (future.component) {
2999 // If we have a normal route, we need to go through an outlet.
3000 /** @type {?} */
3001 const context = parentContext.getContext(future.outlet);
3002 if (context) {
3003 this.deactivateChildRoutes(futureNode, currNode, context.children);
3004 }
3005 }
3006 else {
3007 // if we have a componentless route, we recurse but keep the same outlet map.
3008 this.deactivateChildRoutes(futureNode, currNode, parentContext);
3009 }
3010 }
3011 else {
3012 if (curr) {
3013 // Deactivate the current route which will not be re-used
3014 this.deactivateRouteAndItsChildren(currNode, parentContext);
3015 }
3016 }
3017 }
3018 /**
3019 * @private
3020 * @param {?} route
3021 * @param {?} parentContexts
3022 * @return {?}
3023 */
3024 deactivateRouteAndItsChildren(route, parentContexts) {
3025 if (this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
3026 this.detachAndStoreRouteSubtree(route, parentContexts);
3027 }
3028 else {
3029 this.deactivateRouteAndOutlet(route, parentContexts);
3030 }
3031 }
3032 /**
3033 * @private
3034 * @param {?} route
3035 * @param {?} parentContexts
3036 * @return {?}
3037 */
3038 detachAndStoreRouteSubtree(route, parentContexts) {
3039 /** @type {?} */
3040 const context = parentContexts.getContext(route.value.outlet);
3041 if (context && context.outlet) {
3042 /** @type {?} */
3043 const componentRef = context.outlet.detach();
3044 /** @type {?} */
3045 const contexts = context.children.onOutletDeactivated();
3046 this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts });
3047 }
3048 }
3049 /**
3050 * @private
3051 * @param {?} route
3052 * @param {?} parentContexts
3053 * @return {?}
3054 */
3055 deactivateRouteAndOutlet(route, parentContexts) {
3056 /** @type {?} */
3057 const context = parentContexts.getContext(route.value.outlet);
3058 if (context) {
3059 /** @type {?} */
3060 const children = nodeChildrenAsMap(route);
3061 /** @type {?} */
3062 const contexts = route.value.component ? context.children : parentContexts;
3063 forEach(children, (/**
3064 * @param {?} v
3065 * @param {?} k
3066 * @return {?}
3067 */
3068 (v, k) => this.deactivateRouteAndItsChildren(v, contexts)));
3069 if (context.outlet) {
3070 // Destroy the component
3071 context.outlet.deactivate();
3072 // Destroy the contexts for all the outlets that were in the component
3073 context.children.onOutletDeactivated();
3074 }
3075 }
3076 }
3077 /**
3078 * @private
3079 * @param {?} futureNode
3080 * @param {?} currNode
3081 * @param {?} contexts
3082 * @return {?}
3083 */
3084 activateChildRoutes(futureNode, currNode, contexts) {
3085 /** @type {?} */
3086 const children = nodeChildrenAsMap(currNode);
3087 futureNode.children.forEach((/**
3088 * @param {?} c
3089 * @return {?}
3090 */
3091 c => {
3092 this.activateRoutes(c, children[c.value.outlet], contexts);
3093 this.forwardEvent(new ActivationEnd(c.value.snapshot));
3094 }));
3095 if (futureNode.children.length) {
3096 this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
3097 }
3098 }
3099 /**
3100 * @private
3101 * @param {?} futureNode
3102 * @param {?} currNode
3103 * @param {?} parentContexts
3104 * @return {?}
3105 */
3106 activateRoutes(futureNode, currNode, parentContexts) {
3107 /** @type {?} */
3108 const future = futureNode.value;
3109 /** @type {?} */
3110 const curr = currNode ? currNode.value : null;
3111 advanceActivatedRoute(future);
3112 // reusing the node
3113 if (future === curr) {
3114 if (future.component) {
3115 // If we have a normal route, we need to go through an outlet.
3116 /** @type {?} */
3117 const context = parentContexts.getOrCreateContext(future.outlet);
3118 this.activateChildRoutes(futureNode, currNode, context.children);
3119 }
3120 else {
3121 // if we have a componentless route, we recurse but keep the same outlet map.
3122 this.activateChildRoutes(futureNode, currNode, parentContexts);
3123 }
3124 }
3125 else {
3126 if (future.component) {
3127 // if we have a normal route, we need to place the component into the outlet and recurse.
3128 /** @type {?} */
3129 const context = parentContexts.getOrCreateContext(future.outlet);
3130 if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
3131 /** @type {?} */
3132 const stored = ((/** @type {?} */ (this.routeReuseStrategy.retrieve(future.snapshot))));
3133 this.routeReuseStrategy.store(future.snapshot, null);
3134 context.children.onOutletReAttached(stored.contexts);
3135 context.attachRef = stored.componentRef;
3136 context.route = stored.route.value;
3137 if (context.outlet) {
3138 // Attach right away when the outlet has already been instantiated
3139 // Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
3140 context.outlet.attach(stored.componentRef, stored.route.value);
3141 }
3142 advanceActivatedRouteNodeAndItsChildren(stored.route);
3143 }
3144 else {
3145 /** @type {?} */
3146 const config = parentLoadedConfig(future.snapshot);
3147 /** @type {?} */
3148 const cmpFactoryResolver = config ? config.module.componentFactoryResolver : null;
3149 context.attachRef = null;
3150 context.route = future;
3151 context.resolver = cmpFactoryResolver;
3152 if (context.outlet) {
3153 // Activate the outlet when it has already been instantiated
3154 // Otherwise it will get activated from its `ngOnInit` when instantiated
3155 context.outlet.activateWith(future, cmpFactoryResolver);
3156 }
3157 this.activateChildRoutes(futureNode, null, context.children);
3158 }
3159 }
3160 else {
3161 // if we have a componentless route, we recurse but keep the same outlet map.
3162 this.activateChildRoutes(futureNode, null, parentContexts);
3163 }
3164 }
3165 }
3166}
3167/**
3168 * @param {?} node
3169 * @return {?}
3170 */
3171function advanceActivatedRouteNodeAndItsChildren(node) {
3172 advanceActivatedRoute(node.value);
3173 node.children.forEach(advanceActivatedRouteNodeAndItsChildren);
3174}
3175/**
3176 * @param {?} snapshot
3177 * @return {?}
3178 */
3179function parentLoadedConfig(snapshot) {
3180 for (let s = snapshot.parent; s; s = s.parent) {
3181 /** @type {?} */
3182 const route = s.routeConfig;
3183 if (route && route._loadedConfig)
3184 return route._loadedConfig;
3185 if (route && route.component)
3186 return null;
3187 }
3188 return null;
3189}
3190
3191/**
3192 * @fileoverview added by tsickle
3193 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3194 */
3195/**
3196 * Simple function check, but generic so type inference will flow. Example:
3197 *
3198 * function product(a: number, b: number) {
3199 * return a * b;
3200 * }
3201 *
3202 * if (isFunction<product>(fn)) {
3203 * return fn(1, 2);
3204 * } else {
3205 * throw "Must provide the `product` function";
3206 * }
3207 * @template T
3208 * @param {?} v
3209 * @return {?}
3210 */
3211function isFunction(v) {
3212 return typeof v === 'function';
3213}
3214/**
3215 * @param {?} v
3216 * @return {?}
3217 */
3218function isBoolean(v) {
3219 return typeof v === 'boolean';
3220}
3221/**
3222 * @param {?} v
3223 * @return {?}
3224 */
3225function isUrlTree(v) {
3226 return v instanceof UrlTree;
3227}
3228/**
3229 * @param {?} guard
3230 * @return {?}
3231 */
3232function isCanLoad(guard) {
3233 return guard && isFunction(guard.canLoad);
3234}
3235/**
3236 * @param {?} guard
3237 * @return {?}
3238 */
3239function isCanActivate(guard) {
3240 return guard && isFunction(guard.canActivate);
3241}
3242/**
3243 * @param {?} guard
3244 * @return {?}
3245 */
3246function isCanActivateChild(guard) {
3247 return guard && isFunction(guard.canActivateChild);
3248}
3249/**
3250 * @template T
3251 * @param {?} guard
3252 * @return {?}
3253 */
3254function isCanDeactivate(guard) {
3255 return guard && isFunction(guard.canDeactivate);
3256}
3257
3258/**
3259 * @fileoverview added by tsickle
3260 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3261 */
3262class NoMatch {
3263 /**
3264 * @param {?=} segmentGroup
3265 */
3266 constructor(segmentGroup) { this.segmentGroup = segmentGroup || null; }
3267}
3268class AbsoluteRedirect {
3269 /**
3270 * @param {?} urlTree
3271 */
3272 constructor(urlTree) {
3273 this.urlTree = urlTree;
3274 }
3275}
3276/**
3277 * @param {?} segmentGroup
3278 * @return {?}
3279 */
3280function noMatch(segmentGroup) {
3281 return new Observable((/**
3282 * @param {?} obs
3283 * @return {?}
3284 */
3285 (obs) => obs.error(new NoMatch(segmentGroup))));
3286}
3287/**
3288 * @param {?} newTree
3289 * @return {?}
3290 */
3291function absoluteRedirect(newTree) {
3292 return new Observable((/**
3293 * @param {?} obs
3294 * @return {?}
3295 */
3296 (obs) => obs.error(new AbsoluteRedirect(newTree))));
3297}
3298/**
3299 * @param {?} redirectTo
3300 * @return {?}
3301 */
3302function namedOutletsRedirect(redirectTo) {
3303 return new Observable((/**
3304 * @param {?} obs
3305 * @return {?}
3306 */
3307 (obs) => obs.error(new Error(`Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`))));
3308}
3309/**
3310 * @param {?} route
3311 * @return {?}
3312 */
3313function canLoadFails(route) {
3314 return new Observable((/**
3315 * @param {?} obs
3316 * @return {?}
3317 */
3318 (obs) => obs.error(navigationCancelingError(`Cannot load children because the guard of the route "path: '${route.path}'" returned false`))));
3319}
3320/**
3321 * Returns the `UrlTree` with the redirection applied.
3322 *
3323 * Lazy modules are loaded along the way.
3324 * @param {?} moduleInjector
3325 * @param {?} configLoader
3326 * @param {?} urlSerializer
3327 * @param {?} urlTree
3328 * @param {?} config
3329 * @return {?}
3330 */
3331function applyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config) {
3332 return new ApplyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config).apply();
3333}
3334class ApplyRedirects {
3335 /**
3336 * @param {?} moduleInjector
3337 * @param {?} configLoader
3338 * @param {?} urlSerializer
3339 * @param {?} urlTree
3340 * @param {?} config
3341 */
3342 constructor(moduleInjector, configLoader, urlSerializer, urlTree, config) {
3343 this.configLoader = configLoader;
3344 this.urlSerializer = urlSerializer;
3345 this.urlTree = urlTree;
3346 this.config = config;
3347 this.allowRedirects = true;
3348 this.ngModule = moduleInjector.get(NgModuleRef);
3349 }
3350 /**
3351 * @return {?}
3352 */
3353 apply() {
3354 /** @type {?} */
3355 const expanded$ = this.expandSegmentGroup(this.ngModule, this.config, this.urlTree.root, PRIMARY_OUTLET);
3356 /** @type {?} */
3357 const urlTrees$ = expanded$.pipe(map((/**
3358 * @param {?} rootSegmentGroup
3359 * @return {?}
3360 */
3361 (rootSegmentGroup) => this.createUrlTree(rootSegmentGroup, this.urlTree.queryParams, (/** @type {?} */ (this.urlTree.fragment))))));
3362 return urlTrees$.pipe(catchError((/**
3363 * @param {?} e
3364 * @return {?}
3365 */
3366 (e) => {
3367 if (e instanceof AbsoluteRedirect) {
3368 // after an absolute redirect we do not apply any more redirects!
3369 this.allowRedirects = false;
3370 // we need to run matching, so we can fetch all lazy-loaded modules
3371 return this.match(e.urlTree);
3372 }
3373 if (e instanceof NoMatch) {
3374 throw this.noMatchError(e);
3375 }
3376 throw e;
3377 })));
3378 }
3379 /**
3380 * @private
3381 * @param {?} tree
3382 * @return {?}
3383 */
3384 match(tree) {
3385 /** @type {?} */
3386 const expanded$ = this.expandSegmentGroup(this.ngModule, this.config, tree.root, PRIMARY_OUTLET);
3387 /** @type {?} */
3388 const mapped$ = expanded$.pipe(map((/**
3389 * @param {?} rootSegmentGroup
3390 * @return {?}
3391 */
3392 (rootSegmentGroup) => this.createUrlTree(rootSegmentGroup, tree.queryParams, (/** @type {?} */ (tree.fragment))))));
3393 return mapped$.pipe(catchError((/**
3394 * @param {?} e
3395 * @return {?}
3396 */
3397 (e) => {
3398 if (e instanceof NoMatch) {
3399 throw this.noMatchError(e);
3400 }
3401 throw e;
3402 })));
3403 }
3404 /**
3405 * @private
3406 * @param {?} e
3407 * @return {?}
3408 */
3409 noMatchError(e) {
3410 return new Error(`Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3411 }
3412 /**
3413 * @private
3414 * @param {?} rootCandidate
3415 * @param {?} queryParams
3416 * @param {?} fragment
3417 * @return {?}
3418 */
3419 createUrlTree(rootCandidate, queryParams, fragment) {
3420 /** @type {?} */
3421 const root = rootCandidate.segments.length > 0 ?
3422 new UrlSegmentGroup([], { [PRIMARY_OUTLET]: rootCandidate }) :
3423 rootCandidate;
3424 return new UrlTree(root, queryParams, fragment);
3425 }
3426 /**
3427 * @private
3428 * @param {?} ngModule
3429 * @param {?} routes
3430 * @param {?} segmentGroup
3431 * @param {?} outlet
3432 * @return {?}
3433 */
3434 expandSegmentGroup(ngModule, routes, segmentGroup, outlet) {
3435 if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
3436 return this.expandChildren(ngModule, routes, segmentGroup)
3437 .pipe(map((/**
3438 * @param {?} children
3439 * @return {?}
3440 */
3441 (children) => new UrlSegmentGroup([], children))));
3442 }
3443 return this.expandSegment(ngModule, segmentGroup, routes, segmentGroup.segments, outlet, true);
3444 }
3445 // Recursively expand segment groups for all the child outlets
3446 /**
3447 * @private
3448 * @param {?} ngModule
3449 * @param {?} routes
3450 * @param {?} segmentGroup
3451 * @return {?}
3452 */
3453 expandChildren(ngModule, routes, segmentGroup) {
3454 return waitForMap(segmentGroup.children, (/**
3455 * @param {?} childOutlet
3456 * @param {?} child
3457 * @return {?}
3458 */
3459 (childOutlet, child) => this.expandSegmentGroup(ngModule, routes, child, childOutlet)));
3460 }
3461 /**
3462 * @private
3463 * @param {?} ngModule
3464 * @param {?} segmentGroup
3465 * @param {?} routes
3466 * @param {?} segments
3467 * @param {?} outlet
3468 * @param {?} allowRedirects
3469 * @return {?}
3470 */
3471 expandSegment(ngModule, segmentGroup, routes, segments, outlet, allowRedirects) {
3472 return of(...routes).pipe(map((/**
3473 * @param {?} r
3474 * @return {?}
3475 */
3476 (r) => {
3477 /** @type {?} */
3478 const expanded$ = this.expandSegmentAgainstRoute(ngModule, segmentGroup, routes, r, segments, outlet, allowRedirects);
3479 return expanded$.pipe(catchError((/**
3480 * @param {?} e
3481 * @return {?}
3482 */
3483 (e) => {
3484 if (e instanceof NoMatch) {
3485 // TODO(i): this return type doesn't match the declared Observable<UrlSegmentGroup> -
3486 // talk to Jason
3487 return (/** @type {?} */ (of(null)));
3488 }
3489 throw e;
3490 })));
3491 })), concatAll(), first((/**
3492 * @param {?} s
3493 * @return {?}
3494 */
3495 (s) => !!s)), catchError((/**
3496 * @param {?} e
3497 * @param {?} _
3498 * @return {?}
3499 */
3500 (e, _) => {
3501 if (e instanceof EmptyError || e.name === 'EmptyError') {
3502 if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
3503 return of(new UrlSegmentGroup([], {}));
3504 }
3505 throw new NoMatch(segmentGroup);
3506 }
3507 throw e;
3508 })));
3509 }
3510 /**
3511 * @private
3512 * @param {?} segmentGroup
3513 * @param {?} segments
3514 * @param {?} outlet
3515 * @return {?}
3516 */
3517 noLeftoversInUrl(segmentGroup, segments, outlet) {
3518 return segments.length === 0 && !segmentGroup.children[outlet];
3519 }
3520 /**
3521 * @private
3522 * @param {?} ngModule
3523 * @param {?} segmentGroup
3524 * @param {?} routes
3525 * @param {?} route
3526 * @param {?} paths
3527 * @param {?} outlet
3528 * @param {?} allowRedirects
3529 * @return {?}
3530 */
3531 expandSegmentAgainstRoute(ngModule, segmentGroup, routes, route, paths, outlet, allowRedirects) {
3532 if (getOutlet(route) !== outlet) {
3533 return noMatch(segmentGroup);
3534 }
3535 if (route.redirectTo === undefined) {
3536 return this.matchSegmentAgainstRoute(ngModule, segmentGroup, route, paths);
3537 }
3538 if (allowRedirects && this.allowRedirects) {
3539 return this.expandSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, paths, outlet);
3540 }
3541 return noMatch(segmentGroup);
3542 }
3543 /**
3544 * @private
3545 * @param {?} ngModule
3546 * @param {?} segmentGroup
3547 * @param {?} routes
3548 * @param {?} route
3549 * @param {?} segments
3550 * @param {?} outlet
3551 * @return {?}
3552 */
3553 expandSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet) {
3554 if (route.path === '**') {
3555 return this.expandWildCardWithParamsAgainstRouteUsingRedirect(ngModule, routes, route, outlet);
3556 }
3557 return this.expandRegularSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet);
3558 }
3559 /**
3560 * @private
3561 * @param {?} ngModule
3562 * @param {?} routes
3563 * @param {?} route
3564 * @param {?} outlet
3565 * @return {?}
3566 */
3567 expandWildCardWithParamsAgainstRouteUsingRedirect(ngModule, routes, route, outlet) {
3568 /** @type {?} */
3569 const newTree = this.applyRedirectCommands([], (/** @type {?} */ (route.redirectTo)), {});
3570 if ((/** @type {?} */ (route.redirectTo)).startsWith('/')) {
3571 return absoluteRedirect(newTree);
3572 }
3573 return this.lineralizeSegments(route, newTree).pipe(mergeMap((/**
3574 * @param {?} newSegments
3575 * @return {?}
3576 */
3577 (newSegments) => {
3578 /** @type {?} */
3579 const group = new UrlSegmentGroup(newSegments, {});
3580 return this.expandSegment(ngModule, group, routes, newSegments, outlet, false);
3581 })));
3582 }
3583 /**
3584 * @private
3585 * @param {?} ngModule
3586 * @param {?} segmentGroup
3587 * @param {?} routes
3588 * @param {?} route
3589 * @param {?} segments
3590 * @param {?} outlet
3591 * @return {?}
3592 */
3593 expandRegularSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet) {
3594 const { matched, consumedSegments, lastChild, positionalParamSegments } = match(segmentGroup, route, segments);
3595 if (!matched)
3596 return noMatch(segmentGroup);
3597 /** @type {?} */
3598 const newTree = this.applyRedirectCommands(consumedSegments, (/** @type {?} */ (route.redirectTo)), (/** @type {?} */ (positionalParamSegments)));
3599 if ((/** @type {?} */ (route.redirectTo)).startsWith('/')) {
3600 return absoluteRedirect(newTree);
3601 }
3602 return this.lineralizeSegments(route, newTree).pipe(mergeMap((/**
3603 * @param {?} newSegments
3604 * @return {?}
3605 */
3606 (newSegments) => {
3607 return this.expandSegment(ngModule, segmentGroup, routes, newSegments.concat(segments.slice(lastChild)), outlet, false);
3608 })));
3609 }
3610 /**
3611 * @private
3612 * @param {?} ngModule
3613 * @param {?} rawSegmentGroup
3614 * @param {?} route
3615 * @param {?} segments
3616 * @return {?}
3617 */
3618 matchSegmentAgainstRoute(ngModule, rawSegmentGroup, route, segments) {
3619 if (route.path === '**') {
3620 if (route.loadChildren) {
3621 return this.configLoader.load(ngModule.injector, route)
3622 .pipe(map((/**
3623 * @param {?} cfg
3624 * @return {?}
3625 */
3626 (cfg) => {
3627 route._loadedConfig = cfg;
3628 return new UrlSegmentGroup(segments, {});
3629 })));
3630 }
3631 return of(new UrlSegmentGroup(segments, {}));
3632 }
3633 const { matched, consumedSegments, lastChild } = match(rawSegmentGroup, route, segments);
3634 if (!matched)
3635 return noMatch(rawSegmentGroup);
3636 /** @type {?} */
3637 const rawSlicedSegments = segments.slice(lastChild);
3638 /** @type {?} */
3639 const childConfig$ = this.getChildConfig(ngModule, route, segments);
3640 return childConfig$.pipe(mergeMap((/**
3641 * @param {?} routerConfig
3642 * @return {?}
3643 */
3644 (routerConfig) => {
3645 /** @type {?} */
3646 const childModule = routerConfig.module;
3647 /** @type {?} */
3648 const childConfig = routerConfig.routes;
3649 const { segmentGroup, slicedSegments } = split(rawSegmentGroup, consumedSegments, rawSlicedSegments, childConfig);
3650 if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
3651 /** @type {?} */
3652 const expanded$ = this.expandChildren(childModule, childConfig, segmentGroup);
3653 return expanded$.pipe(map((/**
3654 * @param {?} children
3655 * @return {?}
3656 */
3657 (children) => new UrlSegmentGroup(consumedSegments, children))));
3658 }
3659 if (childConfig.length === 0 && slicedSegments.length === 0) {
3660 return of(new UrlSegmentGroup(consumedSegments, {}));
3661 }
3662 /** @type {?} */
3663 const expanded$ = this.expandSegment(childModule, segmentGroup, childConfig, slicedSegments, PRIMARY_OUTLET, true);
3664 return expanded$.pipe(map((/**
3665 * @param {?} cs
3666 * @return {?}
3667 */
3668 (cs) => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children))));
3669 })));
3670 }
3671 /**
3672 * @private
3673 * @param {?} ngModule
3674 * @param {?} route
3675 * @param {?} segments
3676 * @return {?}
3677 */
3678 getChildConfig(ngModule, route, segments) {
3679 if (route.children) {
3680 // The children belong to the same module
3681 return of(new LoadedRouterConfig(route.children, ngModule));
3682 }
3683 if (route.loadChildren) {
3684 // lazy children belong to the loaded module
3685 if (route._loadedConfig !== undefined) {
3686 return of(route._loadedConfig);
3687 }
3688 return runCanLoadGuard(ngModule.injector, route, segments)
3689 .pipe(mergeMap((/**
3690 * @param {?} shouldLoad
3691 * @return {?}
3692 */
3693 (shouldLoad) => {
3694 if (shouldLoad) {
3695 return this.configLoader.load(ngModule.injector, route)
3696 .pipe(map((/**
3697 * @param {?} cfg
3698 * @return {?}
3699 */
3700 (cfg) => {
3701 route._loadedConfig = cfg;
3702 return cfg;
3703 })));
3704 }
3705 return canLoadFails(route);
3706 })));
3707 }
3708 return of(new LoadedRouterConfig([], ngModule));
3709 }
3710 /**
3711 * @private
3712 * @param {?} route
3713 * @param {?} urlTree
3714 * @return {?}
3715 */
3716 lineralizeSegments(route, urlTree) {
3717 /** @type {?} */
3718 let res = [];
3719 /** @type {?} */
3720 let c = urlTree.root;
3721 while (true) {
3722 res = res.concat(c.segments);
3723 if (c.numberOfChildren === 0) {
3724 return of(res);
3725 }
3726 if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
3727 return namedOutletsRedirect((/** @type {?} */ (route.redirectTo)));
3728 }
3729 c = c.children[PRIMARY_OUTLET];
3730 }
3731 }
3732 /**
3733 * @private
3734 * @param {?} segments
3735 * @param {?} redirectTo
3736 * @param {?} posParams
3737 * @return {?}
3738 */
3739 applyRedirectCommands(segments, redirectTo, posParams) {
3740 return this.applyRedirectCreatreUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
3741 }
3742 /**
3743 * @private
3744 * @param {?} redirectTo
3745 * @param {?} urlTree
3746 * @param {?} segments
3747 * @param {?} posParams
3748 * @return {?}
3749 */
3750 applyRedirectCreatreUrlTree(redirectTo, urlTree, segments, posParams) {
3751 /** @type {?} */
3752 const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
3753 return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
3754 }
3755 /**
3756 * @private
3757 * @param {?} redirectToParams
3758 * @param {?} actualParams
3759 * @return {?}
3760 */
3761 createQueryParams(redirectToParams, actualParams) {
3762 /** @type {?} */
3763 const res = {};
3764 forEach(redirectToParams, (/**
3765 * @param {?} v
3766 * @param {?} k
3767 * @return {?}
3768 */
3769 (v, k) => {
3770 /** @type {?} */
3771 const copySourceValue = typeof v === 'string' && v.startsWith(':');
3772 if (copySourceValue) {
3773 /** @type {?} */
3774 const sourceName = v.substring(1);
3775 res[k] = actualParams[sourceName];
3776 }
3777 else {
3778 res[k] = v;
3779 }
3780 }));
3781 return res;
3782 }
3783 /**
3784 * @private
3785 * @param {?} redirectTo
3786 * @param {?} group
3787 * @param {?} segments
3788 * @param {?} posParams
3789 * @return {?}
3790 */
3791 createSegmentGroup(redirectTo, group, segments, posParams) {
3792 /** @type {?} */
3793 const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
3794 /** @type {?} */
3795 let children = {};
3796 forEach(group.children, (/**
3797 * @param {?} child
3798 * @param {?} name
3799 * @return {?}
3800 */
3801 (child, name) => {
3802 children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
3803 }));
3804 return new UrlSegmentGroup(updatedSegments, children);
3805 }
3806 /**
3807 * @private
3808 * @param {?} redirectTo
3809 * @param {?} redirectToSegments
3810 * @param {?} actualSegments
3811 * @param {?} posParams
3812 * @return {?}
3813 */
3814 createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
3815 return redirectToSegments.map((/**
3816 * @param {?} s
3817 * @return {?}
3818 */
3819 s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) :
3820 this.findOrReturn(s, actualSegments)));
3821 }
3822 /**
3823 * @private
3824 * @param {?} redirectTo
3825 * @param {?} redirectToUrlSegment
3826 * @param {?} posParams
3827 * @return {?}
3828 */
3829 findPosParam(redirectTo, redirectToUrlSegment, posParams) {
3830 /** @type {?} */
3831 const pos = posParams[redirectToUrlSegment.path.substring(1)];
3832 if (!pos)
3833 throw new Error(`Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
3834 return pos;
3835 }
3836 /**
3837 * @private
3838 * @param {?} redirectToUrlSegment
3839 * @param {?} actualSegments
3840 * @return {?}
3841 */
3842 findOrReturn(redirectToUrlSegment, actualSegments) {
3843 /** @type {?} */
3844 let idx = 0;
3845 for (const s of actualSegments) {
3846 if (s.path === redirectToUrlSegment.path) {
3847 actualSegments.splice(idx);
3848 return s;
3849 }
3850 idx++;
3851 }
3852 return redirectToUrlSegment;
3853 }
3854}
3855/**
3856 * @param {?} moduleInjector
3857 * @param {?} route
3858 * @param {?} segments
3859 * @return {?}
3860 */
3861function runCanLoadGuard(moduleInjector, route, segments) {
3862 /** @type {?} */
3863 const canLoad = route.canLoad;
3864 if (!canLoad || canLoad.length === 0)
3865 return of(true);
3866 /** @type {?} */
3867 const obs = from(canLoad).pipe(map((/**
3868 * @param {?} injectionToken
3869 * @return {?}
3870 */
3871 (injectionToken) => {
3872 /** @type {?} */
3873 const guard = moduleInjector.get(injectionToken);
3874 /** @type {?} */
3875 let guardVal;
3876 if (isCanLoad(guard)) {
3877 guardVal = guard.canLoad(route, segments);
3878 }
3879 else if (isFunction(guard)) {
3880 guardVal = guard(route, segments);
3881 }
3882 else {
3883 throw new Error('Invalid CanLoad guard');
3884 }
3885 return wrapIntoObservable(guardVal);
3886 })));
3887 return obs.pipe(concatAll(), every((/**
3888 * @param {?} result
3889 * @return {?}
3890 */
3891 result => result === true)));
3892}
3893/**
3894 * @param {?} segmentGroup
3895 * @param {?} route
3896 * @param {?} segments
3897 * @return {?}
3898 */
3899function match(segmentGroup, route, segments) {
3900 if (route.path === '') {
3901 if ((route.pathMatch === 'full') && (segmentGroup.hasChildren() || segments.length > 0)) {
3902 return { matched: false, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
3903 }
3904 return { matched: true, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
3905 }
3906 /** @type {?} */
3907 const matcher = route.matcher || defaultUrlMatcher;
3908 /** @type {?} */
3909 const res = matcher(segments, segmentGroup, route);
3910 if (!res) {
3911 return {
3912 matched: false,
3913 consumedSegments: (/** @type {?} */ ([])),
3914 lastChild: 0,
3915 positionalParamSegments: {},
3916 };
3917 }
3918 return {
3919 matched: true,
3920 consumedSegments: (/** @type {?} */ (res.consumed)),
3921 lastChild: (/** @type {?} */ (res.consumed.length)),
3922 positionalParamSegments: (/** @type {?} */ (res.posParams)),
3923 };
3924}
3925/**
3926 * @param {?} segmentGroup
3927 * @param {?} consumedSegments
3928 * @param {?} slicedSegments
3929 * @param {?} config
3930 * @return {?}
3931 */
3932function split(segmentGroup, consumedSegments, slicedSegments, config) {
3933 if (slicedSegments.length > 0 &&
3934 containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, slicedSegments, config)) {
3935 /** @type {?} */
3936 const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptySegments(config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
3937 return { segmentGroup: mergeTrivialChildren(s), slicedSegments: [] };
3938 }
3939 if (slicedSegments.length === 0 &&
3940 containsEmptyPathRedirects(segmentGroup, slicedSegments, config)) {
3941 /** @type {?} */
3942 const s = new UrlSegmentGroup(segmentGroup.segments, addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, config, segmentGroup.children));
3943 return { segmentGroup: mergeTrivialChildren(s), slicedSegments };
3944 }
3945 return { segmentGroup, slicedSegments };
3946}
3947/**
3948 * @param {?} s
3949 * @return {?}
3950 */
3951function mergeTrivialChildren(s) {
3952 if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) {
3953 /** @type {?} */
3954 const c = s.children[PRIMARY_OUTLET];
3955 return new UrlSegmentGroup(s.segments.concat(c.segments), c.children);
3956 }
3957 return s;
3958}
3959/**
3960 * @param {?} segmentGroup
3961 * @param {?} slicedSegments
3962 * @param {?} routes
3963 * @param {?} children
3964 * @return {?}
3965 */
3966function addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, routes, children) {
3967 /** @type {?} */
3968 const res = {};
3969 for (const r of routes) {
3970 if (isEmptyPathRedirect(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
3971 res[getOutlet(r)] = new UrlSegmentGroup([], {});
3972 }
3973 }
3974 return Object.assign({}, children, res);
3975}
3976/**
3977 * @param {?} routes
3978 * @param {?} primarySegmentGroup
3979 * @return {?}
3980 */
3981function createChildrenForEmptySegments(routes, primarySegmentGroup) {
3982 /** @type {?} */
3983 const res = {};
3984 res[PRIMARY_OUTLET] = primarySegmentGroup;
3985 for (const r of routes) {
3986 if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) {
3987 res[getOutlet(r)] = new UrlSegmentGroup([], {});
3988 }
3989 }
3990 return res;
3991}
3992/**
3993 * @param {?} segmentGroup
3994 * @param {?} segments
3995 * @param {?} routes
3996 * @return {?}
3997 */
3998function containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, segments, routes) {
3999 return routes.some((/**
4000 * @param {?} r
4001 * @return {?}
4002 */
4003 r => isEmptyPathRedirect(segmentGroup, segments, r) && getOutlet(r) !== PRIMARY_OUTLET));
4004}
4005/**
4006 * @param {?} segmentGroup
4007 * @param {?} segments
4008 * @param {?} routes
4009 * @return {?}
4010 */
4011function containsEmptyPathRedirects(segmentGroup, segments, routes) {
4012 return routes.some((/**
4013 * @param {?} r
4014 * @return {?}
4015 */
4016 r => isEmptyPathRedirect(segmentGroup, segments, r)));
4017}
4018/**
4019 * @param {?} segmentGroup
4020 * @param {?} segments
4021 * @param {?} r
4022 * @return {?}
4023 */
4024function isEmptyPathRedirect(segmentGroup, segments, r) {
4025 if ((segmentGroup.hasChildren() || segments.length > 0) && r.pathMatch === 'full') {
4026 return false;
4027 }
4028 return r.path === '' && r.redirectTo !== undefined;
4029}
4030/**
4031 * @param {?} route
4032 * @return {?}
4033 */
4034function getOutlet(route) {
4035 return route.outlet || PRIMARY_OUTLET;
4036}
4037
4038/**
4039 * @fileoverview added by tsickle
4040 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4041 */
4042/**
4043 * @param {?} moduleInjector
4044 * @param {?} configLoader
4045 * @param {?} urlSerializer
4046 * @param {?} config
4047 * @return {?}
4048 */
4049function applyRedirects$1(moduleInjector, configLoader, urlSerializer, config) {
4050 return (/**
4051 * @param {?} source
4052 * @return {?}
4053 */
4054 function (source) {
4055 return source.pipe(switchMap((/**
4056 * @param {?} t
4057 * @return {?}
4058 */
4059 t => applyRedirects(moduleInjector, configLoader, urlSerializer, t.extractedUrl, config)
4060 .pipe(map((/**
4061 * @param {?} urlAfterRedirects
4062 * @return {?}
4063 */
4064 urlAfterRedirects => (Object.assign({}, t, { urlAfterRedirects }))))))));
4065 });
4066}
4067
4068/**
4069 * @fileoverview added by tsickle
4070 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4071 */
4072class CanActivate {
4073 /**
4074 * @param {?} path
4075 */
4076 constructor(path) {
4077 this.path = path;
4078 this.route = this.path[this.path.length - 1];
4079 }
4080}
4081class CanDeactivate {
4082 /**
4083 * @param {?} component
4084 * @param {?} route
4085 */
4086 constructor(component, route) {
4087 this.component = component;
4088 this.route = route;
4089 }
4090}
4091/**
4092 * @param {?} future
4093 * @param {?} curr
4094 * @param {?} parentContexts
4095 * @return {?}
4096 */
4097function getAllRouteGuards(future, curr, parentContexts) {
4098 /** @type {?} */
4099 const futureRoot = future._root;
4100 /** @type {?} */
4101 const currRoot = curr ? curr._root : null;
4102 return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
4103}
4104/**
4105 * @param {?} p
4106 * @return {?}
4107 */
4108function getCanActivateChild(p) {
4109 /** @type {?} */
4110 const canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
4111 if (!canActivateChild || canActivateChild.length === 0)
4112 return null;
4113 return { node: p, guards: canActivateChild };
4114}
4115/**
4116 * @param {?} token
4117 * @param {?} snapshot
4118 * @param {?} moduleInjector
4119 * @return {?}
4120 */
4121function getToken(token, snapshot, moduleInjector) {
4122 /** @type {?} */
4123 const config = getClosestLoadedConfig(snapshot);
4124 /** @type {?} */
4125 const injector = config ? config.module.injector : moduleInjector;
4126 return injector.get(token);
4127}
4128/**
4129 * @param {?} snapshot
4130 * @return {?}
4131 */
4132function getClosestLoadedConfig(snapshot) {
4133 if (!snapshot)
4134 return null;
4135 for (let s = snapshot.parent; s; s = s.parent) {
4136 /** @type {?} */
4137 const route = s.routeConfig;
4138 if (route && route._loadedConfig)
4139 return route._loadedConfig;
4140 }
4141 return null;
4142}
4143/**
4144 * @param {?} futureNode
4145 * @param {?} currNode
4146 * @param {?} contexts
4147 * @param {?} futurePath
4148 * @param {?=} checks
4149 * @return {?}
4150 */
4151function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
4152 canDeactivateChecks: [],
4153 canActivateChecks: []
4154}) {
4155 /** @type {?} */
4156 const prevChildren = nodeChildrenAsMap(currNode);
4157 // Process the children of the future route
4158 futureNode.children.forEach((/**
4159 * @param {?} c
4160 * @return {?}
4161 */
4162 c => {
4163 getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks);
4164 delete prevChildren[c.value.outlet];
4165 }));
4166 // Process any children left from the current route (not active for the future route)
4167 forEach(prevChildren, (/**
4168 * @param {?} v
4169 * @param {?} k
4170 * @return {?}
4171 */
4172 (v, k) => deactivateRouteAndItsChildren(v, (/** @type {?} */ (contexts)).getContext(k), checks)));
4173 return checks;
4174}
4175/**
4176 * @param {?} futureNode
4177 * @param {?} currNode
4178 * @param {?} parentContexts
4179 * @param {?} futurePath
4180 * @param {?=} checks
4181 * @return {?}
4182 */
4183function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks = {
4184 canDeactivateChecks: [],
4185 canActivateChecks: []
4186}) {
4187 /** @type {?} */
4188 const future = futureNode.value;
4189 /** @type {?} */
4190 const curr = currNode ? currNode.value : null;
4191 /** @type {?} */
4192 const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null;
4193 // reusing the node
4194 if (curr && future.routeConfig === curr.routeConfig) {
4195 /** @type {?} */
4196 const shouldRun = shouldRunGuardsAndResolvers(curr, future, (/** @type {?} */ (future.routeConfig)).runGuardsAndResolvers);
4197 if (shouldRun) {
4198 checks.canActivateChecks.push(new CanActivate(futurePath));
4199 }
4200 else {
4201 // we need to set the data
4202 future.data = curr.data;
4203 future._resolvedData = curr._resolvedData;
4204 }
4205 // If we have a component, we need to go through an outlet.
4206 if (future.component) {
4207 getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks);
4208 // if we have a componentless route, we recurse but keep the same outlet map.
4209 }
4210 else {
4211 getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
4212 }
4213 if (shouldRun) {
4214 /** @type {?} */
4215 const component = context && context.outlet && context.outlet.component || null;
4216 checks.canDeactivateChecks.push(new CanDeactivate(component, curr));
4217 }
4218 }
4219 else {
4220 if (curr) {
4221 deactivateRouteAndItsChildren(currNode, context, checks);
4222 }
4223 checks.canActivateChecks.push(new CanActivate(futurePath));
4224 // If we have a component, we need to go through an outlet.
4225 if (future.component) {
4226 getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks);
4227 // if we have a componentless route, we recurse but keep the same outlet map.
4228 }
4229 else {
4230 getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks);
4231 }
4232 }
4233 return checks;
4234}
4235/**
4236 * @param {?} curr
4237 * @param {?} future
4238 * @param {?} mode
4239 * @return {?}
4240 */
4241function shouldRunGuardsAndResolvers(curr, future, mode) {
4242 if (typeof mode === 'function') {
4243 return mode(curr, future);
4244 }
4245 switch (mode) {
4246 case 'pathParamsChange':
4247 return !equalPath(curr.url, future.url);
4248 case 'pathParamsOrQueryParamsChange':
4249 return !equalPath(curr.url, future.url) ||
4250 !shallowEqual(curr.queryParams, future.queryParams);
4251 case 'always':
4252 return true;
4253 case 'paramsOrQueryParamsChange':
4254 return !equalParamsAndUrlSegments(curr, future) ||
4255 !shallowEqual(curr.queryParams, future.queryParams);
4256 case 'paramsChange':
4257 default:
4258 return !equalParamsAndUrlSegments(curr, future);
4259 }
4260}
4261/**
4262 * @param {?} route
4263 * @param {?} context
4264 * @param {?} checks
4265 * @return {?}
4266 */
4267function deactivateRouteAndItsChildren(route, context, checks) {
4268 /** @type {?} */
4269 const children = nodeChildrenAsMap(route);
4270 /** @type {?} */
4271 const r = route.value;
4272 forEach(children, (/**
4273 * @param {?} node
4274 * @param {?} childName
4275 * @return {?}
4276 */
4277 (node, childName) => {
4278 if (!r.component) {
4279 deactivateRouteAndItsChildren(node, context, checks);
4280 }
4281 else if (context) {
4282 deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks);
4283 }
4284 else {
4285 deactivateRouteAndItsChildren(node, null, checks);
4286 }
4287 }));
4288 if (!r.component) {
4289 checks.canDeactivateChecks.push(new CanDeactivate(null, r));
4290 }
4291 else if (context && context.outlet && context.outlet.isActivated) {
4292 checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
4293 }
4294 else {
4295 checks.canDeactivateChecks.push(new CanDeactivate(null, r));
4296 }
4297}
4298
4299/**
4300 * @fileoverview added by tsickle
4301 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4302 */
4303/** @type {?} */
4304const INITIAL_VALUE = Symbol('INITIAL_VALUE');
4305/**
4306 * @return {?}
4307 */
4308function prioritizedGuardValue() {
4309 return switchMap((/**
4310 * @param {?} obs
4311 * @return {?}
4312 */
4313 obs => {
4314 return (/** @type {?} */ (combineLatest(...obs.map((/**
4315 * @param {?} o
4316 * @return {?}
4317 */
4318 o => o.pipe(take(1), startWith((/** @type {?} */ (INITIAL_VALUE)))))))
4319 .pipe(scan((/**
4320 * @param {?} acc
4321 * @param {?} list
4322 * @return {?}
4323 */
4324 (acc, list) => {
4325 /** @type {?} */
4326 let isPending = false;
4327 return list.reduce((/**
4328 * @param {?} innerAcc
4329 * @param {?} val
4330 * @param {?} i
4331 * @return {?}
4332 */
4333 (innerAcc, val, i) => {
4334 if (innerAcc !== INITIAL_VALUE)
4335 return innerAcc;
4336 // Toggle pending flag if any values haven't been set yet
4337 if (val === INITIAL_VALUE)
4338 isPending = true;
4339 // Any other return values are only valid if we haven't yet hit a pending call.
4340 // This guarantees that in the case of a guard at the bottom of the tree that
4341 // returns a redirect, we will wait for the higher priority guard at the top to
4342 // finish before performing the redirect.
4343 if (!isPending) {
4344 // Early return when we hit a `false` value as that should always cancel
4345 // navigation
4346 if (val === false)
4347 return val;
4348 if (i === list.length - 1 || isUrlTree(val)) {
4349 return val;
4350 }
4351 }
4352 return innerAcc;
4353 }), acc);
4354 }), INITIAL_VALUE), filter((/**
4355 * @param {?} item
4356 * @return {?}
4357 */
4358 item => item !== INITIAL_VALUE)), map((/**
4359 * @param {?} item
4360 * @return {?}
4361 */
4362 item => isUrlTree(item) ? item : item === true)), //
4363 take(1))));
4364 }));
4365}
4366
4367/**
4368 * @fileoverview added by tsickle
4369 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4370 */
4371/**
4372 * @param {?} moduleInjector
4373 * @param {?=} forwardEvent
4374 * @return {?}
4375 */
4376function checkGuards(moduleInjector, forwardEvent) {
4377 return (/**
4378 * @param {?} source
4379 * @return {?}
4380 */
4381 function (source) {
4382 return source.pipe(mergeMap((/**
4383 * @param {?} t
4384 * @return {?}
4385 */
4386 t => {
4387 const { targetSnapshot, currentSnapshot, guards: { canActivateChecks, canDeactivateChecks } } = t;
4388 if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
4389 return of(Object.assign({}, t, { guardsResult: true }));
4390 }
4391 return runCanDeactivateChecks(canDeactivateChecks, (/** @type {?} */ (targetSnapshot)), currentSnapshot, moduleInjector)
4392 .pipe(mergeMap((/**
4393 * @param {?} canDeactivate
4394 * @return {?}
4395 */
4396 canDeactivate => {
4397 return canDeactivate && isBoolean(canDeactivate) ?
4398 runCanActivateChecks((/** @type {?} */ (targetSnapshot)), canActivateChecks, moduleInjector, forwardEvent) :
4399 of(canDeactivate);
4400 })), map((/**
4401 * @param {?} guardsResult
4402 * @return {?}
4403 */
4404 guardsResult => (Object.assign({}, t, { guardsResult })))));
4405 })));
4406 });
4407}
4408/**
4409 * @param {?} checks
4410 * @param {?} futureRSS
4411 * @param {?} currRSS
4412 * @param {?} moduleInjector
4413 * @return {?}
4414 */
4415function runCanDeactivateChecks(checks, futureRSS, currRSS, moduleInjector) {
4416 return from(checks).pipe(mergeMap((/**
4417 * @param {?} check
4418 * @return {?}
4419 */
4420 check => runCanDeactivate(check.component, check.route, currRSS, futureRSS, moduleInjector))), first((/**
4421 * @param {?} result
4422 * @return {?}
4423 */
4424 result => { return result !== true; }), (/** @type {?} */ (true))));
4425}
4426/**
4427 * @param {?} futureSnapshot
4428 * @param {?} checks
4429 * @param {?} moduleInjector
4430 * @param {?=} forwardEvent
4431 * @return {?}
4432 */
4433function runCanActivateChecks(futureSnapshot, checks, moduleInjector, forwardEvent) {
4434 return from(checks).pipe(concatMap((/**
4435 * @param {?} check
4436 * @return {?}
4437 */
4438 (check) => {
4439 return from([
4440 fireChildActivationStart(check.route.parent, forwardEvent),
4441 fireActivationStart(check.route, forwardEvent),
4442 runCanActivateChild(futureSnapshot, check.path, moduleInjector),
4443 runCanActivate(futureSnapshot, check.route, moduleInjector)
4444 ])
4445 .pipe(concatAll(), first((/**
4446 * @param {?} result
4447 * @return {?}
4448 */
4449 result => {
4450 return result !== true;
4451 }), (/** @type {?} */ (true))));
4452 })), first((/**
4453 * @param {?} result
4454 * @return {?}
4455 */
4456 result => { return result !== true; }), (/** @type {?} */ (true))));
4457}
4458/**
4459 * This should fire off `ActivationStart` events for each route being activated at this
4460 * level.
4461 * In other words, if you're activating `a` and `b` below, `path` will contain the
4462 * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
4463 * return
4464 * `true` so checks continue to run.
4465 * @param {?} snapshot
4466 * @param {?=} forwardEvent
4467 * @return {?}
4468 */
4469function fireActivationStart(snapshot, forwardEvent) {
4470 if (snapshot !== null && forwardEvent) {
4471 forwardEvent(new ActivationStart(snapshot));
4472 }
4473 return of(true);
4474}
4475/**
4476 * This should fire off `ChildActivationStart` events for each route being activated at this
4477 * level.
4478 * In other words, if you're activating `a` and `b` below, `path` will contain the
4479 * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
4480 * return
4481 * `true` so checks continue to run.
4482 * @param {?} snapshot
4483 * @param {?=} forwardEvent
4484 * @return {?}
4485 */
4486function fireChildActivationStart(snapshot, forwardEvent) {
4487 if (snapshot !== null && forwardEvent) {
4488 forwardEvent(new ChildActivationStart(snapshot));
4489 }
4490 return of(true);
4491}
4492/**
4493 * @param {?} futureRSS
4494 * @param {?} futureARS
4495 * @param {?} moduleInjector
4496 * @return {?}
4497 */
4498function runCanActivate(futureRSS, futureARS, moduleInjector) {
4499 /** @type {?} */
4500 const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
4501 if (!canActivate || canActivate.length === 0)
4502 return of(true);
4503 /** @type {?} */
4504 const canActivateObservables = canActivate.map((/**
4505 * @param {?} c
4506 * @return {?}
4507 */
4508 (c) => {
4509 return defer((/**
4510 * @return {?}
4511 */
4512 () => {
4513 /** @type {?} */
4514 const guard = getToken(c, futureARS, moduleInjector);
4515 /** @type {?} */
4516 let observable;
4517 if (isCanActivate(guard)) {
4518 observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
4519 }
4520 else if (isFunction(guard)) {
4521 observable = wrapIntoObservable(guard(futureARS, futureRSS));
4522 }
4523 else {
4524 throw new Error('Invalid CanActivate guard');
4525 }
4526 return observable.pipe(first());
4527 }));
4528 }));
4529 return of(canActivateObservables).pipe(prioritizedGuardValue());
4530}
4531/**
4532 * @param {?} futureRSS
4533 * @param {?} path
4534 * @param {?} moduleInjector
4535 * @return {?}
4536 */
4537function runCanActivateChild(futureRSS, path, moduleInjector) {
4538 /** @type {?} */
4539 const futureARS = path[path.length - 1];
4540 /** @type {?} */
4541 const canActivateChildGuards = path.slice(0, path.length - 1)
4542 .reverse()
4543 .map((/**
4544 * @param {?} p
4545 * @return {?}
4546 */
4547 p => getCanActivateChild(p)))
4548 .filter((/**
4549 * @param {?} _
4550 * @return {?}
4551 */
4552 _ => _ !== null));
4553 /** @type {?} */
4554 const canActivateChildGuardsMapped = canActivateChildGuards.map((/**
4555 * @param {?} d
4556 * @return {?}
4557 */
4558 (d) => {
4559 return defer((/**
4560 * @return {?}
4561 */
4562 () => {
4563 /** @type {?} */
4564 const guardsMapped = d.guards.map((/**
4565 * @param {?} c
4566 * @return {?}
4567 */
4568 (c) => {
4569 /** @type {?} */
4570 const guard = getToken(c, d.node, moduleInjector);
4571 /** @type {?} */
4572 let observable;
4573 if (isCanActivateChild(guard)) {
4574 observable = wrapIntoObservable(guard.canActivateChild(futureARS, futureRSS));
4575 }
4576 else if (isFunction(guard)) {
4577 observable = wrapIntoObservable(guard(futureARS, futureRSS));
4578 }
4579 else {
4580 throw new Error('Invalid CanActivateChild guard');
4581 }
4582 return observable.pipe(first());
4583 }));
4584 return of(guardsMapped).pipe(prioritizedGuardValue());
4585 }));
4586 }));
4587 return of(canActivateChildGuardsMapped).pipe(prioritizedGuardValue());
4588}
4589/**
4590 * @param {?} component
4591 * @param {?} currARS
4592 * @param {?} currRSS
4593 * @param {?} futureRSS
4594 * @param {?} moduleInjector
4595 * @return {?}
4596 */
4597function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector) {
4598 /** @type {?} */
4599 const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
4600 if (!canDeactivate || canDeactivate.length === 0)
4601 return of(true);
4602 /** @type {?} */
4603 const canDeactivateObservables = canDeactivate.map((/**
4604 * @param {?} c
4605 * @return {?}
4606 */
4607 (c) => {
4608 /** @type {?} */
4609 const guard = getToken(c, currARS, moduleInjector);
4610 /** @type {?} */
4611 let observable;
4612 if (isCanDeactivate(guard)) {
4613 observable =
4614 wrapIntoObservable(guard.canDeactivate((/** @type {?} */ (component)), currARS, currRSS, futureRSS));
4615 }
4616 else if (isFunction(guard)) {
4617 observable = wrapIntoObservable(guard(component, currARS, currRSS, futureRSS));
4618 }
4619 else {
4620 throw new Error('Invalid CanDeactivate guard');
4621 }
4622 return observable.pipe(first());
4623 }));
4624 return of(canDeactivateObservables).pipe(prioritizedGuardValue());
4625}
4626
4627/**
4628 * @fileoverview added by tsickle
4629 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4630 */
4631class NoMatch$1 {
4632}
4633/**
4634 * @param {?} rootComponentType
4635 * @param {?} config
4636 * @param {?} urlTree
4637 * @param {?} url
4638 * @param {?=} paramsInheritanceStrategy
4639 * @param {?=} relativeLinkResolution
4640 * @return {?}
4641 */
4642function recognize(rootComponentType, config, urlTree, url, paramsInheritanceStrategy = 'emptyOnly', relativeLinkResolution = 'legacy') {
4643 return new Recognizer(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution)
4644 .recognize();
4645}
4646class Recognizer {
4647 /**
4648 * @param {?} rootComponentType
4649 * @param {?} config
4650 * @param {?} urlTree
4651 * @param {?} url
4652 * @param {?} paramsInheritanceStrategy
4653 * @param {?} relativeLinkResolution
4654 */
4655 constructor(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution) {
4656 this.rootComponentType = rootComponentType;
4657 this.config = config;
4658 this.urlTree = urlTree;
4659 this.url = url;
4660 this.paramsInheritanceStrategy = paramsInheritanceStrategy;
4661 this.relativeLinkResolution = relativeLinkResolution;
4662 }
4663 /**
4664 * @return {?}
4665 */
4666 recognize() {
4667 try {
4668 /** @type {?} */
4669 const rootSegmentGroup = split$1(this.urlTree.root, [], [], this.config, this.relativeLinkResolution).segmentGroup;
4670 /** @type {?} */
4671 const children = this.processSegmentGroup(this.config, rootSegmentGroup, PRIMARY_OUTLET);
4672 /** @type {?} */
4673 const root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze(Object.assign({}, this.urlTree.queryParams)), (/** @type {?} */ (this.urlTree.fragment)), {}, PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {});
4674 /** @type {?} */
4675 const rootNode = new TreeNode(root, children);
4676 /** @type {?} */
4677 const routeState = new RouterStateSnapshot(this.url, rootNode);
4678 this.inheritParamsAndData(routeState._root);
4679 return of(routeState);
4680 }
4681 catch (e) {
4682 return new Observable((/**
4683 * @param {?} obs
4684 * @return {?}
4685 */
4686 (obs) => obs.error(e)));
4687 }
4688 }
4689 /**
4690 * @param {?} routeNode
4691 * @return {?}
4692 */
4693 inheritParamsAndData(routeNode) {
4694 /** @type {?} */
4695 const route = routeNode.value;
4696 /** @type {?} */
4697 const i = inheritedParamsDataResolve(route, this.paramsInheritanceStrategy);
4698 route.params = Object.freeze(i.params);
4699 route.data = Object.freeze(i.data);
4700 routeNode.children.forEach((/**
4701 * @param {?} n
4702 * @return {?}
4703 */
4704 n => this.inheritParamsAndData(n)));
4705 }
4706 /**
4707 * @param {?} config
4708 * @param {?} segmentGroup
4709 * @param {?} outlet
4710 * @return {?}
4711 */
4712 processSegmentGroup(config, segmentGroup, outlet) {
4713 if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
4714 return this.processChildren(config, segmentGroup);
4715 }
4716 return this.processSegment(config, segmentGroup, segmentGroup.segments, outlet);
4717 }
4718 /**
4719 * @param {?} config
4720 * @param {?} segmentGroup
4721 * @return {?}
4722 */
4723 processChildren(config, segmentGroup) {
4724 /** @type {?} */
4725 const children = mapChildrenIntoArray(segmentGroup, (/**
4726 * @param {?} child
4727 * @param {?} childOutlet
4728 * @return {?}
4729 */
4730 (child, childOutlet) => this.processSegmentGroup(config, child, childOutlet)));
4731 checkOutletNameUniqueness(children);
4732 sortActivatedRouteSnapshots(children);
4733 return children;
4734 }
4735 /**
4736 * @param {?} config
4737 * @param {?} segmentGroup
4738 * @param {?} segments
4739 * @param {?} outlet
4740 * @return {?}
4741 */
4742 processSegment(config, segmentGroup, segments, outlet) {
4743 for (const r of config) {
4744 try {
4745 return this.processSegmentAgainstRoute(r, segmentGroup, segments, outlet);
4746 }
4747 catch (e) {
4748 if (!(e instanceof NoMatch$1))
4749 throw e;
4750 }
4751 }
4752 if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
4753 return [];
4754 }
4755 throw new NoMatch$1();
4756 }
4757 /**
4758 * @private
4759 * @param {?} segmentGroup
4760 * @param {?} segments
4761 * @param {?} outlet
4762 * @return {?}
4763 */
4764 noLeftoversInUrl(segmentGroup, segments, outlet) {
4765 return segments.length === 0 && !segmentGroup.children[outlet];
4766 }
4767 /**
4768 * @param {?} route
4769 * @param {?} rawSegment
4770 * @param {?} segments
4771 * @param {?} outlet
4772 * @return {?}
4773 */
4774 processSegmentAgainstRoute(route, rawSegment, segments, outlet) {
4775 if (route.redirectTo)
4776 throw new NoMatch$1();
4777 if ((route.outlet || PRIMARY_OUTLET) !== outlet)
4778 throw new NoMatch$1();
4779 /** @type {?} */
4780 let snapshot;
4781 /** @type {?} */
4782 let consumedSegments = [];
4783 /** @type {?} */
4784 let rawSlicedSegments = [];
4785 if (route.path === '**') {
4786 /** @type {?} */
4787 const params = segments.length > 0 ? (/** @type {?} */ (last(segments))).parameters : {};
4788 snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze(Object.assign({}, this.urlTree.queryParams)), (/** @type {?} */ (this.urlTree.fragment)), getData(route), outlet, (/** @type {?} */ (route.component)), route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + segments.length, getResolve(route));
4789 }
4790 else {
4791 /** @type {?} */
4792 const result = match$1(rawSegment, route, segments);
4793 consumedSegments = result.consumedSegments;
4794 rawSlicedSegments = segments.slice(result.lastChild);
4795 snapshot = new ActivatedRouteSnapshot(consumedSegments, result.parameters, Object.freeze(Object.assign({}, this.urlTree.queryParams)), (/** @type {?} */ (this.urlTree.fragment)), getData(route), outlet, (/** @type {?} */ (route.component)), route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + consumedSegments.length, getResolve(route));
4796 }
4797 /** @type {?} */
4798 const childConfig = getChildConfig(route);
4799 const { segmentGroup, slicedSegments } = split$1(rawSegment, consumedSegments, rawSlicedSegments, childConfig, this.relativeLinkResolution);
4800 if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
4801 /** @type {?} */
4802 const children = this.processChildren(childConfig, segmentGroup);
4803 return [new TreeNode(snapshot, children)];
4804 }
4805 if (childConfig.length === 0 && slicedSegments.length === 0) {
4806 return [new TreeNode(snapshot, [])];
4807 }
4808 /** @type {?} */
4809 const children = this.processSegment(childConfig, segmentGroup, slicedSegments, PRIMARY_OUTLET);
4810 return [new TreeNode(snapshot, children)];
4811 }
4812}
4813/**
4814 * @param {?} nodes
4815 * @return {?}
4816 */
4817function sortActivatedRouteSnapshots(nodes) {
4818 nodes.sort((/**
4819 * @param {?} a
4820 * @param {?} b
4821 * @return {?}
4822 */
4823 (a, b) => {
4824 if (a.value.outlet === PRIMARY_OUTLET)
4825 return -1;
4826 if (b.value.outlet === PRIMARY_OUTLET)
4827 return 1;
4828 return a.value.outlet.localeCompare(b.value.outlet);
4829 }));
4830}
4831/**
4832 * @param {?} route
4833 * @return {?}
4834 */
4835function getChildConfig(route) {
4836 if (route.children) {
4837 return route.children;
4838 }
4839 if (route.loadChildren) {
4840 return (/** @type {?} */ (route._loadedConfig)).routes;
4841 }
4842 return [];
4843}
4844/**
4845 * @param {?} segmentGroup
4846 * @param {?} route
4847 * @param {?} segments
4848 * @return {?}
4849 */
4850function match$1(segmentGroup, route, segments) {
4851 if (route.path === '') {
4852 if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
4853 throw new NoMatch$1();
4854 }
4855 return { consumedSegments: [], lastChild: 0, parameters: {} };
4856 }
4857 /** @type {?} */
4858 const matcher = route.matcher || defaultUrlMatcher;
4859 /** @type {?} */
4860 const res = matcher(segments, segmentGroup, route);
4861 if (!res)
4862 throw new NoMatch$1();
4863 /** @type {?} */
4864 const posParams = {};
4865 forEach((/** @type {?} */ (res.posParams)), (/**
4866 * @param {?} v
4867 * @param {?} k
4868 * @return {?}
4869 */
4870 (v, k) => { posParams[k] = v.path; }));
4871 /** @type {?} */
4872 const parameters = res.consumed.length > 0 ? Object.assign({}, posParams, res.consumed[res.consumed.length - 1].parameters) :
4873 posParams;
4874 return { consumedSegments: res.consumed, lastChild: res.consumed.length, parameters };
4875}
4876/**
4877 * @param {?} nodes
4878 * @return {?}
4879 */
4880function checkOutletNameUniqueness(nodes) {
4881 /** @type {?} */
4882 const names = {};
4883 nodes.forEach((/**
4884 * @param {?} n
4885 * @return {?}
4886 */
4887 n => {
4888 /** @type {?} */
4889 const routeWithSameOutletName = names[n.value.outlet];
4890 if (routeWithSameOutletName) {
4891 /** @type {?} */
4892 const p = routeWithSameOutletName.url.map((/**
4893 * @param {?} s
4894 * @return {?}
4895 */
4896 s => s.toString())).join('/');
4897 /** @type {?} */
4898 const c = n.value.url.map((/**
4899 * @param {?} s
4900 * @return {?}
4901 */
4902 s => s.toString())).join('/');
4903 throw new Error(`Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
4904 }
4905 names[n.value.outlet] = n.value;
4906 }));
4907}
4908/**
4909 * @param {?} segmentGroup
4910 * @return {?}
4911 */
4912function getSourceSegmentGroup(segmentGroup) {
4913 /** @type {?} */
4914 let s = segmentGroup;
4915 while (s._sourceSegment) {
4916 s = s._sourceSegment;
4917 }
4918 return s;
4919}
4920/**
4921 * @param {?} segmentGroup
4922 * @return {?}
4923 */
4924function getPathIndexShift(segmentGroup) {
4925 /** @type {?} */
4926 let s = segmentGroup;
4927 /** @type {?} */
4928 let res = (s._segmentIndexShift ? s._segmentIndexShift : 0);
4929 while (s._sourceSegment) {
4930 s = s._sourceSegment;
4931 res += (s._segmentIndexShift ? s._segmentIndexShift : 0);
4932 }
4933 return res - 1;
4934}
4935/**
4936 * @param {?} segmentGroup
4937 * @param {?} consumedSegments
4938 * @param {?} slicedSegments
4939 * @param {?} config
4940 * @param {?} relativeLinkResolution
4941 * @return {?}
4942 */
4943function split$1(segmentGroup, consumedSegments, slicedSegments, config, relativeLinkResolution) {
4944 if (slicedSegments.length > 0 &&
4945 containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
4946 /** @type {?} */
4947 const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(segmentGroup, consumedSegments, config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
4948 s._sourceSegment = segmentGroup;
4949 s._segmentIndexShift = consumedSegments.length;
4950 return { segmentGroup: s, slicedSegments: [] };
4951 }
4952 if (slicedSegments.length === 0 &&
4953 containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
4954 /** @type {?} */
4955 const s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children, relativeLinkResolution));
4956 s._sourceSegment = segmentGroup;
4957 s._segmentIndexShift = consumedSegments.length;
4958 return { segmentGroup: s, slicedSegments };
4959 }
4960 /** @type {?} */
4961 const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
4962 s._sourceSegment = segmentGroup;
4963 s._segmentIndexShift = consumedSegments.length;
4964 return { segmentGroup: s, slicedSegments };
4965}
4966/**
4967 * @param {?} segmentGroup
4968 * @param {?} consumedSegments
4969 * @param {?} slicedSegments
4970 * @param {?} routes
4971 * @param {?} children
4972 * @param {?} relativeLinkResolution
4973 * @return {?}
4974 */
4975function addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, routes, children, relativeLinkResolution) {
4976 /** @type {?} */
4977 const res = {};
4978 for (const r of routes) {
4979 if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet$1(r)]) {
4980 /** @type {?} */
4981 const s = new UrlSegmentGroup([], {});
4982 s._sourceSegment = segmentGroup;
4983 if (relativeLinkResolution === 'legacy') {
4984 s._segmentIndexShift = segmentGroup.segments.length;
4985 }
4986 else {
4987 s._segmentIndexShift = consumedSegments.length;
4988 }
4989 res[getOutlet$1(r)] = s;
4990 }
4991 }
4992 return Object.assign({}, children, res);
4993}
4994/**
4995 * @param {?} segmentGroup
4996 * @param {?} consumedSegments
4997 * @param {?} routes
4998 * @param {?} primarySegment
4999 * @return {?}
5000 */
5001function createChildrenForEmptyPaths(segmentGroup, consumedSegments, routes, primarySegment) {
5002 /** @type {?} */
5003 const res = {};
5004 res[PRIMARY_OUTLET] = primarySegment;
5005 primarySegment._sourceSegment = segmentGroup;
5006 primarySegment._segmentIndexShift = consumedSegments.length;
5007 for (const r of routes) {
5008 if (r.path === '' && getOutlet$1(r) !== PRIMARY_OUTLET) {
5009 /** @type {?} */
5010 const s = new UrlSegmentGroup([], {});
5011 s._sourceSegment = segmentGroup;
5012 s._segmentIndexShift = consumedSegments.length;
5013 res[getOutlet$1(r)] = s;
5014 }
5015 }
5016 return res;
5017}
5018/**
5019 * @param {?} segmentGroup
5020 * @param {?} slicedSegments
5021 * @param {?} routes
5022 * @return {?}
5023 */
5024function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) {
5025 return routes.some((/**
5026 * @param {?} r
5027 * @return {?}
5028 */
5029 r => emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet$1(r) !== PRIMARY_OUTLET));
5030}
5031/**
5032 * @param {?} segmentGroup
5033 * @param {?} slicedSegments
5034 * @param {?} routes
5035 * @return {?}
5036 */
5037function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) {
5038 return routes.some((/**
5039 * @param {?} r
5040 * @return {?}
5041 */
5042 r => emptyPathMatch(segmentGroup, slicedSegments, r)));
5043}
5044/**
5045 * @param {?} segmentGroup
5046 * @param {?} slicedSegments
5047 * @param {?} r
5048 * @return {?}
5049 */
5050function emptyPathMatch(segmentGroup, slicedSegments, r) {
5051 if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') {
5052 return false;
5053 }
5054 return r.path === '' && r.redirectTo === undefined;
5055}
5056/**
5057 * @param {?} route
5058 * @return {?}
5059 */
5060function getOutlet$1(route) {
5061 return route.outlet || PRIMARY_OUTLET;
5062}
5063/**
5064 * @param {?} route
5065 * @return {?}
5066 */
5067function getData(route) {
5068 return route.data || {};
5069}
5070/**
5071 * @param {?} route
5072 * @return {?}
5073 */
5074function getResolve(route) {
5075 return route.resolve || {};
5076}
5077
5078/**
5079 * @fileoverview added by tsickle
5080 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5081 */
5082/**
5083 * @param {?} rootComponentType
5084 * @param {?} config
5085 * @param {?} serializer
5086 * @param {?} paramsInheritanceStrategy
5087 * @param {?} relativeLinkResolution
5088 * @return {?}
5089 */
5090function recognize$1(rootComponentType, config, serializer, paramsInheritanceStrategy, relativeLinkResolution) {
5091 return (/**
5092 * @param {?} source
5093 * @return {?}
5094 */
5095 function (source) {
5096 return source.pipe(mergeMap((/**
5097 * @param {?} t
5098 * @return {?}
5099 */
5100 t => recognize(rootComponentType, config, t.urlAfterRedirects, serializer(t.urlAfterRedirects), paramsInheritanceStrategy, relativeLinkResolution)
5101 .pipe(map((/**
5102 * @param {?} targetSnapshot
5103 * @return {?}
5104 */
5105 targetSnapshot => (Object.assign({}, t, { targetSnapshot }))))))));
5106 });
5107}
5108
5109/**
5110 * @fileoverview added by tsickle
5111 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5112 */
5113/**
5114 * @param {?} paramsInheritanceStrategy
5115 * @param {?} moduleInjector
5116 * @return {?}
5117 */
5118function resolveData(paramsInheritanceStrategy, moduleInjector) {
5119 return (/**
5120 * @param {?} source
5121 * @return {?}
5122 */
5123 function (source) {
5124 return source.pipe(mergeMap((/**
5125 * @param {?} t
5126 * @return {?}
5127 */
5128 t => {
5129 const { targetSnapshot, guards: { canActivateChecks } } = t;
5130 if (!canActivateChecks.length) {
5131 return of(t);
5132 }
5133 return from(canActivateChecks)
5134 .pipe(concatMap((/**
5135 * @param {?} check
5136 * @return {?}
5137 */
5138 check => runResolve(check.route, (/** @type {?} */ (targetSnapshot)), paramsInheritanceStrategy, moduleInjector))), reduce((/**
5139 * @param {?} _
5140 * @param {?} __
5141 * @return {?}
5142 */
5143 (_, __) => _)), map((/**
5144 * @param {?} _
5145 * @return {?}
5146 */
5147 _ => t)));
5148 })));
5149 });
5150}
5151/**
5152 * @param {?} futureARS
5153 * @param {?} futureRSS
5154 * @param {?} paramsInheritanceStrategy
5155 * @param {?} moduleInjector
5156 * @return {?}
5157 */
5158function runResolve(futureARS, futureRSS, paramsInheritanceStrategy, moduleInjector) {
5159 /** @type {?} */
5160 const resolve = futureARS._resolve;
5161 return resolveNode(resolve, futureARS, futureRSS, moduleInjector)
5162 .pipe(map((/**
5163 * @param {?} resolvedData
5164 * @return {?}
5165 */
5166 (resolvedData) => {
5167 futureARS._resolvedData = resolvedData;
5168 futureARS.data = Object.assign({}, futureARS.data, inheritedParamsDataResolve(futureARS, paramsInheritanceStrategy).resolve);
5169 return null;
5170 })));
5171}
5172/**
5173 * @param {?} resolve
5174 * @param {?} futureARS
5175 * @param {?} futureRSS
5176 * @param {?} moduleInjector
5177 * @return {?}
5178 */
5179function resolveNode(resolve, futureARS, futureRSS, moduleInjector) {
5180 /** @type {?} */
5181 const keys = Object.keys(resolve);
5182 if (keys.length === 0) {
5183 return of({});
5184 }
5185 if (keys.length === 1) {
5186 /** @type {?} */
5187 const key = keys[0];
5188 return getResolver(resolve[key], futureARS, futureRSS, moduleInjector)
5189 .pipe(map((/**
5190 * @param {?} value
5191 * @return {?}
5192 */
5193 (value) => { return { [key]: value }; })));
5194 }
5195 /** @type {?} */
5196 const data = {};
5197 /** @type {?} */
5198 const runningResolvers$ = from(keys).pipe(mergeMap((/**
5199 * @param {?} key
5200 * @return {?}
5201 */
5202 (key) => {
5203 return getResolver(resolve[key], futureARS, futureRSS, moduleInjector)
5204 .pipe(map((/**
5205 * @param {?} value
5206 * @return {?}
5207 */
5208 (value) => {
5209 data[key] = value;
5210 return value;
5211 })));
5212 })));
5213 return runningResolvers$.pipe(last$1(), map((/**
5214 * @return {?}
5215 */
5216 () => data)));
5217}
5218/**
5219 * @param {?} injectionToken
5220 * @param {?} futureARS
5221 * @param {?} futureRSS
5222 * @param {?} moduleInjector
5223 * @return {?}
5224 */
5225function getResolver(injectionToken, futureARS, futureRSS, moduleInjector) {
5226 /** @type {?} */
5227 const resolver = getToken(injectionToken, futureARS, moduleInjector);
5228 return resolver.resolve ? wrapIntoObservable(resolver.resolve(futureARS, futureRSS)) :
5229 wrapIntoObservable(resolver(futureARS, futureRSS));
5230}
5231
5232/**
5233 * @fileoverview added by tsickle
5234 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5235 */
5236/**
5237 * Perform a side effect through a switchMap for every emission on the source Observable,
5238 * but return an Observable that is identical to the source. It's essentially the same as
5239 * the `tap` operator, but if the side effectful `next` function returns an ObservableInput,
5240 * it will wait before continuing with the original value.
5241 * @template T
5242 * @param {?} next
5243 * @return {?}
5244 */
5245function switchTap(next) {
5246 return (/**
5247 * @param {?} source
5248 * @return {?}
5249 */
5250 function (source) {
5251 return source.pipe(switchMap((/**
5252 * @param {?} v
5253 * @return {?}
5254 */
5255 v => {
5256 /** @type {?} */
5257 const nextResult = next(v);
5258 if (nextResult) {
5259 return from(nextResult).pipe(map((/**
5260 * @return {?}
5261 */
5262 () => v)));
5263 }
5264 return from([v]);
5265 })));
5266 });
5267}
5268
5269/**
5270 * @fileoverview added by tsickle
5271 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5272 */
5273/**
5274 * @license
5275 * Copyright Google Inc. All Rights Reserved.
5276 *
5277 * Use of this source code is governed by an MIT-style license that can be
5278 * found in the LICENSE file at https://angular.io/license
5279 */
5280/**
5281 * \@description
5282 *
5283 * Provides a way to customize when activated routes get reused.
5284 *
5285 * \@publicApi
5286 * @abstract
5287 */
5288class RouteReuseStrategy {
5289}
5290/**
5291 * Does not detach any subtrees. Reuses routes as long as their route config is the same.
5292 */
5293class DefaultRouteReuseStrategy {
5294 /**
5295 * @param {?} route
5296 * @return {?}
5297 */
5298 shouldDetach(route) { return false; }
5299 /**
5300 * @param {?} route
5301 * @param {?} detachedTree
5302 * @return {?}
5303 */
5304 store(route, detachedTree) { }
5305 /**
5306 * @param {?} route
5307 * @return {?}
5308 */
5309 shouldAttach(route) { return false; }
5310 /**
5311 * @param {?} route
5312 * @return {?}
5313 */
5314 retrieve(route) { return null; }
5315 /**
5316 * @param {?} future
5317 * @param {?} curr
5318 * @return {?}
5319 */
5320 shouldReuseRoute(future, curr) {
5321 return future.routeConfig === curr.routeConfig;
5322 }
5323}
5324
5325/**
5326 * @fileoverview added by tsickle
5327 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5328 */
5329/**
5330 * \@docsNotRequired
5331 * \@publicApi
5332 * @type {?}
5333 */
5334const ROUTES = new InjectionToken('ROUTES');
5335class RouterConfigLoader {
5336 /**
5337 * @param {?} loader
5338 * @param {?} compiler
5339 * @param {?=} onLoadStartListener
5340 * @param {?=} onLoadEndListener
5341 */
5342 constructor(loader, compiler, onLoadStartListener, onLoadEndListener) {
5343 this.loader = loader;
5344 this.compiler = compiler;
5345 this.onLoadStartListener = onLoadStartListener;
5346 this.onLoadEndListener = onLoadEndListener;
5347 }
5348 /**
5349 * @param {?} parentInjector
5350 * @param {?} route
5351 * @return {?}
5352 */
5353 load(parentInjector, route) {
5354 if (this.onLoadStartListener) {
5355 this.onLoadStartListener(route);
5356 }
5357 /** @type {?} */
5358 const moduleFactory$ = this.loadModuleFactory((/** @type {?} */ (route.loadChildren)));
5359 return moduleFactory$.pipe(map((/**
5360 * @param {?} factory
5361 * @return {?}
5362 */
5363 (factory) => {
5364 if (this.onLoadEndListener) {
5365 this.onLoadEndListener(route);
5366 }
5367 /** @type {?} */
5368 const module = factory.create(parentInjector);
5369 return new LoadedRouterConfig(flatten(module.injector.get(ROUTES)).map(standardizeConfig), module);
5370 })));
5371 }
5372 /**
5373 * @private
5374 * @param {?} loadChildren
5375 * @return {?}
5376 */
5377 loadModuleFactory(loadChildren) {
5378 if (typeof loadChildren === 'string') {
5379 return from(this.loader.load(loadChildren));
5380 }
5381 else {
5382 return wrapIntoObservable(loadChildren()).pipe(mergeMap((/**
5383 * @param {?} t
5384 * @return {?}
5385 */
5386 (t) => {
5387 if (t instanceof NgModuleFactory) {
5388 return of(t);
5389 }
5390 else {
5391 return from(this.compiler.compileModuleAsync(t));
5392 }
5393 })));
5394 }
5395 }
5396}
5397
5398/**
5399 * @fileoverview added by tsickle
5400 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5401 */
5402/**
5403 * @license
5404 * Copyright Google Inc. All Rights Reserved.
5405 *
5406 * Use of this source code is governed by an MIT-style license that can be
5407 * found in the LICENSE file at https://angular.io/license
5408 */
5409/**
5410 * \@description
5411 *
5412 * Provides a way to migrate AngularJS applications to Angular.
5413 *
5414 * \@publicApi
5415 * @abstract
5416 */
5417class UrlHandlingStrategy {
5418}
5419/**
5420 * \@publicApi
5421 */
5422class DefaultUrlHandlingStrategy {
5423 /**
5424 * @param {?} url
5425 * @return {?}
5426 */
5427 shouldProcessUrl(url) { return true; }
5428 /**
5429 * @param {?} url
5430 * @return {?}
5431 */
5432 extract(url) { return url; }
5433 /**
5434 * @param {?} newUrlPart
5435 * @param {?} wholeUrl
5436 * @return {?}
5437 */
5438 merge(newUrlPart, wholeUrl) { return newUrlPart; }
5439}
5440
5441/**
5442 * @fileoverview added by tsickle
5443 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5444 */
5445/**
5446 * @param {?} error
5447 * @return {?}
5448 */
5449function defaultErrorHandler(error) {
5450 throw error;
5451}
5452/**
5453 * @param {?} error
5454 * @param {?} urlSerializer
5455 * @param {?} url
5456 * @return {?}
5457 */
5458function defaultMalformedUriErrorHandler(error, urlSerializer, url) {
5459 return urlSerializer.parse('/');
5460}
5461/**
5462 * \@internal
5463 * @param {?} snapshot
5464 * @param {?} runExtras
5465 * @return {?}
5466 */
5467function defaultRouterHook(snapshot, runExtras) {
5468 return (/** @type {?} */ (of(null)));
5469}
5470/**
5471 * \@description
5472 *
5473 * An NgModule that provides navigation and URL manipulation capabilities.
5474 *
5475 * @see `Route`.
5476 * @see [Routing and Navigation Guide](guide/router).
5477 *
5478 * \@ngModule RouterModule
5479 *
5480 * \@publicApi
5481 */
5482class Router {
5483 /**
5484 * Creates the router service.
5485 * @param {?} rootComponentType
5486 * @param {?} urlSerializer
5487 * @param {?} rootContexts
5488 * @param {?} location
5489 * @param {?} injector
5490 * @param {?} loader
5491 * @param {?} compiler
5492 * @param {?} config
5493 */
5494 // TODO: vsavkin make internal after the final is out.
5495 constructor(rootComponentType, urlSerializer, rootContexts, location, injector, loader, compiler, config) {
5496 this.rootComponentType = rootComponentType;
5497 this.urlSerializer = urlSerializer;
5498 this.rootContexts = rootContexts;
5499 this.location = location;
5500 this.config = config;
5501 this.lastSuccessfulNavigation = null;
5502 this.currentNavigation = null;
5503 this.navigationId = 0;
5504 this.isNgZoneEnabled = false;
5505 /**
5506 * An event stream for routing events in this NgModule.
5507 */
5508 this.events = new Subject();
5509 /**
5510 * A handler for navigation errors in this NgModule.
5511 */
5512 this.errorHandler = defaultErrorHandler;
5513 /**
5514 * Malformed uri error handler is invoked when `Router.parseUrl(url)` throws an
5515 * error due to containing an invalid character. The most common case would be a `%` sign
5516 * that's not encoded and is not part of a percent encoded sequence.
5517 */
5518 this.malformedUriErrorHandler = defaultMalformedUriErrorHandler;
5519 /**
5520 * True if at least one navigation event has occurred,
5521 * false otherwise.
5522 */
5523 this.navigated = false;
5524 this.lastSuccessfulId = -1;
5525 /**
5526 * Hooks that enable you to pause navigation,
5527 * either before or after the preactivation phase.
5528 * Used by `RouterModule`.
5529 *
5530 * \@internal
5531 */
5532 this.hooks = {
5533 beforePreactivation: defaultRouterHook,
5534 afterPreactivation: defaultRouterHook
5535 };
5536 /**
5537 * Extracts and merges URLs. Used for AngularJS to Angular migrations.
5538 */
5539 this.urlHandlingStrategy = new DefaultUrlHandlingStrategy();
5540 /**
5541 * The strategy for re-using routes.
5542 */
5543 this.routeReuseStrategy = new DefaultRouteReuseStrategy();
5544 /**
5545 * How to handle a navigation request to the current URL. One of:
5546 * - `'ignore'` : The router ignores the request.
5547 * - `'reload'` : The router reloads the URL. Use to implement a "refresh" feature.
5548 */
5549 this.onSameUrlNavigation = 'ignore';
5550 /**
5551 * How to merge parameters, data, and resolved data from parent to child
5552 * routes. One of:
5553 *
5554 * - `'emptyOnly'` : Inherit parent parameters, data, and resolved data
5555 * for path-less or component-less routes.
5556 * - `'always'` : Inherit parent parameters, data, and resolved data
5557 * for all child routes.
5558 */
5559 this.paramsInheritanceStrategy = 'emptyOnly';
5560 /**
5561 * Defines when the router updates the browser URL. The default behavior is to update after
5562 * successful navigation. However, some applications may prefer a mode where the URL gets
5563 * updated at the beginning of navigation. The most common use case would be updating the
5564 * URL early so if navigation fails, you can show an error message with the URL that failed.
5565 * Available options are:
5566 *
5567 * - `'deferred'`, the default, updates the browser URL after navigation has finished.
5568 * - `'eager'`, updates browser URL at the beginning of navigation.
5569 */
5570 this.urlUpdateStrategy = 'deferred';
5571 /**
5572 * See {\@link RouterModule} for more information.
5573 */
5574 this.relativeLinkResolution = 'legacy';
5575 /** @type {?} */
5576 const onLoadStart = (/**
5577 * @param {?} r
5578 * @return {?}
5579 */
5580 (r) => this.triggerEvent(new RouteConfigLoadStart(r)));
5581 /** @type {?} */
5582 const onLoadEnd = (/**
5583 * @param {?} r
5584 * @return {?}
5585 */
5586 (r) => this.triggerEvent(new RouteConfigLoadEnd(r)));
5587 this.ngModule = injector.get(NgModuleRef);
5588 this.console = injector.get(ɵConsole);
5589 /** @type {?} */
5590 const ngZone = injector.get(NgZone);
5591 this.isNgZoneEnabled = ngZone instanceof NgZone;
5592 this.resetConfig(config);
5593 this.currentUrlTree = createEmptyUrlTree();
5594 this.rawUrlTree = this.currentUrlTree;
5595 this.browserUrlTree = this.currentUrlTree;
5596 this.configLoader = new RouterConfigLoader(loader, compiler, onLoadStart, onLoadEnd);
5597 this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
5598 this.transitions = new BehaviorSubject({
5599 id: 0,
5600 currentUrlTree: this.currentUrlTree,
5601 currentRawUrl: this.currentUrlTree,
5602 extractedUrl: this.urlHandlingStrategy.extract(this.currentUrlTree),
5603 urlAfterRedirects: this.urlHandlingStrategy.extract(this.currentUrlTree),
5604 rawUrl: this.currentUrlTree,
5605 extras: {},
5606 resolve: null,
5607 reject: null,
5608 promise: Promise.resolve(true),
5609 source: 'imperative',
5610 restoredState: null,
5611 currentSnapshot: this.routerState.snapshot,
5612 targetSnapshot: null,
5613 currentRouterState: this.routerState,
5614 targetRouterState: null,
5615 guards: { canActivateChecks: [], canDeactivateChecks: [] },
5616 guardsResult: null,
5617 });
5618 this.navigations = this.setupNavigations(this.transitions);
5619 this.processNavigations();
5620 }
5621 /**
5622 * @private
5623 * @param {?} transitions
5624 * @return {?}
5625 */
5626 setupNavigations(transitions) {
5627 /** @type {?} */
5628 const eventsSubject = ((/** @type {?} */ (this.events)));
5629 return (/** @type {?} */ ((/** @type {?} */ (transitions.pipe(filter((/**
5630 * @param {?} t
5631 * @return {?}
5632 */
5633 t => t.id !== 0)),
5634 // Extract URL
5635 map((/**
5636 * @param {?} t
5637 * @return {?}
5638 */
5639 t => ((/** @type {?} */ (Object.assign({}, t, { extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl) })))))),
5640 // Using switchMap so we cancel executing navigations when a new one comes in
5641 switchMap((/**
5642 * @param {?} t
5643 * @return {?}
5644 */
5645 t => {
5646 /** @type {?} */
5647 let completed = false;
5648 /** @type {?} */
5649 let errored = false;
5650 return of(t).pipe(
5651 // Store the Navigation object
5652 tap((/**
5653 * @param {?} t
5654 * @return {?}
5655 */
5656 t => {
5657 this.currentNavigation = {
5658 id: t.id,
5659 initialUrl: t.currentRawUrl,
5660 extractedUrl: t.extractedUrl,
5661 trigger: t.source,
5662 extras: t.extras,
5663 previousNavigation: this.lastSuccessfulNavigation ? Object.assign({}, this.lastSuccessfulNavigation, { previousNavigation: null }) :
5664 null
5665 };
5666 })), switchMap((/**
5667 * @param {?} t
5668 * @return {?}
5669 */
5670 t => {
5671 /** @type {?} */
5672 const urlTransition = !this.navigated || t.extractedUrl.toString() !== this.browserUrlTree.toString();
5673 /** @type {?} */
5674 const processCurrentUrl = (this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
5675 this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
5676 if (processCurrentUrl) {
5677 return of(t).pipe(
5678 // Fire NavigationStart event
5679 switchMap((/**
5680 * @param {?} t
5681 * @return {?}
5682 */
5683 t => {
5684 /** @type {?} */
5685 const transition = this.transitions.getValue();
5686 eventsSubject.next(new NavigationStart(t.id, this.serializeUrl(t.extractedUrl), t.source, t.restoredState));
5687 if (transition !== this.transitions.getValue()) {
5688 return EMPTY;
5689 }
5690 return [t];
5691 })),
5692 // This delay is required to match old behavior that forced navigation to
5693 // always be async
5694 switchMap((/**
5695 * @param {?} t
5696 * @return {?}
5697 */
5698 t => Promise.resolve(t))),
5699 // ApplyRedirects
5700 applyRedirects$1(this.ngModule.injector, this.configLoader, this.urlSerializer, this.config),
5701 // Update the currentNavigation
5702 tap((/**
5703 * @param {?} t
5704 * @return {?}
5705 */
5706 t => {
5707 this.currentNavigation = Object.assign({}, (/** @type {?} */ (this.currentNavigation)), { finalUrl: t.urlAfterRedirects });
5708 })),
5709 // Recognize
5710 recognize$1(this.rootComponentType, this.config, (/**
5711 * @param {?} url
5712 * @return {?}
5713 */
5714 (url) => this.serializeUrl(url)), this.paramsInheritanceStrategy, this.relativeLinkResolution),
5715 // Update URL if in `eager` update mode
5716 tap((/**
5717 * @param {?} t
5718 * @return {?}
5719 */
5720 t => {
5721 if (this.urlUpdateStrategy === 'eager') {
5722 if (!t.extras.skipLocationChange) {
5723 this.setBrowserUrl(t.urlAfterRedirects, !!t.extras.replaceUrl, t.id, t.extras.state);
5724 }
5725 this.browserUrlTree = t.urlAfterRedirects;
5726 }
5727 })),
5728 // Fire RoutesRecognized
5729 tap((/**
5730 * @param {?} t
5731 * @return {?}
5732 */
5733 t => {
5734 /** @type {?} */
5735 const routesRecognized = new RoutesRecognized(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)));
5736 eventsSubject.next(routesRecognized);
5737 })));
5738 }
5739 else {
5740 /** @type {?} */
5741 const processPreviousUrl = urlTransition && this.rawUrlTree &&
5742 this.urlHandlingStrategy.shouldProcessUrl(this.rawUrlTree);
5743 /* When the current URL shouldn't be processed, but the previous one was, we
5744 * handle this "error condition" by navigating to the previously successful URL,
5745 * but leaving the URL intact.*/
5746 if (processPreviousUrl) {
5747 const { id, extractedUrl, source, restoredState, extras } = t;
5748 /** @type {?} */
5749 const navStart = new NavigationStart(id, this.serializeUrl(extractedUrl), source, restoredState);
5750 eventsSubject.next(navStart);
5751 /** @type {?} */
5752 const targetSnapshot = createEmptyState(extractedUrl, this.rootComponentType).snapshot;
5753 return of(Object.assign({}, t, { targetSnapshot, urlAfterRedirects: extractedUrl, extras: Object.assign({}, extras, { skipLocationChange: false, replaceUrl: false }) }));
5754 }
5755 else {
5756 /* When neither the current or previous URL can be processed, do nothing other
5757 * than update router's internal reference to the current "settled" URL. This
5758 * way the next navigation will be coming from the current URL in the browser.
5759 */
5760 this.rawUrlTree = t.rawUrl;
5761 this.browserUrlTree = t.urlAfterRedirects;
5762 t.resolve(null);
5763 return EMPTY;
5764 }
5765 }
5766 })),
5767 // Before Preactivation
5768 switchTap((/**
5769 * @param {?} t
5770 * @return {?}
5771 */
5772 t => {
5773 const { targetSnapshot, id: navigationId, extractedUrl: appliedUrlTree, rawUrl: rawUrlTree, extras: { skipLocationChange, replaceUrl } } = t;
5774 return this.hooks.beforePreactivation((/** @type {?} */ (targetSnapshot)), {
5775 navigationId,
5776 appliedUrlTree,
5777 rawUrlTree,
5778 skipLocationChange: !!skipLocationChange,
5779 replaceUrl: !!replaceUrl,
5780 });
5781 })),
5782 // --- GUARDS ---
5783 tap((/**
5784 * @param {?} t
5785 * @return {?}
5786 */
5787 t => {
5788 /** @type {?} */
5789 const guardsStart = new GuardsCheckStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)));
5790 this.triggerEvent(guardsStart);
5791 })), map((/**
5792 * @param {?} t
5793 * @return {?}
5794 */
5795 t => (Object.assign({}, t, { guards: getAllRouteGuards((/** @type {?} */ (t.targetSnapshot)), t.currentSnapshot, this.rootContexts) })))), checkGuards(this.ngModule.injector, (/**
5796 * @param {?} evt
5797 * @return {?}
5798 */
5799 (evt) => this.triggerEvent(evt))), tap((/**
5800 * @param {?} t
5801 * @return {?}
5802 */
5803 t => {
5804 if (isUrlTree(t.guardsResult)) {
5805 /** @type {?} */
5806 const error = navigationCancelingError(`Redirecting to "${this.serializeUrl(t.guardsResult)}"`);
5807 error.url = t.guardsResult;
5808 throw error;
5809 }
5810 })), tap((/**
5811 * @param {?} t
5812 * @return {?}
5813 */
5814 t => {
5815 /** @type {?} */
5816 const guardsEnd = new GuardsCheckEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)), !!t.guardsResult);
5817 this.triggerEvent(guardsEnd);
5818 })), filter((/**
5819 * @param {?} t
5820 * @return {?}
5821 */
5822 t => {
5823 if (!t.guardsResult) {
5824 this.resetUrlToCurrentUrlTree();
5825 /** @type {?} */
5826 const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), '');
5827 eventsSubject.next(navCancel);
5828 t.resolve(false);
5829 return false;
5830 }
5831 return true;
5832 })),
5833 // --- RESOLVE ---
5834 switchTap((/**
5835 * @param {?} t
5836 * @return {?}
5837 */
5838 t => {
5839 if (t.guards.canActivateChecks.length) {
5840 return of(t).pipe(tap((/**
5841 * @param {?} t
5842 * @return {?}
5843 */
5844 t => {
5845 /** @type {?} */
5846 const resolveStart = new ResolveStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)));
5847 this.triggerEvent(resolveStart);
5848 })), resolveData(this.paramsInheritanceStrategy, this.ngModule.injector), //
5849 tap((/**
5850 * @param {?} t
5851 * @return {?}
5852 */
5853 t => {
5854 /** @type {?} */
5855 const resolveEnd = new ResolveEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)));
5856 this.triggerEvent(resolveEnd);
5857 })));
5858 }
5859 return undefined;
5860 })),
5861 // --- AFTER PREACTIVATION ---
5862 switchTap((/**
5863 * @param {?} t
5864 * @return {?}
5865 */
5866 (t) => {
5867 const { targetSnapshot, id: navigationId, extractedUrl: appliedUrlTree, rawUrl: rawUrlTree, extras: { skipLocationChange, replaceUrl } } = t;
5868 return this.hooks.afterPreactivation((/** @type {?} */ (targetSnapshot)), {
5869 navigationId,
5870 appliedUrlTree,
5871 rawUrlTree,
5872 skipLocationChange: !!skipLocationChange,
5873 replaceUrl: !!replaceUrl,
5874 });
5875 })), map((/**
5876 * @param {?} t
5877 * @return {?}
5878 */
5879 (t) => {
5880 /** @type {?} */
5881 const targetRouterState = createRouterState(this.routeReuseStrategy, (/** @type {?} */ (t.targetSnapshot)), t.currentRouterState);
5882 return (Object.assign({}, t, { targetRouterState }));
5883 })),
5884 /* Once here, we are about to activate syncronously. The assumption is this will
5885 succeed, and user code may read from the Router service. Therefore before
5886 activation, we need to update router properties storing the current URL and the
5887 RouterState, as well as updated the browser URL. All this should happen *before*
5888 activating. */
5889 tap((/**
5890 * @param {?} t
5891 * @return {?}
5892 */
5893 (t) => {
5894 this.currentUrlTree = t.urlAfterRedirects;
5895 this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, t.rawUrl);
5896 ((/** @type {?} */ (this))).routerState = (/** @type {?} */ (t.targetRouterState));
5897 if (this.urlUpdateStrategy === 'deferred') {
5898 if (!t.extras.skipLocationChange) {
5899 this.setBrowserUrl(this.rawUrlTree, !!t.extras.replaceUrl, t.id, t.extras.state);
5900 }
5901 this.browserUrlTree = t.urlAfterRedirects;
5902 }
5903 })), activateRoutes(this.rootContexts, this.routeReuseStrategy, (/**
5904 * @param {?} evt
5905 * @return {?}
5906 */
5907 (evt) => this.triggerEvent(evt))), tap({ /**
5908 * @return {?}
5909 */
5910 next() { completed = true; }, /**
5911 * @return {?}
5912 */
5913 complete() { completed = true; } }), finalize((/**
5914 * @return {?}
5915 */
5916 () => {
5917 /* When the navigation stream finishes either through error or success, we set the
5918 * `completed` or `errored` flag. However, there are some situations where we could
5919 * get here without either of those being set. For instance, a redirect during
5920 * NavigationStart. Therefore, this is a catch-all to make sure the NavigationCancel
5921 * event is fired when a navigation gets cancelled but not caught by other means. */
5922 if (!completed && !errored) {
5923 // Must reset to current URL tree here to ensure history.state is set. On a fresh
5924 // page load, if a new navigation comes in before a successful navigation
5925 // completes, there will be nothing in history.state.navigationId. This can cause
5926 // sync problems with AngularJS sync code which looks for a value here in order
5927 // to determine whether or not to handle a given popstate event or to leave it
5928 // to the Angualr router.
5929 this.resetUrlToCurrentUrlTree();
5930 /** @type {?} */
5931 const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), `Navigation ID ${t.id} is not equal to the current navigation id ${this.navigationId}`);
5932 eventsSubject.next(navCancel);
5933 t.resolve(false);
5934 }
5935 // currentNavigation should always be reset to null here. If navigation was
5936 // successful, lastSuccessfulTransition will have already been set. Therefore we
5937 // can safely set currentNavigation to null here.
5938 this.currentNavigation = null;
5939 })), catchError((/**
5940 * @param {?} e
5941 * @return {?}
5942 */
5943 (e) => {
5944 errored = true;
5945 /* This error type is issued during Redirect, and is handled as a cancellation
5946 * rather than an error. */
5947 if (isNavigationCancelingError(e)) {
5948 /** @type {?} */
5949 const redirecting = isUrlTree(e.url);
5950 if (!redirecting) {
5951 // Set property only if we're not redirecting. If we landed on a page and
5952 // redirect to `/` route, the new navigation is going to see the `/` isn't
5953 // a change from the default currentUrlTree and won't navigate. This is
5954 // only applicable with initial navigation, so setting `navigated` only when
5955 // not redirecting resolves this scenario.
5956 this.navigated = true;
5957 this.resetStateAndUrl(t.currentRouterState, t.currentUrlTree, t.rawUrl);
5958 }
5959 /** @type {?} */
5960 const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), e.message);
5961 eventsSubject.next(navCancel);
5962 t.resolve(false);
5963 if (redirecting) {
5964 this.navigateByUrl(e.url);
5965 }
5966 /* All other errors should reset to the router's internal URL reference to the
5967 * pre-error state. */
5968 }
5969 else {
5970 this.resetStateAndUrl(t.currentRouterState, t.currentUrlTree, t.rawUrl);
5971 /** @type {?} */
5972 const navError = new NavigationError(t.id, this.serializeUrl(t.extractedUrl), e);
5973 eventsSubject.next(navError);
5974 try {
5975 t.resolve(this.errorHandler(e));
5976 }
5977 catch (ee) {
5978 t.reject(ee);
5979 }
5980 }
5981 return EMPTY;
5982 })));
5983 // TODO(jasonaden): remove cast once g3 is on updated TypeScript
5984 })))))));
5985 }
5986 /**
5987 * \@internal
5988 * TODO: this should be removed once the constructor of the router made internal
5989 * @param {?} rootComponentType
5990 * @return {?}
5991 */
5992 resetRootComponentType(rootComponentType) {
5993 this.rootComponentType = rootComponentType;
5994 // TODO: vsavkin router 4.0 should make the root component set to null
5995 // this will simplify the lifecycle of the router.
5996 this.routerState.root.component = this.rootComponentType;
5997 }
5998 /**
5999 * @private
6000 * @return {?}
6001 */
6002 getTransition() {
6003 /** @type {?} */
6004 const transition = this.transitions.value;
6005 // This value needs to be set. Other values such as extractedUrl are set on initial navigation
6006 // but the urlAfterRedirects may not get set if we aren't processing the new URL *and* not
6007 // processing the previous URL.
6008 transition.urlAfterRedirects = this.browserUrlTree;
6009 return transition;
6010 }
6011 /**
6012 * @private
6013 * @param {?} t
6014 * @return {?}
6015 */
6016 setTransition(t) {
6017 this.transitions.next(Object.assign({}, this.getTransition(), t));
6018 }
6019 /**
6020 * Sets up the location change listener and performs the initial navigation.
6021 * @return {?}
6022 */
6023 initialNavigation() {
6024 this.setUpLocationChangeListener();
6025 if (this.navigationId === 0) {
6026 this.navigateByUrl(this.location.path(true), { replaceUrl: true });
6027 }
6028 }
6029 /**
6030 * Sets up the location change listener.
6031 * @return {?}
6032 */
6033 setUpLocationChangeListener() {
6034 // Don't need to use Zone.wrap any more, because zone.js
6035 // already patch onPopState, so location change callback will
6036 // run into ngZone
6037 if (!this.locationSubscription) {
6038 this.locationSubscription = (/** @type {?} */ (this.location.subscribe((/**
6039 * @param {?} change
6040 * @return {?}
6041 */
6042 (change) => {
6043 /** @type {?} */
6044 let rawUrlTree = this.parseUrl(change['url']);
6045 /** @type {?} */
6046 const source = change['type'] === 'popstate' ? 'popstate' : 'hashchange';
6047 // Navigations coming from Angular router have a navigationId state property. When this
6048 // exists, restore the state.
6049 /** @type {?} */
6050 const state = change.state && change.state.navigationId ? change.state : null;
6051 setTimeout((/**
6052 * @return {?}
6053 */
6054 () => { this.scheduleNavigation(rawUrlTree, source, state, { replaceUrl: true }); }), 0);
6055 }))));
6056 }
6057 }
6058 /**
6059 * The current URL.
6060 * @return {?}
6061 */
6062 get url() { return this.serializeUrl(this.currentUrlTree); }
6063 /**
6064 * The current Navigation object if one exists
6065 * @return {?}
6066 */
6067 getCurrentNavigation() { return this.currentNavigation; }
6068 /**
6069 * \@internal
6070 * @param {?} event
6071 * @return {?}
6072 */
6073 triggerEvent(event) { ((/** @type {?} */ (this.events))).next(event); }
6074 /**
6075 * Resets the configuration used for navigation and generating links.
6076 *
6077 * \@usageNotes
6078 *
6079 * ```
6080 * router.resetConfig([
6081 * { path: 'team/:id', component: TeamCmp, children: [
6082 * { path: 'simple', component: SimpleCmp },
6083 * { path: 'user/:name', component: UserCmp }
6084 * ]}
6085 * ]);
6086 * ```
6087 * @param {?} config The route array for the new configuration.
6088 *
6089 * @return {?}
6090 */
6091 resetConfig(config) {
6092 validateConfig(config);
6093 this.config = config.map(standardizeConfig);
6094 this.navigated = false;
6095 this.lastSuccessfulId = -1;
6096 }
6097 /**
6098 * \@docsNotRequired
6099 * @return {?}
6100 */
6101 ngOnDestroy() { this.dispose(); }
6102 /**
6103 * Disposes of the router.
6104 * @return {?}
6105 */
6106 dispose() {
6107 if (this.locationSubscription) {
6108 this.locationSubscription.unsubscribe();
6109 this.locationSubscription = (/** @type {?} */ (null));
6110 }
6111 }
6112 /**
6113 * Applies an array of commands to the current URL tree and creates a new URL tree.
6114 *
6115 * When given an activate route, applies the given commands starting from the route.
6116 * When not given a route, applies the given command starting from the root.
6117 *
6118 * \@usageNotes
6119 *
6120 * ```
6121 * // create /team/33/user/11
6122 * router.createUrlTree(['/team', 33, 'user', 11]);
6123 *
6124 * // create /team/33;expand=true/user/11
6125 * router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
6126 *
6127 * // you can collapse static segments like this (this works only with the first passed-in value):
6128 * router.createUrlTree(['/team/33/user', userId]);
6129 *
6130 * // If the first segment can contain slashes, and you do not want the router to split it, you
6131 * // can do the following:
6132 *
6133 * router.createUrlTree([{segmentPath: '/one/two'}]);
6134 *
6135 * // create /team/33/(user/11//right:chat)
6136 * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: 'chat'}}]);
6137 *
6138 * // remove the right secondary node
6139 * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
6140 *
6141 * // assuming the current url is `/team/33/user/11` and the route points to `user/11`
6142 *
6143 * // navigate to /team/33/user/11/details
6144 * router.createUrlTree(['details'], {relativeTo: route});
6145 *
6146 * // navigate to /team/33/user/22
6147 * router.createUrlTree(['../22'], {relativeTo: route});
6148 *
6149 * // navigate to /team/44/user/22
6150 * router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
6151 * ```
6152 * @param {?} commands An array of commands to apply.
6153 * @param {?=} navigationExtras
6154 * @return {?} The new URL tree.
6155 *
6156 */
6157 createUrlTree(commands, navigationExtras = {}) {
6158 const { relativeTo, queryParams, fragment, preserveQueryParams, queryParamsHandling, preserveFragment } = navigationExtras;
6159 if (isDevMode() && preserveQueryParams && (/** @type {?} */ (console)) && (/** @type {?} */ (console.warn))) {
6160 console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
6161 }
6162 /** @type {?} */
6163 const a = relativeTo || this.routerState.root;
6164 /** @type {?} */
6165 const f = preserveFragment ? this.currentUrlTree.fragment : fragment;
6166 /** @type {?} */
6167 let q = null;
6168 if (queryParamsHandling) {
6169 switch (queryParamsHandling) {
6170 case 'merge':
6171 q = Object.assign({}, this.currentUrlTree.queryParams, queryParams);
6172 break;
6173 case 'preserve':
6174 q = this.currentUrlTree.queryParams;
6175 break;
6176 default:
6177 q = queryParams || null;
6178 }
6179 }
6180 else {
6181 q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams || null;
6182 }
6183 if (q !== null) {
6184 q = this.removeEmptyProps(q);
6185 }
6186 return createUrlTree(a, this.currentUrlTree, commands, (/** @type {?} */ (q)), (/** @type {?} */ (f)));
6187 }
6188 /**
6189 * Navigate based on the provided URL, which must be absolute.
6190 *
6191 * \@usageNotes
6192 *
6193 * ### Example
6194 *
6195 * ```
6196 * router.navigateByUrl("/team/33/user/11");
6197 *
6198 * // Navigate without updating the URL
6199 * router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
6200 * ```
6201 *
6202 * @param {?} url An absolute URL. The function does not apply any delta to the current URL.
6203 * @param {?=} extras An object containing properties that modify the navigation strategy.
6204 * The function ignores any properties in the `NavigationExtras` that would change the
6205 * provided URL.
6206 *
6207 * @return {?} A Promise that resolves to 'true' when navigation succeeds,
6208 * to 'false' when navigation fails, or is rejected on error.
6209 *
6210 */
6211 navigateByUrl(url, extras = { skipLocationChange: false }) {
6212 if (isDevMode() && this.isNgZoneEnabled && !NgZone.isInAngularZone()) {
6213 this.console.warn(`Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`);
6214 }
6215 /** @type {?} */
6216 const urlTree = isUrlTree(url) ? url : this.parseUrl(url);
6217 /** @type {?} */
6218 const mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
6219 return this.scheduleNavigation(mergedTree, 'imperative', null, extras);
6220 }
6221 /**
6222 * Navigate based on the provided array of commands and a starting point.
6223 * If no starting route is provided, the navigation is absolute.
6224 *
6225 * Returns a promise that:
6226 * - resolves to 'true' when navigation succeeds,
6227 * - resolves to 'false' when navigation fails,
6228 * - is rejected when an error happens.
6229 *
6230 * \@usageNotes
6231 *
6232 * ### Example
6233 *
6234 * ```
6235 * router.navigate(['team', 33, 'user', 11], {relativeTo: route});
6236 *
6237 * // Navigate without updating the URL
6238 * router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
6239 * ```
6240 *
6241 * The first parameter of `navigate()` is a delta to be applied to the current URL
6242 * or the one provided in the `relativeTo` property of the second parameter (the
6243 * `NavigationExtras`).
6244 *
6245 * In order to affect this browser's `history.state` entry, the `state`
6246 * parameter can be passed. This must be an object because the router
6247 * will add the `navigationId` property to this object before creating
6248 * the new history item.
6249 * @param {?} commands
6250 * @param {?=} extras
6251 * @return {?}
6252 */
6253 navigate(commands, extras = { skipLocationChange: false }) {
6254 validateCommands(commands);
6255 return this.navigateByUrl(this.createUrlTree(commands, extras), extras);
6256 }
6257 /**
6258 * Serializes a `UrlTree` into a string
6259 * @param {?} url
6260 * @return {?}
6261 */
6262 serializeUrl(url) { return this.urlSerializer.serialize(url); }
6263 /**
6264 * Parses a string into a `UrlTree`
6265 * @param {?} url
6266 * @return {?}
6267 */
6268 parseUrl(url) {
6269 /** @type {?} */
6270 let urlTree;
6271 try {
6272 urlTree = this.urlSerializer.parse(url);
6273 }
6274 catch (e) {
6275 urlTree = this.malformedUriErrorHandler(e, this.urlSerializer, url);
6276 }
6277 return urlTree;
6278 }
6279 /**
6280 * Returns whether the url is activated
6281 * @param {?} url
6282 * @param {?} exact
6283 * @return {?}
6284 */
6285 isActive(url, exact) {
6286 if (isUrlTree(url)) {
6287 return containsTree(this.currentUrlTree, url, exact);
6288 }
6289 /** @type {?} */
6290 const urlTree = this.parseUrl(url);
6291 return containsTree(this.currentUrlTree, urlTree, exact);
6292 }
6293 /**
6294 * @private
6295 * @param {?} params
6296 * @return {?}
6297 */
6298 removeEmptyProps(params) {
6299 return Object.keys(params).reduce((/**
6300 * @param {?} result
6301 * @param {?} key
6302 * @return {?}
6303 */
6304 (result, key) => {
6305 /** @type {?} */
6306 const value = params[key];
6307 if (value !== null && value !== undefined) {
6308 result[key] = value;
6309 }
6310 return result;
6311 }), {});
6312 }
6313 /**
6314 * @private
6315 * @return {?}
6316 */
6317 processNavigations() {
6318 this.navigations.subscribe((/**
6319 * @param {?} t
6320 * @return {?}
6321 */
6322 t => {
6323 this.navigated = true;
6324 this.lastSuccessfulId = t.id;
6325 ((/** @type {?} */ (this.events)))
6326 .next(new NavigationEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
6327 this.lastSuccessfulNavigation = this.currentNavigation;
6328 this.currentNavigation = null;
6329 t.resolve(true);
6330 }), (/**
6331 * @param {?} e
6332 * @return {?}
6333 */
6334 e => { this.console.warn(`Unhandled Navigation Error: `); }));
6335 }
6336 /**
6337 * @private
6338 * @param {?} rawUrl
6339 * @param {?} source
6340 * @param {?} restoredState
6341 * @param {?} extras
6342 * @return {?}
6343 */
6344 scheduleNavigation(rawUrl, source, restoredState, extras) {
6345 /** @type {?} */
6346 const lastNavigation = this.getTransition();
6347 // If the user triggers a navigation imperatively (e.g., by using navigateByUrl),
6348 // and that navigation results in 'replaceState' that leads to the same URL,
6349 // we should skip those.
6350 if (lastNavigation && source !== 'imperative' && lastNavigation.source === 'imperative' &&
6351 lastNavigation.rawUrl.toString() === rawUrl.toString()) {
6352 return Promise.resolve(true); // return value is not used
6353 }
6354 // Because of a bug in IE and Edge, the location class fires two events (popstate and
6355 // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
6356 // flicker. Handles the case when a popstate was emitted first.
6357 if (lastNavigation && source == 'hashchange' && lastNavigation.source === 'popstate' &&
6358 lastNavigation.rawUrl.toString() === rawUrl.toString()) {
6359 return Promise.resolve(true); // return value is not used
6360 }
6361 // Because of a bug in IE and Edge, the location class fires two events (popstate and
6362 // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
6363 // flicker. Handles the case when a hashchange was emitted first.
6364 if (lastNavigation && source == 'popstate' && lastNavigation.source === 'hashchange' &&
6365 lastNavigation.rawUrl.toString() === rawUrl.toString()) {
6366 return Promise.resolve(true); // return value is not used
6367 }
6368 /** @type {?} */
6369 let resolve = null;
6370 /** @type {?} */
6371 let reject = null;
6372 /** @type {?} */
6373 const promise = new Promise((/**
6374 * @param {?} res
6375 * @param {?} rej
6376 * @return {?}
6377 */
6378 (res, rej) => {
6379 resolve = res;
6380 reject = rej;
6381 }));
6382 /** @type {?} */
6383 const id = ++this.navigationId;
6384 this.setTransition({
6385 id,
6386 source,
6387 restoredState,
6388 currentUrlTree: this.currentUrlTree,
6389 currentRawUrl: this.rawUrlTree, rawUrl, extras, resolve, reject, promise,
6390 currentSnapshot: this.routerState.snapshot,
6391 currentRouterState: this.routerState
6392 });
6393 // Make sure that the error is propagated even though `processNavigations` catch
6394 // handler does not rethrow
6395 return promise.catch((/**
6396 * @param {?} e
6397 * @return {?}
6398 */
6399 (e) => { return Promise.reject(e); }));
6400 }
6401 /**
6402 * @private
6403 * @param {?} url
6404 * @param {?} replaceUrl
6405 * @param {?} id
6406 * @param {?=} state
6407 * @return {?}
6408 */
6409 setBrowserUrl(url, replaceUrl, id, state) {
6410 /** @type {?} */
6411 const path = this.urlSerializer.serialize(url);
6412 state = state || {};
6413 if (this.location.isCurrentPathEqualTo(path) || replaceUrl) {
6414 // TODO(jasonaden): Remove first `navigationId` and rely on `ng` namespace.
6415 this.location.replaceState(path, '', Object.assign({}, state, { navigationId: id }));
6416 }
6417 else {
6418 this.location.go(path, '', Object.assign({}, state, { navigationId: id }));
6419 }
6420 }
6421 /**
6422 * @private
6423 * @param {?} storedState
6424 * @param {?} storedUrl
6425 * @param {?} rawUrl
6426 * @return {?}
6427 */
6428 resetStateAndUrl(storedState, storedUrl, rawUrl) {
6429 ((/** @type {?} */ (this))).routerState = storedState;
6430 this.currentUrlTree = storedUrl;
6431 this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
6432 this.resetUrlToCurrentUrlTree();
6433 }
6434 /**
6435 * @private
6436 * @return {?}
6437 */
6438 resetUrlToCurrentUrlTree() {
6439 this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', { navigationId: this.lastSuccessfulId });
6440 }
6441}
6442/**
6443 * @param {?} commands
6444 * @return {?}
6445 */
6446function validateCommands(commands) {
6447 for (let i = 0; i < commands.length; i++) {
6448 /** @type {?} */
6449 const cmd = commands[i];
6450 if (cmd == null) {
6451 throw new Error(`The requested path contains ${cmd} segment at index ${i}`);
6452 }
6453 }
6454}
6455
6456/**
6457 * @fileoverview added by tsickle
6458 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
6459 */
6460/**
6461 * \@description
6462 *
6463 * Lets you link to specific routes in your app.
6464 *
6465 * Consider the following route configuration:
6466 * `[{ path: 'user/:name', component: UserCmp }]`.
6467 * When linking to this `user/:name` route, you use the `RouterLink` directive.
6468 *
6469 * If the link is static, you can use the directive as follows:
6470 * `<a routerLink="/user/bob">link to user component</a>`
6471 *
6472 * If you use dynamic values to generate the link, you can pass an array of path
6473 * segments, followed by the params for each segment.
6474 *
6475 * For instance `['/team', teamId, 'user', userName, {details: true}]`
6476 * means that we want to generate a link to `/team/11/user/bob;details=true`.
6477 *
6478 * Multiple static segments can be merged into one
6479 * (e.g., `['/team/11/user', userName, {details: true}]`).
6480 *
6481 * The first segment name can be prepended with `/`, `./`, or `../`:
6482 * * If the first segment begins with `/`, the router will look up the route from the root of the
6483 * app.
6484 * * If the first segment begins with `./`, or doesn't begin with a slash, the router will
6485 * instead look in the children of the current activated route.
6486 * * And if the first segment begins with `../`, the router will go up one level.
6487 *
6488 * You can set query params and fragment as follows:
6489 *
6490 * ```
6491 * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education">
6492 * link to user component
6493 * </a>
6494 * ```
6495 * RouterLink will use these to generate this link: `/user/bob#education?debug=true`.
6496 *
6497 * (Deprecated in v4.0.0 use `queryParamsHandling` instead) You can also tell the
6498 * directive to preserve the current query params and fragment:
6499 *
6500 * ```
6501 * <a [routerLink]="['/user/bob']" preserveQueryParams preserveFragment>
6502 * link to user component
6503 * </a>
6504 * ```
6505 *
6506 * You can tell the directive how to handle queryParams. Available options are:
6507 * - `'merge'`: merge the queryParams into the current queryParams
6508 * - `'preserve'`: preserve the current queryParams
6509 * - default/`''`: use the queryParams only
6510 *
6511 * Same options for {\@link NavigationExtras#queryParamsHandling
6512 * NavigationExtras#queryParamsHandling}.
6513 *
6514 * ```
6515 * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge">
6516 * link to user component
6517 * </a>
6518 * ```
6519 *
6520 * You can provide a `state` value to be persisted to the browser's History.state
6521 * property (See https://developer.mozilla.org/en-US/docs/Web/API/History#Properties). It's
6522 * used as follows:
6523 *
6524 * ```
6525 * <a [routerLink]="['/user/bob']" [state]="{tracingId: 123}">
6526 * link to user component
6527 * </a>
6528 * ```
6529 *
6530 * And later the value can be read from the router through `router.getCurrentNavigation`.
6531 * For example, to capture the `tracingId` above during the `NavigationStart` event:
6532 *
6533 * ```
6534 * // Get NavigationStart events
6535 * router.events.pipe(filter(e => e instanceof NavigationStart)).subscribe(e => {
6536 * const navigation = router.getCurrentNavigation();
6537 * tracingService.trace({id: navigation.extras.state.tracingId});
6538 * });
6539 * ```
6540 *
6541 * The router link directive always treats the provided input as a delta to the current url.
6542 *
6543 * For instance, if the current url is `/user/(box//aux:team)`.
6544 *
6545 * Then the following link `<a [routerLink]="['/user/jim']">Jim</a>` will generate the link
6546 * `/user/(jim//aux:team)`.
6547 *
6548 * See {\@link Router#createUrlTree createUrlTree} for more information.
6549 *
6550 * \@ngModule RouterModule
6551 *
6552 * \@publicApi
6553 */
6554class RouterLink {
6555 /**
6556 * @param {?} router
6557 * @param {?} route
6558 * @param {?} tabIndex
6559 * @param {?} renderer
6560 * @param {?} el
6561 */
6562 constructor(router, route, tabIndex, renderer, el) {
6563 this.router = router;
6564 this.route = route;
6565 this.commands = [];
6566 if (tabIndex == null) {
6567 renderer.setAttribute(el.nativeElement, 'tabindex', '0');
6568 }
6569 }
6570 /**
6571 * @param {?} commands
6572 * @return {?}
6573 */
6574 set routerLink(commands) {
6575 if (commands != null) {
6576 this.commands = Array.isArray(commands) ? commands : [commands];
6577 }
6578 else {
6579 this.commands = [];
6580 }
6581 }
6582 /**
6583 * @deprecated 4.0.0 use `queryParamsHandling` instead.
6584 * @param {?} value
6585 * @return {?}
6586 */
6587 set preserveQueryParams(value) {
6588 if (isDevMode() && (/** @type {?} */ (console)) && (/** @type {?} */ (console.warn))) {
6589 console.warn('preserveQueryParams is deprecated!, use queryParamsHandling instead.');
6590 }
6591 this.preserve = value;
6592 }
6593 /**
6594 * @return {?}
6595 */
6596 onClick() {
6597 /** @type {?} */
6598 const extras = {
6599 skipLocationChange: attrBoolValue(this.skipLocationChange),
6600 replaceUrl: attrBoolValue(this.replaceUrl),
6601 };
6602 this.router.navigateByUrl(this.urlTree, extras);
6603 return true;
6604 }
6605 /**
6606 * @return {?}
6607 */
6608 get urlTree() {
6609 return this.router.createUrlTree(this.commands, {
6610 relativeTo: this.route,
6611 queryParams: this.queryParams,
6612 fragment: this.fragment,
6613 preserveQueryParams: attrBoolValue(this.preserve),
6614 queryParamsHandling: this.queryParamsHandling,
6615 preserveFragment: attrBoolValue(this.preserveFragment),
6616 });
6617 }
6618}
6619RouterLink.decorators = [
6620 { type: Directive, args: [{ selector: ':not(a):not(area)[routerLink]' },] }
6621];
6622/** @nocollapse */
6623RouterLink.ctorParameters = () => [
6624 { type: Router },
6625 { type: ActivatedRoute },
6626 { type: String, decorators: [{ type: Attribute, args: ['tabindex',] }] },
6627 { type: Renderer2 },
6628 { type: ElementRef }
6629];
6630RouterLink.propDecorators = {
6631 queryParams: [{ type: Input }],
6632 fragment: [{ type: Input }],
6633 queryParamsHandling: [{ type: Input }],
6634 preserveFragment: [{ type: Input }],
6635 skipLocationChange: [{ type: Input }],
6636 replaceUrl: [{ type: Input }],
6637 state: [{ type: Input }],
6638 routerLink: [{ type: Input }],
6639 preserveQueryParams: [{ type: Input }],
6640 onClick: [{ type: HostListener, args: ['click',] }]
6641};
6642/**
6643 * \@description
6644 *
6645 * Lets you link to specific routes in your app.
6646 *
6647 * See `RouterLink` for more information.
6648 *
6649 * \@ngModule RouterModule
6650 *
6651 * \@publicApi
6652 */
6653class RouterLinkWithHref {
6654 /**
6655 * @param {?} router
6656 * @param {?} route
6657 * @param {?} locationStrategy
6658 */
6659 constructor(router, route, locationStrategy) {
6660 this.router = router;
6661 this.route = route;
6662 this.locationStrategy = locationStrategy;
6663 this.commands = [];
6664 this.subscription = router.events.subscribe((/**
6665 * @param {?} s
6666 * @return {?}
6667 */
6668 (s) => {
6669 if (s instanceof NavigationEnd) {
6670 this.updateTargetUrlAndHref();
6671 }
6672 }));
6673 }
6674 /**
6675 * @param {?} commands
6676 * @return {?}
6677 */
6678 set routerLink(commands) {
6679 if (commands != null) {
6680 this.commands = Array.isArray(commands) ? commands : [commands];
6681 }
6682 else {
6683 this.commands = [];
6684 }
6685 }
6686 /**
6687 * @param {?} value
6688 * @return {?}
6689 */
6690 set preserveQueryParams(value) {
6691 if (isDevMode() && (/** @type {?} */ (console)) && (/** @type {?} */ (console.warn))) {
6692 console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
6693 }
6694 this.preserve = value;
6695 }
6696 /**
6697 * @param {?} changes
6698 * @return {?}
6699 */
6700 ngOnChanges(changes) { this.updateTargetUrlAndHref(); }
6701 /**
6702 * @return {?}
6703 */
6704 ngOnDestroy() { this.subscription.unsubscribe(); }
6705 /**
6706 * @param {?} button
6707 * @param {?} ctrlKey
6708 * @param {?} metaKey
6709 * @param {?} shiftKey
6710 * @return {?}
6711 */
6712 onClick(button, ctrlKey, metaKey, shiftKey) {
6713 if (button !== 0 || ctrlKey || metaKey || shiftKey) {
6714 return true;
6715 }
6716 if (typeof this.target === 'string' && this.target != '_self') {
6717 return true;
6718 }
6719 /** @type {?} */
6720 const extras = {
6721 skipLocationChange: attrBoolValue(this.skipLocationChange),
6722 replaceUrl: attrBoolValue(this.replaceUrl),
6723 state: this.state
6724 };
6725 this.router.navigateByUrl(this.urlTree, extras);
6726 return false;
6727 }
6728 /**
6729 * @private
6730 * @return {?}
6731 */
6732 updateTargetUrlAndHref() {
6733 this.href = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.urlTree));
6734 }
6735 /**
6736 * @return {?}
6737 */
6738 get urlTree() {
6739 return this.router.createUrlTree(this.commands, {
6740 relativeTo: this.route,
6741 queryParams: this.queryParams,
6742 fragment: this.fragment,
6743 preserveQueryParams: attrBoolValue(this.preserve),
6744 queryParamsHandling: this.queryParamsHandling,
6745 preserveFragment: attrBoolValue(this.preserveFragment),
6746 });
6747 }
6748}
6749RouterLinkWithHref.decorators = [
6750 { type: Directive, args: [{ selector: 'a[routerLink],area[routerLink]' },] }
6751];
6752/** @nocollapse */
6753RouterLinkWithHref.ctorParameters = () => [
6754 { type: Router },
6755 { type: ActivatedRoute },
6756 { type: LocationStrategy }
6757];
6758RouterLinkWithHref.propDecorators = {
6759 target: [{ type: HostBinding, args: ['attr.target',] }, { type: Input }],
6760 queryParams: [{ type: Input }],
6761 fragment: [{ type: Input }],
6762 queryParamsHandling: [{ type: Input }],
6763 preserveFragment: [{ type: Input }],
6764 skipLocationChange: [{ type: Input }],
6765 replaceUrl: [{ type: Input }],
6766 state: [{ type: Input }],
6767 href: [{ type: HostBinding }],
6768 routerLink: [{ type: Input }],
6769 preserveQueryParams: [{ type: Input }],
6770 onClick: [{ type: HostListener, args: ['click', ['$event.button', '$event.ctrlKey', '$event.metaKey', '$event.shiftKey'],] }]
6771};
6772/**
6773 * @param {?} s
6774 * @return {?}
6775 */
6776function attrBoolValue(s) {
6777 return s === '' || !!s;
6778}
6779
6780/**
6781 * @fileoverview added by tsickle
6782 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
6783 */
6784/**
6785 *
6786 * \@description
6787 *
6788 * Lets you add a CSS class to an element when the link's route becomes active.
6789 *
6790 * This directive lets you add a CSS class to an element when the link's route
6791 * becomes active.
6792 *
6793 * Consider the following example:
6794 *
6795 * ```
6796 * <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
6797 * ```
6798 *
6799 * When the url is either '/user' or '/user/bob', the active-link class will
6800 * be added to the `a` tag. If the url changes, the class will be removed.
6801 *
6802 * You can set more than one class, as follows:
6803 *
6804 * ```
6805 * <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
6806 * <a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
6807 * ```
6808 *
6809 * You can configure RouterLinkActive by passing `exact: true`. This will add the classes
6810 * only when the url matches the link exactly.
6811 *
6812 * ```
6813 * <a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact:
6814 * true}">Bob</a>
6815 * ```
6816 *
6817 * You can assign the RouterLinkActive instance to a template variable and directly check
6818 * the `isActive` status.
6819 * ```
6820 * <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive">
6821 * Bob {{ rla.isActive ? '(already open)' : ''}}
6822 * </a>
6823 * ```
6824 *
6825 * Finally, you can apply the RouterLinkActive directive to an ancestor of a RouterLink.
6826 *
6827 * ```
6828 * <div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
6829 * <a routerLink="/user/jim">Jim</a>
6830 * <a routerLink="/user/bob">Bob</a>
6831 * </div>
6832 * ```
6833 *
6834 * This will set the active-link class on the div tag if the url is either '/user/jim' or
6835 * '/user/bob'.
6836 *
6837 * \@ngModule RouterModule
6838 *
6839 * \@publicApi
6840 */
6841class RouterLinkActive {
6842 /**
6843 * @param {?} router
6844 * @param {?} element
6845 * @param {?} renderer
6846 * @param {?=} link
6847 * @param {?=} linkWithHref
6848 */
6849 constructor(router, element, renderer, link, linkWithHref) {
6850 this.router = router;
6851 this.element = element;
6852 this.renderer = renderer;
6853 this.link = link;
6854 this.linkWithHref = linkWithHref;
6855 this.classes = [];
6856 this.isActive = false;
6857 this.routerLinkActiveOptions = { exact: false };
6858 this.subscription = router.events.subscribe((/**
6859 * @param {?} s
6860 * @return {?}
6861 */
6862 (s) => {
6863 if (s instanceof NavigationEnd) {
6864 this.update();
6865 }
6866 }));
6867 }
6868 /**
6869 * @return {?}
6870 */
6871 ngAfterContentInit() {
6872 this.links.changes.subscribe((/**
6873 * @param {?} _
6874 * @return {?}
6875 */
6876 _ => this.update()));
6877 this.linksWithHrefs.changes.subscribe((/**
6878 * @param {?} _
6879 * @return {?}
6880 */
6881 _ => this.update()));
6882 this.update();
6883 }
6884 /**
6885 * @param {?} data
6886 * @return {?}
6887 */
6888 set routerLinkActive(data) {
6889 /** @type {?} */
6890 const classes = Array.isArray(data) ? data : data.split(' ');
6891 this.classes = classes.filter((/**
6892 * @param {?} c
6893 * @return {?}
6894 */
6895 c => !!c));
6896 }
6897 /**
6898 * @param {?} changes
6899 * @return {?}
6900 */
6901 ngOnChanges(changes) { this.update(); }
6902 /**
6903 * @return {?}
6904 */
6905 ngOnDestroy() { this.subscription.unsubscribe(); }
6906 /**
6907 * @private
6908 * @return {?}
6909 */
6910 update() {
6911 if (!this.links || !this.linksWithHrefs || !this.router.navigated)
6912 return;
6913 Promise.resolve().then((/**
6914 * @return {?}
6915 */
6916 () => {
6917 /** @type {?} */
6918 const hasActiveLinks = this.hasActiveLinks();
6919 if (this.isActive !== hasActiveLinks) {
6920 ((/** @type {?} */ (this))).isActive = hasActiveLinks;
6921 this.classes.forEach((/**
6922 * @param {?} c
6923 * @return {?}
6924 */
6925 (c) => {
6926 if (hasActiveLinks) {
6927 this.renderer.addClass(this.element.nativeElement, c);
6928 }
6929 else {
6930 this.renderer.removeClass(this.element.nativeElement, c);
6931 }
6932 }));
6933 }
6934 }));
6935 }
6936 /**
6937 * @private
6938 * @param {?} router
6939 * @return {?}
6940 */
6941 isLinkActive(router) {
6942 return (/**
6943 * @param {?} link
6944 * @return {?}
6945 */
6946 (link) => router.isActive(link.urlTree, this.routerLinkActiveOptions.exact));
6947 }
6948 /**
6949 * @private
6950 * @return {?}
6951 */
6952 hasActiveLinks() {
6953 /** @type {?} */
6954 const isActiveCheckFn = this.isLinkActive(this.router);
6955 return this.link && isActiveCheckFn(this.link) ||
6956 this.linkWithHref && isActiveCheckFn(this.linkWithHref) ||
6957 this.links.some(isActiveCheckFn) || this.linksWithHrefs.some(isActiveCheckFn);
6958 }
6959}
6960RouterLinkActive.decorators = [
6961 { type: Directive, args: [{
6962 selector: '[routerLinkActive]',
6963 exportAs: 'routerLinkActive',
6964 },] }
6965];
6966/** @nocollapse */
6967RouterLinkActive.ctorParameters = () => [
6968 { type: Router },
6969 { type: ElementRef },
6970 { type: Renderer2 },
6971 { type: RouterLink, decorators: [{ type: Optional }] },
6972 { type: RouterLinkWithHref, decorators: [{ type: Optional }] }
6973];
6974RouterLinkActive.propDecorators = {
6975 links: [{ type: ContentChildren, args: [RouterLink, { descendants: true },] }],
6976 linksWithHrefs: [{ type: ContentChildren, args: [RouterLinkWithHref, { descendants: true },] }],
6977 routerLinkActiveOptions: [{ type: Input }],
6978 routerLinkActive: [{ type: Input }]
6979};
6980
6981/**
6982 * @fileoverview added by tsickle
6983 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
6984 */
6985/**
6986 * @license
6987 * Copyright Google Inc. All Rights Reserved.
6988 *
6989 * Use of this source code is governed by an MIT-style license that can be
6990 * found in the LICENSE file at https://angular.io/license
6991 */
6992/**
6993 * Store contextual information about a `RouterOutlet`
6994 *
6995 * \@publicApi
6996 */
6997class OutletContext {
6998 constructor() {
6999 this.outlet = null;
7000 this.route = null;
7001 this.resolver = null;
7002 this.children = new ChildrenOutletContexts();
7003 this.attachRef = null;
7004 }
7005}
7006/**
7007 * Store contextual information about the children (= nested) `RouterOutlet`
7008 *
7009 * \@publicApi
7010 */
7011class ChildrenOutletContexts {
7012 constructor() {
7013 // contexts for child outlets, by name.
7014 this.contexts = new Map();
7015 }
7016 /**
7017 * Called when a `RouterOutlet` directive is instantiated
7018 * @param {?} childName
7019 * @param {?} outlet
7020 * @return {?}
7021 */
7022 onChildOutletCreated(childName, outlet) {
7023 /** @type {?} */
7024 const context = this.getOrCreateContext(childName);
7025 context.outlet = outlet;
7026 this.contexts.set(childName, context);
7027 }
7028 /**
7029 * Called when a `RouterOutlet` directive is destroyed.
7030 * We need to keep the context as the outlet could be destroyed inside a NgIf and might be
7031 * re-created later.
7032 * @param {?} childName
7033 * @return {?}
7034 */
7035 onChildOutletDestroyed(childName) {
7036 /** @type {?} */
7037 const context = this.getContext(childName);
7038 if (context) {
7039 context.outlet = null;
7040 }
7041 }
7042 /**
7043 * Called when the corresponding route is deactivated during navigation.
7044 * Because the component get destroyed, all children outlet are destroyed.
7045 * @return {?}
7046 */
7047 onOutletDeactivated() {
7048 /** @type {?} */
7049 const contexts = this.contexts;
7050 this.contexts = new Map();
7051 return contexts;
7052 }
7053 /**
7054 * @param {?} contexts
7055 * @return {?}
7056 */
7057 onOutletReAttached(contexts) { this.contexts = contexts; }
7058 /**
7059 * @param {?} childName
7060 * @return {?}
7061 */
7062 getOrCreateContext(childName) {
7063 /** @type {?} */
7064 let context = this.getContext(childName);
7065 if (!context) {
7066 context = new OutletContext();
7067 this.contexts.set(childName, context);
7068 }
7069 return context;
7070 }
7071 /**
7072 * @param {?} childName
7073 * @return {?}
7074 */
7075 getContext(childName) { return this.contexts.get(childName) || null; }
7076}
7077
7078/**
7079 * @fileoverview added by tsickle
7080 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
7081 */
7082/**
7083 * \@description
7084 *
7085 * Acts as a placeholder that Angular dynamically fills based on the current router state.
7086 *
7087 * ```
7088 * <router-outlet></router-outlet>
7089 * <router-outlet name='left'></router-outlet>
7090 * <router-outlet name='right'></router-outlet>
7091 * ```
7092 *
7093 * A router outlet will emit an activate event any time a new component is being instantiated,
7094 * and a deactivate event when it is being destroyed.
7095 *
7096 * ```
7097 * <router-outlet
7098 * (activate)='onActivate($event)'
7099 * (deactivate)='onDeactivate($event)'></router-outlet>
7100 * ```
7101 * \@ngModule RouterModule
7102 *
7103 * \@publicApi
7104 */
7105class RouterOutlet {
7106 /**
7107 * @param {?} parentContexts
7108 * @param {?} location
7109 * @param {?} resolver
7110 * @param {?} name
7111 * @param {?} changeDetector
7112 */
7113 constructor(parentContexts, location, resolver, name, changeDetector) {
7114 this.parentContexts = parentContexts;
7115 this.location = location;
7116 this.resolver = resolver;
7117 this.changeDetector = changeDetector;
7118 this.activated = null;
7119 this._activatedRoute = null;
7120 this.activateEvents = new EventEmitter();
7121 this.deactivateEvents = new EventEmitter();
7122 this.name = name || PRIMARY_OUTLET;
7123 parentContexts.onChildOutletCreated(this.name, this);
7124 }
7125 /**
7126 * @return {?}
7127 */
7128 ngOnDestroy() { this.parentContexts.onChildOutletDestroyed(this.name); }
7129 /**
7130 * @return {?}
7131 */
7132 ngOnInit() {
7133 if (!this.activated) {
7134 // If the outlet was not instantiated at the time the route got activated we need to populate
7135 // the outlet when it is initialized (ie inside a NgIf)
7136 /** @type {?} */
7137 const context = this.parentContexts.getContext(this.name);
7138 if (context && context.route) {
7139 if (context.attachRef) {
7140 // `attachRef` is populated when there is an existing component to mount
7141 this.attach(context.attachRef, context.route);
7142 }
7143 else {
7144 // otherwise the component defined in the configuration is created
7145 this.activateWith(context.route, context.resolver || null);
7146 }
7147 }
7148 }
7149 }
7150 /**
7151 * @return {?}
7152 */
7153 get isActivated() { return !!this.activated; }
7154 /**
7155 * @return {?}
7156 */
7157 get component() {
7158 if (!this.activated)
7159 throw new Error('Outlet is not activated');
7160 return this.activated.instance;
7161 }
7162 /**
7163 * @return {?}
7164 */
7165 get activatedRoute() {
7166 if (!this.activated)
7167 throw new Error('Outlet is not activated');
7168 return (/** @type {?} */ (this._activatedRoute));
7169 }
7170 /**
7171 * @return {?}
7172 */
7173 get activatedRouteData() {
7174 if (this._activatedRoute) {
7175 return this._activatedRoute.snapshot.data;
7176 }
7177 return {};
7178 }
7179 /**
7180 * Called when the `RouteReuseStrategy` instructs to detach the subtree
7181 * @return {?}
7182 */
7183 detach() {
7184 if (!this.activated)
7185 throw new Error('Outlet is not activated');
7186 this.location.detach();
7187 /** @type {?} */
7188 const cmp = this.activated;
7189 this.activated = null;
7190 this._activatedRoute = null;
7191 return cmp;
7192 }
7193 /**
7194 * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
7195 * @param {?} ref
7196 * @param {?} activatedRoute
7197 * @return {?}
7198 */
7199 attach(ref, activatedRoute) {
7200 this.activated = ref;
7201 this._activatedRoute = activatedRoute;
7202 this.location.insert(ref.hostView);
7203 }
7204 /**
7205 * @return {?}
7206 */
7207 deactivate() {
7208 if (this.activated) {
7209 /** @type {?} */
7210 const c = this.component;
7211 this.activated.destroy();
7212 this.activated = null;
7213 this._activatedRoute = null;
7214 this.deactivateEvents.emit(c);
7215 }
7216 }
7217 /**
7218 * @param {?} activatedRoute
7219 * @param {?} resolver
7220 * @return {?}
7221 */
7222 activateWith(activatedRoute, resolver) {
7223 if (this.isActivated) {
7224 throw new Error('Cannot activate an already activated outlet');
7225 }
7226 this._activatedRoute = activatedRoute;
7227 /** @type {?} */
7228 const snapshot = activatedRoute._futureSnapshot;
7229 /** @type {?} */
7230 const component = (/** @type {?} */ ((/** @type {?} */ (snapshot.routeConfig)).component));
7231 resolver = resolver || this.resolver;
7232 /** @type {?} */
7233 const factory = resolver.resolveComponentFactory(component);
7234 /** @type {?} */
7235 const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
7236 /** @type {?} */
7237 const injector = new OutletInjector(activatedRoute, childContexts, this.location.injector);
7238 this.activated = this.location.createComponent(factory, this.location.length, injector);
7239 // Calling `markForCheck` to make sure we will run the change detection when the
7240 // `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
7241 this.changeDetector.markForCheck();
7242 this.activateEvents.emit(this.activated.instance);
7243 }
7244}
7245RouterOutlet.decorators = [
7246 { type: Directive, args: [{ selector: 'router-outlet', exportAs: 'outlet' },] }
7247];
7248/** @nocollapse */
7249RouterOutlet.ctorParameters = () => [
7250 { type: ChildrenOutletContexts },
7251 { type: ViewContainerRef },
7252 { type: ComponentFactoryResolver },
7253 { type: String, decorators: [{ type: Attribute, args: ['name',] }] },
7254 { type: ChangeDetectorRef }
7255];
7256RouterOutlet.propDecorators = {
7257 activateEvents: [{ type: Output, args: ['activate',] }],
7258 deactivateEvents: [{ type: Output, args: ['deactivate',] }]
7259};
7260class OutletInjector {
7261 /**
7262 * @param {?} route
7263 * @param {?} childContexts
7264 * @param {?} parent
7265 */
7266 constructor(route, childContexts, parent) {
7267 this.route = route;
7268 this.childContexts = childContexts;
7269 this.parent = parent;
7270 }
7271 /**
7272 * @param {?} token
7273 * @param {?=} notFoundValue
7274 * @return {?}
7275 */
7276 get(token, notFoundValue) {
7277 if (token === ActivatedRoute) {
7278 return this.route;
7279 }
7280 if (token === ChildrenOutletContexts) {
7281 return this.childContexts;
7282 }
7283 return this.parent.get(token, notFoundValue);
7284 }
7285}
7286
7287/**
7288 * @fileoverview added by tsickle
7289 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
7290 */
7291/**
7292 * \@description
7293 *
7294 * Provides a preloading strategy.
7295 *
7296 * \@publicApi
7297 * @abstract
7298 */
7299class PreloadingStrategy {
7300}
7301/**
7302 * \@description
7303 *
7304 * Provides a preloading strategy that preloads all modules as quickly as possible.
7305 *
7306 * ```
7307 * RouteModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules})
7308 * ```
7309 *
7310 * \@publicApi
7311 */
7312class PreloadAllModules {
7313 /**
7314 * @param {?} route
7315 * @param {?} fn
7316 * @return {?}
7317 */
7318 preload(route, fn) {
7319 return fn().pipe(catchError((/**
7320 * @return {?}
7321 */
7322 () => of(null))));
7323 }
7324}
7325/**
7326 * \@description
7327 *
7328 * Provides a preloading strategy that does not preload any modules.
7329 *
7330 * This strategy is enabled by default.
7331 *
7332 * \@publicApi
7333 */
7334class NoPreloading {
7335 /**
7336 * @param {?} route
7337 * @param {?} fn
7338 * @return {?}
7339 */
7340 preload(route, fn) { return of(null); }
7341}
7342/**
7343 * The preloader optimistically loads all router configurations to
7344 * make navigations into lazily-loaded sections of the application faster.
7345 *
7346 * The preloader runs in the background. When the router bootstraps, the preloader
7347 * starts listening to all navigation events. After every such event, the preloader
7348 * will check if any configurations can be loaded lazily.
7349 *
7350 * If a route is protected by `canLoad` guards, the preloaded will not load it.
7351 *
7352 * \@publicApi
7353 */
7354class RouterPreloader {
7355 /**
7356 * @param {?} router
7357 * @param {?} moduleLoader
7358 * @param {?} compiler
7359 * @param {?} injector
7360 * @param {?} preloadingStrategy
7361 */
7362 constructor(router, moduleLoader, compiler, injector, preloadingStrategy) {
7363 this.router = router;
7364 this.injector = injector;
7365 this.preloadingStrategy = preloadingStrategy;
7366 /** @type {?} */
7367 const onStartLoad = (/**
7368 * @param {?} r
7369 * @return {?}
7370 */
7371 (r) => router.triggerEvent(new RouteConfigLoadStart(r)));
7372 /** @type {?} */
7373 const onEndLoad = (/**
7374 * @param {?} r
7375 * @return {?}
7376 */
7377 (r) => router.triggerEvent(new RouteConfigLoadEnd(r)));
7378 this.loader = new RouterConfigLoader(moduleLoader, compiler, onStartLoad, onEndLoad);
7379 }
7380 /**
7381 * @return {?}
7382 */
7383 setUpPreloading() {
7384 this.subscription =
7385 this.router.events
7386 .pipe(filter((/**
7387 * @param {?} e
7388 * @return {?}
7389 */
7390 (e) => e instanceof NavigationEnd)), concatMap((/**
7391 * @return {?}
7392 */
7393 () => this.preload())))
7394 .subscribe((/**
7395 * @return {?}
7396 */
7397 () => { }));
7398 }
7399 /**
7400 * @return {?}
7401 */
7402 preload() {
7403 /** @type {?} */
7404 const ngModule = this.injector.get(NgModuleRef);
7405 return this.processRoutes(ngModule, this.router.config);
7406 }
7407 // TODO(jasonaden): This class relies on code external to the class to call setUpPreloading. If
7408 // this hasn't been done, ngOnDestroy will fail as this.subscription will be undefined. This
7409 // should be refactored.
7410 /**
7411 * @return {?}
7412 */
7413 ngOnDestroy() { this.subscription.unsubscribe(); }
7414 /**
7415 * @private
7416 * @param {?} ngModule
7417 * @param {?} routes
7418 * @return {?}
7419 */
7420 processRoutes(ngModule, routes) {
7421 /** @type {?} */
7422 const res = [];
7423 for (const route of routes) {
7424 // we already have the config loaded, just recurse
7425 if (route.loadChildren && !route.canLoad && route._loadedConfig) {
7426 /** @type {?} */
7427 const childConfig = route._loadedConfig;
7428 res.push(this.processRoutes(childConfig.module, childConfig.routes));
7429 // no config loaded, fetch the config
7430 }
7431 else if (route.loadChildren && !route.canLoad) {
7432 res.push(this.preloadConfig(ngModule, route));
7433 // recurse into children
7434 }
7435 else if (route.children) {
7436 res.push(this.processRoutes(ngModule, route.children));
7437 }
7438 }
7439 return from(res).pipe(mergeAll(), map((/**
7440 * @param {?} _
7441 * @return {?}
7442 */
7443 (_) => void 0)));
7444 }
7445 /**
7446 * @private
7447 * @param {?} ngModule
7448 * @param {?} route
7449 * @return {?}
7450 */
7451 preloadConfig(ngModule, route) {
7452 return this.preloadingStrategy.preload(route, (/**
7453 * @return {?}
7454 */
7455 () => {
7456 /** @type {?} */
7457 const loaded$ = this.loader.load(ngModule.injector, route);
7458 return loaded$.pipe(mergeMap((/**
7459 * @param {?} config
7460 * @return {?}
7461 */
7462 (config) => {
7463 route._loadedConfig = config;
7464 return this.processRoutes(config.module, config.routes);
7465 })));
7466 }));
7467 }
7468}
7469RouterPreloader.decorators = [
7470 { type: Injectable }
7471];
7472/** @nocollapse */
7473RouterPreloader.ctorParameters = () => [
7474 { type: Router },
7475 { type: NgModuleFactoryLoader },
7476 { type: Compiler },
7477 { type: Injector },
7478 { type: PreloadingStrategy }
7479];
7480
7481/**
7482 * @fileoverview added by tsickle
7483 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
7484 */
7485class RouterScroller {
7486 /**
7487 * @param {?} router
7488 * @param {?} viewportScroller
7489 * @param {?=} options
7490 */
7491 constructor(router, viewportScroller, options = {}) {
7492 this.router = router;
7493 this.viewportScroller = viewportScroller;
7494 this.options = options;
7495 this.lastId = 0;
7496 this.lastSource = 'imperative';
7497 this.restoredId = 0;
7498 this.store = {};
7499 // Default both options to 'disabled'
7500 options.scrollPositionRestoration = options.scrollPositionRestoration || 'disabled';
7501 options.anchorScrolling = options.anchorScrolling || 'disabled';
7502 }
7503 /**
7504 * @return {?}
7505 */
7506 init() {
7507 // we want to disable the automatic scrolling because having two places
7508 // responsible for scrolling results race conditions, especially given
7509 // that browser don't implement this behavior consistently
7510 if (this.options.scrollPositionRestoration !== 'disabled') {
7511 this.viewportScroller.setHistoryScrollRestoration('manual');
7512 }
7513 this.routerEventsSubscription = this.createScrollEvents();
7514 this.scrollEventsSubscription = this.consumeScrollEvents();
7515 }
7516 /**
7517 * @private
7518 * @return {?}
7519 */
7520 createScrollEvents() {
7521 return this.router.events.subscribe((/**
7522 * @param {?} e
7523 * @return {?}
7524 */
7525 e => {
7526 if (e instanceof NavigationStart) {
7527 // store the scroll position of the current stable navigations.
7528 this.store[this.lastId] = this.viewportScroller.getScrollPosition();
7529 this.lastSource = e.navigationTrigger;
7530 this.restoredId = e.restoredState ? e.restoredState.navigationId : 0;
7531 }
7532 else if (e instanceof NavigationEnd) {
7533 this.lastId = e.id;
7534 this.scheduleScrollEvent(e, this.router.parseUrl(e.urlAfterRedirects).fragment);
7535 }
7536 }));
7537 }
7538 /**
7539 * @private
7540 * @return {?}
7541 */
7542 consumeScrollEvents() {
7543 return this.router.events.subscribe((/**
7544 * @param {?} e
7545 * @return {?}
7546 */
7547 e => {
7548 if (!(e instanceof Scroll))
7549 return;
7550 // a popstate event. The pop state event will always ignore anchor scrolling.
7551 if (e.position) {
7552 if (this.options.scrollPositionRestoration === 'top') {
7553 this.viewportScroller.scrollToPosition([0, 0]);
7554 }
7555 else if (this.options.scrollPositionRestoration === 'enabled') {
7556 this.viewportScroller.scrollToPosition(e.position);
7557 }
7558 // imperative navigation "forward"
7559 }
7560 else {
7561 if (e.anchor && this.options.anchorScrolling === 'enabled') {
7562 this.viewportScroller.scrollToAnchor(e.anchor);
7563 }
7564 else if (this.options.scrollPositionRestoration !== 'disabled') {
7565 this.viewportScroller.scrollToPosition([0, 0]);
7566 }
7567 }
7568 }));
7569 }
7570 /**
7571 * @private
7572 * @param {?} routerEvent
7573 * @param {?} anchor
7574 * @return {?}
7575 */
7576 scheduleScrollEvent(routerEvent, anchor) {
7577 this.router.triggerEvent(new Scroll(routerEvent, this.lastSource === 'popstate' ? this.store[this.restoredId] : null, anchor));
7578 }
7579 /**
7580 * @return {?}
7581 */
7582 ngOnDestroy() {
7583 if (this.routerEventsSubscription) {
7584 this.routerEventsSubscription.unsubscribe();
7585 }
7586 if (this.scrollEventsSubscription) {
7587 this.scrollEventsSubscription.unsubscribe();
7588 }
7589 }
7590}
7591
7592/**
7593 * @fileoverview added by tsickle
7594 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
7595 */
7596/**
7597 * \@description
7598 *
7599 * Contains a list of directives
7600 *
7601 *
7602 * @type {?}
7603 */
7604const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent];
7605/**
7606 * \@description
7607 *
7608 * Is used in DI to configure the router.
7609 *
7610 * \@publicApi
7611 * @type {?}
7612 */
7613const ROUTER_CONFIGURATION = new InjectionToken('ROUTER_CONFIGURATION');
7614/**
7615 * \@docsNotRequired
7616 * @type {?}
7617 */
7618const ROUTER_FORROOT_GUARD = new InjectionToken('ROUTER_FORROOT_GUARD');
7619const ɵ0 = { enableTracing: false };
7620/** @type {?} */
7621const ROUTER_PROVIDERS = [
7622 Location,
7623 { provide: UrlSerializer, useClass: DefaultUrlSerializer },
7624 {
7625 provide: Router,
7626 useFactory: setupRouter,
7627 deps: [
7628 ApplicationRef, UrlSerializer, ChildrenOutletContexts, Location, Injector,
7629 NgModuleFactoryLoader, Compiler, ROUTES, ROUTER_CONFIGURATION,
7630 [UrlHandlingStrategy, new Optional()], [RouteReuseStrategy, new Optional()]
7631 ]
7632 },
7633 ChildrenOutletContexts,
7634 { provide: ActivatedRoute, useFactory: rootRoute, deps: [Router] },
7635 { provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader },
7636 RouterPreloader,
7637 NoPreloading,
7638 PreloadAllModules,
7639 { provide: ROUTER_CONFIGURATION, useValue: ɵ0 },
7640];
7641/**
7642 * @return {?}
7643 */
7644function routerNgProbeToken() {
7645 return new NgProbeToken('Router', Router);
7646}
7647/**
7648 * \@usageNotes
7649 *
7650 * RouterModule can be imported multiple times: once per lazily-loaded bundle.
7651 * Since the router deals with a global shared resource--location, we cannot have
7652 * more than one router service active.
7653 *
7654 * That is why there are two ways to create the module: `RouterModule.forRoot` and
7655 * `RouterModule.forChild`.
7656 *
7657 * * `forRoot` creates a module that contains all the directives, the given routes, and the router
7658 * service itself.
7659 * * `forChild` creates a module that contains all the directives and the given routes, but does not
7660 * include the router service.
7661 *
7662 * When registered at the root, the module should be used as follows
7663 *
7664 * ```
7665 * \@NgModule({
7666 * imports: [RouterModule.forRoot(ROUTES)]
7667 * })
7668 * class MyNgModule {}
7669 * ```
7670 *
7671 * For submodules and lazy loaded submodules the module should be used as follows:
7672 *
7673 * ```
7674 * \@NgModule({
7675 * imports: [RouterModule.forChild(ROUTES)]
7676 * })
7677 * class MyNgModule {}
7678 * ```
7679 *
7680 * \@description
7681 *
7682 * Adds router directives and providers.
7683 *
7684 * Managing state transitions is one of the hardest parts of building applications. This is
7685 * especially true on the web, where you also need to ensure that the state is reflected in the URL.
7686 * In addition, we often want to split applications into multiple bundles and load them on demand.
7687 * Doing this transparently is not trivial.
7688 *
7689 * The Angular router solves these problems. Using the router, you can declaratively specify
7690 * application states, manage state transitions while taking care of the URL, and load bundles on
7691 * demand.
7692 *
7693 * [Read this developer guide](https://angular.io/docs/ts/latest/guide/router.html) to get an
7694 * overview of how the router should be used.
7695 *
7696 * \@publicApi
7697 */
7698class RouterModule {
7699 // Note: We are injecting the Router so it gets created eagerly...
7700 /**
7701 * @param {?} guard
7702 * @param {?} router
7703 */
7704 constructor(guard, router) { }
7705 /**
7706 * Creates a module with all the router providers and directives. It also optionally sets up an
7707 * application listener to perform an initial navigation.
7708 *
7709 * Configuration Options:
7710 *
7711 * * `enableTracing` Toggles whether the router should log all navigation events to the console.
7712 * * `useHash` Enables the location strategy that uses the URL fragment instead of the history
7713 * API.
7714 * * `initialNavigation` Disables the initial navigation.
7715 * * `errorHandler` Defines a custom error handler for failed navigations.
7716 * * `preloadingStrategy` Configures a preloading strategy. See `PreloadAllModules`.
7717 * * `onSameUrlNavigation` Define what the router should do if it receives a navigation request to
7718 * the current URL.
7719 * * `scrollPositionRestoration` Configures if the scroll position needs to be restored when
7720 * navigating back.
7721 * * `anchorScrolling` Configures if the router should scroll to the element when the url has a
7722 * fragment.
7723 * * `scrollOffset` Configures the scroll offset the router will use when scrolling to an element.
7724 * * `paramsInheritanceStrategy` Defines how the router merges params, data and resolved data from
7725 * parent to child routes.
7726 * * `malformedUriErrorHandler` Defines a custom malformed uri error handler function. This
7727 * handler is invoked when encodedURI contains invalid character sequences.
7728 * * `urlUpdateStrategy` Defines when the router updates the browser URL. The default behavior is
7729 * to update after successful navigation.
7730 * * `relativeLinkResolution` Enables the correct relative link resolution in components with
7731 * empty paths.
7732 *
7733 * See `ExtraOptions` for more details about the above options.
7734 * @param {?} routes
7735 * @param {?=} config
7736 * @return {?}
7737 */
7738 static forRoot(routes, config) {
7739 return {
7740 ngModule: RouterModule,
7741 providers: [
7742 ROUTER_PROVIDERS,
7743 provideRoutes(routes),
7744 {
7745 provide: ROUTER_FORROOT_GUARD,
7746 useFactory: provideForRootGuard,
7747 deps: [[Router, new Optional(), new SkipSelf()]]
7748 },
7749 { provide: ROUTER_CONFIGURATION, useValue: config ? config : {} },
7750 {
7751 provide: LocationStrategy,
7752 useFactory: provideLocationStrategy,
7753 deps: [
7754 PlatformLocation, [new Inject(APP_BASE_HREF), new Optional()], ROUTER_CONFIGURATION
7755 ]
7756 },
7757 {
7758 provide: RouterScroller,
7759 useFactory: createRouterScroller,
7760 deps: [Router, ViewportScroller, ROUTER_CONFIGURATION]
7761 },
7762 {
7763 provide: PreloadingStrategy,
7764 useExisting: config && config.preloadingStrategy ? config.preloadingStrategy :
7765 NoPreloading
7766 },
7767 { provide: NgProbeToken, multi: true, useFactory: routerNgProbeToken },
7768 provideRouterInitializer(),
7769 ],
7770 };
7771 }
7772 /**
7773 * Creates a module with all the router directives and a provider registering routes.
7774 * @param {?} routes
7775 * @return {?}
7776 */
7777 static forChild(routes) {
7778 return { ngModule: RouterModule, providers: [provideRoutes(routes)] };
7779 }
7780}
7781RouterModule.decorators = [
7782 { type: NgModule, args: [{
7783 declarations: ROUTER_DIRECTIVES,
7784 exports: ROUTER_DIRECTIVES,
7785 entryComponents: [ɵEmptyOutletComponent]
7786 },] }
7787];
7788/** @nocollapse */
7789RouterModule.ctorParameters = () => [
7790 { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [ROUTER_FORROOT_GUARD,] }] },
7791 { type: Router, decorators: [{ type: Optional }] }
7792];
7793/**
7794 * @param {?} router
7795 * @param {?} viewportScroller
7796 * @param {?} config
7797 * @return {?}
7798 */
7799function createRouterScroller(router, viewportScroller, config) {
7800 if (config.scrollOffset) {
7801 viewportScroller.setOffset(config.scrollOffset);
7802 }
7803 return new RouterScroller(router, viewportScroller, config);
7804}
7805/**
7806 * @param {?} platformLocationStrategy
7807 * @param {?} baseHref
7808 * @param {?=} options
7809 * @return {?}
7810 */
7811function provideLocationStrategy(platformLocationStrategy, baseHref, options = {}) {
7812 return options.useHash ? new HashLocationStrategy(platformLocationStrategy, baseHref) :
7813 new PathLocationStrategy(platformLocationStrategy, baseHref);
7814}
7815/**
7816 * @param {?} router
7817 * @return {?}
7818 */
7819function provideForRootGuard(router) {
7820 if (router) {
7821 throw new Error(`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
7822 }
7823 return 'guarded';
7824}
7825/**
7826 * \@description
7827 *
7828 * Registers routes.
7829 *
7830 * \@usageNotes
7831 * ### Example
7832 *
7833 * ```
7834 * \@NgModule({
7835 * imports: [RouterModule.forChild(ROUTES)],
7836 * providers: [provideRoutes(EXTRA_ROUTES)]
7837 * })
7838 * class MyNgModule {}
7839 * ```
7840 *
7841 * \@publicApi
7842 * @param {?} routes
7843 * @return {?}
7844 */
7845function provideRoutes(routes) {
7846 return [
7847 { provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes },
7848 { provide: ROUTES, multi: true, useValue: routes },
7849 ];
7850}
7851/**
7852 * @param {?} ref
7853 * @param {?} urlSerializer
7854 * @param {?} contexts
7855 * @param {?} location
7856 * @param {?} injector
7857 * @param {?} loader
7858 * @param {?} compiler
7859 * @param {?} config
7860 * @param {?=} opts
7861 * @param {?=} urlHandlingStrategy
7862 * @param {?=} routeReuseStrategy
7863 * @return {?}
7864 */
7865function setupRouter(ref, urlSerializer, contexts, location, injector, loader, compiler, config, opts = {}, urlHandlingStrategy, routeReuseStrategy) {
7866 /** @type {?} */
7867 const router = new Router(null, urlSerializer, contexts, location, injector, loader, compiler, flatten(config));
7868 if (urlHandlingStrategy) {
7869 router.urlHandlingStrategy = urlHandlingStrategy;
7870 }
7871 if (routeReuseStrategy) {
7872 router.routeReuseStrategy = routeReuseStrategy;
7873 }
7874 if (opts.errorHandler) {
7875 router.errorHandler = opts.errorHandler;
7876 }
7877 if (opts.malformedUriErrorHandler) {
7878 router.malformedUriErrorHandler = opts.malformedUriErrorHandler;
7879 }
7880 if (opts.enableTracing) {
7881 /** @type {?} */
7882 const dom = ɵgetDOM();
7883 router.events.subscribe((/**
7884 * @param {?} e
7885 * @return {?}
7886 */
7887 (e) => {
7888 dom.logGroup(`Router Event: ${((/** @type {?} */ (e.constructor))).name}`);
7889 dom.log(e.toString());
7890 dom.log(e);
7891 dom.logGroupEnd();
7892 }));
7893 }
7894 if (opts.onSameUrlNavigation) {
7895 router.onSameUrlNavigation = opts.onSameUrlNavigation;
7896 }
7897 if (opts.paramsInheritanceStrategy) {
7898 router.paramsInheritanceStrategy = opts.paramsInheritanceStrategy;
7899 }
7900 if (opts.urlUpdateStrategy) {
7901 router.urlUpdateStrategy = opts.urlUpdateStrategy;
7902 }
7903 if (opts.relativeLinkResolution) {
7904 router.relativeLinkResolution = opts.relativeLinkResolution;
7905 }
7906 return router;
7907}
7908/**
7909 * @param {?} router
7910 * @return {?}
7911 */
7912function rootRoute(router) {
7913 return router.routerState.root;
7914}
7915/**
7916 * To initialize the router properly we need to do in two steps:
7917 *
7918 * We need to start the navigation in a APP_INITIALIZER to block the bootstrap if
7919 * a resolver or a guards executes asynchronously. Second, we need to actually run
7920 * activation in a BOOTSTRAP_LISTENER. We utilize the afterPreactivation
7921 * hook provided by the router to do that.
7922 *
7923 * The router navigation starts, reaches the point when preactivation is done, and then
7924 * pauses. It waits for the hook to be resolved. We then resolve it only in a bootstrap listener.
7925 */
7926class RouterInitializer {
7927 /**
7928 * @param {?} injector
7929 */
7930 constructor(injector) {
7931 this.injector = injector;
7932 this.initNavigation = false;
7933 this.resultOfPreactivationDone = new Subject();
7934 }
7935 /**
7936 * @return {?}
7937 */
7938 appInitializer() {
7939 /** @type {?} */
7940 const p = this.injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
7941 return p.then((/**
7942 * @return {?}
7943 */
7944 () => {
7945 /** @type {?} */
7946 let resolve = (/** @type {?} */ (null));
7947 /** @type {?} */
7948 const res = new Promise((/**
7949 * @param {?} r
7950 * @return {?}
7951 */
7952 r => resolve = r));
7953 /** @type {?} */
7954 const router = this.injector.get(Router);
7955 /** @type {?} */
7956 const opts = this.injector.get(ROUTER_CONFIGURATION);
7957 if (this.isLegacyDisabled(opts) || this.isLegacyEnabled(opts)) {
7958 resolve(true);
7959 }
7960 else if (opts.initialNavigation === 'disabled') {
7961 router.setUpLocationChangeListener();
7962 resolve(true);
7963 }
7964 else if (opts.initialNavigation === 'enabled') {
7965 router.hooks.afterPreactivation = (/**
7966 * @return {?}
7967 */
7968 () => {
7969 // only the initial navigation should be delayed
7970 if (!this.initNavigation) {
7971 this.initNavigation = true;
7972 resolve(true);
7973 return this.resultOfPreactivationDone;
7974 // subsequent navigations should not be delayed
7975 }
7976 else {
7977 return (/** @type {?} */ (of(null)));
7978 }
7979 });
7980 router.initialNavigation();
7981 }
7982 else {
7983 throw new Error(`Invalid initialNavigation options: '${opts.initialNavigation}'`);
7984 }
7985 return res;
7986 }));
7987 }
7988 /**
7989 * @param {?} bootstrappedComponentRef
7990 * @return {?}
7991 */
7992 bootstrapListener(bootstrappedComponentRef) {
7993 /** @type {?} */
7994 const opts = this.injector.get(ROUTER_CONFIGURATION);
7995 /** @type {?} */
7996 const preloader = this.injector.get(RouterPreloader);
7997 /** @type {?} */
7998 const routerScroller = this.injector.get(RouterScroller);
7999 /** @type {?} */
8000 const router = this.injector.get(Router);
8001 /** @type {?} */
8002 const ref = this.injector.get(ApplicationRef);
8003 if (bootstrappedComponentRef !== ref.components[0]) {
8004 return;
8005 }
8006 if (this.isLegacyEnabled(opts)) {
8007 router.initialNavigation();
8008 }
8009 else if (this.isLegacyDisabled(opts)) {
8010 router.setUpLocationChangeListener();
8011 }
8012 preloader.setUpPreloading();
8013 routerScroller.init();
8014 router.resetRootComponentType(ref.componentTypes[0]);
8015 this.resultOfPreactivationDone.next((/** @type {?} */ (null)));
8016 this.resultOfPreactivationDone.complete();
8017 }
8018 /**
8019 * @private
8020 * @param {?} opts
8021 * @return {?}
8022 */
8023 isLegacyEnabled(opts) {
8024 return opts.initialNavigation === 'legacy_enabled' || opts.initialNavigation === true ||
8025 opts.initialNavigation === undefined;
8026 }
8027 /**
8028 * @private
8029 * @param {?} opts
8030 * @return {?}
8031 */
8032 isLegacyDisabled(opts) {
8033 return opts.initialNavigation === 'legacy_disabled' || opts.initialNavigation === false;
8034 }
8035}
8036RouterInitializer.decorators = [
8037 { type: Injectable }
8038];
8039/** @nocollapse */
8040RouterInitializer.ctorParameters = () => [
8041 { type: Injector }
8042];
8043/**
8044 * @param {?} r
8045 * @return {?}
8046 */
8047function getAppInitializer(r) {
8048 return r.appInitializer.bind(r);
8049}
8050/**
8051 * @param {?} r
8052 * @return {?}
8053 */
8054function getBootstrapListener(r) {
8055 return r.bootstrapListener.bind(r);
8056}
8057/**
8058 * A token for the router initializer that will be called after the app is bootstrapped.
8059 *
8060 * \@publicApi
8061 * @type {?}
8062 */
8063const ROUTER_INITIALIZER = new InjectionToken('Router Initializer');
8064/**
8065 * @return {?}
8066 */
8067function provideRouterInitializer() {
8068 return [
8069 RouterInitializer,
8070 {
8071 provide: APP_INITIALIZER,
8072 multi: true,
8073 useFactory: getAppInitializer,
8074 deps: [RouterInitializer]
8075 },
8076 { provide: ROUTER_INITIALIZER, useFactory: getBootstrapListener, deps: [RouterInitializer] },
8077 { provide: APP_BOOTSTRAP_LISTENER, multi: true, useExisting: ROUTER_INITIALIZER },
8078 ];
8079}
8080
8081/**
8082 * @fileoverview added by tsickle
8083 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
8084 */
8085/**
8086 * \@publicApi
8087 * @type {?}
8088 */
8089const VERSION = new Version('8.0.2');
8090
8091/**
8092 * @fileoverview added by tsickle
8093 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
8094 */
8095
8096/**
8097 * @fileoverview added by tsickle
8098 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
8099 */
8100
8101/**
8102 * @fileoverview added by tsickle
8103 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
8104 */
8105
8106/**
8107 * @fileoverview added by tsickle
8108 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
8109 */
8110
8111/**
8112 * Generated bundle index. Do not edit.
8113 */
8114
8115export { ɵEmptyOutletComponent as ɵangular_packages_router_router_l, ɵEmptyOutletComponent, ROUTER_FORROOT_GUARD as ɵangular_packages_router_router_a, RouterInitializer as ɵangular_packages_router_router_h, createRouterScroller as ɵangular_packages_router_router_c, getAppInitializer as ɵangular_packages_router_router_i, getBootstrapListener as ɵangular_packages_router_router_j, provideForRootGuard as ɵangular_packages_router_router_e, provideLocationStrategy as ɵangular_packages_router_router_d, provideRouterInitializer as ɵangular_packages_router_router_k, rootRoute as ɵangular_packages_router_router_g, routerNgProbeToken as ɵangular_packages_router_router_b, setupRouter as ɵangular_packages_router_router_f, RouterScroller as ɵangular_packages_router_router_o, Tree as ɵangular_packages_router_router_m, TreeNode as ɵangular_packages_router_router_n, RouterLink, RouterLinkWithHref, RouterLinkActive, RouterOutlet, ActivationEnd, ActivationStart, ChildActivationEnd, ChildActivationStart, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized, Scroll, RouteReuseStrategy, Router, ROUTES, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, RouterModule, provideRoutes, ChildrenOutletContexts, OutletContext, NoPreloading, PreloadAllModules, PreloadingStrategy, RouterPreloader, ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, PRIMARY_OUTLET, convertToParamMap, UrlHandlingStrategy, DefaultUrlSerializer, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree, VERSION, ROUTER_PROVIDERS as ɵROUTER_PROVIDERS, flatten as ɵflatten };
8116//# sourceMappingURL=router.js.map