/** * @license Angular v21.1.1 * (c) 2010-2026 Google LLC. https://angular.dev/ * License: MIT */ import { DOCUMENT, Location } from '@angular/common'; import * as i0 from '@angular/core'; import { ɵisPromise as _isPromise, computed, ɵRuntimeError as _RuntimeError, Injectable, InjectionToken, EventEmitter, input, inject, ViewContainerRef, ChangeDetectorRef, Directive, Input, Output, reflectComponentType, Component, runInInjectionContext, ɵisInjectable as _isInjectable, ɵisNgModule as _isNgModule, isStandalone, createEnvironmentInjector, Compiler, NgModuleFactory, ɵresolveComponentResources as _resolveComponentResources, afterNextRender, signal, EnvironmentInjector, DestroyRef, untracked, ɵConsole as _Console, ɵPendingTasksInternal as _PendingTasksInternal, ɵINTERNAL_APPLICATION_ERROR_HANDLER as _INTERNAL_APPLICATION_ERROR_HANDLER, ɵformatRuntimeError as _formatRuntimeError } from '@angular/core'; import { isObservable, from, of, BehaviorSubject, combineLatest, EmptyError, Observable, concat, defer, pipe, EMPTY, throwError, Subject, Subscription } from 'rxjs'; import { first, map, switchMap, take, startWith, filter, takeUntil, mergeMap, concatMap, tap, takeLast, catchError, finalize } from 'rxjs/operators'; import * as i1 from '@angular/platform-browser'; const PRIMARY_OUTLET = 'primary'; const RouteTitleKey = /* @__PURE__ */Symbol('RouteTitle'); class ParamsAsMap { params; constructor(params) { this.params = params || {}; } has(name) { return Object.prototype.hasOwnProperty.call(this.params, name); } get(name) { if (this.has(name)) { const v = this.params[name]; return Array.isArray(v) ? v[0] : v; } return null; } getAll(name) { if (this.has(name)) { const v = this.params[name]; return Array.isArray(v) ? v : [v]; } return []; } get keys() { return Object.keys(this.params); } } function convertToParamMap(params) { return new ParamsAsMap(params); } function matchParts(routeParts, urlSegments, posParams) { for (let i = 0; i < routeParts.length; i++) { const part = routeParts[i]; const segment = urlSegments[i]; const isParameter = part[0] === ':'; if (isParameter) { posParams[part.substring(1)] = segment; } else if (part !== segment.path) { return false; } } return true; } function defaultUrlMatcher(segments, segmentGroup, route) { const parts = route.path.split('/'); const wildcardIndex = parts.indexOf('**'); if (wildcardIndex === -1) { if (parts.length > segments.length) { return null; } if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || parts.length < segments.length)) { return null; } const posParams = {}; const consumed = segments.slice(0, parts.length); if (!matchParts(parts, consumed, posParams)) { return null; } return { consumed, posParams }; } if (wildcardIndex !== parts.lastIndexOf('**')) { return null; } const pre = parts.slice(0, wildcardIndex); const post = parts.slice(wildcardIndex + 1); if (pre.length + post.length > segments.length) { return null; } if (route.pathMatch === 'full' && segmentGroup.hasChildren() && route.path !== '**') { return null; } const posParams = {}; if (!matchParts(pre, segments.slice(0, pre.length), posParams)) { return null; } if (!matchParts(post, segments.slice(segments.length - post.length), posParams)) { return null; } return { consumed: segments, posParams }; } function firstValueFrom(source) { return new Promise((resolve, reject) => { source.pipe(first()).subscribe({ next: value => resolve(value), error: err => reject(err) }); }); } function shallowEqualArrays(a, b) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; ++i) { if (!shallowEqual(a[i], b[i])) return false; } return true; } function shallowEqual(a, b) { const k1 = a ? getDataKeys(a) : undefined; const k2 = b ? getDataKeys(b) : undefined; if (!k1 || !k2 || k1.length != k2.length) { return false; } let key; for (let i = 0; i < k1.length; i++) { key = k1[i]; if (!equalArraysOrString(a[key], b[key])) { return false; } } return true; } function getDataKeys(obj) { return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)]; } function equalArraysOrString(a, b) { if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; const aSorted = [...a].sort(); const bSorted = [...b].sort(); return aSorted.every((val, index) => bSorted[index] === val); } else { return a === b; } } function last(a) { return a.length > 0 ? a[a.length - 1] : null; } function wrapIntoObservable(value) { if (isObservable(value)) { return value; } if (_isPromise(value)) { return from(Promise.resolve(value)); } return of(value); } function wrapIntoPromise(value) { if (isObservable(value)) { return firstValueFrom(value); } return Promise.resolve(value); } const pathCompareMap = { 'exact': equalSegmentGroups, 'subset': containsSegmentGroup }; const paramCompareMap = { 'exact': equalParams, 'subset': containsParams, 'ignored': () => true }; function isActive(url, router, matchOptions) { const urlTree = url instanceof UrlTree ? url : router.parseUrl(url); return computed(() => containsTree(router.lastSuccessfulNavigation()?.finalUrl ?? new UrlTree(), urlTree, matchOptions)); } function containsTree(container, containee, options) { return pathCompareMap[options.paths](container.root, containee.root, options.matrixParams) && paramCompareMap[options.queryParams](container.queryParams, containee.queryParams) && !(options.fragment === 'exact' && container.fragment !== containee.fragment); } function equalParams(container, containee) { return shallowEqual(container, containee); } function equalSegmentGroups(container, containee, matrixParams) { if (!equalPath(container.segments, containee.segments)) return false; if (!matrixParamsMatch(container.segments, containee.segments, matrixParams)) { return false; } if (container.numberOfChildren !== containee.numberOfChildren) return false; for (const c in containee.children) { if (!container.children[c]) return false; if (!equalSegmentGroups(container.children[c], containee.children[c], matrixParams)) return false; } return true; } function containsParams(container, containee) { return Object.keys(containee).length <= Object.keys(container).length && Object.keys(containee).every(key => equalArraysOrString(container[key], containee[key])); } function containsSegmentGroup(container, containee, matrixParams) { return containsSegmentGroupHelper(container, containee, containee.segments, matrixParams); } function containsSegmentGroupHelper(container, containee, containeePaths, matrixParams) { if (container.segments.length > containeePaths.length) { const current = container.segments.slice(0, containeePaths.length); if (!equalPath(current, containeePaths)) return false; if (containee.hasChildren()) return false; if (!matrixParamsMatch(current, containeePaths, matrixParams)) return false; return true; } else if (container.segments.length === containeePaths.length) { if (!equalPath(container.segments, containeePaths)) return false; if (!matrixParamsMatch(container.segments, containeePaths, matrixParams)) return false; for (const c in containee.children) { if (!container.children[c]) return false; if (!containsSegmentGroup(container.children[c], containee.children[c], matrixParams)) { return false; } } return true; } else { const current = containeePaths.slice(0, container.segments.length); const next = containeePaths.slice(container.segments.length); if (!equalPath(container.segments, current)) return false; if (!matrixParamsMatch(container.segments, current, matrixParams)) return false; if (!container.children[PRIMARY_OUTLET]) return false; return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next, matrixParams); } } function matrixParamsMatch(containerPaths, containeePaths, options) { return containeePaths.every((containeeSegment, i) => { return paramCompareMap[options](containerPaths[i].parameters, containeeSegment.parameters); }); } class UrlTree { root; queryParams; fragment; _queryParamMap; constructor(root = new UrlSegmentGroup([], {}), queryParams = {}, fragment = null) { this.root = root; this.queryParams = queryParams; this.fragment = fragment; if (typeof ngDevMode === 'undefined' || ngDevMode) { if (root.segments.length > 0) { throw new _RuntimeError(4015, 'The root `UrlSegmentGroup` should not contain `segments`. ' + 'Instead, these segments belong in the `children` so they can be associated with a named outlet.'); } } } get queryParamMap() { this._queryParamMap ??= convertToParamMap(this.queryParams); return this._queryParamMap; } toString() { return DEFAULT_SERIALIZER.serialize(this); } } class UrlSegmentGroup { segments; children; parent = null; constructor(segments, children) { this.segments = segments; this.children = children; Object.values(children).forEach(v => v.parent = this); } hasChildren() { return this.numberOfChildren > 0; } get numberOfChildren() { return Object.keys(this.children).length; } toString() { return serializePaths(this); } } class UrlSegment { path; parameters; _parameterMap; constructor(path, parameters) { this.path = path; this.parameters = parameters; } get parameterMap() { this._parameterMap ??= convertToParamMap(this.parameters); return this._parameterMap; } toString() { return serializePath(this); } } function equalSegments(as, bs) { return equalPath(as, bs) && as.every((a, i) => shallowEqual(a.parameters, bs[i].parameters)); } function equalPath(as, bs) { if (as.length !== bs.length) return false; return as.every((a, i) => a.path === bs[i].path); } function mapChildrenIntoArray(segment, fn) { let res = []; Object.entries(segment.children).forEach(([childOutlet, child]) => { if (childOutlet === PRIMARY_OUTLET) { res = res.concat(fn(child, childOutlet)); } }); Object.entries(segment.children).forEach(([childOutlet, child]) => { if (childOutlet !== PRIMARY_OUTLET) { res = res.concat(fn(child, childOutlet)); } }); return res; } class UrlSerializer { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: UrlSerializer, decorators: [{ type: Injectable, args: [{ providedIn: 'root', useFactory: () => new DefaultUrlSerializer() }] }] }); class DefaultUrlSerializer { parse(url) { const p = new UrlParser(url); return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment()); } serialize(tree) { const segment = `/${serializeSegment(tree.root, true)}`; const query = serializeQueryParams(tree.queryParams); const fragment = typeof tree.fragment === `string` ? `#${encodeUriFragment(tree.fragment)}` : ''; return `${segment}${query}${fragment}`; } } const DEFAULT_SERIALIZER = new DefaultUrlSerializer(); function serializePaths(segment) { return segment.segments.map(p => serializePath(p)).join('/'); } function serializeSegment(segment, root) { if (!segment.hasChildren()) { return serializePaths(segment); } if (root) { const primary = segment.children[PRIMARY_OUTLET] ? serializeSegment(segment.children[PRIMARY_OUTLET], false) : ''; const children = []; Object.entries(segment.children).forEach(([k, v]) => { if (k !== PRIMARY_OUTLET) { children.push(`${k}:${serializeSegment(v, false)}`); } }); return children.length > 0 ? `${primary}(${children.join('//')})` : primary; } else { const children = mapChildrenIntoArray(segment, (v, k) => { if (k === PRIMARY_OUTLET) { return [serializeSegment(segment.children[PRIMARY_OUTLET], false)]; } return [`${k}:${serializeSegment(v, false)}`]; }); if (Object.keys(segment.children).length === 1 && segment.children[PRIMARY_OUTLET] != null) { return `${serializePaths(segment)}/${children[0]}`; } return `${serializePaths(segment)}/(${children.join('//')})`; } } function encodeUriString(s) { return encodeURIComponent(s).replace(/%40/g, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ','); } function encodeUriQuery(s) { return encodeUriString(s).replace(/%3B/gi, ';'); } function encodeUriFragment(s) { return encodeURI(s); } function encodeUriSegment(s) { return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&'); } function decode(s) { return decodeURIComponent(s); } function decodeQuery(s) { return decode(s.replace(/\+/g, '%20')); } function serializePath(path) { return `${encodeUriSegment(path.path)}${serializeMatrixParams(path.parameters)}`; } function serializeMatrixParams(params) { return Object.entries(params).map(([key, value]) => `;${encodeUriSegment(key)}=${encodeUriSegment(value)}`).join(''); } function serializeQueryParams(params) { const strParams = Object.entries(params).map(([name, value]) => { return Array.isArray(value) ? value.map(v => `${encodeUriQuery(name)}=${encodeUriQuery(v)}`).join('&') : `${encodeUriQuery(name)}=${encodeUriQuery(value)}`; }).filter(s => s); return strParams.length ? `?${strParams.join('&')}` : ''; } const SEGMENT_RE = /^[^\/()?;#]+/; function matchSegments(str) { const match = str.match(SEGMENT_RE); return match ? match[0] : ''; } const MATRIX_PARAM_SEGMENT_RE = /^[^\/()?;=#]+/; function matchMatrixKeySegments(str) { const match = str.match(MATRIX_PARAM_SEGMENT_RE); return match ? match[0] : ''; } const QUERY_PARAM_RE = /^[^=?&#]+/; function matchQueryParams(str) { const match = str.match(QUERY_PARAM_RE); return match ? match[0] : ''; } const QUERY_PARAM_VALUE_RE = /^[^&#]+/; function matchUrlQueryParamValue(str) { const match = str.match(QUERY_PARAM_VALUE_RE); return match ? match[0] : ''; } class UrlParser { url; remaining; constructor(url) { this.url = url; this.remaining = url; } parseRootSegment() { this.consumeOptional('/'); if (this.remaining === '' || this.peekStartsWith('?') || this.peekStartsWith('#')) { return new UrlSegmentGroup([], {}); } return new UrlSegmentGroup([], this.parseChildren()); } parseQueryParams() { const params = {}; if (this.consumeOptional('?')) { do { this.parseQueryParam(params); } while (this.consumeOptional('&')); } return params; } parseFragment() { return this.consumeOptional('#') ? decodeURIComponent(this.remaining) : null; } parseChildren() { if (this.remaining === '') { return {}; } this.consumeOptional('/'); const segments = []; if (!this.peekStartsWith('(')) { segments.push(this.parseSegment()); } while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) { this.capture('/'); segments.push(this.parseSegment()); } let children = {}; if (this.peekStartsWith('/(')) { this.capture('/'); children = this.parseParens(true); } let res = {}; if (this.peekStartsWith('(')) { res = this.parseParens(false); } if (segments.length > 0 || Object.keys(children).length > 0) { res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children); } return res; } parseSegment() { const path = matchSegments(this.remaining); if (path === '' && this.peekStartsWith(';')) { throw new _RuntimeError(4009, (typeof ngDevMode === 'undefined' || ngDevMode) && `Empty path url segment cannot have parameters: '${this.remaining}'.`); } this.capture(path); return new UrlSegment(decode(path), this.parseMatrixParams()); } parseMatrixParams() { const params = {}; while (this.consumeOptional(';')) { this.parseParam(params); } return params; } parseParam(params) { const key = matchMatrixKeySegments(this.remaining); if (!key) { return; } this.capture(key); let value = ''; if (this.consumeOptional('=')) { const valueMatch = matchSegments(this.remaining); if (valueMatch) { value = valueMatch; this.capture(value); } } params[decode(key)] = decode(value); } parseQueryParam(params) { const key = matchQueryParams(this.remaining); if (!key) { return; } this.capture(key); let value = ''; if (this.consumeOptional('=')) { const valueMatch = matchUrlQueryParamValue(this.remaining); if (valueMatch) { value = valueMatch; this.capture(value); } } const decodedKey = decodeQuery(key); const decodedVal = decodeQuery(value); if (params.hasOwnProperty(decodedKey)) { let currentVal = params[decodedKey]; if (!Array.isArray(currentVal)) { currentVal = [currentVal]; params[decodedKey] = currentVal; } currentVal.push(decodedVal); } else { params[decodedKey] = decodedVal; } } parseParens(allowPrimary) { const segments = {}; this.capture('('); while (!this.consumeOptional(')') && this.remaining.length > 0) { const path = matchSegments(this.remaining); const next = this.remaining[path.length]; if (next !== '/' && next !== ')' && next !== ';') { throw new _RuntimeError(4010, (typeof ngDevMode === 'undefined' || ngDevMode) && `Cannot parse url '${this.url}'`); } let outletName; if (path.indexOf(':') > -1) { outletName = path.slice(0, path.indexOf(':')); this.capture(outletName); this.capture(':'); } else if (allowPrimary) { outletName = PRIMARY_OUTLET; } const children = this.parseChildren(); segments[outletName ?? PRIMARY_OUTLET] = Object.keys(children).length === 1 && children[PRIMARY_OUTLET] ? children[PRIMARY_OUTLET] : new UrlSegmentGroup([], children); this.consumeOptional('//'); } return segments; } peekStartsWith(str) { return this.remaining.startsWith(str); } consumeOptional(str) { if (this.peekStartsWith(str)) { this.remaining = this.remaining.substring(str.length); return true; } return false; } capture(str) { if (!this.consumeOptional(str)) { throw new _RuntimeError(4011, (typeof ngDevMode === 'undefined' || ngDevMode) && `Expected "${str}".`); } } } function createRoot(rootCandidate) { return rootCandidate.segments.length > 0 ? new UrlSegmentGroup([], { [PRIMARY_OUTLET]: rootCandidate }) : rootCandidate; } function squashSegmentGroup(segmentGroup) { const newChildren = {}; for (const [childOutlet, child] of Object.entries(segmentGroup.children)) { const childCandidate = squashSegmentGroup(child); if (childOutlet === PRIMARY_OUTLET && childCandidate.segments.length === 0 && childCandidate.hasChildren()) { for (const [grandChildOutlet, grandChild] of Object.entries(childCandidate.children)) { newChildren[grandChildOutlet] = grandChild; } } else if (childCandidate.segments.length > 0 || childCandidate.hasChildren()) { newChildren[childOutlet] = childCandidate; } } const s = new UrlSegmentGroup(segmentGroup.segments, newChildren); return mergeTrivialChildren(s); } function mergeTrivialChildren(s) { if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) { const c = s.children[PRIMARY_OUTLET]; return new UrlSegmentGroup(s.segments.concat(c.segments), c.children); } return s; } function isUrlTree(v) { return v instanceof UrlTree; } function createUrlTreeFromSnapshot(relativeTo, commands, queryParams = null, fragment = null, urlSerializer = new DefaultUrlSerializer()) { const relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeTo); return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, queryParams, fragment, urlSerializer); } function createSegmentGroupFromRoute(route) { let targetGroup; function createSegmentGroupFromRouteRecursive(currentRoute) { const childOutlets = {}; for (const childSnapshot of currentRoute.children) { const root = createSegmentGroupFromRouteRecursive(childSnapshot); childOutlets[childSnapshot.outlet] = root; } const segmentGroup = new UrlSegmentGroup(currentRoute.url, childOutlets); if (currentRoute === route) { targetGroup = segmentGroup; } return segmentGroup; } const rootCandidate = createSegmentGroupFromRouteRecursive(route.root); const rootSegmentGroup = createRoot(rootCandidate); return targetGroup ?? rootSegmentGroup; } function createUrlTreeFromSegmentGroup(relativeTo, commands, queryParams, fragment, urlSerializer) { let root = relativeTo; while (root.parent) { root = root.parent; } if (commands.length === 0) { return tree(root, root, root, queryParams, fragment, urlSerializer); } const nav = computeNavigation(commands); if (nav.toRoot()) { return tree(root, root, new UrlSegmentGroup([], {}), queryParams, fragment, urlSerializer); } const position = findStartingPositionForTargetGroup(nav, root, relativeTo); const newSegmentGroup = position.processChildren ? updateSegmentGroupChildren(position.segmentGroup, position.index, nav.commands) : updateSegmentGroup(position.segmentGroup, position.index, nav.commands); return tree(root, position.segmentGroup, newSegmentGroup, queryParams, fragment, urlSerializer); } function isMatrixParams(command) { return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath; } function isCommandWithOutlets(command) { return typeof command === 'object' && command != null && command.outlets; } function normalizeQueryParams(k, v, urlSerializer) { k ||= 'ɵ'; const tree = new UrlTree(); tree.queryParams = { [k]: v }; return urlSerializer.parse(urlSerializer.serialize(tree)).queryParams[k]; } function tree(oldRoot, oldSegmentGroup, newSegmentGroup, queryParams, fragment, urlSerializer) { const qp = {}; for (const [key, value] of Object.entries(queryParams ?? {})) { qp[key] = Array.isArray(value) ? value.map(v => normalizeQueryParams(key, v, urlSerializer)) : normalizeQueryParams(key, value, urlSerializer); } let rootCandidate; if (oldRoot === oldSegmentGroup) { rootCandidate = newSegmentGroup; } else { rootCandidate = replaceSegment(oldRoot, oldSegmentGroup, newSegmentGroup); } const newRoot = createRoot(squashSegmentGroup(rootCandidate)); return new UrlTree(newRoot, qp, fragment); } function replaceSegment(current, oldSegment, newSegment) { const children = {}; Object.entries(current.children).forEach(([outletName, c]) => { if (c === oldSegment) { children[outletName] = newSegment; } else { children[outletName] = replaceSegment(c, oldSegment, newSegment); } }); return new UrlSegmentGroup(current.segments, children); } class Navigation { isAbsolute; numberOfDoubleDots; commands; constructor(isAbsolute, numberOfDoubleDots, commands) { this.isAbsolute = isAbsolute; this.numberOfDoubleDots = numberOfDoubleDots; this.commands = commands; if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) { throw new _RuntimeError(4003, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Root segment cannot have matrix parameters'); } const cmdWithOutlet = commands.find(isCommandWithOutlets); if (cmdWithOutlet && cmdWithOutlet !== last(commands)) { throw new _RuntimeError(4004, (typeof ngDevMode === 'undefined' || ngDevMode) && '{outlets:{}} has to be the last command'); } } toRoot() { return this.isAbsolute && this.commands.length === 1 && this.commands[0] == '/'; } } function computeNavigation(commands) { if (typeof commands[0] === 'string' && commands.length === 1 && commands[0] === '/') { return new Navigation(true, 0, commands); } let numberOfDoubleDots = 0; let isAbsolute = false; const res = commands.reduce((res, cmd, cmdIdx) => { if (typeof cmd === 'object' && cmd != null) { if (cmd.outlets) { const outlets = {}; Object.entries(cmd.outlets).forEach(([name, commands]) => { outlets[name] = typeof commands === 'string' ? commands.split('/') : commands; }); return [...res, { outlets }]; } if (cmd.segmentPath) { return [...res, cmd.segmentPath]; } } if (!(typeof cmd === 'string')) { return [...res, cmd]; } if (cmdIdx === 0) { cmd.split('/').forEach((urlPart, partIndex) => { if (partIndex == 0 && urlPart === '.') ; else if (partIndex == 0 && urlPart === '') { isAbsolute = true; } else if (urlPart === '..') { numberOfDoubleDots++; } else if (urlPart != '') { res.push(urlPart); } }); return res; } return [...res, cmd]; }, []); return new Navigation(isAbsolute, numberOfDoubleDots, res); } class Position { segmentGroup; processChildren; index; constructor(segmentGroup, processChildren, index) { this.segmentGroup = segmentGroup; this.processChildren = processChildren; this.index = index; } } function findStartingPositionForTargetGroup(nav, root, target) { if (nav.isAbsolute) { return new Position(root, true, 0); } if (!target) { return new Position(root, false, NaN); } if (target.parent === null) { return new Position(target, true, 0); } const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1; const index = target.segments.length - 1 + modifier; return createPositionApplyingDoubleDots(target, index, nav.numberOfDoubleDots); } function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) { let g = group; let ci = index; let dd = numberOfDoubleDots; while (dd > ci) { dd -= ci; g = g.parent; if (!g) { throw new _RuntimeError(4005, (typeof ngDevMode === 'undefined' || ngDevMode) && "Invalid number of '../'"); } ci = g.segments.length; } return new Position(g, false, ci - dd); } function getOutlets(commands) { if (isCommandWithOutlets(commands[0])) { return commands[0].outlets; } return { [PRIMARY_OUTLET]: commands }; } function updateSegmentGroup(segmentGroup, startIndex, commands) { segmentGroup ??= new UrlSegmentGroup([], {}); if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) { return updateSegmentGroupChildren(segmentGroup, startIndex, commands); } const m = prefixedWith(segmentGroup, startIndex, commands); const slicedCommands = commands.slice(m.commandIndex); if (m.match && m.pathIndex < segmentGroup.segments.length) { const g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {}); g.children[PRIMARY_OUTLET] = new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children); return updateSegmentGroupChildren(g, 0, slicedCommands); } else if (m.match && slicedCommands.length === 0) { return new UrlSegmentGroup(segmentGroup.segments, {}); } else if (m.match && !segmentGroup.hasChildren()) { return createNewSegmentGroup(segmentGroup, startIndex, commands); } else if (m.match) { return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands); } else { return createNewSegmentGroup(segmentGroup, startIndex, commands); } } function updateSegmentGroupChildren(segmentGroup, startIndex, commands) { if (commands.length === 0) { return new UrlSegmentGroup(segmentGroup.segments, {}); } else { const outlets = getOutlets(commands); const children = {}; if (Object.keys(outlets).some(o => o !== PRIMARY_OUTLET) && segmentGroup.children[PRIMARY_OUTLET] && segmentGroup.numberOfChildren === 1 && segmentGroup.children[PRIMARY_OUTLET].segments.length === 0) { const childrenOfEmptyChild = updateSegmentGroupChildren(segmentGroup.children[PRIMARY_OUTLET], startIndex, commands); return new UrlSegmentGroup(segmentGroup.segments, childrenOfEmptyChild.children); } Object.entries(outlets).forEach(([outlet, commands]) => { if (typeof commands === 'string') { commands = [commands]; } if (commands !== null) { children[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands); } }); Object.entries(segmentGroup.children).forEach(([childOutlet, child]) => { if (outlets[childOutlet] === undefined) { children[childOutlet] = child; } }); return new UrlSegmentGroup(segmentGroup.segments, children); } } function prefixedWith(segmentGroup, startIndex, commands) { let currentCommandIndex = 0; let currentPathIndex = startIndex; const noMatch = { match: false, pathIndex: 0, commandIndex: 0 }; while (currentPathIndex < segmentGroup.segments.length) { if (currentCommandIndex >= commands.length) return noMatch; const path = segmentGroup.segments[currentPathIndex]; const command = commands[currentCommandIndex]; if (isCommandWithOutlets(command)) { break; } const curr = `${command}`; const next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null; if (currentPathIndex > 0 && curr === undefined) break; if (curr && next && typeof next === 'object' && next.outlets === undefined) { if (!compare(curr, next, path)) return noMatch; currentCommandIndex += 2; } else { if (!compare(curr, {}, path)) return noMatch; currentCommandIndex++; } currentPathIndex++; } return { match: true, pathIndex: currentPathIndex, commandIndex: currentCommandIndex }; } function createNewSegmentGroup(segmentGroup, startIndex, commands) { const paths = segmentGroup.segments.slice(0, startIndex); let i = 0; while (i < commands.length) { const command = commands[i]; if (isCommandWithOutlets(command)) { const children = createNewSegmentChildren(command.outlets); return new UrlSegmentGroup(paths, children); } if (i === 0 && isMatrixParams(commands[0])) { const p = segmentGroup.segments[startIndex]; paths.push(new UrlSegment(p.path, stringify(commands[0]))); i++; continue; } const curr = isCommandWithOutlets(command) ? command.outlets[PRIMARY_OUTLET] : `${command}`; const next = i < commands.length - 1 ? commands[i + 1] : null; if (curr && next && isMatrixParams(next)) { paths.push(new UrlSegment(curr, stringify(next))); i += 2; } else { paths.push(new UrlSegment(curr, {})); i++; } } return new UrlSegmentGroup(paths, {}); } function createNewSegmentChildren(outlets) { const children = {}; Object.entries(outlets).forEach(([outlet, commands]) => { if (typeof commands === 'string') { commands = [commands]; } if (commands !== null) { children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands); } }); return children; } function stringify(params) { const res = {}; Object.entries(params).forEach(([k, v]) => res[k] = `${v}`); return res; } function compare(path, params, segment) { return path == segment.path && shallowEqual(params, segment.parameters); } const IMPERATIVE_NAVIGATION = 'imperative'; var EventType; (function (EventType) { EventType[EventType["NavigationStart"] = 0] = "NavigationStart"; EventType[EventType["NavigationEnd"] = 1] = "NavigationEnd"; EventType[EventType["NavigationCancel"] = 2] = "NavigationCancel"; EventType[EventType["NavigationError"] = 3] = "NavigationError"; EventType[EventType["RoutesRecognized"] = 4] = "RoutesRecognized"; EventType[EventType["ResolveStart"] = 5] = "ResolveStart"; EventType[EventType["ResolveEnd"] = 6] = "ResolveEnd"; EventType[EventType["GuardsCheckStart"] = 7] = "GuardsCheckStart"; EventType[EventType["GuardsCheckEnd"] = 8] = "GuardsCheckEnd"; EventType[EventType["RouteConfigLoadStart"] = 9] = "RouteConfigLoadStart"; EventType[EventType["RouteConfigLoadEnd"] = 10] = "RouteConfigLoadEnd"; EventType[EventType["ChildActivationStart"] = 11] = "ChildActivationStart"; EventType[EventType["ChildActivationEnd"] = 12] = "ChildActivationEnd"; EventType[EventType["ActivationStart"] = 13] = "ActivationStart"; EventType[EventType["ActivationEnd"] = 14] = "ActivationEnd"; EventType[EventType["Scroll"] = 15] = "Scroll"; EventType[EventType["NavigationSkipped"] = 16] = "NavigationSkipped"; })(EventType || (EventType = {})); class RouterEvent { id; url; constructor(id, url) { this.id = id; this.url = url; } } class NavigationStart extends RouterEvent { type = EventType.NavigationStart; navigationTrigger; restoredState; constructor(id, url, navigationTrigger = 'imperative', restoredState = null) { super(id, url); this.navigationTrigger = navigationTrigger; this.restoredState = restoredState; } toString() { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; } } class NavigationEnd extends RouterEvent { urlAfterRedirects; type = EventType.NavigationEnd; constructor(id, url, urlAfterRedirects) { super(id, url); this.urlAfterRedirects = urlAfterRedirects; } toString() { return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`; } } var NavigationCancellationCode; (function (NavigationCancellationCode) { NavigationCancellationCode[NavigationCancellationCode["Redirect"] = 0] = "Redirect"; NavigationCancellationCode[NavigationCancellationCode["SupersededByNewNavigation"] = 1] = "SupersededByNewNavigation"; NavigationCancellationCode[NavigationCancellationCode["NoDataFromResolver"] = 2] = "NoDataFromResolver"; NavigationCancellationCode[NavigationCancellationCode["GuardRejected"] = 3] = "GuardRejected"; NavigationCancellationCode[NavigationCancellationCode["Aborted"] = 4] = "Aborted"; })(NavigationCancellationCode || (NavigationCancellationCode = {})); var NavigationSkippedCode; (function (NavigationSkippedCode) { NavigationSkippedCode[NavigationSkippedCode["IgnoredSameUrlNavigation"] = 0] = "IgnoredSameUrlNavigation"; NavigationSkippedCode[NavigationSkippedCode["IgnoredByUrlHandlingStrategy"] = 1] = "IgnoredByUrlHandlingStrategy"; })(NavigationSkippedCode || (NavigationSkippedCode = {})); class NavigationCancel extends RouterEvent { reason; code; type = EventType.NavigationCancel; constructor(id, url, reason, code) { super(id, url); this.reason = reason; this.code = code; } toString() { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; } } function isRedirectingEvent(event) { return event instanceof NavigationCancel && (event.code === NavigationCancellationCode.Redirect || event.code === NavigationCancellationCode.SupersededByNewNavigation); } class NavigationSkipped extends RouterEvent { reason; code; type = EventType.NavigationSkipped; constructor(id, url, reason, code) { super(id, url); this.reason = reason; this.code = code; } } class NavigationError extends RouterEvent { error; target; type = EventType.NavigationError; constructor(id, url, error, target) { super(id, url); this.error = error; this.target = target; } toString() { return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`; } } class RoutesRecognized extends RouterEvent { urlAfterRedirects; state; type = EventType.RoutesRecognized; constructor(id, url, urlAfterRedirects, state) { super(id, url); this.urlAfterRedirects = urlAfterRedirects; this.state = state; } toString() { return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`; } } class GuardsCheckStart extends RouterEvent { urlAfterRedirects; state; type = EventType.GuardsCheckStart; constructor(id, url, urlAfterRedirects, state) { super(id, url); this.urlAfterRedirects = urlAfterRedirects; this.state = state; } toString() { return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`; } } class GuardsCheckEnd extends RouterEvent { urlAfterRedirects; state; shouldActivate; type = EventType.GuardsCheckEnd; constructor(id, url, urlAfterRedirects, state, shouldActivate) { super(id, url); this.urlAfterRedirects = urlAfterRedirects; this.state = state; this.shouldActivate = shouldActivate; } toString() { return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`; } } class ResolveStart extends RouterEvent { urlAfterRedirects; state; type = EventType.ResolveStart; constructor(id, url, urlAfterRedirects, state) { super(id, url); this.urlAfterRedirects = urlAfterRedirects; this.state = state; } toString() { return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`; } } class ResolveEnd extends RouterEvent { urlAfterRedirects; state; type = EventType.ResolveEnd; constructor(id, url, urlAfterRedirects, state) { super(id, url); this.urlAfterRedirects = urlAfterRedirects; this.state = state; } toString() { return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`; } } class RouteConfigLoadStart { route; type = EventType.RouteConfigLoadStart; constructor(route) { this.route = route; } toString() { return `RouteConfigLoadStart(path: ${this.route.path})`; } } class RouteConfigLoadEnd { route; type = EventType.RouteConfigLoadEnd; constructor(route) { this.route = route; } toString() { return `RouteConfigLoadEnd(path: ${this.route.path})`; } } class ChildActivationStart { snapshot; type = EventType.ChildActivationStart; constructor(snapshot) { this.snapshot = snapshot; } toString() { const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return `ChildActivationStart(path: '${path}')`; } } class ChildActivationEnd { snapshot; type = EventType.ChildActivationEnd; constructor(snapshot) { this.snapshot = snapshot; } toString() { const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return `ChildActivationEnd(path: '${path}')`; } } class ActivationStart { snapshot; type = EventType.ActivationStart; constructor(snapshot) { this.snapshot = snapshot; } toString() { const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return `ActivationStart(path: '${path}')`; } } class ActivationEnd { snapshot; type = EventType.ActivationEnd; constructor(snapshot) { this.snapshot = snapshot; } toString() { const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || ''; return `ActivationEnd(path: '${path}')`; } } class Scroll { routerEvent; position; anchor; scrollBehavior; type = EventType.Scroll; constructor(routerEvent, position, anchor, scrollBehavior) { this.routerEvent = routerEvent; this.position = position; this.anchor = anchor; this.scrollBehavior = scrollBehavior; } toString() { const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null; return `Scroll(anchor: '${this.anchor}', position: '${pos}')`; } } class BeforeActivateRoutes {} class RedirectRequest { url; navigationBehaviorOptions; constructor(url, navigationBehaviorOptions) { this.url = url; this.navigationBehaviorOptions = navigationBehaviorOptions; } } function isPublicRouterEvent(e) { return !(e instanceof BeforeActivateRoutes) && !(e instanceof RedirectRequest); } function stringifyEvent(routerEvent) { switch (routerEvent.type) { case EventType.ActivationEnd: return `ActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`; case EventType.ActivationStart: return `ActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`; case EventType.ChildActivationEnd: return `ChildActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`; case EventType.ChildActivationStart: return `ChildActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`; case EventType.GuardsCheckEnd: return `GuardsCheckEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state}, shouldActivate: ${routerEvent.shouldActivate})`; case EventType.GuardsCheckStart: return `GuardsCheckStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`; case EventType.NavigationCancel: return `NavigationCancel(id: ${routerEvent.id}, url: '${routerEvent.url}')`; case EventType.NavigationSkipped: return `NavigationSkipped(id: ${routerEvent.id}, url: '${routerEvent.url}')`; case EventType.NavigationEnd: return `NavigationEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}')`; case EventType.NavigationError: return `NavigationError(id: ${routerEvent.id}, url: '${routerEvent.url}', error: ${routerEvent.error})`; case EventType.NavigationStart: return `NavigationStart(id: ${routerEvent.id}, url: '${routerEvent.url}')`; case EventType.ResolveEnd: return `ResolveEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`; case EventType.ResolveStart: return `ResolveStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`; case EventType.RouteConfigLoadEnd: return `RouteConfigLoadEnd(path: ${routerEvent.route.path})`; case EventType.RouteConfigLoadStart: return `RouteConfigLoadStart(path: ${routerEvent.route.path})`; case EventType.RoutesRecognized: return `RoutesRecognized(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`; case EventType.Scroll: const pos = routerEvent.position ? `${routerEvent.position[0]}, ${routerEvent.position[1]}` : null; return `Scroll(anchor: '${routerEvent.anchor}', position: '${pos}')`; } } class OutletContext { rootInjector; outlet = null; route = null; children; attachRef = null; get injector() { return this.route?.snapshot._environmentInjector ?? this.rootInjector; } constructor(rootInjector) { this.rootInjector = rootInjector; this.children = new ChildrenOutletContexts(this.rootInjector); } } class ChildrenOutletContexts { rootInjector; contexts = new Map(); constructor(rootInjector) { this.rootInjector = rootInjector; } onChildOutletCreated(childName, outlet) { const context = this.getOrCreateContext(childName); context.outlet = outlet; this.contexts.set(childName, context); } onChildOutletDestroyed(childName) { const context = this.getContext(childName); if (context) { context.outlet = null; context.attachRef = null; } } onOutletDeactivated() { const contexts = this.contexts; this.contexts = new Map(); return contexts; } onOutletReAttached(contexts) { this.contexts = contexts; } getOrCreateContext(childName) { let context = this.getContext(childName); if (!context) { context = new OutletContext(this.rootInjector); this.contexts.set(childName, context); } return context; } getContext(childName) { return this.contexts.get(childName) || null; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ChildrenOutletContexts, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ChildrenOutletContexts, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ChildrenOutletContexts, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i0.EnvironmentInjector }] }); class Tree { _root; constructor(root) { this._root = root; } get root() { return this._root.value; } parent(t) { const p = this.pathFromRoot(t); return p.length > 1 ? p[p.length - 2] : null; } children(t) { const n = findNode(t, this._root); return n ? n.children.map(t => t.value) : []; } firstChild(t) { const n = findNode(t, this._root); return n && n.children.length > 0 ? n.children[0].value : null; } siblings(t) { const p = findPath(t, this._root); if (p.length < 2) return []; const c = p[p.length - 2].children.map(c => c.value); return c.filter(cc => cc !== t); } pathFromRoot(t) { return findPath(t, this._root).map(s => s.value); } } function findNode(value, node) { if (value === node.value) return node; for (const child of node.children) { const node = findNode(value, child); if (node) return node; } return null; } function findPath(value, node) { if (value === node.value) return [node]; for (const child of node.children) { const path = findPath(value, child); if (path.length) { path.unshift(node); return path; } } return []; } class TreeNode { value; children; constructor(value, children) { this.value = value; this.children = children; } toString() { return `TreeNode(${this.value})`; } } function nodeChildrenAsMap(node) { const map = {}; if (node) { node.children.forEach(child => map[child.value.outlet] = child); } return map; } class RouterState extends Tree { snapshot; constructor(root, snapshot) { super(root); this.snapshot = snapshot; setRouterState(this, root); } toString() { return this.snapshot.toString(); } } function createEmptyState(rootComponent, injector) { const snapshot = createEmptyStateSnapshot(rootComponent, injector); const emptyUrl = new BehaviorSubject([new UrlSegment('', {})]); const emptyParams = new BehaviorSubject({}); const emptyData = new BehaviorSubject({}); const emptyQueryParams = new BehaviorSubject({}); const fragment = new BehaviorSubject(''); const activated = new ActivatedRoute(emptyUrl, emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, snapshot.root); activated.snapshot = snapshot.root; return new RouterState(new TreeNode(activated, []), snapshot); } function createEmptyStateSnapshot(rootComponent, injector) { const emptyParams = {}; const emptyData = {}; const emptyQueryParams = {}; const fragment = ''; const activated = new ActivatedRouteSnapshot([], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null, {}, injector); return new RouterStateSnapshot('', new TreeNode(activated, [])); } class ActivatedRoute { urlSubject; paramsSubject; queryParamsSubject; fragmentSubject; dataSubject; outlet; component; snapshot; _futureSnapshot; _routerState; _paramMap; _queryParamMap; title; url; params; queryParams; fragment; data; constructor(urlSubject, paramsSubject, queryParamsSubject, fragmentSubject, dataSubject, outlet, component, futureSnapshot) { this.urlSubject = urlSubject; this.paramsSubject = paramsSubject; this.queryParamsSubject = queryParamsSubject; this.fragmentSubject = fragmentSubject; this.dataSubject = dataSubject; this.outlet = outlet; this.component = component; this._futureSnapshot = futureSnapshot; this.title = this.dataSubject?.pipe(map(d => d[RouteTitleKey])) ?? of(undefined); this.url = urlSubject; this.params = paramsSubject; this.queryParams = queryParamsSubject; this.fragment = fragmentSubject; this.data = dataSubject; } get routeConfig() { return this._futureSnapshot.routeConfig; } get root() { return this._routerState.root; } get parent() { return this._routerState.parent(this); } get firstChild() { return this._routerState.firstChild(this); } get children() { return this._routerState.children(this); } get pathFromRoot() { return this._routerState.pathFromRoot(this); } get paramMap() { this._paramMap ??= this.params.pipe(map(p => convertToParamMap(p))); return this._paramMap; } get queryParamMap() { this._queryParamMap ??= this.queryParams.pipe(map(p => convertToParamMap(p))); return this._queryParamMap; } toString() { return this.snapshot ? this.snapshot.toString() : `Future(${this._futureSnapshot})`; } } function getInherited(route, parent, paramsInheritanceStrategy = 'emptyOnly') { let inherited; const { routeConfig } = route; if (parent !== null && (paramsInheritanceStrategy === 'always' || routeConfig?.path === '' || !parent.component && !parent.routeConfig?.loadComponent)) { inherited = { params: { ...parent.params, ...route.params }, data: { ...parent.data, ...route.data }, resolve: { ...route.data, ...parent.data, ...routeConfig?.data, ...route._resolvedData } }; } else { inherited = { params: { ...route.params }, data: { ...route.data }, resolve: { ...route.data, ...(route._resolvedData ?? {}) } }; } if (routeConfig && hasStaticTitle(routeConfig)) { inherited.resolve[RouteTitleKey] = routeConfig.title; } return inherited; } class ActivatedRouteSnapshot { url; params; queryParams; fragment; data; outlet; component; routeConfig; _resolve; _resolvedData; _routerState; _paramMap; _queryParamMap; _environmentInjector; get title() { return this.data?.[RouteTitleKey]; } constructor(url, params, queryParams, fragment, data, outlet, component, routeConfig, resolve, environmentInjector) { this.url = url; this.params = params; this.queryParams = queryParams; this.fragment = fragment; this.data = data; this.outlet = outlet; this.component = component; this.routeConfig = routeConfig; this._resolve = resolve; this._environmentInjector = environmentInjector; } get root() { return this._routerState.root; } get parent() { return this._routerState.parent(this); } get firstChild() { return this._routerState.firstChild(this); } get children() { return this._routerState.children(this); } get pathFromRoot() { return this._routerState.pathFromRoot(this); } get paramMap() { this._paramMap ??= convertToParamMap(this.params); return this._paramMap; } get queryParamMap() { this._queryParamMap ??= convertToParamMap(this.queryParams); return this._queryParamMap; } toString() { const url = this.url.map(segment => segment.toString()).join('/'); const matched = this.routeConfig ? this.routeConfig.path : ''; return `Route(url:'${url}', path:'${matched}')`; } } class RouterStateSnapshot extends Tree { url; constructor(url, root) { super(root); this.url = url; setRouterState(this, root); } toString() { return serializeNode(this._root); } } function setRouterState(state, node) { node.value._routerState = state; node.children.forEach(c => setRouterState(state, c)); } function serializeNode(node) { const c = node.children.length > 0 ? ` { ${node.children.map(serializeNode).join(', ')} } ` : ''; return `${node.value}${c}`; } function advanceActivatedRoute(route) { if (route.snapshot) { const currentSnapshot = route.snapshot; const nextSnapshot = route._futureSnapshot; route.snapshot = nextSnapshot; if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) { route.queryParamsSubject.next(nextSnapshot.queryParams); } if (currentSnapshot.fragment !== nextSnapshot.fragment) { route.fragmentSubject.next(nextSnapshot.fragment); } if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) { route.paramsSubject.next(nextSnapshot.params); } if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) { route.urlSubject.next(nextSnapshot.url); } if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) { route.dataSubject.next(nextSnapshot.data); } } else { route.snapshot = route._futureSnapshot; route.dataSubject.next(route._futureSnapshot.data); } } function equalParamsAndUrlSegments(a, b) { const equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url); const parentsMismatch = !a.parent !== !b.parent; return equalUrlParams && !parentsMismatch && (!a.parent || equalParamsAndUrlSegments(a.parent, b.parent)); } function hasStaticTitle(config) { return typeof config.title === 'string' || config.title === null; } const ROUTER_OUTLET_DATA = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'RouterOutlet data' : ''); class RouterOutlet { activated = null; get activatedComponentRef() { return this.activated; } _activatedRoute = null; name = PRIMARY_OUTLET; activateEvents = new EventEmitter(); deactivateEvents = new EventEmitter(); attachEvents = new EventEmitter(); detachEvents = new EventEmitter(); routerOutletData = input(...(ngDevMode ? [undefined, { debugName: "routerOutletData" }] : [])); parentContexts = inject(ChildrenOutletContexts); location = inject(ViewContainerRef); changeDetector = inject(ChangeDetectorRef); inputBinder = inject(INPUT_BINDER, { optional: true }); supportsBindingToComponentInputs = true; ngOnChanges(changes) { if (changes['name']) { const { firstChange, previousValue } = changes['name']; if (firstChange) { return; } if (this.isTrackedInParentContexts(previousValue)) { this.deactivate(); this.parentContexts.onChildOutletDestroyed(previousValue); } this.initializeOutletWithName(); } } ngOnDestroy() { if (this.isTrackedInParentContexts(this.name)) { this.parentContexts.onChildOutletDestroyed(this.name); } this.inputBinder?.unsubscribeFromRouteData(this); } isTrackedInParentContexts(outletName) { return this.parentContexts.getContext(outletName)?.outlet === this; } ngOnInit() { this.initializeOutletWithName(); } initializeOutletWithName() { this.parentContexts.onChildOutletCreated(this.name, this); if (this.activated) { return; } const context = this.parentContexts.getContext(this.name); if (context?.route) { if (context.attachRef) { this.attach(context.attachRef, context.route); } else { this.activateWith(context.route, context.injector); } } } get isActivated() { return !!this.activated; } get component() { if (!this.activated) throw new _RuntimeError(4012, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Outlet is not activated'); return this.activated.instance; } get activatedRoute() { if (!this.activated) throw new _RuntimeError(4012, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Outlet is not activated'); return this._activatedRoute; } get activatedRouteData() { if (this._activatedRoute) { return this._activatedRoute.snapshot.data; } return {}; } detach() { if (!this.activated) throw new _RuntimeError(4012, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Outlet is not activated'); this.location.detach(); const cmp = this.activated; this.activated = null; this._activatedRoute = null; this.detachEvents.emit(cmp.instance); return cmp; } attach(ref, activatedRoute) { this.activated = ref; this._activatedRoute = activatedRoute; this.location.insert(ref.hostView); this.inputBinder?.bindActivatedRouteToOutletComponent(this); this.attachEvents.emit(ref.instance); } deactivate() { if (this.activated) { const c = this.component; this.activated.destroy(); this.activated = null; this._activatedRoute = null; this.deactivateEvents.emit(c); } } activateWith(activatedRoute, environmentInjector) { if (this.isActivated) { throw new _RuntimeError(4013, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Cannot activate an already activated outlet'); } this._activatedRoute = activatedRoute; const location = this.location; const snapshot = activatedRoute.snapshot; const component = snapshot.component; const childContexts = this.parentContexts.getOrCreateContext(this.name).children; const injector = new OutletInjector(activatedRoute, childContexts, location.injector, this.routerOutletData); this.activated = location.createComponent(component, { index: location.length, injector, environmentInjector: environmentInjector }); this.changeDetector.markForCheck(); this.inputBinder?.bindActivatedRouteToOutletComponent(this); this.activateEvents.emit(this.activated.instance); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RouterOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: RouterOutlet, isStandalone: true, selector: "router-outlet", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: false, isRequired: false, transformFunction: null }, routerOutletData: { classPropertyName: "routerOutletData", publicName: "routerOutletData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], usesOnChanges: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RouterOutlet, decorators: [{ type: Directive, args: [{ selector: 'router-outlet', exportAs: 'outlet' }] }], propDecorators: { name: [{ type: Input }], activateEvents: [{ type: Output, args: ['activate'] }], deactivateEvents: [{ type: Output, args: ['deactivate'] }], attachEvents: [{ type: Output, args: ['attach'] }], detachEvents: [{ type: Output, args: ['detach'] }], routerOutletData: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerOutletData", required: false }] }] } }); class OutletInjector { route; childContexts; parent; outletData; constructor(route, childContexts, parent, outletData) { this.route = route; this.childContexts = childContexts; this.parent = parent; this.outletData = outletData; } get(token, notFoundValue) { if (token === ActivatedRoute) { return this.route; } if (token === ChildrenOutletContexts) { return this.childContexts; } if (token === ROUTER_OUTLET_DATA) { return this.outletData; } return this.parent.get(token, notFoundValue); } } const INPUT_BINDER = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'Router Input Binder' : ''); class RoutedComponentInputBinder { outletDataSubscriptions = new Map(); bindActivatedRouteToOutletComponent(outlet) { this.unsubscribeFromRouteData(outlet); this.subscribeToRouteData(outlet); } unsubscribeFromRouteData(outlet) { this.outletDataSubscriptions.get(outlet)?.unsubscribe(); this.outletDataSubscriptions.delete(outlet); } subscribeToRouteData(outlet) { const { activatedRoute } = outlet; const dataSubscription = combineLatest([activatedRoute.queryParams, activatedRoute.params, activatedRoute.data]).pipe(switchMap(([queryParams, params, data], index) => { data = { ...queryParams, ...params, ...data }; if (index === 0) { return of(data); } return Promise.resolve(data); })).subscribe(data => { if (!outlet.isActivated || !outlet.activatedComponentRef || outlet.activatedRoute !== activatedRoute || activatedRoute.component === null) { this.unsubscribeFromRouteData(outlet); return; } const mirror = reflectComponentType(activatedRoute.component); if (!mirror) { this.unsubscribeFromRouteData(outlet); return; } for (const { templateName } of mirror.inputs) { outlet.activatedComponentRef.setInput(templateName, data[templateName]); } }); this.outletDataSubscriptions.set(outlet, dataSubscription); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RoutedComponentInputBinder, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RoutedComponentInputBinder }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RoutedComponentInputBinder, decorators: [{ type: Injectable }] }); class ɵEmptyOutletComponent { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.1", type: ɵEmptyOutletComponent, isStandalone: true, selector: "ng-component", exportAs: ["emptyRouterOutlet"], ngImport: i0, template: ``, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{ type: Component, args: [{ template: ``, imports: [RouterOutlet], exportAs: 'emptyRouterOutlet' }] }] }); function standardizeConfig(r) { const children = r.children && r.children.map(standardizeConfig); const c = children ? { ...r, children } : { ...r }; if (!c.component && !c.loadComponent && (children || c.loadChildren) && c.outlet && c.outlet !== PRIMARY_OUTLET) { c.component = ɵEmptyOutletComponent; } return c; } function createRouterState(routeReuseStrategy, curr, prevState) { const root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : undefined); return new RouterState(root, curr); } function createNode(routeReuseStrategy, curr, prevState) { if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) { const value = prevState.value; value._futureSnapshot = curr.value; const children = createOrReuseChildren(routeReuseStrategy, curr, prevState); return new TreeNode(value, children); } else { if (routeReuseStrategy.shouldAttach(curr.value)) { const detachedRouteHandle = routeReuseStrategy.retrieve(curr.value); if (detachedRouteHandle !== null) { const tree = detachedRouteHandle.route; tree.value._futureSnapshot = curr.value; tree.children = curr.children.map(c => createNode(routeReuseStrategy, c)); return tree; } } const value = createActivatedRoute(curr.value); const children = curr.children.map(c => createNode(routeReuseStrategy, c)); return new TreeNode(value, children); } } function createOrReuseChildren(routeReuseStrategy, curr, prevState) { return curr.children.map(child => { for (const p of prevState.children) { if (routeReuseStrategy.shouldReuseRoute(child.value, p.value.snapshot)) { return createNode(routeReuseStrategy, child, p); } } return createNode(routeReuseStrategy, child); }); } function createActivatedRoute(c) { 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); } class RedirectCommand { redirectTo; navigationBehaviorOptions; constructor(redirectTo, navigationBehaviorOptions) { this.redirectTo = redirectTo; this.navigationBehaviorOptions = navigationBehaviorOptions; } } const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError'; function redirectingNavigationError(urlSerializer, redirect) { const { redirectTo, navigationBehaviorOptions } = isUrlTree(redirect) ? { redirectTo: redirect, navigationBehaviorOptions: undefined } : redirect; const error = navigationCancelingError(ngDevMode && `Redirecting to "${urlSerializer.serialize(redirectTo)}"`, NavigationCancellationCode.Redirect); error.url = redirectTo; error.navigationBehaviorOptions = navigationBehaviorOptions; return error; } function navigationCancelingError(message, code) { const error = new Error(`NavigationCancelingError: ${message || ''}`); error[NAVIGATION_CANCELING_ERROR] = true; error.cancellationCode = code; return error; } function isRedirectingNavigationCancelingError(error) { return isNavigationCancelingError(error) && isUrlTree(error.url); } function isNavigationCancelingError(error) { return !!error && error[NAVIGATION_CANCELING_ERROR]; } let warnedAboutUnsupportedInputBinding = false; class ActivateRoutes { routeReuseStrategy; futureState; currState; forwardEvent; inputBindingEnabled; constructor(routeReuseStrategy, futureState, currState, forwardEvent, inputBindingEnabled) { this.routeReuseStrategy = routeReuseStrategy; this.futureState = futureState; this.currState = currState; this.forwardEvent = forwardEvent; this.inputBindingEnabled = inputBindingEnabled; } activate(parentContexts) { const futureRoot = this.futureState._root; const currRoot = this.currState ? this.currState._root : null; this.deactivateChildRoutes(futureRoot, currRoot, parentContexts); advanceActivatedRoute(this.futureState.root); this.activateChildRoutes(futureRoot, currRoot, parentContexts); } deactivateChildRoutes(futureNode, currNode, contexts) { const children = nodeChildrenAsMap(currNode); futureNode.children.forEach(futureChild => { const childOutletName = futureChild.value.outlet; this.deactivateRoutes(futureChild, children[childOutletName], contexts); delete children[childOutletName]; }); Object.values(children).forEach(v => { this.deactivateRouteAndItsChildren(v, contexts); }); } deactivateRoutes(futureNode, currNode, parentContext) { const future = futureNode.value; const curr = currNode ? currNode.value : null; if (future === curr) { if (future.component) { const context = parentContext.getContext(future.outlet); if (context) { this.deactivateChildRoutes(futureNode, currNode, context.children); } } else { this.deactivateChildRoutes(futureNode, currNode, parentContext); } } else { if (curr) { this.deactivateRouteAndItsChildren(currNode, parentContext); } } } deactivateRouteAndItsChildren(route, parentContexts) { if (route.value.component && this.routeReuseStrategy.shouldDetach(route.value.snapshot)) { this.detachAndStoreRouteSubtree(route, parentContexts); } else { this.deactivateRouteAndOutlet(route, parentContexts); } } detachAndStoreRouteSubtree(route, parentContexts) { const context = parentContexts.getContext(route.value.outlet); const contexts = context && route.value.component ? context.children : parentContexts; const children = nodeChildrenAsMap(route); for (const treeNode of Object.values(children)) { this.deactivateRouteAndItsChildren(treeNode, contexts); } if (context && context.outlet) { const componentRef = context.outlet.detach(); const contexts = context.children.onOutletDeactivated(); this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts }); } } deactivateRouteAndOutlet(route, parentContexts) { const context = parentContexts.getContext(route.value.outlet); const contexts = context && route.value.component ? context.children : parentContexts; const children = nodeChildrenAsMap(route); for (const treeNode of Object.values(children)) { this.deactivateRouteAndItsChildren(treeNode, contexts); } if (context) { if (context.outlet) { context.outlet.deactivate(); context.children.onOutletDeactivated(); } context.attachRef = null; context.route = null; } } activateChildRoutes(futureNode, currNode, contexts) { const children = nodeChildrenAsMap(currNode); futureNode.children.forEach(c => { this.activateRoutes(c, children[c.value.outlet], contexts); this.forwardEvent(new ActivationEnd(c.value.snapshot)); }); if (futureNode.children.length) { this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot)); } } activateRoutes(futureNode, currNode, parentContexts) { const future = futureNode.value; const curr = currNode ? currNode.value : null; advanceActivatedRoute(future); if (future === curr) { if (future.component) { const context = parentContexts.getOrCreateContext(future.outlet); this.activateChildRoutes(futureNode, currNode, context.children); } else { this.activateChildRoutes(futureNode, currNode, parentContexts); } } else { if (future.component) { const context = parentContexts.getOrCreateContext(future.outlet); if (this.routeReuseStrategy.shouldAttach(future.snapshot)) { const stored = this.routeReuseStrategy.retrieve(future.snapshot); this.routeReuseStrategy.store(future.snapshot, null); context.children.onOutletReAttached(stored.contexts); context.attachRef = stored.componentRef; context.route = stored.route.value; if (context.outlet) { context.outlet.attach(stored.componentRef, stored.route.value); } advanceActivatedRoute(stored.route.value); this.activateChildRoutes(futureNode, null, context.children); } else { context.attachRef = null; context.route = future; if (context.outlet) { context.outlet.activateWith(future, context.injector); } this.activateChildRoutes(futureNode, null, context.children); } } else { this.activateChildRoutes(futureNode, null, parentContexts); } } if (typeof ngDevMode === 'undefined' || ngDevMode) { const context = parentContexts.getOrCreateContext(future.outlet); const outlet = context.outlet; if (outlet && this.inputBindingEnabled && !outlet.supportsBindingToComponentInputs && !warnedAboutUnsupportedInputBinding) { console.warn(`'withComponentInputBinding' feature is enabled but ` + `this application is using an outlet that may not support binding to component inputs.`); warnedAboutUnsupportedInputBinding = true; } } } } class CanActivate { path; route; constructor(path) { this.path = path; this.route = this.path[this.path.length - 1]; } } class CanDeactivate { component; route; constructor(component, route) { this.component = component; this.route = route; } } function getAllRouteGuards(future, curr, parentContexts) { const futureRoot = future._root; const currRoot = curr ? curr._root : null; return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]); } function getCanActivateChild(p) { const canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null; if (!canActivateChild || canActivateChild.length === 0) return null; return { node: p, guards: canActivateChild }; } function getTokenOrFunctionIdentity(tokenOrFunction, injector) { const NOT_FOUND = Symbol(); const result = injector.get(tokenOrFunction, NOT_FOUND); if (result === NOT_FOUND) { if (typeof tokenOrFunction === 'function' && !_isInjectable(tokenOrFunction)) { return tokenOrFunction; } else { return injector.get(tokenOrFunction); } } return result; } function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = { canDeactivateChecks: [], canActivateChecks: [] }) { const prevChildren = nodeChildrenAsMap(currNode); futureNode.children.forEach(c => { getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks); delete prevChildren[c.value.outlet]; }); Object.entries(prevChildren).forEach(([k, v]) => deactivateRouteAndItsChildren(v, contexts.getContext(k), checks)); return checks; } function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks = { canDeactivateChecks: [], canActivateChecks: [] }) { const future = futureNode.value; const curr = currNode ? currNode.value : null; const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null; if (curr && future.routeConfig === curr.routeConfig) { const shouldRun = shouldRunGuardsAndResolvers(curr, future, future.routeConfig.runGuardsAndResolvers); if (shouldRun) { checks.canActivateChecks.push(new CanActivate(futurePath)); } else { future.data = curr.data; future._resolvedData = curr._resolvedData; } if (future.component) { getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks); } else { getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks); } if (shouldRun && context && context.outlet && context.outlet.isActivated) { checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, curr)); } } else { if (curr) { deactivateRouteAndItsChildren(currNode, context, checks); } checks.canActivateChecks.push(new CanActivate(futurePath)); if (future.component) { getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks); } else { getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks); } } return checks; } function shouldRunGuardsAndResolvers(curr, future, mode) { if (typeof mode === 'function') { return runInInjectionContext(future._environmentInjector, () => mode(curr, future)); } switch (mode) { case 'pathParamsChange': return !equalPath(curr.url, future.url); case 'pathParamsOrQueryParamsChange': return !equalPath(curr.url, future.url) || !shallowEqual(curr.queryParams, future.queryParams); case 'always': return true; case 'paramsOrQueryParamsChange': return !equalParamsAndUrlSegments(curr, future) || !shallowEqual(curr.queryParams, future.queryParams); case 'paramsChange': default: return !equalParamsAndUrlSegments(curr, future); } } function deactivateRouteAndItsChildren(route, context, checks) { const children = nodeChildrenAsMap(route); const r = route.value; Object.entries(children).forEach(([childName, node]) => { if (!r.component) { deactivateRouteAndItsChildren(node, context, checks); } else if (context) { deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks); } else { deactivateRouteAndItsChildren(node, null, checks); } }); if (!r.component) { checks.canDeactivateChecks.push(new CanDeactivate(null, r)); } else if (context && context.outlet && context.outlet.isActivated) { checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r)); } else { checks.canDeactivateChecks.push(new CanDeactivate(null, r)); } } function isFunction(v) { return typeof v === 'function'; } function isBoolean(v) { return typeof v === 'boolean'; } function isCanLoad(guard) { return guard && isFunction(guard.canLoad); } function isCanActivate(guard) { return guard && isFunction(guard.canActivate); } function isCanActivateChild(guard) { return guard && isFunction(guard.canActivateChild); } function isCanDeactivate(guard) { return guard && isFunction(guard.canDeactivate); } function isCanMatch(guard) { return guard && isFunction(guard.canMatch); } function isEmptyError(e) { return e instanceof EmptyError || e?.name === 'EmptyError'; } const INITIAL_VALUE = /* @__PURE__ */Symbol('INITIAL_VALUE'); function prioritizedGuardValue() { return switchMap(obs => { return combineLatest(obs.map(o => o.pipe(take(1), startWith(INITIAL_VALUE)))).pipe(map(results => { for (const result of results) { if (result === true) { continue; } else if (result === INITIAL_VALUE) { return INITIAL_VALUE; } else if (result === false || isRedirect(result)) { return result; } } return true; }), filter(item => item !== INITIAL_VALUE), take(1)); }); } function isRedirect(val) { return isUrlTree(val) || val instanceof RedirectCommand; } function abortSignalToObservable(signal) { if (signal.aborted) { return of(undefined).pipe(take(1)); } return new Observable(subscriber => { const handler = () => { subscriber.next(); subscriber.complete(); }; signal.addEventListener('abort', handler); return () => signal.removeEventListener('abort', handler); }); } function takeUntilAbort(signal) { return takeUntil(abortSignalToObservable(signal)); } function checkGuards(forwardEvent) { return mergeMap(t => { const { targetSnapshot, currentSnapshot, guards: { canActivateChecks, canDeactivateChecks } } = t; if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) { return of({ ...t, guardsResult: true }); } return runCanDeactivateChecks(canDeactivateChecks, targetSnapshot, currentSnapshot).pipe(mergeMap(canDeactivate => { return canDeactivate && isBoolean(canDeactivate) ? runCanActivateChecks(targetSnapshot, canActivateChecks, forwardEvent) : of(canDeactivate); }), map(guardsResult => ({ ...t, guardsResult }))); }); } function runCanDeactivateChecks(checks, futureRSS, currRSS) { return from(checks).pipe(mergeMap(check => runCanDeactivate(check.component, check.route, currRSS, futureRSS)), first(result => { return result !== true; }, true)); } function runCanActivateChecks(futureSnapshot, checks, forwardEvent) { return from(checks).pipe(concatMap(check => { return concat(fireChildActivationStart(check.route.parent, forwardEvent), fireActivationStart(check.route, forwardEvent), runCanActivateChild(futureSnapshot, check.path), runCanActivate(futureSnapshot, check.route)); }), first(result => { return result !== true; }, true)); } function fireActivationStart(snapshot, forwardEvent) { if (snapshot !== null && forwardEvent) { forwardEvent(new ActivationStart(snapshot)); } return of(true); } function fireChildActivationStart(snapshot, forwardEvent) { if (snapshot !== null && forwardEvent) { forwardEvent(new ChildActivationStart(snapshot)); } return of(true); } function runCanActivate(futureRSS, futureARS) { const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null; if (!canActivate || canActivate.length === 0) return of(true); const canActivateObservables = canActivate.map(canActivate => { return defer(() => { const closestInjector = futureARS._environmentInjector; const guard = getTokenOrFunctionIdentity(canActivate, closestInjector); const guardVal = isCanActivate(guard) ? guard.canActivate(futureARS, futureRSS) : runInInjectionContext(closestInjector, () => guard(futureARS, futureRSS)); return wrapIntoObservable(guardVal).pipe(first()); }); }); return of(canActivateObservables).pipe(prioritizedGuardValue()); } function runCanActivateChild(futureRSS, path) { const futureARS = path[path.length - 1]; const canActivateChildGuards = path.slice(0, path.length - 1).reverse().map(p => getCanActivateChild(p)).filter(_ => _ !== null); const canActivateChildGuardsMapped = canActivateChildGuards.map(d => { return defer(() => { const guardsMapped = d.guards.map(canActivateChild => { const closestInjector = d.node._environmentInjector; const guard = getTokenOrFunctionIdentity(canActivateChild, closestInjector); const guardVal = isCanActivateChild(guard) ? guard.canActivateChild(futureARS, futureRSS) : runInInjectionContext(closestInjector, () => guard(futureARS, futureRSS)); return wrapIntoObservable(guardVal).pipe(first()); }); return of(guardsMapped).pipe(prioritizedGuardValue()); }); }); return of(canActivateChildGuardsMapped).pipe(prioritizedGuardValue()); } function runCanDeactivate(component, currARS, currRSS, futureRSS) { const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null; if (!canDeactivate || canDeactivate.length === 0) return of(true); const canDeactivateObservables = canDeactivate.map(c => { const closestInjector = currARS._environmentInjector; const guard = getTokenOrFunctionIdentity(c, closestInjector); const guardVal = isCanDeactivate(guard) ? guard.canDeactivate(component, currARS, currRSS, futureRSS) : runInInjectionContext(closestInjector, () => guard(component, currARS, currRSS, futureRSS)); return wrapIntoObservable(guardVal).pipe(first()); }); return of(canDeactivateObservables).pipe(prioritizedGuardValue()); } function runCanLoadGuards(injector, route, segments, urlSerializer, abortSignal) { const canLoad = route.canLoad; if (canLoad === undefined || canLoad.length === 0) { return of(true); } const canLoadObservables = canLoad.map(injectionToken => { const guard = getTokenOrFunctionIdentity(injectionToken, injector); const guardVal = isCanLoad(guard) ? guard.canLoad(route, segments) : runInInjectionContext(injector, () => guard(route, segments)); const obs$ = wrapIntoObservable(guardVal); return abortSignal ? obs$.pipe(takeUntilAbort(abortSignal)) : obs$; }); return of(canLoadObservables).pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer)); } function redirectIfUrlTree(urlSerializer) { return pipe(tap(result => { if (typeof result === 'boolean') return; throw redirectingNavigationError(urlSerializer, result); }), map(result => result === true)); } function runCanMatchGuards(injector, route, segments, urlSerializer, abortSignal) { const canMatch = route.canMatch; if (!canMatch || canMatch.length === 0) return of(true); const canMatchObservables = canMatch.map(injectionToken => { const guard = getTokenOrFunctionIdentity(injectionToken, injector); const guardVal = isCanMatch(guard) ? guard.canMatch(route, segments) : runInInjectionContext(injector, () => guard(route, segments)); return wrapIntoObservable(guardVal).pipe(takeUntilAbort(abortSignal)); }); return of(canMatchObservables).pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer)); } class NoMatch extends Error { segmentGroup; constructor(segmentGroup) { super(); this.segmentGroup = segmentGroup || null; Object.setPrototypeOf(this, NoMatch.prototype); } } class AbsoluteRedirect extends Error { urlTree; constructor(urlTree) { super(); this.urlTree = urlTree; Object.setPrototypeOf(this, AbsoluteRedirect.prototype); } } function namedOutletsRedirect(redirectTo) { throw new _RuntimeError(4000, (typeof ngDevMode === 'undefined' || ngDevMode) && `Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`); } function canLoadFails(route) { throw navigationCancelingError((typeof ngDevMode === 'undefined' || ngDevMode) && `Cannot load children because the guard of the route "path: '${route.path}'" returned false`, NavigationCancellationCode.GuardRejected); } class ApplyRedirects { urlSerializer; urlTree; constructor(urlSerializer, urlTree) { this.urlSerializer = urlSerializer; this.urlTree = urlTree; } async lineralizeSegments(route, urlTree) { let res = []; let c = urlTree.root; while (true) { res = res.concat(c.segments); if (c.numberOfChildren === 0) { return res; } if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) { throw namedOutletsRedirect(`${route.redirectTo}`); } c = c.children[PRIMARY_OUTLET]; } } async applyRedirectCommands(segments, redirectTo, posParams, currentSnapshot, injector) { const redirect = await getRedirectResult(redirectTo, currentSnapshot, injector); if (redirect instanceof UrlTree) { throw new AbsoluteRedirect(redirect); } const newTree = this.applyRedirectCreateUrlTree(redirect, this.urlSerializer.parse(redirect), segments, posParams); if (redirect[0] === '/') { throw new AbsoluteRedirect(newTree); } return newTree; } applyRedirectCreateUrlTree(redirectTo, urlTree, segments, posParams) { const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams); return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment); } createQueryParams(redirectToParams, actualParams) { const res = {}; Object.entries(redirectToParams).forEach(([k, v]) => { const copySourceValue = typeof v === 'string' && v[0] === ':'; if (copySourceValue) { const sourceName = v.substring(1); res[k] = actualParams[sourceName]; } else { res[k] = v; } }); return res; } createSegmentGroup(redirectTo, group, segments, posParams) { const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams); let children = {}; Object.entries(group.children).forEach(([name, child]) => { children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams); }); return new UrlSegmentGroup(updatedSegments, children); } createSegments(redirectTo, redirectToSegments, actualSegments, posParams) { return redirectToSegments.map(s => s.path[0] === ':' ? this.findPosParam(redirectTo, s, posParams) : this.findOrReturn(s, actualSegments)); } findPosParam(redirectTo, redirectToUrlSegment, posParams) { const pos = posParams[redirectToUrlSegment.path.substring(1)]; if (!pos) throw new _RuntimeError(4001, (typeof ngDevMode === 'undefined' || ngDevMode) && `Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`); return pos; } findOrReturn(redirectToUrlSegment, actualSegments) { let idx = 0; for (const s of actualSegments) { if (s.path === redirectToUrlSegment.path) { actualSegments.splice(idx); return s; } idx++; } return redirectToUrlSegment; } } function getRedirectResult(redirectTo, currentSnapshot, injector) { if (typeof redirectTo === 'string') { return Promise.resolve(redirectTo); } const redirectToFn = redirectTo; const { queryParams, fragment, routeConfig, url, outlet, params, data, title, paramMap, queryParamMap } = currentSnapshot; return firstValueFrom(wrapIntoObservable(runInInjectionContext(injector, () => redirectToFn({ params, data, queryParams, fragment, routeConfig, url, outlet, title, paramMap, queryParamMap })))); } function getOrCreateRouteInjectorIfNeeded(route, currentInjector) { if (route.providers && !route._injector) { route._injector = createEnvironmentInjector(route.providers, currentInjector, `Route: ${route.path}`); } return route._injector ?? currentInjector; } function validateConfig(config, parentPath = '', requireStandaloneComponents = false) { for (let i = 0; i < config.length; i++) { const route = config[i]; const fullPath = getFullPath(parentPath, route); validateNode(route, fullPath, requireStandaloneComponents); } } function assertStandalone(fullPath, component) { if (component && _isNgModule(component)) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}'. You are using 'loadComponent' with a module, ` + `but it must be used with standalone components. Use 'loadChildren' instead.`); } else if (component && !isStandalone(component)) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}'. The component must be standalone.`); } } function validateNode(route, fullPath, requireStandaloneComponents) { if (typeof ngDevMode === 'undefined' || ngDevMode) { if (!route) { throw new _RuntimeError(4014, ` Invalid configuration of route '${fullPath}': Encountered undefined route. The reason might be an extra comma. Example: const routes: Routes = [ { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, { path: 'dashboard', component: DashboardComponent },, << two commas { path: 'detail/:id', component: HeroDetailComponent } ]; `); } if (Array.isArray(route)) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': Array cannot be specified`); } if (!route.redirectTo && !route.component && !route.loadComponent && !route.children && !route.loadChildren && route.outlet && route.outlet !== PRIMARY_OUTLET) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`); } if (route.redirectTo && route.children) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`); } if (route.redirectTo && route.loadChildren) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`); } if (route.children && route.loadChildren) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`); } if (route.component && route.loadComponent) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': component and loadComponent cannot be used together`); } if (route.redirectTo) { if (route.component || route.loadComponent) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': redirectTo and component/loadComponent cannot be used together`); } if (route.canMatch || route.canActivate) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': redirectTo and ${route.canMatch ? 'canMatch' : 'canActivate'} cannot be used together.` + `Redirects happen before guards are executed.`); } } if (route.path && route.matcher) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': path and matcher cannot be used together`); } if (route.redirectTo === void 0 && !route.component && !route.loadComponent && !route.children && !route.loadChildren) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}'. One of the following must be provided: component, loadComponent, redirectTo, children or loadChildren`); } if (route.path === void 0 && route.matcher === void 0) { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`); } if (typeof route.path === 'string' && route.path.charAt(0) === '/') { throw new _RuntimeError(4014, `Invalid configuration of route '${fullPath}': path cannot start with a slash`); } if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) { const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`; throw new _RuntimeError(4014, `Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`); } if (requireStandaloneComponents) { assertStandalone(fullPath, route.component); } } if (route.children) { validateConfig(route.children, fullPath, requireStandaloneComponents); } } function getFullPath(parentPath, currentRoute) { if (!currentRoute) { return parentPath; } if (!parentPath && !currentRoute.path) { return ''; } else if (parentPath && !currentRoute.path) { return `${parentPath}/`; } else if (!parentPath && currentRoute.path) { return currentRoute.path; } else { return `${parentPath}/${currentRoute.path}`; } } function getOutlet(route) { return route.outlet || PRIMARY_OUTLET; } function sortByMatchingOutlets(routes, outletName) { const sortedConfig = routes.filter(r => getOutlet(r) === outletName); sortedConfig.push(...routes.filter(r => getOutlet(r) !== outletName)); return sortedConfig; } const noMatch = { matched: false, consumedSegments: [], remainingSegments: [], parameters: {}, positionalParamSegments: {} }; function matchWithChecks(segmentGroup, route, segments, injector, urlSerializer, abortSignal) { const result = match(segmentGroup, route, segments); if (!result.matched) { return of(result); } injector = getOrCreateRouteInjectorIfNeeded(route, injector); return runCanMatchGuards(injector, route, segments, urlSerializer, abortSignal).pipe(map(v => v === true ? result : { ...noMatch })); } function match(segmentGroup, route, segments) { if (route.path === '') { if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) { return { ...noMatch }; } return { matched: true, consumedSegments: [], remainingSegments: segments, parameters: {}, positionalParamSegments: {} }; } const matcher = route.matcher || defaultUrlMatcher; const res = matcher(segments, segmentGroup, route); if (!res) return { ...noMatch }; const posParams = {}; Object.entries(res.posParams ?? {}).forEach(([k, v]) => { posParams[k] = v.path; }); const parameters = res.consumed.length > 0 ? { ...posParams, ...res.consumed[res.consumed.length - 1].parameters } : posParams; return { matched: true, consumedSegments: res.consumed, remainingSegments: segments.slice(res.consumed.length), parameters, positionalParamSegments: res.posParams ?? {} }; } function split(segmentGroup, consumedSegments, slicedSegments, config) { if (slicedSegments.length > 0 && containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) { const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(config, new UrlSegmentGroup(slicedSegments, segmentGroup.children))); return { segmentGroup: s, slicedSegments: [] }; } if (slicedSegments.length === 0 && containsEmptyPathMatches(segmentGroup, slicedSegments, config)) { const s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, slicedSegments, config, segmentGroup.children)); return { segmentGroup: s, slicedSegments }; } const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children); return { segmentGroup: s, slicedSegments }; } function addEmptyPathsToChildrenIfNeeded(segmentGroup, slicedSegments, routes, children) { const res = {}; for (const r of routes) { if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) { const s = new UrlSegmentGroup([], {}); res[getOutlet(r)] = s; } } return { ...children, ...res }; } function createChildrenForEmptyPaths(routes, primarySegment) { const res = {}; res[PRIMARY_OUTLET] = primarySegment; for (const r of routes) { if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) { const s = new UrlSegmentGroup([], {}); res[getOutlet(r)] = s; } } return res; } function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) { return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet(r) !== PRIMARY_OUTLET); } function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) { return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r)); } function emptyPathMatch(segmentGroup, slicedSegments, r) { if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') { return false; } return r.path === ''; } function noLeftoversInUrl(segmentGroup, segments, outlet) { return segments.length === 0 && !segmentGroup.children[outlet]; } class NoLeftoversInUrl {} async function recognize$1(injector, configLoader, rootComponentType, config, urlTree, urlSerializer, paramsInheritanceStrategy = 'emptyOnly', abortSignal) { return new Recognizer(injector, configLoader, rootComponentType, config, urlTree, paramsInheritanceStrategy, urlSerializer, abortSignal).recognize(); } const MAX_ALLOWED_REDIRECTS = 31; class Recognizer { injector; configLoader; rootComponentType; config; urlTree; paramsInheritanceStrategy; urlSerializer; abortSignal; applyRedirects; absoluteRedirectCount = 0; allowRedirects = true; constructor(injector, configLoader, rootComponentType, config, urlTree, paramsInheritanceStrategy, urlSerializer, abortSignal) { this.injector = injector; this.configLoader = configLoader; this.rootComponentType = rootComponentType; this.config = config; this.urlTree = urlTree; this.paramsInheritanceStrategy = paramsInheritanceStrategy; this.urlSerializer = urlSerializer; this.abortSignal = abortSignal; this.applyRedirects = new ApplyRedirects(this.urlSerializer, this.urlTree); } noMatchError(e) { return new _RuntimeError(4002, typeof ngDevMode === 'undefined' || ngDevMode ? `Cannot match any routes. URL Segment: '${e.segmentGroup}'` : `'${e.segmentGroup}'`); } async recognize() { const rootSegmentGroup = split(this.urlTree.root, [], [], this.config).segmentGroup; const { children, rootSnapshot } = await this.match(rootSegmentGroup); const rootNode = new TreeNode(rootSnapshot, children); const routeState = new RouterStateSnapshot('', rootNode); const tree = createUrlTreeFromSnapshot(rootSnapshot, [], this.urlTree.queryParams, this.urlTree.fragment); tree.queryParams = this.urlTree.queryParams; routeState.url = this.urlSerializer.serialize(tree); return { state: routeState, tree }; } async match(rootSegmentGroup) { const rootSnapshot = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, Object.freeze({}), PRIMARY_OUTLET, this.rootComponentType, null, {}, this.injector); try { const children = await this.processSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET, rootSnapshot); return { children, rootSnapshot }; } catch (e) { if (e instanceof AbsoluteRedirect) { this.urlTree = e.urlTree; return this.match(e.urlTree.root); } if (e instanceof NoMatch) { throw this.noMatchError(e); } throw e; } } async processSegmentGroup(injector, config, segmentGroup, outlet, parentRoute) { if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) { return this.processChildren(injector, config, segmentGroup, parentRoute); } const child = await this.processSegment(injector, config, segmentGroup, segmentGroup.segments, outlet, true, parentRoute); return child instanceof TreeNode ? [child] : []; } async processChildren(injector, config, segmentGroup, parentRoute) { const childOutlets = []; for (const child of Object.keys(segmentGroup.children)) { if (child === 'primary') { childOutlets.unshift(child); } else { childOutlets.push(child); } } let children = []; for (const childOutlet of childOutlets) { const child = segmentGroup.children[childOutlet]; const sortedConfig = sortByMatchingOutlets(config, childOutlet); const outletChildren = await this.processSegmentGroup(injector, sortedConfig, child, childOutlet, parentRoute); children.push(...outletChildren); } const mergedChildren = mergeEmptyPathMatches(children); if (typeof ngDevMode === 'undefined' || ngDevMode) { checkOutletNameUniqueness(mergedChildren); } sortActivatedRouteSnapshots(mergedChildren); return mergedChildren; } async processSegment(injector, routes, segmentGroup, segments, outlet, allowRedirects, parentRoute) { for (const r of routes) { try { return await this.processSegmentAgainstRoute(r._injector ?? injector, routes, r, segmentGroup, segments, outlet, allowRedirects, parentRoute); } catch (e) { if (e instanceof NoMatch || isEmptyError(e)) { continue; } throw e; } } if (noLeftoversInUrl(segmentGroup, segments, outlet)) { return new NoLeftoversInUrl(); } throw new NoMatch(segmentGroup); } async processSegmentAgainstRoute(injector, routes, route, rawSegment, segments, outlet, allowRedirects, parentRoute) { if (getOutlet(route) !== outlet && (outlet === PRIMARY_OUTLET || !emptyPathMatch(rawSegment, segments, route))) { throw new NoMatch(rawSegment); } if (route.redirectTo === undefined) { return this.matchSegmentAgainstRoute(injector, rawSegment, route, segments, outlet, parentRoute); } if (this.allowRedirects && allowRedirects) { return this.expandSegmentAgainstRouteUsingRedirect(injector, rawSegment, routes, route, segments, outlet, parentRoute); } throw new NoMatch(rawSegment); } async expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet, parentRoute) { const { matched, parameters, consumedSegments, positionalParamSegments, remainingSegments } = match(segmentGroup, route, segments); if (!matched) throw new NoMatch(segmentGroup); if (typeof route.redirectTo === 'string' && route.redirectTo[0] === '/') { this.absoluteRedirectCount++; if (this.absoluteRedirectCount > MAX_ALLOWED_REDIRECTS) { if (ngDevMode) { throw new _RuntimeError(4016, `Detected possible infinite redirect when redirecting from '${this.urlTree}' to '${route.redirectTo}'.\n` + `This is currently a dev mode only error but will become a` + ` call stack size exceeded error in production in a future major version.`); } this.allowRedirects = false; } } const currentSnapshot = new ActivatedRouteSnapshot(segments, parameters, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getResolve(route), injector); const inherited = getInherited(currentSnapshot, parentRoute, this.paramsInheritanceStrategy); currentSnapshot.params = Object.freeze(inherited.params); currentSnapshot.data = Object.freeze(inherited.data); if (this.abortSignal.aborted) { throw new Error(this.abortSignal.reason); } const newTree = await this.applyRedirects.applyRedirectCommands(consumedSegments, route.redirectTo, positionalParamSegments, currentSnapshot, injector); const newSegments = await this.applyRedirects.lineralizeSegments(route, newTree); return this.processSegment(injector, routes, segmentGroup, newSegments.concat(remainingSegments), outlet, false, parentRoute); } async matchSegmentAgainstRoute(injector, rawSegment, route, segments, outlet, parentRoute) { if (this.abortSignal.aborted) { throw new Error(this.abortSignal.reason); } const result = await firstValueFrom(matchWithChecks(rawSegment, route, segments, injector, this.urlSerializer, this.abortSignal)); if (route.path === '**') { rawSegment.children = {}; } if (!result?.matched) { throw new NoMatch(rawSegment); } injector = route._injector ?? injector; const { routes: childConfig } = await this.getChildConfig(injector, route, segments); const childInjector = route._loadedInjector ?? injector; const { parameters, consumedSegments, remainingSegments } = result; const snapshot = new ActivatedRouteSnapshot(consumedSegments, parameters, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getResolve(route), injector); const inherited = getInherited(snapshot, parentRoute, this.paramsInheritanceStrategy); snapshot.params = Object.freeze(inherited.params); snapshot.data = Object.freeze(inherited.data); const { segmentGroup, slicedSegments } = split(rawSegment, consumedSegments, remainingSegments, childConfig); if (slicedSegments.length === 0 && segmentGroup.hasChildren()) { const children = await this.processChildren(childInjector, childConfig, segmentGroup, snapshot); return new TreeNode(snapshot, children); } if (childConfig.length === 0 && slicedSegments.length === 0) { return new TreeNode(snapshot, []); } const matchedOnOutlet = getOutlet(route) === outlet; const child = await this.processSegment(childInjector, childConfig, segmentGroup, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true, snapshot); return new TreeNode(snapshot, child instanceof TreeNode ? [child] : []); } async getChildConfig(injector, route, segments) { if (route.children) { return { routes: route.children, injector }; } if (route.loadChildren) { if (route._loadedRoutes !== undefined) { const ngModuleFactory = route._loadedNgModuleFactory; if (ngModuleFactory && !route._loadedInjector) { route._loadedInjector = ngModuleFactory.create(injector).injector; } return { routes: route._loadedRoutes, injector: route._loadedInjector }; } if (this.abortSignal.aborted) { throw new Error(this.abortSignal.reason); } const shouldLoadResult = await firstValueFrom(runCanLoadGuards(injector, route, segments, this.urlSerializer, this.abortSignal)); if (shouldLoadResult) { const cfg = await this.configLoader.loadChildren(injector, route); route._loadedRoutes = cfg.routes; route._loadedInjector = cfg.injector; route._loadedNgModuleFactory = cfg.factory; return cfg; } throw canLoadFails(route); } return { routes: [], injector }; } } function sortActivatedRouteSnapshots(nodes) { nodes.sort((a, b) => { if (a.value.outlet === PRIMARY_OUTLET) return -1; if (b.value.outlet === PRIMARY_OUTLET) return 1; return a.value.outlet.localeCompare(b.value.outlet); }); } function hasEmptyPathConfig(node) { const config = node.value.routeConfig; return config && config.path === ''; } function mergeEmptyPathMatches(nodes) { const result = []; const mergedNodes = new Set(); for (const node of nodes) { if (!hasEmptyPathConfig(node)) { result.push(node); continue; } const duplicateEmptyPathNode = result.find(resultNode => node.value.routeConfig === resultNode.value.routeConfig); if (duplicateEmptyPathNode !== undefined) { duplicateEmptyPathNode.children.push(...node.children); mergedNodes.add(duplicateEmptyPathNode); } else { result.push(node); } } for (const mergedNode of mergedNodes) { const mergedChildren = mergeEmptyPathMatches(mergedNode.children); result.push(new TreeNode(mergedNode.value, mergedChildren)); } return result.filter(n => !mergedNodes.has(n)); } function checkOutletNameUniqueness(nodes) { const names = {}; nodes.forEach(n => { const routeWithSameOutletName = names[n.value.outlet]; if (routeWithSameOutletName) { const p = routeWithSameOutletName.url.map(s => s.toString()).join('/'); const c = n.value.url.map(s => s.toString()).join('/'); throw new _RuntimeError(4006, (typeof ngDevMode === 'undefined' || ngDevMode) && `Two segments cannot have the same outlet name: '${p}' and '${c}'.`); } names[n.value.outlet] = n.value; }); } function getData(route) { return route.data || {}; } function getResolve(route) { return route.resolve || {}; } function recognize(injector, configLoader, rootComponentType, config, serializer, paramsInheritanceStrategy, abortSignal) { return mergeMap(async t => { const { state: targetSnapshot, tree: urlAfterRedirects } = await recognize$1(injector, configLoader, rootComponentType, config, t.extractedUrl, serializer, paramsInheritanceStrategy, abortSignal); return { ...t, targetSnapshot, urlAfterRedirects }; }); } function resolveData(paramsInheritanceStrategy) { return mergeMap(t => { const { targetSnapshot, guards: { canActivateChecks } } = t; if (!canActivateChecks.length) { return of(t); } const routesWithResolversToRun = new Set(canActivateChecks.map(check => check.route)); const routesNeedingDataUpdates = new Set(); for (const route of routesWithResolversToRun) { if (routesNeedingDataUpdates.has(route)) { continue; } for (const newRoute of flattenRouteTree(route)) { routesNeedingDataUpdates.add(newRoute); } } let routesProcessed = 0; return from(routesNeedingDataUpdates).pipe(concatMap(route => { if (routesWithResolversToRun.has(route)) { return runResolve(route, targetSnapshot, paramsInheritanceStrategy); } else { route.data = getInherited(route, route.parent, paramsInheritanceStrategy).resolve; return of(void 0); } }), tap(() => routesProcessed++), takeLast(1), mergeMap(_ => routesProcessed === routesNeedingDataUpdates.size ? of(t) : EMPTY)); }); } function flattenRouteTree(route) { const descendants = route.children.map(child => flattenRouteTree(child)).flat(); return [route, ...descendants]; } function runResolve(futureARS, futureRSS, paramsInheritanceStrategy) { const config = futureARS.routeConfig; const resolve = futureARS._resolve; if (config?.title !== undefined && !hasStaticTitle(config)) { resolve[RouteTitleKey] = config.title; } return defer(() => { futureARS.data = getInherited(futureARS, futureARS.parent, paramsInheritanceStrategy).resolve; return resolveNode(resolve, futureARS, futureRSS).pipe(map(resolvedData => { futureARS._resolvedData = resolvedData; futureARS.data = { ...futureARS.data, ...resolvedData }; return null; })); }); } function resolveNode(resolve, futureARS, futureRSS) { const keys = getDataKeys(resolve); if (keys.length === 0) { return of({}); } const data = {}; return from(keys).pipe(mergeMap(key => getResolver(resolve[key], futureARS, futureRSS).pipe(first(), tap(value => { if (value instanceof RedirectCommand) { throw redirectingNavigationError(new DefaultUrlSerializer(), value); } data[key] = value; }))), takeLast(1), map(() => data), catchError(e => isEmptyError(e) ? EMPTY : throwError(e))); } function getResolver(injectionToken, futureARS, futureRSS) { const closestInjector = futureARS._environmentInjector; const resolver = getTokenOrFunctionIdentity(injectionToken, closestInjector); const resolverValue = resolver.resolve ? resolver.resolve(futureARS, futureRSS) : runInInjectionContext(closestInjector, () => resolver(futureARS, futureRSS)); return wrapIntoObservable(resolverValue); } function switchTap(next) { return switchMap(v => { const nextResult = next(v); if (nextResult) { return from(nextResult).pipe(map(() => v)); } return of(v); }); } class TitleStrategy { buildTitle(snapshot) { let pageTitle; let route = snapshot.root; while (route !== undefined) { pageTitle = this.getResolvedTitleForRoute(route) ?? pageTitle; route = route.children.find(child => child.outlet === PRIMARY_OUTLET); } return pageTitle; } getResolvedTitleForRoute(snapshot) { return snapshot.data[RouteTitleKey]; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TitleStrategy, decorators: [{ type: Injectable, args: [{ providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) }] }] }); class DefaultTitleStrategy extends TitleStrategy { title; constructor(title) { super(); this.title = title; } updateTitle(snapshot) { const title = this.buildTitle(snapshot); if (title !== undefined) { this.title.setTitle(title); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DefaultTitleStrategy, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.Title }] }); const ROUTER_CONFIGURATION = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'router config' : '', { factory: () => ({}) }); const ROUTES = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'ROUTES' : ''); class RouterConfigLoader { componentLoaders = new WeakMap(); childrenLoaders = new WeakMap(); onLoadStartListener; onLoadEndListener; compiler = inject(Compiler); async loadComponent(injector, route) { if (this.componentLoaders.get(route)) { return this.componentLoaders.get(route); } else if (route._loadedComponent) { return Promise.resolve(route._loadedComponent); } if (this.onLoadStartListener) { this.onLoadStartListener(route); } const loader = (async () => { try { const loaded = await wrapIntoPromise(runInInjectionContext(injector, () => route.loadComponent())); const component = await maybeResolveResources(maybeUnwrapDefaultExport(loaded)); if (this.onLoadEndListener) { this.onLoadEndListener(route); } (typeof ngDevMode === 'undefined' || ngDevMode) && assertStandalone(route.path ?? '', component); route._loadedComponent = component; return component; } finally { this.componentLoaders.delete(route); } })(); this.componentLoaders.set(route, loader); return loader; } loadChildren(parentInjector, route) { if (this.childrenLoaders.get(route)) { return this.childrenLoaders.get(route); } else if (route._loadedRoutes) { return Promise.resolve({ routes: route._loadedRoutes, injector: route._loadedInjector }); } if (this.onLoadStartListener) { this.onLoadStartListener(route); } const loader = (async () => { try { const result = await loadChildren(route, this.compiler, parentInjector, this.onLoadEndListener); route._loadedRoutes = result.routes; route._loadedInjector = result.injector; route._loadedNgModuleFactory = result.factory; return result; } finally { this.childrenLoaders.delete(route); } })(); this.childrenLoaders.set(route, loader); return loader; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RouterConfigLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RouterConfigLoader, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RouterConfigLoader, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); async function loadChildren(route, compiler, parentInjector, onLoadEndListener) { const loaded = await wrapIntoPromise(runInInjectionContext(parentInjector, () => route.loadChildren())); const t = await maybeResolveResources(maybeUnwrapDefaultExport(loaded)); let factoryOrRoutes; if (t instanceof NgModuleFactory || Array.isArray(t)) { factoryOrRoutes = t; } else { factoryOrRoutes = await compiler.compileModuleAsync(t); } if (onLoadEndListener) { onLoadEndListener(route); } let injector; let rawRoutes; let requireStandaloneComponents = false; let factory = undefined; if (Array.isArray(factoryOrRoutes)) { rawRoutes = factoryOrRoutes; requireStandaloneComponents = true; } else { injector = factoryOrRoutes.create(parentInjector).injector; factory = factoryOrRoutes; rawRoutes = injector.get(ROUTES, [], { optional: true, self: true }).flat(); } const routes = rawRoutes.map(standardizeConfig); (typeof ngDevMode === 'undefined' || ngDevMode) && validateConfig(routes, route.path, requireStandaloneComponents); return { routes, injector, factory }; } function isWrappedDefaultExport(value) { return value && typeof value === 'object' && 'default' in value; } function maybeUnwrapDefaultExport(input) { return isWrappedDefaultExport(input) ? input['default'] : input; } async function maybeResolveResources(value) { if ((typeof ngJitMode === 'undefined' || ngJitMode) && typeof fetch === 'function') { try { await _resolveComponentResources(fetch); } catch (error) { console.error(error); } } return value; } class UrlHandlingStrategy { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: UrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: UrlHandlingStrategy, providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: UrlHandlingStrategy, decorators: [{ type: Injectable, args: [{ providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) }] }] }); class DefaultUrlHandlingStrategy { shouldProcessUrl(url) { return true; } extract(url) { return url; } merge(newUrlPart, wholeUrl) { return newUrlPart; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DefaultUrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DefaultUrlHandlingStrategy, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DefaultUrlHandlingStrategy, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); const CREATE_VIEW_TRANSITION = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'view transition helper' : ''); const VIEW_TRANSITION_OPTIONS = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'view transition options' : ''); function createViewTransition(injector, from, to) { const transitionOptions = injector.get(VIEW_TRANSITION_OPTIONS); const document = injector.get(DOCUMENT); if (!document.startViewTransition || transitionOptions.skipNextTransition) { transitionOptions.skipNextTransition = false; return new Promise(resolve => setTimeout(resolve)); } let resolveViewTransitionStarted; const viewTransitionStarted = new Promise(resolve => { resolveViewTransitionStarted = resolve; }); const transition = document.startViewTransition(() => { resolveViewTransitionStarted(); return createRenderPromise(injector); }); transition.updateCallbackDone.catch(error => { if (typeof ngDevMode === 'undefined' || ngDevMode) { console.error(error); } }); transition.ready.catch(error => { if (typeof ngDevMode === 'undefined' || ngDevMode) { console.error(error); } }); transition.finished.catch(error => { if (typeof ngDevMode === 'undefined' || ngDevMode) { console.error(error); } }); const { onViewTransitionCreated } = transitionOptions; if (onViewTransitionCreated) { runInInjectionContext(injector, () => onViewTransitionCreated({ transition, from, to })); } return viewTransitionStarted; } function createRenderPromise(injector) { return new Promise(resolve => { afterNextRender({ read: () => setTimeout(resolve) }, { injector }); }); } const noop = () => {}; const NAVIGATION_ERROR_HANDLER = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'navigation error handler' : ''); class NavigationTransitions { currentNavigation = signal(null, { ...(ngDevMode ? { debugName: "currentNavigation" } : {}), equal: () => false }); currentTransition = null; lastSuccessfulNavigation = signal(null, ...(ngDevMode ? [{ debugName: "lastSuccessfulNavigation" }] : [])); events = new Subject(); transitionAbortWithErrorSubject = new Subject(); configLoader = inject(RouterConfigLoader); environmentInjector = inject(EnvironmentInjector); destroyRef = inject(DestroyRef); urlSerializer = inject(UrlSerializer); rootContexts = inject(ChildrenOutletContexts); location = inject(Location); inputBindingEnabled = inject(INPUT_BINDER, { optional: true }) !== null; titleStrategy = inject(TitleStrategy); options = inject(ROUTER_CONFIGURATION, { optional: true }) || {}; paramsInheritanceStrategy = this.options.paramsInheritanceStrategy || 'emptyOnly'; urlHandlingStrategy = inject(UrlHandlingStrategy); createViewTransition = inject(CREATE_VIEW_TRANSITION, { optional: true }); navigationErrorHandler = inject(NAVIGATION_ERROR_HANDLER, { optional: true }); navigationId = 0; get hasRequestedNavigation() { return this.navigationId !== 0; } transitions; afterPreactivation = () => of(void 0); rootComponentType = null; destroyed = false; constructor() { const onLoadStart = r => this.events.next(new RouteConfigLoadStart(r)); const onLoadEnd = r => this.events.next(new RouteConfigLoadEnd(r)); this.configLoader.onLoadEndListener = onLoadEnd; this.configLoader.onLoadStartListener = onLoadStart; this.destroyRef.onDestroy(() => { this.destroyed = true; }); } complete() { this.transitions?.complete(); } handleNavigationRequest(request) { const id = ++this.navigationId; untracked(() => { this.transitions?.next({ ...request, extractedUrl: this.urlHandlingStrategy.extract(request.rawUrl), targetSnapshot: null, targetRouterState: null, guards: { canActivateChecks: [], canDeactivateChecks: [] }, guardsResult: null, id }); }); } setupNavigations(router) { this.transitions = new BehaviorSubject(null); return this.transitions.pipe(filter(t => t !== null), switchMap(overallTransitionState => { let completedOrAborted = false; const abortController = new AbortController(); const shouldContinueNavigation = () => { return !completedOrAborted && this.currentTransition?.id === overallTransitionState.id; }; return of(overallTransitionState).pipe(switchMap(t => { if (this.navigationId > overallTransitionState.id) { const cancellationReason = typeof ngDevMode === 'undefined' || ngDevMode ? `Navigation ID ${overallTransitionState.id} is not equal to the current navigation id ${this.navigationId}` : ''; this.cancelNavigationTransition(overallTransitionState, cancellationReason, NavigationCancellationCode.SupersededByNewNavigation); return EMPTY; } this.currentTransition = overallTransitionState; const lastSuccessfulNavigation = this.lastSuccessfulNavigation(); this.currentNavigation.set({ id: t.id, initialUrl: t.rawUrl, extractedUrl: t.extractedUrl, targetBrowserUrl: typeof t.extras.browserUrl === 'string' ? this.urlSerializer.parse(t.extras.browserUrl) : t.extras.browserUrl, trigger: t.source, extras: t.extras, previousNavigation: !lastSuccessfulNavigation ? null : { ...lastSuccessfulNavigation, previousNavigation: null }, abort: () => abortController.abort() }); const urlTransition = !router.navigated || this.isUpdatingInternalState() || this.isUpdatedBrowserUrl(); const onSameUrlNavigation = t.extras.onSameUrlNavigation ?? router.onSameUrlNavigation; if (!urlTransition && onSameUrlNavigation !== 'reload') { const reason = typeof ngDevMode === 'undefined' || ngDevMode ? `Navigation to ${t.rawUrl} was ignored because it is the same as the current Router URL.` : ''; this.events.next(new NavigationSkipped(t.id, this.urlSerializer.serialize(t.rawUrl), reason, NavigationSkippedCode.IgnoredSameUrlNavigation)); t.resolve(false); return EMPTY; } if (this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl)) { return of(t).pipe(switchMap(t => { this.events.next(new NavigationStart(t.id, this.urlSerializer.serialize(t.extractedUrl), t.source, t.restoredState)); if (t.id !== this.navigationId) { return EMPTY; } return Promise.resolve(t); }), recognize(this.environmentInjector, this.configLoader, this.rootComponentType, router.config, this.urlSerializer, this.paramsInheritanceStrategy, abortController.signal), tap(t => { overallTransitionState.targetSnapshot = t.targetSnapshot; overallTransitionState.urlAfterRedirects = t.urlAfterRedirects; this.currentNavigation.update(nav => { nav.finalUrl = t.urlAfterRedirects; return nav; }); const routesRecognized = new RoutesRecognized(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot); this.events.next(routesRecognized); })); } else if (urlTransition && this.urlHandlingStrategy.shouldProcessUrl(t.currentRawUrl)) { const { id, extractedUrl, source, restoredState, extras } = t; const navStart = new NavigationStart(id, this.urlSerializer.serialize(extractedUrl), source, restoredState); this.events.next(navStart); const targetSnapshot = createEmptyState(this.rootComponentType, this.environmentInjector).snapshot; this.currentTransition = overallTransitionState = { ...t, targetSnapshot, urlAfterRedirects: extractedUrl, extras: { ...extras, skipLocationChange: false, replaceUrl: false } }; this.currentNavigation.update(nav => { nav.finalUrl = extractedUrl; return nav; }); return of(overallTransitionState); } else { const reason = typeof ngDevMode === 'undefined' || ngDevMode ? `Navigation was ignored because the UrlHandlingStrategy` + ` indicated neither the current URL ${t.currentRawUrl} nor target URL ${t.rawUrl} should be processed.` : ''; this.events.next(new NavigationSkipped(t.id, this.urlSerializer.serialize(t.extractedUrl), reason, NavigationSkippedCode.IgnoredByUrlHandlingStrategy)); t.resolve(false); return EMPTY; } }), map(t => { const guardsStart = new GuardsCheckStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot); this.events.next(guardsStart); this.currentTransition = overallTransitionState = { ...t, guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts) }; return overallTransitionState; }), checkGuards(evt => this.events.next(evt)), switchMap(t => { overallTransitionState.guardsResult = t.guardsResult; if (t.guardsResult && typeof t.guardsResult !== 'boolean') { throw redirectingNavigationError(this.urlSerializer, t.guardsResult); } const guardsEnd = new GuardsCheckEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult); this.events.next(guardsEnd); if (!shouldContinueNavigation()) { return EMPTY; } if (!t.guardsResult) { this.cancelNavigationTransition(t, '', NavigationCancellationCode.GuardRejected); return EMPTY; } if (t.guards.canActivateChecks.length === 0) { return of(t); } const resolveStart = new ResolveStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot); this.events.next(resolveStart); if (!shouldContinueNavigation()) { return EMPTY; } let dataResolved = false; return of(t).pipe(resolveData(this.paramsInheritanceStrategy), tap({ next: () => { dataResolved = true; const resolveEnd = new ResolveEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot); this.events.next(resolveEnd); }, complete: () => { if (!dataResolved) { this.cancelNavigationTransition(t, typeof ngDevMode === 'undefined' || ngDevMode ? `At least one route resolver didn't emit any value.` : '', NavigationCancellationCode.NoDataFromResolver); } } })); }), switchTap(t => { const loadComponents = route => { const loaders = []; if (route.routeConfig?._loadedComponent) { route.component = route.routeConfig?._loadedComponent; } else if (route.routeConfig?.loadComponent) { const injector = route._environmentInjector; loaders.push(this.configLoader.loadComponent(injector, route.routeConfig).then(loadedComponent => { route.component = loadedComponent; })); } for (const child of route.children) { loaders.push(...loadComponents(child)); } return loaders; }; const loaders = loadComponents(t.targetSnapshot.root); return loaders.length === 0 ? of(t) : from(Promise.all(loaders).then(() => t)); }), switchTap(() => this.afterPreactivation()), switchMap(() => { const { currentSnapshot, targetSnapshot } = overallTransitionState; const viewTransitionStarted = this.createViewTransition?.(this.environmentInjector, currentSnapshot.root, targetSnapshot.root); return viewTransitionStarted ? from(viewTransitionStarted).pipe(map(() => overallTransitionState)) : of(overallTransitionState); }), take(1), map(t => { const targetRouterState = createRouterState(router.routeReuseStrategy, t.targetSnapshot, t.currentRouterState); this.currentTransition = overallTransitionState = t = { ...t, targetRouterState }; this.currentNavigation.update(nav => { nav.targetRouterState = targetRouterState; return nav; }); this.events.next(new BeforeActivateRoutes()); if (!shouldContinueNavigation()) { return; } new ActivateRoutes(router.routeReuseStrategy, overallTransitionState.targetRouterState, overallTransitionState.currentRouterState, evt => this.events.next(evt), this.inputBindingEnabled).activate(this.rootContexts); if (!shouldContinueNavigation()) { return; } completedOrAborted = true; this.currentNavigation.update(nav => { nav.abort = noop; return nav; }); this.lastSuccessfulNavigation.set(untracked(this.currentNavigation)); this.events.next(new NavigationEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects))); this.titleStrategy?.updateTitle(t.targetRouterState.snapshot); t.resolve(true); }), takeUntil(abortSignalToObservable(abortController.signal).pipe(filter(() => !completedOrAborted && !overallTransitionState.targetRouterState), tap(() => { this.cancelNavigationTransition(overallTransitionState, abortController.signal.reason + '', NavigationCancellationCode.Aborted); }))), tap({ complete: () => { completedOrAborted = true; } }), takeUntil(this.transitionAbortWithErrorSubject.pipe(tap(err => { throw err; }))), finalize(() => { abortController.abort(); if (!completedOrAborted) { const cancelationReason = typeof ngDevMode === 'undefined' || ngDevMode ? `Navigation ID ${overallTransitionState.id} is not equal to the current navigation id ${this.navigationId}` : ''; this.cancelNavigationTransition(overallTransitionState, cancelationReason, NavigationCancellationCode.SupersededByNewNavigation); } if (this.currentTransition?.id === overallTransitionState.id) { this.currentNavigation.set(null); this.currentTransition = null; } }), catchError(e => { completedOrAborted = true; if (this.destroyed) { overallTransitionState.resolve(false); return EMPTY; } if (isNavigationCancelingError(e)) { this.events.next(new NavigationCancel(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e.message, e.cancellationCode)); if (!isRedirectingNavigationCancelingError(e)) { overallTransitionState.resolve(false); } else { this.events.next(new RedirectRequest(e.url, e.navigationBehaviorOptions)); } } else { const navigationError = new NavigationError(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e, overallTransitionState.targetSnapshot ?? undefined); try { const navigationErrorHandlerResult = runInInjectionContext(this.environmentInjector, () => this.navigationErrorHandler?.(navigationError)); if (navigationErrorHandlerResult instanceof RedirectCommand) { const { message, cancellationCode } = redirectingNavigationError(this.urlSerializer, navigationErrorHandlerResult); this.events.next(new NavigationCancel(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), message, cancellationCode)); this.events.next(new RedirectRequest(navigationErrorHandlerResult.redirectTo, navigationErrorHandlerResult.navigationBehaviorOptions)); } else { this.events.next(navigationError); throw e; } } catch (ee) { if (this.options.resolveNavigationPromiseOnError) { overallTransitionState.resolve(false); } else { overallTransitionState.reject(ee); } } } return EMPTY; })); })); } cancelNavigationTransition(t, reason, code) { const navCancel = new NavigationCancel(t.id, this.urlSerializer.serialize(t.extractedUrl), reason, code); this.events.next(navCancel); t.resolve(false); } isUpdatingInternalState() { return this.currentTransition?.extractedUrl.toString() !== this.currentTransition?.currentUrlTree.toString(); } isUpdatedBrowserUrl() { const currentBrowserUrl = this.urlHandlingStrategy.extract(this.urlSerializer.parse(this.location.path(true))); const currentNavigation = untracked(this.currentNavigation); const targetBrowserUrl = currentNavigation?.targetBrowserUrl ?? currentNavigation?.extractedUrl; return currentBrowserUrl.toString() !== targetBrowserUrl?.toString() && !currentNavigation?.extras.skipLocationChange; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: NavigationTransitions, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: NavigationTransitions, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: NavigationTransitions, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); function isBrowserTriggeredNavigation(source) { return source !== IMPERATIVE_NAVIGATION; } const ROUTE_INJECTOR_CLEANUP = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'RouteInjectorCleanup' : ''); function routeInjectorCleanup(routeReuseStrategy, routerState, config) { const activeRoutes = new Set(); if (routerState.snapshot.root) { collectDescendants(routerState.snapshot.root, activeRoutes); } const storedHandles = routeReuseStrategy.retrieveStoredRouteHandles?.() || []; for (const handle of storedHandles) { const internalHandle = handle; if (internalHandle?.route?.value?.snapshot) { for (const snapshot of internalHandle.route.value.snapshot.pathFromRoot) { if (snapshot.routeConfig) { activeRoutes.add(snapshot.routeConfig); } } } } destroyUnusedInjectors(config, activeRoutes, routeReuseStrategy, false); } function collectDescendants(snapshot, activeRoutes) { if (snapshot.routeConfig) { activeRoutes.add(snapshot.routeConfig); } for (const child of snapshot.children) { collectDescendants(child, activeRoutes); } } function destroyUnusedInjectors(routes, activeRoutes, strategy, inheritedForceDestroy) { for (const route of routes) { const shouldDestroyCurrentRoute = inheritedForceDestroy || !!((route._injector || route._loadedInjector) && !activeRoutes.has(route) && (strategy.shouldDestroyInjector?.(route) ?? false)); if (route.children) { destroyUnusedInjectors(route.children, activeRoutes, strategy, shouldDestroyCurrentRoute); } if (route.loadChildren && route._loadedRoutes) { destroyUnusedInjectors(route._loadedRoutes, activeRoutes, strategy, shouldDestroyCurrentRoute); } if (shouldDestroyCurrentRoute) { if (route._injector) { route._injector.destroy(); route._injector = undefined; } if (route._loadedInjector) { route._loadedInjector.destroy(); route._loadedInjector = undefined; } } } } function destroyDetachedRouteHandle(handle) { const internalHandle = handle; if (internalHandle && internalHandle.componentRef) { internalHandle.componentRef.destroy(); } } class RouteReuseStrategy { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RouteReuseStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RouteReuseStrategy, providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: RouteReuseStrategy, decorators: [{ type: Injectable, args: [{ providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) }] }] }); class BaseRouteReuseStrategy { shouldDetach(route) { return false; } store(route, detachedTree) {} shouldAttach(route) { return false; } retrieve(route) { return null; } shouldReuseRoute(future, curr) { return future.routeConfig === curr.routeConfig; } shouldDestroyInjector(route) { return true; } } class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DefaultRouteReuseStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DefaultRouteReuseStrategy, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DefaultRouteReuseStrategy, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); class StateManager { urlSerializer = inject(UrlSerializer); options = inject(ROUTER_CONFIGURATION, { optional: true }) || {}; canceledNavigationResolution = this.options.canceledNavigationResolution || 'replace'; location = inject(Location); urlHandlingStrategy = inject(UrlHandlingStrategy); urlUpdateStrategy = this.options.urlUpdateStrategy || 'deferred'; currentUrlTree = new UrlTree(); getCurrentUrlTree() { return this.currentUrlTree; } rawUrlTree = this.currentUrlTree; getRawUrlTree() { return this.rawUrlTree; } createBrowserPath({ finalUrl, initialUrl, targetBrowserUrl }) { const rawUrl = finalUrl !== undefined ? this.urlHandlingStrategy.merge(finalUrl, initialUrl) : initialUrl; const url = targetBrowserUrl ?? rawUrl; const path = url instanceof UrlTree ? this.urlSerializer.serialize(url) : url; return path; } commitTransition({ targetRouterState, finalUrl, initialUrl }) { if (finalUrl && targetRouterState) { this.currentUrlTree = finalUrl; this.rawUrlTree = this.urlHandlingStrategy.merge(finalUrl, initialUrl); this.routerState = targetRouterState; } else { this.rawUrlTree = initialUrl; } } routerState = createEmptyState(null, inject(EnvironmentInjector)); getRouterState() { return this.routerState; } _stateMemento = this.createStateMemento(); get stateMemento() { return this._stateMemento; } updateStateMemento() { this._stateMemento = this.createStateMemento(); } createStateMemento() { return { rawUrlTree: this.rawUrlTree, currentUrlTree: this.currentUrlTree, routerState: this.routerState }; } restoredState() { return this.location.getState(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: StateManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: StateManager, providedIn: 'root', useFactory: () => inject(HistoryStateManager) }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: StateManager, decorators: [{ type: Injectable, args: [{ providedIn: 'root', useFactory: () => inject(HistoryStateManager) }] }] }); class HistoryStateManager extends StateManager { currentPageId = 0; lastSuccessfulId = -1; get browserPageId() { if (this.canceledNavigationResolution !== 'computed') { return this.currentPageId; } return this.restoredState()?.ɵrouterPageId ?? this.currentPageId; } registerNonRouterCurrentEntryChangeListener(listener) { return this.location.subscribe(event => { if (event['type'] === 'popstate') { setTimeout(() => { listener(event['url'], event.state, 'popstate'); }); } }); } handleRouterEvent(e, currentTransition) { if (e instanceof NavigationStart) { this.updateStateMemento(); } else if (e instanceof NavigationSkipped) { this.commitTransition(currentTransition); } else if (e instanceof RoutesRecognized) { if (this.urlUpdateStrategy === 'eager') { if (!currentTransition.extras.skipLocationChange) { this.setBrowserUrl(this.createBrowserPath(currentTransition), currentTransition); } } } else if (e instanceof BeforeActivateRoutes) { this.commitTransition(currentTransition); if (this.urlUpdateStrategy === 'deferred' && !currentTransition.extras.skipLocationChange) { this.setBrowserUrl(this.createBrowserPath(currentTransition), currentTransition); } } else if (e instanceof NavigationCancel && !isRedirectingEvent(e)) { this.restoreHistory(currentTransition); } else if (e instanceof NavigationError) { this.restoreHistory(currentTransition, true); } else if (e instanceof NavigationEnd) { this.lastSuccessfulId = e.id; this.currentPageId = this.browserPageId; } } setBrowserUrl(path, { extras, id }) { const { replaceUrl, state } = extras; if (this.location.isCurrentPathEqualTo(path) || !!replaceUrl) { const currentBrowserPageId = this.browserPageId; const newState = { ...state, ...this.generateNgRouterState(id, currentBrowserPageId) }; this.location.replaceState(path, '', newState); } else { const newState = { ...state, ...this.generateNgRouterState(id, this.browserPageId + 1) }; this.location.go(path, '', newState); } } restoreHistory(navigation, restoringFromCaughtError = false) { if (this.canceledNavigationResolution === 'computed') { const currentBrowserPageId = this.browserPageId; const targetPagePosition = this.currentPageId - currentBrowserPageId; if (targetPagePosition !== 0) { this.location.historyGo(targetPagePosition); } else if (this.getCurrentUrlTree() === navigation.finalUrl && targetPagePosition === 0) { this.resetInternalState(navigation); this.resetUrlToCurrentUrlTree(); } else ; } else if (this.canceledNavigationResolution === 'replace') { if (restoringFromCaughtError) { this.resetInternalState(navigation); } this.resetUrlToCurrentUrlTree(); } } resetInternalState({ finalUrl }) { this.routerState = this.stateMemento.routerState; this.currentUrlTree = this.stateMemento.currentUrlTree; this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, finalUrl ?? this.rawUrlTree); } resetUrlToCurrentUrlTree() { this.location.replaceState(this.urlSerializer.serialize(this.getRawUrlTree()), '', this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId)); } generateNgRouterState(navigationId, routerPageId) { if (this.canceledNavigationResolution === 'computed') { return { navigationId, ɵrouterPageId: routerPageId }; } return { navigationId }; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: HistoryStateManager, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: HistoryStateManager, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: HistoryStateManager, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); function afterNextNavigation(router, action) { router.events.pipe(filter(e => e instanceof NavigationEnd || e instanceof NavigationCancel || e instanceof NavigationError || e instanceof NavigationSkipped), map(e => { if (e instanceof NavigationEnd || e instanceof NavigationSkipped) { return 0; } const redirecting = e instanceof NavigationCancel ? e.code === NavigationCancellationCode.Redirect || e.code === NavigationCancellationCode.SupersededByNewNavigation : false; return redirecting ? 2 : 1; }), filter(result => result !== 2), take(1)).subscribe(() => { action(); }); } const exactMatchOptions = { paths: 'exact', fragment: 'ignored', matrixParams: 'ignored', queryParams: 'exact' }; const subsetMatchOptions = { paths: 'subset', fragment: 'ignored', matrixParams: 'ignored', queryParams: 'subset' }; class Router { get currentUrlTree() { return this.stateManager.getCurrentUrlTree(); } get rawUrlTree() { return this.stateManager.getRawUrlTree(); } disposed = false; nonRouterCurrentEntryChangeSubscription; console = inject(_Console); stateManager = inject(StateManager); options = inject(ROUTER_CONFIGURATION, { optional: true }) || {}; pendingTasks = inject(_PendingTasksInternal); urlUpdateStrategy = this.options.urlUpdateStrategy || 'deferred'; navigationTransitions = inject(NavigationTransitions); urlSerializer = inject(UrlSerializer); location = inject(Location); urlHandlingStrategy = inject(UrlHandlingStrategy); injector = inject(EnvironmentInjector); _events = new Subject(); get events() { return this._events; } get routerState() { return this.stateManager.getRouterState(); } navigated = false; routeReuseStrategy = inject(RouteReuseStrategy); injectorCleanup = inject(ROUTE_INJECTOR_CLEANUP, { optional: true }); onSameUrlNavigation = this.options.onSameUrlNavigation || 'ignore'; config = inject(ROUTES, { optional: true })?.flat() ?? []; componentInputBindingEnabled = !!inject(INPUT_BINDER, { optional: true }); currentNavigation = this.navigationTransitions.currentNavigation.asReadonly(); constructor() { this.resetConfig(this.config); this.navigationTransitions.setupNavigations(this).subscribe({ error: e => {} }); this.subscribeToNavigationEvents(); } eventsSubscription = new Subscription(); subscribeToNavigationEvents() { const subscription = this.navigationTransitions.events.subscribe(e => { try { const currentTransition = this.navigationTransitions.currentTransition; const currentNavigation = untracked(this.navigationTransitions.currentNavigation); if (currentTransition !== null && currentNavigation !== null) { this.stateManager.handleRouterEvent(e, currentNavigation); if (e instanceof NavigationCancel && e.code !== NavigationCancellationCode.Redirect && e.code !== NavigationCancellationCode.SupersededByNewNavigation) { this.navigated = true; } else if (e instanceof NavigationEnd) { this.navigated = true; this.injectorCleanup?.(this.routeReuseStrategy, this.routerState, this.config); } else if (e instanceof RedirectRequest) { const opts = e.navigationBehaviorOptions; const mergedTree = this.urlHandlingStrategy.merge(e.url, currentTransition.currentRawUrl); const extras = { scroll: currentTransition.extras.scroll, browserUrl: currentTransition.extras.browserUrl, info: currentTransition.extras.info, skipLocationChange: currentTransition.extras.skipLocationChange, replaceUrl: currentTransition.extras.replaceUrl || this.urlUpdateStrategy === 'eager' || isBrowserTriggeredNavigation(currentTransition.source), ...opts }; this.scheduleNavigation(mergedTree, IMPERATIVE_NAVIGATION, null, extras, { resolve: currentTransition.resolve, reject: currentTransition.reject, promise: currentTransition.promise }); } } if (isPublicRouterEvent(e)) { this._events.next(e); } } catch (e) { this.navigationTransitions.transitionAbortWithErrorSubject.next(e); } }); this.eventsSubscription.add(subscription); } resetRootComponentType(rootComponentType) { this.routerState.root.component = rootComponentType; this.navigationTransitions.rootComponentType = rootComponentType; } initialNavigation() { this.setUpLocationChangeListener(); if (!this.navigationTransitions.hasRequestedNavigation) { this.navigateToSyncWithBrowser(this.location.path(true), IMPERATIVE_NAVIGATION, this.stateManager.restoredState()); } } setUpLocationChangeListener() { this.nonRouterCurrentEntryChangeSubscription ??= this.stateManager.registerNonRouterCurrentEntryChangeListener((url, state, source) => { this.navigateToSyncWithBrowser(url, source, state); }); } navigateToSyncWithBrowser(url, source, state) { const extras = { replaceUrl: true }; const restoredState = state?.navigationId ? state : null; if (state) { const stateCopy = { ...state }; delete stateCopy.navigationId; delete stateCopy.ɵrouterPageId; if (Object.keys(stateCopy).length !== 0) { extras.state = stateCopy; } } const urlTree = this.parseUrl(url); this.scheduleNavigation(urlTree, source, restoredState, extras).catch(e => { if (this.disposed) { return; } this.injector.get(_INTERNAL_APPLICATION_ERROR_HANDLER)(e); }); } get url() { return this.serializeUrl(this.currentUrlTree); } getCurrentNavigation() { return untracked(this.navigationTransitions.currentNavigation); } get lastSuccessfulNavigation() { return this.navigationTransitions.lastSuccessfulNavigation; } resetConfig(config) { (typeof ngDevMode === 'undefined' || ngDevMode) && validateConfig(config); this.config = config.map(standardizeConfig); this.navigated = false; } ngOnDestroy() { this.dispose(); } dispose() { this._events.unsubscribe(); this.navigationTransitions.complete(); this.nonRouterCurrentEntryChangeSubscription?.unsubscribe(); this.nonRouterCurrentEntryChangeSubscription = undefined; this.disposed = true; this.eventsSubscription.unsubscribe(); } createUrlTree(commands, navigationExtras = {}) { const { relativeTo, queryParams, fragment, queryParamsHandling, preserveFragment } = navigationExtras; const f = preserveFragment ? this.currentUrlTree.fragment : fragment; let q = null; switch (queryParamsHandling ?? this.options.defaultQueryParamsHandling) { case 'merge': q = { ...this.currentUrlTree.queryParams, ...queryParams }; break; case 'preserve': q = this.currentUrlTree.queryParams; break; default: q = queryParams || null; } if (q !== null) { q = this.removeEmptyProps(q); } let relativeToUrlSegmentGroup; try { const relativeToSnapshot = relativeTo ? relativeTo.snapshot : this.routerState.snapshot.root; relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeToSnapshot); } catch (e) { if (typeof commands[0] !== 'string' || commands[0][0] !== '/') { commands = []; } relativeToUrlSegmentGroup = this.currentUrlTree.root; } return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, q, f ?? null, this.urlSerializer); } navigateByUrl(url, extras = { skipLocationChange: false }) { const urlTree = isUrlTree(url) ? url : this.parseUrl(url); const mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree); return this.scheduleNavigation(mergedTree, IMPERATIVE_NAVIGATION, null, extras); } navigate(commands, extras = { skipLocationChange: false }) { validateCommands(commands); return this.navigateByUrl(this.createUrlTree(commands, extras), extras); } serializeUrl(url) { return this.urlSerializer.serialize(url); } parseUrl(url) { try { return this.urlSerializer.parse(url); } catch (e) { this.console.warn(_formatRuntimeError(4018, ngDevMode && `Error parsing URL ${url}. Falling back to '/' instead. \n` + e)); return this.urlSerializer.parse('/'); } } isActive(url, matchOptions) { let options; if (matchOptions === true) { options = { ...exactMatchOptions }; } else if (matchOptions === false) { options = { ...subsetMatchOptions }; } else { options = matchOptions; } if (isUrlTree(url)) { return containsTree(this.currentUrlTree, url, options); } const urlTree = this.parseUrl(url); return containsTree(this.currentUrlTree, urlTree, options); } removeEmptyProps(params) { return Object.entries(params).reduce((result, [key, value]) => { if (value !== null && value !== undefined) { result[key] = value; } return result; }, {}); } scheduleNavigation(rawUrl, source, restoredState, extras, priorPromise) { if (this.disposed) { return Promise.resolve(false); } let resolve; let reject; let promise; if (priorPromise) { resolve = priorPromise.resolve; reject = priorPromise.reject; promise = priorPromise.promise; } else { promise = new Promise((res, rej) => { resolve = res; reject = rej; }); } const taskId = this.pendingTasks.add(); afterNextNavigation(this, () => { queueMicrotask(() => this.pendingTasks.remove(taskId)); }); this.navigationTransitions.handleNavigationRequest({ source, restoredState, currentUrlTree: this.currentUrlTree, currentRawUrl: this.currentUrlTree, rawUrl, extras, resolve: resolve, reject: reject, promise, currentSnapshot: this.routerState.snapshot, currentRouterState: this.routerState }); return promise.catch(e => { return Promise.reject(e); }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Router, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Router, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Router, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); function validateCommands(commands) { for (let i = 0; i < commands.length; i++) { const cmd = commands[i]; if (cmd == null) { throw new _RuntimeError(4008, (typeof ngDevMode === 'undefined' || ngDevMode) && `The requested path contains ${cmd} segment at index ${i}`); } } } export { ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart, BaseRouteReuseStrategy, BeforeActivateRoutes, CREATE_VIEW_TRANSITION, ChildActivationEnd, ChildActivationStart, ChildrenOutletContexts, DefaultTitleStrategy, DefaultUrlSerializer, EventType, GuardsCheckEnd, GuardsCheckStart, IMPERATIVE_NAVIGATION, INPUT_BINDER, NAVIGATION_ERROR_HANDLER, NavigationCancel, NavigationCancellationCode, NavigationEnd, NavigationError, NavigationSkipped, NavigationSkippedCode, NavigationStart, NavigationTransitions, OutletContext, PRIMARY_OUTLET, ROUTER_CONFIGURATION, ROUTER_OUTLET_DATA, ROUTES, ROUTE_INJECTOR_CLEANUP, RedirectCommand, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, RoutedComponentInputBinder, Router, RouterConfigLoader, RouterEvent, RouterOutlet, RouterState, RouterStateSnapshot, RoutesRecognized, Scroll, StateManager, TitleStrategy, UrlHandlingStrategy, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree, VIEW_TRANSITION_OPTIONS, afterNextNavigation, convertToParamMap, createUrlTreeFromSnapshot, createViewTransition, defaultUrlMatcher, destroyDetachedRouteHandle, exactMatchOptions, isActive, isRedirectingEvent, isUrlTree, loadChildren, routeInjectorCleanup, stringifyEvent, subsetMatchOptions, ɵEmptyOutletComponent }; //# sourceMappingURL=_router-chunk.mjs.map