{"ast":null,"code":"/**\n * @license Angular v19.2.20\n * (c) 2010-2025 Google LLC. https://angular.io/\n * License: MIT\n */\n\nimport * as i0 from '@angular/core';\nimport { InjectionToken, inject, Injectable, Optional, Inject, ɵɵinject as __inject } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { DOCUMENT } from './dom_tokens-rA0ACyx7.mjs';\nlet _DOM = null;\nfunction getDOM() {\n  return _DOM;\n}\nfunction setRootDomAdapter(adapter) {\n  _DOM ??= adapter;\n}\n/**\n * Provides DOM operations in an environment-agnostic way.\n *\n * @security Tread carefully! Interacting with the DOM directly is dangerous and\n * can introduce XSS risks.\n */\nclass DomAdapter {}\n\n/**\n * This class should not be used directly by an application developer. Instead, use\n * {@link Location}.\n *\n * `PlatformLocation` encapsulates all calls to DOM APIs, which allows the Router to be\n * platform-agnostic.\n * This means that we can have different implementation of `PlatformLocation` for the different\n * platforms that Angular supports. For example, `@angular/platform-browser` provides an\n * implementation specific to the browser environment, while `@angular/platform-server` provides\n * one suitable for use with server-side rendering.\n *\n * The `PlatformLocation` class is used directly by all implementations of {@link LocationStrategy}\n * when they need to interact with the DOM APIs like pushState, popState, etc.\n *\n * {@link LocationStrategy} in turn is used by the {@link Location} service which is used directly\n * by the {@link /api/router/Router Router} in order to navigate between routes. Since all interactions between\n * {@link /api/router/Router Router} /\n * {@link Location} / {@link LocationStrategy} and DOM APIs flow through the `PlatformLocation`\n * class, they are all platform-agnostic.\n *\n * @publicApi\n */\nlet PlatformLocation = /*#__PURE__*/(() => {\n  class PlatformLocation {\n    historyGo(relativePosition) {\n      throw new Error(ngDevMode ? 'Not implemented' : '');\n    }\n    static ɵfac = function PlatformLocation_Factory(__ngFactoryType__) {\n      return new (__ngFactoryType__ || PlatformLocation)();\n    };\n    static ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: PlatformLocation,\n      factory: () => (() => inject(BrowserPlatformLocation))(),\n      providedIn: 'platform'\n    });\n  }\n  return PlatformLocation;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @description\n * Indicates when a location is initialized.\n *\n * @publicApi\n */\nconst LOCATION_INITIALIZED = /*#__PURE__*/new InjectionToken(ngDevMode ? 'Location Initialized' : '');\n/**\n * `PlatformLocation` encapsulates all of the direct calls to platform APIs.\n * This class should not be used directly by an application developer. Instead, use\n * {@link Location}.\n *\n * @publicApi\n */\nlet BrowserPlatformLocation = /*#__PURE__*/(() => {\n  class BrowserPlatformLocation extends PlatformLocation {\n    _location;\n    _history;\n    _doc = inject(DOCUMENT);\n    constructor() {\n      super();\n      this._location = window.location;\n      this._history = window.history;\n    }\n    getBaseHrefFromDOM() {\n      return getDOM().getBaseHref(this._doc);\n    }\n    onPopState(fn) {\n      const window = getDOM().getGlobalEventTarget(this._doc, 'window');\n      window.addEventListener('popstate', fn, false);\n      return () => window.removeEventListener('popstate', fn);\n    }\n    onHashChange(fn) {\n      const window = getDOM().getGlobalEventTarget(this._doc, 'window');\n      window.addEventListener('hashchange', fn, false);\n      return () => window.removeEventListener('hashchange', fn);\n    }\n    get href() {\n      return this._location.href;\n    }\n    get protocol() {\n      return this._location.protocol;\n    }\n    get hostname() {\n      return this._location.hostname;\n    }\n    get port() {\n      return this._location.port;\n    }\n    get pathname() {\n      return this._location.pathname;\n    }\n    get search() {\n      return this._location.search;\n    }\n    get hash() {\n      return this._location.hash;\n    }\n    set pathname(newPath) {\n      this._location.pathname = newPath;\n    }\n    pushState(state, title, url) {\n      this._history.pushState(state, title, url);\n    }\n    replaceState(state, title, url) {\n      this._history.replaceState(state, title, url);\n    }\n    forward() {\n      this._history.forward();\n    }\n    back() {\n      this._history.back();\n    }\n    historyGo(relativePosition = 0) {\n      this._history.go(relativePosition);\n    }\n    getState() {\n      return this._history.state;\n    }\n    static ɵfac = function BrowserPlatformLocation_Factory(__ngFactoryType__) {\n      return new (__ngFactoryType__ || BrowserPlatformLocation)();\n    };\n    static ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: BrowserPlatformLocation,\n      factory: () => (() => new BrowserPlatformLocation())(),\n      providedIn: 'platform'\n    });\n  }\n  return BrowserPlatformLocation;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Joins two parts of a URL with a slash if needed.\n *\n * @param start  URL string\n * @param end    URL string\n *\n *\n * @returns The joined URL string.\n */\nfunction joinWithSlash(start, end) {\n  // If `start` is an empty string, return `end` as the result.\n  if (!start) return end;\n  // If `end` is an empty string, return `start` as the result.\n  if (!end) return start;\n  // If `start` ends with a slash, remove the leading slash from `end`.\n  if (start.endsWith('/')) {\n    return end.startsWith('/') ? start + end.slice(1) : start + end;\n  }\n  // If `start` doesn't end with a slash, add one if `end` doesn't start with a slash.\n  return end.startsWith('/') ? start + end : `${start}/${end}`;\n}\n/**\n * Removes a trailing slash from a URL string if needed.\n * Looks for the first occurrence of either `#`, `?`, or the end of the\n * line as `/` characters and removes the trailing slash if one exists.\n *\n * @param url URL string.\n *\n * @returns The URL string, modified if needed.\n */\nfunction stripTrailingSlash(url) {\n  // Find the index of the first occurrence of `#`, `?`, or the end of the string.\n  // This marks the start of the query string, fragment, or the end of the URL path.\n  const pathEndIdx = url.search(/#|\\?|$/);\n  // Check if the character before `pathEndIdx` is a trailing slash.\n  // If it is, remove the trailing slash and return the modified URL.\n  // Otherwise, return the URL as is.\n  return url[pathEndIdx - 1] === '/' ? url.slice(0, pathEndIdx - 1) + url.slice(pathEndIdx) : url;\n}\n/**\n * Normalizes URL parameters by prepending with `?` if needed.\n *\n * @param  params String of URL parameters.\n *\n * @returns The normalized URL parameters string.\n */\nfunction normalizeQueryParams(params) {\n  return params && params[0] !== '?' ? `?${params}` : params;\n}\n\n/**\n * Enables the `Location` service to read route state from the browser's URL.\n * Angular provides two strategies:\n * `HashLocationStrategy` and `PathLocationStrategy`.\n *\n * Applications should use the `Router` or `Location` services to\n * interact with application route state.\n *\n * For instance, `HashLocationStrategy` produces URLs like\n * <code class=\"no-auto-link\">http://example.com/#/foo</code>,\n * and `PathLocationStrategy` produces\n * <code class=\"no-auto-link\">http://example.com/foo</code> as an equivalent URL.\n *\n * See these two classes for more.\n *\n * @publicApi\n */\nlet LocationStrategy = /*#__PURE__*/(() => {\n  class LocationStrategy {\n    historyGo(relativePosition) {\n      throw new Error(ngDevMode ? 'Not implemented' : '');\n    }\n    static ɵfac = function LocationStrategy_Factory(__ngFactoryType__) {\n      return new (__ngFactoryType__ || LocationStrategy)();\n    };\n    static ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: LocationStrategy,\n      factory: () => (() => inject(PathLocationStrategy))(),\n      providedIn: 'root'\n    });\n  }\n  return LocationStrategy;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * A predefined DI token for the base href\n * to be used with the `PathLocationStrategy`.\n * The base href is the URL prefix that should be preserved when generating\n * and recognizing URLs.\n *\n * @usageNotes\n *\n * The following example shows how to use this token to configure the root app injector\n * with a base href value, so that the DI framework can supply the dependency anywhere in the app.\n *\n * ```ts\n * import {NgModule} from '@angular/core';\n * import {APP_BASE_HREF} from '@angular/common';\n *\n * @NgModule({\n *   providers: [{provide: APP_BASE_HREF, useValue: '/my/app'}]\n * })\n * class AppModule {}\n * ```\n *\n * @publicApi\n */\nconst APP_BASE_HREF = /*#__PURE__*/new InjectionToken(ngDevMode ? 'appBaseHref' : '');\n/**\n * @description\n * A {@link LocationStrategy} used to configure the {@link Location} service to\n * represent its state in the\n * [path](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax) of the\n * browser's URL.\n *\n * If you're using `PathLocationStrategy`, you may provide a {@link APP_BASE_HREF}\n * or add a `<base href>` element to the document to override the default.\n *\n * For instance, if you provide an `APP_BASE_HREF` of `'/my/app/'` and call\n * `location.go('/foo')`, the browser's URL will become\n * `example.com/my/app/foo`. To ensure all relative URIs resolve correctly,\n * the `<base href>` and/or `APP_BASE_HREF` should end with a `/`.\n *\n * Similarly, if you add `<base href='/my/app/'/>` to the document and call\n * `location.go('/foo')`, the browser's URL will become\n * `example.com/my/app/foo`.\n *\n * Note that when using `PathLocationStrategy`, neither the query nor\n * the fragment in the `<base href>` will be preserved, as outlined\n * by the [RFC](https://tools.ietf.org/html/rfc3986#section-5.2.2).\n *\n * @usageNotes\n *\n * ### Example\n *\n * {@example common/location/ts/path_location_component.ts region='LocationComponent'}\n *\n * @publicApi\n */\nlet PathLocationStrategy = /*#__PURE__*/(() => {\n  class PathLocationStrategy extends LocationStrategy {\n    _platformLocation;\n    _baseHref;\n    _removeListenerFns = [];\n    constructor(_platformLocation, href) {\n      super();\n      this._platformLocation = _platformLocation;\n      this._baseHref = href ?? this._platformLocation.getBaseHrefFromDOM() ?? inject(DOCUMENT).location?.origin ?? '';\n    }\n    /** @docs-private */\n    ngOnDestroy() {\n      while (this._removeListenerFns.length) {\n        this._removeListenerFns.pop()();\n      }\n    }\n    onPopState(fn) {\n      this._removeListenerFns.push(this._platformLocation.onPopState(fn), this._platformLocation.onHashChange(fn));\n    }\n    getBaseHref() {\n      return this._baseHref;\n    }\n    prepareExternalUrl(internal) {\n      return joinWithSlash(this._baseHref, internal);\n    }\n    path(includeHash = false) {\n      const pathname = this._platformLocation.pathname + normalizeQueryParams(this._platformLocation.search);\n      const hash = this._platformLocation.hash;\n      return hash && includeHash ? `${pathname}${hash}` : pathname;\n    }\n    pushState(state, title, url, queryParams) {\n      const externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams));\n      this._platformLocation.pushState(state, title, externalUrl);\n    }\n    replaceState(state, title, url, queryParams) {\n      const externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams));\n      this._platformLocation.replaceState(state, title, externalUrl);\n    }\n    forward() {\n      this._platformLocation.forward();\n    }\n    back() {\n      this._platformLocation.back();\n    }\n    getState() {\n      return this._platformLocation.getState();\n    }\n    historyGo(relativePosition = 0) {\n      this._platformLocation.historyGo?.(relativePosition);\n    }\n    static ɵfac = function PathLocationStrategy_Factory(__ngFactoryType__) {\n      return new (__ngFactoryType__ || PathLocationStrategy)(i0.ɵɵinject(PlatformLocation), i0.ɵɵinject(APP_BASE_HREF, 8));\n    };\n    static ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: PathLocationStrategy,\n      factory: PathLocationStrategy.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return PathLocationStrategy;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * @description\n *\n * A service that applications can use to interact with a browser's URL.\n *\n * Depending on the `LocationStrategy` used, `Location` persists\n * to the URL's path or the URL's hash segment.\n *\n * @usageNotes\n *\n * It's better to use the `Router.navigate()` service to trigger route changes. Use\n * `Location` only if you need to interact with or create normalized URLs outside of\n * routing.\n *\n * `Location` is responsible for normalizing the URL against the application's base href.\n * A normalized URL is absolute from the URL host, includes the application's base href, and has no\n * trailing slash:\n * - `/my/app/user/123` is normalized\n * - `my/app/user/123` **is not** normalized\n * - `/my/app/user/123/` **is not** normalized\n *\n * ### Example\n *\n * {@example common/location/ts/path_location_component.ts region='LocationComponent'}\n *\n * @publicApi\n */\nlet Location = /*#__PURE__*/(() => {\n  class Location {\n    /** @internal */\n    _subject = new Subject();\n    /** @internal */\n    _basePath;\n    /** @internal */\n    _locationStrategy;\n    /** @internal */\n    _urlChangeListeners = [];\n    /** @internal */\n    _urlChangeSubscription = null;\n    constructor(locationStrategy) {\n      this._locationStrategy = locationStrategy;\n      const baseHref = this._locationStrategy.getBaseHref();\n      // Note: This class's interaction with base HREF does not fully follow the rules\n      // outlined in the spec https://www.freesoft.org/CIE/RFC/1808/18.htm.\n      // Instead of trying to fix individual bugs with more and more code, we should\n      // investigate using the URL constructor and providing the base as a second\n      // argument.\n      // https://developer.mozilla.org/en-US/docs/Web/API/URL/URL#parameters\n      this._basePath = _stripOrigin(stripTrailingSlash(_stripIndexHtml(baseHref)));\n      this._locationStrategy.onPopState(ev => {\n        this._subject.next({\n          'url': this.path(true),\n          'pop': true,\n          'state': ev.state,\n          'type': ev.type\n        });\n      });\n    }\n    /** @docs-private */\n    ngOnDestroy() {\n      this._urlChangeSubscription?.unsubscribe();\n      this._urlChangeListeners = [];\n    }\n    /**\n     * Normalizes the URL path for this location.\n     *\n     * @param includeHash True to include an anchor fragment in the path.\n     *\n     * @returns The normalized URL path.\n     */\n    // TODO: vsavkin. Remove the boolean flag and always include hash once the deprecated router is\n    // removed.\n    path(includeHash = false) {\n      return this.normalize(this._locationStrategy.path(includeHash));\n    }\n    /**\n     * Reports the current state of the location history.\n     * @returns The current value of the `history.state` object.\n     */\n    getState() {\n      return this._locationStrategy.getState();\n    }\n    /**\n     * Normalizes the given path and compares to the current normalized path.\n     *\n     * @param path The given URL path.\n     * @param query Query parameters.\n     *\n     * @returns True if the given URL path is equal to the current normalized path, false\n     * otherwise.\n     */\n    isCurrentPathEqualTo(path, query = '') {\n      return this.path() == this.normalize(path + normalizeQueryParams(query));\n    }\n    /**\n     * Normalizes a URL path by stripping any trailing slashes.\n     *\n     * @param url String representing a URL.\n     *\n     * @returns The normalized URL string.\n     */\n    normalize(url) {\n      return Location.stripTrailingSlash(_stripBasePath(this._basePath, _stripIndexHtml(url)));\n    }\n    /**\n     * Normalizes an external URL path.\n     * If the given URL doesn't begin with a leading slash (`'/'`), adds one\n     * before normalizing. Adds a hash if `HashLocationStrategy` is\n     * in use, or the `APP_BASE_HREF` if the `PathLocationStrategy` is in use.\n     *\n     * @param url String representing a URL.\n     *\n     * @returns  A normalized platform-specific URL.\n     */\n    prepareExternalUrl(url) {\n      if (url && url[0] !== '/') {\n        url = '/' + url;\n      }\n      return this._locationStrategy.prepareExternalUrl(url);\n    }\n    // TODO: rename this method to pushState\n    /**\n     * Changes the browser's URL to a normalized version of a given URL, and pushes a\n     * new item onto the platform's history.\n     *\n     * @param path  URL path to normalize.\n     * @param query Query parameters.\n     * @param state Location history state.\n     *\n     */\n    go(path, query = '', state = null) {\n      this._locationStrategy.pushState(state, '', path, query);\n      this._notifyUrlChangeListeners(this.prepareExternalUrl(path + normalizeQueryParams(query)), state);\n    }\n    /**\n     * Changes the browser's URL to a normalized version of the given URL, and replaces\n     * the top item on the platform's history stack.\n     *\n     * @param path  URL path to normalize.\n     * @param query Query parameters.\n     * @param state Location history state.\n     */\n    replaceState(path, query = '', state = null) {\n      this._locationStrategy.replaceState(state, '', path, query);\n      this._notifyUrlChangeListeners(this.prepareExternalUrl(path + normalizeQueryParams(query)), state);\n    }\n    /**\n     * Navigates forward in the platform's history.\n     */\n    forward() {\n      this._locationStrategy.forward();\n    }\n    /**\n     * Navigates back in the platform's history.\n     */\n    back() {\n      this._locationStrategy.back();\n    }\n    /**\n     * Navigate to a specific page from session history, identified by its relative position to the\n     * current page.\n     *\n     * @param relativePosition  Position of the target page in the history relative to the current\n     *     page.\n     * A negative value moves backwards, a positive value moves forwards, e.g. `location.historyGo(2)`\n     * moves forward two pages and `location.historyGo(-2)` moves back two pages. When we try to go\n     * beyond what's stored in the history session, we stay in the current page. Same behaviour occurs\n     * when `relativePosition` equals 0.\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/History_API#Moving_to_a_specific_point_in_history\n     */\n    historyGo(relativePosition = 0) {\n      this._locationStrategy.historyGo?.(relativePosition);\n    }\n    /**\n     * Registers a URL change listener. Use to catch updates performed by the Angular\n     * framework that are not detectible through \"popstate\" or \"hashchange\" events.\n     *\n     * @param fn The change handler function, which take a URL and a location history state.\n     * @returns A function that, when executed, unregisters a URL change listener.\n     */\n    onUrlChange(fn) {\n      this._urlChangeListeners.push(fn);\n      this._urlChangeSubscription ??= this.subscribe(v => {\n        this._notifyUrlChangeListeners(v.url, v.state);\n      });\n      return () => {\n        const fnIndex = this._urlChangeListeners.indexOf(fn);\n        this._urlChangeListeners.splice(fnIndex, 1);\n        if (this._urlChangeListeners.length === 0) {\n          this._urlChangeSubscription?.unsubscribe();\n          this._urlChangeSubscription = null;\n        }\n      };\n    }\n    /** @internal */\n    _notifyUrlChangeListeners(url = '', state) {\n      this._urlChangeListeners.forEach(fn => fn(url, state));\n    }\n    /**\n     * Subscribes to the platform's `popState` events.\n     *\n     * Note: `Location.go()` does not trigger the `popState` event in the browser. Use\n     * `Location.onUrlChange()` to subscribe to URL changes instead.\n     *\n     * @param value Event that is triggered when the state history changes.\n     * @param exception The exception to throw.\n     *\n     * @see [onpopstate](https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate)\n     *\n     * @returns Subscribed events.\n     */\n    subscribe(onNext, onThrow, onReturn) {\n      return this._subject.subscribe({\n        next: onNext,\n        error: onThrow ?? undefined,\n        complete: onReturn ?? undefined\n      });\n    }\n    /**\n     * Normalizes URL parameters by prepending with `?` if needed.\n     *\n     * @param  params String of URL parameters.\n     *\n     * @returns The normalized URL parameters string.\n     */\n    static normalizeQueryParams = normalizeQueryParams;\n    /**\n     * Joins two parts of a URL with a slash if needed.\n     *\n     * @param start  URL string\n     * @param end    URL string\n     *\n     *\n     * @returns The joined URL string.\n     */\n    static joinWithSlash = joinWithSlash;\n    /**\n     * Removes a trailing slash from a URL string if needed.\n     * Looks for the first occurrence of either `#`, `?`, or the end of the\n     * line as `/` characters and removes the trailing slash if one exists.\n     *\n     * @param url URL string.\n     *\n     * @returns The URL string, modified if needed.\n     */\n    static stripTrailingSlash = stripTrailingSlash;\n    static ɵfac = function Location_Factory(__ngFactoryType__) {\n      return new (__ngFactoryType__ || Location)(i0.ɵɵinject(LocationStrategy));\n    };\n    static ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: Location,\n      factory: () => createLocation(),\n      providedIn: 'root'\n    });\n  }\n  return Location;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nfunction createLocation() {\n  return new Location(__inject(LocationStrategy));\n}\nfunction _stripBasePath(basePath, url) {\n  if (!basePath || !url.startsWith(basePath)) {\n    return url;\n  }\n  const strippedUrl = url.substring(basePath.length);\n  if (strippedUrl === '' || ['/', ';', '?', '#'].includes(strippedUrl[0])) {\n    return strippedUrl;\n  }\n  return url;\n}\nfunction _stripIndexHtml(url) {\n  return url.replace(/\\/index.html$/, '');\n}\nfunction _stripOrigin(baseHref) {\n  // DO NOT REFACTOR! Previously, this check looked like this:\n  // `/^(https?:)?\\/\\//.test(baseHref)`, but that resulted in\n  // syntactically incorrect code after Closure Compiler minification.\n  // This was likely caused by a bug in Closure Compiler, but\n  // for now, the check is rewritten to use `new RegExp` instead.\n  const isAbsoluteUrl = new RegExp('^(https?:)?//').test(baseHref);\n  if (isAbsoluteUrl) {\n    const [, pathname] = baseHref.split(/\\/\\/[^\\/]+/);\n    return pathname;\n  }\n  return baseHref;\n}\nexport { APP_BASE_HREF, BrowserPlatformLocation, DomAdapter, LOCATION_INITIALIZED, Location, LocationStrategy, PathLocationStrategy, PlatformLocation, getDOM, joinWithSlash, normalizeQueryParams, setRootDomAdapter };\n//# sourceMappingURL=location-Dq4mJT-A.mjs.map","map":null,"metadata":{},"sourceType":"module","externalDependencies":[]}