diff --git a/README.md b/README.md index ecd0704..8954bc2 100644 --- a/README.md +++ b/README.md @@ -88,27 +88,38 @@ When embedded in Express, the MCP endpoint is also available over HTTP at `/__ng MCP clients see these with an underscore, as `ng-devtools_get-routes`. -| Tool | Description | -| ---------------------------------- | ----------------------------------------------------------- | -| `ng-devtools:get-routes` | List Angular routes from source | -| `ng-devtools:get-components` | Discover components and directives, with inputs and outputs | -| `ng-devtools:get-signals` | Signal declarations from source | -| `ng-devtools:get-providers` | DI providers from source | -| `ng-devtools:build-meta` | Angular/TS versions, SSR status | -| `ng-devtools:highlight` | Highlight a component in the page | -| `ng-devtools:inspect-signals` | Signal graph a connected page reported | -| `ng-devtools:inspect-providers` | Injector tree a connected page reported | -| `ng-devtools:get-ngrx-store` | Scan source for NgRx store patterns | -| `ng-devtools:inspect-forms` | Forms on the page with every field's state and errors | -| `ng-devtools:explain-form-invalid` | Which fields make a form invalid, and why | -| `ng-devtools:inspect-route` | The current route with params, data, guards and resolvers | -| `ng-devtools:explain-navigation` | Recent navigations and why each succeeded or not | -| `ng-devtools:list-routes` | Live route config; match a URL; audit guard protection | -| `ng-devtools:lint-routes` | Route config mistakes, with fixes | -| `ng-devtools:router-config` | Router options, features and strategies in effect | -| `ng-devtools:export-navigation` | Markdown repro of a navigation | -| `ng-devtools:explain-render-mode` | ServerRoute and render mode for a URL | -| `ng-devtools:navigate` | Navigate, abort, replay, probe, instrument (dev only) | +| Tool | Description | +| ------------------------------------ | ----------------------------------------------------------- | +| `ng-devtools:get-routes` | List Angular routes from source | +| `ng-devtools:get-components` | Discover components and directives, with inputs and outputs | +| `ng-devtools:get-signals` | Signal declarations from source | +| `ng-devtools:get-providers` | DI providers from source | +| `ng-devtools:build-meta` | Angular/TS versions, SSR status | +| `ng-devtools:highlight` | Highlight a component in the page | +| `ng-devtools:inspect-signals` | Signal graph a connected page reported | +| `ng-devtools:inspect-providers` | Injector tree a connected page reported | +| `ng-devtools:get-ngrx-store` | Scan source for NgRx store patterns | +| `ng-devtools:inspect-forms` | Forms on the page with every field's state and errors | +| `ng-devtools:explain-form-invalid` | Which fields make a form invalid, and why | +| `ng-devtools:explain-field` | One field: error sources, skip reasons, binding, source | +| `ng-devtools:explain-submit` | What submit will do, and why it might do nothing | +| `ng-devtools:form-payload` | What the form sends: value vs raw value, unvalidated fields | +| `ng-devtools:form-history` | Change timeline with origin (user, code, devtools) | +| `ng-devtools:form-diff` | Net change since a marker | +| `ng-devtools:lint-forms` | Form bugs and model-aware accessibility checks | +| `ng-devtools:explain-custom-control` | How a field is bound, and what is wrong with the binding | +| `ng-devtools:export-form` | JSON snapshot or test fixture | +| `ng-devtools:wait-for-form` | Wait until settled, valid, not pending or submitted | +| `ng-devtools:form-action` | Set, touch, revalidate, reset, submit, focus, snapshot | +| `ng-devtools:fill-form` | Fill several fields through the inputs | +| `ng-devtools:inspect-route` | The current route with params, data, guards and resolvers | +| `ng-devtools:explain-navigation` | Recent navigations and why each succeeded or not | +| `ng-devtools:list-routes` | Live route config; match a URL; audit guard protection | +| `ng-devtools:lint-routes` | Route config mistakes, with fixes | +| `ng-devtools:router-config` | Router options, features and strategies in effect | +| `ng-devtools:export-navigation` | Markdown repro of a navigation | +| `ng-devtools:explain-render-mode` | ServerRoute and render mode for a URL | +| `ng-devtools:navigate` | Navigate, abort, replay, probe, instrument (dev only) | #### Forms @@ -118,8 +129,12 @@ The Forms tab and the forms tools read Signal Forms, reactive forms and template - `ng-devtools:explain-form-invalid` is the tool to reach for first: without arguments it lists every form that is invalid or waiting on async validation, with each failing field's current value, the validator that failed, its message and whether it was touched. Pass `form` (an id like `form-1`, or part of a label like `SignupComponent`) to explain one form. - `ng-devtools:inspect-forms` lists the forms with their status and error counts. Pass `form` for a field tree, plus `path` (e.g. `address.city`), `onlyInvalid` or `includeValues: false` to narrow it down. - Both tools note when the page last reported, so an agent can tell when the data is stale. +- Each error says where it comes from: a validator, a template attribute, a cross-field rule (and on which ancestor), async, parse, a server/submission error, or `setErrors()`. `explain-field` adds why validation is skipped (hidden, disabled, readonly), typed-but-uncommitted values (`updateOn`, `debounce`), stale validity after validator changes, the binding, whether the error text is visible, and the file and line of the form and its rules. +- Agents can loop: inspect, act (`form-action`, `fill-form`), `wait-for-form`, then `form-diff` from the marker they had. Writes need a development build; `reset`, `submit` and `restore` need `confirm: true`. +- The Forms tab has Fields (with filters and per-field actions), Timeline, Submit and Lint views. Pick a field on the page to select it, or open a form from its component in the Components tab. +- Timeline recording (a checkbox in the Timeline view, or `form-action` with `instrument`) adds the calling code of each change, validator changes, async validation times and component renders per keystroke. Array items are tracked by identity, so moves show as moves. -Form values leave the page: they are sent to the devtools server, shown in the Forms tab and returned to agents. Values of password fields, fields with a password, one-time-code or credit-card `autocomplete`, and fields whose name looks secret (password, token, card, cvv and similar) are replaced with `[redacted]`. Other values are sent as they are, so keep real credentials out of forms you inspect, and don't expose the dev server beyond localhost. +Form values leave the page: they are sent to the devtools server, shown in the Forms tab and returned to agents. Values of password fields, fields with a password, one-time-code or credit-card `autocomplete`, fields inside `.sentry-mask`, `.rr-mask`, `[data-private]` or `[data-ng-devtools="mask"]`, and fields whose name contains a secret word (password, token, card, cvv, apiKey and similar) are replaced with `[redacted]`, and those values are also removed from error messages. `[data-ng-devtools="unmask"]` opts a field back in; `window.__NG_DEVTOOLS_FORMS__ = { mask: ['iban'], unmask: ['passport'] }` does the same by key. DevTools never writes secret fields. Other values are sent as they are, so keep real credentials out of forms you inspect, and don't expose the dev server beyond localhost. #### Router diff --git a/app/src/app.ts b/app/src/app.ts index 9698ecc..de0c495 100644 --- a/app/src/app.ts +++ b/app/src/app.ts @@ -64,7 +64,7 @@ type Tab = 'dashboard' | 'components' | 'routes' | 'signals' | 'injectors' | 'st } @case ('components') { - + } @case ('routes') { @@ -79,7 +79,11 @@ type Tab = 'dashboard' | 'components' | 'routes' | 'signals' | 'injectors' | 'st } @case ('forms') { - + } } @@ -199,6 +203,13 @@ export class App implements OnInit, OnDestroy { // cleanup handled by devframe client } + formFocus = signal<{ id: string } | null>(null); + + showForm(formId: string) { + this.formFocus.set({ id: formId }); + this.switchTab('forms'); + } + switchTab(id: Tab) { this.tab.set(id); history.replaceState(history.state, '', `#tab=${id}`); diff --git a/app/src/pages/component-tree.ts b/app/src/pages/component-tree.ts index 30a65e3..47eac77 100644 --- a/app/src/pages/component-tree.ts +++ b/app/src/pages/component-tree.ts @@ -1,4 +1,13 @@ -import { Component, DestroyRef, computed, effect, inject, input, signal } from '@angular/core'; +import { + Component, + DestroyRef, + computed, + effect, + inject, + input, + output, + signal, +} from '@angular/core'; import { JsonPipe } from '@angular/common'; import type { DevframeRpcClient } from 'devframe/client'; @@ -68,6 +77,11 @@ interface ProviderEntry {
Standalone
{{ comp.isStandalone ? 'Yes' : 'No' }}
+ @for (form of formsIn(comp.file); track form.formId) { + + } @if (comp.inputs.length) {

Inputs

    @@ -192,6 +206,9 @@ interface ProviderEntry { .io .label { color: #71717a; } + .show-form { + margin: 0 8px 8px 0; + } .inline-detail { padding: 0 16px 12px; border-top: 1px solid #27272a; @@ -291,6 +308,8 @@ interface ProviderEntry { }) export class ComponentTree { rpc = input(null); + readonly showForm = output(); + formOwners = signal<{ formId: string; label: string; file: string | null }[]>([]); components = signal([]); allProviders = signal([]); @@ -367,6 +386,12 @@ export class ComponentTree { my.rpc.call('get-providers') as Promise, ]); this.components.set(comps); + const owners = (await my.rpc.call('forms-owners').catch(() => [])) as { + formId: string; + label: string; + file: string | null; + }[]; + this.formOwners.set(owners ?? []); this.allProviders.set(providers); const sel = this.selected(); if (sel) { @@ -384,6 +409,10 @@ export class ComponentTree { } } + formsIn(file: string) { + return this.formOwners().filter((form) => form.file === file); + } + isSelected(comp: ComponentInfo): boolean { return this.selected()?.selector === comp.selector; } diff --git a/app/src/pages/forms-field-detail.ts b/app/src/pages/forms-field-detail.ts new file mode 100644 index 0000000..f769aae --- /dev/null +++ b/app/src/pages/forms-field-detail.ts @@ -0,0 +1,124 @@ +import { Component, computed, effect, input, linkedSignal, signal, untracked } from '@angular/core'; +import type { DevframeRpcClient } from 'devframe/client'; +import { + FORMS_STYLES, + actionMessage, + formAction, + formsCall, + plain, + type CollectedForm, + type FormFieldNode, +} from './forms-types'; + +@Component({ + selector: 'app-forms-field-detail', + template: ` +

    {{ node().path || '(form)' }}

    +
    {{ text() || 'Loading…' }}
    +
    + @if (node().type === 'control' && !node().redacted) { + + + + } + + + + +
    +

    {{ message() }}

    + `, + styles: ` + ${FORMS_STYLES} + :host { + display: grid; + gap: 8px; + padding: 10px; + border: 1px solid #3f3f46; + border-radius: 8px; + } + h3 { + margin: 0; + color: #e4e4e7; + font-size: 14px; + font-family: ui-monospace, monospace; + } + .row { + display: flex; + flex-wrap: wrap; + gap: 6px; + align-items: center; + } + .sr-only { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + } + `, +}) +export class FormsFieldDetail { + form = input.required(); + node = input.required(); + version = input(0); + rpc = input(null); + + readonly text = signal(''); + private readonly target = computed(() => `${this.form().id}|${this.node().path}`); + readonly draft = linkedSignal({ source: this.target, computation: () => '' }); + readonly message = linkedSignal({ source: this.target, computation: () => '' }); + + constructor() { + effect(() => { + const form = this.form().id; + const path = this.node().path; + this.version(); + const client = this.rpc(); + untracked(() => this.load(client, form, path)); + }); + } + + private async load(client: DevframeRpcClient | null, form: string, path: string) { + const text = await formsCall(client, 'forms-explain', { kind: 'field', form, path }); + if (this.form().id === form && this.node().path === path) this.text.set(plain(text)); + } + + async act(action: string) { + const result = await formAction(this.rpc(), { + action, + formId: this.form().id, + path: this.node().path, + }); + this.message.set( + result.expression ? `${actionMessage(result)} ${result.expression}` : actionMessage(result), + ); + } + + async setValue() { + const raw = this.draft(); + let value: unknown = raw; + try { + value = JSON.parse(raw); + } catch { + value = raw; + } + const result = await formAction(this.rpc(), { + action: 'set-value', + formId: this.form().id, + path: this.node().path, + value, + mode: 'user', + }); + this.message.set(actionMessage(result)); + } +} diff --git a/app/src/pages/forms-inspector.ts b/app/src/pages/forms-inspector.ts index 718806d..5f62e48 100644 --- a/app/src/pages/forms-inspector.ts +++ b/app/src/pages/forms-inspector.ts @@ -1,62 +1,68 @@ -import { Component, DestroyRef, computed, effect, inject, input, signal } from '@angular/core'; +import { + Component, + DestroyRef, + computed, + effect, + inject, + input, + output, + signal, + untracked, +} from '@angular/core'; import { JsonPipe } from '@angular/common'; import type { DevframeRpcClient } from 'devframe/client'; +import { FormsFieldDetail } from './forms-field-detail'; +import { FormsLint, FormsSubmit } from './forms-report'; +import { FormsTimeline } from './forms-timeline'; +import { + FORMS_STYLES, + KIND_LABELS, + SOURCE_LABELS, + actionMessage, + formAction, + type CollectedForm, + type FormEvent, + type FormFieldError, + type FormFieldNode, +} from './forms-types'; -type FieldStatus = 'VALID' | 'INVALID' | 'PENDING' | 'DISABLED'; +type Tab = 'fields' | 'timeline' | 'submit' | 'lint'; +type Chip = 'invalid' | 'dirty' | 'touched' | 'disabled' | 'hidden-error'; -interface FormFieldError { - kind: string; - message: string; -} - -interface FormFieldNode { - key: string; - path: string; - type: 'group' | 'array' | 'control'; - status: FieldStatus; - touched: boolean; - dirty: boolean; - required?: boolean; - readonly?: boolean; - hidden?: boolean; - disabledReasons?: string[]; - updateOn?: 'blur' | 'submit'; - materialized?: false; - bound: boolean; - constraints?: Record; - submitting?: boolean; - debouncing?: boolean; - validators?: { sync: boolean; async: boolean }; - defaultValue?: unknown; - accessor?: string; - value?: unknown; - errors: FormFieldError[]; - children?: FormFieldNode[]; - truncated?: number; -} +const TABS: { id: Tab; label: string }[] = [ + { id: 'fields', label: 'Fields' }, + { id: 'timeline', label: 'Timeline' }, + { id: 'submit', label: 'Submit' }, + { id: 'lint', label: 'Lint' }, +]; -interface CollectedForm { - id: string; - kind: 'signal' | 'reactive' | 'template'; - owner: string; - property?: string; - label: string; - submitted?: boolean; - root: FormFieldNode; -} +const CHIPS: { id: Chip; label: string }[] = [ + { id: 'invalid', label: 'Invalid' }, + { id: 'dirty', label: 'Dirty' }, + { id: 'touched', label: 'Touched' }, + { id: 'disabled', label: 'Disabled' }, + { id: 'hidden-error', label: 'Error not shown' }, +]; -interface FormEvent { - formId: string; - path: string; - type: string; - detail?: string; - timestamp: number; - seq?: number; +function matchesChip(node: FormFieldNode, chip: Chip): boolean { + switch (chip) { + case 'invalid': + return node.errors.length > 0; + case 'dirty': + return node.dirty && node.type === 'control'; + case 'touched': + return node.touched && node.type === 'control'; + case 'disabled': + return node.status === 'DISABLED'; + case 'hidden-error': + return node.dom?.errorShown === false; + } } interface FormsSnapshot { forms?: CollectedForm[]; events?: FormEvent[]; + instrumented?: string[]; } interface FieldRow { @@ -64,12 +70,6 @@ interface FieldRow { depth: number; } -const KIND_LABELS: Record = { - signal: 'Signal Forms', - reactive: 'Reactive', - template: 'Template-driven', -}; - function countErrors(node: FormFieldNode): number { return node.errors.length + (node.children ?? []).reduce((sum, c) => sum + countErrors(c), 0); } @@ -80,7 +80,7 @@ function countFields(node: FormFieldNode): number { @Component({ selector: 'app-forms-inspector', - imports: [JsonPipe], + imports: [JsonPipe, FormsFieldDetail, FormsTimeline, FormsSubmit, FormsLint], template: ` @if (!rpc()) {

    Connecting…

    @@ -142,153 +142,316 @@ function countFields(node: FormFieldNode): number { > - - -
    - - - - - - - - - - - - @for (row of rows(); track row.node.path) { - - - - - - - - @if (row.node.truncated) { - - - - } - } @empty { - - - - } - -
    FieldValueStatusStateErrors
    - - {{ row.node.type }} - - @if (row.node.type === 'control') { - {{ row.node.value | json }} - @if (row.node.defaultValue !== undefined) { -
    - resets to {{ row.node.defaultValue | json }} -
    - } - } -
    - @if (row.node.materialized === false) { - not created yet - } @else { - {{ - row.node.status - }} - } - - @if (row.node.touched) { - touched - } - @if (row.node.dirty) { - dirty - } - @if (row.node.required) { - required - } - @if (row.node.readonly) { - readonly - } - @if (row.node.hidden) { - hidden - } - @if (row.node.updateOn) { - updates on {{ row.node.updateOn }} - } - @if (row.node.debouncing) { - debouncing - } - @if (row.node.validators?.sync) { - validators - } - @if (row.node.validators?.async) { - async validator - } - @for (rule of constraintList(row.node); track rule) { - {{ rule }} - } - @if (row.node.accessor) { - {{ row.node.accessor }} - } - @for (reason of row.node.disabledReasons ?? []; track $index) { - disabled: {{ reason }} - } - - @for (error of row.node.errors; track $index) { -
    - {{ errorText(row.node, error) }} - {{ error.kind }} -
    - } -
    - {{ row.node.truncated }} more fields under - {{ row.node.path || 'the form' }} not shown -
    No field path matches "{{ filter() }}".
    +
    + + + + + + @if (snapshot()) { + + } + +
    +

    {{ message() }}

    -

    Recent changes

    - @if (selectedEvents().length) { -
      - @for (event of selectedEvents(); track event.formId + '#' + event.seq) { -
    1. - - {{ event.path || '(form)' }} - {{ event.type }} - @if (event.detail) { - {{ event.detail }} +
      + @for (tab of tabs; track tab.id) { + + } +
      +
      + @switch (tab_()) { + @case ('fields') { +
      + Show only fields that are + @for (chip of chips; track chip.id) { + } -
    2. + + + +
      + + + + + + + + + + + + @for (row of rows(); track row.node.path) { + + + + + + + + @if (row.node.truncated) { + + + + } + } @empty { + + + + } + +
      FieldValueStatusStateErrors
      + + {{ row.node.type }} + + @if (row.node.type === 'control') { + {{ row.node.value | json }} + @if (row.node.uncommitted !== undefined) { +
      + typed {{ row.node.uncommitted | json }}, not in the model yet +
      + } + @if (row.node.defaultValue !== undefined) { +
      + resets to {{ row.node.defaultValue | json }} +
      + } + } +
      + @if (row.node.materialized === false) { + not created yet + } @else { + {{ + row.node.status + }} + } + + @if (row.node.touched) { + touched + } + @if (row.node.dirty) { + {{ + row.node.changed === false ? 'dirty, unchanged' : 'dirty' + }} + } + @if (row.node.skipped) { + not validated ({{ row.node.skipped }}) + } + @if (row.node.stale?.length) { + stale: {{ row.node.stale!.join(', ') }} + } + @if (row.node.dom?.drift !== undefined) { + view out of sync + } + @if (row.node.redacted) { + redacted ({{ row.node.redacted }}) + } + @if (row.node.required) { + required + } + @if (row.node.readonly) { + readonly + } + @if (row.node.hidden) { + hidden + } + @if (row.node.updateOn) { + updates on {{ row.node.updateOn }} + } + @if (row.node.debouncing) { + debouncing + } + @if (row.node.validators?.sync) { + validators + } + @if (row.node.validators?.async) { + async validator + } + @for (rule of constraintList(row.node); track rule) { + {{ rule }} + } + @if (row.node.accessor) { + {{ row.node.accessor }} + } + @for (reason of row.node.disabledReasons ?? []; track $index) { + disabled: {{ reason }} + } + + @for (error of row.node.errors; track $index) { +
      + {{ errorText(row.node, error) }} + {{ error.kind }} + @if (error.source) { + {{ sourceText(error) }} + } +
      + } + @if (row.node.errors.length && row.node.dom?.errorShown === false) { +
      not shown to the user
      + } +
      + {{ row.node.truncated }} more fields under + {{ row.node.path || 'the form' }} not shown +
      + @if (filter()) { + No field path matches "{{ filter() }}". + } @else { + No field matches the selected filters. + } +
      +
      + + @if (selectedNode(); as node) { + + } + } + @case ('timeline') { + + } + @case ('submit') { + + } + @case ('lint') { + } -
    - } @else { -

    No changes yet. Type into the form to see them here.

    - } + } +
    } } `, styles: ` + ${FORMS_STYLES} + .actions { + display: flex; + flex-wrap: wrap; + gap: 6px; + } + .tabs { + display: flex; + gap: 4px; + border-bottom: 1px solid #27272a; + } + .tabs [role='tab'] { + padding: 6px 12px; + border: none; + border-bottom: 2px solid transparent; + background: none; + color: #d4d4d8; + font: inherit; + font-size: 13px; + cursor: pointer; + } + .tabs [role='tab'][aria-selected='true'] { + border-bottom-color: var(--accent); + color: #fafafa; + } + .tabs [role='tab']:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } + .panel { + display: grid; + gap: 12px; + } + .chips { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin: 0; + padding: 0; + border: 0; + color: #d4d4d8; + font-size: 13px; + } + .field[aria-pressed='true'] { + color: var(--accent); + text-decoration: underline; + } + .flags span.warn { + border-color: #a16207; + color: #fef08a; + } + .source { + margin-left: 6px; + color: #a1a1aa; + font-size: 11px; + } + .unseen { + color: #fde68a !important; + font-size: 11px; + } .layout { display: grid; grid-template-columns: minmax(200px, 260px) minmax(0, 1fr); @@ -463,8 +626,7 @@ function countFields(node: FormFieldNode): number { font-weight: 400; } .value code, - .errors code, - .events code { + .errors code { color: #c4b5fd; overflow-wrap: anywhere; } @@ -485,32 +647,6 @@ function countFields(node: FormFieldNode): number { color: #a1a1aa; font-size: 11px; } - h2 { - margin: 8px 0 0; - color: #d4d4d8; - font-size: 14px; - } - .events { - display: grid; - gap: 4px; - margin: 0; - padding: 0; - list-style: none; - font-size: 13px; - } - .events li { - display: flex; - flex-wrap: wrap; - gap: 8px; - color: #d4d4d8; - } - .events time { - color: #a1a1aa; - font-variant-numeric: tabular-nums; - } - .event-type { - color: #93c5fd; - } .muted { color: #a1a1aa; } @@ -523,13 +659,29 @@ function countFields(node: FormFieldNode): number { }) export class FormsInspector { rpc = input(null); + focus = input<{ id: string } | null>(null); + readonly focusHandled = output(); readonly forms = signal([]); readonly events = signal([]); readonly loading = signal(true); readonly failed = signal(false); readonly selectedId = signal(null); + readonly instrumented = signal([]); + readonly recording = computed(() => { + const id = this.selected()?.id ?? ''; + return this.instrumented().some((page) => id.endsWith(`@${page}`)); + }); readonly filter = signal(''); + readonly tabs = TABS; + readonly chips = CHIPS; + readonly tab_ = signal('fields'); + readonly active = signal(new Set()); + readonly fieldPath = signal(null); + readonly version = signal(0); + readonly message = signal(''); + readonly armed = signal(null); + readonly snapshot = signal(null); private unsubscribe: (() => void) | null = null; private readonly destroyRef = inject(DestroyRef); @@ -553,10 +705,13 @@ export class FormsInspector { const form = this.selected(); if (!form) return []; const query = this.filter().toLowerCase(); + const chips = Array.from(this.active()); const rows: FieldRow[] = []; const visit = (node: FormFieldNode, depth: number): boolean => { const at = rows.length; - let keep = !query || node.path.toLowerCase().includes(query); + let keep = + (!query || node.path.toLowerCase().includes(query)) && + chips.every((chip) => matchesChip(node, chip)); for (const child of node.children ?? []) keep = visit(child, depth + 1) || keep; if (keep) rows.splice(at, 0, { node, depth }); return keep; @@ -565,12 +720,20 @@ export class FormsInspector { return rows; }); + readonly selectedNode = computed(() => { + const path = this.fieldPath(); + const form = this.selected(); + if (path === null || !form) return null; + const find = (node: FormFieldNode): FormFieldNode | null => + node.path === path ? node : ((node.children ?? []).map(find).find(Boolean) ?? null); + return find(form.root); + }); + readonly selectedEvents = computed(() => { const id = this.selected()?.id; return this.events() .filter((e) => e.formId === id) - .slice(-50) - .reverse(); + .slice(-200); }); constructor() { @@ -578,6 +741,14 @@ export class FormsInspector { const client = this.rpc(); if (client) this.load(client); }); + effect(() => { + const focus = this.focus(); + if (!focus) return; + untracked(() => { + this.selectForm(focus.id); + this.focusHandled.emit(); + }); + }); this.destroyRef.onDestroy(() => { this.unsubscribe?.(); this.highlight(null, ''); @@ -594,6 +765,8 @@ export class FormsInspector { const snapshot = value as FormsSnapshot | undefined; this.forms.set(snapshot?.forms ?? []); this.events.set(snapshot?.events ?? []); + this.instrumented.set(snapshot?.instrumented ?? []); + this.version.update((v) => v + 1); }; apply(state.value()); this.unsubscribe?.(); @@ -605,9 +778,86 @@ export class FormsInspector { } } + async pick() { + const form = this.selected(); + if (!form) return; + this.message.set('Click a field in the app (Esc cancels).'); + const result = await formAction(this.rpc(), { action: 'pick', formId: form.id }); + const picked = result as typeof result & { formId?: string; path?: string }; + if (!result.ok || !picked.formId) { + this.message.set(actionMessage(result)); + return; + } + this.selectForm(picked.formId); + this.tab_.set('fields'); + this.fieldPath.set(picked.path ?? ''); + this.message.set(`Picked ${picked.path || '(form)'}.`); + } + + async setRecording(on: boolean) { + const form = this.selected(); + if (!form) return; + const result = await formAction(this.rpc(), { + action: 'instrument', + formId: form.id, + value: on, + }); + this.message.set(actionMessage(result)); + } + selectForm(id: string) { this.selectedId.set(id); this.filter.set(''); + this.fieldPath.set(null); + this.snapshot.set(null); + this.armed.set(null); + } + + toggleChip(chip: Chip) { + this.active.update((set) => { + const next = new Set(set); + if (next.has(chip)) next.delete(chip); + else next.add(chip); + return next; + }); + } + + async act(action: string, extra: Record = {}) { + const form = this.selected(); + if (!form) return; + this.armed.set(null); + const result = await formAction(this.rpc(), { action, formId: form.id, ...extra }); + if (result.snapshot) this.snapshot.set(result.snapshot); + this.message.set(actionMessage(result)); + } + + confirmAct(action: 'reset' | 'submit' | 'restore') { + if (this.armed() !== action) { + this.armed.set(action); + this.message.set(`Press "Confirm ${action}" to ${action} the form in the app.`); + return; + } + void this.act(action, { confirm: true, snapshot: this.snapshot() ?? undefined }); + } + + onKey(event: KeyboardEvent) { + const order = this.tabs.map((tab) => tab.id); + const index = order.indexOf(this.tab_()); + let next = index; + if (event.key === 'ArrowRight') next = (index + 1) % order.length; + else if (event.key === 'ArrowLeft') next = (index - 1 + order.length) % order.length; + else if (event.key === 'Home') next = 0; + else if (event.key === 'End') next = order.length - 1; + else return; + event.preventDefault(); + this.tab_.set(order[next]); + const host = event.currentTarget as HTMLElement; + queueMicrotask(() => host.querySelector(`#forms-tab-${order[next]}`)?.focus()); + } + + sourceText(error: FormFieldError) { + const label = SOURCE_LABELS[error.source ?? ''] ?? error.source ?? ''; + return error.from !== undefined ? `${label} on ${error.from || 'the form'}` : label; } onFilter(event: Event) { @@ -635,8 +885,4 @@ export class FormsInspector { ? `${node.key || 'The form'} ${error.message}` : error.message; } - - time(timestamp: number) { - return new Date(timestamp).toLocaleTimeString(); - } } diff --git a/app/src/pages/forms-report.ts b/app/src/pages/forms-report.ts new file mode 100644 index 0000000..ba3ca64 --- /dev/null +++ b/app/src/pages/forms-report.ts @@ -0,0 +1,146 @@ +import { Component, effect, input, signal, untracked } from '@angular/core'; +import type { DevframeRpcClient } from 'devframe/client'; +import { FORMS_STYLES, formsCall, plain, type FormLintFinding } from './forms-types'; + +@Component({ + selector: 'app-forms-submit', + template: ` +

    Submit

    +
    {{ submit() || 'Loading…' }}
    +

    Payload

    +
    {{ payload() || 'Loading…' }}
    +
    + + {{ message() }} +
    + `, + styles: ` + ${FORMS_STYLES} + :host { + display: grid; + gap: 8px; + } + h3 { + margin: 4px 0 0; + color: #d4d4d8; + font-size: 13px; + } + .status { + margin-left: 8px; + } + `, +}) +export class FormsSubmit { + formId = input.required(); + version = input(0); + rpc = input(null); + + readonly submit = signal(''); + readonly payload = signal(''); + readonly message = signal(''); + + constructor() { + effect(() => { + const form = this.formId(); + this.version(); + const client = this.rpc(); + untracked(async () => { + const [submit, payload] = await Promise.all([ + formsCall(client, 'forms-explain', { kind: 'submit', form }), + formsCall(client, 'forms-explain', { kind: 'payload', form }), + ]); + if (this.formId() !== form) return; + this.submit.set(plain(submit)); + this.payload.set(plain(payload)); + }); + }); + } + + async copyFixture() { + const text = await formsCall(this.rpc(), 'forms-explain', { + kind: 'fixture', + form: this.formId(), + }); + const code = (text ?? '').match(/```ts\n([\s\S]*?)```/)?.[1]; + if (!code) { + this.message.set('No test fixture is available for this form.'); + return; + } + try { + await navigator.clipboard.writeText(code); + this.message.set('Copied.'); + } catch { + this.message.set('Clipboard is not available here.'); + } + } +} + +@Component({ + selector: 'app-forms-lint', + template: ` + @if (findings() === null) { +

    Checking…

    + } @else if (!findings()!.length) { +

    No problems found. For generic accessibility, run axe on the page.

    + } @else { +
      + @for (f of findings(); track $index) { +
    • + {{ f.severity }} + {{ f.rule }} + @if (f.path) { + at {{ f.path }} + } +
      {{ f.message }}
      +
      Fix: {{ f.fix }}
      +
    • + } +
    + } + `, + styles: ` + ${FORMS_STYLES} + .findings { + display: grid; + gap: 8px; + margin: 0; + padding: 0; + list-style: none; + font-size: 13px; + color: #e4e4e7; + } + .findings li { + padding: 8px; + border: 1px solid #27272a; + border-radius: 6px; + } + code { + color: #c4b5fd; + } + `, +}) +export class FormsLint { + formId = input.required(); + version = input(0); + rpc = input(null); + + readonly findings = signal(null); + + constructor() { + effect(() => { + const form = this.formId(); + this.version(); + const client = this.rpc(); + untracked(async () => { + const found = await formsCall(client, 'forms-lint', { form }); + if (this.formId() === form) this.findings.set(found ?? []); + }); + }); + } +} diff --git a/app/src/pages/forms-timeline.ts b/app/src/pages/forms-timeline.ts new file mode 100644 index 0000000..0bbcd55 --- /dev/null +++ b/app/src/pages/forms-timeline.ts @@ -0,0 +1,161 @@ +import { Component, computed, input, output, signal } from '@angular/core'; +import { FORMS_STYLES, type FormEvent } from './forms-types'; + +const ORIGINS = ['all', 'user', 'code', 'devtools'] as const; + +@Component({ + selector: 'app-forms-timeline', + template: ` + +
    + Show changes from + @for (origin of origins; track origin) { + + } +
    + @if (shown().length) { +
      + @for (event of shown(); track event.formId + '#' + event.seq) { +
    1. + + {{ event.path || '(form)' }} + {{ event.type }} + @if (event.outcome) { + {{ + event.outcome + }} + } + + @if (event.prev !== undefined) { + {{ event.prev }} → + } + {{ event.detail }} + + @if (event.count && event.count > 1) { + ×{{ event.count }} + } + @if (event.origin) { + {{ event.origin }} + } + @if (event.ms !== undefined) { + pending {{ event.ms }}ms + } + @if (event.renders) { + {{ event.renders }} renders: {{ (event.rendered ?? []).join(', ') }} + } + @if (event.caller) { + from {{ event.caller }} + } +
    2. + } +
    + } @else { +

    No changes yet. Type into the form to see them here.

    + } + `, + styles: ` + ${FORMS_STYLES} + :host { + display: grid; + gap: 8px; + } + .chips { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin: 0; + padding: 0; + border: 0; + color: #d4d4d8; + font-size: 13px; + } + .sr-only { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + } + .events { + display: grid; + gap: 4px; + margin: 0; + padding: 0; + list-style: none; + font-size: 13px; + } + .events li { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: baseline; + color: #d4d4d8; + } + .events li[data-type='submit'] { + border-left: 3px solid var(--accent); + padding-left: 6px; + } + time { + color: #a1a1aa; + font-variant-numeric: tabular-nums; + } + code { + color: #c4b5fd; + } + .event-type { + color: #93c5fd; + } + .detail { + overflow-wrap: anywhere; + } + .record { + color: #d4d4d8; + font-size: 13px; + } + .caller { + flex-basis: 100%; + padding-left: 16px; + color: #a1a1aa; + font-family: ui-monospace, monospace; + font-size: 12px; + overflow-wrap: anywhere; + } + `, +}) +export class FormsTimeline { + events = input.required(); + recording = input(false); + readonly record = output(); + + readonly origins = ORIGINS; + readonly filter = signal<(typeof ORIGINS)[number]>('all'); + + readonly shown = computed(() => { + const origin = this.filter(); + return this.events() + .filter((e) => origin === 'all' || e.origin === origin) + .slice(-100) + .reverse(); + }); + + time(timestamp: number) { + return new Date(timestamp).toLocaleTimeString(); + } +} diff --git a/app/src/pages/forms-types.ts b/app/src/pages/forms-types.ts new file mode 100644 index 0000000..386354c --- /dev/null +++ b/app/src/pages/forms-types.ts @@ -0,0 +1,212 @@ +import type { DevframeRpcClient } from 'devframe/client'; + +export type FieldStatus = 'VALID' | 'INVALID' | 'PENDING' | 'DISABLED'; + +export interface FormFieldError { + kind: string; + message: string; + source?: string; + from?: string; +} + +export interface FormFieldNode { + key: string; + path: string; + type: 'group' | 'array' | 'control'; + status: FieldStatus; + touched: boolean; + dirty: boolean; + required?: boolean; + readonly?: boolean; + hidden?: boolean; + disabledReasons?: string[]; + updateOn?: 'blur' | 'submit'; + materialized?: false; + bound: boolean; + constraints?: Record; + submitting?: boolean; + debouncing?: boolean; + validators?: { sync: boolean; async: boolean }; + defaultValue?: unknown; + accessor?: string; + value?: unknown; + errors: FormFieldError[]; + children?: FormFieldNode[]; + truncated?: number; + skipped?: string; + stale?: string[]; + uncommitted?: unknown; + changed?: boolean; + redacted?: string; + pendingSince?: number; + dom?: { errorShown?: boolean; drift?: string | true; labelled?: boolean }; +} + +export interface CollectedForm { + id: string; + kind: 'signal' | 'reactive' | 'template'; + owner: string; + property?: string; + label: string; + submitted?: boolean; + submit?: { hasAction: boolean; willRun: boolean; submitting: boolean }; + submitDom?: { reasons: string[] }; + root: FormFieldNode; +} + +export interface FormEvent { + formId: string; + path: string; + type: string; + detail?: string; + timestamp: number; + seq?: number; + origin?: string; + prev?: string; + count?: number; + outcome?: string; + caller?: string; + ms?: number; + renders?: number; + rendered?: string[]; +} + +export interface FormLintFinding { + rule: string; + severity: 'error' | 'warning' | 'info'; + form: string; + label: string; + path?: string; + message: string; + fix: string; +} + +export interface FormActionResult { + ok: boolean; + message?: string; + error?: string; + skipped?: { path: string; reason: string }[]; + status?: string; + snapshot?: string; + expression?: string; +} + +export const KIND_LABELS: Record = { + signal: 'Signal Forms', + reactive: 'Reactive', + template: 'Template-driven', +}; + +export const SOURCE_LABELS: Record = { + own: 'validator', + directive: 'template attribute', + tree: 'cross-field rule', + async: 'async', + parse: 'parse', + submission: 'server', + schema: 'schema', + manual: 'setErrors', +}; + +export function formsCall( + client: DevframeRpcClient | null, + name: string, + arg?: unknown, +): Promise { + if (!client) return Promise.resolve(null); + const rpc = client.scope('ng-devtools').rpc as unknown as { + call: (name: string, ...args: unknown[]) => Promise; + }; + return rpc.call(name, ...(arg === undefined ? [] : [arg])).then( + (value) => value as T, + () => null, + ); +} + +export async function formAction( + client: DevframeRpcClient | null, + request: Record, +): Promise { + const result = await formsCall(client, 'request-form-action', request); + return result ?? { ok: false, error: 'The devtools server did not answer.' }; +} + +export function actionMessage(result: FormActionResult): string { + const text = result.ok ? (result.message ?? 'Done.') : (result.error ?? 'Failed.'); + const skipped = result.skipped?.length + ? ` Skipped: ${result.skipped.map((s) => `${s.path} (${s.reason})`).join(', ')}.` + : ''; + return `${text}${skipped}${result.status ? ` Status: ${result.status}.` : ''}`; +} + +export function plain(text: string | null): string { + return (text ?? '') + .replace(/^_Labels, paths.*_\n\n/, '') + .replace(/`/g, '') + .replace(/\*\*/g, ''); +} + +export const FORMS_STYLES = ` + .muted { + color: #a1a1aa; + } + .small { + padding: 4px 10px; + border: 1px solid #52525b; + border-radius: 6px; + background: #18181b; + color: #e4e4e7; + font-size: 12px; + cursor: pointer; + } + .small:hover { + border-color: var(--accent); + } + .small:focus-visible, + .field-input:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } + .field-input { + padding: 4px 8px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .explain { + margin: 0; + padding: 10px; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 12px; + white-space: pre-wrap; + overflow-wrap: anywhere; + font-family: ui-monospace, monospace; + } + .tag { + display: inline-block; + margin: 0 4px 2px 0; + padding: 0 5px; + border: 1px solid #3f3f46; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + } + .tag[data-tone='warn'] { + border-color: #a16207; + color: #fef08a; + } + .tag[data-tone='bad'] { + border-color: #b91c1c; + color: #fecaca; + } + .status { + min-height: 1.2em; + margin: 0; + color: #d4d4d8; + font-size: 13px; + } +`; diff --git a/extension/ui/assets/browser-agent-rpc-BXhoSh1z-BTrINugR.js b/extension/ui/assets/browser-agent-rpc-BXhoSh1z-D0HBE3Mq.js similarity index 93% rename from extension/ui/assets/browser-agent-rpc-BXhoSh1z-BTrINugR.js rename to extension/ui/assets/browser-agent-rpc-BXhoSh1z-D0HBE3Mq.js index 48e7034..240a292 100644 --- a/extension/ui/assets/browser-agent-rpc-BXhoSh1z-BTrINugR.js +++ b/extension/ui/assets/browser-agent-rpc-BXhoSh1z-D0HBE3Mq.js @@ -1 +1 @@ -import{t as e}from"./index-DVDok6wK.js";var t=Symbol.for(`devframe:browser-agent-registry`),{tools:n,listeners:r}=globalThis[t]??={tools:new Map,listeners:new Set};function i(){return[...n.values()]}function a(e){return r.add(e),()=>r.delete(e)}var o=`devframe:client-id`,s;function c(t=globalThis.window){try{let n=t?.sessionStorage;if(n){let t=n.getItem(o);return t||(t=e(),n.setItem(o,t)),t}}catch{}return s??=e(),s}function l(e){e.client.register({name:`devframe:agent:invoke-client-tool`,type:`action`,jsonSerializable:!0,handler:async(e,t)=>{let n=i().find(t=>t.id===e);if(!n)throw Error(`[devframe/agent] browser tool "${e}" not found`);return await n.invoke(t)}});let t=!1,n=!1,r=0,o=()=>{t||n||(t=!0,queueMicrotask(async()=>{if(t=!1,n)return;let a=i().map(({invoke:e,...t})=>t);(a.length!==0||r!==0)&&(r=a.length,await e.callOptional(`devframe:agent:sync-client-tools`,c(),a).catch(()=>{}))}))},s=a(o),l=e.events.on(`connection:status`,e=>{e===`connected`&&o()});return o(),()=>{n=!0,s(),l()}}export{l as setupBrowserAgentRpcBridge}; \ No newline at end of file +import{t as e}from"./index-BfB0QtSt.js";var t=Symbol.for(`devframe:browser-agent-registry`),{tools:n,listeners:r}=globalThis[t]??={tools:new Map,listeners:new Set};function i(){return[...n.values()]}function a(e){return r.add(e),()=>r.delete(e)}var o=`devframe:client-id`,s;function c(t=globalThis.window){try{let n=t?.sessionStorage;if(n){let t=n.getItem(o);return t||(t=e(),n.setItem(o,t)),t}}catch{}return s??=e(),s}function l(e){e.client.register({name:`devframe:agent:invoke-client-tool`,type:`action`,jsonSerializable:!0,handler:async(e,t)=>{let n=i().find(t=>t.id===e);if(!n)throw Error(`[devframe/agent] browser tool "${e}" not found`);return await n.invoke(t)}});let t=!1,n=!1,r=0,o=()=>{t||n||(t=!0,queueMicrotask(async()=>{if(t=!1,n)return;let a=i().map(({invoke:e,...t})=>t);(a.length!==0||r!==0)&&(r=a.length,await e.callOptional(`devframe:agent:sync-client-tools`,c(),a).catch(()=>{}))}))},s=a(o),l=e.events.on(`connection:status`,e=>{e===`connected`&&o()});return o(),()=>{n=!0,s(),l()}}export{l as setupBrowserAgentRpcBridge}; \ No newline at end of file diff --git a/extension/ui/assets/index-BfB0QtSt.js b/extension/ui/assets/index-BfB0QtSt.js new file mode 100644 index 0000000..dfe9ee4 --- /dev/null +++ b/extension/ui/assets/index-BfB0QtSt.js @@ -0,0 +1,2527 @@ +(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=Object.defineProperty,t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable,i=(t,n,r)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[n]=r,a=(e,a)=>{for(var o in a||={})n.call(a,o)&&i(e,o,a[o]);if(t)for(var o of t(a))r.call(a,o)&&i(e,o,a[o]);return e},o=(e,t,n)=>(i(e,typeof t==`symbol`?t:t+``,n),n),s=globalThis;function c(e){let t=s.__Zone_symbol_prefix;return(typeof t==`string`?t:`__zone_symbol__`)+e}function l(){let e=s.performance;function t(t){e&&e.mark&&e.mark(t)}function n(t,n){e&&e.measure&&e.measure(t,n)}t(`Zone`);let r=class e{constructor(e,t){o(this,`_parent`),o(this,`_name`),o(this,`_properties`),o(this,`_zoneDelegate`),this._parent=e,this._name=t?t.name||`unnamed`:``,this._properties=t&&t.properties||{},this._zoneDelegate=new l(this,this._parent&&this._parent._zoneDelegate,t)}static assertZonePatched(){if(s.Promise!==se.ZoneAwarePromise)throw Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")}static get root(){let t=e.current;for(;t.parent;)t=t.parent;return t}static get current(){return le.zone}static get currentTask(){return ue}static __load_patch(r,i,a=!1){if(Object.hasOwn(se,r)){let e=s[c(`forceDuplicateZoneCheck`)]===!0;if(!a&&e)throw Error(`Already loaded patch: `+r)}else if(!s[`__Zone_disable_`+r]){let a=`Zone:`+r;t(a),se[r]=i(s,e,ce),n(a,a)}}get parent(){return this._parent}get name(){return this._name}get(e){let t=this.getZoneWith(e);if(t)return t._properties[e]}getZoneWith(e){let t=this;for(;t;){if(Object.hasOwn(t._properties,e))return t;t=t._parent}return null}fork(e){if(!e)throw Error(`ZoneSpec required!`);return this._zoneDelegate.fork(this,e)}wrap(e,t){if(typeof e!=`function`)throw Error(`Expecting function got: `+e);let n=this._zoneDelegate.intercept(this,e,t),r=this;return function(){return r.runGuarded(n,this,arguments,t)}}run(e,t,n,r){le={parent:le,zone:this};try{return this._zoneDelegate.invoke(this,e,t,n,r)}finally{le=le.parent}}runGuarded(e,t=null,n,r){le={parent:le,zone:this};try{try{return this._zoneDelegate.invoke(this,e,t,n,r)}catch(e){if(this._zoneDelegate.handleError(this,e))throw e}}finally{le=le.parent}}runTask(e,t,n){if(e.zone!=this)throw Error(`A task can only be run in the zone of creation! (Creation: `+(e.zone||ee).name+`; Execution: `+this.name+`)`);let r=e,{type:i,data:{isPeriodic:a=!1,isRefreshable:o=!1}={}}=e;if(e.state===te&&(i===C||i===oe))return;let s=e.state!=x;s&&r._transitionTo(x,re);let c=ue;ue=r,le={parent:le,zone:this};try{i==oe&&e.data&&!a&&!o&&(e.cancelFn=void 0);try{return this._zoneDelegate.invokeTask(this,r,t,n)}catch(e){if(this._zoneDelegate.handleError(this,e))throw e}}finally{let t=e.state;if(t!==te&&t!==ie){if(i==C||a||o&&t===ne)s&&r._transitionTo(re,x,ne);else{let e=r._zoneDelegates;this._updateTaskCount(r,-1),s&&r._transitionTo(te,x,te),o&&(r._zoneDelegates=e)}}le=le.parent,ue=c}}scheduleTask(e){if(e.zone&&e.zone!==this){let t=this;for(;t;){if(t===e.zone)throw Error(`can not reschedule task to ${this.name} which is descendants of the original zone ${e.zone.name}`);t=t.parent}}e._transitionTo(ne,te);let t=[];e._zoneDelegates=t,e._zone=this;try{e=this._zoneDelegate.scheduleTask(this,e)}catch(t){throw e._transitionTo(ie,ne,te),this._zoneDelegate.handleError(this,t),t}return e._zoneDelegates===t&&this._updateTaskCount(e,1),e.state==ne&&e._transitionTo(re,ne),e}scheduleMicroTask(e,t,n,r){return this.scheduleTask(new u(ae,e,t,n,r,void 0))}scheduleMacroTask(e,t,n,r,i){return this.scheduleTask(new u(oe,e,t,n,r,i))}scheduleEventTask(e,t,n,r,i){return this.scheduleTask(new u(C,e,t,n,r,i))}cancelTask(e){if(e.zone!=this)throw Error(`A task can only be cancelled in the zone of creation! (Creation: `+(e.zone||ee).name+`; Execution: `+this.name+`)`);if(e.state===re||e.state===x){e._transitionTo(S,re,x);try{this._zoneDelegate.cancelTask(this,e)}catch(t){throw e._transitionTo(ie,S),this._zoneDelegate.handleError(this,t),t}return this._updateTaskCount(e,-1),e._transitionTo(te,S),e.runCount=-1,e}}_updateTaskCount(e,t){let n=e._zoneDelegates;t==-1&&(e._zoneDelegates=null);for(let r=0;re.hasTask(n,r),onScheduleTask:(e,t,n,r)=>e.scheduleTask(n,r),onInvokeTask:(e,t,n,r,i,a)=>e.invokeTask(n,r,i,a),onCancelTask:(e,t,n,r)=>e.cancelTask(n,r)};class l{constructor(e,t,n){o(this,`_zone`),o(this,`_taskCounts`,{microTask:0,macroTask:0,eventTask:0}),o(this,`_forkDlgt`),o(this,`_forkZS`),o(this,`_forkCurrZone`),o(this,`_interceptDlgt`),o(this,`_interceptZS`),o(this,`_interceptCurrZone`),o(this,`_invokeDlgt`),o(this,`_invokeZS`),o(this,`_invokeCurrZone`),o(this,`_handleErrorDlgt`),o(this,`_handleErrorZS`),o(this,`_handleErrorCurrZone`),o(this,`_scheduleTaskDlgt`),o(this,`_scheduleTaskZS`),o(this,`_scheduleTaskCurrZone`),o(this,`_invokeTaskDlgt`),o(this,`_invokeTaskZS`),o(this,`_invokeTaskCurrZone`),o(this,`_cancelTaskDlgt`),o(this,`_cancelTaskZS`),o(this,`_cancelTaskCurrZone`),o(this,`_hasTaskDlgt`),o(this,`_hasTaskDlgtOwner`),o(this,`_hasTaskZS`),o(this,`_hasTaskCurrZone`),this._zone=e,this._forkZS=n&&(n&&n.onFork?n:t._forkZS),this._forkDlgt=n&&(n.onFork?t:t._forkDlgt),this._forkCurrZone=n&&(n.onFork?this._zone:t._forkCurrZone),this._interceptZS=n&&(n.onIntercept?n:t._interceptZS),this._interceptDlgt=n&&(n.onIntercept?t:t._interceptDlgt),this._interceptCurrZone=n&&(n.onIntercept?this._zone:t._interceptCurrZone),this._invokeZS=n&&(n.onInvoke?n:t._invokeZS),this._invokeDlgt=n&&(n.onInvoke?t:t._invokeDlgt),this._invokeCurrZone=n&&(n.onInvoke?this._zone:t._invokeCurrZone),this._handleErrorZS=n&&(n.onHandleError?n:t._handleErrorZS),this._handleErrorDlgt=n&&(n.onHandleError?t:t._handleErrorDlgt),this._handleErrorCurrZone=n&&(n.onHandleError?this._zone:t._handleErrorCurrZone),this._scheduleTaskZS=n&&(n.onScheduleTask?n:t._scheduleTaskZS),this._scheduleTaskDlgt=n&&(n.onScheduleTask?t:t._scheduleTaskDlgt),this._scheduleTaskCurrZone=n&&(n.onScheduleTask?this._zone:t._scheduleTaskCurrZone),this._invokeTaskZS=n&&(n.onInvokeTask?n:t._invokeTaskZS),this._invokeTaskDlgt=n&&(n.onInvokeTask?t:t._invokeTaskDlgt),this._invokeTaskCurrZone=n&&(n.onInvokeTask?this._zone:t._invokeTaskCurrZone),this._cancelTaskZS=n&&(n.onCancelTask?n:t._cancelTaskZS),this._cancelTaskDlgt=n&&(n.onCancelTask?t:t._cancelTaskDlgt),this._cancelTaskCurrZone=n&&(n.onCancelTask?this._zone:t._cancelTaskCurrZone),this._hasTaskZS=null,this._hasTaskDlgt=null,this._hasTaskDlgtOwner=null,this._hasTaskCurrZone=null;let r=n&&n.onHasTask,i=t&&t._hasTaskZS;(r||i)&&(this._hasTaskZS=r?n:a,this._hasTaskDlgt=t,this._hasTaskDlgtOwner=this,this._hasTaskCurrZone=this._zone,n.onScheduleTask||(this._scheduleTaskZS=a,this._scheduleTaskDlgt=t,this._scheduleTaskCurrZone=this._zone),n.onInvokeTask||(this._invokeTaskZS=a,this._invokeTaskDlgt=t,this._invokeTaskCurrZone=this._zone),n.onCancelTask||(this._cancelTaskZS=a,this._cancelTaskDlgt=t,this._cancelTaskCurrZone=this._zone))}get zone(){return this._zone}fork(e,t){return this._forkZS?this._forkZS.onFork(this._forkDlgt,this.zone,e,t):new i(e,t)}intercept(e,t,n){return this._interceptZS?this._interceptZS.onIntercept(this._interceptDlgt,this._interceptCurrZone,e,t,n):t}invoke(e,t,n,r,i){return this._invokeZS?this._invokeZS.onInvoke(this._invokeDlgt,this._invokeCurrZone,e,t,n,r,i):t.apply(n,r)}handleError(e,t){return!this._handleErrorZS||this._handleErrorZS.onHandleError(this._handleErrorDlgt,this._handleErrorCurrZone,e,t)}scheduleTask(e,t){let n=t;if(this._scheduleTaskZS)this._hasTaskZS&&n._zoneDelegates.push(this._hasTaskDlgtOwner),n=this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt,this._scheduleTaskCurrZone,e,t),n||=t;else if(t.scheduleFn)t.scheduleFn(t);else if(t.type==ae)y(t);else throw Error(`Task is missing scheduleFn.`);return n}invokeTask(e,t,n,r){return this._invokeTaskZS?this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt,this._invokeTaskCurrZone,e,t,n,r):t.callback.apply(n,r)}cancelTask(e,t){let n;if(this._cancelTaskZS)n=this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt,this._cancelTaskCurrZone,e,t);else{if(!t.cancelFn)throw Error(`Task is not cancelable`);n=t.cancelFn(t)}return n}hasTask(e,t){try{this._hasTaskZS&&this._hasTaskZS.onHasTask(this._hasTaskDlgt,this._hasTaskCurrZone,e,t)}catch(t){this.handleError(e,t)}}_updateTaskCount(e,t){let n=this._taskCounts,r=n[e],i=n[e]=r+t;if(i<0)throw Error(`More tasks executed then were scheduled.`);if(r==0||i==0){let t={microTask:n.microTask>0,macroTask:n.macroTask>0,eventTask:n.eventTask>0,change:e};this.hasTask(this._zone,t)}}}class u{constructor(e,t,n,r,i,a){if(o(this,`type`),o(this,`source`),o(this,`invoke`),o(this,`callback`),o(this,`data`),o(this,`scheduleFn`),o(this,`cancelFn`),o(this,`_zone`,null),o(this,`runCount`,0),o(this,`_zoneDelegates`,null),o(this,`_state`,`notScheduled`),this.type=e,this.source=t,this.data=r,this.scheduleFn=i,this.cancelFn=a,!n)throw Error(`callback is not defined`);this.callback=n;let c=this;this.invoke=e===C&&r&&r.useG?u.invokeTask:function(){return u.invokeTask.call(s,c,this,arguments)}}static invokeTask(e,t,n){e||=this,de++;try{return e.runCount++,e.zone.runTask(e,t,n)}finally{try{de===1&&!s[m]&&b()}finally{de--}}}get zone(){return this._zone}get state(){return this._state}cancelScheduleRequest(){this._transitionTo(te,ne)}_transitionTo(e,t,n){if(this._state===t||this._state===n)this._state=e,e==te&&(this._zoneDelegates=null);else throw Error(`${this.type} '${this.source}': can not transition to '${e}', expecting state '${t}'${n?` or '`+n+`'`:``}, was '${this._state}'.`)}toString(){return this.data&&this.data.handleId!==void 0?this.data.handleId.toString():Object.prototype.toString.call(this)}toJSON(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,runCount:this.runCount}}}let d=c(`setTimeout`),f=c(`Promise`),p=c(`then`),m=c(`enable_native_microtask_draining`),h=[],g=!1,_;function v(e){!_&&s[f]&&(_=s[f].resolve(0)),_?(_[p]??_.then).call(_,e):s[d](e,0)}function y(e){let t=s[m],n=t&&h.length===0&&!g,r=!t&&de===0&&h.length===0;(n||r)&&v(b),e&&h.push(e)}function b(){if(!g){g=!0;try{for(;h.length;){let e=h;h=[];for(let t of e)try{t.zone.runTask(t,null,null)}catch(e){ce.onUnhandledError(e)}}}finally{if(s[m])g=!1,ce.microtaskDrainDone();else try{ce.microtaskDrainDone()}finally{g=!1}}}}let ee={name:`NO ZONE`},te=`notScheduled`,ne=`scheduling`,re=`scheduled`,x=`running`,S=`canceling`,ie=`unknown`,ae=`microTask`,oe=`macroTask`,C=`eventTask`,se=Object.create(null),ce={symbol:c,currentZoneFrame:()=>le,onUnhandledError:fe,microtaskDrainDone:fe,scheduleMicroTask:y,showUncaughtError:()=>!i[c(`ignoreConsoleErrorUncaughtError`)],patchEventTarget:()=>[],patchOnProperties:fe,patchMethod:()=>fe,bindArguments:()=>[],patchThen:()=>fe,patchMacroTask:()=>fe,patchEventPrototype:()=>fe,getGlobalObjects:()=>void 0,ObjectDefineProperty:()=>fe,ObjectGetOwnPropertyDescriptor:()=>void 0,ObjectCreate:()=>void 0,ArraySlice:()=>[],patchClass:()=>fe,wrapWithCurrentZone:()=>fe,filterProperties:()=>[],attachOriginToPatched:()=>fe,_redefineProperty:()=>fe,patchCallbacks:()=>fe,nativeScheduleMicroTask:v},le={parent:null,zone:new i(null,null)},ue=null,de=0;function fe(){}return n(`Zone`,`Zone`),i}function u(){let e=globalThis,t=e[c(`forceDuplicateZoneCheck`)]===!0;if(e.Zone&&(t||typeof e.Zone.__symbol__!=`function`))throw Error(`Zone already loaded.`);return e.Zone??=l(),e.Zone}var d=Object.getOwnPropertyDescriptor,f=Object.defineProperty,p=Object.getPrototypeOf,m=Object.create,h=Array.prototype.slice,g=`addEventListener`,_=`removeEventListener`,v=c(g),y=c(_),b=`true`,ee=`false`,te=c(``);function ne(e,t){return Zone.current.wrap(e,t)}function re(e,t,n,r,i){return Zone.current.scheduleMacroTask(e,t,n,r,i)}var x=c,S=typeof window<`u`,ie=S?window:void 0,ae=S&&ie||globalThis,oe=`removeAttribute`;function C(e,t){for(let n=e.length-1;n>=0;n--)typeof e[n]==`function`&&(e[n]=ne(e[n],t+`_`+n));return e}function se(e,t){let n=e.constructor.name;for(let r=0;r{let t=function(){return e.apply(this,C(arguments,n+`.`+i))};return Se(t,e),t})(a)}}}function ce(e){return e?e.writable===!1?!1:typeof e.get!=`function`||e.set!==void 0:!0}var le=typeof WorkerGlobalScope<`u`&&self instanceof WorkerGlobalScope,ue=!(`nw`in ae)&&ae.process!==void 0&&ae.process.toString()===`[object process]`,de=!ue&&!le&&!!(S&&ie.HTMLElement),fe=ae.process!==void 0&&ae.process.toString()===`[object process]`&&!le&&!!(S&&ie.HTMLElement),pe=Object.create(null),me=x(`enable_beforeunload`),he=function(e){if(e||=ae.event,!e)return;let t=pe[e.type];t||=pe[e.type]=x(`ON_PROPERTY`+e.type);let n=this||e.target||ae,r=n[t],i;if(de&&n===ie&&e.type===`error`){let t=e;i=r&&r.call(this,t.message,t.filename,t.lineno,t.colno,t.error),i===!0&&e.preventDefault()}else i=r&&r.apply(this,arguments),e.type===`beforeunload`&&ae[me]&&typeof i==`string`?e.returnValue=i:i!=null&&!i&&e.preventDefault();return i};function ge(e,t,n){let r=d(e,t);if(!r&&n&&d(n,t)&&(r={enumerable:!0,configurable:!0}),!r||!r.configurable)return;let i=x(`on`+t+`patched`);if(Object.hasOwn(e,i)&&e[i])return;delete r.writable,delete r.value;let a=r.get,o=r.set,s=t.slice(2),c=pe[s];c||=pe[s]=x(`ON_PROPERTY`+s),r.set=function(t){let n=this;!n&&e===ae&&(n=ae),n&&(typeof n[c]==`function`&&n.removeEventListener(s,he),o?.call(n,null),n[c]=t,typeof t==`function`&&n.addEventListener(s,he,!1))},r.get=function(){let n=this;if(!n&&e===ae&&(n=ae),!n)return null;let i=n[c];if(i)return i;if(a){let e=a.call(this);if(e)return r.set.call(this,e),typeof n[oe]==`function`&&n.removeAttribute(t),e}return null},f(e,t,r),e[i]=!0}function _e(e,t,n){if(t)for(let r=0;rfunction(t,r){let a=n(t,r);return a.cbIdx>=0&&typeof r[a.cbIdx]==`function`?re(a.name,r[a.cbIdx],a,i):e.apply(t,r)})}function Se(e,t){e[x(`OriginalDelegate`)]=t}function Ce(e){return typeof e==`function`}function we(e){return typeof e==`number`}var Te={useG:!0},Ee=Object.create(null),De={},Oe=RegExp(`^`+te+`(\\w+)(true|false)$`),ke=x(`propagationStopped`),Ae=[`capture`,`once`,`passive`,`signal`];function je(e,t){let n=(t?t(e):e)+ee,r=(t?t(e):e)+b,i=te+n,a=te+r;Ee[e]={[ee]:i,[b]:a}}function Me(e,t,n,r){let i=r&&r.add||g,o=r&&r.rm||_,s=r&&r.listeners||`eventListeners`,c=r&&r.rmAll||`removeAllListeners`,l=x(i),u=`.`+i+`:`,d=function(e,t,n){if(e.isRemoved)return;let r=e.callback;typeof r==`object`&&r.handleEvent&&(e.callback=e=>r.handleEvent(e),e.originalDelegate=r);let i;try{e.invoke(e,t,[n])}catch(e){i=e}let a=e.options;if(a&&typeof a==`object`&&a.once){let r=e.originalDelegate?e.originalDelegate:e.callback;t[o].call(t,n.type,r,a)}return i};function f(n,r,i){if(r||=e.event,!r)return;let a=n||r.target||e,o=a[Ee[r.type][i?b:ee]];if(o){let e=[];if(o.length===1){let t=d(o[0],a,r);t&&e.push(t)}else{let t=o.slice();for(let n=0;n{throw r})}}}let m=function(e){return f(this,e,!1)},h=function(e){return f(this,e,!0)};function v(t,n){if(!t)return!1;let r=!0;n&&n.useG!==void 0&&(r=n.useG);let d=n&&n.vh,f=!0;n&&n.chkDup!==void 0&&(f=n.chkDup);let g=!1;n&&n.rt!==void 0&&(g=n.rt);let _=t;for(;_&&!Object.hasOwn(_,i);)_=p(_);if(!_&&t[i]&&(_=t),!_||_[l])return!1;let v=n&&n.eventNameToString,y={},ne=_[l]=_[i],re=_[x(o)]=_[o],S=_[x(s)]=_[s],ie=_[x(c)]=_[c],ae;n&&n.prepend&&(ae=_[x(n.prepend)]=_[n.prepend]);function oe(e,t){return t?typeof e==`boolean`?{capture:e,passive:!0}:e?(typeof e==`object`&&e.passive!==!1&&(e.passive=!0),e):{passive:!0}:e}let C=function(e){if(!y.isExisting)return ne.call(y.target,y.eventName,y.capture?h:m,y.options)},se=function(e){if(!e.isRemoved){let t=Ee[e.eventName],n;t&&(n=t[e.capture?b:ee]);let r=n&&e.target[n];if(r){for(let t=0;tde.zone.cancelTask(de);t.call(_,`abort`,e,{once:!0}),de.removeAbortListener=()=>_.removeEventListener(`abort`,e)}if(y.target=null,le&&(le.taskData=null),ne&&(y.options.once=!0),typeof de.options!=`boolean`&&(de.options=g),de.target=l,de.capture=te,de.eventName=u,m&&(de.originalDelegate=p),c?ie.unshift(de):ie.push(de),s)return l}};return _[i]=ve(ne,u,fe,pe,g),ae&&(_.prependListener=ve(ae,`.prependListener:`,le,pe,g,!0)),_[o]=function(){let t=this||e,r=arguments[0];n&&n.transferEventName&&(r=n.transferEventName(r));let i=arguments[2],a=i?typeof i==`boolean`||i.capture:!1,o=arguments[1];if(!o)return re.apply(this,arguments);if(d&&!d(re,o,t,arguments))return;let s=Ee[r],c;s&&(c=s[a?b:ee]);let l=c&&t[c];if(l)for(let e=0;efunction(t,n){t[ke]=!0,e&&e.apply(t,n)})}function Fe(e,t){t.patchMethod(e,`queueMicrotask`,e=>function(e,t){Zone.current.scheduleMicroTask(`queueMicrotask`,t[0])})}var Ie=x(`zoneTask`);function Le(e,t,n,r){let i=null,a=null;t+=r,n+=r;let o={};function s(t){let n=t.data;n.args[0]=function(){return t.invoke.apply(this,arguments)};let r=i.apply(e,n.args);return we(r)?n.handleId=r:(n.handle=r,n.isRefreshable=Ce(r?.refresh)),t}function c(t){let{handle:n,handleId:r}=t.data;return a.call(e,n??r)}i=be(e,t,n=>function(i,a){if(Ce(a[0])){let e={isRefreshable:!1,isPeriodic:r===`Interval`,delay:r===`Timeout`||r===`Interval`?a[1]||0:void 0,args:a},n=a[0];a[0]=function(){try{return n.apply(this,arguments)}finally{let{handle:t,handleId:n,isPeriodic:r,isRefreshable:i}=e;!r&&!i&&(n?delete o[n]:t&&(t[Ie]=null))}};let i=re(t,a[0],e,s,c);if(!i)return i;let{handleId:l,handle:u,isRefreshable:d,isPeriodic:f}=i.data;if(l)o[l]=i;else if(u&&(u[Ie]=i,d&&!f)){let e=u.refresh;u.refresh=function(){let{zone:t,state:n}=i;return n===`notScheduled`?(i._state=`scheduled`,t._updateTaskCount(i,1)):n===`running`&&(i._state=`scheduling`),e.call(this)}}return u??l??i}return n.apply(e,a)}),a=be(e,n,t=>function(n,r){let i=r[0],a;we(i)?(a=o[i],delete o[i]):(a=i?.[Ie],a?i[Ie]=null:a=i),a?.type?a.cancelFn&&a.zone.cancelTask(a):t.apply(e,r)})}function Re(e,t){let{isBrowser:n,isMix:r}=t.getGlobalObjects();(n||r)&&e.customElements&&`customElements`in e&&t.patchCallbacks(t,e.customElements,`customElements`,`define`,[`connectedCallback`,`disconnectedCallback`,`adoptedCallback`,`attributeChangedCallback`,`formAssociatedCallback`,`formDisabledCallback`,`formResetCallback`,`formStateRestoreCallback`])}function ze(e,t){if(Zone[t.symbol(`patchEventTarget`)])return;let{eventNames:n,zoneSymbolEventNames:r,TRUE_STR:i,FALSE_STR:a,ZONE_SYMBOL_PREFIX:o}=t.getGlobalObjects();for(let e=0;et.target===e);if(r.length===0)return t;let i=r[0].ignoreProperties;return t.filter(e=>i.indexOf(e)===-1)}function He(e,t,n,r){e&&_e(e,Ve(e,t,n),r)}function Ue(e){return Object.getOwnPropertyNames(e).filter(e=>e.startsWith(`on`)&&e.length>2).map(e=>e.substring(2))}function We(e,t){if(ue&&!fe||Zone[e.symbol(`patchEvents`)])return;let n=t.__Zone_ignore_on_properties,r=[];if(de){let e=window;r=r.concat([`Document`,`SVGElement`,`Element`,`HTMLElement`,`HTMLBodyElement`,`HTMLMediaElement`,`HTMLFrameSetElement`,`HTMLFrameElement`,`HTMLIFrameElement`,`HTMLMarqueeElement`,`Worker`]),He(e,Ue(e),n,p(e))}r=r.concat([`XMLHttpRequest`,`XMLHttpRequestEventTarget`,`IDBIndex`,`IDBRequest`,`IDBOpenDBRequest`,`IDBDatabase`,`IDBTransaction`,`IDBCursor`,`WebSocket`]);for(let e=0;e{let t=`clear`;Le(e,`set`,t,`Timeout`),Le(e,`set`,t,`Interval`),Le(e,`set`,t,`Immediate`)}),e.__load_patch(`requestAnimationFrame`,e=>{Le(e,`request`,`cancel`,`AnimationFrame`),Le(e,`mozRequest`,`mozCancel`,`AnimationFrame`),Le(e,`webkitRequest`,`webkitCancel`,`AnimationFrame`)}),e.__load_patch(`blocking`,(e,t)=>{let n=[`alert`,`prompt`,`confirm`];for(let r=0;rfunction(r,a){return t.current.run(n,e,a,i)})}}),e.__load_patch(`EventTarget`,(e,t,n)=>{Be(e,n),ze(e,n);let r=e.XMLHttpRequestEventTarget;r&&r.prototype&&n.patchEventTarget(e,n,[r.prototype])}),e.__load_patch(`MutationObserver`,(e,t,n)=>{ye(`MutationObserver`),ye(`WebKitMutationObserver`)}),e.__load_patch(`IntersectionObserver`,(e,t,n)=>{ye(`IntersectionObserver`)}),e.__load_patch(`FileReader`,(e,t,n)=>{ye(`FileReader`)}),e.__load_patch(`on_property`,(e,t,n)=>{We(n,e)}),e.__load_patch(`customElements`,(e,t,n)=>{Re(e,n)}),e.__load_patch(`XHR`,(e,t)=>{c(e);let n=x(`xhrTask`),r=x(`xhrSync`),i=x(`xhrListener`),a=x(`xhrScheduled`),o=x(`xhrURL`),s=x(`xhrErrorBeforeScheduled`);function c(e){let c=e.XMLHttpRequest;if(!c)return;let l=c.prototype;function u(e){return e[n]}let d=l[v],f=l[y];if(!d){let t=e.XMLHttpRequestEventTarget;if(t){let e=t.prototype;d=e[v],f=e[y]}}let p=`readystatechange`,m=`scheduled`;function h(e){let r=e.data,o=r.target;o[a]=!1,o[s]=!1;let c=o[i];d||(d=o[v],f=o[y]),c&&f.call(o,p,c);let l=o[i]=()=>{if(o.readyState===o.DONE){if(!r.aborted&&o[a]&&e.state===m){let n=o[t.__symbol__(`loadfalse`)];if(o.status!==0&&n&&n.length>0){let i=e.invoke;e.invoke=function(){let n=o[t.__symbol__(`loadfalse`)];for(let t=0;tfunction(e,t){return e[r]=t[2]==0,e[o]=t[1],b.apply(e,t)}),ee=x(`fetchTaskAborting`),te=x(`fetchTaskScheduling`),ne=be(l,`send`,()=>function(e,n){if(t.current[te]===!0||e[r])return ne.apply(e,n);{let t={target:e,url:e[o],isPeriodic:!1,args:n,aborted:!1},r=re(`XMLHttpRequest.send`,g,t,h,_);e&&e[s]===!0&&!t.aborted&&r.state===m&&r.invoke()}}),S=be(l,`abort`,()=>function(e,n){let r=u(e);if(r&&typeof r.type==`string`){if(r.cancelFn==null||r.data&&r.data.aborted)return;r.zone.cancelTask(r)}else if(t.current[ee]===!0)return S.apply(e,n)})}}),e.__load_patch(`geolocation`,e=>{e.navigator&&e.navigator.geolocation&&se(e.navigator.geolocation,[`getCurrentPosition`,`watchPosition`])}),e.__load_patch(`PromiseRejectionEvent`,(e,t)=>{function n(t){return function(n){Ne(e,t).forEach(r=>{let i=e.PromiseRejectionEvent;if(i){let e=new i(t,{promise:n.promise,reason:n.rejection});r.invoke(e)}})}}e.PromiseRejectionEvent&&(t[x(`unhandledPromiseRejectionHandler`)]=n(`unhandledrejection`),t[x(`rejectionHandledHandler`)]=n(`rejectionhandled`))}),e.__load_patch(`queueMicrotask`,(e,t,n)=>{Fe(e,n)})}function Ke(e){e.__load_patch(`ZoneAwarePromise`,(e,t,n)=>{let r=Object.getOwnPropertyDescriptor,i=Object.defineProperty;function a(e){return e&&e.toString===Object.prototype.toString?(e.constructor&&e.constructor.name||``)+`: `+JSON.stringify(e):e?e.toString():Object.prototype.toString.call(e)}let o=n.symbol,s=[],c=e[o(`DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION`)]!==!1,l=o(`Promise`),u=o(`then`);n.onUnhandledError=e=>{if(n.showUncaughtError()){let t=e&&e.rejection;t&&e.zone&&e.task?console.error(`Unhandled Promise rejection:`,t instanceof Error?t.message:t,`; Zone:`,e.zone.name,`; Task:`,e.task&&e.task.source,`; Value:`,t,t instanceof Error?t.stack:void 0):console.error(e)}},n.microtaskDrainDone=()=>{for(;s.length;){let e=s.shift();try{e.zone.runGuarded(()=>{throw e.throwOriginal?e.rejection:e})}catch(e){f(e)}}};let d=o(`unhandledPromiseRejectionHandler`);function f(e){n.onUnhandledError(e);try{let n=t[d];typeof n==`function`&&n.call(this,e)}catch{}}function p(e){return e&&typeof e.then==`function`}function m(e){return e}function h(e){return C.reject(e)}let g=o(`state`),_=o(`value`),v=o(`finally`),y=o(`parentPromiseValue`),b=o(`parentPromiseState`);function ee(e,t){return n=>{try{re(e,t,n)}catch(t){re(e,!1,t)}}}let te=function(){let e=!1;return function(t){return function(){e||(e=!0,t.apply(null,arguments))}}},ne=o(`currentTaskTrace`);function re(e,r,o){let l=te();if(e===o)throw TypeError(`Promise resolved with itself`);if(e[g]===null){let u=null;try{(typeof o==`object`||typeof o==`function`)&&(u=o&&o.then)}catch(t){return l(()=>{re(e,!1,t)})(),e}if(r!==!1&&o instanceof C&&Object.hasOwn(o,g)&&Object.hasOwn(o,_)&&o[g]!==null)S(o),re(e,o[g],o[_]);else if(r!==!1&&typeof u==`function`)try{u.call(o,l(ee(e,r)),l(ee(e,!1)))}catch(t){l(()=>{re(e,!1,t)})()}else{e[g]=r;let l=e[_];if(e[_]=o,e[v]===v&&r===!0&&(e[g]=e[b],e[_]=e[y]),r===!1&&o instanceof Error){let e=t.currentTask&&t.currentTask.data&&t.currentTask.data.__creationTrace__;e&&i(o,ne,{configurable:!0,enumerable:!1,writable:!0,value:e})}for(let t=0;t{try{let r=e[_],i=!!n&&v===n[v];i&&(n[y]=r,n[b]=a),re(n,!0,t.run(o,void 0,i&&o!==h&&o!==m?[]:[r]))}catch(e){re(n,!1,e)}},n)}let ae=function(){},oe=e.AggregateError;class C{static toString(){return`function ZoneAwarePromise() { [native code] }`}static resolve(e){return e instanceof C?e:re(new this(null),!0,e)}static reject(e){return re(new this(null),!1,e)}static withResolvers(){let e={};return e.promise=new C((t,n)=>{e.resolve=t,e.reject=n}),e}static any(e){if(!e||typeof e[Symbol.iterator]!=`function`)return Promise.reject(new oe([],`All promises were rejected`));let t=[],n=0;try{for(let r of e)n++,t.push(C.resolve(r))}catch{return Promise.reject(new oe([],`All promises were rejected`))}if(n===0)return Promise.reject(new oe([],`All promises were rejected`));let r=!1,i=[];return new C((e,a)=>{for(let o=0;o{r||(r=!0,e(t))},e=>{i.push(e),n--,n===0&&(r=!0,a(new oe(i,`All promises were rejected`)))})})}static race(e){let t,n,r=new this((e,r)=>{t=e,n=r});function i(e){t(e)}function a(e){n(e)}for(let t of e)p(t)||(t=this.resolve(t)),t.then(i,a);return r}static all(e){return C.allWithCallback(e)}static allSettled(e){return(this&&this.prototype instanceof C?this:C).allWithCallback(e,{thenCallback:e=>({status:`fulfilled`,value:e}),errorCallback:e=>({status:`rejected`,reason:e})})}static allWithCallback(e,t){let n,r,i=new this((e,t)=>{n=e,r=t}),a=2,o=0,s=[];for(let i of e){p(i)||(i=this.resolve(i));let e=o;try{i.then(r=>{s[e]=t?t.thenCallback(r):r,a--,a===0&&n(s)},i=>{t?(s[e]=t.errorCallback(i),a--,a===0&&n(s)):r(i)})}catch(e){r(e)}a++,o++}return a-=2,a===0&&n(s),i}constructor(e){let t=this;if(!(t instanceof C))throw Error(`Must be an instanceof Promise.`);t[g]=null,t[_]=[];try{let n=te();e&&e(n(ee(t,!0)),n(ee(t,!1)))}catch(e){re(t,!1,e)}}get[Symbol.toStringTag](){return`Promise`}get[Symbol.species](){return C}then(e,n){let r=this.constructor?.[Symbol.species];(!r||typeof r!=`function`)&&(r=this.constructor||C);let i=new r(ae),a=t.current;return this[g]==null?this[_].push(a,i,e,n):ie(this,a,i,e,n),i}catch(e){return this.then(null,e)}finally(e){let n=this.constructor?.[Symbol.species];(!n||typeof n!=`function`)&&(n=C);let r=new n(ae);r[v]=v;let i=t.current;return this[g]==null?this[_].push(i,r,e,e):ie(this,i,r,e,e),r}}C.resolve=C.resolve,C.reject=C.reject,C.race=C.race,C.all=C.all;let se=e[l]=e.Promise;e.Promise=C;let ce=o(`thenPatched`);function le(e){let t=e.prototype,n=r(t,`then`);if(n&&(n.writable===!1||!n.configurable))return;let i=t.then;t[u]=i,e.prototype.then=function(e,t){return new C((e,t)=>{i.call(this,e,t)}).then(e,t)},e[ce]=!0}n.patchThen=le;function ue(e){return function(t,n){let r=e.apply(t,n);if(r instanceof C)return r;let i=r.constructor;return i[ce]||le(i),r}}if(se){le(se);let t=se.try;t&&typeof t==`function`&&(C.try=t),be(e,`fetch`,e=>ue(e))}return Promise[t.__symbol__(`uncaughtPromiseErrors`)]=s,C})}function qe(e){e.__load_patch(`toString`,e=>{let t=Function.prototype.toString,n=x(`OriginalDelegate`),r=x(`Promise`),i=x(`Error`),a=function(){if(typeof this==`function`){let a=this[n];if(a)return typeof a==`function`?t.call(a):Object.prototype.toString.call(a);if(this===Promise){let n=e[r];if(n)return t.call(n)}if(this===Error){let n=e[i];if(n)return t.call(n)}}return t.call(this)};a[n]=t,Function.prototype.toString=a;let o=Object.prototype.toString;Object.prototype.toString=function(){return typeof Promise==`function`&&this instanceof Promise?`[object Promise]`:o.call(this)}})}function Je(e,t,n,r,i){let a=Zone.__symbol__(r);if(t[a])return;let o=t[a]=t[r];t[r]=function(a,s,c){return s&&s.prototype&&i.forEach(function(t){let i=`${n}.${r}::`+t,a=s.prototype;try{if(Object.hasOwn(a,t)){let n=e.ObjectGetOwnPropertyDescriptor(a,t);n&&n.value?(n.value=e.wrapWithCurrentZone(n.value,i),e._redefineProperty(s.prototype,t,n)):a[t]&&(a[t]=e.wrapWithCurrentZone(a[t],i))}else a[t]&&(a[t]=e.wrapWithCurrentZone(a[t],i))}catch{}}),o.call(t,a,s,c)},e.attachOriginToPatched(t[r],o)}function Ye(e){e.__load_patch(`util`,(e,t,n)=>{let r=Ue(e);n.patchOnProperties=_e,n.patchMethod=be,n.bindArguments=C,n.patchMacroTask=xe;let i=t.__symbol__(`BLACK_LISTED_EVENTS`),a=t.__symbol__(`UNPATCHED_EVENTS`);e[a]&&(e[i]=e[a]),e[i]&&(t[i]=t[a]=e[i]),n.patchEventPrototype=Pe,n.patchEventTarget=Me,n.ObjectDefineProperty=f,n.ObjectGetOwnPropertyDescriptor=d,n.ObjectCreate=m,n.ArraySlice=h,n.patchClass=ye,n.wrapWithCurrentZone=ne,n.filterProperties=Ve,n.attachOriginToPatched=Se,n._redefineProperty=Object.defineProperty,n.patchCallbacks=Je,n.getGlobalObjects=()=>({globalSources:De,zoneSymbolEventNames:Ee,eventNames:r,isBrowser:de,isMix:fe,isNode:ue,TRUE_STR:b,FALSE_STR:ee,ZONE_SYMBOL_PREFIX:te,ADD_EVENT_LISTENER_STR:g,REMOVE_EVENT_LISTENER_STR:_})})}function Xe(e){Ke(e),qe(e),Ye(e)}var Ze=u();Xe(Ze),Ge(Ze);var Qe=(function(e){return e[e.NONE=0]=`NONE`,e[e.HTML=1]=`HTML`,e[e.STYLE=2]=`STYLE`,e[e.SCRIPT=3]=`SCRIPT`,e[e.URL=4]=`URL`,e[e.RESOURCE_URL=5]=`RESOURCE_URL`,e[e.ATTRIBUTE_NO_BINDING=6]=`ATTRIBUTE_NO_BINDING`,e})(Qe||{}),$e=(function(e){return e[e.None=0]=`None`,e[e.Const=1]=`Const`,e})($e||{}),et=class{modifiers;constructor(e=$e.None){this.modifiers=e}hasModifier(e){return(this.modifiers&e)!==0}},tt=(function(e){return e[e.Dynamic=0]=`Dynamic`,e[e.Bool=1]=`Bool`,e[e.String=2]=`String`,e[e.Int=3]=`Int`,e[e.Number=4]=`Number`,e[e.Function=5]=`Function`,e[e.Inferred=6]=`Inferred`,e[e.None=7]=`None`,e})(tt||{}),nt=class extends et{name;constructor(e,t){super(t),this.name=e}visitType(e,t){return e.visitBuiltinType(this,t)}};tt.Dynamic;var rt=new nt(tt.Inferred);tt.Bool,tt.Int,tt.Number,tt.String,tt.Function,tt.None;var w=(function(e){return e[e.Equals=0]=`Equals`,e[e.NotEquals=1]=`NotEquals`,e[e.Assign=2]=`Assign`,e[e.Identical=3]=`Identical`,e[e.NotIdentical=4]=`NotIdentical`,e[e.Minus=5]=`Minus`,e[e.Plus=6]=`Plus`,e[e.Divide=7]=`Divide`,e[e.Multiply=8]=`Multiply`,e[e.Modulo=9]=`Modulo`,e[e.And=10]=`And`,e[e.Or=11]=`Or`,e[e.BitwiseOr=12]=`BitwiseOr`,e[e.BitwiseAnd=13]=`BitwiseAnd`,e[e.Lower=14]=`Lower`,e[e.LowerEquals=15]=`LowerEquals`,e[e.Bigger=16]=`Bigger`,e[e.BiggerEquals=17]=`BiggerEquals`,e[e.NullishCoalesce=18]=`NullishCoalesce`,e[e.Exponentiation=19]=`Exponentiation`,e[e.In=20]=`In`,e[e.InstanceOf=21]=`InstanceOf`,e[e.AdditionAssignment=22]=`AdditionAssignment`,e[e.SubtractionAssignment=23]=`SubtractionAssignment`,e[e.MultiplicationAssignment=24]=`MultiplicationAssignment`,e[e.DivisionAssignment=25]=`DivisionAssignment`,e[e.RemainderAssignment=26]=`RemainderAssignment`,e[e.ExponentiationAssignment=27]=`ExponentiationAssignment`,e[e.AndAssignment=28]=`AndAssignment`,e[e.OrAssignment=29]=`OrAssignment`,e[e.NullishCoalesceAssignment=30]=`NullishCoalesceAssignment`,e})(w||{});function it(e,t){return e==null||t==null?e==t:e.isEquivalent(t)}function at(e,t,n){let r=e.length;if(r!==t.length)return!1;for(let i=0;ie.isEquivalent(t))}var st=class{leadingComments;type;sourceSpan;constructor(e,t,n){this.leadingComments=n,this.type=e||null,this.sourceSpan=t||null}prop(e,t){return new _t(this,e,null,t)}key(e,t,n){return new vt(this,e,t,n)}callFn(e,t,n,r){return new ut(this,e,null,t,n,r)}instantiate(e,t,n,r){return new dt(this,e,t,n)}conditional(e,t=null,n,r){return new ht(this,e,t,null,n)}equals(e,t){return new gt(w.Equals,this,e,null,t)}notEquals(e,t){return new gt(w.NotEquals,this,e,null,t)}identical(e,t){return new gt(w.Identical,this,e,null,t)}notIdentical(e,t){return new gt(w.NotIdentical,this,e,null,t)}minus(e,t){return new gt(w.Minus,this,e,null,t)}plus(e,t){return new gt(w.Plus,this,e,null,t)}divide(e,t){return new gt(w.Divide,this,e,null,t)}multiply(e,t){return new gt(w.Multiply,this,e,null,t)}modulo(e,t){return new gt(w.Modulo,this,e,null,t)}power(e,t){return new gt(w.Exponentiation,this,e,null,t)}and(e,t){return new gt(w.And,this,e,null,t)}bitwiseOr(e,t){return new gt(w.BitwiseOr,this,e,null,t)}bitwiseAnd(e,t){return new gt(w.BitwiseAnd,this,e,null,t)}or(e,t){return new gt(w.Or,this,e,null,t)}lower(e,t){return new gt(w.Lower,this,e,null,t)}lowerEquals(e,t){return new gt(w.LowerEquals,this,e,null,t)}bigger(e,t){return new gt(w.Bigger,this,e,null,t)}biggerEquals(e,t){return new gt(w.BiggerEquals,this,e,null,t)}isBlank(e){return this.equals(Ct,e)}nullishCoalesce(e,t){return new gt(w.NullishCoalesce,this,e,null,t)}toStmt(e){return new Et(this,null,e)}},ct=class e extends st{name;constructor(e,t,n,r){super(t,n,r),this.name=e}isEquivalent(t){return t instanceof e&&this.name===t.name}isConstant(){return!1}visitExpression(e,t){return e.visitReadVarExpr(this,t)}clone(){return new e(this.name,this.type,this.sourceSpan)}set(e){return new gt(w.Assign,this,e,null,this.sourceSpan)}},lt=class e extends st{expr;constructor(e,t,n,r){super(t,n,r),this.expr=e}visitExpression(e,t){return e.visitTypeofExpr(this,t)}isEquivalent(t){return t instanceof e&&t.expr.isEquivalent(this.expr)}isConstant(){return this.expr.isConstant()}clone(){return new e(this.expr.clone())}},ut=class e extends st{fn;args;pure;isOptional;constructor(e,t,n,r,i=!1,a,o=!1){super(n,r,a),this.fn=e,this.args=t,this.pure=i,this.isOptional=o}get receiver(){return this.fn}isEquivalent(t){return t instanceof e&&this.fn.isEquivalent(t.fn)&&ot(this.args,t.args)&&this.pure===t.pure}isConstant(){return!1}visitExpression(e,t){return e.visitInvokeFunctionExpr(this,t)}clone(){return new e(this.fn.clone(),this.args.map(e=>e.clone()),this.type,this.sourceSpan,this.pure,[],this.isOptional)}},dt=class e extends st{classExpr;args;constructor(e,t,n,r,i){super(n,r,i),this.classExpr=e,this.args=t}isEquivalent(t){return t instanceof e&&this.classExpr.isEquivalent(t.classExpr)&&ot(this.args,t.args)}isConstant(){return!1}visitExpression(e,t){return e.visitInstantiateExpr(this,t)}clone(){return new e(this.classExpr.clone(),this.args.map(e=>e.clone()),this.type,this.sourceSpan)}},ft=class e extends st{body;flags;constructor(e,t,n,r){super(null,n,r),this.body=e,this.flags=t}isEquivalent(t){return t instanceof e&&this.body===t.body&&this.flags===t.flags}isConstant(){return!0}visitExpression(e,t){return e.visitRegularExpressionLiteral(this,t)}clone(){return new e(this.body,this.flags,this.sourceSpan)}},pt=class e extends st{value;constructor(e,t,n,r){super(t,n,r),this.value=e}isEquivalent(t){return t instanceof e&&this.value===t.value}isConstant(){return!0}visitExpression(e,t){return e.visitLiteralExpr(this,t)}clone(){return new e(this.value,this.type,this.sourceSpan)}},mt=class e extends st{value;typeParams;constructor(e,t,n=null,r,i){super(t,r,i),this.value=e,this.typeParams=n}isEquivalent(t){return t instanceof e&&this.value.name===t.value.name&&this.value.moduleName===t.value.moduleName}isConstant(){return!1}visitExpression(e,t){return e.visitExternalExpr(this,t)}clone(){return new e(this.value,this.type,this.typeParams,this.sourceSpan)}},ht=class e extends st{condition;falseCase;trueCase;constructor(e,t,n=null,r,i,a){super(r||t.type,i,a),this.condition=e,this.falseCase=n,this.trueCase=t}isEquivalent(t){return t instanceof e&&this.condition.isEquivalent(t.condition)&&this.trueCase.isEquivalent(t.trueCase)&&it(this.falseCase,t.falseCase)}isConstant(){return!1}visitExpression(e,t){return e.visitConditionalExpr(this,t)}clone(){return new e(this.condition.clone(),this.trueCase.clone(),this.falseCase?.clone(),this.type,this.sourceSpan)}},gt=class e extends st{operator;rhs;lhs;constructor(e,t,n,r,i,a){super(r||t.type,i,a),this.operator=e,this.rhs=n,this.lhs=t}isEquivalent(t){return t instanceof e&&this.operator===t.operator&&this.lhs.isEquivalent(t.lhs)&&this.rhs.isEquivalent(t.rhs)}isConstant(){return!1}visitExpression(e,t){return e.visitBinaryOperatorExpr(this,t)}clone(){return new e(this.operator,this.lhs.clone(),this.rhs.clone(),this.type,this.sourceSpan)}isAssignment(){let e=this.operator;return e===w.Assign||e===w.AdditionAssignment||e===w.SubtractionAssignment||e===w.MultiplicationAssignment||e===w.DivisionAssignment||e===w.RemainderAssignment||e===w.ExponentiationAssignment||e===w.AndAssignment||e===w.OrAssignment||e===w.NullishCoalesceAssignment}},_t=class e extends st{receiver;name;isOptional;constructor(e,t,n,r,i,a=!1){super(n,r,i),this.receiver=e,this.name=t,this.isOptional=a}get index(){return this.name}isEquivalent(t){return t instanceof e&&this.receiver.isEquivalent(t.receiver)&&this.name===t.name&&this.isOptional===t.isOptional}isConstant(){return!1}visitExpression(e,t){return e.visitReadPropExpr(this,t)}set(e){return new gt(w.Assign,this.receiver.prop(this.name),e,null,this.sourceSpan)}clone(){return new e(this.receiver.clone(),this.name,this.type,this.sourceSpan,[],this.isOptional)}},vt=class e extends st{receiver;index;isOptional;constructor(e,t,n,r,i,a=!1){super(n,r,i),this.receiver=e,this.index=t,this.isOptional=a}isEquivalent(t){return t instanceof e&&this.receiver.isEquivalent(t.receiver)&&this.index.isEquivalent(t.index)&&this.isOptional===t.isOptional}isConstant(){return!1}visitExpression(e,t){return e.visitReadKeyExpr(this,t)}set(e){return new gt(w.Assign,this.receiver.key(this.index),e,null,this.sourceSpan)}clone(){return new e(this.receiver.clone(),this.index.clone(),this.type,this.sourceSpan,[],this.isOptional)}},yt=class e extends st{entries;constructor(e,t,n,r){super(t,n,r),this.entries=e}isConstant(){return this.entries.every(e=>e.isConstant())}isEquivalent(t){return t instanceof e&&ot(this.entries,t.entries)}visitExpression(e,t){return e.visitLiteralArrayExpr(this,t)}clone(){return new e(this.entries.map(e=>e.clone()),this.type,this.sourceSpan)}},bt=class e{expression;constructor(e){this.expression=e}isEquivalent(t){return t instanceof e&&this.expression.isEquivalent(t.expression)}clone(){return new e(this.expression.clone())}isConstant(){return this.expression.isConstant()}},xt=class e extends st{entries;valueType=null;constructor(e,t,n,r){super(t,n,r),this.entries=e,t&&(this.valueType=t.valueType)}isEquivalent(t){return t instanceof e&&ot(this.entries,t.entries)}isConstant(){return this.entries.every(e=>e.isConstant())}visitExpression(e,t){return e.visitLiteralMapExpr(this,t)}clone(){let t=this.entries.map(e=>e.clone());return new e(t,this.type,this.sourceSpan)}},St=class e extends st{expression;constructor(e,t,n){super(null,t,n),this.expression=e}isEquivalent(t){return t instanceof e&&this.expression.isEquivalent(t.expression)}isConstant(){return this.expression.isConstant()}visitExpression(e,t){return e.visitSpreadElementExpr(this,t)}clone(){return new e(this.expression.clone(),this.sourceSpan)}},Ct=new pt(null,rt,null),wt=(function(e){return e[e.None=0]=`None`,e[e.Final=1]=`Final`,e[e.Private=2]=`Private`,e[e.Exported=4]=`Exported`,e[e.Static=8]=`Static`,e})(wt||{}),Tt=class{modifiers;sourceSpan;leadingComments;constructor(e=wt.None,t=null,n){this.modifiers=e,this.sourceSpan=t,this.leadingComments=n}hasModifier(e){return(this.modifiers&e)!==0}addLeadingComment(e){this.leadingComments=this.leadingComments??[],this.leadingComments.push(e)}},Et=class e extends Tt{expr;constructor(e,t,n){super(wt.None,t,n),this.expr=e}isEquivalent(t){return t instanceof e&&this.expr.isEquivalent(t.expr)}visitStatement(e,t){return e.visitExpressionStmt(this,t)}};(class e{static INSTANCE=new e;keyOf(e){if(e instanceof pt&&typeof e.value==`string`)return`"${e.value}"`;if(e instanceof pt)return String(e.value);if(e instanceof ft)return`/${e.body}/${e.flags??``}`;if(e instanceof yt){let t=[];for(let n of e.entries)t.push(this.keyOf(n));return`[${t.join(`,`)}]`}if(e instanceof xt){let t=[];for(let n of e.entries)if(n instanceof bt)t.push(`...`+this.keyOf(n.expression));else{let e=n.key;n.quoted&&(e=`"${e}"`),t.push(e+`:`+this.keyOf(n.value))}return`{${t.join(`,`)}}`}if(e instanceof mt)return`import("${e.value.moduleName}", ${e.value.name})`;if(e instanceof ct)return`read(${e.name})`;if(e instanceof lt)return`typeof(${this.keyOf(e.expr)})`;if(e instanceof St)return`...${this.keyOf(e.expression)}`;throw Error(`${this.constructor.name} does not handle expressions of type ${e.constructor.name}`)}});var T=`@angular/core`,E=(()=>{class e{static core={name:null,moduleName:T};static namespaceHTML={name:`ɵɵnamespaceHTML`,moduleName:T};static namespaceMathML={name:`ɵɵnamespaceMathML`,moduleName:T};static namespaceSVG={name:`ɵɵnamespaceSVG`,moduleName:T};static element={name:`ɵɵelement`,moduleName:T};static elementStart={name:`ɵɵelementStart`,moduleName:T};static elementEnd={name:`ɵɵelementEnd`,moduleName:T};static foreignComponent={name:`ɵɵforeignComponent`,moduleName:T};static foreignContent={name:`ɵɵforeignContent`,moduleName:T};static foreignContentFn={name:`ɵɵforeignContentFn`,moduleName:T};static domElement={name:`ɵɵdomElement`,moduleName:T};static domElementStart={name:`ɵɵdomElementStart`,moduleName:T};static domElementEnd={name:`ɵɵdomElementEnd`,moduleName:T};static domElementContainer={name:`ɵɵdomElementContainer`,moduleName:T};static domElementContainerStart={name:`ɵɵdomElementContainerStart`,moduleName:T};static domElementContainerEnd={name:`ɵɵdomElementContainerEnd`,moduleName:T};static domTemplate={name:`ɵɵdomTemplate`,moduleName:T};static domListener={name:`ɵɵdomListener`,moduleName:T};static advance={name:`ɵɵadvance`,moduleName:T};static syntheticHostProperty={name:`ɵɵsyntheticHostProperty`,moduleName:T};static syntheticHostListener={name:`ɵɵsyntheticHostListener`,moduleName:T};static attribute={name:`ɵɵattribute`,moduleName:T};static classProp={name:`ɵɵclassProp`,moduleName:T};static elementContainerStart={name:`ɵɵelementContainerStart`,moduleName:T};static elementContainerEnd={name:`ɵɵelementContainerEnd`,moduleName:T};static elementContainer={name:`ɵɵelementContainer`,moduleName:T};static styleMap={name:`ɵɵstyleMap`,moduleName:T};static classMap={name:`ɵɵclassMap`,moduleName:T};static styleProp={name:`ɵɵstyleProp`,moduleName:T};static interpolate={name:`ɵɵinterpolate`,moduleName:T};static interpolate1={name:`ɵɵinterpolate1`,moduleName:T};static interpolate2={name:`ɵɵinterpolate2`,moduleName:T};static interpolate3={name:`ɵɵinterpolate3`,moduleName:T};static interpolate4={name:`ɵɵinterpolate4`,moduleName:T};static interpolate5={name:`ɵɵinterpolate5`,moduleName:T};static interpolate6={name:`ɵɵinterpolate6`,moduleName:T};static interpolate7={name:`ɵɵinterpolate7`,moduleName:T};static interpolate8={name:`ɵɵinterpolate8`,moduleName:T};static interpolateV={name:`ɵɵinterpolateV`,moduleName:T};static nextContext={name:`ɵɵnextContext`,moduleName:T};static resetView={name:`ɵɵresetView`,moduleName:T};static templateCreate={name:`ɵɵtemplate`,moduleName:T};static defer={name:`ɵɵdefer`,moduleName:T};static deferWhen={name:`ɵɵdeferWhen`,moduleName:T};static deferOnIdle={name:`ɵɵdeferOnIdle`,moduleName:T};static deferOnImmediate={name:`ɵɵdeferOnImmediate`,moduleName:T};static deferOnTimer={name:`ɵɵdeferOnTimer`,moduleName:T};static deferOnHover={name:`ɵɵdeferOnHover`,moduleName:T};static deferOnInteraction={name:`ɵɵdeferOnInteraction`,moduleName:T};static deferOnViewport={name:`ɵɵdeferOnViewport`,moduleName:T};static deferPrefetchWhen={name:`ɵɵdeferPrefetchWhen`,moduleName:T};static deferPrefetchOnIdle={name:`ɵɵdeferPrefetchOnIdle`,moduleName:T};static deferPrefetchOnImmediate={name:`ɵɵdeferPrefetchOnImmediate`,moduleName:T};static deferPrefetchOnTimer={name:`ɵɵdeferPrefetchOnTimer`,moduleName:T};static deferPrefetchOnHover={name:`ɵɵdeferPrefetchOnHover`,moduleName:T};static deferPrefetchOnInteraction={name:`ɵɵdeferPrefetchOnInteraction`,moduleName:T};static deferPrefetchOnViewport={name:`ɵɵdeferPrefetchOnViewport`,moduleName:T};static deferHydrateWhen={name:`ɵɵdeferHydrateWhen`,moduleName:T};static deferHydrateNever={name:`ɵɵdeferHydrateNever`,moduleName:T};static deferHydrateOnIdle={name:`ɵɵdeferHydrateOnIdle`,moduleName:T};static deferHydrateOnImmediate={name:`ɵɵdeferHydrateOnImmediate`,moduleName:T};static deferHydrateOnTimer={name:`ɵɵdeferHydrateOnTimer`,moduleName:T};static deferHydrateOnHover={name:`ɵɵdeferHydrateOnHover`,moduleName:T};static deferHydrateOnInteraction={name:`ɵɵdeferHydrateOnInteraction`,moduleName:T};static deferHydrateOnViewport={name:`ɵɵdeferHydrateOnViewport`,moduleName:T};static deferEnableTimerScheduling={name:`ɵɵdeferEnableTimerScheduling`,moduleName:T};static enableIncrementalHydrationRuntime={name:`ɵɵenableIncrementalHydrationRuntime`,moduleName:T};static conditionalCreate={name:`ɵɵconditionalCreate`,moduleName:T};static conditionalBranchCreate={name:`ɵɵconditionalBranchCreate`,moduleName:T};static conditional={name:`ɵɵconditional`,moduleName:T};static repeater={name:`ɵɵrepeater`,moduleName:T};static repeaterCreate={name:`ɵɵrepeaterCreate`,moduleName:T};static repeaterTrackByIndex={name:`ɵɵrepeaterTrackByIndex`,moduleName:T};static repeaterTrackByIdentity={name:`ɵɵrepeaterTrackByIdentity`,moduleName:T};static componentInstance={name:`ɵɵcomponentInstance`,moduleName:T};static text={name:`ɵɵtext`,moduleName:T};static enableBindings={name:`ɵɵenableBindings`,moduleName:T};static disableBindings={name:`ɵɵdisableBindings`,moduleName:T};static getCurrentView={name:`ɵɵgetCurrentView`,moduleName:T};static textInterpolate={name:`ɵɵtextInterpolate`,moduleName:T};static textInterpolate1={name:`ɵɵtextInterpolate1`,moduleName:T};static textInterpolate2={name:`ɵɵtextInterpolate2`,moduleName:T};static textInterpolate3={name:`ɵɵtextInterpolate3`,moduleName:T};static textInterpolate4={name:`ɵɵtextInterpolate4`,moduleName:T};static textInterpolate5={name:`ɵɵtextInterpolate5`,moduleName:T};static textInterpolate6={name:`ɵɵtextInterpolate6`,moduleName:T};static textInterpolate7={name:`ɵɵtextInterpolate7`,moduleName:T};static textInterpolate8={name:`ɵɵtextInterpolate8`,moduleName:T};static textInterpolateV={name:`ɵɵtextInterpolateV`,moduleName:T};static restoreView={name:`ɵɵrestoreView`,moduleName:T};static pureFunction0={name:`ɵɵpureFunction0`,moduleName:T};static pureFunction1={name:`ɵɵpureFunction1`,moduleName:T};static pureFunction2={name:`ɵɵpureFunction2`,moduleName:T};static pureFunction3={name:`ɵɵpureFunction3`,moduleName:T};static pureFunction4={name:`ɵɵpureFunction4`,moduleName:T};static pureFunction5={name:`ɵɵpureFunction5`,moduleName:T};static pureFunction6={name:`ɵɵpureFunction6`,moduleName:T};static pureFunction7={name:`ɵɵpureFunction7`,moduleName:T};static pureFunction8={name:`ɵɵpureFunction8`,moduleName:T};static pureFunctionV={name:`ɵɵpureFunctionV`,moduleName:T};static pipeBind1={name:`ɵɵpipeBind1`,moduleName:T};static pipeBind2={name:`ɵɵpipeBind2`,moduleName:T};static pipeBind3={name:`ɵɵpipeBind3`,moduleName:T};static pipeBind4={name:`ɵɵpipeBind4`,moduleName:T};static pipeBindV={name:`ɵɵpipeBindV`,moduleName:T};static domProperty={name:`ɵɵdomProperty`,moduleName:T};static ariaProperty={name:`ɵɵariaProperty`,moduleName:T};static property={name:`ɵɵproperty`,moduleName:T};static control={name:`ɵɵcontrol`,moduleName:T};static controlCreate={name:`ɵɵcontrolCreate`,moduleName:T};static animationEnterListener={name:`ɵɵanimateEnterListener`,moduleName:T};static animationLeaveListener={name:`ɵɵanimateLeaveListener`,moduleName:T};static animationEnter={name:`ɵɵanimateEnter`,moduleName:T};static animationLeave={name:`ɵɵanimateLeave`,moduleName:T};static i18n={name:`ɵɵi18n`,moduleName:T};static i18nAttributes={name:`ɵɵi18nAttributes`,moduleName:T};static i18nExp={name:`ɵɵi18nExp`,moduleName:T};static i18nStart={name:`ɵɵi18nStart`,moduleName:T};static i18nEnd={name:`ɵɵi18nEnd`,moduleName:T};static i18nApply={name:`ɵɵi18nApply`,moduleName:T};static i18nPostprocess={name:`ɵɵi18nPostprocess`,moduleName:T};static pipe={name:`ɵɵpipe`,moduleName:T};static projection={name:`ɵɵprojection`,moduleName:T};static projectionDef={name:`ɵɵprojectionDef`,moduleName:T};static reference={name:`ɵɵreference`,moduleName:T};static inject={name:`ɵɵinject`,moduleName:T};static injectAttribute={name:`ɵɵinjectAttribute`,moduleName:T};static directiveInject={name:`ɵɵdirectiveInject`,moduleName:T};static invalidFactory={name:`ɵɵinvalidFactory`,moduleName:T};static invalidFactoryDep={name:`ɵɵinvalidFactoryDep`,moduleName:T};static templateRefExtractor={name:`ɵɵtemplateRefExtractor`,moduleName:T};static forwardRef={name:`forwardRef`,moduleName:T};static resolveForwardRef={name:`resolveForwardRef`,moduleName:T};static replaceMetadata={name:`ɵɵreplaceMetadata`,moduleName:T};static getReplaceMetadataURL={name:`ɵɵgetReplaceMetadataURL`,moduleName:T};static ɵɵdefineInjectable={name:`ɵɵdefineInjectable`,moduleName:T};static declareInjectable={name:`ɵɵngDeclareInjectable`,moduleName:T};static InjectableDeclaration={name:`ɵɵInjectableDeclaration`,moduleName:T};static defineService={name:`ɵɵdefineService`,moduleName:T};static declareService={name:`ɵɵngDeclareService`,moduleName:T};static resolveWindow={name:`ɵɵresolveWindow`,moduleName:T};static resolveDocument={name:`ɵɵresolveDocument`,moduleName:T};static resolveBody={name:`ɵɵresolveBody`,moduleName:T};static getComponentDepsFactory={name:`ɵɵgetComponentDepsFactory`,moduleName:T};static defineComponent={name:`ɵɵdefineComponent`,moduleName:T};static declareComponent={name:`ɵɵngDeclareComponent`,moduleName:T};static setComponentScope={name:`ɵɵsetComponentScope`,moduleName:T};static ChangeDetectionStrategy={name:`ChangeDetectionStrategy`,moduleName:T};static ViewEncapsulation={name:`ViewEncapsulation`,moduleName:T};static ComponentDeclaration={name:`ɵɵComponentDeclaration`,moduleName:T};static FactoryDeclaration={name:`ɵɵFactoryDeclaration`,moduleName:T};static declareFactory={name:`ɵɵngDeclareFactory`,moduleName:T};static FactoryTarget={name:`ɵɵFactoryTarget`,moduleName:T};static defineDirective={name:`ɵɵdefineDirective`,moduleName:T};static declareDirective={name:`ɵɵngDeclareDirective`,moduleName:T};static DirectiveDeclaration={name:`ɵɵDirectiveDeclaration`,moduleName:T};static InjectorDef={name:`ɵɵInjectorDef`,moduleName:T};static InjectorDeclaration={name:`ɵɵInjectorDeclaration`,moduleName:T};static defineInjector={name:`ɵɵdefineInjector`,moduleName:T};static declareInjector={name:`ɵɵngDeclareInjector`,moduleName:T};static NgModuleDeclaration={name:`ɵɵNgModuleDeclaration`,moduleName:T};static ModuleWithProviders={name:`ModuleWithProviders`,moduleName:T};static defineNgModule={name:`ɵɵdefineNgModule`,moduleName:T};static declareNgModule={name:`ɵɵngDeclareNgModule`,moduleName:T};static setNgModuleScope={name:`ɵɵsetNgModuleScope`,moduleName:T};static registerNgModuleType={name:`ɵɵregisterNgModuleType`,moduleName:T};static PipeDeclaration={name:`ɵɵPipeDeclaration`,moduleName:T};static definePipe={name:`ɵɵdefinePipe`,moduleName:T};static declarePipe={name:`ɵɵngDeclarePipe`,moduleName:T};static declareClassMetadata={name:`ɵɵngDeclareClassMetadata`,moduleName:T};static declareClassMetadataAsync={name:`ɵɵngDeclareClassMetadataAsync`,moduleName:T};static setClassMetadata={name:`ɵsetClassMetadata`,moduleName:T};static setClassMetadataAsync={name:`ɵsetClassMetadataAsync`,moduleName:T};static setClassDebugInfo={name:`ɵsetClassDebugInfo`,moduleName:T};static queryRefresh={name:`ɵɵqueryRefresh`,moduleName:T};static viewQuery={name:`ɵɵviewQuery`,moduleName:T};static loadQuery={name:`ɵɵloadQuery`,moduleName:T};static contentQuery={name:`ɵɵcontentQuery`,moduleName:T};static viewQuerySignal={name:`ɵɵviewQuerySignal`,moduleName:T};static contentQuerySignal={name:`ɵɵcontentQuerySignal`,moduleName:T};static queryAdvance={name:`ɵɵqueryAdvance`,moduleName:T};static twoWayProperty={name:`ɵɵtwoWayProperty`,moduleName:T};static twoWayBindingSet={name:`ɵɵtwoWayBindingSet`,moduleName:T};static twoWayListener={name:`ɵɵtwoWayListener`,moduleName:T};static declareLet={name:`ɵɵdeclareLet`,moduleName:T};static storeLet={name:`ɵɵstoreLet`,moduleName:T};static readContextLet={name:`ɵɵreadContextLet`,moduleName:T};static arrowFunction={name:`ɵɵarrowFunction`,moduleName:T};static attachSourceLocations={name:`ɵɵattachSourceLocations`,moduleName:T};static NgOnChangesFeature={name:`ɵɵNgOnChangesFeature`,moduleName:T};static ControlFeature={name:`ɵɵControlFeature`,moduleName:T};static InheritDefinitionFeature={name:`ɵɵInheritDefinitionFeature`,moduleName:T};static ProvidersFeature={name:`ɵɵProvidersFeature`,moduleName:T};static HostDirectivesFeature={name:`ɵɵHostDirectivesFeature`,moduleName:T};static ExternalStylesFeature={name:`ɵɵExternalStylesFeature`,moduleName:T};static listener={name:`ɵɵlistener`,moduleName:T};static getInheritedFactory={name:`ɵɵgetInheritedFactory`,moduleName:T};static sanitizeHtml={name:`ɵɵsanitizeHtml`,moduleName:T};static sanitizeStyle={name:`ɵɵsanitizeStyle`,moduleName:T};static validateAttribute={name:`ɵɵvalidateAttribute`,moduleName:T};static sanitizeResourceUrl={name:`ɵɵsanitizeResourceUrl`,moduleName:T};static sanitizeScript={name:`ɵɵsanitizeScript`,moduleName:T};static sanitizeUrl={name:`ɵɵsanitizeUrl`,moduleName:T};static sanitizeUrlOrResourceUrl={name:`ɵɵsanitizeUrlOrResourceUrl`,moduleName:T};static trustConstantHtml={name:`ɵɵtrustConstantHtml`,moduleName:T};static trustConstantResourceUrl={name:`ɵɵtrustConstantResourceUrl`,moduleName:T};static inputDecorator={name:`Input`,moduleName:T};static outputDecorator={name:`Output`,moduleName:T};static viewChildDecorator={name:`ViewChild`,moduleName:T};static viewChildrenDecorator={name:`ViewChildren`,moduleName:T};static contentChildDecorator={name:`ContentChild`,moduleName:T};static contentChildrenDecorator={name:`ContentChildren`,moduleName:T};static InputSignalBrandWriteType={name:`ɵINPUT_SIGNAL_BRAND_WRITE_TYPE`,moduleName:T};static UnwrapDirectiveSignalInputs={name:`ɵUnwrapDirectiveSignalInputs`,moduleName:T};static unwrapWritableSignal={name:`ɵunwrapWritableSignal`,moduleName:T};static assertType={name:`ɵassertType`,moduleName:T}}return e})();w.And,w.Bigger,w.BiggerEquals,w.BitwiseOr,w.BitwiseAnd,w.Divide,w.Assign,w.Equals,w.Identical,w.Lower,w.LowerEquals,w.Minus,w.Modulo,w.Exponentiation,w.Multiply,w.NotEquals,w.NotIdentical,w.NullishCoalesce,w.Or,w.Plus,w.In,w.InstanceOf,w.AdditionAssignment,w.SubtractionAssignment,w.MultiplicationAssignment,w.DivisionAssignment,w.RemainderAssignment,w.ExponentiationAssignment,w.AndAssignment,w.OrAssignment,w.NullishCoalesceAssignment;var Dt=class{span;sourceSpan;constructor(e,t){this.span=e,this.sourceSpan=t}toString(){return`AST`}},Ot=class extends Dt{receiver;args;argumentSpan;constructor(e,t,n,r,i){super(e,t),this.receiver=n,this.args=r,this.argumentSpan=i}visit(e,t=null){return e.visitCall(this,t)}},kt=(function(e){return e[e.Property=0]=`Property`,e[e.Attribute=1]=`Attribute`,e[e.Class=2]=`Class`,e[e.Style=3]=`Style`,e[e.LegacyAnimation=4]=`LegacyAnimation`,e[e.TwoWay=5]=`TwoWay`,e[e.Animation=6]=`Animation`,e})(kt||{}),At=`(:(where|is)\\()?`,jt=`-shadowcsshost`,Mt=`-shadowcsscontext`,Nt=`[^)(]*`,Pt=String.raw`(?:\(${Nt}\)|${Nt})+?`,Ft=String.raw`(?:\(${Pt}\)|${Nt})+?`,It=String.raw`(?:\((${Ft})\))`;String.raw`(:nth-[-\w]+)`+It,jt+It+``,`${At}`,Mt+It+``;var D=(function(e){return e[e.ListEnd=0]=`ListEnd`,e[e.Statement=1]=`Statement`,e[e.Variable=2]=`Variable`,e[e.ElementStart=3]=`ElementStart`,e[e.Element=4]=`Element`,e[e.ForeignComponent=5]=`ForeignComponent`,e[e.Template=6]=`Template`,e[e.ElementEnd=7]=`ElementEnd`,e[e.ContainerStart=8]=`ContainerStart`,e[e.Container=9]=`Container`,e[e.ContainerEnd=10]=`ContainerEnd`,e[e.DisableBindings=11]=`DisableBindings`,e[e.ConditionalCreate=12]=`ConditionalCreate`,e[e.ConditionalBranchCreate=13]=`ConditionalBranchCreate`,e[e.Conditional=14]=`Conditional`,e[e.EnableBindings=15]=`EnableBindings`,e[e.Text=16]=`Text`,e[e.Listener=17]=`Listener`,e[e.InterpolateText=18]=`InterpolateText`,e[e.Binding=19]=`Binding`,e[e.Property=20]=`Property`,e[e.StyleProp=21]=`StyleProp`,e[e.ClassProp=22]=`ClassProp`,e[e.StyleMap=23]=`StyleMap`,e[e.ClassMap=24]=`ClassMap`,e[e.Advance=25]=`Advance`,e[e.Pipe=26]=`Pipe`,e[e.Attribute=27]=`Attribute`,e[e.ExtractedAttribute=28]=`ExtractedAttribute`,e[e.Defer=29]=`Defer`,e[e.DeferOn=30]=`DeferOn`,e[e.DeferWhen=31]=`DeferWhen`,e[e.I18nMessage=32]=`I18nMessage`,e[e.DomProperty=33]=`DomProperty`,e[e.Namespace=34]=`Namespace`,e[e.ProjectionDef=35]=`ProjectionDef`,e[e.EnableIncrementalHydrationRuntime=36]=`EnableIncrementalHydrationRuntime`,e[e.Projection=37]=`Projection`,e[e.Content=38]=`Content`,e[e.RepeaterCreate=39]=`RepeaterCreate`,e[e.Repeater=40]=`Repeater`,e[e.TwoWayProperty=41]=`TwoWayProperty`,e[e.TwoWayListener=42]=`TwoWayListener`,e[e.DeclareLet=43]=`DeclareLet`,e[e.StoreLet=44]=`StoreLet`,e[e.I18nStart=45]=`I18nStart`,e[e.I18n=46]=`I18n`,e[e.I18nEnd=47]=`I18nEnd`,e[e.I18nExpression=48]=`I18nExpression`,e[e.I18nApply=49]=`I18nApply`,e[e.IcuStart=50]=`IcuStart`,e[e.IcuEnd=51]=`IcuEnd`,e[e.IcuPlaceholder=52]=`IcuPlaceholder`,e[e.I18nContext=53]=`I18nContext`,e[e.I18nAttributes=54]=`I18nAttributes`,e[e.SourceLocation=55]=`SourceLocation`,e[e.Animation=56]=`Animation`,e[e.AnimationString=57]=`AnimationString`,e[e.AnimationBinding=58]=`AnimationBinding`,e[e.AnimationListener=59]=`AnimationListener`,e[e.Control=60]=`Control`,e[e.ControlCreate=61]=`ControlCreate`,e})(D||{}),Lt=(function(e){return e[e.LexicalRead=0]=`LexicalRead`,e[e.Context=1]=`Context`,e[e.TrackContext=2]=`TrackContext`,e[e.ReadVariable=3]=`ReadVariable`,e[e.NextContext=4]=`NextContext`,e[e.Reference=5]=`Reference`,e[e.StoreLet=6]=`StoreLet`,e[e.ContextLetReference=7]=`ContextLetReference`,e[e.GetCurrentView=8]=`GetCurrentView`,e[e.RestoreView=9]=`RestoreView`,e[e.ResetView=10]=`ResetView`,e[e.PureFunctionExpr=11]=`PureFunctionExpr`,e[e.PureFunctionParameterExpr=12]=`PureFunctionParameterExpr`,e[e.PipeBinding=13]=`PipeBinding`,e[e.PipeBindingVariadic=14]=`PipeBindingVariadic`,e[e.SafePropertyRead=15]=`SafePropertyRead`,e[e.SafeKeyedRead=16]=`SafeKeyedRead`,e[e.SafeNavigationMigration=17]=`SafeNavigationMigration`,e[e.SafeTernaryExpr=18]=`SafeTernaryExpr`,e[e.EmptyExpr=19]=`EmptyExpr`,e[e.AssignTemporaryExpr=20]=`AssignTemporaryExpr`,e[e.ReadTemporaryExpr=21]=`ReadTemporaryExpr`,e[e.SlotLiteralExpr=22]=`SlotLiteralExpr`,e[e.ConditionalCase=23]=`ConditionalCase`,e[e.ConstCollected=24]=`ConstCollected`,e[e.TwoWayBindingSet=25]=`TwoWayBindingSet`,e[e.ForeignContent=26]=`ForeignContent`,e[e.ArrowFunction=27]=`ArrowFunction`,e})(Lt||{}),Rt=(function(e){return e[e.None=0]=`None`,e[e.AlwaysInline=1]=`AlwaysInline`,e})(Rt||{}),zt=(function(e){return e[e.Context=0]=`Context`,e[e.Identifier=1]=`Identifier`,e[e.SavedView=2]=`SavedView`,e[e.Alias=3]=`Alias`,e})(zt||{}),Bt=(function(e){return e[e.Attribute=0]=`Attribute`,e[e.ClassName=1]=`ClassName`,e[e.StyleProperty=2]=`StyleProperty`,e[e.Property=3]=`Property`,e[e.Template=4]=`Template`,e[e.I18n=5]=`I18n`,e[e.LegacyAnimation=6]=`LegacyAnimation`,e[e.TwoWayProperty=7]=`TwoWayProperty`,e[e.Animation=8]=`Animation`,e})(Bt||{}),Vt=(function(e){return e[e.Creation=0]=`Creation`,e[e.Postproccessing=1]=`Postproccessing`,e})(Vt||{}),Ht=(function(e){return e[e.I18nText=0]=`I18nText`,e[e.I18nAttribute=1]=`I18nAttribute`,e})(Ht||{}),Ut=(function(e){return e[e.None=0]=`None`,e[e.ElementTag=1]=`ElementTag`,e[e.TemplateTag=2]=`TemplateTag`,e[e.OpenTag=4]=`OpenTag`,e[e.CloseTag=8]=`CloseTag`,e[e.ExpressionIndex=16]=`ExpressionIndex`,e})(Ut||{}),Wt=(function(e){return e[e.HTML=0]=`HTML`,e[e.SVG=1]=`SVG`,e[e.Math=2]=`Math`,e})(Wt||{}),Gt=(function(e){return e[e.Idle=0]=`Idle`,e[e.Immediate=1]=`Immediate`,e[e.Timer=2]=`Timer`,e[e.Hover=3]=`Hover`,e[e.Interaction=4]=`Interaction`,e[e.Viewport=5]=`Viewport`,e[e.Never=6]=`Never`,e})(Gt||{}),Kt=(function(e){return e[e.RootI18n=0]=`RootI18n`,e[e.Icu=1]=`Icu`,e[e.Attr=2]=`Attr`,e})(Kt||{}),qt=(function(e){return e[e.NgTemplate=0]=`NgTemplate`,e[e.Structural=1]=`Structural`,e[e.Block=2]=`Block`,e})(qt||{}),Jt=(function(e){return e[e.None=0]=`None`,e[e.InChildOperation=1]=`InChildOperation`,e[e.InArrowFunctionOperation=2]=`InArrowFunctionOperation`,e[e.InSafeNavigationMigration=4]=`InSafeNavigationMigration`,e})(Jt||{});D.Element,D.ElementStart,D.Container,D.ContainerStart,D.Template,D.RepeaterCreate,D.ConditionalCreate,D.ConditionalBranchCreate;var O=(function(e){return e[e.Tmpl=0]=`Tmpl`,e[e.Host=1]=`Host`,e[e.Both=2]=`Both`,e})(O||{}),Yt=(function(e){return e[e.Full=0]=`Full`,e[e.DomOnly=1]=`DomOnly`,e})(Yt||{});E.ariaProperty,E.ariaProperty,E.attribute,E.attribute,E.classProp,E.classProp,E.element,E.element,E.elementContainer,E.elementContainer,E.elementContainerEnd,E.elementContainerEnd,E.elementContainerStart,E.elementContainerStart,E.elementEnd,E.elementEnd,E.elementStart,E.elementStart,E.domProperty,E.domProperty,E.i18nExp,E.i18nExp,E.listener,E.listener,E.listener,E.listener,E.property,E.property,E.styleProp,E.styleProp,E.syntheticHostListener,E.syntheticHostListener,E.syntheticHostProperty,E.syntheticHostProperty,E.templateCreate,E.templateCreate,E.twoWayProperty,E.twoWayProperty,E.twoWayListener,E.twoWayListener,E.declareLet,E.declareLet,E.conditionalCreate,E.conditionalBranchCreate,E.conditionalBranchCreate,E.conditionalBranchCreate,E.domElement,E.domElement,E.domElementStart,E.domElementStart,E.domElementEnd,E.domElementEnd,E.domElementContainer,E.domElementContainer,E.domElementContainerStart,E.domElementContainerStart,E.domElementContainerEnd,E.domElementContainerEnd,E.domListener,E.domListener,E.domTemplate,E.domTemplate,E.animationEnter,E.animationEnter,E.animationLeave,E.animationLeave,E.animationEnterListener,E.animationEnterListener,E.animationLeaveListener,E.animationLeaveListener,w.And,w.Bigger,w.BiggerEquals,w.BitwiseOr,w.BitwiseAnd,w.Divide,w.Assign,w.Equals,w.Identical,w.Lower,w.LowerEquals,w.Minus,w.Modulo,w.Exponentiation,w.Multiply,w.NotEquals,w.NotIdentical,w.NullishCoalesce,w.Or,w.Plus,w.In,w.InstanceOf,w.AdditionAssignment,w.SubtractionAssignment,w.MultiplicationAssignment,w.DivisionAssignment,w.RemainderAssignment,w.ExponentiationAssignment,w.AndAssignment,w.OrAssignment,w.NullishCoalesceAssignment,D.Property,D.Property,D.Property,D.Attribute,D.Attribute,D.Property,D.TwoWayProperty,D.Container,D.ContainerStart,D.ContainerEnd,D.Element,D.ElementStart,D.ElementEnd,D.Template,D.ElementEnd,D.ElementStart,D.Element,D.ContainerEnd,D.ContainerStart,D.Container,D.I18nEnd,D.I18nStart,D.I18n,D.Pipe;var Xt=` \f +\r \v ᠎ - \u2028\u2029   `;`${Xt}`,`${Xt}`;var Zt=(function(e){return e[e.Character=0]=`Character`,e[e.Identifier=1]=`Identifier`,e[e.PrivateIdentifier=2]=`PrivateIdentifier`,e[e.Keyword=3]=`Keyword`,e[e.String=4]=`String`,e[e.Operator=5]=`Operator`,e[e.Number=6]=`Number`,e[e.RegExpBody=7]=`RegExpBody`,e[e.RegExpFlags=8]=`RegExpFlags`,e[e.Error=9]=`Error`,e})(Zt||{}),Qt=(function(e){return e[e.Plain=0]=`Plain`,e[e.TemplateLiteralPart=1]=`TemplateLiteralPart`,e[e.TemplateLiteralEnd=2]=`TemplateLiteralEnd`,e})(Qt||{});Zt.Character,D.StyleMap,D.ClassMap,D.StyleProp,D.ClassProp,D.Attribute,D.Property,D.Attribute,D.Control,D.DomProperty,D.DomProperty,D.Attribute,D.StyleMap,D.ClassMap,D.StyleProp,D.ClassProp,D.Listener,D.TwoWayListener,D.AnimationListener,D.StyleMap,D.ClassMap,D.StyleProp,D.ClassProp,D.Property,D.TwoWayProperty,D.DomProperty,D.Attribute,D.Animation,D.Control,Gt.Idle,E.deferOnIdle,E.deferPrefetchOnIdle,E.deferHydrateOnIdle,Gt.Immediate,E.deferOnImmediate,E.deferPrefetchOnImmediate,E.deferHydrateOnImmediate,Gt.Timer,E.deferOnTimer,E.deferPrefetchOnTimer,E.deferHydrateOnTimer,Gt.Hover,E.deferOnHover,E.deferPrefetchOnHover,E.deferHydrateOnHover,Gt.Interaction,E.deferOnInteraction,E.deferPrefetchOnInteraction,E.deferHydrateOnInteraction,Gt.Viewport,E.deferOnViewport,E.deferPrefetchOnViewport,E.deferHydrateOnViewport,Gt.Never,E.deferHydrateNever,E.deferHydrateNever,E.deferHydrateNever,E.pipeBind1,E.pipeBind2,E.pipeBind3,E.pipeBind4,E.textInterpolate,E.textInterpolate1,E.textInterpolate2,E.textInterpolate3,E.textInterpolate4,E.textInterpolate5,E.textInterpolate6,E.textInterpolate7,E.textInterpolate8,E.textInterpolateV,E.interpolate,E.interpolate1,E.interpolate2,E.interpolate3,E.interpolate4,E.interpolate5,E.interpolate6,E.interpolate7,E.interpolate8,E.interpolateV,E.pureFunction0,E.pureFunction1,E.pureFunction2,E.pureFunction3,E.pureFunction4,E.pureFunction5,E.pureFunction6,E.pureFunction7,E.pureFunction8,E.pureFunctionV,E.resolveWindow,E.resolveDocument,E.resolveBody,Qe.HTML,E.sanitizeHtml,Qe.RESOURCE_URL,E.sanitizeResourceUrl,Qe.SCRIPT,E.sanitizeScript,Qe.STYLE,E.sanitizeStyle,Qe.URL,E.sanitizeUrl,Qe.ATTRIBUTE_NO_BINDING,E.validateAttribute,Qe.HTML,E.trustConstantHtml,Qe.RESOURCE_URL,E.trustConstantResourceUrl;var $t=(function(e){return e[e.None=0]=`None`,e[e.ViewContextRead=1]=`ViewContextRead`,e[e.ViewContextWrite=2]=`ViewContextWrite`,e[e.SideEffectful=4]=`SideEffectful`,e})($t||{});O.Tmpl,O.Tmpl,O.Both,O.Host,O.Tmpl,O.Tmpl,O.Tmpl,O.Both,O.Both,O.Both,O.Tmpl,O.Both,O.Both,O.Tmpl,O.Both,O.Tmpl,O.Both,O.Both,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Both,O.Both,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Both,O.Both,O.Both,O.Tmpl,O.Tmpl,O.Both,O.Tmpl,O.Tmpl,O.Tmpl,O.Both,O.Both,O.Tmpl,O.Both,O.Both,O.Both,O.Both,O.Both,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Both,O.Tmpl,O.Both,O.Tmpl,O.Both,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Tmpl,O.Both,O.Both,O.Both,kt.Property,Bt.Property,kt.TwoWay,Bt.TwoWayProperty,kt.Attribute,Bt.Attribute,kt.Class,Bt.ClassName,kt.Style,Bt.StyleProperty,kt.LegacyAnimation,Bt.LegacyAnimation,kt.Animation,Bt.Animation;var en=`%COMP%`;`${en}`,`${en}`,class e{static SINGLETON=new e;static veWillInferAnyFor(t){let n=e.SINGLETON;return t instanceof Ot?t.visit(n):t.receiver.visit(n)}visitUnary(e){return e.expr.visit(this)}visitBinary(e){return e.left.visit(this)||e.right.visit(this)}visitChain(){return!1}visitConditional(e){return e.condition.visit(this)||e.trueExp.visit(this)||e.falseExp.visit(this)}visitCall(){return!0}visitSafeCall(){return!1}visitImplicitReceiver(){return!1}visitThisReceiver(){return!1}visitInterpolation(e){return e.expressions.some(e=>e.visit(this))}visitKeyedRead(){return!1}visitLiteralArray(){return!0}visitLiteralMap(){return!0}visitLiteralPrimitive(){return!1}visitPipe(){return!0}visitPrefixNot(e){return e.expression.visit(this)}visitTypeofExpression(e){return e.expression.visit(this)}visitVoidExpression(e){return e.expression.visit(this)}visitNonNullAssert(e){return e.expression.visit(this)}visitPropertyRead(){return!1}visitSafePropertyRead(){return!1}visitSafeKeyedRead(){return!1}visitTemplateLiteral(){return!1}visitTemplateLiteralElement(){return!1}visitTaggedTemplateLiteral(){return!1}visitParenthesizedExpression(e){return e.expression.visit(this)}visitRegularExpressionLiteral(){return!1}visitSpreadElement(e){return e.expression.visit(this)}visitArrowFunction(e,t){return!1}};var tn=null,nn=!1,rn=1,an=null,on=Symbol(`SIGNAL`);function k(e){let t=tn;return tn=e,t}function sn(){return tn}var cn={version:0,lastCleanEpoch:0,dirty:!1,producers:void 0,producersTail:void 0,consumers:void 0,consumersTail:void 0,recomputing:!1,consumerAllowSignalWrites:!1,consumerIsAlwaysLive:!1,kind:`unknown`,producerMustRecompute:()=>!1,producerRecomputeValue:()=>{},consumerMarkedDirty:()=>{},consumerOnSignalRead:()=>{}};function ln(e){if(nn)throw Error(``);if(tn===null)return;tn.consumerOnSignalRead(e);let t=tn.producersTail;if(t!==void 0&&t.producer===e)return;let n,r=tn.recomputing;if(r&&(n=t===void 0?tn.producers:t.nextProducer,n!==void 0&&n.producer===e)){tn.producersTail=n,n.lastReadVersion=e.version,n.knownValidAtEpoch=rn;return}let i=e.consumersTail;if(i!==void 0&&i.consumer===tn&&(!r||i.knownValidAtEpoch===rn))return;let a=wn(tn),o={producer:e,consumer:tn,nextProducer:n,prevConsumer:void 0,knownValidAtEpoch:rn,lastReadVersion:e.version,nextConsumer:void 0};tn.producersTail=o,t===void 0?tn.producers=o:t.nextProducer=o,a&&Sn(e,o)}function un(){rn++}function dn(e){if((!wn(e)||e.dirty)&&(e.dirty||e.lastCleanEpoch!==rn)){if(!e.producerMustRecompute(e)&&!bn(e)){hn(e);return}e.producerRecomputeValue(e),hn(e)}}function fn(e){if(e.consumers===void 0)return;let t=nn;nn=!0;try{for(let t=e.consumers;t!==void 0;t=t.nextConsumer){let e=t.consumer;e.dirty||mn(e)}}finally{nn=t}}function pn(){return tn?.consumerAllowSignalWrites!==!1}function mn(e){e.dirty=!0,fn(e),e.consumerMarkedDirty?.(e)}function hn(e){e.dirty=!1,e.lastCleanEpoch=rn}function gn(e){return e&&_n(e),k(e)}function _n(e){if(e.producersTail?.knownValidAtEpoch===rn){let t=e.producers;for(;t!==void 0;)t.knownValidAtEpoch=null,t=t.nextProducer}e.producersTail=void 0,e.recomputing=!0}function vn(e,t){k(t),e&&yn(e)}function yn(e){e.recomputing=!1;let t=e.producersTail,n=t===void 0?e.producers:t.nextProducer;if(n!==void 0){if(wn(e))do n=Cn(n);while(n!==void 0);t===void 0?e.producers=void 0:t.nextProducer=void 0}}function bn(e){for(let t=e.producers;t!==void 0;t=t.nextProducer){let e=t.producer,n=t.lastReadVersion;if(n!==e.version||(dn(e),n!==e.version))return!0}return!1}function xn(e){if(wn(e)){let t=e.producers;for(;t!==void 0;)t=Cn(t)}e.producers=void 0,e.producersTail=void 0,e.consumers=void 0,e.consumersTail=void 0}function Sn(e,t){let n=e.consumersTail,r=wn(e);if(n===void 0?(t.nextConsumer=void 0,e.consumers=t):(t.nextConsumer=n.nextConsumer,n.nextConsumer=t),t.prevConsumer=n,e.consumersTail=t,!r)for(let t=e.producers;t!==void 0;t=t.nextProducer)Sn(t.producer,t)}function Cn(e){let t=e.producer,n=e.nextProducer,r=e.nextConsumer,i=e.prevConsumer;if(e.nextConsumer=void 0,e.prevConsumer=void 0,r===void 0?t.consumersTail=i:r.prevConsumer=i,i!==void 0)i.nextConsumer=r;else if(t.consumers=r,!wn(t)){let e=t.producers;for(;e!==void 0;)e=Cn(e)}return n}function wn(e){return e.consumerIsAlwaysLive||e.consumers!==void 0}function Tn(e){an?.(e)}function En(e,t){return Object.is(e,t)}function Dn(e,t){let n=Object.create(jn);n.computation=e,t!==void 0&&(n.equal=t);let r=()=>{if(dn(n),ln(n),n.value===An)throw n.error;return n.value};return r[on]=n,Tn(n),r}var On=Symbol(`UNSET`),kn=Symbol(`COMPUTING`),An=Symbol(`ERRORED`),jn={...cn,value:On,dirty:!0,error:null,equal:En,kind:`computed`,producerMustRecompute(e){return e.value===On||e.value===kn},producerRecomputeValue(e){if(e.value===kn)throw Error(``);let t=e.value;e.value=kn;let n=gn(e),r,i=!1;try{r=e.computation(),k(null),i=t!==On&&t!==An&&r!==An&&e.equal(t,r)}catch(t){r=An,e.error=t}finally{vn(e,n)}if(i){e.value=t;return}e.value=r,e.version++}};function Mn(){throw Error()}var Nn=Mn;function Pn(e){Nn(e)}function Fn(e){Nn=e}var In=null;function Ln(e,t){let n=Object.create(Vn);n.value=e,t!==void 0&&(n.equal=t);let r=()=>Rn(n);return r[on]=n,Tn(n),[r,e=>zn(n,e),e=>Bn(n,e)]}function Rn(e){return ln(e),e.value}function zn(e,t){pn()||Pn(e),e.equal(e.value,t)||(e.value=t,Hn(e))}function Bn(e,t){pn()||Pn(e),zn(e,t(e.value))}var Vn={...cn,equal:En,value:void 0,kind:`signal`};function Hn(e){e.version++,un(),fn(e),In?.(e)}var Un={...cn,consumerIsAlwaysLive:!0,consumerAllowSignalWrites:!0,dirty:!0,kind:`effect`};function Wn(e){if(e.dirty=!1,e.version>0&&!bn(e))return;e.version++;let t=gn(e);try{e.cleanup(),e.fn()}finally{vn(e,t)}}var Gn=void 0;function Kn(){return Gn}function qn(e){let t=Gn;return Gn=e,t}var Jn=Symbol(`NotFound`);function Yn(e){return e===Jn||e?.name===`ɵNotFound`}function Xn(e,t,n){let r=Object.create($n);r.source=e,r.computation=t,n!=null&&(r.equal=n);let i=()=>{if(dn(r),ln(r),r.value===An)throw r.error;return r.value};return i[on]=r,Tn(r),i}function Zn(e,t){dn(e),zn(e,t),hn(e)}function Qn(e,t){if(dn(e),e.value===An)throw e.error;Bn(e,t),hn(e)}var $n={...cn,value:On,dirty:!0,error:null,equal:En,kind:`linkedSignal`,producerMustRecompute(e){return e.value===On||e.value===kn},producerRecomputeValue(e){if(e.value===kn)throw Error(``);let t=e.value;e.value=kn;let n=gn(e),r,i=!1;try{let n=e.source(),a=t!==On&&t!==An,o=a?{source:e.sourceValue,value:t}:void 0;r=e.computation(n,o),e.sourceValue=n,k(null),i=a&&r!==An&&e.equal(t,r)}catch(t){r=An,e.error=t}finally{vn(e,n)}if(i){e.value=t;return}e.value=r,e.version++}};function er(e){let t=k(null);try{return e()}finally{k(t)}}var tr=function(e,t){return tr=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},tr(e,t)};function nr(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);tr(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}function rr(e){var t=typeof Symbol==`function`&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&typeof e.length==`number`)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw TypeError(t?`Object is not iterable.`:`Symbol.iterator is not defined.`)}function ir(e,t){var n=typeof Symbol==`function`&&e[Symbol.iterator];if(!n)return e;var r=n.call(e),i,a=[],o;try{for(;(t===void 0||t-->0)&&!(i=r.next()).done;)a.push(i.value)}catch(e){o={error:e}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a}function ar(e,t,n){if(n||arguments.length===2)for(var r=0,i=t.length,a;r0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(t){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,t)},t.prototype._subscribe=function(e){return this._throwIfClosed(),this._checkFinalizedStatuses(e),this._innerSubscribe(e)},t.prototype._innerSubscribe=function(e){var t=this,n=this,r=n.hasError,i=n.isStopped,a=n.observers;return r||i?dr:(this.currentObservers=null,a.push(e),new ur(function(){t.currentObservers=null,lr(a,e)}))},t.prototype._checkFinalizedStatuses=function(e){var t=this,n=t.hasError,r=t.thrownError,i=t.isStopped;n?e.error(r):i&&e.complete()},t.prototype.asObservable=function(){var e=new Lr;return e.source=this,e},t.create=function(e,t){return new qr(e,t)},t}(Lr),qr=function(e){nr(t,e);function t(t,n){var r=e.call(this)||this;return r.destination=t,r.source=n,r}return t.prototype.next=function(e){var t,n;(n=(t=this.destination)?.next)==null||n.call(t,e)},t.prototype.error=function(e){var t,n;(n=(t=this.destination)?.error)==null||n.call(t,e)},t.prototype.complete=function(){var e,t;(t=(e=this.destination)?.complete)==null||t.call(e)},t.prototype._subscribe=function(e){return this.source?.subscribe(e)??dr},t}(Kr),Jr=function(e){nr(t,e);function t(t){var n=e.call(this)||this;return n._value=t,n}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(t){var n=e.prototype._subscribe.call(this,t);return!n.closed&&t.next(this._value),n},t.prototype.getValue=function(){var e=this,t=e.hasError,n=e.thrownError,r=e._value;if(t)throw n;return this._throwIfClosed(),r},t.prototype.next=function(t){e.prototype.next.call(this,this._value=t)},t}(Kr);function Yr(e,t){return Hr(function(n,r){var i=0;n.subscribe(Ur(r,function(n){r.next(e.call(t,n,i++))}))})}var Xr=`https://angular.dev/best-practices/security#preventing-cross-site-scripting-xss`,A=class extends Error{code;constructor(e,t){super(Qr(e,t)),this.code=e}};function Zr(e){return`NG0${Math.abs(e)}`}function Qr(e,t){return`${Zr(e)}${t?`: `+t:``}`}function $r(e){for(let t in e)if(e[t]===$r)return t;throw Error(``)}function ei(e){if(typeof e==`string`)return e;if(Array.isArray(e))return`[${e.map(ei).join(`, `)}]`;if(e==null)return``+e;let t=e.overriddenName||e.name;if(t)return`${t}`;let n=e.toString();if(n==null)return``+n;let r=n.indexOf(` +`);return r>=0?n.slice(0,r):n}function ti(e,t){return e?t?`${e} ${t}`:e:t||``}var ni=$r({__forward_ref__:$r});function ri(e){return e.__forward_ref__=ri,e}function ii(e){return ai(e)?e():e}function ai(e){return typeof e==`function`&&Object.hasOwn(e,ni)&&e.__forward_ref__===ri}function oi(e){return{token:e.token,providedIn:e.providedIn||null,factory:e.factory,value:void 0}}function si(e){return ci(e,di)}function ci(e,t){return Object.hasOwn(e,t)&&e[t]||null}function li(e){return(e?.[di]??null)||null}function ui(e){return e&&Object.hasOwn(e,fi)?e[fi]:null}var di=$r({ɵprov:$r}),fi=$r({ɵinj:$r}),j=class{_desc;ngMetadataName=`InjectionToken`;ɵprov;constructor(e,t){this._desc=e,this.ɵprov=void 0,typeof t==`number`?this.__NG_ELEMENT_ID__=t:t!==void 0&&(this.ɵprov=oi({token:this,providedIn:t.providedIn||`root`,factory:t.factory}))}get multi(){return this}toString(){return`InjectionToken ${this._desc}`}};function pi(e){return e&&!!e.ɵproviders}var mi=$r({ɵcmp:$r}),hi=$r({ɵdir:$r}),gi=$r({ɵpipe:$r}),_i=$r({ɵfac:$r}),vi=$r({__NG_ELEMENT_ID__:$r}),yi=$r({__NG_ENV_ID__:$r});function bi(e){return Ci(e,`@Component`),e[mi]||null}function xi(e){return Ci(e,`@Directive`),e[hi]||null}function Si(e){return Ci(e,`@Pipe`),e[gi]||null}function Ci(e,t){if(e==null)throw new A(-919,!1)}function wi(e){return typeof e==`string`?e:e==null?``:String(e)}var Ti=$r({ngErrorCode:$r}),Ei=$r({ngErrorMessage:$r}),Di=$r({ngTokenPath:$r});function Oi(e,t){return Ai(``,-200,t)}function ki(e,t){throw new A(-201,!1)}function Ai(e,t,n){let r=new A(t,e);return r[Ti]=t,r[Ei]=e,n&&(r[Di]=n),r}function ji(e){return e[Ti]}var Mi;function Ni(){return Mi}function Pi(e){let t=Mi;return Mi=e,t}function Fi(e,t,n){let r=si(e);if(r&&r.providedIn==`root`)return r.value===void 0?r.value=r.factory():r.value;if(n&8)return null;if(t!==void 0)return t;ki(e,``)}var Ii=globalThis,Li={},Ri=`__NG_DI_FLAG__`,zi=class{injector;constructor(e){this.injector=e}retrieve(e,t){let n=Hi(t)||0;try{return this.injector.get(e,n&8?null:Li,n)}catch(e){if(Yn(e))return e;throw e}}};function Bi(e,t=0){let n=Kn();if(n===void 0)throw new A(-203,!1);if(n===null)return Fi(e,void 0,t);{let r=Ui(t),i=n.retrieve(e,r);if(Yn(i)){if(r.optional)return null;throw i}return i}}function Vi(e,t=0){return(Ni()||Bi)(ii(e),t)}function M(e,t){return Vi(e,Hi(t))}function Hi(e){return e===void 0||typeof e==`number`?e:0|(e.optional&&8)|(e.host&&1)|(e.self&&2)|(e.skipSelf&&4)}function Ui(e){return{optional:!!(e&8),host:!!(e&1),self:!!(e&2),skipSelf:!!(e&4)}}function Wi(e){let t=[];for(let n=0;nArray.isArray(e)?qi(e,t):t(e))}function Ji(e,t,n){t>=e.length?e.push(n):e.splice(t,0,n)}function Yi(e,t){return t>=e.length-1?e.pop():e.splice(t,1)[0]}function Xi(e,t,n,r){let i=e.length;if(i==t)e.push(n,r);else if(i===1)e.push(r,e[0]),e[0]=n;else{for(i--,e.push(e[i-1],e[i]);i>t;){let t=i-2;e[i]=e[t],i--}e[t]=n,e[t+1]=r}}function Zi(e,t,n){let r=$i(e,t);return r>=0?e[r|1]=n:(r=~r,Xi(e,r,t,n)),r}function Qi(e,t){let n=$i(e,t);if(n>=0)return e[n|1]}function $i(e,t){return ea(e,t,1)}function ea(e,t,n){let r=0,i=e.length>>n;for(;i!==r;){let a=r+(i-r>>1),o=e[a<t?i=a:r=a+1}return~(i<{n.push(e)};return qi(t,e=>{let t=e;ua(t,a,[],r)&&(i||=[],i.push(t))}),i!==void 0&&la(i,a),n}function la(e,t){for(let n=0;n{t(e,r)})}}function ua(e,t,n,r){if(e=ii(e),!e)return!1;let i=null,a=ui(e),o=!a&&bi(e);if(!a&&!o){let t=e.ngModule;if(a=ui(t),a)i=t;else return!1}else if(o&&!o.standalone)return!1;else i=e;let s=r.has(i);if(o){if(s)return!1;if(r.add(i),o.dependencies){let e=typeof o.dependencies==`function`?o.dependencies():o.dependencies;for(let i of e)ua(i,t,n,r)}}else if(a){if(a.imports!=null&&!s){r.add(i);let e;try{qi(a.imports,i=>{ua(i,t,n,r)&&(e||=[],e.push(i))})}finally{}e!==void 0&&la(e,t)}if(!s){let e=Ki(i)||(()=>new i);t({provide:i,useFactory:e,deps:na},i),t({provide:aa,useValue:i,multi:!0},i),t({provide:ra,useValue:()=>Vi(i),multi:!0},i)}let o=a.providers;if(o!=null&&!s){let n=e;da(o,e=>{t(e,n)})}}else return!1;return i!==e&&e.providers!==void 0}function da(e,t){for(let n of e)pi(n)&&(n=n.ɵproviders),Array.isArray(n)?da(n,t):t(n)}var fa=$r({provide:String,useValue:$r});function pa(e){return typeof e==`object`&&!!e&&fa in e}function ma(e){return!!(e&&e.useExisting)}function ha(e){return!!(e&&e.useFactory)}function ga(e){return typeof e==`function`}var _a=new j(``),va={},ya={},ba=void 0;function xa(){return ba===void 0&&(ba=new oa),ba}var Sa=class{},Ca=class extends Sa{parent;source;scopes;records=new Map;_ngOnDestroyHooks=new Set;_onDestroyHooks=[];get destroyed(){return this._destroyed}_destroyed=!1;injectorDefTypes;constructor(e,t,n,r){super(),this.parent=t,this.source=n,this.scopes=r,Na(e,e=>this.processProvider(e)),this.records.set(ia,ka(void 0,this)),r.has(`environment`)&&this.records.set(Sa,ka(void 0,this));let i=this.records.get(_a);i!=null&&typeof i.value==`string`&&this.scopes.add(i.value),this.injectorDefTypes=new Set(this.get(aa,na,{self:!0}))}retrieve(e,t){let n=Hi(t)||0;try{return this.get(e,Li,n)}catch(e){if(Yn(e))return e;throw e}}destroy(){Oa(this),this._destroyed=!0;let e=k(null);try{for(let e of this._ngOnDestroyHooks)e.ngOnDestroy();let e=this._onDestroyHooks;this._onDestroyHooks=[];for(let t of e)t()}finally{this.records.clear(),this._ngOnDestroyHooks.clear(),this.injectorDefTypes.clear(),k(e)}}onDestroy(e){return Oa(this),this._onDestroyHooks.push(e),()=>this.removeOnDestroy(e)}runInContext(e){Oa(this);let t=qn(this),n=Pi(void 0);try{return e()}finally{qn(t),Pi(n)}}get(e,t=Li,n){if(Oa(this),Object.hasOwn(e,yi))return e[yi](this);let r=Hi(n),i=qn(this),a=Pi(void 0);try{if(!(r&4)){let t=this.records.get(e);if(t===void 0){let n=Ma(e)&&si(e);t=n&&this.injectableDefInScope(n)?ka(wa(e),va):null,this.records.set(e,t)}if(t!=null)return this.hydrate(e,t,r)}let n=r&2?xa():this.parent;return t=r&8&&t===Li?null:t,n.get(e,t)}catch(e){let t=ji(e);throw t===-200||t===-201?new A(t,null):e}finally{Pi(a),qn(i)}}resolveInjectorInitializers(){let e=k(null),t=qn(this),n=Pi(void 0);try{let e=this.get(ra,na,{self:!0});for(let t of e)t()}finally{qn(t),Pi(n),k(e)}}toString(){return`R3Injector[...]`}processProvider(e){e=ii(e);let t=ga(e)?e:ii(e&&e.provide),n=Ea(e);if(!ga(e)&&e.multi===!0){let n=this.records.get(t);n||(n=ka(void 0,va,!0),n.factory=()=>Wi(n.multi),this.records.set(t,n)),t=e,n.multi.push(e)}this.records.set(t,n)}hydrate(e,t,n){let r=k(null);try{if(t.value===ya)throw Oi(``);return t.value===va&&(t.value=ya,t.value=t.factory(void 0,n)),typeof t.value==`object`&&t.value&&ja(t.value)&&this._ngOnDestroyHooks.add(t.value),t.value}finally{k(r)}}injectableDefInScope(e){if(!e.providedIn)return!1;let t=ii(e.providedIn);return typeof t==`string`?t===`any`||this.scopes.has(t):this.injectorDefTypes.has(t)}removeOnDestroy(e){let t=this._onDestroyHooks.indexOf(e);t!==-1&&this._onDestroyHooks.splice(t,1)}};function wa(e){let t=si(e),n=t===null?Ki(e):t.factory;if(n!==null)return n;if(e instanceof j)throw new A(-204,!1);if(e instanceof Function)return Ta(e);throw new A(-204,!1)}function Ta(e){if(e.length>0)throw new A(-204,!1);let t=li(e);return t===null?()=>new e:()=>t.factory(e)}function Ea(e){return pa(e)?ka(void 0,e.useValue):ka(Da(e),va)}function Da(e,t,n){let r;if(ga(e)){let t=ii(e);return Ki(t)||wa(t)}if(pa(e))r=()=>ii(e.useValue);else if(ha(e))r=()=>e.useFactory(...Wi(e.deps||[]));else if(ma(e))r=(t,n)=>Vi(ii(e.useExisting),n!==void 0&&n&8?8:void 0);else{let t=ii(e&&(e.useClass||e.provide));if(Aa(e))r=()=>new t(...Wi(e.deps));else return Ki(t)||wa(t)}return r}function Oa(e){if(e.destroyed)throw new A(-205,!1)}function ka(e,t,n=!1){return{factory:e,value:t,multi:n?[]:void 0}}function Aa(e){return!!e.deps}function ja(e){return typeof e==`object`&&!!e&&typeof e.ngOnDestroy==`function`}function Ma(e){return typeof e==`function`||typeof e==`object`&&e.ngMetadataName===`InjectionToken`}function Na(e,t){for(let n of e)Array.isArray(n)?Na(n,t):n&&pi(n)?Na(n.ɵproviders,t):t(n)}function Pa(e,t){let n;e instanceof Ca?(Oa(e),n=e):n=new zi(e);let r=qn(n),i=Pi(void 0);try{return t()}finally{qn(r),Pi(i)}}function Fa(){return Ni()!==void 0||Kn()!=null}var Ia=1;function La(e){return Array.isArray(e)&&typeof e[Ia]==`object`}function Ra(e){return Array.isArray(e)&&e[Ia]===!0}function za(e){return!!(e.flags&4)}function Ba(e){return e.componentOffset>-1}function Va(e){return(e.flags&1)==1}function Ha(e){return!!e.template}function Ua(e){return!!(e[2]&512)}function Wa(e){return(e[2]&256)==256}var Ga=`math`;function Ka(e){for(;Array.isArray(e);)e=e[0];return e}function qa(e,t){return Ka(t[e])}function Ja(e,t){return Ka(t[e.index])}function Ya(e,t){return e.data[t]}function Xa(e,t){return e[t]}function Za(e,t,n,r){n>=e.data.length&&(e.data[n]=null,e.blueprint[n]=null),t[n]=r}function Qa(e,t){let n=t[e];return La(n)?n:n[0]}function $a(e){return(e[2]&128)==128}function eo(e,t){return t==null?null:e[t]}function to(e){e[17]=0}function no(e){e[2]&1024||(e[2]|=1024,$a(e)&&oo(e))}function ro(e,t){for(;e>0;)t=t[14],e--;return t}function io(e){return!!(e[2]&9216||e[24]?.dirty)}function ao(e){e[10].changeDetectionScheduler?.notify(8),e[2]&64&&(e[2]|=1024),io(e)&&oo(e)}function oo(e){e[10].changeDetectionScheduler?.notify(0);let t=lo(e);for(;t!==null&&!(t[2]&8192||(t[2]|=8192,!$a(t)));)t=lo(t)}function so(e,t){if(Wa(e))throw new A(911,!1);e[21]===null&&(e[21]=[]),e[21].push(t)}function co(e,t){if(e[21]===null)return;let n=e[21].indexOf(t);n!==-1&&e[21].splice(n,1)}function lo(e){let t=e[3];return Ra(t)?t[3]:t}function uo(e){return e[7]??=[]}function fo(e){return e.cleanup??=[]}var N={lFrame:Go(null),bindingsEnabled:!0,skipHydrationRootTNode:null},po=!1;function mo(){return N.lFrame.elementDepthCount}function ho(){N.lFrame.elementDepthCount++}function go(){N.lFrame.elementDepthCount--}function _o(){return N.bindingsEnabled}function vo(){return N.skipHydrationRootTNode!==null}function yo(e){return N.skipHydrationRootTNode===e}function bo(){N.skipHydrationRootTNode=null}function P(){return N.lFrame.lView}function xo(){return N.lFrame.tView}function F(e){return N.lFrame.contextLView=e,e[8]}function I(e){return N.lFrame.contextLView=null,e}function So(){let e=Co();for(;e!==null&&e.type===64;)e=e.parent;return e}function Co(){return N.lFrame.currentTNode}function wo(){let e=N.lFrame,t=e.currentTNode;return e.isParent?t:t.parent}function To(e,t){let n=N.lFrame;n.currentTNode=e,n.isParent=t}function Eo(){return N.lFrame.isParent}function Do(){N.lFrame.isParent=!1}function Oo(){return po}function ko(e){let t=po;return po=e,t}function Ao(){let e=N.lFrame,t=e.bindingRootIndex;return t===-1&&(t=e.bindingRootIndex=e.tView.bindingStartIndex),t}function jo(){return N.lFrame.bindingIndex}function Mo(e){return N.lFrame.bindingIndex=e}function No(){return N.lFrame.bindingIndex++}function Po(e){let t=N.lFrame,n=t.bindingIndex;return t.bindingIndex+=e,n}function Fo(){return N.lFrame.inI18n}function Io(e,t){let n=N.lFrame;n.bindingIndex=n.bindingRootIndex=e,Ro(t)}function Lo(){return N.lFrame.currentDirectiveIndex}function Ro(e){N.lFrame.currentDirectiveIndex=e}function zo(e){let t=N.lFrame.currentDirectiveIndex;return t===-1?null:e[t]}function Bo(e){N.lFrame.currentQueryIndex=e}function Vo(e){let t=e[1];return t.type===2?t.declTNode:t.type===1?e[5]:null}function Ho(e,t,n){if(n&4){let r=t,i=e;for(;r=r.parent,r===null&&!(n&1)&&(r=Vo(i),!(r===null||(i=i[14],r.type&10))););if(r===null)return!1;t=r,e=i}let r=N.lFrame=Wo();return r.currentTNode=t,r.lView=e,!0}function Uo(e){let t=Wo(),n=e[1];N.lFrame=t,t.currentTNode=n.firstChild,t.lView=e,t.tView=n,t.contextLView=e,t.bindingIndex=n.bindingStartIndex,t.inI18n=!1}function Wo(){let e=N.lFrame,t=e===null?null:e.child;return t===null?Go(e):t}function Go(e){let t={currentTNode:null,isParent:!0,lView:null,tView:null,selectedIndex:-1,contextLView:null,elementDepthCount:0,currentNamespace:null,currentDirectiveIndex:-1,bindingRootIndex:-1,bindingIndex:-1,currentQueryIndex:0,parent:e,child:null,inI18n:!1};return e!==null&&(e.child=t),t}function Ko(){let e=N.lFrame;return N.lFrame=e.parent,e.currentTNode=null,e.lView=null,e}var qo=Ko;function Jo(){let e=Ko();e.isParent=!0,e.tView=null,e.selectedIndex=-1,e.contextLView=null,e.elementDepthCount=0,e.currentDirectiveIndex=-1,e.currentNamespace=null,e.bindingRootIndex=-1,e.bindingIndex=-1,e.currentQueryIndex=0}function Yo(e){return(N.lFrame.contextLView=ro(e,N.lFrame.contextLView))[8]}function Xo(){return N.lFrame.selectedIndex}function Zo(e){N.lFrame.selectedIndex=e}function Qo(){let e=N.lFrame;return Ya(e.tView,e.selectedIndex)}function $o(){N.lFrame.currentNamespace=`svg`}function es(){ts()}function ts(){N.lFrame.currentNamespace=null}function ns(){return N.lFrame.currentNamespace}var rs=!0;function is(){return rs}function as(e){rs=e}function os(e,t=null,n=null,r){let i=ss(e,t,n,r);return i.resolveInjectorInitializers(),i}function ss(e,t=null,n=null,r,i=new Set){return new Ca([n||na,sa(e)],t||xa(),null,i)}var cs=class e{static THROW_IF_NOT_FOUND=Li;static NULL=new oa;static create(e,t){if(Array.isArray(e))return os({name:``},t,e,``);{let t=e.name??``;return os({name:t},e.parent,e.providers,t)}}static ɵprov=oi({token:e,providedIn:`any`,factory:()=>Vi(ia)});static __NG_ELEMENT_ID__=-1},ls=new j(``),us=class{static __NG_ELEMENT_ID__=fs;static __NG_ENV_ID__=e=>e},ds=class extends us{_lView;constructor(e){super(),this._lView=e}get destroyed(){return Wa(this._lView)}onDestroy(e){let t=this._lView;return so(t,e),()=>co(t,e)}};function fs(){return new ds(P())}var ps=new j(``),ms=(()=>{class e{taskId=0;pendingTasks=new Set;destroyed=!1;pendingTask=new Jr(!1);debugTaskTracker=M(ps,{optional:!0});get hasPendingTasks(){return!this.destroyed&&this.pendingTask.value}get hasPendingTasksObservable(){return this.destroyed?new Lr(e=>{e.next(!1),e.complete()}):this.pendingTask}add(){!this.hasPendingTasks&&!this.destroyed&&this.pendingTask.next(!0);let e=this.taskId++;return this.pendingTasks.add(e),this.debugTaskTracker?.add(e),e}has(e){return this.pendingTasks.has(e)}remove(e){this.pendingTasks.delete(e),this.debugTaskTracker?.remove(e),this.pendingTasks.size===0&&this.hasPendingTasks&&this.pendingTask.next(!1)}ngOnDestroy(){this.pendingTasks.clear(),this.hasPendingTasks&&this.pendingTask.next(!1),this.destroyed=!0,this.pendingTask.unsubscribe()}static ɵprov=oi({token:e,providedIn:`root`,factory:()=>new e})}return e})(),hs=class extends Kr{__isAsync;destroyRef=void 0;pendingTasks=void 0;constructor(e=!1){super(),this.__isAsync=e,Fa()&&(this.destroyRef=M(us,{optional:!0})??void 0,this.pendingTasks=M(ms,{optional:!0})??void 0)}emit(e){let t=k(null);try{super.next(e)}finally{k(t)}}subscribe(e,t,n){let r=e,i=t||(()=>null),a=n;if(e&&typeof e==`object`){let t=e;r=t.next?.bind(t),i=t.error?.bind(t),a=t.complete?.bind(t)}this.__isAsync&&(i=this.wrapInTimeout(i),r&&=this.wrapInTimeout(r),a&&=this.wrapInTimeout(a));let o=super.subscribe({next:r,error:i,complete:a});return e instanceof ur&&e.add(o),o}wrapInTimeout(e){return t=>{let n=this.pendingTasks?.add();setTimeout(()=>{try{e(t)}finally{n!==void 0&&this.pendingTasks?.remove(n)}})}}};function gs(...e){}function _s(e){let t,n;function r(){e=gs;try{n!==void 0&&typeof cancelAnimationFrame==`function`&&cancelAnimationFrame(n),t!==void 0&&clearTimeout(t)}catch{}}return t=setTimeout(()=>{e(),r()}),typeof requestAnimationFrame==`function`&&(n=requestAnimationFrame(()=>{e(),r()})),()=>r()}function vs(e){return queueMicrotask(()=>e()),()=>{e=gs}}var ys=`isAngularZone`,bs=`isAngularZone_ID`,xs=0,Ss=class e{hasPendingMacrotasks=!1;hasPendingMicrotasks=!1;isStable=!0;onUnstable=new hs(!1);onMicrotaskEmpty=new hs(!1);onStable=new hs(!1);onError=new hs(!1);constructor(e){let{enableLongStackTrace:t=!1,shouldCoalesceEventChangeDetection:n=!1,shouldCoalesceRunChangeDetection:r=!1,scheduleInRootZone:i=!1}=e;if(typeof Zone>`u`)throw new A(908,!1);Zone.assertZonePatched();let a=this;a._nesting=0,a._outer=a._inner=Zone.current,Zone.TaskTrackingZoneSpec&&(a._inner=a._inner.fork(new Zone.TaskTrackingZoneSpec)),t&&Zone.longStackTraceZoneSpec&&(a._inner=a._inner.fork(Zone.longStackTraceZoneSpec)),a.shouldCoalesceEventChangeDetection=!r&&n,a.shouldCoalesceRunChangeDetection=r,a.callbackScheduled=!1,a.scheduleInRootZone=i,Es(a)}static isInAngularZone(){return typeof Zone<`u`&&Zone.current.get(ys)===!0}static assertInAngularZone(){if(!e.isInAngularZone())throw new A(909,!1)}static assertNotInAngularZone(){if(e.isInAngularZone())throw new A(909,!1)}run(e,t,n){return this._inner.run(e,t,n)}runTask(e,t,n,r){let i=this._inner,a=i.scheduleEventTask(`NgZoneEvent: `+r,e,Cs,gs,gs);try{return i.runTask(a,t,n)}finally{i.cancelTask(a)}}runGuarded(e,t,n){return this._inner.runGuarded(e,t,n)}runOutsideAngular(e){return this._outer.run(e)}},Cs={};function ws(e){if(e._nesting==0&&!e.hasPendingMicrotasks&&!e.isStable)try{e._nesting++,e.onMicrotaskEmpty.emit(null)}finally{if(e._nesting--,!e.hasPendingMicrotasks)try{e.runOutsideAngular(()=>e.onStable.emit(null))}finally{e.isStable=!0}}}function Ts(e){if(e.isCheckStableRunning||e.callbackScheduled)return;e.callbackScheduled=!0;function t(){_s(()=>{e.callbackScheduled=!1,Ds(e),e.isCheckStableRunning=!0,ws(e),e.isCheckStableRunning=!1})}e.scheduleInRootZone?Zone.root.run(()=>{t()}):e._outer.run(()=>{t()}),Ds(e)}function Es(e){let t=()=>{Ts(e)},n=xs++;e._inner=e._inner.fork({name:`angular`,properties:{[ys]:!0,[bs]:n,[bs+n]:!0},onInvokeTask:(n,r,i,a,o,s)=>{if(js(s))return n.invokeTask(i,a,o,s);try{return Os(e),n.invokeTask(i,a,o,s)}finally{(e.shouldCoalesceEventChangeDetection&&a.type===`eventTask`||e.shouldCoalesceRunChangeDetection)&&t(),ks(e)}},onInvoke:(n,r,i,a,o,s,c)=>{try{return Os(e),n.invoke(i,a,o,s,c)}finally{e.shouldCoalesceRunChangeDetection&&!e.callbackScheduled&&!Ms(s)&&t(),ks(e)}},onHasTask:(t,n,r,i)=>{t.hasTask(r,i),n===r&&(i.change==`microTask`?(e._hasPendingMicrotasks=i.microTask,Ds(e),ws(e)):i.change==`macroTask`&&(e.hasPendingMacrotasks=i.macroTask))},onHandleError:(t,n,r,i)=>(t.handleError(r,i),e.runOutsideAngular(()=>e.onError.emit(i)),!1)})}function Ds(e){e.hasPendingMicrotasks=!!(e._hasPendingMicrotasks||(e.shouldCoalesceEventChangeDetection||e.shouldCoalesceRunChangeDetection)&&e.callbackScheduled===!0)}function Os(e){e._nesting++,e.isStable&&(e.isStable=!1,e.onUnstable.emit(null))}function ks(e){e._nesting--,ws(e)}var As=class{hasPendingMicrotasks=!1;hasPendingMacrotasks=!1;isStable=!0;onUnstable=new hs;onMicrotaskEmpty=new hs;onStable=new hs;onError=new hs;run(e,t,n){return e.apply(t,n)}runGuarded(e,t,n){return e.apply(t,n)}runOutsideAngular(e){return e()}runTask(e,t,n,r){return e.apply(t,n)}};function js(e){return Ns(e,`__ignore_ng_zone__`)}function Ms(e){return Ns(e,`__scheduler_tick__`)}function Ns(e,t){return!Array.isArray(e)||e.length!==1?!1:e[0]?.data?.[t]===!0}var Ps=class{_console=console;handleError(e){this._console.error(`ERROR`,e)}},Fs=new j(``,{factory:()=>{let e=M(Ss),t=M(Sa),n;return r=>{e.runOutsideAngular(()=>{t.destroyed&&!n?setTimeout(()=>{throw r}):(n??=t.get(Ps),n.handleError(r))})}}}),Is={provide:ra,useValue:()=>{M(Ps,{optional:!0})},multi:!0};function L(e,t){let[n,r,i]=Ln(e,t?.equal),a=n;return a[on],a.set=r,a.update=i,a.asReadonly=Ls.bind(a),a}function Ls(){let e=this[on];if(e.readonlyFn===void 0){let t=()=>this();t[on]=e,e.readonlyFn=t}return e.readonlyFn}var Rs=new j(``,{factory:()=>zs}),zs=`ng`,Bs=new j(``),Vs=new j(``,{providedIn:`platform`,factory:()=>`unknown`}),Hs=new j(``,{factory:()=>M(ls).body?.querySelector(`[ngCspNonce]`)?.getAttribute(`ngCspNonce`)||null}),Us=(()=>{class e{view;node;constructor(e,t){this.view=e,this.node=t}static __NG_ELEMENT_ID__=Ws}return e})();function Ws(){return new Us(P(),So())}var Gs=class{},Ks=new j(``,{factory:()=>!0}),qs=new j(``),Js=(()=>{class e{static ɵprov=oi({token:e,providedIn:`root`,factory:()=>new Ys})}return e})(),Ys=class{dirtyEffectCount=0;queues=new Map;add(e){this.enqueue(e),this.schedule(e)}schedule(e){e.dirty&&this.dirtyEffectCount++}remove(e){let t=e.zone,n=this.queues.get(t);n.has(e)&&(n.delete(e),e.dirty&&this.dirtyEffectCount--)}enqueue(e){let t=e.zone;this.queues.has(t)||this.queues.set(t,new Set);let n=this.queues.get(t);n.has(e)||n.add(e)}flush(){for(;this.dirtyEffectCount>0;){let e=!1;for(let[t,n]of this.queues)e||=t===null?this.flushQueue(n):t.run(()=>this.flushQueue(n));e||(this.dirtyEffectCount=0)}}flushQueue(e){let t=!1;for(let n of e)n.dirty&&(this.dirtyEffectCount--,t=!0,n.run());return t}},Xs=class{[on];constructor(e){this[on]=e}destroy(){this[on].destroy()}};function Zs(e,t){let n=t?.injector??M(cs),r=t?.manualCleanup===!0?null:n.get(us),i,a=n.get(Us,null,{optional:!0}),o=n.get(Gs);return a===null?i=nc(e,n.get(Js),o):(i=tc(a.view,o,e),r instanceof ds&&r._lView===a.view&&(r=null)),i.injector=n,r!==null&&(i.onDestroyFns=[r.onDestroy(()=>i.destroy())]),new Xs(i)}var Qs={...Un,cleanupFns:void 0,zone:null,onDestroyFns:null,run(){let e=ko(!1);try{Wn(this)}finally{ko(e)}},cleanup(){if(!this.cleanupFns?.length)return;let e=k(null);try{for(;this.cleanupFns.length;)this.cleanupFns.pop()()}finally{this.cleanupFns=[],k(e)}}},$s={...Qs,consumerMarkedDirty(){this.scheduler.schedule(this),this.notifier.notify(12)},destroy(){if(xn(this),this.onDestroyFns!==null)for(let e of this.onDestroyFns)e();this.cleanup(),this.scheduler.remove(this)}},ec={...Qs,consumerMarkedDirty(){this.view[2]|=8192,oo(this.view),this.notifier.notify(13)},destroy(){if(xn(this),this.onDestroyFns!==null)for(let e of this.onDestroyFns)e();this.cleanup(),this.view[23]?.delete(this)}};function tc(e,t,n){let r=Object.create(ec);return r.view=e,r.zone=typeof Zone<`u`?Zone.current:null,r.notifier=t,r.fn=rc(r,n),e[23]??=new Set,e[23].add(r),r.consumerMarkedDirty(r),r}function nc(e,t,n){let r=Object.create($s);return r.fn=rc(r,e),r.scheduler=t,r.notifier=n,r.zone=typeof Zone<`u`?Zone.current:null,r.scheduler.add(r),r.notifier.notify(12),r}function rc(e,t){return()=>{t(t=>(e.cleanupFns??=[]).push(t))}}var ic=(()=>{class e{internalPendingTasks=M(ms);scheduler=M(Gs);errorHandler=M(Fs);add(){let e=this.internalPendingTasks.add();return()=>{this.internalPendingTasks.has(e)&&(this.scheduler.notify(11),this.internalPendingTasks.remove(e))}}run(e){let t=this.add();try{e().catch(this.errorHandler).finally(t)}catch(e){this.errorHandler(e),t()}}static ɵprov=oi({token:e,providedIn:`root`,factory:()=>new e})}return e})(),ac=Symbol(`InputSignalNode#UNSET`),oc={...Vn,transformFn:void 0,applyValueToInputSignal(e,t){zn(e,t)}};function sc(e){return{toString:e}.toString()}var R=(function(e){return e[e.TemplateCreateStart=0]=`TemplateCreateStart`,e[e.TemplateCreateEnd=1]=`TemplateCreateEnd`,e[e.TemplateUpdateStart=2]=`TemplateUpdateStart`,e[e.TemplateUpdateEnd=3]=`TemplateUpdateEnd`,e[e.LifecycleHookStart=4]=`LifecycleHookStart`,e[e.LifecycleHookEnd=5]=`LifecycleHookEnd`,e[e.OutputStart=6]=`OutputStart`,e[e.OutputEnd=7]=`OutputEnd`,e[e.BootstrapApplicationStart=8]=`BootstrapApplicationStart`,e[e.BootstrapApplicationEnd=9]=`BootstrapApplicationEnd`,e[e.BootstrapComponentStart=10]=`BootstrapComponentStart`,e[e.BootstrapComponentEnd=11]=`BootstrapComponentEnd`,e[e.ChangeDetectionStart=12]=`ChangeDetectionStart`,e[e.ChangeDetectionEnd=13]=`ChangeDetectionEnd`,e[e.ChangeDetectionSyncStart=14]=`ChangeDetectionSyncStart`,e[e.ChangeDetectionSyncEnd=15]=`ChangeDetectionSyncEnd`,e[e.AfterRenderHooksStart=16]=`AfterRenderHooksStart`,e[e.AfterRenderHooksEnd=17]=`AfterRenderHooksEnd`,e[e.ComponentStart=18]=`ComponentStart`,e[e.ComponentEnd=19]=`ComponentEnd`,e[e.DeferBlockStateStart=20]=`DeferBlockStateStart`,e[e.DeferBlockStateEnd=21]=`DeferBlockStateEnd`,e[e.DynamicComponentStart=22]=`DynamicComponentStart`,e[e.DynamicComponentEnd=23]=`DynamicComponentEnd`,e[e.HostBindingsUpdateStart=24]=`HostBindingsUpdateStart`,e[e.HostBindingsUpdateEnd=25]=`HostBindingsUpdateEnd`,e})(R||{});function cc(e,t,n,r){t===null?e[n]=r:t.applyValueToInputSignal(t,r)}var lc=null;function uc(){return lc}var dc=[],fc=function(e,t=null,n){for(let r=0;r=r)break}else t[c]<0&&(e[17]+=65536),(s>14>16&&(e[2]&3)===t&&(e[2]+=16384,yc(o,a)):yc(o,a)}var xc=-1,Sc=class{factory;name;injectImpl;resolving=!1;canSeeViewProviders;multi;componentProviders;index;providerFactory;constructor(e,t,n,r){this.factory=e,this.name=r,this.canSeeViewProviders=t,this.injectImpl=n}};function Cc(e){return!!(e.flags&8)}function wc(e){return!!(e.flags&16)}function Tc(e,t,n){let r=0;for(;rt){o=a-1;break}}}for(;a>16}function Nc(e,t){let n=Mc(e),r=t;for(;n>0;)r=r[14],n--;return r}var Pc=!0;function Fc(e){let t=Pc;return Pc=e,t}var Ic=255,Lc=5,Rc=0,zc={};function Bc(e,t,n){let r;typeof n==`string`?r=n.charCodeAt(0)||0:Object.hasOwn(n,vi)&&(r=n[vi]),r??=n[vi]=Rc++;let i=r&Ic,a=1<>Lc)]|=a}function Vc(e,t){let n=Uc(e,t);if(n!==-1)return n;let r=t[1];r.firstCreatePass&&(e.injectorIndex=t.length,Hc(r.data,e),Hc(t,null),Hc(r.blueprint,null));let i=Wc(e,t),a=e.injectorIndex;if(Ac(i)){let e=jc(i),n=Nc(i,t),r=n[1].data;for(let i=0;i<8;i++)t[a+i]=n[e+i]|r[e+i]}return t[a+8]=i,a}function Hc(e,t){e.push(0,0,0,0,0,0,0,0,t)}function Uc(e,t){return e.injectorIndex===-1||e.parent&&e.parent.injectorIndex===e.injectorIndex||t[e.injectorIndex+8]===null?-1:e.injectorIndex}function Wc(e,t){if(e.parent&&e.parent.injectorIndex!==-1)return e.parent.injectorIndex;let n=0,r=null,i=t;for(;i!==null;){if(r=al(i),r===null)return xc;if(n++,i=i[14],r.injectorIndex!==-1)return r.injectorIndex|n<<16}return xc}function Gc(e,t,n){Bc(e,t,n)}function Kc(e,t,n){if(n&8||e!==void 0)return e;ki(t,`NodeInjector`)}function qc(e,t,n,r){if(n&8&&r===void 0&&(r=null),!(n&3)){let i=e[9],a=Pi(void 0);try{return i?i.get(t,r,n&8):Fi(t,r,n&8)}finally{Pi(a)}}return Kc(r,t,n)}function Jc(e,t,n,r=0,i){if(e!==null){if(t[2]&2048&&!(r&2)){let i=il(e,t,n,r,zc);if(i!==zc)return i}let i=Yc(e,t,n,r,zc);if(i!==zc)return i}return qc(t,n,r,i)}function Yc(e,t,n,r,i){let a=$c(n);if(typeof a==`function`){if(!Ho(t,e,r))return r&1?Kc(i,n,r):qc(t,n,r,i);try{let e;if(e=a(r),e==null&&!(r&8))ki(n);else return e}finally{qo()}}else if(typeof a==`number`){let i=null,o=Uc(e,t),s=xc,c=r&1?t[15][5]:null;for((o===-1||r&4)&&(s=o===-1?Wc(e,t):t[o+8],s===xc||!tl(r,!1)?o=-1:(i=t[1],o=jc(s),t=Nc(s,t)));o!==-1;){let e=t[1];if(el(a,o,e.data)){let e=Xc(o,t,n,i,r,c);if(e!==zc)return e}s=t[o+8],s!==xc&&tl(r,t[1].data[o+8]===c)&&el(a,o,t)?(i=e,o=jc(s),t=Nc(s,t)):o=-1}}return i}function Xc(e,t,n,r,i,a){let o=t[1],s=o.data[e+8],c=Zc(s,o,n,r==null?Ba(s)&&Pc:r!=o&&!!(s.type&3),i&1&&a===s);return c===null?zc:Qc(t,o,c,s,i)}function Zc(e,t,n,r,i){let a=e.providerIndexes,o=t.data,s=a&1048575,c=e.directiveStart,l=e.directiveEnd,u=a>>20,d=r?s:s+u,f=i?s+u:l;for(let e=d;e=c&&t.type===n)return e}if(i){let e=o[c];if(e&&Ha(e)&&e.type===n)return c}return null}function Qc(e,t,n,r,i){let a=e[n],o=t.data;if(a instanceof Sc){let s=a;if(s.resolving)throw Oi(``);let c=Fc(s.canSeeViewProviders);s.resolving=!0,o[n].type||o[n];let l=s.injectImpl?Pi(s.injectImpl):null;Ho(e,r,0);try{a=e[n]=s.factory(void 0,i,o,e,r),t.firstCreatePass&&n>=r.directiveStart&&pc(n,o[n],t)}finally{l!==null&&Pi(l),Fc(c),s.resolving=!1,qo()}}return a}function $c(e){if(typeof e==`string`)return e.charCodeAt(0)||0;let t=Object.hasOwn(e,vi)?e[vi]:void 0;return typeof t==`number`?t>=0?t&Ic:rl:t}function el(e,t,n){let r=1<>Lc)]&r)}function tl(e,t){return!(e&2)&&!(e&1&&t)}var nl=class{_tNode;_lView;constructor(e,t){this._tNode=e,this._lView=t}get(e,t,n){return Jc(this._tNode,this._lView,e,Hi(n),t)}};function rl(){return new nl(So(),P())}function il(e,t,n,r,i){let a=e,o=t;for(;a!==null&&o!==null&&o[2]&2048&&!Ua(o);){let e=Yc(a,o,n,r|2,zc);if(e!==zc)return e;r&=-5;let t=a.parent;if(!t){let e=o[20];if(e){let t=e.get(n,zc,r);if(t!==zc)return t}t=al(o),o=o[14]}a=t}return i}function al(e){let t=e[1],n=t.type;return n===2?t.declTNode:n===1?e[5]:null}var ol=()=>(typeof requestIdleCallback<`u`?requestIdleCallback:e=>setTimeout(e)).bind(globalThis),sl=()=>(typeof requestIdleCallback<`u`?cancelIdleCallback:clearTimeout).bind(globalThis),cl=new j(``,{factory:()=>new ll}),ll=class{requestIdleCallback=ol();cancelIdleCallback=sl();requestOnIdle(e,t){return this.requestIdleCallback(e,t)}cancelOnIdle(e){return this.cancelIdleCallback(e)}};function ul(e){return{token:e.token,providedIn:e.autoProvided===!1?null:`root`,factory:e.factory,value:void 0}}function dl(){return fl(So(),P())}function fl(e,t){return new pl(Ja(e,t))}var pl=(()=>{class e{nativeElement;constructor(e){this.nativeElement=e}static __NG_ELEMENT_ID__=dl}return e})();function ml(e){return(e.flags&128)==128}var hl=(function(e){return e[e.OnPush=0]=`OnPush`,e[e.Eager=1]=`Eager`,e[e.Default=1]=`Default`,e})(hl||{}),gl=new Map,_l=0;function vl(){return _l++}function yl(e){gl.set(e[19],e)}function bl(e){gl.delete(e[19])}var xl=`__ngContext__`;function Sl(e,t){La(t)?(e[xl]=t[19],yl(t)):e[xl]=t}function Cl(e){return Tl(e[12])}function wl(e){return Tl(e[4])}function Tl(e){for(;e!==null&&!Ra(e);)e=e[4];return e}var El=void 0;function Dl(e){El=e}function Ol(){if(El!==void 0)return El;if(typeof document<`u`)return document;throw new A(210,!1)}var kl=!1,Al=new j(``,{factory:()=>kl}),jl=new j(``),Ml=new WeakMap;function Nl(e,t){if(typeof e!=`object`||!e)return;let n=Ml.get(e);n||(n=new WeakSet,Ml.set(e,n)),n.add(t)}var Pl=new j(``);function Fl(e){return(e.flags&32)==32}var Il=()=>null;function Ll(e,t,n=!1){return Il(e,t,n)}function Rl(e){return e.get(jl,!1,{optional:!0})}function zl(e,t){let n=e.contentQueries;if(n!==null){let r=k(null);try{for(let r=0;r|^->||--!>|)/g,ql=`​$1​`;function Jl(e){return e.replace(Gl,e=>e.replace(Kl,ql))}function Yl(e,t){return e.createText(t)}function Xl(e,t,n){e.setValue(t,n)}function Zl(e,t){return e.createComment(Jl(t))}function Ql(e,t,n){return e.createElement(t,n)}function $l(e,t,n,r,i){e.insertBefore(t,n,r,i)}function eu(e,t,n){e.appendChild(t,n)}function tu(e,t,n,r,i){r===null?eu(e,t,n):$l(e,t,n,r,i)}function nu(e,t,n,r){e.removeChild(null,t,n,r)}function ru(e,t,n){e.setAttribute(t,`style`,n)}function iu(e,t,n){n===``?e.removeAttribute(t,`class`):e.setAttribute(t,`class`,n)}function au(e,t,n){let{mergedAttrs:r,classes:i,styles:a}=n;r!==null&&Tc(e,t,r),i!==null&&iu(e,t,i),a!==null&&ru(e,t,a)}function ou(e,t,n){let r=e.length;for(;;){let i=e.indexOf(t,n);if(i===-1)return i;if(i===0||e.charCodeAt(i-1)<=32){let n=t.length;if(i+n===r||e.charCodeAt(i+n)<=32)return i}n=i+1}}var su=`ng-template`;function cu(e,t,n,r){let i=0;if(r){for(;i-1){let e;for(;++ia?``:i[u+1].toLowerCase(),r&2&&l!==e){if(fu(r))return!1;o=!0}}}}}return fu(r)||o}function fu(e){return!(e&1)}function pu(e,t,n,r){if(t===null)return-1;let i=0;if(r||!n){let n=!1;for(;i-1)for(n++;n0?`="`+t+`"`:``)+`]`}else r&8?i+=`.`+o:r&4&&(i+=` `+o)}else i!==``&&!fu(o)&&(t+=_u(a,i),i=``),r=o,a||=!fu(r);n++}return i!==``&&(t+=_u(a,i)),t}function yu(e){return e.map(vu).join(`,`)}function bu(e){let t=[],n=[],r=1,i=2;for(;r=0;e--){let{el:n,declarationView:s}=r[e],c=n.parentNode;n===t?(r.splice(e,1),Ou.add(n),n.dispatchEvent(new CustomEvent(`animationend`,{detail:{cancel:!0}}))):(a&&n===a||c&&i&&c!==i&&(o===null||s===null||o===s))&&(r.splice(e,1),n.dispatchEvent(new CustomEvent(`animationend`,{detail:{cancel:!0}})),n.parentNode?.removeChild(n))}}function Au(e,t,n){let r=Du(n),i=Eu.get(e);i?i.some(e=>e.el===t)||i.push({el:t,declarationView:r}):Eu.set(e,[{el:t,declarationView:r}])}var ju=(function(e){return e[e.CHANGE_DETECTION=0]=`CHANGE_DETECTION`,e[e.AFTER_NEXT_RENDER=1]=`AFTER_NEXT_RENDER`,e})(ju||{}),Mu=new j(``),Nu=new Set;function Pu(e){Nu.has(e)||(Nu.add(e),performance?.mark?.(`mark_feature_usage`,{detail:{feature:e}}))}var Fu=(()=>{class e{impl=null;execute(){this.impl?.execute()}static ɵprov=oi({token:e,providedIn:`root`,factory:()=>new e})}return e})(),Iu=new j(``,{factory:()=>{let e=M(Sa),t=new Set;return e.onDestroy(()=>t.clear()),{queue:t,isScheduled:!1,scheduler:null,injector:e}}});function Lu(e,t,n){let r=e.get(Iu);if(Array.isArray(t))for(let e of t)r.queue.add(e),n?.detachedLeaveAnimationFns?.push(e);else r.queue.add(t),n?.detachedLeaveAnimationFns?.push(t);r.scheduler&&r.scheduler(e)}function Ru(e,t){let n=e.get(Iu);if(Array.isArray(t))for(let e of t)n.queue.delete(e);else n.queue.delete(t)}function zu(e,t){let n=e.get(Iu);if(t.detachedLeaveAnimationFns){for(let e of t.detachedLeaveAnimationFns)n.queue.delete(e);t.detachedLeaveAnimationFns=void 0}}function Bu(e,t){for(let[n,r]of t)Lu(e,r.animateFns)}function Vu(e,t,n,r){let i=e?.[26]?.enter;t!==null&&i&&i.has(n.index)&&Bu(r,i)}function Hu(e,t,n,r){try{n.get(ia)}catch{return r(!1)}let i=e?.[26];i?.enter?.has(t.index)&&Ru(n,i.enter.get(t.index).animateFns);let a=Uu(e,t,i);if(a.size===0){let n=!1;if(e){let r=[];Gu(e,t,r),n=r.length>0}if(!n)return r(!1)}e&&Tu.add(e[19]),Lu(n,()=>Wu(e,t,i||void 0,a,r),i||void 0)}function Uu(e,t,n){let r=new Map,i=n?.leave;if(i&&i.has(t.index)&&r.set(t.index,i.get(t.index)),e&&i)for(let[n,a]of i){if(r.has(n))continue;let i=e[1].data[n].parent;for(;i;){if(i===t){r.set(n,a);break}i=i.parent}}return r}function Wu(e,t,n,r,i){let a=[];if(n&&n.leave)for(let[e]of r){if(!n.leave.has(e))continue;let t=n.leave.get(e);for(let e of t.animateFns){let{promise:t}=e();a.push(t)}n.detachedLeaveAnimationFns=void 0}if(e&&Gu(e,t,a),a.length>0){let t=n||e?.[26];if(t){let n=t.running;n&&a.push(n),t.running=Promise.allSettled(a),qu(e,t.running,i)}else Promise.allSettled(a).then(()=>{e&&Tu.delete(e[19]),i(!0)})}else e&&Tu.delete(e[19]),i(!1)}function Gu(e,t,n){if(t.type&12){let r=e[t.index];if(Ra(r))for(let e=10;e{e[26]?.running===t&&(e[26].running=void 0,Tu.delete(e[19])),n(!0)})}function Ju(e,t,n,r,i,a,o,s){if(i!=null){let c,l=!1;Ra(i)?c=i:La(i)&&(l=!0,i=i[0]);let u=Ka(i);e===0&&r!==null?(Vu(s,r,a,n),o==null?eu(t,r,u):$l(t,r,u,o||null,!0)):e===1&&r!==null?(Vu(s,r,a,n),$l(t,r,u,o||null,!0),ku(a,u,s)):e===2?(s?.[26]?.leave?.has(a.index)&&Au(a,u,s),Ou.delete(u),Hu(s,a,n,e=>{if(Ou.has(u)){Ou.delete(u);return}nu(t,u,l,e)})):e===3&&(Ou.delete(u),Hu(s,a,n,()=>{t.destroyNode(u)})),c!=null&&_d(t,e,n,c,a,r,o)}}function Yu(e,t){Zu(e,t),t[0]=null,t[5]=null}function Xu(e,t,n,r,i,a){r[0]=i,r[5]=t,md(e,r,n,1,i,a)}function Zu(e,t){t[10].changeDetectionScheduler?.notify(9),md(e,t,t[11],2,null,null)}function Qu(e){let t=e[12];if(!t)return td(e[1],e);for(;t;){let n=null;if(La(t))n=t[12];else{let e=t[10];e&&(n=e)}if(!n){for(;t&&!t[4]&&t!==e;)La(t)&&td(t[1],t),t=t[3];t===null&&(t=e),La(t)&&td(t[1],t),n=t&&t[4]}t=n}}function $u(e,t){let n=e[9],r=n.indexOf(t);n.splice(r,1)}function ed(e,t){if(Wa(t))return;let n=t[11];n.destroyNode&&md(e,t,n,3,null,null),Qu(t)}function td(e,t){if(Wa(t))return;let n=k(null);try{t[2]&=-129,t[2]|=256,t[24]&&xn(t[24]),rd(e,t),nd(e,t),t[1].type===1&&t[11].destroy();let n=t[16];if(n!==null&&Ra(t[3])){n!==t[3]&&$u(n,t);let r=t[18];r!==null&&r.detachView(e)}bl(t)}finally{k(n)}}function nd(e,t){let n=e.cleanup,r=t[7];if(n!==null)for(let e=0;e=0?r[t]():r[-t].unsubscribe(),e+=2}else{let t=r[n[e+1]];n[e].call(t)}r!==null&&(t[7]=null);let i=t[21];if(i!==null){t[21]=null;for(let e=0;e27&&Dd(e,t,27,!1),fc(o?R.TemplateUpdateStart:R.TemplateCreateStart,i,n),n(r,i)}finally{Zo(a),fc(o?R.TemplateUpdateEnd:R.TemplateCreateEnd,i,n)}}function jd(e,t,n){Rd(e,t,n),(n.flags&64)==64&&zd(e,t,n)}function Md(e,t,n=Ja){let r=t.localNames;if(r!==null){let i=t.index+1;for(let a=0;a{oo(e.lView)},consumerOnSignalRead(){this.lView[24]=this}};function uf(e){let t=e[24]??Object.create(df);return t.lView=e,t}var df={...cn,consumerIsAlwaysLive:!0,kind:`template`,consumerMarkedDirty:e=>{let t=lo(e.lView);for(;t&&!ff(t[1]);)t=lo(t);t&&no(t)},consumerOnSignalRead(){this.lView[24]=this}};function ff(e){return e.type!==2}function pf(e){if(e[23]===null)return;let t=!0;for(;t;){let n=!1;for(let t of e[23])if(t.dirty&&(n=!0,t.zone===null||Zone.current===t.zone?t.run():t.zone.run(()=>t.run()),e[23]===null))return;t=n&&!!(e[2]&8192)}}var mf=100;function hf(e,t=0){let n=e[10].rendererFactory;n.begin?.();try{gf(e,t)}finally{n.end?.()}}function gf(e,t){let n=Oo();try{ko(!0),Sf(e,t);let n=0;for(;io(e);){if(n===mf)throw new A(103,!1);n++,Sf(e,1)}}finally{ko(n)}}function _f(e,t,n,r){if(Wa(t))return;let i=t[2];Uo(t);let a=!0,o=null,s=null;ff(e)?(s=of(t),o=gn(s)):sn()===null?(a=!1,s=uf(t),o=gn(s)):t[24]&&=(xn(t[24]),null);try{to(t),Mo(e.bindingStartIndex),n!==null&&Ad(e,t,n,2,r);let a=(i&3)==3;if(a){let n=e.preOrderCheckHooks;n!==null&&hc(t,n,null)}else{let n=e.preOrderHooks;n!==null&&gc(t,n,0,null),_c(t,0)}if(yf(t),pf(t),vf(t,0),e.contentQueries!==null&&zl(e,t),a){let n=e.contentCheckHooks;n!==null&&hc(t,n)}else{let n=e.contentHooks;n!==null&&gc(t,n,1),_c(t,1)}wf(e,t);let o=e.components;o!==null&&Cf(t,o,0);let s=e.viewQuery;if(s!==null&&Bl(2,s,r),a){let n=e.viewCheckHooks;n!==null&&hc(t,n)}else{let n=e.viewHooks;n!==null&&gc(t,n,2),_c(t,2)}if(e.firstUpdatePass===!0&&(e.firstUpdatePass=!1),t[22]){for(let e of t[22])e();t[22]=null}rf(t),t[2]&=-73}catch(e){throw oo(t),e}finally{s!==null&&(vn(s,o),a&&cf(s)),Jo()}}function vf(e,t){for(let n=Cl(e);n!==null;n=wl(n))for(let e=10;e0&&(e[n-1][4]=r[4]);let a=Yi(e,10+t);Yu(r[1],r);let o=a[18];o!==null&&o.detachView(a[1]),r[3]=null,r[4]=null,r[2]&=-129}return r}function jf(e,t,n,r){let i=10+r,a=n.length;r>0&&(n[i-1][4]=t),r-1&&(Af(e,n),Yi(t,n))}this._attachedToViewContainer=!1}ed(this._lView[1],this._lView)}onDestroy(e){so(this._lView,e)}markForCheck(){Tf(this._cdRefInjectingView||this._lView,4)}detach(){this._lView[2]&=-129}reattach(){ao(this._lView),this._lView[2]|=128}detectChanges(){this._lView[2]|=1024,hf(this._lView)}checkNoChanges(){}attachToViewContainerRef(){if(this._appRef)throw new A(902,!1);this._attachedToViewContainer=!0}detachFromAppRef(){this._appRef=null;let e=Ua(this._lView),t=this._lView[16];t!==null&&!e&&$u(t,this._lView),Zu(this._lView[1],this._lView)}attachToAppRef(e){if(this._attachedToViewContainer)throw new A(902,!1);this._appRef=e;let t=Ua(this._lView),n=this._lView[16];n!==null&&!t&&Mf(n,this._lView),ao(this._lView)}};function Pf(e,t,n,r,i){let a=e.data[t];if(a===null)a=Ff(e,t,n,r,i),Fo()&&(a.flags|=32);else if(a.type&64){a.type=n,a.value=r,a.attrs=i;let e=wo();a.injectorIndex=e===null?-1:e.injectorIndex}return To(a,!0),a}function Ff(e,t,n,r,i){let a=Co(),o=Eo(),s=o?a:a&&a.parent,c=e.data[t]=Lf(e,s,n,t,r,i);return If(e,c,a,o),c}function If(e,t,n,r){e.firstChild===null&&(e.firstChild=t),n!==null&&(r?n.child==null&&t.parent!==null&&(n.child=t):n.next===null&&(n.next=t,t.prev=n))}function Lf(e,t,n,r,i,a){let o=t?t.injectorIndex:-1,s=0;return vo()&&(s|=128),{type:n,index:r,insertBeforeIndex:null,injectorIndex:o,directiveStart:-1,directiveEnd:-1,directiveStylingLast:-1,componentOffset:-1,controlDirectiveIndex:-1,customControlIndex:-1,propertyBindings:null,flags:s,providerIndexes:0,value:i,namespace:ns(),attrs:a,mergedAttrs:null,localNames:null,initialInputs:null,inputs:null,hostDirectiveInputs:null,outputs:null,hostDirectiveOutputs:null,directiveToIndex:null,tView:null,next:null,prev:null,projectionNext:null,child:null,parent:t,projection:null,styles:null,stylesWithoutHost:null,residualStyles:void 0,classes:null,classesWithoutHost:null,residualClasses:void 0,classBindings:0,styleBindings:0}}function Rf(e){let t=e[6]??[],n=e[3][11],r=[];for(let e of t)e.data.di===void 0?zf(e,n):r.push(e);e[6]=r}function zf(e,t){let n=0,r=e.firstChild;if(r){let i=e.data.r;for(;nnull,Vf=()=>null;function Hf(e,t){return Bf(e,t)}function Uf(e,t,n){return Vf(e,t,n)}var Wf=class{},Gf=class{},Kf=(()=>{class e{static ɵprov=oi({token:e,providedIn:`root`,factory:()=>null})}return e})();function qf(e){return e.debugInfo?.className||e.type.name||null}var Jf={},Yf=class{injector;parentInjector;constructor(e,t){this.injector=e,this.parentInjector=t}get(e,t,n){let r=this.injector.get(e,Jf,n);return r!==Jf||t===Jf?r:this.parentInjector.get(e,t,n)}};function Xf(e,t,n){return e[t]=n}function Zf(e,t){return e[t]}function Qf(e,t,n){if(n===xu)return!1;let r=e[t];return!Object.is(r,n)&&(e[t]=n,!0)}function $f(e,t,n,r){let i=Qf(e,t,n);return Qf(e,t+1,r)||i}function ep(e,t,n,r,i){let a=$f(e,t,n,r);return Qf(e,t+2,i)||a}function tp(e,t,n){return function r(i){let a=r.__ngNativeEl__;a!==void 0&&Nl(i,a),Tf(Ba(e)?Qa(e.index,t):t,5);let o=t[8],s=np(t,o,n,i),c=r.__ngNextListenerFn__;for(;c;)s=np(t,o,c,i)&&s,c=c.__ngNextListenerFn__;return s}}function np(e,t,n,r){let i=k(null);try{return fc(R.OutputStart,t,n),n(r)!==!1}catch(t){return qd(e,t),!1}finally{fc(R.OutputEnd,t,n),k(i)}}function rp(e,t,n,r,i,a,o,s){let c=Va(e),l=!1,u=null;if(!r&&c&&(u=ap(t,n,a,e.index)),u!==null){let e=u.__ngLastListenerFn__||u;e.__ngNextListenerFn__=o,u.__ngLastListenerFn__=o,l=!0}else{let o=Ja(e,n),c=r?r(o):o;r||(s.__ngNativeEl__=o);let l=i.listen(c,a,s);ip(a)||op(r?t=>r(Ka(t[e.index])):e.index,t,n,a,s,l,!1)}return l}function ip(e){return e.startsWith(`animation`)||e.startsWith(`transition`)}function ap(e,t,n,r){let i=e.cleanup;if(i!=null)for(let e=0;er?n[r]:null}typeof a==`string`&&(e+=2)}return null}function op(e,t,n,r,i,a,o){let s=t.firstCreatePass?fo(t):null,c=uo(n),l=c.length;c.push(i,a),s&&s.push(r,e,l,(l+1)*(o?-1:1))}function sp(e,t,n,r,i,a){let o=t[n],s=t[1],c=o[s.data[n].outputs[r]].subscribe(a);op(e.index,s,t,i,a,c,!0)}var cp=Symbol(`BINDING`),lp=new j(``);function up(e,t,n){let r=n?e.styles:null,i=n?e.classes:null,a=0;if(t!==null)for(let e=0;e0&&(n.directiveToIndex=new Map);for(let c=0;c0;){let n=e[--t];if(typeof n==`number`&&n<0)return n}return 0}function wp(e,t,n){if(n){if(t.exportAs)for(let r=0;r{let[n,r,i]=e[t],a={propName:n,templateName:t,isSignal:(r&Od.SignalBased)!==0};return i&&(a.transform=i),a})}function Mp(e){return Object.keys(e).map(t=>({propName:e[t],templateName:t}))}function Np(e,t,n){let r=t instanceof Sa?t:t?.injector;return r&&e.getStandaloneInjector!==null&&(r=e.getStandaloneInjector(r)||r),r?new Yf(n,r):n}function Pp(e){let t=e.get(Gf,null);if(t===null)throw new A(407,!1);return{rendererFactory:t,sanitizer:e.get(Kf,null),changeDetectionScheduler:e.get(Gs,null),ngReflect:!1,tracingService:e.get(Mu,null,{optional:!0})}}function Fp(e,t,n){let r=Lp(e);return Ql(t,r,r===`svg`?`svg`:r===`math`?Ga:n)}function Ip(e){if((e&&`localName`in e&&typeof e.localName==`string`?e.localName:e?.tagName)?.toLowerCase()===`script`)throw new A(905,!1)}function Lp(e){return(e.selectors[0][0]||`div`).toLowerCase()}var Rp=class{componentDef;ngModule;selector;componentType;ngContentSelectors;isBoundToModule;cachedInputs=null;cachedOutputs=null;get inputs(){return this.cachedInputs??=jp(this.componentDef.inputs),this.cachedInputs}get outputs(){return this.cachedOutputs??=Mp(this.componentDef.outputs),this.cachedOutputs}constructor(e,t){this.componentDef=e,this.ngModule=t,this.componentType=e.type,this.selector=yu(e.selectors),this.ngContentSelectors=e.ngContentSelectors??[],this.isBoundToModule=!!t}create(e,t,n,r,i,a,o){fc(R.DynamicComponentStart);let s=k(null);try{let s=this.componentDef,c=Np(s,r||this.ngModule,e),l=Pp(c),u=l.tracingService;return u&&u.componentCreate?u.componentCreate(qf(s),()=>this.createComponentRef(l,c,t,n,i,a,o)):this.createComponentRef(l,c,t,n,i,a,o)}finally{k(s)}}createComponentRef(e,t,n,r,i,a,o){let s=this.componentDef,c=zp(r,s,a,i),l=e.rendererFactory.createRenderer(null,s),u=r?Nd(l,r,s.encapsulation,t):Fp(s,l,o??null);Ip(u);let d=t.get(lp,null),f=Bp(u,()=>t.get(ls,null)??Ol());d&&d.addHost(f);let p=a?.some(Hp)||i?.some(e=>typeof e!=`function`&&e.bindings.some(Hp)),m=Sd(null,c,null,512|wd(s),null,null,e,l,t,null,Ll(u,t,!0));d&&kp&&f instanceof ShadowRoot&&so(m,()=>{d.removeHost(f)}),m[27]=u,Uo(m);let h=null;try{let e=Ep(27,m,2,`#host`,()=>c.directiveRegistry,!0,0);au(l,u,e),Sl(u,m),jd(c,m,e),Vl(c,e,m),Dp(c,e),n!==void 0&&Wp(e,this.ngContentSelectors,n),h=Qa(e.index,m),m[8]=h[8],Zd(c,m,null)}catch(e){throw h!==null&&bl(h),bl(m),e}finally{fc(R.DynamicComponentEnd),Jo()}return new Up(this.componentType,m,!!p)}};function zp(e,t,n,r){let i=e?[`ng-version`,`22.1.7`]:bu(t.selectors[0]),a=null,o=null,s=0;if(n)for(let e of n)s+=e[cp].requiredVars,e.create&&(e.targetIdx=0,(a??=[]).push(e)),e.update&&(e.targetIdx=0,(o??=[]).push(e));if(r)for(let e=0;e{if(n&1&&e)for(let t of e)t.create();if(n&2&&t)for(let e of t)e.update()}}function Hp(e){let t=e[cp].kind;return t===`input`||t===`twoWay`}var Up=class extends Wf{_rootLView;_hasInputBindings;instance;hostView;changeDetectorRef;componentType;location;previousInputValues=null;_tNode;constructor(e,t,n){super(),this._rootLView=t,this._hasInputBindings=n,this._tNode=Ya(t[1],27),this.location=fl(this._tNode,t),this.instance=Qa(this._tNode.index,t)[8],this.hostView=this.changeDetectorRef=new Nf(t,void 0),this.componentType=e}setInput(e,t){this._hasInputBindings;let n=this._tNode;if(this.previousInputValues??=new Map,this.previousInputValues.has(e)&&Object.is(this.previousInputValues.get(e),t))return;let r=this._rootLView;Jd(n,r[1],r,e,t),this.previousInputValues.set(e,t),Tf(Qa(n.index,r),1)}get injector(){return new nl(this._tNode,this._rootLView)}destroy(){this.hostView.destroy()}onDestroy(e){this.hostView.onDestroy(e)}};function Wp(e,t,n){let r=e.projection=[];for(let e=0;e!1;function Kp(e,t,n){return Gp(e,t,n)}function qp(e){return!!e&&typeof e.then==`function`}function Jp(e){return!!e&&typeof e.subscribe==`function`}var Yp=class{},Xp=class extends Yp{injector;instance=null;constructor(e){super();let t=new Ca([...e.providers,{provide:Yp,useValue:this}],e.parent||xa(),e.debugName,new Set([`environment`]));this.injector=t,e.runEnvironmentInitializers&&t.resolveInjectorInitializers()}destroy(){this.injector.destroy()}onDestroy(e){this.injector.onDestroy(e)}};function Zp(e,t,n=null){return new Xp({providers:e,parent:t,debugName:n,runEnvironmentInitializers:!0}).injector}var Qp=(()=>{class e{_injector;cachedInjectors=new Map;constructor(e){this._injector=e}getOrCreateStandaloneInjector(e){if(!e.standalone)return null;if(!this.cachedInjectors.has(e)){let t=ca(!1,e.type),n=t.length>0?Zp([t],this._injector,``):null;this.cachedInjectors.set(e,n)}return this.cachedInjectors.get(e)}ngOnDestroy(){try{for(let e of this.cachedInjectors.values())e!==null&&e.destroy()}finally{this.cachedInjectors.clear()}}static ɵprov=oi({token:e,providedIn:`environment`,factory:()=>new e(Vi(Sa))})}return e})();function $p(e){return sc(()=>{let t=im(e),n={...t,decls:e.decls,vars:e.vars,template:e.template,consts:e.consts||null,ngContentSelectors:e.ngContentSelectors,onPush:e.changeDetection!==hl.Eager,directiveDefs:null,pipeDefs:null,dependencies:t.standalone&&e.dependencies||null,getStandaloneInjector:t.standalone?e=>e.get(Qp).getOrCreateStandaloneInjector(n):null,getExternalStyles:null,signals:e.signals??!1,data:e.data||{},encapsulation:e.encapsulation||Hl.Emulated,styles:e.styles||na,_:null,schemas:e.schemas||null,tView:null,id:``};t.standalone&&Pu(`NgStandalone`),am(n);let r=e.dependencies;return n.directiveDefs=om(r,em),n.pipeDefs=om(r,Si),n.id=sm(n),n})}function em(e){return bi(e)||xi(e)}function tm(e,t){if(e==null)return ta;let n={};for(let r in e)if(Object.hasOwn(e,r)){let i=e[r],a,o,s,c;Array.isArray(i)?(s=i[0],a=i[1],o=i[2]??a,c=i[3]||null):(a=i,o=i,s=Od.None,c=null),n[a]=[r,s,c],t[a]=o}return n}function nm(e){if(e==null)return ta;let t={};for(let n in e)Object.hasOwn(e,n)&&(t[e[n]]=n);return t}function rm(e){return{type:e.type,name:e.name,factory:null,pure:e.pure!==!1,standalone:e.standalone??!0,onDestroy:e.type.prototype.ngOnDestroy||null}}function im(e){let t={};return{type:e.type,providersResolver:null,viewProvidersResolver:null,factory:null,hostBindings:e.hostBindings||null,hostVars:e.hostVars||0,hostAttrs:e.hostAttrs||null,contentQueries:e.contentQueries||null,declaredInputs:t,inputConfig:e.inputs||ta,exportAs:e.exportAs||null,standalone:e.standalone??!0,signals:e.signals===!0,selectors:e.selectors||na,viewQuery:e.viewQuery||null,features:e.features||null,setInput:null,resolveHostDirectives:null,hostDirectives:null,controlDef:null,signalFormsInputPresence:null,inputs:tm(e.inputs,t),outputs:nm(e.outputs),debugInfo:null}}function am(e){e.features?.forEach(t=>t(e))}function om(e,t){return e?()=>{let n=typeof e==`function`?e():e,r=[];for(let e of n){let n=t(e);n!==null&&r.push(n)}return r}:null}function sm(e){let t=0,n=typeof e.consts==`function`?``:e.consts,r=[e.selectors,e.ngContentSelectors,e.hostVars,e.hostAttrs,n,e.vars,e.decls,e.encapsulation,e.standalone,e.signals,e.exportAs,JSON.stringify(e.inputs),JSON.stringify(e.outputs),Object.getOwnPropertyNames(e.type.prototype),!!e.contentQueries,!!e.viewQuery];for(let e of r.join(`|`))t=Math.imul(31,t)+e.charCodeAt(0)<<0;return t+=2147483648,`c`+t}var cm=new j(``),lm=(()=>{class e{resolve;reject;initialized=!1;done=!1;donePromise=new Promise((e,t)=>{this.resolve=e,this.reject=t});appInits=M(cm,{optional:!0})??[];injector=M(cs);constructor(){}runInitializers(){if(this.initialized)return;let e=[];for(let t of this.appInits){let n=Pa(this.injector,t);if(qp(n))e.push(n);else if(Jp(n)){let t=new Promise((e,t)=>{n.subscribe({complete:e,error:t})});e.push(t)}}let t=()=>{this.done=!0,this.resolve()};Promise.all(e).then(()=>{t()}).catch(e=>{this.reject(e)}),e.length===0&&t(),this.initialized=!0}static ɵfac=function(t){return new(t||e)};static ɵprov=ul({token:e,factory:e.ɵfac})}return e})();function um(e,t,n,r,i,a,o,s){if(n.firstCreatePass){e.mergedAttrs=Oc(e.mergedAttrs,e.attrs);let t=e.tView=yd(2,e,i,a,o,n.directiveRegistry,n.pipeRegistry,null,n.schemas,n.consts,null);n.queries!==null&&(n.queries.template(n,e),t.queries=n.queries.embeddedTView(e))}s&&(e.flags|=s),To(e,!1);let c=pm(n,t,e,r);is()&&ld(n,t,c,e),Sl(c,t);let l=Ef(c,t,c,e);t[r+27]=l,Ed(t,l),Kp(l,e,t)}function dm(e,t,n,r,i,a,o,s,c,l,u){let d=n+27,f;if(t.firstCreatePass){if(f=Pf(t,d,4,o||null,s||null),l!=null){let e=eo(t.consts,l);f.localNames=[];for(let t=0;t{class e{cachedInjectors=new Map;getOrCreateInjector(e,t,n,r){if(!this.cachedInjectors.has(e)){let i=n.length>0?Zp(n,t,r):null;this.cachedInjectors.set(e,i)}return this.cachedInjectors.get(e)}ngOnDestroy(){try{for(let e of this.cachedInjectors.values())e!==null&&e.destroy()}finally{this.cachedInjectors.clear()}}static ɵprov=oi({token:e,providedIn:`environment`,factory:()=>new e})}return e})(),Um=new j(``);function Wm(e,t,n){return e.get(Hm).getOrCreateInjector(t,e,n,``)}function Gm(e,t,n){if(e instanceof Yf){let r=e.injector,i=e.parentInjector;return new Yf(r,Wm(i,t,n))}let r=e.get(Sa);return r===e?Wm(e,t,n):new Yf(e,Wm(r,t,n))}function Km(e,t,n,r=!1){let i=n[3],a=i[1];if(Wa(i))return;let o=Nm(i,t),s=o[1],c=o[wm];if(!(c!==null&&ee.data.s===t[1])??-1;return{dehydratedView:n>-1?e[6][n]:null,dehydratedViewIx:n}}function Jm(e,t,n,r,i){fc(R.DeferBlockStateStart);let a=Lm(e,i,r);if(a!==null){t[1]=e;let o=i[1],s=Ya(o,a+27);kf(n,0);let c;if(e===vm.Complete){let e=Fm(o,r),t=e.providers;t&&t.length>0&&(c=Gm(i[9],e,t))}let{dehydratedView:l,dehydratedViewIx:u}=qm(n,t),d=$d(i,s,null,{injector:c,dehydratedView:l});if(Of(n,d,0,ef(s,l)),no(d),u>-1&&n[6]?.splice(u,1),(e===vm.Complete||e===vm.Error)&&Array.isArray(t[Tm])){for(let e of t[Tm])e();t[Tm]=null}}fc(R.DeferBlockStateEnd)}function Ym(e,t){return e{e.loadingState===hm.COMPLETE?Km(vm.Complete,t,n):e.loadingState===hm.FAILED&&Km(vm.Error,t,n)})}var Qm=null;function $m(e,t){return t[9].get(Um,null,{optional:!0})?.behavior!==Dm.Manual}var eh=new j(``),th=new j(``);function nh(){Fn(()=>{throw new A(600,``)})}var rh=10,ih=(()=>{class e{_runningTick=!1;_destroyed=!1;_destroyListeners=[];_views=[];internalErrorHandler=M(Fs);afterRenderManager=M(Fu);zonelessEnabled=M(Ks);rootEffectScheduler=M(Js);dirtyFlags=0;tracingSnapshot=null;allTestViews=new Set;autoDetectTestViews=new Set;includeAllTestViews=!1;afterTick=new Kr;get allViews(){return[...(this.includeAllTestViews?this.allTestViews:this.autoDetectTestViews).keys(),...this._views]}get destroyed(){return this._destroyed}componentTypes=[];components=[];internalPendingTask=M(ms);get isStable(){return this.internalPendingTask.hasPendingTasksObservable.pipe(Yr(e=>!e))}constructor(){M(Mu,{optional:!0})}whenStable(){let e;return new Promise(t=>{e=this.isStable.subscribe({next:e=>{e&&t()}})}).finally(()=>{e.unsubscribe()})}_injector=M(Sa);_rendererFactory=null;get injector(){return this._injector}bootstrap(e,t){return this.bootstrapImpl(e,t)}bootstrapImpl(e,t,n=cs.NULL){return this._injector.get(Ss).run(()=>{if(fc(R.BootstrapComponentStart),!this._injector.get(lm).done)throw new A(405,``);let r=bi(e),i=this._injector.get(Yp),a=new Rp(r,i);this.componentTypes.push(e);let{hostElement:o,directives:s,bindings:c}=ah(t),l=o||a.selector,u=a.create(n,[],l,i.injector,s,c),d=u.location.nativeElement,f=u.injector.get(eh,null);return f?.registerApplication(d),u.onDestroy(()=>{this.detachView(u.hostView),oh(this.components,u),f?.unregisterApplication(d)}),this._loadComponent(u),fc(R.BootstrapComponentEnd,u),u})}tick(){this.zonelessEnabled||(this.dirtyFlags|=1),this._tick()}_tick(){fc(R.ChangeDetectionStart),this.tracingSnapshot===null?this.tickImpl():this.tracingSnapshot.run(ju.CHANGE_DETECTION,this.tickImpl)}tickImpl=()=>{if(this._runningTick)throw fc(R.ChangeDetectionEnd),new A(101,!1);let e=k(null);try{this._runningTick=!0,this.synchronize()}finally{this._runningTick=!1,this.tracingSnapshot?.dispose(),this.tracingSnapshot=null,k(e),this.afterTick.next(),fc(R.ChangeDetectionEnd)}};synchronize(){this._rendererFactory===null&&!this._injector.destroyed&&(this._rendererFactory=this._injector.get(Gf,null,{optional:!0}));let e=0;for(;this.dirtyFlags!==0&&e++io(e))){this.dirtyFlags|=2;return}this.dirtyFlags&=-8}attachView(e){let t=e;this._views.push(t),t.attachToAppRef(this)}detachView(e){let t=e;oh(this._views,t),t.detachFromAppRef()}_loadComponent(e){this.attachView(e.hostView);try{this.tick()}catch(e){this.internalErrorHandler(e)}this.components.push(e),this._injector.get(th,[]).forEach(t=>t(e))}ngOnDestroy(){if(!this._destroyed)try{this._destroyListeners.forEach(e=>e()),this._views.slice().forEach(e=>e.destroy())}finally{this._destroyed=!0,this._views=[],this._destroyListeners=[]}}onDestroy(e){return this._destroyListeners.push(e),()=>oh(this._destroyListeners,e)}destroy(){if(this._destroyed)throw new A(406,!1);let e=this._injector;e.destroy&&!e.destroyed&&e.destroy()}get viewCount(){return this._views.length}static ɵfac=function(t){return new(t||e)};static ɵprov=ul({token:e,factory:e.ɵfac})}return e})();function ah(e){return e===void 0||typeof e==`string`||e instanceof Element?{hostElement:e}:e}function oh(e,t){let n=e.indexOf(t);n>-1&&e.splice(n,1)}function sh(e,t,n){let r=t.get(lh);return r.add(e,n),()=>r.remove(e)}function ch(e){return(t,n)=>sh(t,n,e)}var lh=(()=>{class e{buckets=new Map;callbackBucket=new Map;applicationRef=M(ih);ngZone=M(Ss);idleService=M(cl);add(e,t){let n=uh(t);this.callbackBucket.set(e,n);let r=this.buckets.get(n);r??(r={idleId:null,queue:new Set},this.buckets.set(n,r)),r.queue.add(e),this.scheduleBucket(r,t)}remove(e){let t=this.callbackBucket.get(e);if(t===void 0)return;this.callbackBucket.delete(e);let n=this.buckets.get(t);n&&(n.queue.delete(e),n.queue.size===0&&(this.cancelBucket(n),this.buckets.delete(t)))}scheduleBucket(e,t){if(e.idleId!==null)return;let n=uh(t),r=r=>{for(let t of e.queue)if(t(),this.applicationRef._tick(),e.queue.delete(t),this.callbackBucket.delete(t),r&&r.timeRemaining()===0&&!r.didTimeout)break;e.idleId=null,e.queue.size>0?this.scheduleBucket(e,t):this.buckets.delete(n)};e.idleId=this.idleService.requestOnIdle(e=>this.ngZone.run(()=>r(e)),t)}cancelBucket(e){e.idleId!==null&&(this.idleService.cancelOnIdle(e.idleId),e.idleId=null)}ngOnDestroy(){for(let e of this.buckets.values())this.cancelBucket(e);this.buckets.clear(),this.callbackBucket.clear()}static ɵprov=oi({token:e,providedIn:`root`,factory:()=>new e})}return e})();function uh(e){return!e||e.timeout==null?``:`${e.timeout}`}function dh(e){let t=P(),n=So();if(Xm(t,n),!$m(0,t))return;let r=t[9];Om(0,Nm(t,n),e(()=>ph(0,t,n),r))}function fh(e,t,n){let r=t[9],i=t[1];if(e.loadingState!==hm.NOT_STARTED)return e.loadingPromise??Promise.resolve();let a=Nm(t,n),o=Vm(i,e);e.loadingState=hm.IN_PROGRESS,km(1,a);let s=e.dependencyResolverFn,c=r.get(ic).add();return s?(e.loadingPromise=Promise.allSettled(s()).then(n=>{let r=!1,i=[],a=[];for(let e=0;e0&&(t.directiveRegistry=Bm(t.directiveRegistry,i),e.providers=ca(!1,...i.map(e=>e.type))),a.length>0&&(t.pipeRegistry=Bm(t.pipeRegistry,a))}}),e.loadingPromise.finally(()=>{e.loadingPromise=null,c()})):(e.loadingPromise=Promise.resolve().then(()=>{e.loadingPromise=null,e.loadingState=hm.COMPLETE,c()}),e.loadingPromise)}function ph(e,t,n){let r=t[1],i=t[n.index];if(!$m(e,t))return;let a=Nm(t,n),o=Fm(r,n);switch(Am(a),o.loadingState){case hm.NOT_STARTED:Km(vm.Loading,n,i),fh(o,t,n),o.loadingState===hm.IN_PROGRESS&&Zm(o,n,i);break;case hm.IN_PROGRESS:Km(vm.Loading,n,i),Zm(o,n,i);break;case hm.COMPLETE:Km(vm.Complete,n,i);break;case hm.FAILED:Km(vm.Error,n,i)}}function mh(e,t,n){return e===0?gh(t,n):e!==2||!gh(t,n)}function hh(e){return e!=null&&(e&1)==1}function gh(e,t){let n=e[9],r=Fm(e[1],t),i=Rl(n),a=hh(r.flags),o=Nm(e,t)[Cm]!==null;return!(a&&o&&i)}function _h(e,t,n,r,i,a,o,s,c,l){let u=P(),d=xo(),f=e+27,p=dm(u,d,e,null,0,0),m=u[9],h=Rl(m);if(d.firstCreatePass){Pu(`NgDefer`);let e={primaryTmplIndex:t,loadingTmplIndex:r??null,placeholderTmplIndex:i??null,errorTmplIndex:a??null,placeholderBlockConfig:null,loadingBlockConfig:null,dependencyResolverFn:n??null,loadingState:hm.NOT_STARTED,loadingPromise:null,providers:null,hydrateTriggers:null,debug:null,flags:l??0};c?.(d,e,s,o),Im(d,f,e)}let g=u[f];Kp(g,p,u);let _=null,v=null;if(g[6]?.length>0){let e=g[6][0].data;v=e.di??null,_=e.s}let y=[null,ym.Initial,null,null,null,null,v,_,null,null];Pm(u,f,y);let b=null;v!==null&&h&&(b=m.get(Pl),b.add(v,{lView:u,tNode:p,lContainer:g}));let ee=()=>{Am(y),v!==null&&b?.cleanup([v])};Om(0,y,()=>co(u,ee)),so(u,ee)}function vh(e){mh(0,P(),So())&&dh(ch({timeout:e}))}function B(e,t,n,r){let i=P();return Qf(i,No(),t)&&(xo(),Hd(Qo(),i,e,t,n,r)),B}var yh=class{destroy(e){}updateValue(e,t){}swap(e,t){let n=Math.min(e,t),r=Math.max(e,t),i=this.detach(r);if(r-n>1){let e=this.detach(n);this.attach(n,i),this.attach(r,e)}else this.attach(n,i)}move(e,t){this.attach(t,this.detach(e))}};function bh(e,t,n,r,i){return e===n&&Object.is(t,r)?1:Object.is(i(e,t),i(n,r))?-1:0}function xh(e,t,n,r){let i,a,o=0,s=e.length-1;if(Array.isArray(t)){k(r);let c=t.length-1;for(k(null);o<=s&&o<=c;){let r=e.at(o),l=t[o],u=bh(o,r,o,l,n);if(u!==0){u<0&&e.updateValue(o,l),o++;continue}let d=e.at(s),f=t[c],p=bh(s,d,c,f,n);if(p!==0){p<0&&e.updateValue(s,f),s--,c--;continue}let m=n(o,r),h=n(s,d),g=n(o,l);if(Object.is(g,h)){let t=n(c,f);Object.is(t,m)?(e.swap(o,s),e.updateValue(s,f),c--,s--):e.move(s,o),e.updateValue(o,l),o++;continue}if(i??=new Th,a??=wh(e,o,s,n),Sh(e,i,o,g))e.updateValue(o,l),o++,s++;else if(a.has(g))i.set(m,e.detach(o)),s--;else{let n=e.create(o,t[o]);e.attach(o,n),o++,s++}}for(;o<=c;)Ch(e,i,n,o,t[o]),o++}else if(t!=null){k(r);let c=t[Symbol.iterator]();k(null);let l=c.next();for(;!l.done&&o<=s;){let t=e.at(o),r=l.value,u=bh(o,t,o,r,n);if(u!==0)u<0&&e.updateValue(o,r),o++,l=c.next();else{i??=new Th,a??=wh(e,o,s,n);let u=n(o,r);if(Sh(e,i,o,u))e.updateValue(o,r),o++,s++,l=c.next();else if(!a.has(u))e.attach(o,e.create(o,r)),o++,s++,l=c.next();else{let r=n(o,t);i.set(r,e.detach(o)),s--}}}for(;!l.done;)Ch(e,i,n,e.length,l.value),l=c.next()}for(;o<=s;)e.destroy(e.detach(s--));i?.forEach(t=>{e.destroy(t)})}function Sh(e,t,n,r){return t!==void 0&&t.has(r)?(e.attach(n,t.get(r)),t.delete(r),!0):!1}function Ch(e,t,n,r,i){if(Sh(e,t,r,n(r,i)))e.updateValue(r,i);else{let t=e.create(r,i);e.attach(r,t)}}function wh(e,t,n,r){let i=new Set;for(let a=t;a<=n;a++)i.add(r(a,e.at(a)));return i}var Th=class{kvMap=new Map;_vMap=void 0;has(e){return this.kvMap.has(e)}delete(e){if(!this.has(e))return!1;let t=this.kvMap.get(e);return this._vMap!==void 0&&this._vMap.has(t)?(this.kvMap.set(e,this._vMap.get(t)),this._vMap.delete(t)):this.kvMap.delete(e),!0}get(e){return this.kvMap.get(e)}set(e,t){if(this.kvMap.has(e)){let n=this.kvMap.get(e);this._vMap===void 0&&(this._vMap=new Map);let r=this._vMap;for(;r.has(n);)n=r.get(n);r.set(n,t)}else this.kvMap.set(e,t)}forEach(e){for(let[t,n]of this.kvMap)if(e(n,t),this._vMap!==void 0){let r=this._vMap;for(;r.has(n);)n=r.get(n),e(n,t)}}};function V(e,t,n,r,i,a,o,s){Pu(`NgControlFlow`);let c=P(),l=xo();return dm(c,l,e,t,n,r,i,eo(l.consts,a),256,o,s),Eh}function Eh(e,t,n,r,i,a,o,s){Pu(`NgControlFlow`);let c=P(),l=xo();return dm(c,l,e,t,n,r,i,eo(l.consts,a),512,o,s),Eh}function H(e,t){Pu(`NgControlFlow`);let n=P(),r=No(),i=n[r]===xu?-1:n[r],a=i===-1?void 0:Mh(n,27+i);if(Qf(n,r,e)){let r=k(null);try{if(a!==void 0&&kf(a,0),e!==-1){let r=27+e,i=Mh(n,r),a=Lh(n[1],r),o=Uf(i,a,n);Of(i,$d(n,a,t,{dehydratedView:o}),0,ef(a,o))}}finally{k(r)}}else if(a!==void 0){let e=Df(a,0);e!==void 0&&(e[8]=t)}}var Dh=class{lContainer;$implicit;$index;constructor(e,t,n){this.lContainer=e,this.$implicit=t,this.$index=n}get $count(){return this.lContainer.length-10}};function Oh(e){return e}function kh(e,t){return t}var Ah=class{hasEmptyBlock;trackByFn;liveCollection;constructor(e,t,n){this.hasEmptyBlock=e,this.trackByFn=t,this.liveCollection=n}};function U(e,t,n,r,i,a,o,s,c,l,u,d,f){Pu(`NgControlFlow`);let p=P(),m=xo(),h=c!==void 0,g=P(),_=new Ah(h,s?o.bind(g[15][8]):o);g[27+e]=_,dm(p,m,e+1,t,n,r,i,eo(m.consts,a),256),h&&dm(p,m,e+2,c,l,u,d,eo(m.consts,f),512)}var jh=class extends yh{lContainer;hostLView;templateTNode;operationsCounter=void 0;needsIndexUpdate=!1;constructor(e,t,n){super(),this.lContainer=e,this.hostLView=t,this.templateTNode=n}get length(){return this.lContainer.length-10}at(e){return this.getLView(e)[8].$implicit}attach(e,t){let n=t[6];this.needsIndexUpdate||=e!==this.length,Of(this.lContainer,t,e,ef(this.templateTNode,n)),Nh(this.lContainer,e)}detach(e){return this.needsIndexUpdate||=e!==this.length-1,Ph(this.lContainer,e),Fh(this.lContainer,e)}create(e,t){let n=Hf(this.lContainer,this.templateTNode.tView.ssrId);return $d(this.hostLView,this.templateTNode,new Dh(this.lContainer,t,e),{dehydratedView:n})}destroy(e){ed(e[1],e)}updateValue(e,t){this.getLView(e)[8].$implicit=t}reset(){this.needsIndexUpdate=!1}updateIndexes(){if(this.needsIndexUpdate)for(let e=0;e0){let e=n[9];zu(e,r),Tu.delete(n[19]),r.detachedLeaveAnimationFns=void 0}}function Ph(e,t){if(e.length<=10)return;let n=e[10+t],r=n?n[26]:void 0;r&&r.leave&&r.leave.size>0&&(r.detachedLeaveAnimationFns=[])}function Fh(e,t){return Af(e,t)}function Ih(e,t){return Df(e,t)}function Lh(e,t){return Ya(e,t)}function Rh(e,t,n){let r=P();return Qf(r,No(),t)&&(xo(),Fd(Qo(),r,e,t,r[11],n)),Rh}function zh(e,t,n,r,i){Jd(t,e,n,i?`class`:`style`,r)}function G(e,t,n,r){let i=P(),a=i[1],o=e+27,s=a.firstCreatePass?Ep(o,i,2,t,Vd,_o(),n,r):a.data[o];if(Ba(s)){let n=i[10].tracingService;if(n&&n.componentCreate){let o=a.data[s.directiveStart+s.componentOffset];return n.componentCreate(qf(o),()=>(Bh(e,t,i,s,r),G))}}return Bh(e,t,i,s,r),G}function Bh(e,t,n,r,i){if(Gd(r,n,e,t,Uh),Va(r)){let e=n[1];jd(e,n,r),Vl(e,r,n)}i!=null&&Md(n,r)}function K(){let e=xo(),t=Kd(So());return e.firstCreatePass&&Dp(e,t),yo(t)&&bo(),go(),t.classesWithoutHost!=null&&Cc(t)&&zh(e,t,P(),t.classesWithoutHost,!0),t.stylesWithoutHost!=null&&wc(t)&&zh(e,t,P(),t.stylesWithoutHost,!1),K}function Vh(e,t,n,r){return G(e,t,n,r),K(),Vh}function q(e,t,n,r){let i=P(),a=i[1],o=e+27,s=a.firstCreatePass?Op(o,a,2,t,n,r):a.data[o];return Gd(s,i,e,t,Uh),r!=null&&Md(i,s),q}function J(){return yo(Kd(So()))&&bo(),go(),J}function Hh(e,t,n,r){return q(e,t,n,r),J(),Hh}var Uh=(e,t,n,r,i)=>(as(!0),Ql(t[11],r,ns()));function Wh(){let e=xo(),t=Kd(So());return e.firstCreatePass&&Dp(e,t),Wh}function Gh(e,t,n){let r=P(),i=r[1],a=e+27,o=i.firstCreatePass?Op(a,i,8,`ng-container`,t,n):i.data[a];return Gd(o,r,e,`ng-container`,Jh),n!=null&&Md(r,o),Gh}function Kh(){return Kd(So()),Wh}function qh(e,t,n){return Gh(e,t,n),Kh(),qh}var Jh=(e,t,n,r,i)=>(as(!0),Zl(t[11],``));function Yh(){return P()}function Xh(e,t,n){let r=P();return Qf(r,No(),t)&&(xo(),Id(Qo(),r,e,t,r[11],n)),Xh}var Zh=void 0;function Qh(e){let t=Math.floor(Math.abs(e)),n=e.toString().replace(/^[^.]*\.?/,``).length;return t===1&&n===0?1:5}var $h=[`en`,[[`a`,`p`],[`AM`,`PM`]],[[`AM`,`PM`]],[[`S`,`M`,`T`,`W`,`T`,`F`,`S`],[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`],[`Su`,`Mo`,`Tu`,`We`,`Th`,`Fr`,`Sa`]],Zh,[[`J`,`F`,`M`,`A`,`M`,`J`,`J`,`A`,`S`,`O`,`N`,`D`],[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`]],Zh,[[`B`,`A`],[`BC`,`AD`],[`Before Christ`,`Anno Domini`]],0,[6,0],[`M/d/yy`,`MMM d, y`,`MMMM d, y`,`EEEE, MMMM d, y`],[`h:mm a`,`h:mm:ss a`,`h:mm:ss a z`,`h:mm:ss a zzzz`],[`{1}, {0}`,Zh,Zh,Zh],[`.`,`,`,`;`,`%`,`+`,`-`,`E`,`×`,`‰`,`∞`,`NaN`,`:`],[`#,##0.###`,`#,##0%`,`¤#,##0.00`,`#E0`],`USD`,`$`,`US Dollar`,{},`ltr`,Qh],eg=Object.create(null);function tg(e){let t=ig(e),n=ng(t);if(n)return n;let r=t.split(`-`)[0];if(n=ng(r),n)return n;if(r===`en`)return $h;throw new A(701,!1)}function ng(e){if(!(e in eg)){let t=Ii.ng&&Ii.ng.common&&Ii.ng.common.locales&&Ii.ng.common.locales[e];return t!==void 0&&(eg[e]=t),t}return eg[e]}var rg={LocaleId:0,DayPeriodsFormat:1,DayPeriodsStandalone:2,DaysFormat:3,DaysStandalone:4,MonthsFormat:5,MonthsStandalone:6,Eras:7,FirstDayOfWeek:8,WeekendRange:9,DateFormat:10,TimeFormat:11,DateTimeFormat:12,NumberSymbols:13,NumberFormats:14,CurrencyCode:15,CurrencySymbol:16,CurrencyName:17,Currencies:18,Directionality:19,PluralCase:20,ExtraData:21};function ig(e){return e.toLowerCase().replace(/_/g,`-`)}var ag=`en-US`;function og(e){typeof e==`string`&&e.toLowerCase().replace(/_/g,`-`)}function sg(e,t,n){let r=P(),i=xo(),a=So();return cg(i,r,r[11],a,e,t,n),sg}function Y(e,t,n){let r=P(),i=xo(),a=So();return(a.type&3||n)&&rp(a,i,r,n,r[11],e,t,tp(a,r,t)),Y}function cg(e,t,n,r,i,a,o){let s=!0,c=null;if((r.type&3||o)&&(c??=tp(r,t,a),rp(r,e,t,o,n,i,a,c)&&(s=!1)),s){let e=r.outputs?.[i],n=r.hostDirectiveOutputs?.[i];if(n&&n.length)for(let e=0;e>17&32767}function dg(e){return(e&2)==2}function fg(e,t){return e&131071|t<<17}function pg(e){return e|2}function mg(e){return(e&131068)>>2}function hg(e,t){return e&-131069|t<<2}function gg(e){return(e&1)==1}function _g(e){return e|1}function vg(e,t,n,r,i,a){let o=a?t.classBindings:t.styleBindings,s=ug(o),c=mg(o);e[r]=n;let l=!1,u;if(Array.isArray(n)){let e=n;u=e[1],(u===null||$i(e,u)>0)&&(l=!0)}else u=n;if(i){if(c!==0){let t=ug(e[s+1]);e[r+1]=lg(t,s),t!==0&&(e[t+1]=hg(e[t+1],r)),e[s+1]=fg(e[s+1],r)}else e[r+1]=lg(s,0),s!==0&&(e[s+1]=hg(e[s+1],r)),s=r}else e[r+1]=lg(c,0),s===0?s=r:e[c+1]=hg(e[c+1],r),c=r;l&&(e[r+1]=pg(e[r+1])),bg(e,u,r,!0),bg(e,u,r,!1),yg(t,u,e,r,a),o=lg(s,c),a?t.classBindings=o:t.styleBindings=o}function yg(e,t,n,r,i){let a=i?e.residualClasses:e.residualStyles;a!=null&&typeof t==`string`&&$i(a,t)>=0&&(n[r+1]=_g(n[r+1]))}function bg(e,t,n,r){let i=e[n+1],a=t===null,o=r?ug(i):mg(i),s=!1;for(;o!==0&&(s===!1||a);){let n=e[o],i=e[o+1];xg(n,t)&&(s=!0,e[o+1]=r?_g(i):pg(i)),o=r?ug(i):mg(i)}s&&(e[n+1]=r?pg(i):_g(i))}function xg(e,t){return e===null||t==null||(Array.isArray(e)?e[1]:e)===t?!0:Array.isArray(e)&&typeof t==`string`?$i(e,t)>=0:!1}var Sg={textEnd:0,key:0,keyEnd:0,value:0,valueEnd:0};function Cg(e){return e.substring(Sg.key,Sg.keyEnd)}function wg(e){return Eg(e),Tg(e,Dg(e,0,Sg.textEnd))}function Tg(e,t){let n=Sg.textEnd;return n===t?-1:(t=Sg.keyEnd=Og(e,Sg.key=t,n),Dg(e,t,n))}function Eg(e){Sg.key=0,Sg.keyEnd=0,Sg.value=0,Sg.valueEnd=0,Sg.textEnd=e.length}function Dg(e,t,n){for(;t32;)t++;return t}function kg(e,t,n){return Ng(e,t,n,!1),kg}function Ag(e,t){return Ng(e,t,null,!0),Ag}function jg(e){Pg(Wg,Mg,e,!0)}function Mg(e,t){for(let n=wg(t);n>=0;n=Tg(t,n))Zi(e,Cg(t),!0)}function Ng(e,t,n,r){let i=P(),a=xo(),o=Po(2);if(a.firstUpdatePass&&Ig(a,e,o,r),t!==xu&&Qf(i,o,t)){let s=a.data[Xo()];Kg(a,s,i,i[11],e,i[o+1]=Yg(t,n),r,o)}}function Pg(e,t,n,r){let i=xo(),a=Po(2);i.firstUpdatePass&&Ig(i,null,a,r);let o=P();if(n!==xu&&Qf(o,a,n)){let s=i.data[Xo()];if(Xg(s,r)&&!Fg(i,a)){let e=r?s.classesWithoutHost:s.stylesWithoutHost;e!==null&&(n=ti(e,n||``)),zh(i,s,o,n,r)}else Gg(i,s,o,o[11],o[a+1],o[a+1]=Ug(e,t,n),r,a)}}function Fg(e,t){return t>=e.expandoStartIndex}function Ig(e,t,n,r){let i=e.data;if(i[n+1]===null){let a=i[Xo()],o=Fg(e,n);Xg(a,r)&&t===null&&!o&&(t=!1),t=Lg(i,a,t,r),vg(i,a,t,n,o,r)}}function Lg(e,t,n,r){let i=zo(e),a=r?t.residualClasses:t.residualStyles;if(i===null)(r?t.classBindings:t.styleBindings)===0&&(n=Vg(null,e,t,n,r),n=Hg(n,t.attrs,r),a=null);else{let o=t.directiveStylingLast;if(o===-1||e[o]!==i){if(n=Vg(i,e,t,n,r),a===null){let n=Rg(e,t,r);n!==void 0&&Array.isArray(n)&&(n=Vg(null,e,t,n[1],r),n=Hg(n,t.attrs,r),zg(e,t,r,n))}else a=Bg(e,t,r)}}return a!==void 0&&(r?t.residualClasses=a:t.residualStyles=a),n}function Rg(e,t,n){let r=n?t.classBindings:t.styleBindings;if(mg(r)!==0)return e[ug(r)]}function zg(e,t,n,r){let i=n?t.classBindings:t.styleBindings;e[ug(i)]=r}function Bg(e,t,n){let r,i=t.directiveEnd;for(let a=1+t.directiveStylingLast;a0;){let t=e[i],a=Array.isArray(t),c=a?t[1]:t,l=c===null,u=n[i+1];u===xu&&(u=l?na:void 0);let d=l?Qi(u,r):c===r?u:void 0;if(a&&!Jg(d)&&(d=Qi(t,r)),Jg(d)&&(s=d,o))return s;let f=e[i+1];i=o?ug(f):mg(f)}if(t!==null){let e=a?t.residualClasses:t.residualStyles;e!=null&&(s=Qi(e,r))}return s}function Jg(e){return e!==void 0}function Yg(e,t){return e==null||e===``||(typeof t==`string`?e=Wl(e)+t:typeof e==`object`&&(e=ei(Wl(e)))),e}function Xg(e,t){return!!(e.flags&(t?8:16))}function Z(e,t=``){let n=P(),r=xo(),i=e+27,a=r.firstCreatePass?Pf(r,i,1,t,null):r.data[i],o=Zg(r,n,a,t);n[i]=o,is()&&ld(r,n,o,a),To(a,!1)}var Zg=(e,t,n,r)=>(as(!0),Yl(t[11],r));function Qg(e,t,n,r=``){return Qf(e,No(),n)?t+wi(n)+r:xu}function $g(e,t,n,r,i,a=``){let o=$f(e,jo(),n,i);return Po(2),o?t+wi(n)+r+wi(i)+a:xu}function e_(e,t,n,r,i,a,o,s=``){let c=ep(e,jo(),n,i,o);return Po(3),c?t+wi(n)+r+wi(i)+a+wi(o)+s:xu}function Q(e){return $(``,e),Q}function $(e,t,n){let r=P(),i=Qg(r,e,t,n);return i!==xu&&r_(r,Xo(),i),$}function t_(e,t,n,r,i){let a=P(),o=$g(a,e,t,n,r,i);return o!==xu&&r_(a,Xo(),o),t_}function n_(e,t,n,r,i,a,o){let s=P(),c=e_(s,e,t,n,r,i,a,o);return c!==xu&&r_(s,Xo(),c),n_}function r_(e,t,n){let r=qa(t,e);Xl(e[11],r,n)}function i_(e,t){let n=Ao()+e,r=P();return r[n]===xu?Xf(r,n,t()):Zf(r,n)}function a_(e,t,n,r){return c_(P(),Ao(),e,t,n,r)}function o_(e,t){let n=e[t];return n===xu?void 0:n}function s_(e,t,n,r,i,a){let o=t+n;return Qf(e,o,i)?Xf(e,o+1,a?r.call(a,i):r(i)):o_(e,o+1)}function c_(e,t,n,r,i,a,o){let s=t+n;return $f(e,s,i,a)?Xf(e,s+2,o?r.call(o,i,a):r(i,a)):o_(e,s+2)}function l_(e,t){let n=xo(),r,i=e+27;n.firstCreatePass?(r=u_(t,n.pipeRegistry),n.data[i]=r,r.onDestroy&&(n.destroyHooks??=[]).push(i,r.onDestroy)):r=n.data[i];let a=r.factory||(r.factory=Ki(r.type,!0)),o=Pi(dp);try{let e=Fc(!1),t=a();return Fc(e),Za(n,P(),i,t),t}finally{Pi(o)}}function u_(e,t){if(t)for(let n=t.length-1;n>=0;n--){let r=t[n];if(e===r.name)return r}}function d_(e,t,n){let r=e+27,i=P(),a=Xa(i,r);return p_(i,r)?s_(i,Ao(),t,a.transform,n,a):a.transform(n)}function f_(e,t,n,r){let i=e+27,a=P(),o=Xa(a,i);return p_(a,i)?c_(a,Ao(),t,o.transform,n,r,o):o.transform(n,r)}function p_(e,t){return e[1].data[t].pure}var m_=(()=>{class e{applicationErrorHandler=M(Fs);appRef=M(ih);taskService=M(ms);ngZone=M(Ss);zonelessEnabled=M(Ks);tracing=M(Mu,{optional:!0});zoneIsDefined=typeof Zone<`u`&&!!Zone.root.run;schedulerTickApplyArgs=[{data:{__scheduler_tick__:!0}}];subscriptions=new ur;angularZoneId=this.zoneIsDefined?this.ngZone._inner?.get(bs):null;scheduleInRootZone=!this.zonelessEnabled&&this.zoneIsDefined&&(M(qs,{optional:!0})??!1);cancelScheduledCallback=null;useMicrotaskScheduler=!1;runningTick=!1;pendingRenderTaskId=null;constructor(){this.subscriptions.add(this.appRef.afterTick.subscribe(()=>{let e=this.taskService.add();if(!this.runningTick&&(this.cleanup(),!this.zonelessEnabled||this.appRef.includeAllTestViews)){this.taskService.remove(e);return}this.switchToMicrotaskScheduler(),this.taskService.remove(e)})),this.subscriptions.add(this.ngZone.onUnstable.subscribe(()=>{this.runningTick||this.cleanup()}))}switchToMicrotaskScheduler(){this.ngZone.runOutsideAngular(()=>{let e=this.taskService.add();this.useMicrotaskScheduler=!0,queueMicrotask(()=>{this.useMicrotaskScheduler=!1,this.taskService.remove(e)})})}notify(e){if(!this.zonelessEnabled&&e===5)return;switch(e){case 0:case 2:this.appRef.dirtyFlags|=2;break;case 3:case 4:case 5:case 1:this.appRef.dirtyFlags|=4;break;case 6:this.appRef.dirtyFlags|=2;break;case 12:this.appRef.dirtyFlags|=16;break;case 13:this.appRef.dirtyFlags|=2;break;case 11:break;default:this.appRef.dirtyFlags|=8}if(this.appRef.tracingSnapshot=this.tracing?.snapshot(this.appRef.tracingSnapshot)??null,!this.shouldScheduleTick())return;let t=this.useMicrotaskScheduler?vs:_s;this.pendingRenderTaskId=this.taskService.add(),this.cancelScheduledCallback=this.scheduleInRootZone?Zone.root.run(()=>t(()=>this.tick())):this.ngZone.runOutsideAngular(()=>t(()=>this.tick()))}shouldScheduleTick(){return!(this.appRef.destroyed||this.pendingRenderTaskId!==null||this.runningTick||this.appRef._runningTick||!this.zonelessEnabled&&this.zoneIsDefined&&Zone.current.get(`isAngularZone_ID`+this.angularZoneId))}tick(){if(this.runningTick||this.appRef.destroyed)return;if(this.appRef.dirtyFlags===0){this.cleanup();return}!this.zonelessEnabled&&this.appRef.dirtyFlags&7&&(this.appRef.dirtyFlags|=1);let e=this.taskService.add();try{this.ngZone.run(()=>{this.runningTick=!0,this.appRef._tick()},void 0,this.schedulerTickApplyArgs)}catch(e){this.applicationErrorHandler(e)}finally{this.taskService.remove(e),this.cleanup()}}ngOnDestroy(){this.subscriptions.unsubscribe(),this.cleanup()}cleanup(){if(this.runningTick=!1,this.cancelScheduledCallback?.(),this.cancelScheduledCallback=null,this.pendingRenderTaskId!==null){let e=this.pendingRenderTaskId;this.pendingRenderTaskId=null,this.taskService.remove(e)}}static ɵfac=function(t){return new(t||e)};static ɵprov=ul({token:e,factory:e.ɵfac})}return e})();function h_(){return[{provide:Gs,useExisting:m_},{provide:Ss,useClass:As},{provide:Ks,useValue:!0}]}function g_(){return typeof $localize<`u`&&$localize.locale||`en-US`}var __=new j(``,{factory:()=>M(__,{optional:!0,skipSelf:!0})||g_()}),v_=class{destroyed=!1;listeners=null;errorHandler=M(Ps,{optional:!0});isEmitting=!1;hasNullListeners=!1;destroyRef=M(us);constructor(){this.destroyRef.onDestroy(()=>{this.destroyed=!0,this.listeners=null})}subscribe(e){if(this.destroyed)throw new A(953,!1);return(this.listeners??=[]).push(e),{unsubscribe:()=>{let t=this.listeners?this.listeners.indexOf(e):-1;t>-1&&(this.isEmitting?(this.hasNullListeners=!0,this.listeners[t]=null):this.listeners.splice(t,1))}}}emit(e){if(this.destroyed){console.warn(Qr(953,!1));return}if(this.listeners===null)return;this.isEmitting=!0;let t=k(null);try{for(let t of this.listeners)try{t!==null&&t(e)}catch(e){this.errorHandler?.handleError(e)}}finally{this.hasNullListeners&&(this.hasNullListeners=!1,this.listeners&&y_(this.listeners)),k(t),this.isEmitting=!1}}};function y_(e){let t=e.length-1;for(;t>-1;)e[t]===null&&e.splice(t,1),t--}function b_(e,t){return Dn(e,t?.equal)}function x_(e){return er(e)}(class e extends Error{_brand;constructor(e){super(e)}static IDLE=new e(`IDLE`);static LOADING=new e(`LOADING`)});var S_=e=>e;function C_(e,t){return typeof e==`function`?w_(Xn(e,S_,t?.equal),t?.debugName,t?.set):w_(Xn(e.source,e.computation,e.equal),e.debugName,e.set)}function w_(e,t,n){let r=e[on],i=e;if(n!==void 0){let t=e=>Zn(r,e);i.set=e=>n(e,t),i.update=r=>n(r(x_(e)),t)}else i.set=e=>Zn(r,e),i.update=e=>Qn(r,e);return i.asReadonly=Ls.bind(e),i}function T_(e,t){let n=Object.create(oc);n.value=e,n.transformFn=t?.transform;function r(){if(ln(n),n.value===ac)throw new A(-950,null);return n.value}return r[on]=n,r}function E_(e){return new v_}function D_(e,t){return T_(e,t)}function O_(e){return T_(ac,e)}var k_=(D_.required=O_,D_),A_=new j(``),j_=new j(``);function M_(e){return!e.moduleRef}function N_(e){let t=M_(e)?e.r3Injector:e.moduleRef.injector,n=t.get(Ss);return n.run(()=>{M_(e)?e.r3Injector.resolveInjectorInitializers():e.moduleRef.resolveInjectorInitializers();let r=t.get(Fs),i;if(n.runOutsideAngular(()=>{i=n.onError.subscribe({next:r})}),M_(e)){let n=()=>t.destroy(),r=e.platformInjector.get(A_);r.add(n),t.onDestroy(()=>{i.unsubscribe(),r.delete(n)})}else{let t=()=>e.moduleRef.destroy(),n=e.platformInjector.get(A_);n.add(t),e.moduleRef.onDestroy(()=>{oh(e.allPlatformModules,e.moduleRef),i.unsubscribe(),n.delete(t)})}return F_(r,n,()=>{let n=t.get(ms),r=n.add(),i=t.get(lm);return i.runInitializers(),i.donePromise.then(()=>{if(og(t.get(__,ag)||`en-US`),!t.get(j_,!0))return M_(e)?t.get(ih):(e.allPlatformModules.push(e.moduleRef),e.moduleRef);if(M_(e)){let n=t.get(ih);return e.rootComponent!==void 0&&n.bootstrap(e.rootComponent),n}return P_?.(e.moduleRef,e.allPlatformModules),e.moduleRef}).finally(()=>void n.remove(r))})})}var P_;function F_(e,t,n){try{let r=n();return qp(r)?r.catch(n=>{throw t.runOutsideAngular(()=>e(n)),n}):r}catch(n){throw t.runOutsideAngular(()=>e(n)),n}}var I_=null;function L_(e=[],t){return cs.create({name:t,providers:[{provide:_a,useValue:`platform`},{provide:A_,useValue:new Set([()=>I_=null])},...e]})}function R_(e=[]){if(I_)return I_;let t=L_(e);return I_=t,nh(),z_(t),t}function z_(e){let t=e.get(Bs,null);Pa(e,()=>{t?.forEach(e=>e())})}function B_(e){let{rootComponent:t,appProviders:n,platformProviders:r,platformRef:i}=e;fc(R.BootstrapApplicationStart);try{let e=i?.injector??R_(r);return N_({r3Injector:new Xp({providers:[h_(),Is,...n||[]],parent:e,debugName:``,runEnvironmentInitializers:!1}).injector,platformInjector:e,rootComponent:t})}catch(e){return Promise.reject(e)}finally{fc(R.BootstrapApplicationEnd)}}var V_=null;function H_(){return V_}function U_(e){V_??=e}var W_=class{},G_=(function(e){return e[e.Format=0]=`Format`,e[e.Standalone=1]=`Standalone`,e})(G_||{}),K_=(function(e){return e[e.Narrow=0]=`Narrow`,e[e.Abbreviated=1]=`Abbreviated`,e[e.Wide=2]=`Wide`,e[e.Short=3]=`Short`,e})(K_||{}),q_=(function(e){return e[e.Short=0]=`Short`,e[e.Medium=1]=`Medium`,e[e.Long=2]=`Long`,e[e.Full=3]=`Full`,e})(q_||{}),J_={Decimal:0,Group:1,List:2,PercentSign:3,PlusSign:4,MinusSign:5,Exponential:6,SuperscriptingExponent:7,PerMille:8,Infinity:9,NaN:10,TimeSeparator:11,CurrencyDecimal:12,CurrencyGroup:13};function Y_(e){return tg(e)[rg.LocaleId]}function X_(e,t,n){let r=tg(e);return sv(sv([r[rg.DayPeriodsFormat],r[rg.DayPeriodsStandalone]],t),n)}function Z_(e,t,n){let r=tg(e);return sv(sv([r[rg.DaysFormat],r[rg.DaysStandalone]],t),n)}function Q_(e,t,n){let r=tg(e);return sv(sv([r[rg.MonthsFormat],r[rg.MonthsStandalone]],t),n)}function $_(e,t){let n=tg(e)[rg.Eras];return sv(n,t)}function ev(e,t){return sv(tg(e)[rg.DateFormat],t)}function tv(e,t){return sv(tg(e)[rg.TimeFormat],t)}function nv(e,t){let n=tg(e)[rg.DateTimeFormat];return sv(n,t)}function rv(e,t){let n=tg(e),r=n[rg.NumberSymbols][t];if(r===void 0){if(t===J_.CurrencyDecimal)return n[rg.NumberSymbols][J_.Decimal];if(t===J_.CurrencyGroup)return n[rg.NumberSymbols][J_.Group]}return r}function iv(e){if(!e[rg.ExtraData])throw new A(2303,!1)}function av(e){let t=tg(e);return iv(t),(t[rg.ExtraData][2]||[]).map(e=>typeof e==`string`?cv(e):[cv(e[0]),cv(e[1])])}function ov(e,t,n){let r=tg(e);return iv(r),sv(sv([r[rg.ExtraData][0],r[rg.ExtraData][1]],t)||[],n)||[]}function sv(e,t){for(let n=t;n>-1;n--)if(e[n]!==void 0)return e[n];throw new A(2304,!1)}function cv(e){let[t,n]=e.split(`:`);return{hours:+t,minutes:+n}}var lv=/^(\d{4,})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/,uv=Object.create(null),dv=/((?:[^BEGHLMOSWYZabcdhmswyz']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|c{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/,fv=256;function pv(e,t,n,r){let i=Iv(e);mv(t),t=gv(n,t)||t;let a=[],o;for(;t;)if(o=dv.exec(t),o){a=a.concat(o.slice(1));let e=a.pop();if(!e)break;t=e}else{a.push(t);break}let s=i.getTimezoneOffset();r&&(s=Nv(r,s),i=Fv(i,r));let c=``;return a.forEach(e=>{let t=Mv(e);c+=t?t(i,n,s):e===`''`?`'`:e.replace(/(^'|'$)/g,``).replace(/''/g,`'`)}),c}function mv(e){if(e.length>fv)throw new A(2300,!1)}function hv(e,t,n){let r=new Date(0);return r.setFullYear(e,t,n),r.setHours(0,0,0),r}function gv(e,t){let n=Y_(e);if(uv[n]??=Object.create(null),uv[n][t])return uv[n][t];let r=``;switch(t){case`shortDate`:r=ev(e,q_.Short);break;case`mediumDate`:r=ev(e,q_.Medium);break;case`longDate`:r=ev(e,q_.Long);break;case`fullDate`:r=ev(e,q_.Full);break;case`shortTime`:r=tv(e,q_.Short);break;case`mediumTime`:r=tv(e,q_.Medium);break;case`longTime`:r=tv(e,q_.Long);break;case`fullTime`:r=tv(e,q_.Full);break;case`short`:let t=gv(e,`shortTime`),n=gv(e,`shortDate`);r=_v(nv(e,q_.Short),[t,n]);break;case`medium`:let i=gv(e,`mediumTime`),a=gv(e,`mediumDate`);r=_v(nv(e,q_.Medium),[i,a]);break;case`long`:let o=gv(e,`longTime`),s=gv(e,`longDate`);r=_v(nv(e,q_.Long),[o,s]);break;case`full`:let c=gv(e,`fullTime`),l=gv(e,`fullDate`);r=_v(nv(e,q_.Full),[c,l])}return r&&(uv[n][t]=r),r}function _v(e,t){return t&&(e=e.replace(/\{([^}]+)}/g,function(e,n){return Object.hasOwn(t,n)?t[n]:e})),e}function vv(e,t,n=`-`,r,i){let a=``;(e<0||i&&e<=0)&&(i?e=-e+1:(e=-e,a=n));let o=String(e);for(;o.length0||s>-n)&&(s+=n),e===3)s===0&&n===-12&&(s=12);else if(e===6)return yv(s,t);let c=rv(o,J_.MinusSign);return vv(s,t,c,r,i)}}function xv(e,t){switch(e){case 0:return t.getFullYear();case 1:return t.getMonth();case 2:return t.getDate();case 3:return t.getHours();case 4:return t.getMinutes();case 5:return t.getSeconds();case 6:return t.getMilliseconds();case 7:return t.getDay();default:throw new A(2301,!1)}}function Sv(e,t,n=G_.Format,r=!1){return function(i,a){return Cv(i,a,e,t,n,r)}}function Cv(e,t,n,r,i,a){switch(n){case 2:return Q_(t,i,r)[e.getMonth()];case 1:return Z_(t,i,r)[e.getDay()];case 0:let n=e.getHours(),o=e.getMinutes();if(a){let e=av(t),a=ov(t,i,r),s=e.findIndex(e=>{if(Array.isArray(e)){let[t,r]=e,i=n>=t.hours&&o>=t.minutes,a=n0?Math.floor(i/60):Math.ceil(i/60);switch(e){case 0:return(i>=0?`+`:``)+vv(o,2,a)+vv(Math.abs(i%60),2,a);case 1:return`GMT`+(i>=0?`+`:``)+vv(o,1,a);case 2:return`GMT`+(i>=0?`+`:``)+vv(o,2,a)+`:`+vv(Math.abs(i%60),2,a);case 3:return r===0?`Z`:(i>=0?`+`:``)+vv(o,2,a)+`:`+vv(Math.abs(i%60),2,a);default:throw new A(2310,!1)}}}var Tv=0,Ev=4;function Dv(e){let t=hv(e,Tv,1).getDay();return hv(e,0,1+(t<=Ev?Ev:11)-t)}function Ov(e){let t=e.getDay(),n=t===0?-3:Ev-t;return hv(e.getFullYear(),e.getMonth(),e.getDate()+n)}function kv(e,t=!1){return function(n,r){let i;if(t){let e=new Date(n.getFullYear(),n.getMonth(),1).getDay()-1,t=n.getDate();i=1+Math.floor((t+e)/7)}else{let e=Ov(n),t=Dv(e.getFullYear()),r=e.getTime()-t.getTime();i=1+Math.round(r/6048e5)}return vv(i,e,rv(r,J_.MinusSign))}}function Av(e,t=!1){return function(n,r){return vv(Ov(n).getFullYear(),e,rv(r,J_.MinusSign),t)}}var jv=Object.create(null);function Mv(e){if(jv[e])return jv[e];let t;switch(e){case`G`:case`GG`:case`GGG`:t=Sv(3,K_.Abbreviated);break;case`GGGG`:t=Sv(3,K_.Wide);break;case`GGGGG`:t=Sv(3,K_.Narrow);break;case`y`:t=bv(0,1,0,!1,!0);break;case`yy`:t=bv(0,2,0,!0,!0);break;case`yyy`:t=bv(0,3,0,!1,!0);break;case`yyyy`:t=bv(0,4,0,!1,!0);break;case`Y`:t=Av(1);break;case`YY`:t=Av(2,!0);break;case`YYY`:t=Av(3);break;case`YYYY`:t=Av(4);break;case`M`:case`L`:t=bv(1,1,1);break;case`MM`:case`LL`:t=bv(1,2,1);break;case`MMM`:t=Sv(2,K_.Abbreviated);break;case`MMMM`:t=Sv(2,K_.Wide);break;case`MMMMM`:t=Sv(2,K_.Narrow);break;case`LLL`:t=Sv(2,K_.Abbreviated,G_.Standalone);break;case`LLLL`:t=Sv(2,K_.Wide,G_.Standalone);break;case`LLLLL`:t=Sv(2,K_.Narrow,G_.Standalone);break;case`w`:t=kv(1);break;case`ww`:t=kv(2);break;case`W`:t=kv(1,!0);break;case`d`:t=bv(2,1);break;case`dd`:t=bv(2,2);break;case`c`:case`cc`:t=bv(7,1);break;case`ccc`:t=Sv(1,K_.Abbreviated,G_.Standalone);break;case`cccc`:t=Sv(1,K_.Wide,G_.Standalone);break;case`ccccc`:t=Sv(1,K_.Narrow,G_.Standalone);break;case`cccccc`:t=Sv(1,K_.Short,G_.Standalone);break;case`E`:case`EE`:case`EEE`:t=Sv(1,K_.Abbreviated);break;case`EEEE`:t=Sv(1,K_.Wide);break;case`EEEEE`:t=Sv(1,K_.Narrow);break;case`EEEEEE`:t=Sv(1,K_.Short);break;case`a`:case`aa`:case`aaa`:t=Sv(0,K_.Abbreviated);break;case`aaaa`:t=Sv(0,K_.Wide);break;case`aaaaa`:t=Sv(0,K_.Narrow);break;case`b`:case`bb`:case`bbb`:t=Sv(0,K_.Abbreviated,G_.Standalone,!0);break;case`bbbb`:t=Sv(0,K_.Wide,G_.Standalone,!0);break;case`bbbbb`:t=Sv(0,K_.Narrow,G_.Standalone,!0);break;case`B`:case`BB`:case`BBB`:t=Sv(0,K_.Abbreviated,G_.Format,!0);break;case`BBBB`:t=Sv(0,K_.Wide,G_.Format,!0);break;case`BBBBB`:t=Sv(0,K_.Narrow,G_.Format,!0);break;case`h`:t=bv(3,1,-12);break;case`hh`:t=bv(3,2,-12);break;case`H`:t=bv(3,1);break;case`HH`:t=bv(3,2);break;case`m`:t=bv(4,1);break;case`mm`:t=bv(4,2);break;case`s`:t=bv(5,1);break;case`ss`:t=bv(5,2);break;case`S`:t=bv(6,1);break;case`SS`:t=bv(6,2);break;case`SSS`:t=bv(6,3);break;case`Z`:case`ZZ`:case`ZZZ`:t=wv(0);break;case`ZZZZZ`:t=wv(3);break;case`O`:case`OO`:case`OOO`:case`z`:case`zz`:case`zzz`:t=wv(1);break;case`OOOO`:case`ZZZZ`:case`zzzz`:t=wv(2);break;default:return null}return jv[e]=t,t}function Nv(e,t){e=e.replace(/:/g,``);let n=Date.parse(`Jan 01, 1970 00:00:00 `+e)/6e4;return isNaN(n)?t:n}function Pv(e,t){return e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+t),e}function Fv(e,t,n){let r=e.getTimezoneOffset();return Pv(e,-1*(Nv(t,r)-r))}function Iv(e){if(Rv(e))return e;if(typeof e==`number`&&!isNaN(e))return new Date(e);if(typeof e==`string`){if(e=e.trim(),/^(\d{4}(-\d{1,2}(-\d{1,2})?)?)$/.test(e)){let[t,n=1,r=1]=e.split(`-`).map(e=>+e);return hv(t,n-1,r)}let t=parseFloat(e);if(!isNaN(e-t))return new Date(t);let n;if(n=e.match(lv))return Lv(n)}let t=new Date(e);if(!Rv(t))throw new A(2311,!1);return t}function Lv(e){let t=new Date(0),n=0,r=0,i=e[8]?t.setUTCFullYear:t.setFullYear,a=e[8]?t.setUTCHours:t.setHours;e[9]&&(n=Number(e[9]+e[10]),r=Number(e[9]+e[11])),i.call(t,Number(e[1]),Number(e[2])-1,Number(e[3]));let o=Number(e[4]||0)-n,s=Number(e[5]||0)-r,c=Number(e[6]||0),l=Math.floor(parseFloat(`0.`+(e[7]||0))*1e3);return a.call(t,o,s,c,l),t}function Rv(e){return e instanceof Date&&!isNaN(e.valueOf())}function zv(e,t){return new A(2100,!1)}var Bv=`mediumDate`,Vv=new j(``),Hv=new j(``),Uv=(()=>{class e{locale;defaultTimezone;defaultOptions;constructor(e,t,n){this.locale=e,this.defaultTimezone=t,this.defaultOptions=n}transform(t,n,r,i){if(t==null||t===``||t!==t)return null;try{let e=n??this.defaultOptions?.dateFormat??Bv,a=r??this.defaultOptions?.timezone??this.defaultTimezone??void 0;return pv(t,e,i||this.locale,a)}catch(t){throw zv(e,t.message)}}static ɵfac=function(t){return new(t||e)(dp(__,16),dp(Vv,24),dp(Hv,24))};static ɵpipe=rm({name:`date`,type:e,pure:!0})}return e})(),Wv=(()=>{class e{transform(e){return JSON.stringify(e,null,2)}static ɵfac=function(t){return new(t||e)};static ɵpipe=rm({name:`json`,type:e,pure:!1})}return e})();function Gv(e,t){t=encodeURIComponent(t);for(let n of e.split(`;`)){let e=n.indexOf(`=`),[r,i]=e==-1?[n,``]:[n.slice(0,e),n.slice(e+1)];if(r.trim()!==t)continue;let a=i;try{a=decodeURIComponent(i)}catch{}return a.length>1&&a[0]===`"`&&a[a.length-1]===`"`&&(a=a.slice(1,-1)),a}return null}var Kv=`browser`,qv=class{_doc;constructor(e){this._doc=e}manager},Jv=(()=>{class e extends qv{constructor(e){super(e)}supports(e){return!0}addEventListener(e,t,n,r){return e.addEventListener(t,n,r),()=>this.removeEventListener(e,t,n,r)}removeEventListener(e,t,n,r){return e.removeEventListener(t,n,r)}static ɵfac=function(t){return new(t||e)(Vi(ls))};static ɵprov=oi({token:e,factory:e.ɵfac})}return e})(),Yv=new j(``),Xv=(()=>{class e{_zone;_plugins;_eventNameToPlugin=new Map;constructor(e,t){this._zone=t,e.forEach(e=>{e.manager=this});let n=e.filter(e=>!(e instanceof Jv));this._plugins=n.slice().reverse();let r=e.find(e=>e instanceof Jv);r&&this._plugins.push(r)}addEventListener(e,t,n,r){return this._findPluginFor(t).addEventListener(e,t,n,r)}getZone(){return this._zone}_findPluginFor(e){let t=this._eventNameToPlugin.get(e);if(t)return t;if(t=this._plugins.find(t=>t.supports(e)),!t)throw new A(-5101,!1);return this._eventNameToPlugin.set(e,t),t}static ɵfac=function(t){return new(t||e)(Vi(Yv),Vi(Ss))};static ɵprov=oi({token:e,factory:e.ɵfac})}return e})(),Zv=`ng-app-id`;function Qv(e){for(let t of e)t.remove()}function $v(e,t){let n=t.createElement(`style`);return n.textContent=e,n}function ey(e,t,n,r){let i=e.head?.querySelectorAll(`style[${Zv}="${t}"],link[${Zv}="${t}"]`);if(!i||i.length===0)return!1;for(let e of i)e.removeAttribute(Zv),e instanceof HTMLLinkElement?r.set(e.href.slice(e.href.lastIndexOf(`/`)+1),{usage:0,elements:[e]}):e.textContent&&n.set(e.textContent,{usage:0,elements:[e]});return!0}function ty(e,t){let n=t.createElement(`link`);return n.setAttribute(`rel`,`stylesheet`),n.setAttribute(`href`,e),n}var ny=(()=>{class e{doc;appId;nonce;inline=new Map;external=new Map;hosts=new Set;constructor(e,t,n,r={}){this.doc=e,this.appId=t,this.nonce=n,ey(e,t,this.inline,this.external)&&this.hosts.add(e.head)}addStyles(e,t){for(let t of e)this.addUsage(t,this.inline,$v);t?.forEach(e=>this.addUsage(e,this.external,ty))}removeStyles(e,t){for(let t of e)this.removeUsage(t,this.inline);t?.forEach(e=>this.removeUsage(e,this.external))}addUsage(e,t,n){let r=t.get(e);r?r.usage++:t.set(e,{usage:1,elements:[...this.hosts].map(t=>this.addElement(t,n(e,this.doc)))})}removeUsage(e,t){let n=t.get(e);n&&(n.usage--,n.usage<=0&&(Qv(n.elements),t.delete(e)))}ngOnDestroy(){for(let[,{elements:e}]of[...this.inline,...this.external])Qv(e);this.hosts.clear()}addHost(e){if(!this.hosts.has(e)){this.hosts.add(e);for(let[t,{elements:n}]of this.inline)n.push(this.addElement(e,$v(t,this.doc)));for(let[t,{elements:n}]of this.external)n.push(this.addElement(e,ty(t,this.doc)))}}removeHost(e){this.hosts.delete(e);for(let t of[...this.inline.values(),...this.external.values()]){let n=[];for(let r of t.elements)r.parentNode===e?r.remove():n.push(r);t.elements=n}}addElement(e,t){return this.nonce&&t.setAttribute(`nonce`,this.nonce),e.appendChild(t)}static ɵfac=function(t){return new(t||e)(Vi(ls),Vi(Rs),Vi(Hs,8),Vi(Vs))};static ɵprov=oi({token:e,factory:e.ɵfac})}return e})(),ry={svg:`http://www.w3.org/2000/svg`,xhtml:`http://www.w3.org/1999/xhtml`,xlink:`http://www.w3.org/1999/xlink`,xml:`http://www.w3.org/XML/1998/namespace`,xmlns:`http://www.w3.org/2000/xmlns/`,math:`http://www.w3.org/1998/Math/MathML`},iy=/%COMP%/g,ay=`%COMP%`,oy=`_nghost-${ay}`,sy=`_ngcontent-${ay}`,cy=!0,ly=new j(``,{factory:()=>cy}),uy=new j(``);function dy(e){return sy.replace(iy,e)}function fy(e){return oy.replace(iy,e)}function py(e,t){return t.map(t=>t.replace(iy,e))}var my=(()=>{class e{eventManager;sharedStylesHost;appId;removeStylesOnCompDestroy;doc;ngZone;nonce;tracingService;rendererByCompId=new Map;defaultRenderer;cssVarNamespace;constructor(e,t,n,r,i,a,o=null,s=null,c=null){this.eventManager=e,this.sharedStylesHost=t,this.appId=n,this.removeStylesOnCompDestroy=r,this.doc=i,this.ngZone=a,this.nonce=o,this.tracingService=s,this.cssVarNamespace=c??``,this.defaultRenderer=new hy(e,i,a,this.tracingService,this.cssVarNamespace)}createRenderer(e,t){if(!e||!t)return this.defaultRenderer;let n=this.getOrCreateRenderer(e,t);return n instanceof yy?n.applyToHost(e):n instanceof vy&&n.applyStyles(),n}getOrCreateRenderer(e,t){let n=this.rendererByCompId,r=n.get(t.id);if(!r){let i=this.doc,a=this.ngZone,o=this.eventManager,s=this.sharedStylesHost,c=this.removeStylesOnCompDestroy,l=this.tracingService;switch(t.encapsulation){case Hl.Emulated:r=new yy(o,s,t,this.appId,c,i,a,l,this.cssVarNamespace);break;case Hl.ShadowDom:return new _y(o,e,t,i,a,this.nonce,l,this.cssVarNamespace,s);case Hl.ExperimentalIsolatedShadowDom:return new _y(o,e,t,i,a,this.nonce,l,this.cssVarNamespace);default:r=new vy(o,s,t,c,i,a,l,this.cssVarNamespace)}n.set(t.id,r)}return r}ngOnDestroy(){this.rendererByCompId.clear()}componentReplaced(e){this.rendererByCompId.delete(e)}static ɵfac=function(t){return new(t||e)(Vi(Xv),Vi(lp),Vi(Rs),Vi(ly),Vi(ls),Vi(Ss),Vi(Hs),Vi(Mu,8),Vi(uy,8))};static ɵprov=oi({token:e,factory:e.ɵfac})}return e})(),hy=class{eventManager;doc;ngZone;tracingService;cssVarNamespace;data=Object.create(null);throwOnSyntheticProps=!0;constructor(e,t,n,r,i=``){this.eventManager=e,this.doc=t,this.ngZone=n,this.tracingService=r,this.cssVarNamespace=i}destroy(){}destroyNode=null;createElement(e,t){return t?this.doc.createElementNS(ry[t]||t,e):this.doc.createElement(e)}createComment(e){return this.doc.createComment(e)}createText(e){return this.doc.createTextNode(e)}appendChild(e,t){(gy(e)?e.content:e).appendChild(t)}insertBefore(e,t,n){if(e){let r=gy(e)?e.content:e;if(n!=null&&n.parentNode!==r)throw new A(-5106,!1);r.insertBefore(t,n)}}removeChild(e,t){t.remove()}selectRootElement(e,t){let n=typeof e==`string`?this.doc.querySelector(e):e;if(!n)throw new A(-5104,!1);return t||(n.textContent=``),n}parentNode(e){return e.parentNode}nextSibling(e){return e.nextSibling}setAttribute(e,t,n,r){if(r){t=r+`:`+t;let i=ry[r];i?e.setAttributeNS(i,t,n):e.setAttribute(t,n)}else e.setAttribute(t,n)}removeAttribute(e,t,n){if(n){let r=ry[n];r?e.removeAttributeNS(r,t):e.removeAttribute(`${n}:${t}`)}else e.removeAttribute(t)}addClass(e,t){e.classList.add(t)}removeClass(e,t){e.classList.remove(t)}setStyle(e,t,n,r){let i=t.startsWith(`--`);i&&(t=t.replace(`%NS%`,this.cssVarNamespace)),i||r&(Su.DashCase|Su.Important)?e.style.setProperty(t,n,r&Su.Important?`important`:``):e.style[t]=n}removeStyle(e,t,n){let r=t.startsWith(`--`);r&&(t=t.replace(`%NS%`,this.cssVarNamespace)),r||n&Su.DashCase?e.style.removeProperty(t):e.style[t]=``}setProperty(e,t,n){e!=null&&(e[t]=n)}setValue(e,t){e.nodeValue=t}listen(e,t,n,r){if(typeof e==`string`&&(e=H_().getGlobalEventTarget(this.doc,e),!e))throw new A(-5102,!1);let i=this.decoratePreventDefault(n);return this.tracingService?.wrapEventListener&&(i=this.tracingService.wrapEventListener(e,t,i)),this.eventManager.addEventListener(e,t,i,r)}decoratePreventDefault(e){return t=>{if(t===`__ngUnwrap__`)return e;e(t)===!1&&t.preventDefault()}}};function gy(e){return e.tagName===`TEMPLATE`&&e.content!==void 0}var _y=class extends hy{hostEl;sharedStylesHost;shadowRoot;constructor(e,t,n,r,i,a,o,s,c){super(e,r,i,o,s),this.hostEl=t,this.sharedStylesHost=c,this.shadowRoot=t.attachShadow({mode:`open`}),this.sharedStylesHost&&this.sharedStylesHost.addHost(this.shadowRoot);let l=n.styles;l=py(n.id,l).map(e=>e.replace(/%NS%/g,s));for(let e of l){let t=document.createElement(`style`);a&&t.setAttribute(`nonce`,a),t.textContent=e,this.shadowRoot.appendChild(t)}let u=n.getExternalStyles?.();if(u)for(let e of u){let t=ty(e,r);a&&t.setAttribute(`nonce`,a),this.shadowRoot.appendChild(t)}}nodeOrShadowRoot(e){return e===this.hostEl?this.shadowRoot:e}appendChild(e,t){return super.appendChild(this.nodeOrShadowRoot(e),t)}insertBefore(e,t,n){return super.insertBefore(this.nodeOrShadowRoot(e),t,n)}removeChild(e,t){return super.removeChild(null,t)}parentNode(e){return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(e)))}destroy(){this.sharedStylesHost&&this.sharedStylesHost.removeHost(this.shadowRoot)}},vy=class extends hy{sharedStylesHost;removeStylesOnCompDestroy;styles;styleUrls;constructor(e,t,n,r,i,a,o,s,c){super(e,i,a,o,s),this.sharedStylesHost=t,this.removeStylesOnCompDestroy=r;let l=n.styles,u=c?py(c,l):l;this.styles=u.map(e=>e.replace(/%NS%/g,s)),this.styleUrls=n.getExternalStyles?.(c)}applyStyles(){this.sharedStylesHost.addStyles(this.styles,this.styleUrls)}destroy(){this.removeStylesOnCompDestroy&&Tu.size===0&&this.sharedStylesHost.removeStyles(this.styles,this.styleUrls)}},yy=class extends vy{contentAttr;hostAttr;constructor(e,t,n,r,i,a,o,s,c){let l=r+`-`+n.id;super(e,t,n,i,a,o,s,c,l),this.contentAttr=dy(l),this.hostAttr=fy(l)}applyToHost(e){this.applyStyles(),this.setAttribute(e,this.hostAttr,``)}createElement(e,t){let n=super.createElement(e,t);return super.setAttribute(n,this.contentAttr,``),n}},by=class e extends W_{supportsDOMEvents=!0;static makeCurrent(){U_(new e)}onAndCancel(e,t,n,r){return e.addEventListener(t,n,r),()=>{e.removeEventListener(t,n,r)}}dispatchEvent(e,t){e.dispatchEvent(t)}remove(e){e.remove()}createElement(e,t){return t||=this.getDefaultDocument(),t.createElement(e)}createHtmlDocument(){return document.implementation.createHTMLDocument(`fakeTitle`)}getDefaultDocument(){return document}isElementNode(e){return e.nodeType===Node.ELEMENT_NODE}isShadowRoot(e){return e instanceof DocumentFragment}getGlobalEventTarget(e,t){return t===`window`?window:t===`document`?e:t===`body`?e.body:null}getBaseHref(e){let t=Sy();return t==null?null:Cy(t)}resetBaseElement(){xy=null}getUserAgent(){return window.navigator.userAgent}getCookie(e){return Gv(document.cookie,e)}},xy=null;function Sy(){return xy||=document.head.querySelector(`base`),xy?xy.getAttribute(`href`):null}function Cy(e){return new URL(e,document.baseURI).pathname}var wy=[`alt`,`control`,`meta`,`shift`],Ty={"\b":`Backspace`," ":`Tab`,"":`Delete`,"\x1B":`Escape`,Del:`Delete`,Esc:`Escape`,Left:`ArrowLeft`,Right:`ArrowRight`,Up:`ArrowUp`,Down:`ArrowDown`,Menu:`ContextMenu`,Scroll:`ScrollLock`,Win:`OS`},Ey={alt:e=>e.altKey,control:e=>e.ctrlKey,meta:e=>e.metaKey,shift:e=>e.shiftKey},Dy=(()=>{class e extends qv{constructor(e){super(e)}supports(t){return e.parseEventName(t)!=null}addEventListener(t,n,r,i){let a=e.parseEventName(n),o=e.eventCallback(a.fullKey,r,this.manager.getZone());return this.manager.getZone().runOutsideAngular(()=>H_().onAndCancel(t,a.domEventName,o,i))}static parseEventName(t){let n=t.toLowerCase().split(`.`),r=n.shift();if(n.length===0||r!==`keydown`&&r!==`keyup`)return null;let i=e._normalizeKey(n.pop()),a=``,o=n.indexOf(`code`);if(o>-1&&(n.splice(o,1),a=`code.`),wy.forEach(e=>{let t=n.indexOf(e);t>-1&&(n.splice(t,1),a+=e+`.`)}),a+=i,n.length!=0||i.length===0)return null;let s={};return s.domEventName=r,s.fullKey=a,s}static matchEventFullKeyCode(e,t){let n=Ty[e.key]||e.key,r=``;return t.indexOf(`code.`)>-1&&(n=e.code,r=`code.`),n==null||!n?!1:(n=n.toLowerCase(),n===` `?n=`space`:n===`.`&&(n=`dot`),wy.forEach(t=>{if(t!==n){let n=Ey[t];n(e)&&(r+=t+`.`)}}),r+=n,r===t)}static eventCallback(t,n,r){return i=>{e.matchEventFullKeyCode(i,t)&&r.runGuarded(()=>n(i))}}static _normalizeKey(e){return e===`esc`?`escape`:e}static ɵfac=function(t){return new(t||e)(Vi(ls))};static ɵprov=oi({token:e,factory:e.ɵfac})}return e})();async function Oy(e,t,n){return B_({rootComponent:e,...ky(t,n)})}function ky(e,t){return{platformRef:t?.platformRef,appProviders:[...Py,...e?.providers??[]],platformProviders:Ny}}function Ay(){by.makeCurrent()}function jy(){return new Ps}function My(){return Dl(document),document}var Ny=[{provide:Vs,useValue:Kv},{provide:Bs,useValue:Ay,multi:!0},{provide:ls,useFactory:My}],Py=[{provide:_a,useValue:`root`},{provide:Ps,useFactory:jy},{provide:Yv,useClass:Jv,multi:!0},{provide:Yv,useClass:Dy,multi:!0},my,{provide:lp,useClass:ny},{provide:ny,useExisting:lp},Xv,{provide:Gf,useExisting:my},[]];function Fy(e,t){let n=`\x1B[${e}m`,r=`\x1B[${t}m`;return((e,...t)=>{if(Array.isArray(e)&&`raw`in e){let i=e,a=``;for(let e=0;e{let r=new zy({code:i,why:Ly(a.why,e),fix:Ly(a.fix,e),docs:o,cause:e.cause,sources:e.sources,data:Ly(a.data,e)},s);for(let e of t)e(r,n);return r};n[i]=s}return n}function Hy(e){return t=>{let n=`${e.bold(e.red(`[${t.name}]`))} ${t.message}`,r=[];return t.fix&&r.push(`${e.dim(`fix:`)} ${t.fix}`),t.sources?.length&&r.push(`${e.dim(`sources:`)} ${t.sources.join(`, `)}`),t.docs&&r.push(`${e.dim(`see:`)} ${e.cyan(t.docs)}`),r.length===0?n:[n,...r.map((t,n)=>`${e.dim(n{e=n,t=r}),resolve:e,reject:t}}var Jy=Math.random.bind(Math),Yy=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`;function Xy(e=21){let t=``,n=e;for(;n--;)t+=Yy[Jy()*64|0];return t}var Zy=6e4,Qy=e=>e,$y=Qy,{clearTimeout:eb,setTimeout:tb}=globalThis;function nb(e,t){let{post:n,on:r,off:i=()=>{},eventNames:a=[],serialize:o=Qy,deserialize:s=$y,resolver:c,bind:l=`rpc`,timeout:u=Zy,proxify:d=!0}=t,f=!1,p=new Map,m,h;async function g(e,r,i,a){if(f)throw Error(`[birpc] rpc is closed, cannot call "${e}"`);let s={m:e,a:r,t:`q`};a&&(s.o=!0);let c=async e=>n(o(e));if(i){await c(s);return}if(m)try{await m}finally{m=void 0}let{promise:l,resolve:d,reject:g}=qy(),_=Xy();s.i=_;let v;async function y(n=s){return u>=0&&(v=tb(()=>{try{if(t.onTimeoutError?.call(h,e,r)!==!0)throw Error(`[birpc] timeout on calling "${e}"`)}catch(e){g(e)}p.delete(_)},u),typeof v==`object`&&(v=v.unref?.())),p.set(_,{resolve:d,reject:g,timeoutId:v,method:e}),await c(n),l}try{t.onRequest?await t.onRequest.call(h,s,y,d):await y()}catch(e){if(t.onGeneralError?.call(h,e)!==!0)throw e;return}finally{eb(v),p.delete(_)}return l}let _={$call:(e,...t)=>g(e,t,!1),$callOptional:(e,...t)=>g(e,t,!1,!0),$callEvent:(e,...t)=>g(e,t,!0),$callRaw:e=>g(e.method,e.args,e.event,e.optional),$rejectPendingCalls:y,get $closed(){return f},get $meta(){return t.meta},$close:v,$functions:e};h=d?new Proxy({},{get(t,n){if(Object.hasOwn(_,n))return _[n];if(n===`then`&&!a.includes(`then`)&&!(`then`in e))return;let r=(...e)=>g(n,e,!0);if(a.includes(n))return r.asEvent=r,r;let i=(...e)=>g(n,e,!1);return i.asEvent=r,i}}):_;function v(e){f=!0,p.forEach(({reject:t,method:n})=>{let r=Error(`[birpc] rpc is closed, cannot call "${n}"`);if(e)return e.cause??=r,t(e);t(r)}),p.clear(),i(b)}function y(e){let t=Array.from(p.values()).map(({method:t,reject:n})=>e?e({method:t,reject:n}):n(Error(`[birpc]: rejected pending call "${t}".`)));return p.clear(),t}async function b(r,...i){let a;try{a=s(r)}catch(e){if(t.onGeneralError?.call(h,e)!==!0)throw e;return}if(a.t===`q`){let{m:r,a:s,o:u}=a,d,f,p=await(c?c.call(h,r,e[r]):e[r]);if(u&&(p||=()=>void 0),!p)f=Error(`[birpc] function "${r}" not found`);else try{d=await p.apply(l===`rpc`?h:e,s)}catch(e){f=e}if(a.i){if(f&&t.onFunctionError&&t.onFunctionError.call(h,f,r,s)===!0)return;if(!f)try{await n(o({t:`s`,i:a.i,r:d}),...i);return}catch(e){if(f=e,t.onGeneralError?.call(h,e,r,s)!==!0)throw e}try{await n(o({t:`s`,i:a.i,e:f}),...i)}catch(e){if(t.onGeneralError?.call(h,e,r,s)!==!0)throw e}}}else{let{i:e,r:t,e:n}=a,r=p.get(e);r&&(eb(r.timeoutId),n?r.reject(n):r.resolve(t)),p.delete(e)}}return m=r(b),h}function rb(e,t){return t.safety?t.safety:e===`static`||e===`query`||e==null?`read`:`action`}var ib=Object.freeze({type:`object`,additionalProperties:!0});function ab(e){let t=e[`~standard`];if(t.jsonSchema)try{return t.jsonSchema.input({target:`draft-2020-12`})}catch{return ib}return ib}function ob(e){if(!e||e.length===0)return{type:`object`,properties:{}};let t={},n=[];for(let r=0;rn[`arg${t}`]);if(`arg0`in n){let e=[];for(;`arg${e.length}`in n;)e.push(n[`arg${e.length}`]);return e}return Object.keys(n).length===0?[]:void 0}function cb(e,t){return sb(e,t)??[e]}function lb(e){return typeof e==`string`?`'${e}'`:new pb().serialize(e)}var ub=` _-,;:!?.'"()[]{}@*/\\&#%\`^+<=>|~$0123456789abcdefghijklmnopqrstuvwxyz`,db=(function(){let e=new Uint8Array(128);for(let t=0;t<69;t++)e[ub.charCodeAt(t)]=t+1;for(let t=65;t<=90;t++)e[t]=e[t+32];return e})();function fb(e,t){if(e===t)return 0;let n=Math.min(e.length,t.length),r=0;for(let i=0;ia?-1:1)}return e.length===t.length?r:e.lengththis.compare(e[0],t[0])),r=`${e}{`;for(let e=0;ethis.compare(e,t)))}`}$Map(e){return this.serializeObjectEntries(`Map`,e.entries())}}for(let t of[`Error`,`RegExp`,`URL`])e.prototype[`$`+t]=function(e){return`${t}(${e})`};for(let t of[`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float32Array`,`Float64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`,`)}]`};for(let t of[`BigInt64Array`,`BigUint64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`n,`)}${e.length>0?`n`:``}]`};return e})(),mb=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225],hb=[1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,-778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998],gb=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_`,_b=[],vb=class{_data=new yb;_hash=new yb([...mb]);_nDataBytes=0;_minBufferSize=0;finalize(e){e&&this._append(e);let t=this._nDataBytes*8,n=this._data.sigBytes*8;return this._data.words[n>>>5]|=128<<24-n%32,this._data.words[(n+64>>>9<<4)+14]=Math.floor(t/4294967296),this._data.words[(n+64>>>9<<4)+15]=t,this._data.sigBytes=this._data.words.length*4,this._process(),this._hash}_doProcessBlock(e,t){let n=this._hash.words,r=n[0],i=n[1],a=n[2],o=n[3],s=n[4],c=n[5],l=n[6],u=n[7];for(let n=0;n<64;n++){if(n<16)_b[n]=e[t+n]|0;else{let e=_b[n-15],t=(e<<25|e>>>7)^(e<<14|e>>>18)^e>>>3,r=_b[n-2],i=(r<<15|r>>>17)^(r<<13|r>>>19)^r>>>10;_b[n]=t+_b[n-7]+i+_b[n-16]}let d=s&c^~s&l,f=r&i^r&a^i&a,p=(r<<30|r>>>2)^(r<<19|r>>>13)^(r<<10|r>>>22),m=(s<<26|s>>>6)^(s<<21|s>>>11)^(s<<7|s>>>25),h=u+m+d+hb[n]+_b[n],g=p+f;u=l,l=c,c=s,s=o+h|0,o=a,a=i,i=r,r=h+g|0}n[0]=n[0]+r|0,n[1]=n[1]+i|0,n[2]=n[2]+a|0,n[3]=n[3]+o|0,n[4]=n[4]+s|0,n[5]=n[5]+c|0,n[6]=n[6]+l|0,n[7]=n[7]+u|0}_append(e){typeof e==`string`&&(e=yb.fromUtf8(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes}_process(e){let t,n=this._data.sigBytes/64;n=e?Math.ceil(n):Math.max((n|0)-this._minBufferSize,0);let r=n*16,i=Math.min(r*4,this._data.sigBytes);if(r){for(let e=0;e>>2]|=(n.charCodeAt(e)&255)<<24-e%4*8;return new e(i,r)}toBase64(){let e=[];for(let t=0;t>>2]>>>24-t%4*8&255,r=this.words[t+1>>>2]>>>24-(t+1)%4*8&255,i=this.words[t+2>>>2]>>>24-(t+2)%4*8&255,a=n<<16|r<<8|i;for(let n=0;n<4&&t*8+n*6>>6*(3-n)&63))}return e.join(``)}concat(e){if(this.words[this.sigBytes>>>2]&=4294967295<<32-this.sigBytes%4*8,this.words.length=Math.ceil(this.sigBytes/4),this.sigBytes%4)for(let t=0;t>>2]>>>24-t%4*8&255;this.words[this.sigBytes+t>>>2]|=n<<24-(this.sigBytes+t)%4*8}else for(let t=0;t>>2]=e.words[t>>>2];this.sigBytes+=e.sigBytes}};function bb(e){return new vb().finalize(e).toBase64()}function xb(e){return bb(lb(e))}function Sb(e){return xb(e)}function Cb(){let e={};function t(t,...n){let r=e[t]||[];for(let e=0,t=r.length;e{e[t]=e[t]?.filter(e=>n!==e)}}function i(e,t){let n=r(e,((...e)=>(n(),t(...e))));return n}return{_listeners:e,emit:t,emitOnce:n,on:r,once:i}}var wb=/^[\w+.-]{2,}:\/\//;function Tb(e){return e.endsWith(`/`)?e:`${e}/`}function Eb(e){return(e.endsWith(`/`)?e.slice(0,-1):e)||`/`}function Db(e,...t){let n=e;for(let e of t)e&&e!==`/`&&(n=n?Tb(n)+e.replace(/^\.?\//,``):e);return n}function Ob(e,t){if(!t||t===`/`||wb.test(e))return e;let n=Eb(t);return e.startsWith(n)?e:Db(n,e)}function kb(e,t){let n=e.match(wb);return t+(n?e.slice(n[0].length):e)}var Ab=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`;function jb(e=21){let t=``,n=e;for(;n--;)t+=Ab[Math.random()*64|0];return t}var Mb=Symbol.for(`immer-nothing`),Nb=Symbol.for(`immer-draftable`),Pb=Symbol.for(`immer-state`),Fb=[function(e){return`The plugin for '${e}' has not been loaded into Immer. To enable the plugin, import and call \`enable${e}()\` when initializing your application.`},function(e){return`produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '${e}'`},`This object has been frozen and should not be mutated`,function(e){return`Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? `+e},`An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.`,`Immer forbids circular references`,"The first or second argument to `produce` must be a function","The third argument to `produce` must be a function or undefined","First argument to `createDraft` must be a plain object, an array, or an immerable object","First argument to `finishDraft` must be a draft returned by `createDraft`",function(e){return`'current' expects a draft, got: ${e}`},`Object.defineProperty() cannot be used on an Immer draft`,`Object.setPrototypeOf() cannot be used on an Immer draft`,`Immer only supports deleting array indices`,`Immer only supports setting array indices and the 'length' property`,function(e){return`'original' expects a draft, got: ${e}`}];function Ib(e,...t){{let n=Fb[e],r=ox(n)?n.apply(null,t):n;throw Error(`[Immer] ${r}`)}}var Lb=Object,Rb=Lb.getPrototypeOf,zb=`constructor`,Bb=`prototype`,Vb=`configurable`,Hb=`enumerable`,Ub=`writable`,Wb=`value`,Gb=e=>!!e&&!!e[Pb];function Kb(e){return e?Yb(e)||nx(e)||!!e[Nb]||!!e[zb]?.[Nb]||rx(e)||ix(e):!1}var qb=Lb[Bb][zb].toString(),Jb=new WeakMap;function Yb(e){if(!e||!ax(e))return!1;let t=Rb(e);if(t===null||t===Lb[Bb])return!0;let n=Lb.hasOwnProperty.call(t,zb)&&t[zb];if(n===Object)return!0;if(!ox(n))return!1;let r=Jb.get(n);return r===void 0&&(r=Function.toString.call(n),Jb.set(n,r)),r===qb}function Xb(e,t,n=!0){Zb(e)===0?(n?Reflect.ownKeys(e):Lb.keys(e)).forEach(n=>{t(n,e[n],e)}):e.forEach((n,r)=>t(r,n,e))}function Zb(e){let t=e[Pb];return t?t.type_:nx(e)?1:rx(e)?2:ix(e)?3:0}var Qb=(e,t,n=Zb(e))=>n===2?e.has(t):Lb[Bb].hasOwnProperty.call(e,t),$b=(e,t,n=Zb(e))=>n===2?e.get(t):e[t],ex=(e,t,n,r=Zb(e))=>{r===2?e.set(t,n):r===3?e.add(n):e[t]=n};function tx(e,t){return e===t?e!==0||1/e==1/t:e!==e&&t!==t}var nx=Array.isArray,rx=e=>e instanceof Map,ix=e=>e instanceof Set,ax=e=>typeof e==`object`,ox=e=>typeof e==`function`,sx=e=>typeof e==`boolean`;function cx(e){let t=+e;return Number.isInteger(t)&&String(t)===e}var lx=e=>ax(e)?e?.[Pb]:null,ux=e=>e.copy_||e.base_,dx=e=>e.modified_?e.copy_:e.base_;function fx(e,t){if(rx(e))return new Map(e);if(ix(e))return new Set(e);if(nx(e))return Array[Bb].slice.call(e);let n=Yb(e);if(t===!0||t===`class_only`&&!n){let t=Lb.getOwnPropertyDescriptors(e);delete t[Pb];let n=Reflect.ownKeys(t);for(let r=0;r1&&Lb.defineProperties(e,{set:hx,add:hx,clear:hx,delete:hx}),Lb.freeze(e),t&&Xb(e,(e,t)=>{px(t,!0)},!1),e)}function mx(){Ib(2)}var hx={[Wb]:mx};function gx(e){return e===null||!ax(e)||Lb.isFrozen(e)}var _x=`MapSet`,vx=`Patches`,yx=`ArrayMethods`,bx={};function xx(e){let t=bx[e];return t||Ib(0,e),t}var Sx=e=>!!bx[e];function Cx(e,t){bx[e]||(bx[e]=t)}var wx,Tx=()=>wx,Ex=(e,t)=>({drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0,handledSet_:new Set,processedForPatches_:new Set,mapSetPlugin_:Sx(_x)?xx(_x):void 0,arrayMethodsPlugin_:Sx(yx)?xx(yx):void 0});function Dx(e,t){t&&(e.patchPlugin_=xx(vx),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function Ox(e){kx(e),e.drafts_.forEach(jx),e.drafts_=null}function kx(e){e===wx&&(wx=e.parent_)}var Ax=e=>wx=Ex(wx,e);function jx(e){let t=e[Pb];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function Mx(e,t){t.unfinalizedDrafts_=t.drafts_.length;let n=t.drafts_[0];if(e!==void 0&&e!==n){n[Pb].modified_&&(Ox(t),Ib(4)),Kb(e)&&(e=Nx(t,e));let{patchPlugin_:r}=t;r&&r.generateReplacementPatches_(n[Pb].base_,e,t)}else e=Nx(t,n);return Px(t,e,!0),Ox(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e===Mb?void 0:e}function Nx(e,t){if(gx(t))return t;let n=t[Pb];if(!n)return Hx(t,e.handledSet_,e);if(!Ix(n,e))return t;if(!n.modified_)return n.base_;if(!n.finalized_){let{callbacks_:t}=n;if(t)for(;t.length>0;)t.pop()(e);Bx(n,e)}return n.copy_}function Px(e,t,n=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&px(t,n)}function Fx(e){e.finalized_=!0,e.scope_.unfinalizedDrafts_--}var Ix=(e,t)=>e.scope_===t,Lx=[];function Rx(e,t,n,r){let i=ux(e),a=e.type_;if(r!==void 0&&$b(i,r,a)===t){ex(i,r,n,a);return}if(!e.draftLocations_){let t=e.draftLocations_=new Map;Xb(i,(e,n)=>{if(Gb(n)){let r=t.get(n)||[];r.push(e),t.set(n,r)}})}let o=e.draftLocations_.get(t)??Lx;for(let e of o)ex(i,e,n,a)}function zx(e,t,n){e.callbacks_.push(function(r){let i=t;if(!i||!Ix(i,r))return;r.mapSetPlugin_?.fixSetContents(i);let a=dx(i);Rx(e,i.draft_??i,a,n),Bx(i,r)})}function Bx(e,t){if(e.modified_&&!e.finalized_&&(e.type_===3||e.type_===1&&e.allIndicesReassigned_||(e.assigned_?.size??0)>0)){let{patchPlugin_:n}=t;if(n){let r=n.getPath(e);r&&n.generatePatches_(e,r,t)}Fx(e)}}function Vx(e,t,n){let{scope_:r}=e;if(Gb(n)){let i=n[Pb];Ix(i,r)&&i.callbacks_.push(function(){Zx(e),Rx(e,n,dx(i),t)})}else Kb(n)&&e.callbacks_.push(function(){let i=ux(e);e.type_===3?i.has(n)&&Hx(n,r.handledSet_,r):$b(i,t,e.type_)===n&&r.drafts_.length>1&&(e.assigned_.get(t)??!1)===!0&&e.copy_&&Hx($b(e.copy_,t,e.type_),r.handledSet_,r)})}function Hx(e,t,n){return!n.immer_.autoFreeze_&&n.unfinalizedDrafts_<1||Gb(e)||t.has(e)||!Kb(e)||gx(e)?e:(t.add(e),Xb(e,(r,i)=>{if(Gb(i)){let t=i[Pb];Ix(t,n)&&(ex(e,r,dx(t),e.type_),Fx(t))}else Kb(i)&&Hx(i,t,n)}),e)}function Ux(e,t){let n=nx(e),r={type_:+!!n,scope_:t?t.scope_:Tx(),modified_:!1,finalized_:!1,assigned_:void 0,parent_:t,base_:e,draft_:null,copy_:null,revoke_:null,isManual_:!1,callbacks_:void 0},i=r,a=Wx;n&&(i=[r],a=Gx);let{revoke:o,proxy:s}=Proxy.revocable(i,a);return r.draft_=s,r.revoke_=o,[s,r]}var Wx={get(e,t){if(t===Pb)return e;let n=e.scope_.arrayMethodsPlugin_,r=e.type_===1&&typeof t==`string`;if(r&&n?.isArrayOperationMethod(t))return n.createMethodInterceptor(e,t);let i=ux(e);if(!Qb(i,t,e.type_))return Jx(e,i,t);let a=i[t];if(e.finalized_||!Kb(a)||r&&e.operationMethod&&n?.isMutatingArrayMethod(e.operationMethod)&&cx(t))return a;if(a===Kx(e.base_,t)||qx(e,t,a)){Zx(e);let n=e.type_===1?+t:t,r=$x(e.scope_,a,e,n);return e.copy_[n]=r}return a},has(e,t){return t in ux(e)},ownKeys(e){return Reflect.ownKeys(ux(e))},set(e,t,n){let r=Yx(ux(e),t);if(r?.set)return r.set.call(e.draft_,n),!0;if(!e.modified_){let r=Kx(ux(e),t),i=r?.[Pb];if(i&&i.base_===n)return e.copy_[t]=n,e.assigned_.set(t,!1),!0;if(tx(n,r)&&(n!==void 0||Qb(e.base_,t,e.type_)))return!0;Zx(e),Xx(e)}return e.copy_[t]===n&&(n!==void 0||Qb(e.copy_,t,e.type_))||Number.isNaN(n)&&Number.isNaN(e.copy_[t])?!0:(e.copy_[t]=n,e.assigned_.set(t,!0),Vx(e,t,n),!0)},deleteProperty(e,t){return Zx(e),Kx(e.base_,t)!==void 0||t in e.base_?(e.assigned_.set(t,!1),Xx(e)):e.assigned_.delete(t),e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){let n=ux(e),r=Reflect.getOwnPropertyDescriptor(n,t);return r&&{[Ub]:!0,[Vb]:e.type_!==1||t!==`length`,[Hb]:r[Hb],[Wb]:n[t]}},defineProperty(){Ib(11)},getPrototypeOf(e){return Rb(e.base_)},setPrototypeOf(){Ib(12)}},Gx={};for(let e in Wx){let t=Wx[e];Gx[e]=function(){let e=arguments;return e[0]=e[0][0],t.apply(this,e)}}Gx.deleteProperty=function(e,t){return isNaN(parseInt(t))&&Ib(13),Gx.set.call(this,e,t,void 0)},Gx.set=function(e,t,n){return t!==`length`&&isNaN(parseInt(t))&&Ib(14),Wx.set.call(this,e[0],t,n,e[0])};function Kx(e,t){let n=e[Pb];return(n?ux(n):e)[t]}function qx(e,t,n){return e.type_!==1||!e.allIndicesReassigned_||e.assigned_?.get(t)||!Kb(n)||n[Pb]?!1:e.baseRefs_.has(n)}function Jx(e,t,n){let r=Yx(t,n);return r?Wb in r?r[Wb]:r.get?.call(e.draft_):void 0}function Yx(e,t){if(!(t in e))return;let n=Rb(e);for(;n;){let e=Object.getOwnPropertyDescriptor(n,t);if(e)return e;n=Rb(n)}}function Xx(e){e.modified_||(e.modified_=!0,e.parent_&&Xx(e.parent_))}function Zx(e){e.copy_||=(e.assigned_=new Map,fx(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var Qx=class{constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!1,this.produce=(e,t,n)=>{if(ox(e)&&!ox(t)){let n=t;t=e;let r=this;return function(e=n,...i){return r.produce(e,e=>t.call(this,e,...i))}}ox(t)||Ib(6),n!==void 0&&!ox(n)&&Ib(7);let r;if(Kb(e)){let i=Ax(this),a=$x(i,e,void 0),o=!0;try{r=t(a),o=!1}finally{o?Ox(i):kx(i)}return Dx(i,n),Mx(r,i)}if(!e||!ax(e)){if(r=t(e),r===void 0&&(r=e),r===Mb&&(r=void 0),this.autoFreeze_&&px(r,!0),n){let t=[],i=[];xx(vx).generateReplacementPatches_(e,r,{patches_:t,inversePatches_:i}),n(t,i)}return r}Ib(1,e)},this.produceWithPatches=(e,t)=>{if(ox(e))return(t,...n)=>this.produceWithPatches(t,t=>e(t,...n));let n,r;return[this.produce(e,t,(e,t)=>{n=e,r=t}),n,r]},sx(e?.autoFreeze)&&this.setAutoFreeze(e.autoFreeze),sx(e?.useStrictShallowCopy)&&this.setUseStrictShallowCopy(e.useStrictShallowCopy),sx(e?.useStrictIteration)&&this.setUseStrictIteration(e.useStrictIteration)}createDraft(e){Kb(e)||Ib(8),Gb(e)&&(e=eS(e));let t=Ax(this),n=$x(t,e,void 0);return n[Pb].isManual_=!0,kx(t),n}finishDraft(e,t){let n=e&&e[Pb];(!n||!n.isManual_)&&Ib(9);let{scope_:r}=n;return Dx(r,t),Mx(void 0,r)}setAutoFreeze(e){this.autoFreeze_=e}setUseStrictShallowCopy(e){this.useStrictShallowCopy_=e}setUseStrictIteration(e){this.useStrictIteration_=e}shouldUseStrictIteration(){return this.useStrictIteration_}applyPatches(e,t){let n;for(n=t.length-1;n>=0;n--){let r=t[n];if(r.path.length===0&&r.op===`replace`){e=r.value;break}}n>-1&&(t=t.slice(n+1));let r=xx(vx).applyPatches_;return Gb(e)?r(e,t):this.produce(e,e=>r(e,t))}};function $x(e,t,n,r){let[i,a]=rx(t)?xx(_x).proxyMap_(t,n):ix(t)?xx(_x).proxySet_(t,n):Ux(t,n);return(n?.scope_??Tx()).drafts_.push(i),a.callbacks_=n?.callbacks_??[],a.key_=r,n&&r!==void 0?zx(n,a,r):a.callbacks_.push(function(e){e.mapSetPlugin_?.fixSetContents(a);let{patchPlugin_:t}=e;a.modified_&&t&&t.generatePatches_(a,[],e)}),i}function eS(e){return Gb(e)||Ib(10,e),tS(e)}function tS(e){if(!Kb(e)||gx(e))return e;let t=e[Pb],n,r=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,n=fx(e,t.scope_.immer_.useStrictShallowCopy_),r=t.scope_.immer_.shouldUseStrictIteration()}else n=fx(e,!0);return Xb(n,(e,t)=>{ex(n,e,tS(t))},r),t&&(t.finalized_=!1),n}function nS(){Fb.push(`Sets cannot have "replace" patches.`,function(e){return`Unsupported patch operation: `+e},function(e){return`Cannot apply patch, path doesn't resolve: `+e},`Patching reserved attributes like __proto__, prototype and constructor is not allowed`);function e(n,r=[]){if(n.key_!==void 0){let e=n.parent_.copy_??n.parent_.base_,t=lx($b(e,n.key_)),i=$b(e,n.key_);if(i===void 0||i!==n.draft_&&i!==n.base_&&i!==n.copy_||t!=null&&t.base_!==n.base_)return null;let a=n.parent_.type_===3,o;if(a){let e=n.parent_;o=Array.from(e.drafts_.keys()).indexOf(n.key_)}else o=n.key_;if(!(a&&e.size>o||Qb(e,o)))return null;r.push(o)}if(n.parent_)return e(n.parent_,r);r.reverse();try{t(n.copy_,r)}catch{return null}return r}function t(e,t){let n=e;for(let e=0;e{let u=$b(o,e,c),f=$b(s,e,c),p=l?Qb(o,e)?n:`add`:r;if(u===f&&p===n)return;let m=t.concat(e);i.push(p===r?{op:p,path:m}:{op:p,path:m,value:d(f)}),a.push(p===`add`?{op:r,path:m}:p===r?{op:`add`,path:m,value:d(u)}:{op:n,path:m,value:d(u)})})}function s(e,t,n,i){let{base_:a,copy_:o}=e,s=0;a.forEach(e=>{if(!o.has(e)){let a=t.concat([s]);n.push({op:r,path:a,value:e}),i.unshift({op:`add`,path:a,value:e})}s++}),s=0,o.forEach(e=>{if(!a.has(e)){let a=t.concat([s]);n.push({op:`add`,path:a,value:e}),i.unshift({op:r,path:a,value:e})}s++})}function c(e,t,r){let{patches_:i,inversePatches_:a}=r;i.push({op:n,path:[],value:t===Mb?void 0:t}),a.push({op:n,path:[],value:e})}function l(e,t){return t.forEach(t=>{let{path:i,op:a}=t,o=e;for(let e=0;e[e,u(t)]));if(ix(e))return new Set(Array.from(e).map(u));let t=Object.create(Rb(e));for(let n in e)t[n]=u(e[n]);return Qb(e,Nb)&&(t[Nb]=e[Nb]),t}function d(e){return Gb(e)?u(e):e}Cx(vx,{applyPatches_:l,generatePatches_:i,generateReplacementPatches_:c,getPath:e})}globalThis.Iterator?.from;var rS=new Qx,iS=rS.produce,aS=rS.produceWithPatches.bind(rS),oS=rS.applyPatches.bind(rS),sS=1e3;function cS(e,t){if(e.add(t),e.size>sS){let t=e.values().next().value;t!==void 0&&e.delete(t)}}function lS(e){let{enablePatches:t=!1}=e;t&&nS();let n=Cb(),r=e.initialValue,i=new Set;return{on:n.on,value:()=>r,patch:(e,t=jb())=>{i.has(t)||(nS(),r=oS(r,e),cS(i,t),n.emit(`updated`,r,void 0,t))},mutate:(e,a=jb())=>{if(!i.has(a)){if(cS(i,a),t){let[t,i]=aS(r,e);if(t===r)return;r=t,n.emit(`updated`,r,i,a)}else{let t=iS(r,e);if(t===r)return;r=t,n.emit(`updated`,r,void 0,a)}}},syncIds:i}}var uS=typeof self==`object`?self:globalThis,dS=new Set([`Error`,`EvalError`,`RangeError`,`ReferenceError`,`SyntaxError`,`TypeError`,`URIError`,`AggregateError`]),fS=new Set([`Boolean`,`Number`,`String`,`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float16Array`,`Float32Array`,`Float64Array`,`BigInt64Array`,`BigUint64Array`]);function pS(e,t){let n=(t,n)=>(e.set(n,t),t),r=i=>{if(e.has(i))return e.get(i);let[a,o]=t[i];switch(a){case 0:case-1:return n(o,i);case 1:{let e=n([],i);for(let t of o)e.push(r(t));return e}case 2:{let e=n({},i);for(let[t,n]of o)e[r(t)]=r(n);return e}case 3:return n(new Date(o),i);case 4:{let{source:e,flags:t}=o;return n(new RegExp(e,t),i)}case 5:{let e=n(new Map,i);for(let[t,n]of o)e.set(r(t),r(n));return e}case 6:{let e=n(new Set,i);for(let t of o)e.add(r(t));return e}case 7:{let{name:e,message:t}=o,r=dS.has(e)?uS[e]:void 0;return n(new(r??uS.Error)(t),i)}case 8:return n(BigInt(o),i);case`BigInt`:return n(Object(BigInt(o)),i);case`ArrayBuffer`:return n(new Uint8Array(o).buffer,o);case`DataView`:{let{buffer:e}=new Uint8Array(o);return n(new DataView(e),o)}}if(typeof a==`string`&&fS.has(a))return n(new uS[a](o),i);throw TypeError(`unable to deserialize unsafe or unknown type: ${String(a)}`)};return r}function mS(e){return pS(new Map,e)(0)}var hS=``,{toString:gS}={},{keys:_S}=Object;function vS(e){let t=typeof e;if(t!==`object`||!e)return[0,t];let n=gS.call(e).slice(8,-1);switch(n){case`Array`:return[1,hS];case`Object`:return[2,hS];case`Date`:return[3,hS];case`RegExp`:return[4,hS];case`Map`:return[5,hS];case`Set`:return[6,hS];case`DataView`:return[1,n]}return n.includes(`Array`)?[1,n]:n.includes(`Error`)?[7,n]:[2,n]}function yS([e,t]){return e===0&&(t===`function`||t===`symbol`)}function bS(e,t,n,r){let i=(e,t)=>{let i=r.push(e)-1;return n.set(t,i),i},a=r=>{if(n.has(r))return n.get(r);let[o,s]=vS(r);switch(o){case 0:{let t=r;switch(s){case`bigint`:o=8,t=r.toString();break;case`function`:case`symbol`:if(e)throw TypeError(`unable to serialize ${s}`);t=null;break;case`undefined`:return i([-1],r)}return i([o,t],r)}case 1:{if(s){let e=r;return s===`DataView`?e=new Uint8Array(r.buffer):s===`ArrayBuffer`&&(e=new Uint8Array(r)),i([s,[...e]],r)}let e=[],t=i([o,e],r);for(let t of r)e.push(a(t));return t}case 2:{if(s)switch(s){case`BigInt`:return i([s,r.toString()],r);case`Boolean`:case`Number`:case`String`:return i([s,r.valueOf()],r)}if(t&&`toJSON`in r)return a(r.toJSON());let n=[],c=i([o,n],r);for(let t of _S(r))(e||!yS(vS(r[t])))&&n.push([a(t),a(r[t])]);return c}case 3:return i([o,r.toISOString()],r);case 4:{let{source:e,flags:t}=r;return i([o,{source:e,flags:t}],r)}case 5:{let t=[],n=i([o,t],r);for(let[n,i]of r)(e||!(yS(vS(n))||yS(vS(i))))&&t.push([a(n),a(i)]);return n}case 6:{let t=[],n=i([o,t],r);for(let n of r)(e||!yS(vS(n)))&&t.push(a(n));return n}}let{message:c}=r;return i([o,{name:s,message:c}],r)};return a}function xS(e,t={}){let n=[];return bS(!(t.json||t.lossy),!!t.json,new Map,n)(e),n}var{parse:SS,stringify:CS}=JSON,wS={json:!0,lossy:!0};function TS(e){return mS(SS(e))}function ES(e){return CS(xS(e,wS))}function DS(e){return mS(e)}function OS(e){return ES(e)}function kS(e){return TS(e)}var AS=256,jS=class extends Error{name=`StreamClosedError`};function MS(e={}){let t=e.id??jb(),n=Math.max(0,e.replayWindow??0),r=Cb(),i=new AbortController,a=[],o=!1,s=0;function c(e){if(o)throw new jS(`Cannot write to a closed stream "${t}"`);s+=1,n>0&&(a.push({seq:s,chunk:e}),a.length>n&&(a.length-n===1?a.shift():a.splice(0,a.length-n))),r.emit(`chunk`,s,e)}function l(e){if(o)return;o=!0;let t=PS(e);i.abort(e),r.emit(`end`,t)}function u(){o||(o=!0,i.signal.aborted||i.abort(`stream closed`),r.emit(`end`,void 0))}function d(e){o||i.signal.aborted||i.abort(e??`aborted`)}let f=new WritableStream({write(e){c(e)},close(){u()},abort(e){l(e)}});return{id:t,signal:i.signal,get closed(){return o},get lastSeq(){return s},write:c,error:l,close:u,abort:d,writable:f,events:r,buffer:a}}function NS(e={}){let t=e.id??jb(),n=Math.max(1,e.highWaterMark??AS),r=[],i=0,a=!1,o=!1,s,c,l,u;function d(){if(c){if(r.length>0){let e=r.shift(),t=c;c=void 0,t.resolve({value:e,done:!1});return}if(a){let e=c;if(c=void 0,s){let t=Error(s.message);t.name=s.name,e.reject(t)}else e.resolve({value:void 0,done:!0})}}}function f(){if(l){for(;r.length>0;){let e=r.shift();try{l.enqueue(e)}catch{break}}if(a&&l){try{if(s){let e=Error(s.message);e.name=s.name,l.error(e)}else l.close()}catch{}l=void 0}}}function p(t,s){if(!(a||o)&&!(t<=i)){if(i=t,r.push(s),r.length>n){let t=r.length-n;r.splice(0,t),e.onOverflow?.(t)}d(),u&&f()}}function m(e){a||(a=!0,s=e,d(),u&&f())}function h(){o||a||(o=!0,e.onCancel?.(),m(void 0))}function g(){return u||(u=new ReadableStream({start(e){l=e,f()},cancel(){h()}}),u)}return{id:t,get cancelled(){return o},get done(){return a},get lastSeenSeq(){return i},get readable(){return g()},cancel:h,_push:p,_end:m,[Symbol.asyncIterator](){return{next(){if(r.length>0)return Promise.resolve({value:r.shift(),done:!1});if(a){if(s){let e=Error(s.message);return e.name=s.name,Promise.reject(e)}return Promise.resolve({value:void 0,done:!0})}return new Promise((e,t)=>{c={resolve:e,reject:t}})},return(){return h(),Promise.resolve({value:void 0,done:!0})}}}}}function PS(e){if(e instanceof Error)return{name:e.name||`Error`,message:e.message};if(typeof e==`string`)return{name:`Error`,message:e};try{return{name:`Error`,message:JSON.stringify(e)}}catch{return{name:`Error`,message:String(e)}}}var FS=128;function IS(e){return e.replace(/[^\w-]+/g,`_`).slice(0,FS)}var LS=`modulepreload`,RS=function(e,t){return new URL(e,t).href},zS={},BS=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=RS(t,n),t=s(t),t in zS)return;zS[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:LS,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},VS=`__connection.json`,HS=`__DEVFRAME_CONNECTION__`,US=`x-birpc-session`,WS=`__rpc-dump/index.json`,GS=`devframe:services`,KS=`devframe_otp`,qS=`devframe_auth_token`;Uy.postMessage.remoteAssetsError;var JS=class{cacheMap=new Map;options;keySerializer;constructor(e){this.options=e,this.keySerializer=e.keySerializer||(e=>Sb(e))}updateOptions(e){this.options={...this.options,...e}}cached(e,t){let n=this.cacheMap.get(e);if(n)return n.get(this.keySerializer(t))}has(e,t){return this.cacheMap.get(e)?.has(this.keySerializer(t))??!1}apply(e,t){let n=this.cacheMap.get(e.m)||new Map;n.set(this.keySerializer(e.a),t),this.cacheMap.set(e.m,n)}validate(e){return this.options.functions.includes(e)}clear(e){e?this.cacheMap.delete(e):this.cacheMap.clear()}},YS=Ky({docsBase:`https://devfra.me/errors`,codes:{DF0019:{why:e=>`RPC function "${e.name}" has \`agent\` set but \`jsonSerializable\` is \`false\`; MCP requires JSON-serializable data.`,fix:"Remove `jsonSerializable: false`, or remove `agent` to keep it RPC-only."},DF0020:{why:e=>`RPC function "${e.name}" declares \`jsonSerializable: true\` but the value at "${e.path}" is a ${e.type}.`,fix:"Either drop `jsonSerializable: true` (falls back to structured-clone) or change the value to a JSON-safe shape."},DF0021:{why:e=>`RPC function "${e.name}" is already registered`,fix:"Use the `force` parameter to overwrite an existing registration."},DF0022:{why:e=>`RPC function "${e.name}" is not registered. Use register() to add new functions.`},DF0023:{why:e=>`RPC function "${e.name}" is not registered`},DF0024:{why:e=>`Either handler or setup function must be provided for RPC function "${e.name}"`},DF0025:{why:e=>`Function "${e.name}" not found in dump store`},DF0026:{why:e=>`No dump match for "${e.name}" with args: ${e.args}`},DF0027:{why:e=>`Function "${e.name}" with type "${e.type}" cannot have dump configuration. Only "static" and "query" types support dumps.`},DF0028:{why:e=>`Function "${e.name}" with type "${e.type}" cannot use \`snapshot: true\`. Only "query" functions support this sugar; "static" functions have equivalent default behavior already.`,fix:"Remove `snapshot: true`, or change the function type to `query`."},DF0043:{why:e=>`RPC function "${e.name}" received an invalid argument at position ${e.index}: ${e.issues}`,fix:"Pass a value that satisfies the `args` schema declared for this function."},DF0044:{why:e=>`RPC function "${e.name}" returned a value that failed its \`returns\` schema: ${e.issues}`,fix:"Make the handler return a value that satisfies the `returns` schema, or relax the schema."}}});function XS(e){if(e.agent&&e.jsonSerializable===!1)throw YS.DF0019({name:e.name});e.agent&&!e.jsonSerializable&&(e.jsonSerializable=!0)}async function ZS(e,t){let n=e[`~standard`].validate(t);return n instanceof Promise?await n:n}function QS(e){return e.map(e=>{let t=e.path?.map(e=>typeof e==`object`?e.key:e).join(`.`);return t?`${t}: ${e.message}`:e.message}).join(`; `)}async function $S(e,t,n){let r=n.slice();if(!t||t.length===0)return r;for(let r=0;r{n.get(t)===r&&n.delete(t)}),n.set(t,r)),await r}if(!e.__promise){let n=Promise.resolve(e.setup(t));n.catch(()=>{e.__promise===n&&(e.__promise=void 0)}),e.__promise=n}return await e.__promise}async function nC(e,t){let n=e.handler;if(!n){let r=await tC(e,t);if(!r.handler)throw YS.DF0024({name:e.name});n=r.handler}let r=e.args,i=e.returns;if(!r&&!i)return n;let a=n;return async(...t)=>{let n=await $S(e.name,r,t),o=await a(...n);return await eC(e.name,i,o)}}var rC=class{context;definitions=new Map;functions;_onChanged=[];constructor(e){this.context=e;let t=this.definitions,n=this;this.functions=new Proxy({},{get(e,r){let i=t.get(r);if(i)return nC(i,n.context)},has(e,n){return t.has(n)},getOwnPropertyDescriptor(e,n){return{value:t.get(n)?.handler,configurable:!0,enumerable:!0}},ownKeys(){return Array.from(t.keys())}})}register(e,t=!1){if(this.definitions.has(e.name)&&!t)throw YS.DF0021({name:e.name});XS(e),this.definitions.set(e.name,e),this._onChanged.forEach(t=>t(e.name))}update(e,t=!1){if(!this.definitions.has(e.name)&&!t)throw YS.DF0022({name:e.name});XS(e),this.definitions.set(e.name,e),this._onChanged.forEach(t=>t(e.name))}onChanged(e){return this._onChanged.push(e),()=>{let t=this._onChanged.indexOf(e);t!==-1&&this._onChanged.splice(t,1)}}async getHandler(e){return await nC(this.definitions.get(e),this.context)}getSchema(e){let t=this.definitions.get(e);if(!t)throw YS.DF0023({name:String(e)});return{args:t.args,returns:t.returns}}has(e){return this.definitions.has(e)}get(e){return this.definitions.get(e)}list(){return Array.from(this.definitions.keys())}};function iC(e,t=``){return JSON.stringify(e,function(e,n){let r=this,i=r==null?n:r[e];if(i===void 0){if(Array.isArray(r))throw oC(t,`undefined`,r,e);return n}return i!==null&&aC(i,r,e,t),n})}function aC(e,t,n,r){if(typeof e==`bigint`)throw oC(r,`BigInt`,t,n);if(typeof e!=`object`)return;if(e instanceof Map)throw oC(r,`Map`,t,n);if(e instanceof Set)throw oC(r,`Set`,t,n);if(e instanceof Date)throw oC(r,`Date`,t,n);if(Array.isArray(e))return;let i=Object.getPrototypeOf(e);if(i!==null&&i!==Object.prototype)throw oC(r,e.constructor?.name??`class instance`,t,n)}function oC(e,t,n,r){let i=sC(n,r);return YS.DF0020({name:e||``,type:t,path:i})}function sC(e,t){return Array.isArray(e)?`[${t}]`:t===``?``:t}var cC=`__DEVFRAME_CONNECTION_META__`,lC=`__DEVFRAME_CONNECTION_AUTH_TOKEN__`;function uC(e){let t=[()=>window?.[e],()=>globalThis?.[e],()=>parent.window?.[e]];for(let e of t)try{let t=e();if(t)return t}catch{}}function dC(){return uC(HS)}function fC(){return uC(cC)}function pC(e){if(e)return e;try{let e=localStorage.getItem(lC);if(e)return e}catch{}return uC(lC)}function mC(e){globalThis[HS]=e,globalThis[cC]={...e.connectionMeta,baseUrl:e.metaBaseUrl},e.authToken&&hC(e.authToken)}function hC(e){try{localStorage.setItem(lC,e)}catch{}globalThis[lC]=e;let t=dC();t&&(globalThis[HS]={...t,authToken:e})}function gC(e){let t=Ob(VS,e);try{return new URL(t,globalThis.location?.href).href}catch{return t}}function _C(e,t){return t&&t!==e.authToken?{...e,authToken:t}:e}function vC(){let e=dC();if(e)return _C(e,pC()??e.authToken??e.connectionMeta.authToken);let t=fC();if(t)return{connectionMeta:t,metaBaseUrl:t.baseUrl??gC(`./`),authToken:pC(t.authToken)}}async function yC(e={}){if(e.connection){let t=_C(e.connection,pC(e.authToken??e.connection.authToken??e.connection.connectionMeta.authToken));return mC(t),t}let t=Array.isArray(e.baseURL)?e.baseURL:[e.baseURL??`./`];if(e.connectionMeta){let n={connectionMeta:e.connectionMeta,metaBaseUrl:gC(t[0]??`./`),authToken:pC(e.authToken??e.connectionMeta.authToken)};return mC(n),n}let n=vC();if(n){let t=_C(n,pC(e.authToken??n.authToken??n.connectionMeta.authToken));return mC(t),t}let r=[];for(let n of t){let t=Ob(VS,n),i=gC(n);try{let n=await fetch(t);if(!n.ok)throw Error(`Failed to fetch connection meta from ${i}: ${n.status}`);let r=await n.json(),a=n.url||i,o={connectionMeta:r,metaBaseUrl:r.baseUrl?new URL(r.baseUrl,a).href:a,authToken:pC(e.authToken??r.authToken)};return mC(o),o}catch(e){r.push(e)}}throw Error(`Failed to get connection meta from ${t.join(`, `)}`,{cause:r})}var bC=class extends Error{name=`DevframeConnectionError`;kind;constructor(e,t,n){super(t,n),this.kind=e}};function xC(e=KS){try{let t=globalThis.location?.hash?.replace(/^#/,``)??``;return new URLSearchParams(t).get(e)||void 0}catch{return}}function SC(e){try{let t=new URL(globalThis.location.href),n=new URLSearchParams(t.hash.replace(/^#/,``));if(!n.has(e))return;n.delete(e),t.hash=n.toString(),globalThis.history?.replaceState(globalThis.history.state,``,t.href)}catch{}}function CC(e=KS){let t=xC(e);return t&&SC(e),t}async function wC(e,t={}){let n=CC(t.param??`devframe_otp`);return n?e.isTrusted?!0:e.requestTrustWithCode(n):!1}function TC(e){let t={},n=new WeakMap,r,i=()=>(r??=e.sharedState.get(GS,{initialValue:{}}).then(e=>(t=e.value(),e.on(`updated`,e=>{t=e}),e)),r);return i(),{state:i,has:e=>e in t,keys:()=>Object.keys(t),get:r=>{let i=t[r];if(!i)return;let a=n.get(i);return a||(a={...i,rpc:e.scope(i.scope).rpc},n.set(i,a)),a}}}function EC(e){let t=new Map,n=new Map,r=new Map,i=new Set,a=e.connectionMeta.backend===`static`;function o(e,t){let n=r.get(e);return n&&typeof n==`object`&&!Array.isArray(n)&&typeof t==`object`&&!Array.isArray(t)?{...n,...t}:t}e.client.register({name:Uy.broadcast.clientStateUpdated,type:`event`,handler:(e,n,r)=>{let i=t.get(e);i&&!i.syncIds.has(r)&&i.mutate(()=>o(e,n),r)}}),e.client.register({name:Uy.broadcast.clientStatePatch,type:`event`,handler:(e,n,r)=>{let i=t.get(e);i&&!i.syncIds.has(r)&&i.patch(n,r)}});function s(t,n){let r=[];return r.push(n.on(`updated`,(n,r,i)=>{a||(r?e.callEvent(`devframe:rpc:server-state:patch`,t,r,i):e.callEvent(`devframe:rpc:server-state:set`,t,n,i))})),()=>{for(let e of r)e()}}return{keys:()=>Array.from(t.keys()),onKeyAdded(e){return i.add(e),()=>{i.delete(e)}},delete(e){let i=n.get(e);n.delete(e);let a=t.delete(e);return r.delete(e),i?.(),a},get:async(c,l)=>{if(l?.initialValue!==void 0&&r.set(c,l.initialValue),t.has(c))return t.get(c);let u=lS({initialValue:l?.initialValue,enablePatches:!1});async function d(){if(a||e.callEvent(`devframe:rpc:server-state:subscribe`,c),l?.initialValue!==void 0){t.set(c,u);for(let e of i)e(c);return e.call(`devframe:rpc:server-state:get`,c).then(e=>{e!==void 0&&u.mutate(()=>o(c,e))}).catch(e=>{console.error(`Error getting server state`,e)}),n.set(c,s(c,u)),u}{let r=await e.call(`devframe:rpc:server-state:get`,c);u.mutate(()=>o(c,r)),t.set(c,u);for(let e of i)e(c);return n.set(c,s(c,u)),u}}return new Promise(t=>{if(e.isTrusted)d().then(t);else{t(u);let n=!1;e.events.on(Uy.client.isTrustedUpdated,e=>{e&&!n&&(n=!0,d())})}})}}}var DC=new Map;function OC(e=DC){let t=new Map;return{serialize:n=>{let r;return n.t===`q`?r=n.m:(r=t.get(n.i),t.delete(n.i)),!(n.t===`s`&&`e`in n)&&r&&e.get(r)?.jsonSerializable===!0?iC(n,r??``):`s:${OS(n)}`},deserialize:e=>{let n=e.startsWith(`s:`)?kS(e.slice(2)):JSON.parse(e);return n.t===`q`&&n.i&&n.m&&t.set(n.i,n.m),n}}}function kC(){}function AC(e){let t=e.search(/\n\n|\r\n\r\n/);if(!(t<0))return{frame:e.slice(0,t),rest:e.slice(t+(e[t]===`\r`?4:2))}}function jC(e){let t=`message`,n=[];for(let r of e.split(/\r?\n/))r.startsWith(`:`)||(r.startsWith(`event:`)?t=r.slice(6).trimStart():r.startsWith(`data:`)&&n.push(r.slice(5).replace(/^ /,``)));return{event:t,data:n}}function MC(e){let{onConnected:t=kC,onError:n=kC,onDisconnected:r=kC,definitions:i,fetch:a=globalThis.fetch.bind(globalThis)}=e,o=e.url;e.authToken&&(o=`${o}${o.includes(`?`)?`&`:`?`}${qS}=${encodeURIComponent(e.authToken)}`);let s=OC(i),c=new AbortController,l=!1,u,d,f,p,m=new Promise((e,t)=>{f=e,p=t});m.catch(()=>{});function h(e){l||(l=!0,p(e),n(e),r())}function g(){l||(l=!0,p(Error(`Devframe SSE stream closed`)),r())}function _(e,n){if(e===`session`){f(n),t();return}u?.(n)}async function v(e){let t=e.getReader();d=t;let n=new TextDecoder,r=``;for(;;){let{done:e,value:i}=await t.read();if(e)break;for(r+=n.decode(i,{stream:!0});;){let e=AC(r);if(!e)break;r=e.rest;let{event:t,data:n}=jC(e.frame);n.length>0&&_(t,n.join(` +`))}}g()}return(async()=>{try{let e=await a(o,{headers:{accept:`text/event-stream`},signal:c.signal});if(!e.ok||!e.body)throw Error(`Devframe SSE stream request failed: ${e.status}`);await v(e.body)}catch(e){if(c.signal.aborted){g();return}h(e instanceof Error?e:Error(String(e)))}})(),{close:()=>{l=!0,c.abort(),d?.cancel().catch(()=>{})},on:e=>{u=e},post:async e=>{let t;try{t=await m}catch{return}if(l){n(Error(`Devframe SSE channel is closed; message dropped`));return}try{let n=await a(o,{method:`POST`,headers:{"content-type":`text/plain; charset=utf-8`,[US]:t},body:e});if(n.status===200){let e=await n.text();e&&u?.(e);return}if(!n.ok)throw Error(`Devframe SSE POST failed: ${n.status}`)}catch(e){n(e instanceof Error?e:Error(String(e)))}},serialize:s.serialize,deserialize:s.deserialize}}function NC(e,t){let{channel:n,rpcOptions:r={}}=t;return nb(e,{...n,timeout:-1,...r,proxify:!1})}function PC(e){let{transport:t,authToken:n,connectionMeta:r,events:i,clientRpc:a,rpcOptions:o={},callTimeout:s=0}=e,c=!1,l=`connecting`,u=null,d=Promise.withResolvers();function f(e,t=null){if(t?u=t:e===`connected`&&(u=null),e===l)return;let n=l;l=e,i.emit(Uy.client.connectionStatus,e,n)}let p=new Set;function m(e){for(let t of[...p])t.reject(e)}function h(){return l===`disconnected`||l===`error`?new bC(`connection`,`[devframe] Not connected to the devframe server`,{cause:u??void 0}):l===`unauthorized`?new bC(`auth`,`[devframe] Not authorized by the devframe server`,{cause:u??void 0}):null}function g(e,t){return new Promise((n,r)=>{let a=!1,o,c={reject(e){a||(l(),i.emit(Uy.client.error,e,t),r(e))}};function l(){a=!0,p.delete(c),o&&clearTimeout(o)}p.add(c),s>0&&(o=setTimeout(()=>{c.reject(new bC(`timeout`,`[devframe] RPC call "${t}" timed out after ${s}ms`))},s)),e.then(e=>{a||(l(),n(e))},e=>{if(a)return;l();let n=e instanceof Error?e:Error(String(e));i.emit(Uy.client.error,n,t),r(n)})})}let _=new Map;for(let e of r.jsonSerializableMethods??[])_.set(e,{jsonSerializable:!0});let v=e.createChannel({definitions:_,onError(e){f(`error`,e),i.emit(Uy.client.connectionError,e),m(new bC(`connection`,`[devframe] Connection to the devframe server failed`,{cause:e}))},onDisconnected(){l!==`error`&&f(`disconnected`),m(new bC(`connection`,`[devframe] Disconnected from the devframe server`,{cause:u??void 0}))}}),y=NC(a.functions,{channel:v,rpcOptions:o});a.register({name:Uy.broadcast.authRevoked,type:`event`,handler:()=>{c=!1;let e=new bC(`auth`,`[devframe] The devframe server revoked this client's trust`);f(`unauthorized`,e),i.emit(Uy.client.connectionError,e),m(e),i.emit(Uy.client.isTrustedUpdated,!1)}});let b=n;async function ee(e){b=e;let t=await y.$call(`anonymous:devframe:auth`,{authToken:e,ua:navigator.userAgent,origin:location.origin});if(c=t.isTrusted,c)d.resolve(!0),f(`connected`);else{let e=new bC(`auth`,`[devframe] The devframe server refused this client's credentials`);f(`unauthorized`,e),i.emit(Uy.client.connectionError,e)}return i.emit(Uy.client.isTrustedUpdated,c),t.isTrusted}async function te(e){let t=(await y.$call(`anonymous:devframe:auth:exchange`,{code:e,ua:navigator.userAgent,origin:location.origin}))?.authToken??null;return t&&(b=t,c=!0,d.resolve(!0),f(`connected`),i.emit(Uy.client.isTrustedUpdated,!0)),t}async function ne(e={}){await y.$call(`anonymous:devframe:auth:request-code`,{ua:navigator.userAgent,origin:location.origin,...e.reissue?{reissue:!0}:{}})}async function re(){return c?!0:ee(b??``)}async function x(e=6e4){if(c&&d.resolve(!0),e<=0)return d.promise;let t;try{return await Promise.race([d.promise,new Promise((n,r)=>{t=setTimeout(()=>{r(Error(`[devframe] Timeout waiting for rpc to be trusted`))},e)})]),c}finally{clearTimeout(t)}}return{transport:t,get isTrusted(){return c},get status(){return l},get connectionError(){return u},requestTrust:re,requestTrustWithToken:ee,requestTrustWithCode:te,requestAuthCode:ne,ensureTrusted:x,call:(...e)=>{let t=String(e[0]),n=h();return n?(i.emit(Uy.client.error,n,t),Promise.reject(n)):g(y.$call(...e),t)},callEvent:(...e)=>{let t=h();if(t){i.emit(Uy.client.error,t,String(e[0]));return}return y.$callEvent(...e)},callOptional:(...e)=>{let t=String(e[0]),n=h();return n?(i.emit(Uy.client.error,n,t),Promise.reject(n)):g(y.$callOptional(...e),t)},close:()=>{v.close()}}}function FC(e,t,n){let r=(()=>{try{return new URL(t,n.href)}catch{return new URL(n.href)}})();if(e&&typeof e==`object`){if(e.host!=null||e.port!=null){let t=e.host??`${r.hostname}:${e.port}`;return new URL(e.path??`/`,`${r.protocol}//${t}`).href}return new URL(e.path??``,r).href}let i=e??``;return/^https?:\/\//i.test(i)?i:new URL(i,r).href}function IC(e){let{authToken:t,connectionMeta:n,metaBaseUrl:r,events:i,clientRpc:a,rpcOptions:o={},sseOptions:s={},callTimeout:c=0}=e,l=FC(n.sse,r??`./`,location);return PC({transport:`sse`,authToken:t,connectionMeta:n,events:i,clientRpc:a,rpcOptions:o,callTimeout:c,createChannel:e=>MC({url:l,authToken:t,definitions:e.definitions,...s,onConnected(){s.onConnected?.()},onError(t){e.onError(t),s.onError?.(t)},onDisconnected(){e.onDisconnected(),s.onDisconnected?.()}})})}function LC(e){let{name:t,message:n,cause:r,...i}=e,a=r instanceof Error?r:RC(r)?LC(r):r,o=a===void 0?Error(n):Error(n,{cause:a});return o.name=t,Object.assign(o,i),o}function RC(e){return typeof e==`object`&&!!e&&typeof e.message==`string`&&typeof e.name==`string`}function zC(e){return typeof e==`object`&&!!e&&e.type===`static`&&typeof e.path==`string`}function BC(e){return typeof e==`object`&&!!e&&e.type===`query`&&typeof e.records==`object`&&e.records!==null}function VC(e){return typeof e==`object`&&!!e&&(`output`in e||`error`in e)}function HC(e){if(e.error)throw LC(e.error);return e.output}function UC(e){return e.some(e=>e!=null)}function WC(e){return typeof e==`object`&&e&&`serialization`in e&&`data`in e?e.data:e}function GC(e,t){let n=new Map,r=new Map;function i(e,t){return t===`structured-clone`&&Array.isArray(e)?DS(e):e}function a(e,t){return i(WC(e),t)}async function o(e){n.has(e.path)||n.set(e.path,t(e.path).then(t=>a(t,e.serialization)));let r=await n.get(e.path);return VC(r)?HC(r):r}async function s(e,n){return r.has(e)||r.set(e,t(e).then(e=>a(e,n))),await r.get(e)}async function c(t,n){if(!(t in e))throw Error(`[devframe-rpc] Function "${t}" not found in dump store`);let r=e[t];if(zC(r)){if(UC(n))throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`);return await o(r)}if(BC(r)){let e=Sb(n),i=r.records[e];if(i)return HC(await s(i,r.serialization));if(r.fallback)return HC(await s(r.fallback,r.serialization));throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`)}if(!UC(n))return r;throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`)}return{call:async(e,t)=>await c(e,t),callOptional:async(t,n)=>{if(t in e)return await c(t,n)},callEvent:async(e,t)=>{}}}async function KC(e){let t=GC(await e.fetchJsonFromBases(WS),e.fetchJsonFromBases);return{transport:`static`,isTrusted:!0,status:`connected`,connectionError:null,requestTrust:async()=>!0,requestTrustWithToken:async()=>!0,requestTrustWithCode:async()=>null,requestAuthCode:async()=>{},ensureTrusted:async()=>!0,call:(...e)=>t.call(e[0],e.slice(1)),callEvent:(...e)=>t.callEvent(e[0],e.slice(1)),callOptional:(...e)=>t.callOptional(e[0],e.slice(1)),close:()=>{}}}var qC=``;function JC(e,t){return`${e}${qC}${t}`}function YC(e){let t=new Map,n=new Map;e.client.register({name:Uy.broadcast.streamingChunk,type:`event`,handler(e,n,r,i){t.get(JC(e,n))?._push(r,i)}}),e.client.register({name:Uy.broadcast.streamingEnd,type:`event`,handler(e,n,r){let i=JC(e,n),a=t.get(i);a&&(a._end(r),t.delete(i))}}),e.client.register({name:Uy.broadcast.streamingUploadCancel,type:`event`,handler(e,t){let r=JC(e,t),i=n.get(r);i&&(i.abort(`server cancelled upload`),n.delete(r))}}),e.events.on(Uy.client.isTrustedUpdated,n=>{if(n)for(let[n,r]of t){if(r.cancelled||r.done)continue;let t=n.indexOf(qC);if(t<0)continue;let i=n.slice(0,t),a=n.slice(t+1);e.callEvent(`devframe:streaming:subscribe`,i,a,{afterSeq:r.lastSeenSeq})}});function r(n,r,i={}){let a=JC(n,r),o=t.get(a);if(o)return o;let s=NS({id:r,highWaterMark:i.highWaterMark,onOverflow(e){console.warn(`[devframe] DF0029: Stream "${n}#${r}" dropped ${e} chunk(s) after exceeding the client high-water mark.`)},onCancel(){e.callEvent(`devframe:streaming:cancel`,n,r),t.delete(a)}});if(t.set(a,s),e.isTrusted)e.callEvent(`devframe:streaming:subscribe`,n,r,{afterSeq:0});else{let i=e.events.on(Uy.client.isTrustedUpdated,o=>{o&&(i(),t.has(a)&&!s.cancelled&&!s.done&&e.callEvent(`devframe:streaming:subscribe`,n,r,{afterSeq:s.lastSeenSeq}))})}return s}function i(t,r){let i=JC(t,r),a=n.get(i);if(a)return a;let o=MS({id:r});return o.events.on(`chunk`,(n,i)=>{e.callEvent(`devframe:streaming:upload-chunk`,t,r,n,i)}),o.events.on(`end`,a=>{e.callEvent(`devframe:streaming:upload-end`,t,r,a),n.delete(i)}),n.set(i,o),o}return{subscribe:r,upload:i}}function XC(){}var ZC=new Map;function QC(e){let t=e.url;e.authToken&&(t=`${t}?${qS}=${encodeURIComponent(e.authToken)}`);let n=new WebSocket(t),{onConnected:r=XC,onError:i=XC,onDisconnected:a=XC,definitions:o=ZC}=e;n.addEventListener(`open`,e=>{r(e)}),n.addEventListener(`error`,e=>{let t=e instanceof Error?e:Error(e.type);i(t)}),n.addEventListener(`close`,e=>{a(e)});let s=OC(o);return{close:()=>{n.close()},on:e=>{n.addEventListener(`message`,t=>{e(t.data)})},post:e=>{if(n.readyState===WebSocket.OPEN){n.send(e);return}if(n.readyState===WebSocket.CONNECTING){let t=()=>{i(),n.readyState===WebSocket.OPEN&&n.send(e)},r=()=>i();function i(){n.removeEventListener(`open`,t),n.removeEventListener(`close`,r)}n.addEventListener(`open`,t),n.addEventListener(`close`,r);return}i(Error(`Devframe WebSocket is not open; message dropped`))},serialize:s.serialize,deserialize:s.deserialize}}function $C(e,t,n){let r=(()=>{try{return new URL(t,n.href)}catch{return new URL(n.href)}})(),i=r.protocol===`https:`?`wss:`:`ws:`;if(e&&typeof e==`object`){if(e.host!=null||e.port!=null){let t=e.host??`${r.hostname}:${e.port}`,n=new URL(e.path??`/`,`${i}//${t}`);return n.protocol=i,n.href}let t=new URL(e.path??``,r);return t.protocol=i,t.href}if(typeof e==`number`)return`${i}//${r.hostname}:${e}`;let a=e??``;if(/^wss?:\/\//i.test(a))return a;if(/^https?:\/\//i.test(a))return kb(a,/^https/i.test(a)?`wss://`:`ws://`);let o=new URL(a,r);return o.protocol=i,o.href}function ew(e){let{authToken:t,connectionMeta:n,metaBaseUrl:r,events:i,clientRpc:a,rpcOptions:o={},wsOptions:s={},callTimeout:c=0}=e,l=$C(n.websocket,r??`./`,location);return PC({transport:`websocket`,authToken:t,connectionMeta:n,events:i,clientRpc:a,rpcOptions:o,callTimeout:c,createChannel:e=>QC({url:l,authToken:t,definitions:e.definitions,...s,onConnected(e){s.onConnected?.(e)},onError(t){e.onError(t),s.onError?.(t)},onDisconnected(t){e.onDisconnected(),s.onDisconnected?.(t)}})})}function tw(e){return e.includes(`:`)}function nw(e,t){return tw(t)?t:`${e}:${t}`}function rw(e){return{async get(t){return(await e()).value()[t]},async set(t,n){(await e()).mutate(e=>{e[t]=n})},async delete(t){(await e()).mutate(e=>{delete e[t]})},async all(){return(await e()).value()},async onChange(t){return(await e()).on(`updated`,e=>t(e))}}}function iw(e,t,n){let r=`devframe:settings:${n}:${t}`,i;function a(){return i||=e.sharedState.get(r,{initialValue:{}}),i}return rw(a)}function aw(e,t){return{global:iw(e,t,`global`),project:iw(e,t,`project`)}}function ow(e,t){return{namespace:t,base:e,rpc:{namespace:t,register(n){if(tw(n.name))throw Error(`[devframe] Scoped client RPC registration for namespace "${t}" received an already-namespaced function name "${n.name}". Pass a bare name without a ":" separator.`);e.client.register({...n,name:`${t}:${n.name}`})},call:((n,...r)=>e.call(nw(t,n),...r)),callEvent:((n,...r)=>e.callEvent(nw(t,n),...r)),callOptional:((n,...r)=>e.callOptional(nw(t,n),...r)),sharedState:((n,r)=>e.sharedState.get(nw(t,n),r)),streaming:{subscribe:(n,r,i)=>e.streaming.subscribe(nw(t,n),r,i),upload:(n,r)=>e.streaming.upload(nw(t,n),r)}},settings:aw(e,t),scope:e.scope}}function sw(){if(typeof document<`u`){let e=document.modelContext;if(e)return e}if(typeof navigator<`u`){let e=navigator.modelContext;if(e)return e}}function cw(e,t={}){let n=t.modelContext??sw();if(!n)return()=>{};let r=n,i=new Map,a=new Map;function o(t,n){let o=IS(t.name),s=a.get(o);if(s&&s!==t.name){console.warn(`[devframe] WebMCP tool name "${o}" (from "${t.name}") collides with "${s}"; keeping the first registration.`);return}let c=new AbortController,l=rb(t.type,n),u=r.registerTool({name:o,description:n.description,inputSchema:ob(t.args),annotations:{title:n.title??t.name,readOnlyHint:l===`read`,destructiveHint:l===`destructive`},execute:n=>lw(t,e.context,n)},{signal:c.signal});u&&`then`in u&&u.then(()=>{},()=>{}),a.set(o,t.name),i.set(t.name,()=>{c.abort(),u&&`unregister`in u&&typeof u.unregister==`function`&&u.unregister(),a.delete(o)})}function s(t){let n=t?[t]:[...e.definitions.keys()];for(let t of n){i.get(t)?.(),i.delete(t);let n=e.definitions.get(t),r=n?.agent;n&&r&&o(n,r)}}s();let c=e.onChanged(e=>s(e));return()=>{c();for(let e of i.values())e();i.clear()}}async function lw(e,t,n){try{let r=cb(n,e.args?.length);return{content:[{type:`text`,text:uw(await(await nC(e,t))(...r))}]}}catch(e){return{isError:!0,content:[{type:`text`,text:dw(e)}]}}}function uw(e){return e===void 0?`undefined`:typeof e==`string`?e:JSON.stringify(e,null,2)}function dw(e){if(!(e instanceof Error))return String(e);let t=e.cause instanceof Error?` (cause: ${e.cause.message})`:``;return`${e.name}: ${e.message}${t}`}function fw(e,t){if(t.backend===`static`)return`static`;let n=t.websocket!==void 0,r=t.sse!==void 0;if(e===`websocket`){if(!n)throw Error(`[devframe] transport: 'websocket' was requested, but this server does not advertise a WebSocket endpoint`);return`websocket`}if(e===`sse`){if(!r)throw Error(`[devframe] transport: 'sse' was requested, but this server does not advertise an SSE endpoint`);return`sse`}if(t.backend===`sse`&&r)return`sse`;if(n)return`websocket`;if(r)return`sse`;throw Error(`[devframe] This server advertises no RPC transport (backend "none"), so there is nothing to connect to. Enable the WebSocket or SSE endpoint on the server, or use its static/MCP surfaces instead.`)}async function pw(e={}){let{baseURL:t=`./`,rpcOptions:n={},cacheOptions:r=!1}=e,i=Cb(),a=Array.isArray(t)?t:[t],o=await yC(e),{connectionMeta:s,metaBaseUrl:c,authToken:l}=o,u=a[0]??`./`;try{u=new URL(`.`,c).href}catch{}let d=new JS({functions:[],...typeof e.cacheOptions==`object`?e.cacheOptions:{}}),f={rpc:void 0},p=new rC(f),m=e.webmcp===!1?void 0:cw(p),h,g=!1;async function _(e){let t=[u,...a.filter(e=>e!==u)].filter(e=>e!=null),n=[];for(let r of t)try{return await fetch(Ob(e,r)).then(t=>{if(!t.ok)throw Error(`Failed to fetch ${e} from ${r}: ${t.status}`);return t.json()})}catch(e){n.push(e)}throw Error(`Failed to load ${e} from ${t.join(`, `)}`,{cause:n})}let v={authToken:l,connectionMeta:s,metaBaseUrl:c,events:i,clientRpc:p,callTimeout:e.callTimeout,rpcOptions:{...n,async onRequest(e,t,i){if(await n.onRequest?.call(this,e,t,i),r&&d?.validate(e.m)){if(d.has(e.m,e.a))return i(d.cached(e.m,e.a));let n=await t(e);d.apply(e,n)}else await t(e)}}},y=fw(e.transport??`auto`,s),b=y===`static`?await KC({fetchJsonFromBases:_}):y===`sse`?IC({...v,sseOptions:e.sseOptions}):ew({...v,wsOptions:e.wsOptions}),ee;try{ee=new BroadcastChannel(`devframe-auth`)}catch{}let te,ne=!1;function re(e){return((...t)=>ne||!te?e(...t):te.then(()=>e(...t)))}function x(){g=!0;try{h?.(),m?.()}finally{try{ee?.close()}finally{b.close?.()}}}let S={events:i,get isTrusted(){return b.isTrusted},get status(){return b.status},get connectionError(){return b.connectionError},get transport(){return b.transport??y},get connection(){return o},connectionMeta:s,ensureTrusted:b.ensureTrusted,requestTrust:b.requestTrust,requestTrustWithToken:async e=>(hC(e),o={...o,authToken:e},b.requestTrustWithToken(e)),requestTrustWithCode:async e=>{let t=await b.requestTrustWithCode(e);if(!t)return!1;hC(t),o={...o,authToken:t};try{ee?.postMessage({type:`auth-update`,authToken:t})}catch{}return!0},requestAuthCode:e=>b.requestAuthCode(e),call:re(b.call),callEvent:re(b.callEvent),callOptional:re(b.callOptional),client:p,sharedState:void 0,services:void 0,streaming:void 0,cacheManager:d,scope:void 0,close:x};S.sharedState=EC(S),S.streaming=YC(S),S.services=TC(S);let ie=new Map;S.scope=(e=>{if(!e)return S;let t=ie.get(e);return t||(t=ow(S,e),ie.set(e,t)),t}),f.rpc=S;function ae(){try{return typeof window<`u`&&window.self===window.top}catch{return!1}}async function oe(){if(e.simpleAuth!==!1&&ae()&&typeof globalThis.prompt==`function`)for(await S.requestAuthCode().catch(()=>{});!S.isTrusted;){let e=globalThis.prompt(`devframe: enter the authentication code shown in your terminal`);if(e==null)return;let t=e.trim();if(t&&await S.requestTrustWithCode(t))return}}async function C(){let t=await b.requestTrust(),n=e.otpParam??`devframe_otp`,r=n?await wC(S,{param:n}):!1;t||r||S.isTrusted||await oe()}return te=C().then(()=>{ne=!0},()=>{ne=!0}),s.mcp&&BS(async()=>{let{setupBrowserAgentRpcBridge:e}=await import(`./browser-agent-rpc-BXhoSh1z-D0HBE3Mq.js`);return{setupBrowserAgentRpcBridge:e}},[],import.meta.url).then(({setupBrowserAgentRpcBridge:e})=>{g||(h=e(S))}).catch(()=>{}),ee&&(ee.onmessage=e=>{e.data?.type===`auth-update`&&e.data.authToken&&S.requestTrustWithToken(e.data.authToken)}),S}var mw=pw,hw=class e{rpc=k_(null);navigate=E_();meta=L(null);componentCount=L(0);routeCount=L(0);signalCount=L(0);providerCount=L(0);storeCount=L(0);constructor(){Zs(()=>{let e=this.rpc();if(!e)return;let t=e.scope(`ng-devtools`);t.rpc.call(`build-meta`).then(e=>this.meta.set(e)).catch(()=>{}),t.rpc.call(`get-components`).then(e=>this.componentCount.set(e.length)).catch(()=>{}),t.rpc.call(`get-routes`).then(e=>this.routeCount.set(e.length)).catch(()=>{}),t.rpc.call(`get-signals`).then(e=>this.signalCount.set(e.length)).catch(()=>{}),t.rpc.call(`get-providers`).then(e=>this.providerCount.set(e.length)).catch(()=>{}),t.rpc.call(`get-ngrx-store`).then(e=>this.storeCount.set(e.length)).catch(()=>{})})}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-dashboard`]],inputs:{rpc:[1,`rpc`]},outputs:{navigate:`navigate`},decls:56,vars:9,consts:[[1,`grid`],[1,`card`],[1,`card`,`clickable`,3,`click`],[1,`big`],[1,`sub`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`div`,1)(2,`h2`),Z(3,`Project`),J(),q(4,`dl`)(5,`dt`),Z(6,`Name`),J(),q(7,`dd`),Z(8),J(),q(9,`dt`),Z(10,`Angular`),J(),q(11,`dd`),Z(12),J(),q(13,`dt`),Z(14,`TypeScript`),J(),q(15,`dd`),Z(16),J(),q(17,`dt`),Z(18,`SSR`),J(),q(19,`dd`),Z(20),J()()(),q(21,`div`,2),Y(`click`,function(){return t.navigate.emit(`components`)}),q(22,`h2`),Z(23,`Components`),J(),q(24,`p`,3),Z(25),J(),q(26,`p`,4),Z(27,`discovered in source`),J()(),q(28,`div`,2),Y(`click`,function(){return t.navigate.emit(`routes`)}),q(29,`h2`),Z(30,`Routes`),J(),q(31,`p`,3),Z(32),J(),q(33,`p`,4),Z(34,`registered paths`),J()(),q(35,`div`,2),Y(`click`,function(){return t.navigate.emit(`signals`)}),q(36,`h2`),Z(37,`Signals`),J(),q(38,`p`,3),Z(39),J(),q(40,`p`,4),Z(41,`reactive primitives`),J()(),q(42,`div`,2),Y(`click`,function(){return t.navigate.emit(`injectors`)}),q(43,`h2`),Z(44,`Injectors`),J(),q(45,`p`,3),Z(46),J(),q(47,`p`,4),Z(48,`DI providers`),J()(),q(49,`div`,2),Y(`click`,function(){return t.navigate.emit(`store`)}),q(50,`h2`),Z(51,`NgRx Store`),J(),q(52,`p`,3),Z(53),J(),q(54,`p`,4),Z(55,`store entries`),J()()()),e&2&&(z(8),Q(t.meta()?.projectName??`…`),z(4),Q(t.meta()?.angularVersion??`…`),z(4),Q(t.meta()?.typescript??`…`),z(4),Q(t.meta()?.ssr?`Yes`:`No`),z(5),Q(t.componentCount()),z(7),Q(t.routeCount()),z(7),Q(t.signalCount()),z(7),Q(t.providerCount()),z(7),Q(t.storeCount()))},styles:[`.grid[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 16px; + } + .card[_ngcontent-%COMP%] { + background: #18181b; + border: 1px solid #27272a; + border-radius: 10px; + padding: 20px; + } + .card.clickable[_ngcontent-%COMP%] { + cursor: pointer; + transition: border-color 0.15s; + } + .card.clickable[_ngcontent-%COMP%]:hover { + border-color: var(--%NS%accent); + } + h2[_ngcontent-%COMP%] { + font-size: 13px; + text-transform: uppercase; + color: #71717a; + margin-bottom: 12px; + letter-spacing: 0.05em; + } + dl[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: auto 1fr; + gap: 6px 12px; + font-size: 14px; + } + dt[_ngcontent-%COMP%] { + color: #a1a1aa; + } + dd[_ngcontent-%COMP%] { + color: #e4e4e7; + font-weight: 500; + } + .big[_ngcontent-%COMP%] { + font-size: 36px; + font-weight: 700; + color: var(--%NS%accent); + } + .sub[_ngcontent-%COMP%] { + font-size: 13px; + color: #71717a; + margin-top: 4px; + }`]})},gw=()=>[],_w=(e,t)=>t.selector,vw=(e,t)=>t.outlet+t.route,yw=(e,t)=>t.formId,bw=(e,t)=>t.token+t.line;function xw(e,t){e&1&&(q(0,`p`,3),Z(1,`Scanning components…`),J())}function Sw(e,t){e&1&&(q(0,`p`,3),Z(1,`No components found.`),J())}function Cw(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=t.$implicit;z(),t_(`routed `,e.route,` · outlet `,e.outlet)}}function ww(e,t){if(e&1){let e=Yh();q(0,`button`,14),Y(`click`,function(){let t=F(e).$implicit;return I(X(4).showForm.emit(t.formId))}),Z(1),J()}if(e&2){let e=t.$implicit;z(),$(` Show `,e.label,` in Forms `)}}function Tw(e,t){if(e&1&&(q(0,`li`,16),Z(1),J()),e&2){let e=t.$implicit;z(),Q(e)}}function Ew(e,t){if(e&1&&(q(0,`h4`),Z(1,`Inputs`),J(),q(2,`ul`,15),U(3,Tw,2,1,`li`,16,kh),J()),e&2){let e=X(2).$implicit;z(3),W(e.inputs)}}function Dw(e,t){if(e&1&&(q(0,`li`,17),Z(1),J()),e&2){let e=t.$implicit;z(),Q(e)}}function Ow(e,t){if(e&1&&(q(0,`h4`),Z(1,`Outputs`),J(),q(2,`ul`,15),U(3,Dw,2,1,`li`,17,kh),J()),e&2){let e=X(2).$implicit;z(3),W(e.outputs)}}function kw(e,t){if(e&1&&(q(0,`span`,22),Z(1),J()),e&2){let e=X().$implicit;z(),$(`→ `,e.source)}}function Aw(e,t){if(e&1&&(q(0,`li`,19)(1,`span`,20),Z(2),J(),q(3,`span`,21),Z(4),J(),V(5,kw,2,1,`span`,22),J()),e&2){let e=t.$implicit;z(2),Q(e.token),z(2),Q(e.type),z(),H(e.source&&e.source!==`class`&&e.source!==`providers array`?5:-1)}}function jw(e,t){if(e&1&&(q(0,`h4`),Z(1,`Injected Providers`),J(),q(2,`ul`,18),U(3,Aw,6,3,`li`,19,bw),J()),e&2){let e=X(4);z(3),W(e.selectedProviders())}}function Mw(e,t){e&1&&(q(0,`p`,13),Z(1,`No injected providers detected.`),J())}function Nw(e,t){if(e&1&&(q(0,`div`,11)(1,`dl`)(2,`dt`),Z(3,`File`),J(),q(4,`dd`),Z(5),J(),q(6,`dt`),Z(7,`Standalone`),J(),q(8,`dd`),Z(9),J()(),U(10,ww,2,1,`button`,12,yw),V(12,Ew,5,0),V(13,Ow,5,0),V(14,jw,5,0)(15,Mw,2,0,`p`,13),J()),e&2){let e=X().$implicit,t=X(2);z(5),Q(e.file),z(4),Q(e.isStandalone?`Yes`:`No`),z(),W(t.formsIn(e.file)),z(2),H(e.inputs.length?12:-1),z(),H(e.outputs.length?13:-1),z(),H(t.selectedProviders().length?14:15)}}function Pw(e,t){if(e&1){let e=Yh();q(0,`li`,6)(1,`button`,7),Y(`click`,function(){let t=F(e).$implicit;return I(X(2).select(t))}),q(2,`div`,8),Z(3),J(),q(4,`div`,9),Z(5),J(),U(6,Cw,2,2,`span`,10,vw),J(),V(8,Nw,16,5,`div`,11),J()}if(e&2){let e=t.$implicit,n=X(2);Ag(`expanded`,n.isSelected(e)),z(),B(`aria-expanded`,n.isSelected(e)),z(2),$(`<`,e.selector,`>`),z(2),Q(e.file),z(),W(n.routedBy().get(e.selector)??i_(6,gw)),z(2),H(n.isSelected(e)?8:-1)}}function Fw(e,t){if(e&1&&(q(0,`ul`,4),U(1,Pw,9,7,`li`,5,_w),J()),e&2){let e=X();z(),W(e.filtered())}}var Iw=class e{rpc=k_(null);showForm=E_();formOwners=L([]);components=L([]);allProviders=L([]);filter=L(``);loading=L(!1);selected=L(null);selectedProviders=L([]);filtered=L([]);outlets=L([]);unsubscribeRouter=null;destroyRef=M(us);routedBy=b_(()=>{let e=new Map,t=n=>{for(let r of n)r.activated&&r.element&&r.route&&e.set(r.element,[...e.get(r.element)??[],{route:r.route,outlet:r.outlet}]),r.children&&t(r.children)};return t(this.outlets()),e});constructor(){Zs(()=>{let e=this.filter().toLowerCase(),t=this.components();this.filtered.set(e?t.filter(t=>t.selector.includes(e)||t.file.includes(e)):t)}),Zs(()=>{let e=this.rpc();e&&(this.refresh(),this.watchRouter(e))}),this.destroyRef.onDestroy(()=>this.unsubscribeRouter?.())}async watchRouter(e){try{let t=await e.scope(`ng-devtools`).rpc.sharedState(`router`);if(this.destroyRef.destroyed)return;let n=e=>{let t=e?.pages??[],n=t.find(e=>e.snapshot)??t[0];this.outlets.set(n?.outlets??[])};n(t.value()),this.unsubscribeRouter?.(),this.unsubscribeRouter=t.on(`updated`,n)}catch{this.outlets.set([])}}async refresh(){let e=this.rpc();if(e){this.loading.set(!0);try{let t=e.scope(`ng-devtools`),[n,r]=await Promise.all([t.rpc.call(`get-components`),t.rpc.call(`get-providers`)]);this.components.set(n);let i=await t.rpc.call(`forms-owners`).catch(()=>[]);this.formOwners.set(i??[]),this.allProviders.set(r);let a=this.selected();if(a){let e=n.find(e=>e.selector===a.selector);e?(this.selected.set(e),this.selectedProviders.set(r.filter(t=>t.file===e.file))):(this.selected.set(null),this.selectedProviders.set([]))}}finally{this.loading.set(!1)}}}formsIn(e){return this.formOwners().filter(t=>t.file===e)}isSelected(e){return this.selected()?.selector===e.selector}select(e){if(this.isSelected(e)){this.selected.set(null),this.selectedProviders.set([]);let e=this.rpc();e&&e.scope(`ng-devtools`).rpc.callEvent(`select-component`,null);return}this.selected.set(e),this.selectedProviders.set(this.allProviders().filter(t=>t.file===e.file));let t=this.rpc();t&&t.scope(`ng-devtools`).rpc.callEvent(`select-component`,e.selector)}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-component-tree`]],inputs:{rpc:[1,`rpc`]},outputs:{showForm:`showForm`},decls:7,vars:2,consts:[[1,`toolbar`],[`type`,`text`,`placeholder`,`Filter components…`,3,`input`,`value`],[3,`click`],[1,`muted`],[`role`,`list`,1,`component-list`],[1,`component-item`,3,`expanded`],[1,`component-item`],[1,`component-toggle`,3,`click`],[1,`selector`],[1,`file`],[1,`routed`],[1,`inline-detail`],[`type`,`button`,1,`show-form`],[1,`no-providers`],[`type`,`button`,1,`show-form`,3,`click`],[`role`,`list`,1,`prop-list`],[1,`prop-chip`,`input-chip`],[1,`prop-chip`,`output-chip`],[`role`,`list`,1,`provider-list`],[1,`provider-item`],[1,`provider-token`],[1,`provider-type`],[1,`provider-source`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`input`,1),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(2,`button`,2),Y(`click`,function(){return t.refresh()}),Z(3,`Refresh`),J()(),V(4,xw,2,0,`p`,3)(5,Sw,2,0,`p`,3)(6,Fw,3,0,`ul`,4)),e&2&&(z(),Xh(`value`,t.filter()),z(3),H(t.loading()?4:t.filtered().length===0?5:6))},styles:[`.toolbar[_ngcontent-%COMP%] { + display: flex; + gap: 8px; + margin-bottom: 16px; + } + input[_ngcontent-%COMP%] { + flex: 1; + padding: 8px 12px; + background: #18181b; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 14px; + outline: none; + } + input[_ngcontent-%COMP%]:focus { + border-color: var(--%NS%accent); + } + button[_ngcontent-%COMP%] { + padding: 8px 16px; + background: #3f3f46; + border: none; + border-radius: 6px; + color: #e4e4e7; + cursor: pointer; + font-size: 13px; + } + button[_ngcontent-%COMP%]:hover { + background: #52525b; + } + .muted[_ngcontent-%COMP%] { + color: #71717a; + font-size: 14px; + } + .component-list[_ngcontent-%COMP%] { + list-style: none; + padding: 0; + display: flex; + flex-direction: column; + gap: 8px; + } + .component-item[_ngcontent-%COMP%] { + background: #18181b; + border: 1px solid #27272a; + border-radius: 8px; + padding: 0; + transition: border-color 0.15s; + } + .component-item[_ngcontent-%COMP%]:has(.component-toggle:hover) { + border-color: var(--%NS%accent); + } + .component-item.expanded[_ngcontent-%COMP%] { + border-color: var(--%NS%accent); + } + .component-toggle[_ngcontent-%COMP%] { + display: block; + width: 100%; + padding: 12px 16px; + background: none; + border: none; + color: inherit; + text-align: left; + cursor: pointer; + font: inherit; + } + .selector[_ngcontent-%COMP%] { + font-family: monospace; + font-size: 15px; + color: var(--%NS%accent); + font-weight: 600; + } + .file[_ngcontent-%COMP%] { + font-size: 12px; + color: #71717a; + margin-top: 2px; + } + .io[_ngcontent-%COMP%] { + font-size: 13px; + color: #a1a1aa; + margin-top: 4px; + } + .io[_ngcontent-%COMP%] .label[_ngcontent-%COMP%] { + color: #71717a; + } + .show-form[_ngcontent-%COMP%] { + margin: 0 8px 8px 0; + } + .inline-detail[_ngcontent-%COMP%] { + padding: 0 16px 12px; + border-top: 1px solid #27272a; + margin-top: 0; + padding-top: 12px; + } + .prop-list[_ngcontent-%COMP%] { + list-style: none; + padding: 0; + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-bottom: 12px; + } + .prop-chip[_ngcontent-%COMP%] { + font-family: monospace; + font-size: 12px; + padding: 3px 8px; + border-radius: 4px; + } + .input-chip[_ngcontent-%COMP%] { + background: #1e3a5f; + color: #93c5fd; + } + .output-chip[_ngcontent-%COMP%] { + background: #3b1d1d; + color: #fca5a5; + } + dl[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: auto 1fr; + gap: 4px 12px; + font-size: 13px; + margin-bottom: 16px; + } + dt[_ngcontent-%COMP%] { + color: #71717a; + } + dd[_ngcontent-%COMP%] { + color: #e4e4e7; + } + h4[_ngcontent-%COMP%] { + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.05em; + color: #71717a; + margin-bottom: 8px; + } + .provider-list[_ngcontent-%COMP%] { + list-style: none; + padding: 0; + display: flex; + flex-direction: column; + gap: 6px; + } + .provider-item[_ngcontent-%COMP%] { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 10px; + background: #09090b; + border: 1px solid #27272a; + border-radius: 6px; + font-size: 13px; + } + .provider-token[_ngcontent-%COMP%] { + font-family: monospace; + color: #e4e4e7; + font-weight: 600; + } + .provider-type[_ngcontent-%COMP%] { + font-size: 11px; + padding: 1px 6px; + border-radius: 4px; + background: #3f3f46; + color: #a1a1aa; + } + .routed[_ngcontent-%COMP%] { + display: inline-block; + margin-top: 4px; + padding: 1px 6px; + border: 1px solid #52525b; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + font-family: monospace; + } + .provider-source[_ngcontent-%COMP%] { + font-size: 12px; + color: #a1a1aa; + } + .no-providers[_ngcontent-%COMP%] { + font-size: 13px; + color: #52525b; + }`]})};function Lw(e,t,n){return e?e.scope(`ng-devtools`).rpc.call(t,...n===void 0?[]:[n]).then(e=>e,()=>null):Promise.resolve(null)}function Rw(e,t,n){return Lw(e,`request-router-action`,{pageId:t,request:n})}function zw(e){return e===`succeeded`?`good`:e===`redirected`||e===`pending`||e===`skipped`?`warn`:e===`cancelled`||e===`failed`?`bad`:``}var Bw=()=>[],Vw=(e,t)=>t[0],Hw=(e,t)=>t.input;function Uw(e,t){if(e&1&&(q(0,`p`,2),Z(1,` The browser shows `),q(2,`code`),Z(3),J(),Z(4,`, not the router URL (skipLocationChange, browserUrl, a failed navigation or code that changed history). `),J()),e&2){let e=X();z(3),Q(e.browserUrl)}}function Ww(e,t){if(e&1){let e=Yh();q(0,`div`,3),Z(1,` Navigating to `),q(2,`code`),Z(3),J(),Z(4),q(5,`button`,8),Y(`click`,function(){return F(e),I(X(2).abort())}),Z(6,`Abort`),J()()}if(e&2){let e=t;z(3),Q(e.url),z(),$(` (#`,e.id,`) `)}}function Gw(e,t){if(e&1&&(q(0,`p`,4),Z(1),J()),e&2){let e=X(2);z(),Q(e.message())}}function Kw(e,t){if(e&1&&(q(0,`dt`),Z(1,`Document title`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X();z(3),Q(e.title)}}function qw(e,t){if(e&1&&(q(0,`dt`),Z(1,`Query params`),J(),q(2,`dd`)(3,`code`),Z(4),l_(5,`json`),J()()),e&2){let e=X();z(4),Q(d_(5,1,e.queryParams))}}function Jw(e,t){if(e&1&&(q(0,`dt`),Z(1,`Fragment`),J(),q(2,`dd`)(3,`code`),Z(4),J()()),e&2){let e=X();z(4),Q(e.fragment)}}function Yw(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=X().$implicit;z(),Q(e.route.outlet)}}function Xw(e,t){e&1&&(q(0,`span`,10),Z(1,`lazy`),J())}function Zw(e,t){if(e&1&&(q(0,`div`,11),Z(1),J()),e&2){let e=X().$implicit;z(),t_(` title `,e.route.title,``,e.route.ownTitle===!1?` (inherited)`:``,` `)}}function Qw(e,t){e&1&&(q(0,`span`,10),Z(1,`inherited`),J())}function $w(e,t){if(e&1&&(q(0,`div`)(1,`code`),Z(2),l_(3,`json`),J(),V(4,Qw,2,0,`span`,10),J()),e&2){let e=t.$implicit,n=X().$implicit;z(2),t_(``,e[0],`: `,d_(3,3,e[1])),z(2),H(n.route.paramSources?.[e[0]]===`inherited`?4:-1)}}function eT(e,t){e&1&&Z(0,` — `)}function tT(e,t){e&1&&(q(0,`span`,10),Z(1),J()),e&2&&(z(),Q(t))}function nT(e,t){if(e&1&&(q(0,`div`,12)(1,`code`),Z(2),l_(3,`json`),J(),V(4,tT,2,1,`span`,10),J()),e&2){let e,n=t.$implicit,r=X().$implicit;z(2),t_(``,n[0],`: `,d_(3,3,n[1])),z(2),H((e=r.route.dataSources?.[n[0]])?4:-1,e)}}function rT(e,t){e&1&&Z(0,` — `)}function iT(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=t.$implicit;z(),Q(e)}}function aT(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=t.$implicit;z(),$(`resolve `,e)}}function oT(e,t){e&1&&Z(0,` — `)}function sT(e,t){if(e&1&&(q(0,`tr`)(1,`td`,9),Z(2),V(3,Yw,2,1,`span`,10),V(4,Xw,2,0,`span`,10),V(5,Zw,2,2,`div`,11),J(),q(6,`td`),Z(7),J(),q(8,`td`),U(9,$w,5,5,`div`,null,Vw,!1,eT,1,0),J(),q(12,`td`),U(13,nT,5,5,`div`,12,Vw,!1,rT,1,0),J(),q(16,`td`),U(17,iT,2,1,`span`,10,kh),U(19,aT,2,1,`span`,10,kh),V(21,oT,1,0),J()()),e&2){let e=t.$implicit,n=X(2);z(),kg(`padding-left`,12+e.depth*16,`px`),z(),$(` `,e.depth===0&&!e.route.path?`(root)`:`/`+e.route.path,` `),z(),H(e.route.outlet===`primary`?-1:3),z(),H(e.route.lazy?4:-1),z(),H(e.route.title?5:-1),z(2),Q(e.route.component??`—`),z(2),W(n.entries(e.route.params)),z(4),W(n.entries(e.route.data)),z(4),W(n.guardList(e.route)),z(2),W(e.route.resolvers??i_(10,Bw)),z(2),H(!n.guardList(e.route).length&&!e.route.resolvers?21:-1)}}function cT(e,t){if(e&1&&(q(0,`code`),Z(1),J(),Z(2,` for `),q(3,`code`),Z(4),J()),e&2){let e=X().$implicit;z(),Q(e.outlet.component??`?`),z(3),Q(e.outlet.route??`?`)}}function lT(e,t){e&1&&(q(0,`span`,0),Z(1,`not activated`),J())}function uT(e,t){e&1&&(q(0,`span`,10),Z(1,`detached by reuse strategy`),J())}function dT(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=t.$implicit;z(),t_(`input `,e.input,` ← `,e.source)}}function fT(e,t){if(e&1&&(q(0,`li`)(1,`span`,10),Z(2),J(),V(3,cT,5,2)(4,lT,2,0,`span`,0),V(5,uT,2,0,`span`,10),U(6,dT,2,2,`span`,10,Hw),J()),e&2){let e=t.$implicit,n=X(3);kg(`padding-left`,e.depth*16,`px`),z(2),Q(e.outlet.outlet),z(),H(e.outlet.activated?3:4),z(2),H(e.outlet.detached?5:-1),z(),W(n.boundInputs(e.outlet))}}function pT(e,t){if(e&1&&(q(0,`h3`),Z(1,`Outlets`),J(),q(2,`ul`,13),U(3,fT,8,5,`li`,14,Oh),J()),e&2){let e=X(2);z(3),W(e.outletRows())}}function mT(e,t){if(e&1&&(q(0,`p`,1)(1,`code`),Z(2),J()(),V(3,Uw,5,1,`p`,2),V(4,Ww,7,2,`div`,3),V(5,Gw,2,1,`p`,4),q(6,`dl`,5),V(7,Kw,4,1),V(8,qw,6,3),V(9,Jw,5,1),J(),q(10,`h3`),Z(11,`Active routes`),J(),q(12,`div`,6)(13,`table`)(14,`thead`)(15,`tr`)(16,`th`,7),Z(17,`Route`),J(),q(18,`th`,7),Z(19,`Component`),J(),q(20,`th`,7),Z(21,`Params`),J(),q(22,`th`,7),Z(23,`Data`),J(),q(24,`th`,7),Z(25,`Guards and resolvers`),J()()(),q(26,`tbody`),U(27,sT,22,11,`tr`,null,Oh),J()()(),V(29,pT,5,0)),e&2){let e,n=t,r=X();z(2),Q(n.url),z(),H(n.urlDrift&&n.browserUrl?3:-1),z(),H((e=n.pending)?4:-1,e),z(),H(r.message()?5:-1),z(2),H(n.title?7:-1),z(),H(r.hasKeys(n.queryParams)?8:-1),z(),H(n.fragment?9:-1),z(18),W(r.rows()),z(2),H(r.outletRows().length?29:-1)}}function hT(e,t){e&1&&(q(0,`p`,0),Z(1,`This page reports no Router.`),J())}var gT=class e{page=k_.required();rpc=k_(null);message=L(``);rows=b_(()=>{let e=[],t=(n,r)=>{e.push({route:n,depth:r});for(let e of n.children)t(e,r+1)},n=this.page().snapshot?.root;return n&&t(n,0),e});outletRows=b_(()=>{let e=[],t=(n,r)=>{for(let i of n)e.push({outlet:i,depth:r}),i.children&&t(i.children,r+1)};return t(this.page().outlets??[],0),e});hasKeys(e){return Object.keys(e).length>0}entries(e){return Object.entries(e)}guardList(e){return Object.entries(e.guards??{}).flatMap(([e,t])=>t.map(t=>`${e} ${t}`))}boundInputs(e){return(e.inputs??[]).filter(e=>e.source!==`unset`)}async abort(){let e=await Rw(this.rpc(),this.page().pageId,{action:`abort`});this.message.set(e?.error?String(e.error):`Aborted navigation #${e?.aborted}`)}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-route-current`]],inputs:{page:[1,`page`],rpc:[1,`rpc`]},decls:2,vars:1,consts:[[1,`muted`],[1,`url`],[`role`,`note`,1,`note`],[`role`,`status`,1,`pending`],[`role`,`status`,1,`muted`],[1,`facts`],[`role`,`region`,`aria-label`,`Active routes`,`tabindex`,`0`,1,`table-scroll`],[`scope`,`col`],[`type`,`button`,1,`small`,3,`click`],[1,`path`],[1,`tag`],[1,`sub`],[1,`data`],[1,`outlets`],[3,`padding-left`]],template:function(e,t){if(e&1&&V(0,mT,30,8)(1,hT,2,0,`p`,0),e&2){let e;H((e=t.page().snapshot)?0:1,e)}},dependencies:[Wv],styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + font-size: 13px; + } + code[_ngcontent-%COMP%] { + font-family: monospace; + color: #d4d4d8; + overflow-wrap: anywhere; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 4px 0; + padding: 1px 6px; + border: 1px solid #52525b; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + font-family: monospace; + } + .badge[_ngcontent-%COMP%] { + padding: 1px 6px; + border-radius: 4px; + background: #3f3f46; + color: #e4e4e7; + font-size: 11px; + font-weight: 600; + } + .badge[data-tone='good'][_ngcontent-%COMP%] { + background: #14532d; + color: #bbf7d0; + } + .badge[data-tone='warn'][_ngcontent-%COMP%] { + background: #713f12; + color: #fef08a; + } + .badge[data-tone='bad'][_ngcontent-%COMP%] { + background: #7f1d1d; + color: #fecaca; + } + button.small[_ngcontent-%COMP%] { + padding: 3px 10px; + background: #3f3f46; + border: none; + border-radius: 6px; + color: #e4e4e7; + cursor: pointer; + font-size: 12px; + } + button.small[_ngcontent-%COMP%]:hover { + background: #52525b; + } + button.small[_ngcontent-%COMP%]:focus-visible, + input[_ngcontent-%COMP%]:focus-visible, + select[_ngcontent-%COMP%]:focus-visible, + .table-scroll[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + input.field[_ngcontent-%COMP%] { + padding: 6px 10px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .table-scroll[_ngcontent-%COMP%] { + overflow-x: auto; + } + table[_ngcontent-%COMP%] { + width: 100%; + border-collapse: collapse; + font-size: 13px; + } + th[_ngcontent-%COMP%] { + text-align: left; + padding: 6px 12px; + color: #a1a1aa; + font-size: 12px; + border-bottom: 1px solid #27272a; + } + td[_ngcontent-%COMP%] { + padding: 8px 12px; + border-bottom: 1px solid #1e1e22; + vertical-align: top; + } + h3[_ngcontent-%COMP%] { + margin: 0 0 8px; + font-size: 14px; + color: #e4e4e7; + } + .visually-hidden[_ngcontent-%COMP%] { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + } + + [_nghost-%COMP%] { + display: grid; + gap: 12px; + } + .url[_ngcontent-%COMP%] code[_ngcontent-%COMP%] { + font-size: 14px; + color: var(--%NS%accent); + } + .note[_ngcontent-%COMP%] { + margin: 0; + padding: 8px 10px; + border-left: 3px solid #fef08a; + background: #27272a; + color: #e4e4e7; + font-size: 13px; + } + .pending[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; + font-size: 13px; + color: #fef08a; + } + .facts[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: max-content 1fr; + gap: 4px 12px; + margin: 0; + font-size: 13px; + } + dt[_ngcontent-%COMP%] { + color: #a1a1aa; + } + dd[_ngcontent-%COMP%] { + margin: 0; + color: #e4e4e7; + } + .path[_ngcontent-%COMP%] { + font-family: monospace; + color: var(--%NS%accent); + white-space: nowrap; + } + .sub[_ngcontent-%COMP%] { + font-family: inherit; + color: #a1a1aa; + font-size: 12px; + white-space: normal; + } + .data[_ngcontent-%COMP%] { + max-width: 360px; + } + .outlets[_ngcontent-%COMP%] { + list-style: none; + margin: 0; + padding: 0; + display: grid; + gap: 6px; + font-size: 13px; + color: #e4e4e7; + }`]})};function _T(e,t){e&1&&(q(0,`p`,2),Z(1,`Checking…`),J())}function vT(e,t){if(e&1&&(q(0,`li`)(1,`div`,4)(2,`span`,5),Z(3),J(),q(4,`code`),Z(5),J(),q(6,`code`,6),Z(7),J()(),q(8,`p`),Z(9),J(),q(10,`p`,7),Z(11),q(12,`span`,2),Z(13),J()()()),e&2){let e=t.$implicit;z(2),B(`data-tone`,e.severity===`error`?`bad`:e.severity===`warning`?`warn`:``),z(),Q(e.severity),z(2),Q(e.rule),z(2),Q(e.route),z(2),Q(e.message),z(2),$(` Fix: `,e.fix,` `),z(2),$(`(Angular `,e.angular===`throws`?`throws`:e.angular===`warns`?`warns`:`does not warn`,`)`)}}function yT(e,t){if(e&1&&(q(0,`ul`,3),U(1,vT,14,7,`li`,null,Oh),J()),e&2){let e=X();z(),W(e.findings())}}function bT(e,t){e&1&&(q(0,`p`,2),Z(1,`No route config problems found.`),J())}var xT=class e{page=k_.required();rpc=k_(null);findings=L([]);loading=L(!1);key=b_(()=>`${this.page().pageId}:${this.page().generation}:${this.page().navigations.length}`);constructor(){Zs(()=>{this.key(),x_(()=>void this.run())})}async run(){this.loading.set(!0),this.findings.set(await Lw(this.rpc(),`router-lint`,this.page().pageId)??[]),this.loading.set(!1)}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-route-lint`]],inputs:{page:[1,`page`],rpc:[1,`rpc`]},decls:8,vars:1,consts:[[1,`toolbar`],[`type`,`button`,1,`small`,3,`click`],[1,`muted`],[1,`findings`],[1,`head`],[1,`badge`],[1,`route`],[1,`fix`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`button`,1),Y(`click`,function(){return t.run()}),Z(2,`Check again`),J(),q(3,`span`,2),Z(4,`Checks the live config, links and recent navigations. Lazy routes that have not loaded are skipped.`),J()(),V(5,_T,2,0,`p`,2)(6,yT,3,0,`ul`,3)(7,bT,2,0,`p`,2)),e&2&&(z(5),H(t.loading()?5:t.findings().length?6:7))},styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + font-size: 13px; + } + code[_ngcontent-%COMP%] { + font-family: monospace; + color: #d4d4d8; + overflow-wrap: anywhere; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 4px 0; + padding: 1px 6px; + border: 1px solid #52525b; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + font-family: monospace; + } + .badge[_ngcontent-%COMP%] { + padding: 1px 6px; + border-radius: 4px; + background: #3f3f46; + color: #e4e4e7; + font-size: 11px; + font-weight: 600; + } + .badge[data-tone='good'][_ngcontent-%COMP%] { + background: #14532d; + color: #bbf7d0; + } + .badge[data-tone='warn'][_ngcontent-%COMP%] { + background: #713f12; + color: #fef08a; + } + .badge[data-tone='bad'][_ngcontent-%COMP%] { + background: #7f1d1d; + color: #fecaca; + } + button.small[_ngcontent-%COMP%] { + padding: 3px 10px; + background: #3f3f46; + border: none; + border-radius: 6px; + color: #e4e4e7; + cursor: pointer; + font-size: 12px; + } + button.small[_ngcontent-%COMP%]:hover { + background: #52525b; + } + button.small[_ngcontent-%COMP%]:focus-visible, + input[_ngcontent-%COMP%]:focus-visible, + select[_ngcontent-%COMP%]:focus-visible, + .table-scroll[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + input.field[_ngcontent-%COMP%] { + padding: 6px 10px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .table-scroll[_ngcontent-%COMP%] { + overflow-x: auto; + } + table[_ngcontent-%COMP%] { + width: 100%; + border-collapse: collapse; + font-size: 13px; + } + th[_ngcontent-%COMP%] { + text-align: left; + padding: 6px 12px; + color: #a1a1aa; + font-size: 12px; + border-bottom: 1px solid #27272a; + } + td[_ngcontent-%COMP%] { + padding: 8px 12px; + border-bottom: 1px solid #1e1e22; + vertical-align: top; + } + h3[_ngcontent-%COMP%] { + margin: 0 0 8px; + font-size: 14px; + color: #e4e4e7; + } + .visually-hidden[_ngcontent-%COMP%] { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + } + + [_nghost-%COMP%] { + display: grid; + gap: 10px; + } + .toolbar[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; + } + .findings[_ngcontent-%COMP%] { + list-style: none; + margin: 0; + padding: 0; + display: grid; + gap: 8px; + } + .findings[_ngcontent-%COMP%] li[_ngcontent-%COMP%] { + padding: 10px; + border: 1px solid #27272a; + border-radius: 6px; + font-size: 13px; + color: #e4e4e7; + } + .head[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; + } + .route[_ngcontent-%COMP%] { + color: var(--%NS%accent); + } + p[_ngcontent-%COMP%] { + margin: 6px 0 0; + } + .fix[_ngcontent-%COMP%] { + color: #d4d4d8; + }`]})},ST=(e,t)=>t.name,CT=(e,t)=>t[0];function wT(e,t){e&1&&(q(0,`p`,1),Z(1,` Events-only mode: this build has no debug utils (production build or unusual setup), so the route config, lint and actions are limited. `),J())}function TT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Angular`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X();z(3),Q(e.angularVersion)}}function ET(e,t){if(e&1&&(q(0,`dt`),Z(1,`Base href`),J(),q(2,`dd`)(3,`code`),Z(4),J()()),e&2){let e=X();z(4),Q(e.baseHref)}}function DT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Hydration`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X();z(3),$(``,e.hydrated,` component(s) hydrated from server HTML`)}}function OT(e,t){if(e&1&&(q(0,`tr`)(1,`td`)(2,`code`),Z(3),J()(),q(4,`td`)(5,`code`),Z(6),J()(),q(7,`td`)(8,`span`,6),Z(9),J()()()),e&2){let e=t.$implicit;z(3),Q(e.name),z(3),Q(e.value),z(2),B(`data-tone`,e.set?`warn`:``),z(),Q(e.set?`set`:`default`)}}function kT(e,t){if(e&1&&(q(0,`li`)(1,`span`,6),Z(2),J()()),e&2){let e=t.$implicit;z(),B(`data-tone`,e[1]===`off`?``:`good`),z(),t_(``,e[0],`: `,e[1])}}function AT(e,t){if(e&1&&(q(0,`dt`),Z(1),J(),q(2,`dd`)(3,`code`),Z(4),J()()),e&2){let e=t.$implicit;z(),Q(e[0]),z(3),Q(e[1])}}function jT(e,t){if(e&1&&(V(0,wT,2,0,`p`,1),q(1,`dl`,2)(2,`dt`),Z(3,`Set up with`),J(),q(4,`dd`),Z(5),J(),V(6,TT,4,1),V(7,ET,5,1),V(8,DT,4,1),J(),q(9,`h3`),Z(10,`Options`),J(),q(11,`div`,3)(12,`table`)(13,`thead`)(14,`tr`)(15,`th`,4),Z(16,`Option`),J(),q(17,`th`,4),Z(18,`Value`),J(),q(19,`th`,4),Z(20,`Source`),J()()(),q(21,`tbody`),U(22,OT,10,4,`tr`,null,ST),J()()(),q(24,`h3`),Z(25,`Features`),J(),q(26,`ul`,5),U(27,kT,3,3,`li`,null,CT),J(),q(29,`h3`),Z(30,`Strategies`),J(),q(31,`dl`,2),U(32,AT,5,2,null,null,CT),J()),e&2){let e=t,n=X();H(e.mode===`events-only`?0:-1),z(5),t_(` `,e.setupKind,``,e.routers>1?`, `+e.routers+` routers on the page`:``,` `),z(),H(e.angularVersion?6:-1),z(),H(e.baseHref?7:-1),z(),H(e.hydrated?8:-1),z(14),W(e.options),z(5),W(n.entries(e.features)),z(5),W(n.entries(e.strategies))}}function MT(e,t){e&1&&(q(0,`p`,0),Z(1,`The page has not reported its router setup yet.`),J())}var NT=class e{page=k_.required();entries(e){return Object.entries(e)}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-route-setup`]],inputs:{page:[1,`page`]},decls:2,vars:1,consts:[[1,`muted`],[`role`,`note`,1,`note`],[1,`facts`],[`role`,`region`,`aria-label`,`Router options`,`tabindex`,`0`,1,`table-scroll`],[`scope`,`col`],[1,`chips`],[1,`badge`]],template:function(e,t){if(e&1&&V(0,jT,34,6)(1,MT,2,0,`p`,0),e&2){let e;H((e=t.page().setup)?0:1,e)}},styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + font-size: 13px; + } + code[_ngcontent-%COMP%] { + font-family: monospace; + color: #d4d4d8; + overflow-wrap: anywhere; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 4px 0; + padding: 1px 6px; + border: 1px solid #52525b; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + font-family: monospace; + } + .badge[_ngcontent-%COMP%] { + padding: 1px 6px; + border-radius: 4px; + background: #3f3f46; + color: #e4e4e7; + font-size: 11px; + font-weight: 600; + } + .badge[data-tone='good'][_ngcontent-%COMP%] { + background: #14532d; + color: #bbf7d0; + } + .badge[data-tone='warn'][_ngcontent-%COMP%] { + background: #713f12; + color: #fef08a; + } + .badge[data-tone='bad'][_ngcontent-%COMP%] { + background: #7f1d1d; + color: #fecaca; + } + button.small[_ngcontent-%COMP%] { + padding: 3px 10px; + background: #3f3f46; + border: none; + border-radius: 6px; + color: #e4e4e7; + cursor: pointer; + font-size: 12px; + } + button.small[_ngcontent-%COMP%]:hover { + background: #52525b; + } + button.small[_ngcontent-%COMP%]:focus-visible, + input[_ngcontent-%COMP%]:focus-visible, + select[_ngcontent-%COMP%]:focus-visible, + .table-scroll[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + input.field[_ngcontent-%COMP%] { + padding: 6px 10px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .table-scroll[_ngcontent-%COMP%] { + overflow-x: auto; + } + table[_ngcontent-%COMP%] { + width: 100%; + border-collapse: collapse; + font-size: 13px; + } + th[_ngcontent-%COMP%] { + text-align: left; + padding: 6px 12px; + color: #a1a1aa; + font-size: 12px; + border-bottom: 1px solid #27272a; + } + td[_ngcontent-%COMP%] { + padding: 8px 12px; + border-bottom: 1px solid #1e1e22; + vertical-align: top; + } + h3[_ngcontent-%COMP%] { + margin: 0 0 8px; + font-size: 14px; + color: #e4e4e7; + } + .visually-hidden[_ngcontent-%COMP%] { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + } + + [_nghost-%COMP%] { + display: grid; + gap: 12px; + } + .note[_ngcontent-%COMP%] { + margin: 0; + padding: 8px 10px; + border-left: 3px solid #fef08a; + background: #27272a; + color: #e4e4e7; + font-size: 13px; + } + .facts[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: max-content 1fr; + gap: 4px 12px; + margin: 0; + font-size: 13px; + } + dt[_ngcontent-%COMP%] { + color: #a1a1aa; + } + dd[_ngcontent-%COMP%] { + margin: 0; + color: #e4e4e7; + } + .chips[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin: 0; + padding: 0; + list-style: none; + }`]})},PT=(e,t)=>[e,t],FT=(e,t)=>t.id,IT=(e,t)=>t.phase;function LT(e,t){if(e&1&&(q(0,`p`,5),Z(1),J()),e&2){let e=X();z(),Q(e.message())}}function RT(e,t){if(e&1&&(q(0,`span`),Hh(1,`i`),Z(2),J()),e&2){let e=t.$implicit,n=X();z(),kg(`background`,n.color(e)),z(),Q(e)}}function zT(e,t){if(e&1&&(q(0,`time`),Z(1),J()),e&2){let e=X().$implicit,t=X(2);z(),Q(t.time(e.startedAt))}}function BT(e,t){if(e&1&&(q(0,`span`,15),Z(1,`→`),J(),q(2,`span`,16),Z(3,`redirected to`),J(),q(4,`code`),Z(5),J()),e&2){let e=X().$implicit;z(5),Q(e.finalUrl)}}function VT(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;z(),Q(e.endedAt===void 0&&e.outcome!==`pending`?`before DevTools connected`:`started before DevTools connected`)}}function HT(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;z(),$(``,e.phases?.total,`ms`)}}function UT(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;z(),$(``,e.endedAt-e.startedAt,`ms`)}}function WT(e,t){e&1&&(q(0,`span`,11),Z(1,`probe`),J())}function GT(e,t){if(e&1&&Hh(0,`span`),e&2){let e=t.$implicit,n=X(4);kg(`width`,e.width,`%`)(`background`,n.color(e.phase)),B(`title`,e.phase+` `+e.ms+`ms`)}}function KT(e,t){if(e&1&&(q(0,`div`,12),U(1,GT,1,5,`span`,17,IT),J()),e&2){let e=X().$implicit,t=X(2);B(`aria-label`,t.barLabel(e)),z(),W(t.bars(e))}}function qT(e,t){if(e&1&&(q(0,`dt`),Z(1,`From`),J(),q(2,`dd`)(3,`code`),Z(4),J()()),e&2){let e=X().$implicit;z(4),Q(e.from)}}function JT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Started by`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),t_(``,e.caller,` (`,e.trigger,`)`)}}function YT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Extras`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),Q(e.extras?.join(`, `))}}function XT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Redirect of`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),$(`#`,e.redirectedFrom)}}function ZT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Redirects to`),J(),q(2,`dd`)(3,`code`),Z(4),J(),Z(5),J()),e&2){let e=X().$implicit;z(4),Q(e.redirectTo),z(),$(` (`,e.redirectKind,`) `)}}function QT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Guards`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit,t=X(2);z(3),t_(``,e.guards.names.join(`, `)||`none`,`: `,t.guardResult(e))}}function $T(e,t){if(e&1&&(q(0,`div`)(1,`code`),Z(2),J(),Z(3),q(4,`code`),Z(5),J(),Z(6,`: `),q(7,`strong`),Z(8),J(),Z(9),J()),e&2){let e=t.$implicit,n=X(4);z(2),Q(e.guard),z(),$(` `,e.kind,` on `),z(2),Q(e.route),z(2),Ag(`bad`,n.isBad(e.result)),z(),Q(e.result),z(),$(` (`,e.ms,`ms) `)}}function eE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Runs`),J(),q(2,`dd`),U(3,$T,10,7,`div`,null,Oh),J()),e&2){let e=X().$implicit;z(3),W(e.runs)}}function tE(e,t){if(e&1&&Z(0),e&2){let e=X(2).$implicit;$(` leaving `,e.checked.deactivate.join(`, `),`; `)}}function nE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Checked`),J(),q(2,`dd`),V(3,tE,1,1),Z(4),J()),e&2){let e=X().$implicit;z(3),H(e.checked.deactivate.length?3:-1),z(),$(` entering `,e.checked.activate.join(`, `)||`nothing new`,` `)}}function rE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Resolvers`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),Q(e.resolvers?.names?.join(`, `))}}function iE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Lazy loaded`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),Q(e.lazyLoaded?.join(`, `))}}function aE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Reused`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),$(` `,e.reused?.join(`, `),` (component kept, only inputs and params change) `)}}function oE(e,t){if(e&1&&(q(0,`dt`),Z(1,`HTTP`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),t_(``,e.requests.count,` request(s): `,e.requests.urls.join(`, `))}}function sE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Scroll`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),Q(e.scroll)}}function cE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Title after`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),Q(e.title)}}function lE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Warnings`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),Q(e.warnings?.join(` · `))}}function uE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Reason`),J(),q(2,`dd`,18),Z(3),J()),e&2){let e=X().$implicit,t=X(2);z(3),Q(a_(1,PT,e.code,e.reason).filter(t.Boolean).join(`: `))}}function dE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Error`),J(),q(2,`dd`,18),Z(3),J()),e&2){let e=X().$implicit;z(3),Q(e.errorCode)}}function fE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Error handler`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),Q(e.errorHandler)}}function pE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Earlier`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;z(3),$(``,e.earlier,` navigation(s) before DevTools connected`)}}function mE(e,t){if(e&1){let e=Yh();q(0,`li`)(1,`div`,9),V(2,zT,2,1,`time`),q(3,`span`,8),Z(4),J(),q(5,`code`),Z(6),J(),V(7,BT,6,1),q(8,`span`,10),Z(9),J(),V(10,VT,2,1,`span`,8)(11,HT,2,1,`span`,8)(12,UT,2,1,`span`,8),V(13,WT,2,0,`span`,11),J(),V(14,KT,3,1,`div`,12),q(15,`dl`,13),V(16,qT,5,1),V(17,JT,4,2),V(18,YT,4,1),V(19,XT,4,1),V(20,ZT,6,2),V(21,QT,4,2),V(22,eE,5,0),V(23,nE,5,2),V(24,rE,4,1),V(25,iE,4,1),V(26,aE,4,1),V(27,oE,4,2),V(28,sE,4,1),V(29,cE,4,1),V(30,lE,4,1),V(31,uE,4,4),V(32,dE,4,1),V(33,fE,4,1),V(34,pE,4,1),J(),q(35,`div`,14)(36,`button`,4),Y(`click`,function(){let t=F(e).$implicit;return I(X(2).replay(t))}),Z(37,` Replay `),J(),q(38,`button`,4),Y(`click`,function(){let t=F(e).$implicit;return I(X(2).copy(t))}),Z(39,` Copy repro `),J()()()}if(e&2){let e=t.$implicit,n=X(2);z(2),H(e.beforeConnect?-1:2),z(2),$(`#`,e.id),z(2),Q(e.url),z(),H(e.finalUrl&&e.finalUrl!==e.url?7:-1),z(),B(`data-tone`,n.tone(e.outcome)),z(),Q(e.outcome),z(),H(e.beforeConnect?10:e.phases?.total===void 0?e.endedAt===void 0?-1:12:11),z(3),H(e.probe?13:-1),z(),H(n.bars(e).length?14:-1),z(2),H(e.from?16:-1),z(),H(e.caller?17:-1),z(),H(e.extras?.length?18:-1),z(),H(e.redirectedFrom===void 0?-1:19),z(),H(e.redirectTo?20:-1),z(),H(e.guards&&(e.guards.names.length||e.guards.passed===!1)?21:-1),z(),H(e.runs?.length?22:-1),z(),H(e.checked&&(e.checked.activate.length||e.checked.deactivate.length)?23:-1),z(),H(e.resolvers?.names?.length?24:-1),z(),H(e.lazyLoaded?.length?25:-1),z(),H(e.reused?.length?26:-1),z(),H(e.requests?27:-1),z(),H(e.scroll?28:-1),z(),H(e.title?29:-1),z(),H(e.warnings?.length?30:-1),z(),H(e.reason||e.code?31:-1),z(),H(e.errorCode?32:-1),z(),H(e.errorHandler?33:-1),z(),H(e.earlier?34:-1),z(2),B(`aria-label`,`Replay navigation `+e.id),z(2),B(`aria-label`,`Copy repro for navigation `+e.id)}}function hE(e,t){if(e&1&&(q(0,`ol`,7),U(1,mE,40,30,`li`,null,FT),J()),e&2){let e=X();z(),W(e.items())}}function gE(e,t){e&1&&(q(0,`p`,8),Z(1,` No navigations since DevTools connected; earlier ones are not visible. Click a link in the app. `),J())}var _E=[`recognize`,`guards`,`resolve`,`activate`],vE={recognize:`#60a5fa`,guards:`#f59e0b`,resolve:`#a78bfa`,activate:`#34d399`},yE=class e{page=k_.required();rpc=k_(null);phases=_E;filter=L(``);onlyProblems=L(!1);message=L(``);items=b_(()=>{let e=this.filter().toLowerCase();return[...this.page().navigations].reverse().filter(t=>(!e||t.url.toLowerCase().includes(e)||!!t.finalUrl?.toLowerCase().includes(e))&&(!this.onlyProblems()||![`succeeded`,`pending`].includes(t.outcome)))});tone(e){return zw(e)}color(e){return vE[e]}bars(e){let t=e.phases?.total;return t?_E.filter(t=>(e.phases?.[t]??0)>0).map(n=>({phase:n,ms:e.phases[n],width:Math.max(1,e.phases[n]/t*100)})):[]}barLabel(e){return`Phases: ${this.bars(e).map(e=>`${e.phase} ${e.ms}ms`).join(`, `)}`}guardResult(e){let t=e.guards?.passed;return t===!0?`passed`:t===!1?e.outcome===`redirected`?`redirected`:`blocked`:e.outcome===`pending`?`running`:`did not finish, navigation ${e.outcome}`}isBad(e){return e===`false`||/^(UrlTree|RedirectCommand|threw)/.test(e)}time(e){return new Date(e).toLocaleTimeString()}async toggleInstrument(e){let t=e.target.checked,n=await Rw(this.rpc(),this.page().pageId,{action:`instrument`,on:t});this.message.set(n?.error?String(n.error):t?`Recording each guard and resolver.`:`Stopped recording guards and resolvers.`)}async replay(e){this.message.set(`Replaying #${e.id}…`);let t=await Rw(this.rpc(),this.page().pageId,{action:`replay`,id:e.id});if(!t||t.error){this.message.set(String(t?.error??`Replay failed.`));return}let n=t.replay;this.message.set(`Replay of #${e.id}: ${n?.outcome??`unknown`}${t.same?` (same as before)`:` (different from before)`}.`)}async copy(e){let t=await Lw(this.rpc(),`router-export`,{pageId:this.page().pageId,id:e.id});if(!t){this.message.set(`Could not build the repro.`);return}try{await navigator.clipboard.writeText(t),this.message.set(`Copied a markdown repro of #${e.id}.`)}catch{this.message.set(`The clipboard is not available here.`)}}exportJson(){let e=new Blob([JSON.stringify(this.page().navigations,null,2)],{type:`application/json`}),t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`navigations-${this.page().pageId}.json`,n.click(),URL.revokeObjectURL(t)}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-route-timeline`]],inputs:{page:[1,`page`],rpc:[1,`rpc`]},decls:16,vars:5,consts:[[1,`toolbar`],[1,`check`],[`type`,`checkbox`,3,`change`,`checked`],[`type`,`text`,`aria-label`,`Filter navigations by URL`,`placeholder`,`Filter by URL`,1,`field`,3,`input`,`value`],[`type`,`button`,1,`small`,3,`click`],[`role`,`status`,1,`muted`],[`aria-hidden`,`true`,1,`legend`],[1,`navs`],[1,`muted`],[1,`head`],[1,`badge`],[1,`tag`],[`role`,`img`,1,`bar`],[1,`details`],[1,`actions`],[`aria-hidden`,`true`],[1,`visually-hidden`],[3,`width`,`background`],[1,`reason`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`label`,1)(2,`input`,2),Y(`change`,function(e){return t.toggleInstrument(e)}),J(),Z(3,` Record each guard and resolver `),J(),q(4,`input`,3),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(5,`label`,1)(6,`input`,2),Y(`change`,function(e){return t.onlyProblems.set(e.target.checked)}),J(),Z(7,` Only problems `),J(),q(8,`button`,4),Y(`click`,function(){return t.exportJson()}),Z(9,`Export JSON`),J()(),V(10,LT,2,1,`p`,5),q(11,`div`,6),U(12,RT,3,3,`span`,null,kh),J(),V(14,hE,3,0,`ol`,7)(15,gE,2,0,`p`,8)),e&2&&(z(2),Xh(`checked`,t.page().instrumented),z(2),Xh(`value`,t.filter()),z(2),Xh(`checked`,t.onlyProblems()),z(4),H(t.message()?10:-1),z(2),W(t.phases),z(2),H(t.items().length?14:15))},styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + font-size: 13px; + } + code[_ngcontent-%COMP%] { + font-family: monospace; + color: #d4d4d8; + overflow-wrap: anywhere; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 4px 0; + padding: 1px 6px; + border: 1px solid #52525b; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + font-family: monospace; + } + .badge[_ngcontent-%COMP%] { + padding: 1px 6px; + border-radius: 4px; + background: #3f3f46; + color: #e4e4e7; + font-size: 11px; + font-weight: 600; + } + .badge[data-tone='good'][_ngcontent-%COMP%] { + background: #14532d; + color: #bbf7d0; + } + .badge[data-tone='warn'][_ngcontent-%COMP%] { + background: #713f12; + color: #fef08a; + } + .badge[data-tone='bad'][_ngcontent-%COMP%] { + background: #7f1d1d; + color: #fecaca; + } + button.small[_ngcontent-%COMP%] { + padding: 3px 10px; + background: #3f3f46; + border: none; + border-radius: 6px; + color: #e4e4e7; + cursor: pointer; + font-size: 12px; + } + button.small[_ngcontent-%COMP%]:hover { + background: #52525b; + } + button.small[_ngcontent-%COMP%]:focus-visible, + input[_ngcontent-%COMP%]:focus-visible, + select[_ngcontent-%COMP%]:focus-visible, + .table-scroll[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + input.field[_ngcontent-%COMP%] { + padding: 6px 10px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .table-scroll[_ngcontent-%COMP%] { + overflow-x: auto; + } + table[_ngcontent-%COMP%] { + width: 100%; + border-collapse: collapse; + font-size: 13px; + } + th[_ngcontent-%COMP%] { + text-align: left; + padding: 6px 12px; + color: #a1a1aa; + font-size: 12px; + border-bottom: 1px solid #27272a; + } + td[_ngcontent-%COMP%] { + padding: 8px 12px; + border-bottom: 1px solid #1e1e22; + vertical-align: top; + } + h3[_ngcontent-%COMP%] { + margin: 0 0 8px; + font-size: 14px; + color: #e4e4e7; + } + .visually-hidden[_ngcontent-%COMP%] { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + } + + [_nghost-%COMP%] { + display: grid; + gap: 10px; + } + .toolbar[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 8px 14px; + align-items: center; + font-size: 13px; + color: #e4e4e7; + } + .check[_ngcontent-%COMP%] { + display: flex; + gap: 6px; + align-items: center; + } + .legend[_ngcontent-%COMP%] { + display: flex; + gap: 12px; + font-size: 12px; + color: #a1a1aa; + } + .legend[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { + display: inline-block; + width: 10px; + height: 10px; + margin-right: 4px; + border-radius: 2px; + } + .navs[_ngcontent-%COMP%] { + list-style: none; + margin: 0; + padding: 0; + display: grid; + gap: 8px; + } + .navs[_ngcontent-%COMP%] > li[_ngcontent-%COMP%] { + padding: 10px; + border: 1px solid #27272a; + border-radius: 6px; + font-size: 13px; + } + .head[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; + } + time[_ngcontent-%COMP%] { + color: #a1a1aa; + font-size: 12px; + } + .bar[_ngcontent-%COMP%] { + display: flex; + height: 6px; + margin: 8px 0 4px; + border-radius: 3px; + overflow: hidden; + background: #27272a; + } + .bar[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { + display: block; + min-width: 2px; + } + .details[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: max-content 1fr; + gap: 3px 12px; + margin: 6px 0 0; + font-size: 12px; + } + dt[_ngcontent-%COMP%] { + color: #a1a1aa; + } + dd[_ngcontent-%COMP%] { + margin: 0; + color: #e4e4e7; + overflow-wrap: anywhere; + } + .reason[_ngcontent-%COMP%], + .bad[_ngcontent-%COMP%] { + color: #fecaca; + } + .actions[_ngcontent-%COMP%] { + display: flex; + gap: 8px; + margin-top: 8px; + }`]})},bE=()=>[],xE=(e,t)=>t.node.id;function SE(e,t){if(e&1&&(Z(0,` with `),q(1,`code`),Z(2),l_(3,`json`),J()),e&2){let e=X(2);z(2),Q(d_(3,1,e.params))}}function CE(e,t){if(e&1&&(Z(0),V(1,SE,4,3)),e&2){let e=X(),t=X();$(` Matches `,t.chainText(e),` `),z(),H(t.hasKeys(e.params)?1:-1)}}function wE(e,t){e&1&&Z(0),e&2&&$(` Nearest: `,X(2).nearest.join(`, `),` `)}function TE(e,t){if(e&1&&(Z(0,` Matches no route (NG04002). `),V(1,wE,1,1)),e&2){let e=X();z(),H(e.nearest.length?1:-1)}}function EE(e,t){if(e&1&&(q(0,`div`,8),Z(1),J()),e&2){let e=t.$implicit;z(),Q(e)}}function DE(e,t){if(e&1&&(q(0,`div`,5),V(1,CE,2,2)(2,TE,2,1),U(3,EE,2,1,`div`,8,kh),J()),e&2){let e=t;z(),H(e.matched?1:2),z(2),W(e.notes)}}function OE(e,t){if(e&1&&(q(0,`p`,6),Z(1),J()),e&2){let e=X();z(),Q(e.message())}}function kE(e,t){if(e&1&&(q(0,`p`,8),Z(1),J()),e&2){let e=X();z(),$(` `,e.page().setup?.mode===`events-only`?`This build has no debug utils, so the live config cannot be read.`:`The page has not reported its route config yet.`,` `)}}function AE(e,t){e&1&&(q(0,`span`,14),Z(1,`active`),J())}function jE(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=X().$implicit;z(),$(`lazy `,e.node.lazy)}}function ME(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=X().$implicit;z(),$(`outlet `,e.node.outlet)}}function NE(e,t){if(e&1&&(Z(0,` redirect → `),q(1,`code`),Z(2),J()),e&2){let e=X().$implicit;z(2),Q(e.node.redirectTo)}}function PE(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` `,e.node.component??(e.node.lazy===`unloaded`?`lazy, not loaded yet`:e.node.kind),` `)}}function FE(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=t.$implicit;z(),Q(e)}}function IE(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=t.$implicit;z(),$(`resolve `,e)}}function LE(e,t){if(e&1){let e=Yh();q(0,`input`,18),Y(`input`,function(t){let n=F(e).$implicit,r=X(2).$implicit;return I(X(2).setParam(r.node.id,n,t.target.value))}),J()}if(e&2){let e=t.$implicit,n=X(2).$implicit;Xh(`placeholder`,e),B(`aria-label`,e+` for `+n.node.fullPath)}}function RE(e,t){if(e&1){let e=Yh();U(0,LE,1,2,`input`,17,kh),q(2,`button`,4),Y(`click`,function(){F(e);let t=X().$implicit;return I(X(2).navigate(t.node))}),Z(3,` Go `),J()}if(e&2){let e=X().$implicit;W(X(2).params(e.node)),z(2),B(`aria-label`,`Navigate to `+e.node.fullPath)}}function zE(e,t){if(e&1){let e=Yh();q(0,`button`,4),Y(`click`,function(){F(e);let t=X().$implicit;return I(X(2).resolveLazy(t.node))}),Z(1,` Read lazy `),J()}if(e&2){let e=X().$implicit;B(`aria-label`,`Read lazy routes of `+e.node.fullPath)}}function BE(e,t){if(e&1&&(q(0,`tr`)(1,`td`,13),Z(2),V(3,AE,2,0,`span`,14),V(4,jE,2,1,`span`,14),V(5,ME,2,1,`span`,14),J(),q(6,`td`),V(7,NE,3,1)(8,PE,1,1),J(),q(9,`td`),U(10,FE,2,1,`span`,14,kh),U(12,IE,2,1,`span`,14,kh),J(),q(14,`td`),Z(15),J(),q(16,`td`,15),V(17,RE,4,1),V(18,zE,2,1,`button`,16),J()()),e&2){let e=t.$implicit,n=X(2);Ag(`active`,n.isActive(e.node)),z(),kg(`padding-left`,12+e.depth*16,`px`),z(),$(` `,e.node.fullPath,` `),z(),H(n.isActive(e.node)?3:-1),z(),H(e.node.lazy?4:-1),z(),H(e.node.outlet?5:-1),z(2),H(e.node.redirectTo===void 0?8:7),z(3),W(n.guardList(e.node)),z(2),W(e.node.resolvers??i_(12,bE)),z(3),Q(e.node.title??``),z(2),H(n.canNavigate(e.node)?17:-1),z(),H(e.node.kind===`lazy`&&e.node.lazy===`unloaded`?18:-1)}}function VE(e,t){if(e&1&&(q(0,`p`,8),Z(1),J(),q(2,`div`,9)(3,`table`)(4,`thead`)(5,`tr`)(6,`th`,10),Z(7,`Path`),J(),q(8,`th`,10),Z(9,`Target`),J(),q(10,`th`,10),Z(11,`Guards and resolvers`),J(),q(12,`th`,10),Z(13,`Title`),J(),q(14,`th`,10)(15,`span`,11),Z(16,`Actions`),J()()()(),q(17,`tbody`),U(18,BE,19,13,`tr`,12,xE),J()()()),e&2){let e=X();z(),t_(` Generation `,e.page().generation,` · `,e.rows().length,` route(s). Lazy routes show their children once loaded. `),z(17),W(e.rows())}}var HE=class e{page=k_.required();rpc=k_(null);filter=L(``);testUrl=L(``);match=L(null);message=L(``);paramValues=new Map;active=b_(()=>new Set(this.page().activeIds??[]));rows=b_(()=>{let e=this.filter().toLowerCase(),t=[],n=(r,i)=>{for(let a of r)(!e||a.fullPath.toLowerCase().includes(e)||a.component?.toLowerCase().includes(e))&&t.push({node:a,depth:i}),a.children&&n(a.children,i+1)};return n(this.page().config??[],0),t});hasKeys(e){return Object.keys(e).length>0}isActive(e){return this.active().has(e.id)}guardList(e){return Object.entries(e.guards??{}).flatMap(([e,t])=>t.map(t=>`${e} ${t}`))}params(e){return(e.fullPath.match(/:([A-Za-z0-9_]+)/g)??[]).map(e=>e.slice(1))}canNavigate(e){return e.redirectTo===void 0&&!e.outlet&&!e.fullPath.includes(`**`)&&(!!e.component||e.kind===`component`||e.kind===`lazy`)}setParam(e,t,n){this.paramValues.set(e,{...this.paramValues.get(e),[t]:n})}chainText(e){return e.chain.map(e=>e.fullPath).join(` → `)}async predict(){let e=this.testUrl().trim();e&&this.match.set(await Lw(this.rpc(),`router-match`,{pageId:this.page().pageId,url:e}))}async probe(){let e=this.testUrl().trim();if(!e)return;this.message.set(`Running the real matcher in the app…`);let t=await Rw(this.rpc(),this.page().pageId,{action:`probe`,url:e});if(!t||t.error){this.message.set(String(t?.error??`Probe failed.`));return}this.message.set(t.matched?`The app matched ${e} (see the probe entry in Navigations).`:`The app did not match ${e}: ${String(t.reason??``)}`)}async navigate(e){let t=this.paramValues.get(e.id)??{};this.message.set(`Navigating to ${e.fullPath}…`);let n=await Rw(this.rpc(),this.page().pageId,{action:`navigate`,pattern:e.fullPath,params:t});this.message.set(!n||n.error?String(n?.error??`Navigation failed.`):`Navigation #${n.id}: ${n.outcome}${n.finalUrl?` at ${n.finalUrl}`:``}.`)}async resolveLazy(e){let t=await Rw(this.rpc(),this.page().pageId,{action:`resolve-lazy`,id:e.id});if(!t||t.error){this.message.set(String(t?.error??`Could not read the lazy routes.`));return}let n=t.routes??[];this.message.set(`${e.fullPath} declares ${n.length} route(s): ${n.map(e=>`/${e.path}`).join(`, `)}. The router loads them for real on the first navigation that needs them.`)}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-route-tree`]],inputs:{page:[1,`page`],rpc:[1,`rpc`]},decls:13,vars:5,consts:[[1,`test`,3,`submit`],[`for`,`test-url`],[`id`,`test-url`,`type`,`text`,`placeholder`,`/users/42`,1,`field`,3,`input`,`value`],[`type`,`submit`,1,`small`],[`type`,`button`,1,`small`,3,`click`],[`role`,`status`,1,`result`],[`role`,`status`,1,`muted`],[`type`,`text`,`aria-label`,`Filter routes`,`placeholder`,`Filter by path or component`,1,`field`,`filter`,3,`input`,`value`],[1,`muted`],[`role`,`region`,`aria-label`,`Live route config`,`tabindex`,`0`,1,`table-scroll`],[`scope`,`col`],[1,`visually-hidden`],[3,`active`],[1,`path`],[1,`tag`],[1,`actions`],[`type`,`button`,1,`small`],[`type`,`text`,1,`field`,`param`,3,`placeholder`],[`type`,`text`,1,`field`,`param`,3,`input`,`placeholder`]],template:function(e,t){if(e&1&&(q(0,`form`,0),Y(`submit`,function(e){return e.preventDefault(),t.predict()}),q(1,`label`,1),Z(2,`Test a URL`),J(),q(3,`input`,2),Y(`input`,function(e){return t.testUrl.set(e.target.value)}),J(),q(4,`button`,3),Z(5,`Predict`),J(),q(6,`button`,4),Y(`click`,function(){return t.probe()}),Z(7,`Probe in app`),J()(),V(8,DE,5,1,`div`,5),V(9,OE,2,1,`p`,6),q(10,`input`,7),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),V(11,kE,2,1,`p`,8)(12,VE,20,2)),e&2){let e;z(3),Xh(`value`,t.testUrl()),z(5),H((e=t.match())?8:-1,e),z(),H(t.message()?9:-1),z(),Xh(`value`,t.filter()),z(),H(t.page().config?12:11)}},dependencies:[Wv],styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + font-size: 13px; + } + code[_ngcontent-%COMP%] { + font-family: monospace; + color: #d4d4d8; + overflow-wrap: anywhere; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 4px 0; + padding: 1px 6px; + border: 1px solid #52525b; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + font-family: monospace; + } + .badge[_ngcontent-%COMP%] { + padding: 1px 6px; + border-radius: 4px; + background: #3f3f46; + color: #e4e4e7; + font-size: 11px; + font-weight: 600; + } + .badge[data-tone='good'][_ngcontent-%COMP%] { + background: #14532d; + color: #bbf7d0; + } + .badge[data-tone='warn'][_ngcontent-%COMP%] { + background: #713f12; + color: #fef08a; + } + .badge[data-tone='bad'][_ngcontent-%COMP%] { + background: #7f1d1d; + color: #fecaca; + } + button.small[_ngcontent-%COMP%] { + padding: 3px 10px; + background: #3f3f46; + border: none; + border-radius: 6px; + color: #e4e4e7; + cursor: pointer; + font-size: 12px; + } + button.small[_ngcontent-%COMP%]:hover { + background: #52525b; + } + button.small[_ngcontent-%COMP%]:focus-visible, + input[_ngcontent-%COMP%]:focus-visible, + select[_ngcontent-%COMP%]:focus-visible, + .table-scroll[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + input.field[_ngcontent-%COMP%] { + padding: 6px 10px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .table-scroll[_ngcontent-%COMP%] { + overflow-x: auto; + } + table[_ngcontent-%COMP%] { + width: 100%; + border-collapse: collapse; + font-size: 13px; + } + th[_ngcontent-%COMP%] { + text-align: left; + padding: 6px 12px; + color: #a1a1aa; + font-size: 12px; + border-bottom: 1px solid #27272a; + } + td[_ngcontent-%COMP%] { + padding: 8px 12px; + border-bottom: 1px solid #1e1e22; + vertical-align: top; + } + h3[_ngcontent-%COMP%] { + margin: 0 0 8px; + font-size: 14px; + color: #e4e4e7; + } + .visually-hidden[_ngcontent-%COMP%] { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + } + + [_nghost-%COMP%] { + display: grid; + gap: 10px; + } + .test[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; + font-size: 13px; + color: #e4e4e7; + } + .result[_ngcontent-%COMP%] { + padding: 8px 10px; + border: 1px solid #27272a; + border-radius: 6px; + font-size: 13px; + color: #e4e4e7; + } + .filter[_ngcontent-%COMP%] { + max-width: 320px; + } + .path[_ngcontent-%COMP%] { + font-family: monospace; + color: var(--%NS%accent); + white-space: nowrap; + } + tr.active[_ngcontent-%COMP%] td[_ngcontent-%COMP%] { + background: #1c1917; + } + .actions[_ngcontent-%COMP%] { + white-space: nowrap; + } + .param[_ngcontent-%COMP%] { + width: 80px; + margin-right: 4px; + }`]})},UE=(e,t)=>t.id,WE=(e,t)=>t.pageId;function GE(e,t){e&1&&(G(0,`p`,0),Z(1,`Could not load the live router state.`),K())}function KE(e,t){e&1&&(G(0,`p`,0),Z(1,`Loading the live router state…`),K())}function qE(e,t){if(e&1&&(G(0,`option`,8),Z(1),K()),e&2){let e=t.$implicit,n=X(2);Rh(`value`,e.pageId)(`selected`,e.pageId===n.pageId),z(),t_(` `,e.snapshot?.url??e.pageId,` (`,e.pageId,`) `)}}function JE(e,t){if(e&1){let e=Yh();G(0,`label`,1),Z(1,` Page `),G(2,`select`,7),sg(`change`,function(t){return F(e),I(X(2).pickPage(t))}),U(3,qE,2,4,`option`,8,WE),K()()}if(e&2){let e=X(2);z(3),W(e.pages())}}function YE(e,t){if(e&1&&(G(0,`span`,10),Z(1),K()),e&2){let e=X(3);B(`aria-label`,e.problems()+` problem navigations`),z(),Q(e.problems())}}function XE(e,t){if(e&1){let e=Yh();G(0,`button`,9),sg(`click`,function(){let t=F(e).$implicit;return I(X(2).selected.set(t.id))}),Z(1),V(2,YE,2,2,`span`,10),K()}if(e&2){let e=t.$implicit,n=X(2);Rh(`id`,`router-tab-`+e.id),B(`aria-selected`,e.id===n.selected())(`aria-controls`,`router-panel-`+e.id)(`tabindex`,e.id===n.selected()?0:-1),z(),$(` `,e.label,` `),z(),H(e.id===`navigations`&&n.problems()>0?2:-1)}}function ZE(e,t){if(e&1&&Vh(0,`app-route-current`,5),e&2){let e=X(),t=X();Rh(`page`,e)(`rpc`,t.rpc())}}function QE(e,t){if(e&1&&Vh(0,`app-route-timeline`,5),e&2){let e=X(),t=X();Rh(`page`,e)(`rpc`,t.rpc())}}function $E(e,t){if(e&1&&Vh(0,`app-route-tree`,5),e&2){let e=X(),t=X();Rh(`page`,e)(`rpc`,t.rpc())}}function eD(e,t){e&1&&Vh(0,`app-route-setup`,6),e&2&&Rh(`page`,X())}function tD(e,t){if(e&1&&Vh(0,`app-route-lint`,5),e&2){let e=X(),t=X();Rh(`page`,e)(`rpc`,t.rpc())}}function nD(e,t){if(e&1){let e=Yh();V(0,JE,5,0,`label`,1),G(1,`div`,2),sg(`keydown`,function(t){return F(e),I(X().onKey(t))}),U(2,XE,3,6,`button`,3,UE),K(),G(4,`div`,4),V(5,ZE,1,2,`app-route-current`,5)(6,QE,1,2,`app-route-timeline`,5)(7,$E,1,2,`app-route-tree`,5)(8,eD,1,1,`app-route-setup`,6)(9,tD,1,2,`app-route-lint`,5),K()}if(e&2){let e,t=X();H(t.pages().length>1?0:-1),z(2),W(t.tabs),z(2),Rh(`id`,`router-panel-`+t.selected()),B(`aria-labelledby`,`router-tab-`+t.selected()),z(),H((e=t.selected())===`current`?5:e===`navigations`?6:e===`routes`?7:e===`setup`?8:e===`lint`?9:-1)}}function rD(e,t){e&1&&(G(0,`p`,0),Z(1,`No page is reporting router state yet. Open the app in a browser.`),K())}var iD=[{id:`current`,label:`Current`},{id:`navigations`,label:`Navigations`},{id:`routes`,label:`Routes`},{id:`setup`,label:`Setup`},{id:`lint`,label:`Lint`}],aD=class e{rpc=k_(null);tabs=iD;selected=L(`current`);pages=L([]);loading=L(!0);failed=L(!1);pageId=C_({source:this.pages,computation:(e,t)=>t?.value&&e.some(e=>e.pageId===t.value)?t.value:e.find(e=>e.snapshot)?.pageId??e[0]?.pageId??null});unsubscribe=null;destroyRef=M(us);page=b_(()=>{let e=this.pages();return e.find(e=>e.pageId===this.pageId())??e[0]??null});problems=b_(()=>(this.page()?.navigations??[]).filter(e=>!e.probe&&[`failed`,`cancelled`,`redirected`].includes(e.outcome)).length);constructor(){Zs(()=>{let e=this.rpc();e&&this.load(e)}),this.destroyRef.onDestroy(()=>this.unsubscribe?.())}async load(e){this.loading.set(!0),this.failed.set(!1);try{let t=await e.scope(`ng-devtools`).rpc.sharedState(`router`);if(this.destroyRef.destroyed)return;let n=e=>{this.pages.set(e?.pages??[])};n(t.value()),this.unsubscribe?.(),this.unsubscribe=t.on(`updated`,n)}catch{this.failed.set(!0)}finally{this.loading.set(!1)}}pickPage(e){this.pageId.set(e.target.value)}onKey(e){let t=this.tabs.map(e=>e.id),n=t.indexOf(this.selected()),r=n;if(e.key===`ArrowRight`)r=(n+1)%t.length;else if(e.key===`ArrowLeft`)r=(n-1+t.length)%t.length;else if(e.key===`Home`)r=0;else if(e.key===`End`)r=t.length-1;else return;e.preventDefault(),this.selected.set(t[r]);let i=e.currentTarget;queueMicrotask(()=>i.querySelector(`#router-tab-${t[r]}`)?.focus())}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-live-route`]],inputs:{rpc:[1,`rpc`]},decls:4,vars:1,consts:[[1,`muted`],[1,`page-pick`],[`role`,`tablist`,`aria-label`,`Router views`,1,`tabs`,3,`keydown`],[`type`,`button`,`role`,`tab`,3,`id`],[`role`,`tabpanel`,1,`panel`,3,`id`],[3,`page`,`rpc`],[3,`page`],[3,`change`],[3,`value`,`selected`],[`type`,`button`,`role`,`tab`,3,`click`,`id`],[1,`count`]],template:function(e,t){if(e&1&&V(0,GE,2,0,`p`,0)(1,KE,2,0,`p`,0)(2,nD,10,4)(3,rD,2,0,`p`,0),e&2){let e;H(t.failed()?0:t.loading()?1:(e=t.page())?2:3,e)}},dependencies:[gT,xT,NT,yE,HE],styles:[`[_nghost-%COMP%] { + display: grid; + gap: 12px; + margin-bottom: 28px; + } + .muted[_ngcontent-%COMP%] { + color: #a1a1aa; + font-size: 13px; + } + .page-pick[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; + font-size: 13px; + color: #d4d4d8; + } + select[_ngcontent-%COMP%] { + max-width: 100%; + min-width: 0; + padding: 4px 8px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + } + .tabs[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 4px; + border-bottom: 1px solid #27272a; + } + [role='tab'][_ngcontent-%COMP%] { + padding: 6px 12px; + background: none; + border: none; + border-bottom: 2px solid transparent; + color: #a1a1aa; + cursor: pointer; + font-size: 13px; + } + [role='tab'][aria-selected='true'][_ngcontent-%COMP%] { + color: #e4e4e7; + border-bottom-color: var(--%NS%accent); + } + [role='tab'][_ngcontent-%COMP%]:focus-visible, + select[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .count[_ngcontent-%COMP%] { + margin-left: 4px; + padding: 0 5px; + border-radius: 8px; + background: #7f1d1d; + color: #fecaca; + font-size: 11px; + }`]})};function oD(e,t){e&1&&(G(0,`p`,5),Z(1,`Scanning routes…`),K())}function sD(e,t){e&1&&(G(0,`p`,5),Z(1,`No routes found.`),K())}function cD(e,t){if(e&1&&(G(0,`span`,9),Z(1),K()),e&2){let e=X().$implicit;z(),$(`➜ `,e.redirectTo)}}function lD(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` `,e.component??`—`,` `)}}function uD(e,t){if(e&1&&(G(0,`tr`)(1,`td`,8),Z(2),K(),G(3,`td`),V(4,cD,2,1,`span`,9)(5,lD,1,1),K(),G(6,`td`),Z(7),K(),G(8,`td`,10),Z(9),K(),G(10,`td`),Z(11),K()()),e&2){let e=t.$implicit;z(2),$(`/`,e.path),z(2),H(e.redirectTo===void 0?5:4),z(3),Q(e.title??`—`),z(2),Q(e.file),z(2),Q(e.hasChildren?`Yes`:`—`)}}function dD(e,t){if(e&1&&(G(0,`table`,6)(1,`thead`)(2,`tr`)(3,`th`,7),Z(4,`Path`),K(),G(5,`th`,7),Z(6,`Component / Target`),K(),G(7,`th`,7),Z(8,`Title`),K(),G(9,`th`,7),Z(10,`File`),K(),G(11,`th`,7),Z(12,`Children`),K()()(),G(13,`tbody`),U(14,uD,12,5,`tr`,null,Oh),K()()),e&2){let e=X();z(14),W(e.filtered())}}var fD=class e{rpc=k_(null);routes=L([]);filter=L(``);loading=L(!1);filtered=b_(()=>{let e=this.filter().toLowerCase().trim(),t=this.routes();return e?t.filter(t=>t.path.toLowerCase().includes(e)||t.component&&t.component.toLowerCase().includes(e)||t.redirectTo&&t.redirectTo.toLowerCase().includes(e)||t.title&&t.title.toLowerCase().includes(e)||t.file.toLowerCase().includes(e)):t});constructor(){Zs(()=>{this.rpc()&&this.refresh()})}onFilterInput(e){let t=e.target;this.filter.set(t?.value??``)}async refresh(){let e=this.rpc();if(e){this.loading.set(!0);try{let t=await e.scope(`ng-devtools`).rpc.call(`get-routes`);this.routes.set(t)}finally{this.loading.set(!1)}}}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-route-inspector`]],inputs:{rpc:[1,`rpc`]},decls:10,vars:3,consts:[[3,`rpc`],[1,`config-heading`],[1,`toolbar`],[`type`,`text`,`aria-label`,`Filter routes`,`placeholder`,`Filter routes…`,3,`input`,`value`],[`type`,`button`,3,`click`],[1,`muted`],[`role`,`table`],[`scope`,`col`],[1,`path`],[1,`redirect`],[1,`file`]],template:function(e,t){e&1&&(Vh(0,`app-live-route`,0),G(1,`h2`,1),Z(2,`Route config`),K(),G(3,`div`,2)(4,`input`,3),sg(`input`,function(e){return t.onFilterInput(e)}),K(),G(5,`button`,4),sg(`click`,function(){return t.refresh()}),Z(6,`Refresh`),K()(),V(7,oD,2,0,`p`,5)(8,sD,2,0,`p`,5)(9,dD,16,0,`table`,6)),e&2&&(Rh(`rpc`,t.rpc()),z(4),Rh(`value`,t.filter()),z(3),H(t.loading()?7:t.filtered().length===0?8:9))},dependencies:[aD],styles:[`.config-heading[_ngcontent-%COMP%] { + margin: 0 0 8px; + font-size: 15px; + color: #e4e4e7; + } + .toolbar[_ngcontent-%COMP%] { + display: flex; + gap: 8px; + margin-bottom: 16px; + } + input[_ngcontent-%COMP%] { + flex: 1; + padding: 8px 12px; + background: #18181b; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 14px; + outline: none; + } + input[_ngcontent-%COMP%]:focus { + border-color: var(--%NS%accent); + } + button[_ngcontent-%COMP%] { + padding: 8px 16px; + background: #3f3f46; + border: none; + border-radius: 6px; + color: #e4e4e7; + cursor: pointer; + font-size: 13px; + } + button[_ngcontent-%COMP%]:hover { + background: #52525b; + } + .muted[_ngcontent-%COMP%] { + color: #a1a1aa; + font-size: 14px; + } + table[_ngcontent-%COMP%] { + width: 100%; + border-collapse: collapse; + font-size: 14px; + } + thead[_ngcontent-%COMP%] { + position: sticky; + top: 0; + } + th[_ngcontent-%COMP%] { + text-align: left; + padding: 8px 12px; + background: #18181b; + color: #a1a1aa; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 1px solid #27272a; + } + td[_ngcontent-%COMP%] { + padding: 10px 12px; + border-bottom: 1px solid #1e1e22; + } + tr[_ngcontent-%COMP%]:hover td[_ngcontent-%COMP%] { + background: #18181b; + } + .path[_ngcontent-%COMP%] { + font-family: monospace; + color: var(--%NS%accent); + font-weight: 500; + } + .redirect[_ngcontent-%COMP%] { + font-family: monospace; + color: #38bdf8; + } + .file[_ngcontent-%COMP%] { + font-size: 12px; + color: #a1a1aa; + }`]})},pD=(e,t)=>t.name+t.file+t.line,mD=(e,t)=>t.kind,hD=(e,t)=>t.id,gD=(e,t)=>t.epoch;function _D(e,t){e&1&&(q(0,`div`,3)(1,`p`,4),Z(2,`No signals found.`),J(),q(3,`p`,5),Z(4,` No signal(), computed(), effect() calls found in source. Runtime graph requires Angular 19+ with the overlay connected. `),J()())}function vD(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · in <`,e.component,`> `)}}function yD(e,t){if(e&1&&(q(0,`div`,8)(1,`div`,9)(2,`span`,10),Z(3),J(),q(4,`span`,11),Z(5),J()(),q(6,`div`,12),Z(7),V(8,vD,1,1),J()()),e&2){let e=t.$implicit,n=X(2);z(2),kg(`background`,n.kindColor(e.kind)),z(),Q(e.kind),z(2),Q(e.name),z(2),t_(` `,e.file,`:`,e.line,` `),z(),H(e.component?8:-1)}}function bD(e,t){if(e&1&&(q(0,`p`,6),Z(1,`Signals from source scan (static analysis):`),J(),q(2,`div`,7),U(3,yD,9,7,`div`,8,pD),J()),e&2){let e=X();z(3),W(e.filteredSourceSignals())}}function xD(e,t){if(e&1&&(q(0,`span`,14),Hh(1,`span`,16),Z(2),J()),e&2){let e=t.$implicit;z(),kg(`background`,e.color),z(),$(` `,e.kind,` `)}}function SD(e,t){e&1&&(q(0,`span`,18),Z(1,`watching`),J())}function CD(e,t){if(e&1&&(q(0,`span`,19),Z(1),J()),e&2){let e=t;z(),t_(``,e,` `,e===1?`change`:`changes`)}}function wD(e,t){if(e&1&&(q(0,`span`,20),Z(1),l_(2,`json`),J()),e&2){let e=X().$implicit;z(),Q(d_(2,1,e.value))}}function TD(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · Deps: `,X(2).getDependencies(e).length,` `)}}function ED(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · Consumers: `,X(2).getConsumers(e).length,` `)}}function DD(e,t){if(e&1&&(q(0,`dt`),Z(1,`Value`),J(),q(2,`dd`)(3,`pre`),Z(4),l_(5,`json`),J()()),e&2){let e=X(4);z(4),Q(d_(5,1,e.selectedNode().value))}}function OD(e,t){if(e&1&&(q(0,`li`)(1,`span`,22),Z(2),J(),Z(3),J()),e&2){let e=t.$implicit,n=X(5);z(),kg(`background`,n.kindColor(e.kind)),z(),Q(e.kind),z(),$(` `,e.label??e.id,` `)}}function kD(e,t){if(e&1&&(q(0,`h4`),Z(1,`Dependencies (producers)`),J(),q(2,`ul`),U(3,OD,4,4,`li`,null,hD),J()),e&2){let e=X(4);z(3),W(e.getDependencies(e.selectedNode()))}}function AD(e,t){if(e&1&&(q(0,`li`)(1,`span`,22),Z(2),J(),Z(3),J()),e&2){let e=t.$implicit,n=X(5);z(),kg(`background`,n.kindColor(e.kind)),z(),Q(e.kind),z(),$(` `,e.label??e.id,` `)}}function jD(e,t){if(e&1&&(q(0,`h4`),Z(1,`Consumers`),J(),q(2,`ul`),U(3,AD,4,4,`li`,null,hD),J()),e&2){let e=X(4);z(3),W(e.getConsumers(e.selectedNode()))}}function MD(e,t){if(e&1&&(q(0,`span`,28),Z(1),J()),e&2){let e=X().$implicit;z(),$(``,e.missed,` earlier not captured`)}}function ND(e,t){if(e&1&&(q(0,`li`)(1,`span`,26)(2,`time`),Z(3),l_(4,`date`),J(),q(5,`span`,27),Z(6),J(),q(7,`span`),Z(8),J(),V(9,MD,2,1,`span`,28),J(),q(10,`pre`),Z(11),l_(12,`json`),J()()),e&2){let e=t.$implicit,n=X(5);z(3),Q(f_(4,7,e.at,`HH:mm:ss.SSS`)),z(2),jg(`source-`+e.source),z(),Q(n.sourceLabel(e.source)),z(2),$(`epoch `,e.epoch),z(),H(e.missed?9:-1),z(2),Q(d_(12,10,e.value))}}function PD(e,t){if(e&1&&(q(0,`h4`,23),Z(1,`Value history`),J(),q(2,`p`,24),Z(3),J(),q(4,`ol`,25),U(5,ND,13,12,`li`,null,gD),J()),e&2){let e=X(4);z(3),$(` `,e.changeCount(e.selectedNode().id),` changes recorded, newest first. `),z(2),W(e.selectedHistory())}}function FD(e,t){if(e&1&&(q(0,`div`,21)(1,`h3`),Z(2),J(),q(3,`dl`)(4,`dt`),Z(5,`Kind`),J(),q(6,`dd`),Z(7),J(),q(8,`dt`),Z(9,`Epoch`),J(),q(10,`dd`),Z(11),J(),V(12,DD,6,3),J(),V(13,kD,5,0),V(14,jD,5,0),V(15,PD,7,1),J()),e&2){let e=X().$implicit,t=X(2);Xh(`id`,`signal-detail-`+e.id),z(2),Q(t.selectedNode().label??t.selectedNode().id),z(5),Q(t.selectedNode().kind),z(4),Q(t.selectedNode().epoch),z(),H(t.selectedNode().value===void 0?-1:12),z(),H(t.getDependencies(t.selectedNode()).length?13:-1),z(),H(t.getConsumers(t.selectedNode()).length?14:-1),z(),H(t.selectedHistory().length?15:-1)}}function ID(e,t){if(e&1){let e=Yh();q(0,`li`)(1,`button`,17),Y(`click`,function(){let t=F(e).$implicit;return I(X(2).selectNode(t))}),q(2,`span`,9)(3,`span`,10),Z(4),J(),q(5,`span`,11),Z(6),J(),V(7,SD,2,0,`span`,18),V(8,CD,2,2,`span`,19),J(),V(9,wD,3,3,`span`,20),q(10,`span`,12),Z(11),V(12,TD,1,1),V(13,ED,1,1),J()(),V(14,FD,16,8,`div`,21),J()}if(e&2){let e,n=t.$implicit,r=X(2);z(),Ag(`selected`,r.selectedId()===n.id),B(`aria-expanded`,r.selectedId()===n.id)(`aria-controls`,`signal-detail-`+n.id),z(2),kg(`background`,r.kindColor(n.kind)),z(),Q(n.kind),z(2),Q(n.label??`(unnamed)`),z(),H(n.watched?7:-1),z(),H((e=r.changeCount(n.id))?8:-1,e),z(),H(n.value===void 0?-1:9),z(2),$(` Epoch: `,n.epoch,` `),z(),H(r.getDependencies(n).length?12:-1),z(),H(r.getConsumers(n).length?13:-1),z(),H(r.selectedId()===n.id&&r.selectedNode()?14:-1)}}function LD(e,t){if(e&1&&(q(0,`div`,13),U(1,xD,3,3,`span`,14,mD),J(),q(3,`ul`,15),U(4,ID,15,15,`li`,null,hD),J()),e&2){let e=X();z(),W(e.kindLegend),z(3),W(e.filteredNodes())}}var RD={write:`set`,sample:`sampled`,initial:`initial`},zD={signal:`#a78bfa`,computed:`#60a5fa`,linkedSignal:`#34d399`,effect:`#fb923c`,template:`#94a3b8`,afterRenderEffectPhase:`#f472b6`,childSignalProp:`#c084fc`,"input (signal)":`#f59e0b`,"input.required (signal)":`#f59e0b`,"output (signal)":`#ec4899`,"model (signal)":`#14b8a6`,"model.required (signal)":`#14b8a6`,"viewChild (signal)":`#8b5cf6`,"viewChild.required (signal)":`#8b5cf6`,"viewChildren (signal)":`#8b5cf6`,"contentChild (signal)":`#6366f1`,"contentChild.required (signal)":`#6366f1`,"contentChildren (signal)":`#6366f1`,resource:`#06b6d4`,unknown:`#71717a`},BD=class e{rpc=k_(null);graph=L(null);sourceSignals=L([]);filter=L(``);selectedId=L(null);selectedNode=b_(()=>this.graph()?.nodes.find(e=>e.id===this.selectedId())??null);selectedHistory=b_(()=>{let e=this.selectedId();return e?[...this.graph()?.history?.[e]??[]].reverse():[]});kindLegend=Object.entries(zD).map(([e,t])=>({kind:e,color:t}));filteredNodes=b_(()=>{let e=this.graph();if(!e)return[];let t=this.filter().toLowerCase();return(t?e.nodes.filter(e=>(e.label??``).toLowerCase().includes(t)||e.kind.includes(t)):[...e.nodes]).sort((e,t)=>e.id.localeCompare(t.id,void 0,{numeric:!0}))});filteredSourceSignals=b_(()=>{let e=this.filter().toLowerCase(),t=this.sourceSignals();return e?t.filter(t=>t.name.toLowerCase().includes(e)||t.kind.includes(e)||t.file.includes(e)):t});constructor(){Zs(()=>{let e=this.rpc();e&&(this.loadSignalGraph(e),this.loadSourceSignals(e))})}async loadSignalGraph(e){let t=await e.scope(`ng-devtools`).rpc.sharedState(`signal-graph`),n=new URLSearchParams(location.search).get(`pageId`),r=e=>n&&e?.pages?.[n]||e?.graph,i=r(t.value());i&&this.graph.set(i),t.on(`updated`,e=>{let t=r(e);t&&this.graph.set(t)})}async loadSourceSignals(e){let t=e.scope(`ng-devtools`);try{let e=await t.rpc.call(`get-signals`);this.sourceSignals.set(e)}catch{}}selectNode(e){this.selectedId.set(this.selectedId()===e.id?null:e.id)}changeCount(e){return(this.graph()?.history?.[e]??[]).reduce((e,t)=>e+(t.source===`initial`?0:1+(t.missed??0)),0)}sourceLabel(e){return RD[e]}kindColor(e){return zD[e]??zD.unknown}getDependencies(e){let t=this.graph();if(!t)return[];let n=t.nodes.findIndex(t=>t.id===e.id);return t.edges.filter(e=>e.consumer===n).map(e=>t.nodes[e.producer]).filter(Boolean)}getConsumers(e){let t=this.graph();if(!t)return[];let n=t.nodes.findIndex(t=>t.id===e.id);return t.edges.filter(e=>e.producer===n).map(e=>t.nodes[e.consumer]).filter(Boolean)}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-signal-inspector`]],inputs:{rpc:[1,`rpc`]},decls:7,vars:5,consts:[[1,`toolbar`],[`type`,`text`,`placeholder`,`Filter by name or kind…`,3,`input`,`value`],[1,`label`],[1,`empty`],[1,`muted`],[1,`hint`],[1,`source-label`],[1,`nodes`],[1,`node-card`],[1,`node-header`],[1,`kind-badge`],[1,`node-label`],[1,`node-meta`],[1,`legend`],[1,`legend-item`],[`role`,`list`,1,`nodes`],[1,`dot`],[`type`,`button`,1,`node-card`,3,`click`],[1,`watched-badge`],[1,`changed-badge`],[1,`node-value`],[1,`detail-panel`,3,`id`],[1,`kind-badge`,`sm`],[`id`,`value-history-heading`],[`aria-live`,`polite`,1,`history-summary`],[`aria-labelledby`,`value-history-heading`,1,`history`],[1,`history-meta`],[1,`source-tag`],[1,`missed`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`input`,1),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(2,`span`,2),Z(3),J()(),V(4,_D,5,0,`div`,3),V(5,bD,5,0),V(6,LD,6,0)),e&2&&(z(),Xh(`value`,t.filter()),z(2),$(`Component: `,t.graph()?.componentSelector??`—`),z(),H(!t.graph()&&t.sourceSignals().length===0?4:-1),z(),H(!t.graph()&&t.sourceSignals().length>0?5:-1),z(),H(t.graph()?6:-1))},dependencies:[Uv,Wv],styles:[`.toolbar[_ngcontent-%COMP%] { + display: flex; + gap: 12px; + align-items: center; + margin-bottom: 16px; + } + input[_ngcontent-%COMP%] { + flex: 1; + padding: 8px 12px; + background: #18181b; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 14px; + outline: none; + } + input[_ngcontent-%COMP%]:focus { + border-color: var(--%NS%accent); + } + .label[_ngcontent-%COMP%] { + font-size: 13px; + color: #71717a; + white-space: nowrap; + } + .empty[_ngcontent-%COMP%] { + text-align: center; + padding: 48px 16px; + } + .muted[_ngcontent-%COMP%] { + color: #71717a; + font-size: 14px; + } + .hint[_ngcontent-%COMP%] { + color: #52525b; + font-size: 12px; + margin-top: 8px; + } + .source-label[_ngcontent-%COMP%] { + font-size: 13px; + color: #71717a; + margin-bottom: 12px; + } + .legend[_ngcontent-%COMP%] { + display: flex; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 16px; + } + .legend-item[_ngcontent-%COMP%] { + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; + color: #a1a1aa; + } + .dot[_ngcontent-%COMP%] { + width: 8px; + height: 8px; + border-radius: 50%; + } + .nodes[_ngcontent-%COMP%] { + display: flex; + flex-direction: column; + gap: 8px; + list-style: none; + padding: 0; + margin: 0; + } + .node-card[_ngcontent-%COMP%] { + display: block; + width: 100%; + text-align: left; + font: inherit; + color: inherit; + background: #18181b; + border: 1px solid #27272a; + border-radius: 8px; + padding: 12px 16px; + cursor: pointer; + transition: border-color 0.15s; + } + .node-card[_ngcontent-%COMP%]:hover { + border-color: #3f3f46; + } + .node-card[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .node-value[_ngcontent-%COMP%], + .node-meta[_ngcontent-%COMP%] { + display: block; + } + .changed-badge[_ngcontent-%COMP%] { + font-size: 10px; + padding: 1px 6px; + border-radius: 4px; + background: #422006; + color: #fbbf24; + } + .history-summary[_ngcontent-%COMP%] { + font-size: 12px; + color: #a1a1aa; + margin: 0 0 6px; + } + .history[_ngcontent-%COMP%] { + list-style: none; + padding: 0; + margin: 0; + max-height: 320px; + overflow: auto; + } + .history[_ngcontent-%COMP%] li[_ngcontent-%COMP%] { + display: block; + padding: 6px 0; + border-top: 1px solid #27272a; + } + .history-meta[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; + font-size: 11px; + color: #a1a1aa; + margin-bottom: 2px; + } + .source-tag[_ngcontent-%COMP%] { + padding: 0 5px; + border-radius: 3px; + background: #27272a; + color: #e4e4e7; + } + .source-write[_ngcontent-%COMP%] { + background: #1e3a8a; + color: #dbeafe; + } + .missed[_ngcontent-%COMP%] { + color: #fbbf24; + } + .node-card.selected[_ngcontent-%COMP%] { + border-color: var(--%NS%accent); + } + .node-header[_ngcontent-%COMP%] { + display: flex; + align-items: center; + gap: 8px; + } + .kind-badge[_ngcontent-%COMP%] { + font-size: 11px; + padding: 2px 8px; + border-radius: 4px; + color: #fff; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + } + .kind-badge.sm[_ngcontent-%COMP%] { + font-size: 10px; + padding: 1px 5px; + } + .node-label[_ngcontent-%COMP%] { + font-family: monospace; + font-size: 14px; + color: #e4e4e7; + } + .watched-badge[_ngcontent-%COMP%] { + font-size: 10px; + padding: 1px 6px; + border-radius: 4px; + background: #14532d; + color: #4ade80; + } + .node-value[_ngcontent-%COMP%] { + font-family: monospace; + font-size: 12px; + color: #a1a1aa; + margin-top: 4px; + max-height: 40px; + overflow: hidden; + } + .node-meta[_ngcontent-%COMP%] { + font-size: 11px; + color: #52525b; + margin-top: 4px; + } + .detail-panel[_ngcontent-%COMP%] { + margin-top: 16px; + padding: 16px; + background: #18181b; + border: 1px solid #27272a; + border-radius: 8px; + } + .detail-panel[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { + font-family: monospace; + color: var(--%NS%accent); + margin-bottom: 12px; + } + .detail-panel[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] { + font-size: 12px; + color: #71717a; + margin: 12px 0 4px; + text-transform: uppercase; + letter-spacing: 0.05em; + } + dl[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: auto 1fr; + gap: 4px 12px; + font-size: 13px; + } + dt[_ngcontent-%COMP%] { + color: #71717a; + } + dd[_ngcontent-%COMP%] { + color: #e4e4e7; + } + pre[_ngcontent-%COMP%] { + font-size: 12px; + white-space: pre-wrap; + margin: 0; + } + ul[_ngcontent-%COMP%] { + list-style: none; + padding: 0; + font-size: 13px; + } + li[_ngcontent-%COMP%] { + padding: 2px 0; + color: #a1a1aa; + display: flex; + align-items: center; + gap: 6px; + }`]})},VD=(e,t)=>t.type,HD=(e,t)=>t.token+t.file+t.line,UD=(e,t)=>t.injector.id,WD=(e,t)=>t.node.injector.id,GD=(e,t)=>t.token;function KD(e,t){e&1&&(q(0,`div`,4)(1,`p`,5),Z(2,`No DI data found.`),J(),q(3,`p`,6),Z(4,` No providers, injectables, or inject() calls found. Runtime tree requires Angular 17+ with the overlay connected. `),J()())}function qD(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=X().$implicit;z(),$(`providedIn: `,e.providedIn)}}function JD(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · as `,e.source,` `)}}function YD(e,t){if(e&1&&(q(0,`div`,11)(1,`div`,12)(2,`span`,13),Z(3),J(),V(4,qD,2,1,`span`,14),J(),q(5,`div`,15),Z(6),V(7,JD,1,1),J()()),e&2){let e=t.$implicit;z(3),Q(e.token),z(),H(e.providedIn?4:-1),z(2),t_(` `,e.file,`:`,e.line,` `),z(),H(e.source!==`class`&&e.source!==`providers array`?7:-1)}}function XD(e,t){if(e&1&&(q(0,`div`,9)(1,`h3`),Z(2),J(),q(3,`div`,10),U(4,YD,8,5,`div`,11,HD),J()()),e&2){let e=t.$implicit;z(2),t_(``,e.label,` (`,e.items.length,`)`),z(2),W(e.items)}}function ZD(e,t){if(e&1&&(q(0,`p`,7),Z(1,`DI from source scan (static analysis):`),J(),q(2,`div`,8),U(3,XD,6,2,`div`,9,VD),J()),e&2){let e=X();z(3),W(e.groupedProviders())}}function QD(e,t){e&1&&qh(0)}function $D(e,t){if(e&1&&(q(0,`span`,24),Z(1),J()),e&2){let e=X().$implicit;z(),$(``,e.node.injector.providerCount,` providers`)}}function eO(e,t){if(e&1){let e=Yh();q(0,`div`,21),Y(`click`,function(){let t=F(e).$implicit;return I(X(4).select(t.node))}),q(1,`span`,22),Z(2),J(),q(3,`span`,23),Z(4),J(),V(5,$D,2,1,`span`,24),J()}if(e&2){let e=t.$implicit,n=X(4);kg(`padding-left`,e.depth*24+12,`px`),Ag(`selected`,n.selectedId()===e.node.injector.id),z(),kg(`background`,n.typeColor(e.node.injector.type)),z(),$(` `,e.node.injector.type,` `),z(2),Q(e.node.injector.name),z(),H(e.node.injector.providerCount>0?5:-1)}}function tO(e,t){if(e&1&&(q(0,`div`,19),U(1,eO,6,9,`div`,20,WD),J()),e&2){let e=X().$implicit,t=X(2);z(),W(t.flattenTree(e))}}function nO(e,t){e&1&&(fm(0,QD,1,0,`ng-container`,18)(1,tO,3,0),_h(2,1),vh()),e&2&&Xh(`ngTemplateOutlet`,void 0)}function rO(e,t){e&1&&(q(0,`p`,5),Z(1,`No providers configured on this injector.`),J())}function iO(e,t){if(e&1&&(q(0,`tr`)(1,`td`,13),Z(2),J(),q(3,`td`),Z(4),J(),q(5,`td`),Z(6),J()()),e&2){let e=t.$implicit;z(2),Q(e.token),z(2),Q(e.type),z(2),Q(e.isViewProvider?`Yes`:`—`)}}function aO(e,t){if(e&1&&(q(0,`table`,26)(1,`thead`)(2,`tr`)(3,`th`),Z(4,`Token`),J(),q(5,`th`),Z(6,`Type`),J(),q(7,`th`),Z(8,`View`),J()()(),q(9,`tbody`),U(10,iO,7,3,`tr`,null,GD),J()()),e&2){let e=X(3);z(10),W(e.selectedInjector().providers)}}function oO(e,t){if(e&1&&(q(0,`aside`,17)(1,`div`,25)(2,`span`,22),Z(3),J(),q(4,`h3`),Z(5),J()(),V(6,rO,2,0,`p`,5)(7,aO,12,0,`table`,26),J()),e&2){let e=X(2);z(2),kg(`background`,e.typeColor(e.selectedInjector().injector.type)),z(),$(` `,e.selectedInjector().injector.type,` `),z(2),Q(e.selectedInjector().injector.name),z(),H(e.selectedInjector().providers.length===0?6:7)}}function sO(e,t){if(e&1&&(q(0,`div`,16),U(1,nO,4,1,null,null,UD),J(),V(3,oO,8,5,`aside`,17)),e&2){let e=X();z(),W(e.filteredRoots()),z(2),H(e.selectedInjector()?3:-1)}}var cO={element:`#60a5fa`,environment:`#34d399`,null:`#71717a`},lO=class e{rpc=k_(null);roots=L([]);sourceProviders=L([]);filter=L(``);hideEmpty=L(!1);selectedId=L(null);selectedInjector=b_(()=>{let e=this.selectedId();return e?this.findNode(this.roots(),e):null});filteredRoots=b_(()=>{let e=this.roots();this.hideEmpty()&&(e=this.filterEmpty(e));let t=this.filter().toLowerCase();return t&&(e=this.filterByQuery(e,t)),e});groupedProviders=b_(()=>{let e=this.sourceProviders(),t=this.filter().toLowerCase(),n=t?e.filter(e=>e.token.toLowerCase().includes(t)||e.file.includes(t)):e,r=[{type:`root-provider`,label:`Root Providers (provide*)`,items:[]},{type:`injectable`,label:`Injectable Services`,items:[]},{type:`injection`,label:`inject() Calls`,items:[]},{type:`provider`,label:`Component Providers`,items:[]}];for(let e of n){let t=r.find(t=>t.type===e.type);t&&t.items.push(e)}return r.filter(e=>e.items.length>0)});constructor(){Zs(()=>{let e=this.rpc();e&&(this.loadInjectorTree(e),this.loadSourceProviders(e))})}async loadInjectorTree(e){let t=await e.scope(`ng-devtools`).rpc.sharedState(`injector-tree`),n=t.value();n?.roots?.length&&this.roots.set(n.roots),t.on(`updated`,e=>{e?.roots&&this.roots.set(e.roots)})}async loadSourceProviders(e){let t=e.scope(`ng-devtools`);try{let e=await t.rpc.call(`get-providers`);this.sourceProviders.set(e)}catch{}}select(e){this.selectedId.set(this.selectedId()===e.injector.id?null:e.injector.id)}typeColor(e){return cO[e]??cO.null}flattenTree(e){let t=[],n=(e,r)=>{t.push({node:e,depth:r});for(let t of e.children)n(t,r+1)};return n(e,0),t}findNode(e,t){for(let n of e){if(n.injector.id===t)return n;let e=this.findNode(n.children,t);if(e)return e}return null}filterEmpty(e){return e.map(e=>({...e,children:this.filterEmpty(e.children)})).filter(e=>e.injector.providerCount>0||e.children.length>0)}filterByQuery(e,t){return e.map(e=>({...e,children:this.filterByQuery(e.children,t)})).filter(e=>e.injector.name.toLowerCase().includes(t)||e.providers.some(e=>e.token.toLowerCase().includes(t))||e.children.length>0)}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-di-inspector`]],inputs:{rpc:[1,`rpc`]},decls:8,vars:5,consts:[[1,`toolbar`],[`type`,`text`,`placeholder`,`Filter by injector name or token…`,3,`input`,`value`],[1,`checkbox`],[`type`,`checkbox`,3,`change`,`checked`],[1,`empty`],[1,`muted`],[1,`hint`],[1,`source-label`],[1,`source-providers`],[1,`provider-group`],[1,`provider-list`],[1,`provider-card`],[1,`provider-header`],[1,`token`],[1,`provided-in`],[1,`provider-meta`],[1,`tree-container`],[1,`detail-panel`],[4,`ngTemplateOutlet`],[1,`injector-tree`],[1,`injector-row`,3,`selected`,`paddingLeft`],[1,`injector-row`,3,`click`],[1,`type-badge`],[1,`name`],[1,`provider-count`],[1,`detail-header`],[`role`,`table`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`input`,1),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(2,`label`,2)(3,`input`,3),Y(`change`,function(){return t.hideEmpty.set(!t.hideEmpty())}),J(),Z(4,` Hide empty injectors `),J()(),V(5,KD,5,0,`div`,4),V(6,ZD,5,0),V(7,sO,4,1)),e&2&&(z(),Xh(`value`,t.filter()),z(2),Xh(`checked`,t.hideEmpty()),z(2),H(t.roots().length===0&&t.sourceProviders().length===0?5:-1),z(),H(t.roots().length===0&&t.sourceProviders().length>0?6:-1),z(),H(t.roots().length>0?7:-1))},styles:[`.toolbar[_ngcontent-%COMP%] { + display: flex; + gap: 12px; + align-items: center; + margin-bottom: 16px; + } + input[type='text'][_ngcontent-%COMP%] { + flex: 1; + padding: 8px 12px; + background: #18181b; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 14px; + outline: none; + } + input[type='text'][_ngcontent-%COMP%]:focus { + border-color: var(--%NS%accent); + } + .checkbox[_ngcontent-%COMP%] { + display: flex; + align-items: center; + gap: 6px; + font-size: 13px; + color: #a1a1aa; + white-space: nowrap; + cursor: pointer; + } + .empty[_ngcontent-%COMP%] { + text-align: center; + padding: 48px 16px; + } + .muted[_ngcontent-%COMP%] { + color: #71717a; + font-size: 14px; + } + .hint[_ngcontent-%COMP%] { + color: #52525b; + font-size: 12px; + margin-top: 8px; + } + .tree-container[_ngcontent-%COMP%] { + display: flex; + flex-direction: column; + } + .injector-row[_ngcontent-%COMP%] { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + cursor: pointer; + border-bottom: 1px solid #1e1e22; + transition: background 0.1s; + } + .injector-row[_ngcontent-%COMP%]:hover { + background: #18181b; + } + .injector-row.selected[_ngcontent-%COMP%] { + background: color-mix(in srgb, var(--%NS%accent) 22%, transparent); + border-color: var(--%NS%accent); + } + .type-badge[_ngcontent-%COMP%] { + font-size: 10px; + padding: 2px 6px; + border-radius: 4px; + color: #fff; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + } + .name[_ngcontent-%COMP%] { + font-family: monospace; + font-size: 13px; + color: #e4e4e7; + } + .provider-count[_ngcontent-%COMP%] { + font-size: 11px; + color: #71717a; + margin-left: auto; + } + .detail-panel[_ngcontent-%COMP%] { + margin-top: 16px; + padding: 16px; + background: #18181b; + border: 1px solid #27272a; + border-radius: 8px; + } + .detail-header[_ngcontent-%COMP%] { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 12px; + } + .detail-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { + font-family: monospace; + color: #e4e4e7; + margin: 0; + } + table[_ngcontent-%COMP%] { + width: 100%; + border-collapse: collapse; + font-size: 13px; + } + th[_ngcontent-%COMP%] { + text-align: left; + padding: 6px 10px; + background: #0f0f11; + color: #71717a; + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 1px solid #27272a; + } + td[_ngcontent-%COMP%] { + padding: 8px 10px; + border-bottom: 1px solid #1e1e22; + } + .token[_ngcontent-%COMP%] { + font-family: monospace; + color: var(--%NS%accent); + } + .source-label[_ngcontent-%COMP%] { + font-size: 13px; + color: #71717a; + margin-bottom: 12px; + } + .source-providers[_ngcontent-%COMP%] { + display: flex; + flex-direction: column; + gap: 20px; + } + .provider-group[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { + font-size: 13px; + color: #71717a; + text-transform: uppercase; + letter-spacing: 0.05em; + margin-bottom: 8px; + } + .provider-list[_ngcontent-%COMP%] { + display: flex; + flex-direction: column; + gap: 6px; + } + .provider-card[_ngcontent-%COMP%] { + background: #18181b; + border: 1px solid #27272a; + border-radius: 8px; + padding: 10px 14px; + } + .provider-header[_ngcontent-%COMP%] { + display: flex; + align-items: center; + gap: 8px; + } + .provider-header[_ngcontent-%COMP%] .token[_ngcontent-%COMP%] { + font-size: 14px; + font-weight: 500; + } + .provided-in[_ngcontent-%COMP%] { + font-size: 11px; + padding: 1px 6px; + border-radius: 4px; + background: #14532d; + color: #4ade80; + } + .provider-meta[_ngcontent-%COMP%] { + font-size: 11px; + color: #52525b; + margin-top: 4px; + }`]})},uO=(e,t)=>t.kind,dO=(e,t)=>t.name+t.file+t.line;function fO(e,t){e&1&&Hh(0,`span`,4)}function pO(e,t){e&1&&(q(0,`div`,5)(1,`p`,6),Z(2,`No NgRx store patterns found.`),J(),q(3,`p`,7),Z(4,` No createAction, createReducer, createEffect, createSelector, or createFeature calls found in source. Make sure your app uses @ngrx/store. `),J()())}function mO(e,t){if(e&1&&(q(0,`span`,9),Hh(1,`span`,14),Z(2),J()),e&2){let e=t.$implicit;z(),kg(`background`,e.color),z(),$(` `,e.kind,` `)}}function hO(e,t){if(e&1&&(q(0,`span`,15),Z(1),J()),e&2){let e=t.$implicit;kg(`border-color`,X(3).kindColor(e.kind)),z(),n_(` `,e.count,` `,e.kind,``,e.count===1?``:`s`,` `)}}function gO(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · `,e.detail,` `)}}function _O(e,t){if(e&1&&(q(0,`div`,13)(1,`div`,16)(2,`span`,17),Z(3),J(),q(4,`span`,18),Z(5),J()(),q(6,`div`,19),Z(7),V(8,gO,1,1),J()()),e&2){let e=t.$implicit,n=X(3);z(2),kg(`background`,n.kindColor(e.kind)),z(),$(` `,e.kind,` `),z(2),Q(e.name),z(2),t_(` `,e.file,`:`,e.line,` `),z(),H(e.detail?8:-1)}}function vO(e,t){if(e&1&&(q(0,`div`,8),U(1,mO,3,3,`span`,9,uO),J(),q(3,`div`,10),U(4,hO,2,5,`span`,11,uO),J(),q(6,`div`,12),U(7,_O,9,7,`div`,13,dO),J()),e&2){let e=X(2);z(),W(e.kindLegend),z(3),W(e.groupedEntries()),z(3),W(e.filteredEntries())}}function yO(e,t){e&1&&V(0,pO,5,0,`div`,5)(1,vO,9,0),e&2&&H(X().sourceEntries().length===0?0:1)}function bO(e,t){e&1&&(q(0,`div`,5)(1,`p`,6),Z(2,`No NgRx store connection detected.`),J(),q(3,`p`,7),Z(4,` Runtime inspection requires @ngrx/store-devtools to be configured in your app. The store devtools use the Redux DevTools protocol to expose state. `),J()())}function xO(e,t){if(e&1){let e=Yh();q(0,`div`,28),Y(`click`,function(){let t=F(e).$implicit;return I(X(3).selectedAction.set(t))}),q(1,`div`,29),Z(2),J(),q(3,`div`,30),Z(4),J()()}if(e&2){let e=t.$implicit,n=X(3);Ag(`selected`,n.selectedAction()===e),z(2),Q(e.type),z(2),Q(n.formatTime(e.timestamp))}}function SO(e,t){e&1&&(q(0,`p`,6),Z(1,`No actions dispatched yet.`),J())}function CO(e,t){if(e&1&&(q(0,`dt`),Z(1,`Payload`),J(),q(2,`dd`)(3,`pre`),Z(4),l_(5,`json`),J()()),e&2){let e=X(4);z(4),Q(d_(5,1,e.selectedAction().payload))}}function wO(e,t){if(e&1&&(q(0,`aside`,27)(1,`h3`),Z(2),J(),q(3,`dl`)(4,`dt`),Z(5,`Type`),J(),q(6,`dd`),Z(7),J(),q(8,`dt`),Z(9,`Time`),J(),q(10,`dd`),Z(11),J(),V(12,CO,6,3),J()()),e&2){let e=X(3);z(2),Q(e.selectedAction().type),z(5),Q(e.selectedAction().type),z(4),Q(e.formatTime(e.selectedAction().timestamp)),z(),H(e.selectedAction().payload===void 0?-1:12)}}function TO(e,t){if(e&1&&(q(0,`div`,20)(1,`section`,21)(2,`h3`),Z(3,`Current State`),J(),q(4,`pre`,22),Z(5),l_(6,`json`),J()(),q(7,`section`,23)(8,`h3`),Z(9,` Recent Actions `),q(10,`span`,24),Z(11),J()(),q(12,`div`,25),U(13,xO,5,4,`div`,26,Oh,!1,SO,2,0,`p`,6),J()()(),V(16,wO,13,4,`aside`,27)),e&2){let e=X(2);z(5),Q(d_(6,4,e.runtimeState()?.state)),z(6),Q(e.filteredActions().length),z(2),W(e.filteredActions()),z(3),H(e.selectedAction()?16:-1)}}function EO(e,t){e&1&&V(0,bO,5,0,`div`,5)(1,TO,17,6),e&2&&H(+!!X().runtimeState()?.connected)}var DO={action:`#f59e0b`,reducer:`#a78bfa`,effect:`#fb923c`,selector:`#60a5fa`,feature:`#34d399`,"store-setup":`#94a3b8`,"signal-store":`#e879f9`,"signal-state":`#22d3ee`,"signal-method":`#fb7185`},OO=class e{rpc=k_(null);filter=L(``);mode=L(`source`);sourceEntries=L([]);runtimeState=L(null);selectedAction=L(null);kindLegend=Object.entries(DO).map(([e,t])=>({kind:e,color:t}));filteredEntries=b_(()=>{let e=this.filter().toLowerCase();return this.sourceEntries().filter(t=>t.name.toLowerCase().includes(e)||t.kind.toLowerCase().includes(e))});groupedEntries=b_(()=>{let e=this.sourceEntries(),t=new Map;for(let n of e)t.set(n.kind,(t.get(n.kind)??0)+1);return[...t.entries()].map(([e,t])=>({kind:e,count:t}))});filteredActions=b_(()=>{let e=this.filter().toLowerCase(),t=[...this.runtimeState()?.actions??[]].reverse();return e?t.filter(t=>t.type.toLowerCase().includes(e)):t});constructor(){Zs(()=>{let e=this.rpc();if(!e)return;let t=e.scope(`ng-devtools`);t.rpc.call(`get-ngrx-store`).then(e=>{this.sourceEntries.set(e),e.length===0&&this.mode.set(`runtime`)}).catch(()=>this.sourceEntries.set([])),t.rpc.sharedState(`ngrx-store`).then(e=>{e?.subscribe&&e.subscribe(e=>this.runtimeState.set(e))})})}kindColor(e){return DO[e]??`#71717a`}formatTime(e){return new Date(e).toLocaleTimeString()}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-store-inspector`]],inputs:{rpc:[1,`rpc`]},decls:10,vars:8,consts:[[1,`toolbar`],[`type`,`text`,`placeholder`,`Filter by name or kind…`,3,`input`,`value`],[1,`toggle-group`],[3,`click`],[1,`live-dot`],[1,`empty`],[1,`muted`],[1,`hint`],[1,`legend`],[1,`legend-item`],[1,`summary`],[1,`summary-badge`,3,`border-color`],[1,`nodes`],[1,`node-card`],[1,`dot`],[1,`summary-badge`],[1,`node-header`],[1,`kind-badge`],[1,`node-label`],[1,`node-meta`],[1,`runtime-layout`],[1,`state-panel`],[1,`state-tree`],[1,`actions-panel`],[1,`action-count`],[1,`action-list`],[1,`action-card`,3,`selected`],[1,`detail-panel`],[1,`action-card`,3,`click`],[1,`action-type`],[1,`action-time`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`input`,1),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(2,`div`,2)(3,`button`,3),Y(`click`,function(){return t.mode.set(`source`)}),Z(4,`Source`),J(),q(5,`button`,3),Y(`click`,function(){return t.mode.set(`runtime`)}),Z(6,` Runtime `),V(7,fO,1,0,`span`,4),J()()(),V(8,yO,2,1),V(9,EO,2,1)),e&2&&(z(),Xh(`value`,t.filter()),z(2),Ag(`active`,t.mode()===`source`),z(2),Ag(`active`,t.mode()===`runtime`),z(2),H(t.runtimeState()?.connected?7:-1),z(),H(t.mode()===`source`?8:-1),z(),H(t.mode()===`runtime`?9:-1))},dependencies:[Wv],styles:[`.toolbar[_ngcontent-%COMP%] { + display: flex; + gap: 12px; + align-items: center; + margin-bottom: 16px; + } + input[_ngcontent-%COMP%] { + flex: 1; + padding: 8px 12px; + background: #18181b; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 14px; + outline: none; + } + input[_ngcontent-%COMP%]:focus { + border-color: var(--%NS%accent); + } + .toggle-group[_ngcontent-%COMP%] { + display: flex; + border: 1px solid #27272a; + border-radius: 6px; + overflow: hidden; + } + .toggle-group[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { + padding: 6px 14px; + border: none; + background: transparent; + color: #a1a1aa; + cursor: pointer; + font-size: 13px; + display: flex; + align-items: center; + gap: 6px; + } + .toggle-group[_ngcontent-%COMP%] button.active[_ngcontent-%COMP%] { + background: #3f3f46; + color: #fff; + } + .live-dot[_ngcontent-%COMP%] { + width: 6px; + height: 6px; + border-radius: 50%; + background: #4ade80; + animation: _ngcontent-%COMP%_pulse 2s infinite; + } + @keyframes _ngcontent-%COMP%_pulse { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.4; + } + } + .empty[_ngcontent-%COMP%] { + text-align: center; + padding: 48px 16px; + } + .muted[_ngcontent-%COMP%] { + color: #71717a; + font-size: 14px; + } + .hint[_ngcontent-%COMP%] { + color: #52525b; + font-size: 12px; + margin-top: 8px; + } + .legend[_ngcontent-%COMP%] { + display: flex; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 12px; + } + .legend-item[_ngcontent-%COMP%] { + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; + color: #a1a1aa; + } + .dot[_ngcontent-%COMP%] { + width: 8px; + height: 8px; + border-radius: 50%; + } + .summary[_ngcontent-%COMP%] { + display: flex; + gap: 8px; + flex-wrap: wrap; + margin-bottom: 16px; + } + .summary-badge[_ngcontent-%COMP%] { + font-size: 12px; + padding: 3px 10px; + border-radius: 99px; + border: 1px solid; + color: #e4e4e7; + } + .nodes[_ngcontent-%COMP%] { + display: flex; + flex-direction: column; + gap: 8px; + } + .node-card[_ngcontent-%COMP%] { + background: #18181b; + border: 1px solid #27272a; + border-radius: 8px; + padding: 12px 16px; + transition: border-color 0.15s; + } + .node-card[_ngcontent-%COMP%]:hover { + border-color: #3f3f46; + } + .node-header[_ngcontent-%COMP%] { + display: flex; + align-items: center; + gap: 8px; + } + .kind-badge[_ngcontent-%COMP%] { + font-size: 11px; + padding: 2px 8px; + border-radius: 4px; + color: #fff; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + } + .node-label[_ngcontent-%COMP%] { + font-family: monospace; + font-size: 14px; + color: #e4e4e7; + } + .node-meta[_ngcontent-%COMP%] { + font-size: 12px; + color: #71717a; + margin-top: 4px; + } + .runtime-layout[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + } + .state-panel[_ngcontent-%COMP%], + .actions-panel[_ngcontent-%COMP%] { + background: #18181b; + border: 1px solid #27272a; + border-radius: 10px; + padding: 16px; + } + h3[_ngcontent-%COMP%] { + font-size: 13px; + text-transform: uppercase; + color: #71717a; + margin-bottom: 12px; + letter-spacing: 0.05em; + display: flex; + align-items: center; + gap: 8px; + } + .action-count[_ngcontent-%COMP%] { + font-size: 11px; + padding: 1px 6px; + border-radius: 99px; + background: #3f3f46; + color: #a1a1aa; + } + .state-tree[_ngcontent-%COMP%] { + font-family: monospace; + font-size: 12px; + color: #a1a1aa; + white-space: pre-wrap; + word-break: break-all; + max-height: 500px; + overflow: auto; + } + .action-list[_ngcontent-%COMP%] { + display: flex; + flex-direction: column; + gap: 6px; + max-height: 500px; + overflow: auto; + } + .action-card[_ngcontent-%COMP%] { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 12px; + background: #09090b; + border: 1px solid #27272a; + border-radius: 6px; + cursor: pointer; + transition: border-color 0.15s; + } + .action-card[_ngcontent-%COMP%]:hover { + border-color: #3f3f46; + } + .action-card.selected[_ngcontent-%COMP%] { + border-color: var(--%NS%accent); + } + .action-type[_ngcontent-%COMP%] { + font-family: monospace; + font-size: 13px; + color: #e4e4e7; + } + .action-time[_ngcontent-%COMP%] { + font-size: 11px; + color: #71717a; + } + .detail-panel[_ngcontent-%COMP%] { + margin-top: 16px; + background: #18181b; + border: 1px solid var(--%NS%accent); + border-radius: 10px; + padding: 16px; + } + dl[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: auto 1fr; + gap: 6px 12px; + font-size: 14px; + } + dt[_ngcontent-%COMP%] { + color: #a1a1aa; + } + dd[_ngcontent-%COMP%] { + color: #e4e4e7; + } + pre[_ngcontent-%COMP%] { + font-family: monospace; + font-size: 12px; + white-space: pre-wrap; + word-break: break-all; + }`]})},kO={signal:`Signal Forms`,reactive:`Reactive`,template:`Template-driven`},AO={own:`validator`,directive:`template attribute`,tree:`cross-field rule`,async:`async`,parse:`parse`,submission:`server`,schema:`schema`,manual:`setErrors`};function jO(e,t,n){return e?e.scope(`ng-devtools`).rpc.call(t,...n===void 0?[]:[n]).then(e=>e,()=>null):Promise.resolve(null)}async function MO(e,t){return await jO(e,`request-form-action`,t)??{ok:!1,error:`The devtools server did not answer.`}}function NO(e){return`${e.ok?e.message??`Done.`:e.error??`Failed.`}${e.skipped?.length?` Skipped: ${e.skipped.map(e=>`${e.path} (${e.reason})`).join(`, `)}.`:``}${e.status?` Status: ${e.status}.`:``}`}function PO(e){return(e??``).replace(/^_Labels, paths.*_\n\n/,``).replace(/`/g,``).replace(/\*\*/g,``)}function FO(e,t){if(e&1){let e=Yh();q(0,`label`,4),Z(1),J(),q(2,`input`,5),Y(`input`,function(t){return F(e),I(X().draft.set(t.target.value))})(`keydown.enter`,function(){return F(e),I(X().setValue())}),J(),q(3,`button`,2),Y(`click`,function(){return F(e),I(X().setValue())}),Z(4,`Set`),J()}if(e&2){let e=X();z(),$(`New value for `,e.node().path),z(),Xh(`value`,e.draft())}}var IO=class e{form=k_.required();node=k_.required();version=k_(0);rpc=k_(null);text=L(``);target=b_(()=>`${this.form().id}|${this.node().path}`);draft=C_({source:this.target,computation:()=>``});message=C_({source:this.target,computation:()=>``});constructor(){Zs(()=>{let e=this.form().id,t=this.node().path;this.version();let n=this.rpc();x_(()=>this.load(n,e,t))})}async load(e,t,n){let r=await jO(e,`forms-explain`,{kind:`field`,form:t,path:n});this.form().id===t&&this.node().path===n&&this.text.set(PO(r))}async act(e){let t=await MO(this.rpc(),{action:e,formId:this.form().id,path:this.node().path});this.message.set(t.expression?`${NO(t)} ${t.expression}`:NO(t))}async setValue(){let e=this.draft(),t=e;try{t=JSON.parse(e)}catch{t=e}let n=await MO(this.rpc(),{action:`set-value`,formId:this.form().id,path:this.node().path,value:t,mode:`user`});this.message.set(NO(n))}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-forms-field-detail`]],inputs:{form:[1,`form`],node:[1,`node`],version:[1,`version`],rpc:[1,`rpc`]},decls:16,vars:4,consts:[[1,`explain`],[1,`row`],[`type`,`button`,1,`small`,3,`click`],[`role`,`status`,1,`status`],[`for`,`field-value`,1,`sr-only`],[`id`,`field-value`,`type`,`text`,`placeholder`,`New value (JSON or text)`,1,`field-input`,3,`input`,`keydown.enter`,`value`]],template:function(e,t){e&1&&(q(0,`h3`),Z(1),J(),q(2,`pre`,0),Z(3),J(),q(4,`div`,1),V(5,FO,5,2),q(6,`button`,2),Y(`click`,function(){return t.act(`focus`)}),Z(7,`Focus`),J(),q(8,`button`,2),Y(`click`,function(){return t.act(`mark-touched`)}),Z(9,`Touch`),J(),q(10,`button`,2),Y(`click`,function(){return t.act(`revalidate`)}),Z(11,`Revalidate`),J(),q(12,`button`,2),Y(`click`,function(){return t.act(`store-as-global`)}),Z(13,`Store as global`),J()(),q(14,`p`,3),Z(15),J()),e&2&&(z(),Q(t.node().path||`(form)`),z(2),Q(t.text()||`Loading…`),z(2),H(t.node().type===`control`&&!t.node().redacted?5:-1),z(10),Q(t.message()))},styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + } + .small[_ngcontent-%COMP%] { + padding: 4px 10px; + border: 1px solid #52525b; + border-radius: 6px; + background: #18181b; + color: #e4e4e7; + font-size: 12px; + cursor: pointer; + } + .small[_ngcontent-%COMP%]:hover { + border-color: var(--%NS%accent); + } + .small[_ngcontent-%COMP%]:focus-visible, + .field-input[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .field-input[_ngcontent-%COMP%] { + padding: 4px 8px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .explain[_ngcontent-%COMP%] { + margin: 0; + padding: 10px; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 12px; + white-space: pre-wrap; + overflow-wrap: anywhere; + font-family: ui-monospace, monospace; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 2px 0; + padding: 0 5px; + border: 1px solid #3f3f46; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + } + .tag[data-tone='warn'][_ngcontent-%COMP%] { + border-color: #a16207; + color: #fef08a; + } + .tag[data-tone='bad'][_ngcontent-%COMP%] { + border-color: #b91c1c; + color: #fecaca; + } + .status[_ngcontent-%COMP%] { + min-height: 1.2em; + margin: 0; + color: #d4d4d8; + font-size: 13px; + } + + [_nghost-%COMP%] { + display: grid; + gap: 8px; + padding: 10px; + border: 1px solid #3f3f46; + border-radius: 8px; + } + h3[_ngcontent-%COMP%] { + margin: 0; + color: #e4e4e7; + font-size: 14px; + font-family: ui-monospace, monospace; + } + .row[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 6px; + align-items: center; + } + .sr-only[_ngcontent-%COMP%] { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + }`]})};function LO(e,t){e&1&&(q(0,`p`,0),Z(1,`Checking…`),J())}function RO(e,t){e&1&&(q(0,`p`,0),Z(1,`No problems found. For generic accessibility, run axe on the page.`),J())}function zO(e,t){if(e&1&&(q(0,`span`,0),Z(1),J()),e&2){let e=X().$implicit;z(),$(`at `,e.path)}}function BO(e,t){if(e&1&&(q(0,`li`)(1,`span`,2),Z(2),J(),q(3,`code`),Z(4),J(),V(5,zO,2,1,`span`,0),q(6,`div`),Z(7),J(),q(8,`div`,0),Z(9),J()()),e&2){let e=t.$implicit;z(),B(`data-tone`,e.severity===`info`?``:e.severity===`error`?`bad`:`warn`),z(),Q(e.severity),z(2),Q(e.rule),z(),H(e.path?5:-1),z(2),Q(e.message),z(2),$(`Fix: `,e.fix)}}function VO(e,t){if(e&1&&(q(0,`ul`,1),U(1,BO,10,6,`li`,null,Oh),J()),e&2){let e=X();z(),W(e.findings())}}var HO=class e{formId=k_.required();version=k_(0);rpc=k_(null);submit=L(``);payload=L(``);message=L(``);constructor(){Zs(()=>{let e=this.formId();this.version();let t=this.rpc();x_(async()=>{let[n,r]=await Promise.all([jO(t,`forms-explain`,{kind:`submit`,form:e}),jO(t,`forms-explain`,{kind:`payload`,form:e})]);this.formId()===e&&(this.submit.set(PO(n)),this.payload.set(PO(r)))})})}async copyFixture(){let e=(await jO(this.rpc(),`forms-explain`,{kind:`fixture`,form:this.formId()})??``).match(/```ts\n([\s\S]*?)```/)?.[1];if(!e){this.message.set(`No test fixture is available for this form.`);return}try{await navigator.clipboard.writeText(e),this.message.set(`Copied.`)}catch{this.message.set(`Clipboard is not available here.`)}}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-forms-submit`]],inputs:{formId:[1,`formId`],version:[1,`version`],rpc:[1,`rpc`]},decls:13,vars:3,consts:[[1,`explain`],[`type`,`button`,1,`small`,3,`click`],[`role`,`status`,1,`status`]],template:function(e,t){e&1&&(q(0,`h3`),Z(1,`Submit`),J(),q(2,`pre`,0),Z(3),J(),q(4,`h3`),Z(5,`Payload`),J(),q(6,`pre`,0),Z(7),J(),q(8,`div`)(9,`button`,1),Y(`click`,function(){return t.copyFixture()}),Z(10,`Copy test fixture`),J(),q(11,`span`,2),Z(12),J()()),e&2&&(z(3),Q(t.submit()||`Loading…`),z(4),Q(t.payload()||`Loading…`),z(5),Q(t.message()))},styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + } + .small[_ngcontent-%COMP%] { + padding: 4px 10px; + border: 1px solid #52525b; + border-radius: 6px; + background: #18181b; + color: #e4e4e7; + font-size: 12px; + cursor: pointer; + } + .small[_ngcontent-%COMP%]:hover { + border-color: var(--%NS%accent); + } + .small[_ngcontent-%COMP%]:focus-visible, + .field-input[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .field-input[_ngcontent-%COMP%] { + padding: 4px 8px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .explain[_ngcontent-%COMP%] { + margin: 0; + padding: 10px; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 12px; + white-space: pre-wrap; + overflow-wrap: anywhere; + font-family: ui-monospace, monospace; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 2px 0; + padding: 0 5px; + border: 1px solid #3f3f46; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + } + .tag[data-tone='warn'][_ngcontent-%COMP%] { + border-color: #a16207; + color: #fef08a; + } + .tag[data-tone='bad'][_ngcontent-%COMP%] { + border-color: #b91c1c; + color: #fecaca; + } + .status[_ngcontent-%COMP%] { + min-height: 1.2em; + margin: 0; + color: #d4d4d8; + font-size: 13px; + } + + [_nghost-%COMP%] { + display: grid; + gap: 8px; + } + h3[_ngcontent-%COMP%] { + margin: 4px 0 0; + color: #d4d4d8; + font-size: 13px; + } + .status[_ngcontent-%COMP%] { + margin-left: 8px; + }`]})},UO=class e{formId=k_.required();version=k_(0);rpc=k_(null);findings=L(null);constructor(){Zs(()=>{let e=this.formId();this.version();let t=this.rpc();x_(async()=>{let n=await jO(t,`forms-lint`,{form:e});this.formId()===e&&this.findings.set(n??[])})})}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-forms-lint`]],inputs:{formId:[1,`formId`],version:[1,`version`],rpc:[1,`rpc`]},decls:3,vars:1,consts:[[1,`muted`],[1,`findings`],[1,`tag`]],template:function(e,t){e&1&&V(0,LO,2,0,`p`,0)(1,RO,2,0,`p`,0)(2,VO,3,0,`ul`,1),e&2&&H(t.findings()===null?0:t.findings().length?2:1)},styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + } + .small[_ngcontent-%COMP%] { + padding: 4px 10px; + border: 1px solid #52525b; + border-radius: 6px; + background: #18181b; + color: #e4e4e7; + font-size: 12px; + cursor: pointer; + } + .small[_ngcontent-%COMP%]:hover { + border-color: var(--%NS%accent); + } + .small[_ngcontent-%COMP%]:focus-visible, + .field-input[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .field-input[_ngcontent-%COMP%] { + padding: 4px 8px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .explain[_ngcontent-%COMP%] { + margin: 0; + padding: 10px; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 12px; + white-space: pre-wrap; + overflow-wrap: anywhere; + font-family: ui-monospace, monospace; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 2px 0; + padding: 0 5px; + border: 1px solid #3f3f46; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + } + .tag[data-tone='warn'][_ngcontent-%COMP%] { + border-color: #a16207; + color: #fef08a; + } + .tag[data-tone='bad'][_ngcontent-%COMP%] { + border-color: #b91c1c; + color: #fecaca; + } + .status[_ngcontent-%COMP%] { + min-height: 1.2em; + margin: 0; + color: #d4d4d8; + font-size: 13px; + } + + .findings[_ngcontent-%COMP%] { + display: grid; + gap: 8px; + margin: 0; + padding: 0; + list-style: none; + font-size: 13px; + color: #e4e4e7; + } + .findings[_ngcontent-%COMP%] li[_ngcontent-%COMP%] { + padding: 8px; + border: 1px solid #27272a; + border-radius: 6px; + } + code[_ngcontent-%COMP%] { + color: #c4b5fd; + }`]})},WO=()=>[],GO=(e,t)=>t.formId+`#`+t.seq;function KO(e,t){if(e&1){let e=Yh();q(0,`label`)(1,`input`,6),Y(`change`,function(){let t=F(e).$implicit;return I(X().filter.set(t))}),J(),Z(2),J()}if(e&2){let e=t.$implicit,n=X();z(),Xh(`value`,e)(`checked`,e===n.filter()),z(),$(` `,e,` `)}}function qO(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;B(`data-tone`,e.outcome===`ran`?``:`bad`),z(),Q(e.outcome)}}function JO(e,t){if(e&1&&(q(0,`span`,5),Z(1),J(),Z(2,` → `)),e&2){let e=X().$implicit;z(),Q(e.prev)}}function YO(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;z(),$(`×`,e.count)}}function XO(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;z(),Q(e.origin)}}function ZO(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;B(`data-tone`,e.ms>1e3?`warn`:``),z(),$(`pending `,e.ms,`ms`)}}function QO(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;B(`data-tone`,e.renders>20?`warn`:``),z(),t_(``,e.renders,` renders: `,(e.rendered??i_(3,WO)).join(`, `))}}function $O(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=X().$implicit;z(),$(`from `,e.caller)}}function ek(e,t){if(e&1&&(q(0,`li`)(1,`time`),Z(2),J(),q(3,`code`),Z(4),J(),q(5,`span`,7),Z(6),J(),V(7,qO,2,2,`span`,8),q(8,`span`,9),V(9,JO,3,1),Z(10),J(),V(11,YO,2,1,`span`,8),V(12,XO,2,1,`span`,8),V(13,ZO,2,2,`span`,8),V(14,QO,2,4,`span`,8),V(15,$O,2,1,`span`,10),J()),e&2){let e=t.$implicit,n=X(2);B(`data-type`,e.type),z(2),Q(n.time(e.timestamp)),z(2),Q(e.path||`(form)`),z(2),Q(e.type),z(),H(e.outcome?7:-1),z(2),H(e.prev===void 0?-1:9),z(),$(` `,e.detail,` `),z(),H(e.count&&e.count>1?11:-1),z(),H(e.origin?12:-1),z(),H(e.ms===void 0?-1:13),z(),H(e.renders?14:-1),z(),H(e.caller?15:-1)}}function tk(e,t){if(e&1&&(q(0,`ol`,4),U(1,ek,16,12,`li`,null,GO),J()),e&2){let e=X();z(),W(e.shown())}}function nk(e,t){e&1&&(q(0,`p`,5),Z(1,`No changes yet. Type into the form to see them here.`),J())}var rk=[`all`,`user`,`code`,`devtools`],ik=class e{events=k_.required();recording=k_(!1);record=E_();origins=rk;filter=L(`all`);shown=b_(()=>{let e=this.filter();return this.events().filter(t=>e===`all`||t.origin===e).slice(-100).reverse()});time(e){return new Date(e).toLocaleTimeString()}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-forms-timeline`]],inputs:{events:[1,`events`],recording:[1,`recording`]},outputs:{record:`record`},decls:10,vars:2,consts:[[1,`record`],[`type`,`checkbox`,3,`change`,`checked`],[1,`chips`],[1,`sr-only`],[1,`events`],[1,`muted`],[`type`,`radio`,`name`,`timeline-origin`,3,`change`,`value`,`checked`],[1,`event-type`],[1,`tag`],[1,`detail`],[1,`caller`]],template:function(e,t){e&1&&(q(0,`label`,0)(1,`input`,1),Y(`change`,function(){return t.record.emit(!t.recording())}),J(),Z(2,` Record calling code, validator changes and renders per keystroke `),J(),q(3,`fieldset`,2)(4,`legend`,3),Z(5,`Show changes from`),J(),U(6,KO,3,3,`label`,null,kh),J(),V(8,tk,3,0,`ol`,4)(9,nk,2,0,`p`,5)),e&2&&(z(),Xh(`checked`,t.recording()),z(5),W(t.origins),z(2),H(t.shown().length?8:9))},styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + } + .small[_ngcontent-%COMP%] { + padding: 4px 10px; + border: 1px solid #52525b; + border-radius: 6px; + background: #18181b; + color: #e4e4e7; + font-size: 12px; + cursor: pointer; + } + .small[_ngcontent-%COMP%]:hover { + border-color: var(--%NS%accent); + } + .small[_ngcontent-%COMP%]:focus-visible, + .field-input[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .field-input[_ngcontent-%COMP%] { + padding: 4px 8px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .explain[_ngcontent-%COMP%] { + margin: 0; + padding: 10px; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 12px; + white-space: pre-wrap; + overflow-wrap: anywhere; + font-family: ui-monospace, monospace; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 2px 0; + padding: 0 5px; + border: 1px solid #3f3f46; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + } + .tag[data-tone='warn'][_ngcontent-%COMP%] { + border-color: #a16207; + color: #fef08a; + } + .tag[data-tone='bad'][_ngcontent-%COMP%] { + border-color: #b91c1c; + color: #fecaca; + } + .status[_ngcontent-%COMP%] { + min-height: 1.2em; + margin: 0; + color: #d4d4d8; + font-size: 13px; + } + + [_nghost-%COMP%] { + display: grid; + gap: 8px; + } + .chips[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin: 0; + padding: 0; + border: 0; + color: #d4d4d8; + font-size: 13px; + } + .sr-only[_ngcontent-%COMP%] { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + } + .events[_ngcontent-%COMP%] { + display: grid; + gap: 4px; + margin: 0; + padding: 0; + list-style: none; + font-size: 13px; + } + .events[_ngcontent-%COMP%] li[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: baseline; + color: #d4d4d8; + } + .events[_ngcontent-%COMP%] li[data-type='submit'][_ngcontent-%COMP%] { + border-left: 3px solid var(--%NS%accent); + padding-left: 6px; + } + time[_ngcontent-%COMP%] { + color: #a1a1aa; + font-variant-numeric: tabular-nums; + } + code[_ngcontent-%COMP%] { + color: #c4b5fd; + } + .event-type[_ngcontent-%COMP%] { + color: #93c5fd; + } + .detail[_ngcontent-%COMP%] { + overflow-wrap: anywhere; + } + .record[_ngcontent-%COMP%] { + color: #d4d4d8; + font-size: 13px; + } + .caller[_ngcontent-%COMP%] { + flex-basis: 100%; + padding-left: 16px; + color: #a1a1aa; + font-family: ui-monospace, monospace; + font-size: 12px; + overflow-wrap: anywhere; + }`]})},ak=()=>[],ok=(e,t)=>t.id,sk=(e,t)=>t.node.path;function ck(e,t){e&1&&(G(0,`p`,0),Z(1,`Connecting…`),K())}function lk(e,t){e&1&&(G(0,`p`,0),Z(1,`Could not load forms from the devtools server. Reload to try again.`),K())}function uk(e,t){e&1&&(G(0,`p`,0),Z(1,`Loading forms…`),K())}function dk(e,t){e&1&&(G(0,`div`,0)(1,`p`),Z(2,`No forms on the page yet.`),K(),G(3,`p`,2),Z(4,` Open a page that renders a form. Signal Forms, reactive and template-driven forms all show up here, in development builds. `),K()())}function fk(e,t){e&1&&(G(0,`span`,10),Z(1),G(2,`span`,9),Z(3,` errors`),K()()),e&2&&(z(),Q(t))}function pk(e,t){if(e&1){let e=Yh();G(0,`li`)(1,`button`,5),sg(`click`,function(){let t=F(e).$implicit;return I(X(2).selectForm(t.id))}),Vh(2,`span`,6),G(3,`span`,7),Z(4),K(),G(5,`span`,8),Z(6),G(7,`span`,9),Z(8),K()(),V(9,fk,4,1,`span`,10),K()()}if(e&2){let e,n=t.$implicit,r=X(2);z(),Ag(`active`,n.id===r.selected()?.id),B(`aria-current`,n.id===r.selected()?.id?`true`:null),z(),B(`data-status`,n.root.status),z(2),Q(n.label),z(2),t_(``,r.kindLabel(n.kind),` · `,n.id,` `),z(2),$(`, `,n.root.status),z(),H((e=r.counts().get(n.id)?.errors)?9:-1,e)}}function mk(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X();z(),Q(e.submitted?`submitted`:`not submitted`)}}function hk(e,t){e&1&&(G(0,`span`),Z(1,`submitting`),K())}function gk(e,t){if(e&1){let e=Yh();G(0,`button`,14),sg(`click`,function(){return F(e),I(X(3).confirmAct(`restore`))}),Z(1),K()}if(e&2){let e=X(3);z(),$(` `,e.armed()===`restore`?`Confirm restore`:`Restore `+e.snapshot(),` `)}}function _k(e,t){if(e&1){let e=Yh();G(0,`button`,22),sg(`click`,function(){let t=F(e).$implicit;return I(X(3).tab_.set(t.id))}),Z(1),K()}if(e&2){let e=t.$implicit,n=X(3);Rh(`id`,`forms-tab-`+e.id),B(`aria-selected`,e.id===n.tab_())(`aria-controls`,`forms-panel-`+e.id)(`tabindex`,e.id===n.tab_()?0:-1),z(),$(` `,e.label,` `)}}function vk(e,t){if(e&1){let e=Yh();G(0,`label`)(1,`input`,29),sg(`change`,function(){let t=F(e).$implicit;return I(X(4).toggleChip(t.id))}),K(),Z(2),K()}if(e&2){let e=t.$implicit,n=X(4);z(),Rh(`checked`,n.active().has(e.id)),z(),$(` `,e.label,` `)}}function yk(e,t){if(e&1&&(G(0,`div`,2),Z(1,` typed `),G(2,`code`),Z(3),l_(4,`json`),K(),Z(5,`, not in the model yet `),K()),e&2){let e=X(2).$implicit;z(3),Q(d_(4,1,e.node.uncommitted))}}function bk(e,t){if(e&1&&(G(0,`div`,2),Z(1,` resets to `),G(2,`code`),Z(3),l_(4,`json`),K()()),e&2){let e=X(2).$implicit;z(3),Q(d_(4,1,e.node.defaultValue))}}function xk(e,t){if(e&1&&(G(0,`code`),Z(1),l_(2,`json`),K(),V(3,yk,6,3,`div`,2),V(4,bk,5,3,`div`,2)),e&2){let e=X().$implicit;z(),Q(d_(2,3,e.node.value)),z(2),H(e.node.uncommitted===void 0?-1:3),z(),H(e.node.defaultValue===void 0?-1:4)}}function Sk(e,t){e&1&&(G(0,`span`,2),Z(1,`not created yet`),K())}function Ck(e,t){if(e&1&&(G(0,`span`,12),Z(1),K()),e&2){let e=X().$implicit;B(`data-status`,e.node.status),z(),Q(e.node.status)}}function wk(e,t){e&1&&(G(0,`span`),Z(1,`touched`),K())}function Tk(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;z(),Q(e.node.changed===!1?`dirty, unchanged`:`dirty`)}}function Ek(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;z(),$(`not validated (`,e.node.skipped,`)`)}}function Dk(e,t){if(e&1&&(G(0,`span`,36),Z(1),K()),e&2){let e=X().$implicit;z(),$(`stale: `,e.node.stale.join(`, `))}}function Ok(e,t){e&1&&(G(0,`span`,36),Z(1,`view out of sync`),K())}function kk(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;z(),$(`redacted (`,e.node.redacted,`)`)}}function Ak(e,t){e&1&&(G(0,`span`),Z(1,`required`),K())}function jk(e,t){e&1&&(G(0,`span`),Z(1,`readonly`),K())}function Mk(e,t){e&1&&(G(0,`span`),Z(1,`hidden`),K())}function Nk(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;z(),$(`updates on `,e.node.updateOn)}}function Pk(e,t){e&1&&(G(0,`span`),Z(1,`debouncing`),K())}function Fk(e,t){e&1&&(G(0,`span`),Z(1,`validators`),K())}function Ik(e,t){e&1&&(G(0,`span`),Z(1,`async validator`),K())}function Lk(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=t.$implicit;z(),Q(e)}}function Rk(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;z(),Q(e.node.accessor)}}function zk(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=t.$implicit;z(),$(`disabled: `,e)}}function Bk(e,t){if(e&1&&(G(0,`span`,40),Z(1),K()),e&2){let e=X().$implicit,t=X(5);z(),Q(t.sourceText(e))}}function Vk(e,t){if(e&1&&(G(0,`div`),Z(1),G(2,`code`,39),Z(3),K(),V(4,Bk,2,1,`span`,40),K()),e&2){let e=t.$implicit,n=X().$implicit,r=X(4);z(),$(` `,r.errorText(n.node,e),` `),z(2),Q(e.kind),z(),H(e.source?4:-1)}}function Hk(e,t){e&1&&(G(0,`div`,38),Z(1,`not shown to the user`),K())}function Uk(e,t){if(e&1&&(G(0,`tr`)(1,`td`,41),Z(2),K()()),e&2){let e=X().$implicit;z(),kg(`padding-left`,24+e.depth*16,`px`),z(),t_(` `,e.node.truncated,` more fields under `,e.node.path||`the form`,` not shown `)}}function Wk(e,t){if(e&1){let e=Yh();G(0,`tr`,30),sg(`mouseenter`,function(){let t=F(e).$implicit,n=X(2);return I(X(2).highlight(n.id,t.node.path))})(`mouseleave`,function(){return F(e),I(X(4).highlight(null,``))}),G(1,`th`,31)(2,`button`,32),sg(`focus`,function(){let t=F(e).$implicit,n=X(2);return I(X(2).highlight(n.id,t.node.path))})(`blur`,function(){return F(e),I(X(4).highlight(null,``))})(`click`,function(){let t=F(e).$implicit;return I(X(4).fieldPath.set(t.node.path))}),Z(3),K(),G(4,`span`,33),Z(5),K()(),G(6,`td`,34),V(7,xk,5,5),K(),G(8,`td`),V(9,Sk,2,0,`span`,2)(10,Ck,2,2,`span`,12),K(),G(11,`td`,35),V(12,wk,2,0,`span`),V(13,Tk,2,1,`span`),V(14,Ek,2,1,`span`),V(15,Dk,2,1,`span`,36),V(16,Ok,2,0,`span`,36),V(17,kk,2,1,`span`),V(18,Ak,2,0,`span`),V(19,jk,2,0,`span`),V(20,Mk,2,0,`span`),V(21,Nk,2,1,`span`),V(22,Pk,2,0,`span`),V(23,Fk,2,0,`span`),V(24,Ik,2,0,`span`),U(25,Lk,2,1,`span`,null,kh),V(27,Rk,2,1,`span`),U(28,zk,2,1,`span`,null,Oh),K(),G(30,`td`,37),U(31,Vk,5,3,`div`,null,Oh),V(33,Hk,2,0,`div`,38),K()(),V(34,Uk,3,4,`tr`)}if(e&2){let e=t.$implicit,n=X(4);Ag(`invalid`,e.node.errors.length),z(),kg(`padding-left`,8+e.depth*16,`px`),z(),B(`aria-label`,`Highlight `+(e.node.path||`the form`)+` on the page`)(`aria-pressed`,e.node.path===n.fieldPath()),z(),$(` `,e.node.key||`(form)`,` `),z(2),Q(e.node.type),z(2),H(e.node.type===`control`?7:-1),z(2),H(e.node.materialized===!1?9:10),z(3),H(e.node.touched?12:-1),z(),H(e.node.dirty?13:-1),z(),H(e.node.skipped?14:-1),z(),H(e.node.stale?.length?15:-1),z(),H(e.node.dom?.drift===void 0?-1:16),z(),H(e.node.redacted?17:-1),z(),H(e.node.required?18:-1),z(),H(e.node.readonly?19:-1),z(),H(e.node.hidden?20:-1),z(),H(e.node.updateOn?21:-1),z(),H(e.node.debouncing?22:-1),z(),H(e.node.validators?.sync?23:-1),z(),H(e.node.validators?.async?24:-1),z(),W(n.constraintList(e.node)),z(2),H(e.node.accessor?27:-1),z(),W(e.node.disabledReasons??i_(26,ak)),z(3),W(e.node.errors),z(2),H(e.node.errors.length&&e.node.dom?.errorShown===!1?33:-1),z(),H(e.node.truncated?34:-1)}}function Gk(e,t){e&1&&Z(0),e&2&&$(` No field path matches "`,X(5).filter(),`". `)}function Kk(e,t){e&1&&Z(0,` No field matches the selected filters. `)}function qk(e,t){if(e&1&&(G(0,`tr`)(1,`td`,41),V(2,Gk,1,1)(3,Kk,1,0),K()()),e&2){let e=X(4);z(2),H(e.filter()?2:3)}}function Jk(e,t){if(e&1&&Vh(0,`app-forms-field-detail`,28),e&2){let e=X(2),n=X(2);Rh(`form`,e)(`node`,t)(`version`,n.version())(`rpc`,n.rpc())}}function Yk(e,t){if(e&1){let e=Yh();G(0,`fieldset`,23)(1,`legend`,9),Z(2,`Show only fields that are`),K(),U(3,vk,3,2,`label`,null,ok),K(),G(5,`input`,24),sg(`input`,function(t){return F(e),I(X(3).onFilter(t))}),K(),G(6,`div`,25)(7,`table`,26)(8,`thead`)(9,`tr`)(10,`th`,27),Z(11,`Field`),K(),G(12,`th`,27),Z(13,`Value`),K(),G(14,`th`,27),Z(15,`Status`),K(),G(16,`th`,27),Z(17,`State`),K(),G(18,`th`,27),Z(19,`Errors`),K()()(),G(20,`tbody`),U(21,Wk,35,27,null,null,sk,!1,qk,4,1,`tr`),K()()(),V(24,Jk,1,4,`app-forms-field-detail`,28)}if(e&2){let e,t=X(3);z(3),W(t.chips),z(2),Rh(`value`,t.filter()),z(16),W(t.rows()),z(3),H((e=t.selectedNode())?24:-1,e)}}function Xk(e,t){if(e&1){let e=Yh();G(0,`app-forms-timeline`,42),sg(`record`,function(t){return F(e),I(X(3).setRecording(t))}),K()}if(e&2){let e=X(3);Rh(`events`,e.selectedEvents())(`recording`,e.recording())}}function Zk(e,t){if(e&1&&Vh(0,`app-forms-submit`,21),e&2){let e=X(),t=X(2);Rh(`formId`,e.id)(`version`,t.version())(`rpc`,t.rpc())}}function Qk(e,t){if(e&1&&Vh(0,`app-forms-lint`,21),e&2){let e=X(),t=X(2);Rh(`formId`,e.id)(`version`,t.version())(`rpc`,t.rpc())}}function $k(e,t){if(e&1){let e=Yh();G(0,`section`,4)(1,`div`,11)(2,`span`,12),Z(3),K(),G(4,`span`),Z(5),K(),G(6,`span`),Z(7),K(),V(8,mk,2,1,`span`),V(9,hk,2,0,`span`),G(10,`span`,2),Z(11),K()(),G(12,`div`,13)(13,`button`,14),sg(`click`,function(){return F(e),I(X(2).act(`touch-all`))}),Z(14,`Touch all`),K(),G(15,`button`,14),sg(`click`,function(){return F(e),I(X(2).act(`revalidate`))}),Z(16,`Revalidate`),K(),G(17,`button`,14),sg(`click`,function(){return F(e),I(X(2).act(`focus-first-invalid`))}),Z(18,` Focus first invalid `),K(),G(19,`button`,14),sg(`click`,function(){return F(e),I(X(2).pick())}),Z(20,`Pick field on page`),K(),G(21,`button`,14),sg(`click`,function(){return F(e),I(X(2).act(`snapshot`))}),Z(22,`Snapshot`),K(),V(23,gk,2,1,`button`,15),G(24,`button`,14),sg(`click`,function(){return F(e),I(X(2).confirmAct(`reset`))}),Z(25),K(),G(26,`button`,14),sg(`click`,function(){return F(e),I(X(2).confirmAct(`submit`))}),Z(27),K()(),G(28,`p`,16),Z(29),K(),G(30,`div`,17),sg(`keydown`,function(t){return F(e),I(X(2).onKey(t))}),U(31,_k,2,5,`button`,18,ok),K(),G(33,`div`,19),V(34,Yk,25,3)(35,Xk,1,2,`app-forms-timeline`,20)(36,Zk,1,3,`app-forms-submit`,21)(37,Qk,1,3,`app-forms-lint`,21),K()()}if(e&2){let e,n=t,r=X(2);B(`aria-label`,n.label),z(2),B(`data-status`,n.root.status),z(),Q(n.root.status),z(2),Q(n.root.dirty?`dirty`:`pristine`),z(2),Q(n.root.touched?`touched`:`untouched`),z(),H(n.submitted===void 0?-1:8),z(),H(n.root.submitting?9:-1),z(2),t_(``,r.counts().get(n.id)?.fields,` fields, `,r.counts().get(n.id)?.errors,` errors`),z(12),H(r.snapshot()?23:-1),z(2),$(` `,r.armed()===`reset`?`Confirm reset`:`Reset`,` `),z(2),$(` `,r.armed()===`submit`?`Confirm submit`:`Submit`,` `),z(2),Q(r.message()),z(2),W(r.tabs),z(2),Rh(`id`,`forms-panel-`+r.tab_()),B(`aria-labelledby`,`forms-tab-`+r.tab_()),z(),H((e=r.tab_())===`fields`?34:e===`timeline`?35:e===`submit`?36:e===`lint`?37:-1)}}function eA(e,t){if(e&1&&(G(0,`div`,1)(1,`ul`,3),U(2,pk,10,9,`li`,null,ok),K(),V(4,$k,38,16,`section`,4),K()),e&2){let e,t=X();z(2),W(t.forms()),z(2),H((e=t.selected())?4:-1,e)}}var tA=[{id:`fields`,label:`Fields`},{id:`timeline`,label:`Timeline`},{id:`submit`,label:`Submit`},{id:`lint`,label:`Lint`}],nA=[{id:`invalid`,label:`Invalid`},{id:`dirty`,label:`Dirty`},{id:`touched`,label:`Touched`},{id:`disabled`,label:`Disabled`},{id:`hidden-error`,label:`Error not shown`}];function rA(e,t){switch(t){case`invalid`:return e.errors.length>0;case`dirty`:return e.dirty&&e.type===`control`;case`touched`:return e.touched&&e.type===`control`;case`disabled`:return e.status===`DISABLED`;case`hidden-error`:return e.dom?.errorShown===!1}}function iA(e){return e.errors.length+(e.children??[]).reduce((e,t)=>e+iA(t),0)}function aA(e){return 1+(e.children??[]).reduce((e,t)=>e+aA(t),0)}var oA=class e{rpc=k_(null);focus=k_(null);focusHandled=E_();forms=L([]);events=L([]);loading=L(!0);failed=L(!1);selectedId=L(null);instrumented=L([]);recording=b_(()=>{let e=this.selected()?.id??``;return this.instrumented().some(t=>e.endsWith(`@${t}`))});filter=L(``);tabs=tA;chips=nA;tab_=L(`fields`);active=L(new Set);fieldPath=L(null);version=L(0);message=L(``);armed=L(null);snapshot=L(null);unsubscribe=null;destroyRef=M(us);counts=b_(()=>new Map(this.forms().map(e=>[e.id,{fields:aA(e.root),errors:iA(e.root)}])));selected=b_(()=>{let e=this.forms();return e.find(e=>e.id===this.selectedId())??e[0]??null});rows=b_(()=>{let e=this.selected();if(!e)return[];let t=this.filter().toLowerCase(),n=Array.from(this.active()),r=[],i=(e,a)=>{let o=r.length,s=(!t||e.path.toLowerCase().includes(t))&&n.every(t=>rA(e,t));for(let t of e.children??[])s=i(t,a+1)||s;return s&&r.splice(o,0,{node:e,depth:a}),s};return i(e.root,0),r});selectedNode=b_(()=>{let e=this.fieldPath(),t=this.selected();if(e===null||!t)return null;let n=t=>t.path===e?t:(t.children??[]).map(n).find(Boolean)??null;return n(t.root)});selectedEvents=b_(()=>{let e=this.selected()?.id;return this.events().filter(t=>t.formId===e).slice(-200)});constructor(){Zs(()=>{let e=this.rpc();e&&this.load(e)}),Zs(()=>{let e=this.focus();e&&x_(()=>{this.selectForm(e.id),this.focusHandled.emit()})}),this.destroyRef.onDestroy(()=>{this.unsubscribe?.(),this.highlight(null,``)})}async load(e){this.loading.set(!0),this.failed.set(!1);try{let t=await e.scope(`ng-devtools`).rpc.sharedState(`forms`);if(this.destroyRef.destroyed)return;let n=e=>{let t=e;this.forms.set(t?.forms??[]),this.events.set(t?.events??[]),this.instrumented.set(t?.instrumented??[]),this.version.update(e=>e+1)};n(t.value()),this.unsubscribe?.(),this.unsubscribe=t.on(`updated`,n)}catch{this.failed.set(!0)}finally{this.loading.set(!1)}}async pick(){let e=this.selected();if(!e)return;this.message.set(`Click a field in the app (Esc cancels).`);let t=await MO(this.rpc(),{action:`pick`,formId:e.id}),n=t;if(!t.ok||!n.formId){this.message.set(NO(t));return}this.selectForm(n.formId),this.tab_.set(`fields`),this.fieldPath.set(n.path??``),this.message.set(`Picked ${n.path||`(form)`}.`)}async setRecording(e){let t=this.selected();if(!t)return;let n=await MO(this.rpc(),{action:`instrument`,formId:t.id,value:e});this.message.set(NO(n))}selectForm(e){this.selectedId.set(e),this.filter.set(``),this.fieldPath.set(null),this.snapshot.set(null),this.armed.set(null)}toggleChip(e){this.active.update(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})}async act(e,t={}){let n=this.selected();if(!n)return;this.armed.set(null);let r=await MO(this.rpc(),{action:e,formId:n.id,...t});r.snapshot&&this.snapshot.set(r.snapshot),this.message.set(NO(r))}confirmAct(e){if(this.armed()!==e){this.armed.set(e),this.message.set(`Press "Confirm ${e}" to ${e} the form in the app.`);return}this.act(e,{confirm:!0,snapshot:this.snapshot()??void 0})}onKey(e){let t=this.tabs.map(e=>e.id),n=t.indexOf(this.tab_()),r=n;if(e.key===`ArrowRight`)r=(n+1)%t.length;else if(e.key===`ArrowLeft`)r=(n-1+t.length)%t.length;else if(e.key===`Home`)r=0;else if(e.key===`End`)r=t.length-1;else return;e.preventDefault(),this.tab_.set(t[r]);let i=e.currentTarget;queueMicrotask(()=>i.querySelector(`#forms-tab-${t[r]}`)?.focus())}sourceText(e){let t=AO[e.source??``]??e.source??``;return e.from===void 0?t:`${t} on ${e.from||`the form`}`}onFilter(e){this.filter.set(e.target.value)}highlight(e,t){let n=this.rpc();n&&n.scope(`ng-devtools`).rpc.callEvent(`request-form-highlight`,e?{formId:e,path:t}:null)}kindLabel(e){return kO[e]}constraintList(e){return Object.entries(e.constraints??{}).map(([e,t])=>`${e} ${t}`)}errorText(e,t){return/^[a-z]/.test(t.message)?`${e.key||`The form`} ${t.message}`:t.message}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-forms-inspector`]],inputs:{rpc:[1,`rpc`],focus:[1,`focus`]},outputs:{focusHandled:`focusHandled`},decls:5,vars:1,consts:[[1,`empty`],[1,`layout`],[1,`muted`],[`aria-label`,`Forms on the page`,1,`form-list`],[1,`detail`],[`type`,`button`,1,`form-item`,3,`click`],[`aria-hidden`,`true`,1,`dot`],[1,`label`],[1,`kind`],[1,`sr-only`],[1,`count`],[1,`summary`],[1,`badge`],[`role`,`group`,`aria-label`,`Form actions`,1,`actions`],[`type`,`button`,1,`small`,3,`click`],[`type`,`button`,1,`small`],[`role`,`status`,1,`status`],[`role`,`tablist`,`aria-label`,`Form views`,1,`tabs`,3,`keydown`],[`type`,`button`,`role`,`tab`,3,`id`],[`role`,`tabpanel`,1,`panel`,3,`id`],[3,`events`,`recording`],[3,`formId`,`version`,`rpc`],[`type`,`button`,`role`,`tab`,3,`click`,`id`],[1,`chips`],[`type`,`search`,`placeholder`,`Filter fields by path`,`aria-label`,`Filter fields by path`,1,`filter`,3,`input`,`value`],[`role`,`region`,`aria-label`,`Fields`,`tabindex`,`0`,1,`table-scroll`],[1,`fields`],[`scope`,`col`],[3,`form`,`node`,`version`,`rpc`],[`type`,`checkbox`,3,`change`,`checked`],[3,`mouseenter`,`mouseleave`],[`scope`,`row`],[`type`,`button`,1,`field`,3,`focus`,`blur`,`click`],[1,`type`],[1,`value`],[1,`flags`],[1,`warn`],[1,`errors`],[1,`unseen`],[1,`kind-tag`],[1,`source`],[`colspan`,`5`,1,`muted`],[3,`record`,`events`,`recording`]],template:function(e,t){e&1&&V(0,ck,2,0,`p`,0)(1,lk,2,0,`p`,0)(2,uk,2,0,`p`,0)(3,dk,5,0,`div`,0)(4,eA,5,1,`div`,1),e&2&&H(t.rpc()?t.failed()?1:t.loading()?2:t.forms().length?4:3:0)},dependencies:[IO,ik,HO,UO,Wv],styles:[`.muted[_ngcontent-%COMP%] { + color: #a1a1aa; + } + .small[_ngcontent-%COMP%] { + padding: 4px 10px; + border: 1px solid #52525b; + border-radius: 6px; + background: #18181b; + color: #e4e4e7; + font-size: 12px; + cursor: pointer; + } + .small[_ngcontent-%COMP%]:hover { + border-color: var(--%NS%accent); + } + .small[_ngcontent-%COMP%]:focus-visible, + .field-input[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .field-input[_ngcontent-%COMP%] { + padding: 4px 8px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 13px; + } + .explain[_ngcontent-%COMP%] { + margin: 0; + padding: 10px; + border: 1px solid #27272a; + border-radius: 6px; + color: #e4e4e7; + font-size: 12px; + white-space: pre-wrap; + overflow-wrap: anywhere; + font-family: ui-monospace, monospace; + } + .tag[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 2px 0; + padding: 0 5px; + border: 1px solid #3f3f46; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + } + .tag[data-tone='warn'][_ngcontent-%COMP%] { + border-color: #a16207; + color: #fef08a; + } + .tag[data-tone='bad'][_ngcontent-%COMP%] { + border-color: #b91c1c; + color: #fecaca; + } + .status[_ngcontent-%COMP%] { + min-height: 1.2em; + margin: 0; + color: #d4d4d8; + font-size: 13px; + } + + .actions[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 6px; + } + .tabs[_ngcontent-%COMP%] { + display: flex; + gap: 4px; + border-bottom: 1px solid #27272a; + } + .tabs[_ngcontent-%COMP%] [role='tab'][_ngcontent-%COMP%] { + padding: 6px 12px; + border: none; + border-bottom: 2px solid transparent; + background: none; + color: #d4d4d8; + font: inherit; + font-size: 13px; + cursor: pointer; + } + .tabs[_ngcontent-%COMP%] [role='tab'][aria-selected='true'][_ngcontent-%COMP%] { + border-bottom-color: var(--%NS%accent); + color: #fafafa; + } + .tabs[_ngcontent-%COMP%] [role='tab'][_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .panel[_ngcontent-%COMP%] { + display: grid; + gap: 12px; + } + .chips[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin: 0; + padding: 0; + border: 0; + color: #d4d4d8; + font-size: 13px; + } + .field[aria-pressed='true'][_ngcontent-%COMP%] { + color: var(--%NS%accent); + text-decoration: underline; + } + .flags[_ngcontent-%COMP%] span.warn[_ngcontent-%COMP%] { + border-color: #a16207; + color: #fef08a; + } + .source[_ngcontent-%COMP%] { + margin-left: 6px; + color: #a1a1aa; + font-size: 11px; + } + .unseen[_ngcontent-%COMP%] { + color: #fde68a !important; + font-size: 11px; + } + .layout[_ngcontent-%COMP%] { + display: grid; + grid-template-columns: minmax(200px, 260px) minmax(0, 1fr); + gap: 16px; + } + @media (max-width: 720px) { + .layout[_ngcontent-%COMP%] { + grid-template-columns: 1fr; + } + } + .form-list[_ngcontent-%COMP%] { + display: grid; + gap: 4px; + align-content: start; + margin: 0; + padding: 0; + list-style: none; + } + .form-item[_ngcontent-%COMP%] { + width: 100%; + display: grid; + grid-template-columns: auto 1fr auto; + grid-template-areas: 'dot label count' '. kind kind'; + gap: 2px 8px; + align-items: center; + padding: 8px 10px; + border: 1px solid #27272a; + border-radius: 6px; + background: transparent; + color: #e4e4e7; + text-align: left; + cursor: pointer; + } + .form-item.active[_ngcontent-%COMP%] { + border-color: var(--%NS%accent); + background: #18181b; + } + .form-item[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%] { + grid-area: dot; + } + .form-item[_ngcontent-%COMP%] .label[_ngcontent-%COMP%] { + grid-area: label; + overflow-wrap: anywhere; + font-size: 13px; + } + .form-item[_ngcontent-%COMP%] .kind[_ngcontent-%COMP%] { + grid-area: kind; + color: #a1a1aa; + font-size: 12px; + } + .form-item[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] { + grid-area: count; + padding: 0 6px; + border-radius: 999px; + background: #7f1d1d; + color: #fecaca; + font-size: 12px; + } + .dot[_ngcontent-%COMP%] { + width: 8px; + height: 8px; + border-radius: 50%; + background: #22c55e; + } + .dot[data-status='INVALID'][_ngcontent-%COMP%] { + background: #ef4444; + } + .dot[data-status='PENDING'][_ngcontent-%COMP%] { + background: #eab308; + } + .dot[data-status='DISABLED'][_ngcontent-%COMP%] { + background: #71717a; + } + .detail[_ngcontent-%COMP%] { + display: grid; + gap: 12px; + min-width: 0; + } + .summary[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 8px 14px; + align-items: center; + color: #d4d4d8; + font-size: 13px; + } + .badge[_ngcontent-%COMP%] { + padding: 1px 6px; + border-radius: 4px; + background: #14532d; + color: #bbf7d0; + font-size: 11px; + font-weight: 600; + } + .badge[data-status='INVALID'][_ngcontent-%COMP%] { + background: #7f1d1d; + color: #fecaca; + } + .badge[data-status='PENDING'][_ngcontent-%COMP%] { + background: #713f12; + color: #fef08a; + } + .badge[data-status='DISABLED'][_ngcontent-%COMP%] { + background: #3f3f46; + color: #e4e4e7; + } + .filter[_ngcontent-%COMP%] { + padding: 8px 12px; + background: #18181b; + border: 1px solid #52525b; + border-radius: 6px; + color: #e4e4e7; + font-size: 14px; + } + .filter[_ngcontent-%COMP%]:focus-visible, + .form-item[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .table-scroll[_ngcontent-%COMP%] { + overflow-x: auto; + } + .table-scroll[_ngcontent-%COMP%]:focus-visible, + .field[_ngcontent-%COMP%]:focus-visible { + outline: 2px solid var(--%NS%accent); + outline-offset: 2px; + } + .field[_ngcontent-%COMP%] { + padding: 0; + border: none; + background: none; + color: inherit; + font: inherit; + cursor: pointer; + } + .sr-only[_ngcontent-%COMP%] { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + } + .fields[_ngcontent-%COMP%] { + width: 100%; + border-collapse: collapse; + font-size: 13px; + } + .fields[_ngcontent-%COMP%] th[_ngcontent-%COMP%], + .fields[_ngcontent-%COMP%] td[_ngcontent-%COMP%] { + padding: 6px 8px; + border-bottom: 1px solid #27272a; + text-align: left; + vertical-align: top; + } + .fields[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%] { + color: #a1a1aa; + font-weight: 500; + } + .fields[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] th[_ngcontent-%COMP%] { + color: #e4e4e7; + font-weight: 500; + white-space: nowrap; + } + .fields[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover { + background: #18181b; + } + .type[_ngcontent-%COMP%] { + margin-left: 6px; + color: #a1a1aa; + font-size: 11px; + font-weight: 400; + } + .value[_ngcontent-%COMP%] code[_ngcontent-%COMP%], + .errors[_ngcontent-%COMP%] code[_ngcontent-%COMP%] { + color: #c4b5fd; + overflow-wrap: anywhere; + } + .flags[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { + display: inline-block; + margin: 0 4px 2px 0; + padding: 0 5px; + border: 1px solid #3f3f46; + border-radius: 4px; + color: #d4d4d8; + font-size: 11px; + } + .errors[_ngcontent-%COMP%] div[_ngcontent-%COMP%] { + color: #fca5a5; + } + .kind-tag[_ngcontent-%COMP%] { + margin-left: 6px; + color: #a1a1aa; + font-size: 11px; + } + .muted[_ngcontent-%COMP%] { + color: #a1a1aa; + } + .empty[_ngcontent-%COMP%] { + padding: 32px; + text-align: center; + color: #d4d4d8; + }`]})},sA=(e,t)=>t.id;function cA(e,t){if(e&1){let e=Yh();G(0,`button`,14),sg(`click`,function(){let t=F(e).$implicit;return I(X().switchTab(t.id))}),Z(1),K()}if(e&2){let e=t.$implicit;Ag(`active`,X().tab()===e.id),z(),Q(e.label)}}function lA(e,t){if(e&1){let e=Yh();G(0,`app-dashboard`,15),sg(`navigate`,function(t){return F(e),I(X().switchTab(t))}),K()}e&2&&Rh(`rpc`,X().rpc())}function uA(e,t){if(e&1){let e=Yh();G(0,`app-component-tree`,16),sg(`showForm`,function(t){return F(e),I(X().showForm(t))}),K()}e&2&&Rh(`rpc`,X().rpc())}function dA(e,t){e&1&&Vh(0,`app-route-inspector`,12),e&2&&Rh(`rpc`,X().rpc())}function fA(e,t){e&1&&Vh(0,`app-signal-inspector`,12),e&2&&Rh(`rpc`,X().rpc())}function pA(e,t){e&1&&Vh(0,`app-di-inspector`,12),e&2&&Rh(`rpc`,X().rpc())}function mA(e,t){e&1&&Vh(0,`app-store-inspector`,12),e&2&&Rh(`rpc`,X().rpc())}function hA(e,t){if(e&1){let e=Yh();G(0,`app-forms-inspector`,17),sg(`focusHandled`,function(){return F(e),I(X().formFocus.set(null))}),K()}if(e&2){let e=X();Rh(`rpc`,e.rpc())(`focus`,e.formFocus())}}var gA=class e{tabs=[{id:`dashboard`,label:`Dashboard`},{id:`components`,label:`Components`},{id:`routes`,label:`Routes`},{id:`signals`,label:`Signals`},{id:`injectors`,label:`Injectors`},{id:`store`,label:`Store`},{id:`forms`,label:`Forms`}];tab=L(`dashboard`);rpc=L(null);connected=L(!1);ngOnInit(){let e=new URLSearchParams(location.hash.replace(/^#/,``)).get(`tab`);e&&this.tabs.some(t=>t.id===e)&&this.tab.set(e);let t=vA();mw(t?{baseURL:t}:{}).then(e=>{this.rpc.set(e),this.connected.set(!0),e.events.on(`connection:status`,e=>{this.connected.set(e===`connected`)})})}ngOnDestroy(){}formFocus=L(null);showForm(e){this.formFocus.set({id:e}),this.switchTab(`forms`)}switchTab(e){this.tab.set(e),history.replaceState(history.state,``,`#tab=${e}`)}static ɵfac=function(t){return new(t||e)};static ɵcmp=$p({type:e,selectors:[[`app-root`]],decls:27,vars:4,consts:[[1,`brand`],[`width`,`20`,`height`,`22`,`viewBox`,`0 0 223 236`,`fill`,`url(#ng-logo)`,`aria-hidden`,`true`],[`id`,`ng-logo`,`x1`,`49`,`x2`,`226`,`y1`,`214`,`y2`,`130`,`gradientUnits`,`userSpaceOnUse`],[`stop-color`,`#E40035`],[`offset`,`.24`,`stop-color`,`#F60A48`],[`offset`,`.352`,`stop-color`,`#F20755`],[`offset`,`.494`,`stop-color`,`#DC087D`],[`offset`,`.745`,`stop-color`,`#9717E7`],[`offset`,`1`,`stop-color`,`#6C00F5`],[`d`,`m222.077 39.192-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z`],[3,`active`],[1,`status`],[3,`rpc`],[3,`rpc`,`focus`],[3,`click`],[3,`navigate`,`rpc`],[3,`showForm`,`rpc`],[3,`focusHandled`,`rpc`,`focus`]],template:function(e,t){if(e&1&&(G(0,`header`)(1,`h1`,0),$o(),G(2,`svg`,1)(3,`defs`)(4,`linearGradient`,2),Vh(5,`stop`,3)(6,`stop`,4)(7,`stop`,5)(8,`stop`,6)(9,`stop`,7)(10,`stop`,8),K()(),Vh(11,`path`,9),K(),es(),G(12,`span`),Z(13,`Angular DevTools`),K()(),G(14,`nav`),U(15,cA,2,3,`button`,10,sA),K(),G(17,`span`,11),Z(18),K()(),G(19,`main`),V(20,lA,1,1,`app-dashboard`,12)(21,uA,1,1,`app-component-tree`,12)(22,dA,1,1,`app-route-inspector`,12)(23,fA,1,1,`app-signal-inspector`,12)(24,pA,1,1,`app-di-inspector`,12)(25,mA,1,1,`app-store-inspector`,12)(26,hA,1,2,`app-forms-inspector`,13),K()),e&2){let e;z(15),W(t.tabs),z(2),Ag(`connected`,t.connected()),z(),$(` `,t.connected()?`Connected`:`Connecting…`,` `),z(2),H((e=t.tab())===`dashboard`?20:e===`components`?21:e===`routes`?22:e===`signals`?23:e===`injectors`?24:e===`store`?25:e===`forms`?26:-1)}},dependencies:[hw,Iw,fD,BD,lO,OO,oA],styles:[`[_nghost-%COMP%] { + display: flex; + flex-direction: column; + height: 100vh; + } + header[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 16px; + padding: 8px 16px; + background: #18181b; + border-bottom: 1px solid #27272a; + } + .brand[_ngcontent-%COMP%] { + margin: 0; + font-size: inherit; + display: flex; + align-items: center; + gap: 8px; + font-weight: 600; + color: var(--%NS%accent); + } + .brand[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { + color: var(--%NS%accent); + white-space: nowrap; + } + nav[_ngcontent-%COMP%] { + display: flex; + flex-wrap: wrap; + gap: 4px; + flex: 1; + min-width: 0; + } + @media (max-width: 640px) { + nav[_ngcontent-%COMP%] { + order: 3; + flex-basis: 100%; + } + } + nav[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { + padding: 6px 14px; + border: none; + border-radius: 6px; + background: transparent; + color: #a1a1aa; + cursor: pointer; + font-size: 13px; + transition: all 0.15s; + } + nav[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover { + background: #27272a; + color: #e4e4e7; + } + nav[_ngcontent-%COMP%] button.active[_ngcontent-%COMP%] { + background: #3f3f46; + color: #fff; + } + .status[_ngcontent-%COMP%] { + margin-left: auto; + font-size: 12px; + padding: 3px 10px; + border-radius: 99px; + background: #44403c; + color: #a8a29e; + } + .status.connected[_ngcontent-%COMP%] { + background: #14532d; + color: #4ade80; + } + main[_ngcontent-%COMP%] { + flex: 1; + overflow: auto; + padding: 16px; + }`]})};function _A(e){try{return new URL(e,location.href).origin===location.origin}catch{return!1}}function vA(){let e=new URLSearchParams(location.search).get(`baseURL`);if(e&&_A(e))return e;if(!location.pathname.includes(`__ng-devtools`))return`/__ng-devtools/`}Oy(gA).catch(console.error);export{jb as t}; \ No newline at end of file diff --git a/extension/ui/assets/index-DVDok6wK.js b/extension/ui/assets/index-DVDok6wK.js deleted file mode 100644 index 125e596..0000000 --- a/extension/ui/assets/index-DVDok6wK.js +++ /dev/null @@ -1,2059 +0,0 @@ -(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=Object.defineProperty,t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable,i=(t,n,r)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[n]=r,a=(e,a)=>{for(var o in a||={})n.call(a,o)&&i(e,o,a[o]);if(t)for(var o of t(a))r.call(a,o)&&i(e,o,a[o]);return e},o=(e,t,n)=>(i(e,typeof t==`symbol`?t:t+``,n),n),s=globalThis;function c(e){let t=s.__Zone_symbol_prefix;return(typeof t==`string`?t:`__zone_symbol__`)+e}function l(){let e=s.performance;function t(t){e&&e.mark&&e.mark(t)}function n(t,n){e&&e.measure&&e.measure(t,n)}t(`Zone`);let r=class e{constructor(e,t){o(this,`_parent`),o(this,`_name`),o(this,`_properties`),o(this,`_zoneDelegate`),this._parent=e,this._name=t?t.name||`unnamed`:``,this._properties=t&&t.properties||{},this._zoneDelegate=new l(this,this._parent&&this._parent._zoneDelegate,t)}static assertZonePatched(){if(s.Promise!==ae.ZoneAwarePromise)throw Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")}static get root(){let t=e.current;for(;t.parent;)t=t.parent;return t}static get current(){return se.zone}static get currentTask(){return ce}static __load_patch(r,i,a=!1){if(Object.hasOwn(ae,r)){let e=s[c(`forceDuplicateZoneCheck`)]===!0;if(!a&&e)throw Error(`Already loaded patch: `+r)}else if(!s[`__Zone_disable_`+r]){let a=`Zone:`+r;t(a),ae[r]=i(s,e,oe),n(a,a)}}get parent(){return this._parent}get name(){return this._name}get(e){let t=this.getZoneWith(e);if(t)return t._properties[e]}getZoneWith(e){let t=this;for(;t;){if(Object.hasOwn(t._properties,e))return t;t=t._parent}return null}fork(e){if(!e)throw Error(`ZoneSpec required!`);return this._zoneDelegate.fork(this,e)}wrap(e,t){if(typeof e!=`function`)throw Error(`Expecting function got: `+e);let n=this._zoneDelegate.intercept(this,e,t),r=this;return function(){return r.runGuarded(n,this,arguments,t)}}run(e,t,n,r){se={parent:se,zone:this};try{return this._zoneDelegate.invoke(this,e,t,n,r)}finally{se=se.parent}}runGuarded(e,t=null,n,r){se={parent:se,zone:this};try{try{return this._zoneDelegate.invoke(this,e,t,n,r)}catch(e){if(this._zoneDelegate.handleError(this,e))throw e}}finally{se=se.parent}}runTask(e,t,n){if(e.zone!=this)throw Error(`A task can only be run in the zone of creation! (Creation: `+(e.zone||ee).name+`; Execution: `+this.name+`)`);let r=e,{type:i,data:{isPeriodic:a=!1,isRefreshable:o=!1}={}}=e;if(e.state===te&&(i===T||i===ie))return;let s=e.state!=S;s&&r._transitionTo(S,x);let c=ce;ce=r,se={parent:se,zone:this};try{i==ie&&e.data&&!a&&!o&&(e.cancelFn=void 0);try{return this._zoneDelegate.invokeTask(this,r,t,n)}catch(e){if(this._zoneDelegate.handleError(this,e))throw e}}finally{let t=e.state;if(t!==te&&t!==re){if(i==T||a||o&&t===ne)s&&r._transitionTo(x,S,ne);else{let e=r._zoneDelegates;this._updateTaskCount(r,-1),s&&r._transitionTo(te,S,te),o&&(r._zoneDelegates=e)}}se=se.parent,ce=c}}scheduleTask(e){if(e.zone&&e.zone!==this){let t=this;for(;t;){if(t===e.zone)throw Error(`can not reschedule task to ${this.name} which is descendants of the original zone ${e.zone.name}`);t=t.parent}}e._transitionTo(ne,te);let t=[];e._zoneDelegates=t,e._zone=this;try{e=this._zoneDelegate.scheduleTask(this,e)}catch(t){throw e._transitionTo(re,ne,te),this._zoneDelegate.handleError(this,t),t}return e._zoneDelegates===t&&this._updateTaskCount(e,1),e.state==ne&&e._transitionTo(x,ne),e}scheduleMicroTask(e,t,n,r){return this.scheduleTask(new u(w,e,t,n,r,void 0))}scheduleMacroTask(e,t,n,r,i){return this.scheduleTask(new u(ie,e,t,n,r,i))}scheduleEventTask(e,t,n,r,i){return this.scheduleTask(new u(T,e,t,n,r,i))}cancelTask(e){if(e.zone!=this)throw Error(`A task can only be cancelled in the zone of creation! (Creation: `+(e.zone||ee).name+`; Execution: `+this.name+`)`);if(e.state===x||e.state===S){e._transitionTo(C,x,S);try{this._zoneDelegate.cancelTask(this,e)}catch(t){throw e._transitionTo(re,C),this._zoneDelegate.handleError(this,t),t}return this._updateTaskCount(e,-1),e._transitionTo(te,C),e.runCount=-1,e}}_updateTaskCount(e,t){let n=e._zoneDelegates;t==-1&&(e._zoneDelegates=null);for(let r=0;re.hasTask(n,r),onScheduleTask:(e,t,n,r)=>e.scheduleTask(n,r),onInvokeTask:(e,t,n,r,i,a)=>e.invokeTask(n,r,i,a),onCancelTask:(e,t,n,r)=>e.cancelTask(n,r)};class l{constructor(e,t,n){o(this,`_zone`),o(this,`_taskCounts`,{microTask:0,macroTask:0,eventTask:0}),o(this,`_forkDlgt`),o(this,`_forkZS`),o(this,`_forkCurrZone`),o(this,`_interceptDlgt`),o(this,`_interceptZS`),o(this,`_interceptCurrZone`),o(this,`_invokeDlgt`),o(this,`_invokeZS`),o(this,`_invokeCurrZone`),o(this,`_handleErrorDlgt`),o(this,`_handleErrorZS`),o(this,`_handleErrorCurrZone`),o(this,`_scheduleTaskDlgt`),o(this,`_scheduleTaskZS`),o(this,`_scheduleTaskCurrZone`),o(this,`_invokeTaskDlgt`),o(this,`_invokeTaskZS`),o(this,`_invokeTaskCurrZone`),o(this,`_cancelTaskDlgt`),o(this,`_cancelTaskZS`),o(this,`_cancelTaskCurrZone`),o(this,`_hasTaskDlgt`),o(this,`_hasTaskDlgtOwner`),o(this,`_hasTaskZS`),o(this,`_hasTaskCurrZone`),this._zone=e,this._forkZS=n&&(n&&n.onFork?n:t._forkZS),this._forkDlgt=n&&(n.onFork?t:t._forkDlgt),this._forkCurrZone=n&&(n.onFork?this._zone:t._forkCurrZone),this._interceptZS=n&&(n.onIntercept?n:t._interceptZS),this._interceptDlgt=n&&(n.onIntercept?t:t._interceptDlgt),this._interceptCurrZone=n&&(n.onIntercept?this._zone:t._interceptCurrZone),this._invokeZS=n&&(n.onInvoke?n:t._invokeZS),this._invokeDlgt=n&&(n.onInvoke?t:t._invokeDlgt),this._invokeCurrZone=n&&(n.onInvoke?this._zone:t._invokeCurrZone),this._handleErrorZS=n&&(n.onHandleError?n:t._handleErrorZS),this._handleErrorDlgt=n&&(n.onHandleError?t:t._handleErrorDlgt),this._handleErrorCurrZone=n&&(n.onHandleError?this._zone:t._handleErrorCurrZone),this._scheduleTaskZS=n&&(n.onScheduleTask?n:t._scheduleTaskZS),this._scheduleTaskDlgt=n&&(n.onScheduleTask?t:t._scheduleTaskDlgt),this._scheduleTaskCurrZone=n&&(n.onScheduleTask?this._zone:t._scheduleTaskCurrZone),this._invokeTaskZS=n&&(n.onInvokeTask?n:t._invokeTaskZS),this._invokeTaskDlgt=n&&(n.onInvokeTask?t:t._invokeTaskDlgt),this._invokeTaskCurrZone=n&&(n.onInvokeTask?this._zone:t._invokeTaskCurrZone),this._cancelTaskZS=n&&(n.onCancelTask?n:t._cancelTaskZS),this._cancelTaskDlgt=n&&(n.onCancelTask?t:t._cancelTaskDlgt),this._cancelTaskCurrZone=n&&(n.onCancelTask?this._zone:t._cancelTaskCurrZone),this._hasTaskZS=null,this._hasTaskDlgt=null,this._hasTaskDlgtOwner=null,this._hasTaskCurrZone=null;let r=n&&n.onHasTask,i=t&&t._hasTaskZS;(r||i)&&(this._hasTaskZS=r?n:a,this._hasTaskDlgt=t,this._hasTaskDlgtOwner=this,this._hasTaskCurrZone=this._zone,n.onScheduleTask||(this._scheduleTaskZS=a,this._scheduleTaskDlgt=t,this._scheduleTaskCurrZone=this._zone),n.onInvokeTask||(this._invokeTaskZS=a,this._invokeTaskDlgt=t,this._invokeTaskCurrZone=this._zone),n.onCancelTask||(this._cancelTaskZS=a,this._cancelTaskDlgt=t,this._cancelTaskCurrZone=this._zone))}get zone(){return this._zone}fork(e,t){return this._forkZS?this._forkZS.onFork(this._forkDlgt,this.zone,e,t):new i(e,t)}intercept(e,t,n){return this._interceptZS?this._interceptZS.onIntercept(this._interceptDlgt,this._interceptCurrZone,e,t,n):t}invoke(e,t,n,r,i){return this._invokeZS?this._invokeZS.onInvoke(this._invokeDlgt,this._invokeCurrZone,e,t,n,r,i):t.apply(n,r)}handleError(e,t){return!this._handleErrorZS||this._handleErrorZS.onHandleError(this._handleErrorDlgt,this._handleErrorCurrZone,e,t)}scheduleTask(e,t){let n=t;if(this._scheduleTaskZS)this._hasTaskZS&&n._zoneDelegates.push(this._hasTaskDlgtOwner),n=this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt,this._scheduleTaskCurrZone,e,t),n||=t;else if(t.scheduleFn)t.scheduleFn(t);else if(t.type==w)y(t);else throw Error(`Task is missing scheduleFn.`);return n}invokeTask(e,t,n,r){return this._invokeTaskZS?this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt,this._invokeTaskCurrZone,e,t,n,r):t.callback.apply(n,r)}cancelTask(e,t){let n;if(this._cancelTaskZS)n=this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt,this._cancelTaskCurrZone,e,t);else{if(!t.cancelFn)throw Error(`Task is not cancelable`);n=t.cancelFn(t)}return n}hasTask(e,t){try{this._hasTaskZS&&this._hasTaskZS.onHasTask(this._hasTaskDlgt,this._hasTaskCurrZone,e,t)}catch(t){this.handleError(e,t)}}_updateTaskCount(e,t){let n=this._taskCounts,r=n[e],i=n[e]=r+t;if(i<0)throw Error(`More tasks executed then were scheduled.`);if(r==0||i==0){let t={microTask:n.microTask>0,macroTask:n.macroTask>0,eventTask:n.eventTask>0,change:e};this.hasTask(this._zone,t)}}}class u{constructor(e,t,n,r,i,a){if(o(this,`type`),o(this,`source`),o(this,`invoke`),o(this,`callback`),o(this,`data`),o(this,`scheduleFn`),o(this,`cancelFn`),o(this,`_zone`,null),o(this,`runCount`,0),o(this,`_zoneDelegates`,null),o(this,`_state`,`notScheduled`),this.type=e,this.source=t,this.data=r,this.scheduleFn=i,this.cancelFn=a,!n)throw Error(`callback is not defined`);this.callback=n;let c=this;this.invoke=e===T&&r&&r.useG?u.invokeTask:function(){return u.invokeTask.call(s,c,this,arguments)}}static invokeTask(e,t,n){e||=this,le++;try{return e.runCount++,e.zone.runTask(e,t,n)}finally{try{le===1&&!s[m]&&b()}finally{le--}}}get zone(){return this._zone}get state(){return this._state}cancelScheduleRequest(){this._transitionTo(te,ne)}_transitionTo(e,t,n){if(this._state===t||this._state===n)this._state=e,e==te&&(this._zoneDelegates=null);else throw Error(`${this.type} '${this.source}': can not transition to '${e}', expecting state '${t}'${n?` or '`+n+`'`:``}, was '${this._state}'.`)}toString(){return this.data&&this.data.handleId!==void 0?this.data.handleId.toString():Object.prototype.toString.call(this)}toJSON(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,runCount:this.runCount}}}let d=c(`setTimeout`),f=c(`Promise`),p=c(`then`),m=c(`enable_native_microtask_draining`),h=[],g=!1,_;function v(e){!_&&s[f]&&(_=s[f].resolve(0)),_?(_[p]??_.then).call(_,e):s[d](e,0)}function y(e){let t=s[m],n=t&&h.length===0&&!g,r=!t&&le===0&&h.length===0;(n||r)&&v(b),e&&h.push(e)}function b(){if(!g){g=!0;try{for(;h.length;){let e=h;h=[];for(let t of e)try{t.zone.runTask(t,null,null)}catch(e){oe.onUnhandledError(e)}}}finally{if(s[m])g=!1,oe.microtaskDrainDone();else try{oe.microtaskDrainDone()}finally{g=!1}}}}let ee={name:`NO ZONE`},te=`notScheduled`,ne=`scheduling`,x=`scheduled`,S=`running`,C=`canceling`,re=`unknown`,w=`microTask`,ie=`macroTask`,T=`eventTask`,ae=Object.create(null),oe={symbol:c,currentZoneFrame:()=>se,onUnhandledError:ue,microtaskDrainDone:ue,scheduleMicroTask:y,showUncaughtError:()=>!i[c(`ignoreConsoleErrorUncaughtError`)],patchEventTarget:()=>[],patchOnProperties:ue,patchMethod:()=>ue,bindArguments:()=>[],patchThen:()=>ue,patchMacroTask:()=>ue,patchEventPrototype:()=>ue,getGlobalObjects:()=>void 0,ObjectDefineProperty:()=>ue,ObjectGetOwnPropertyDescriptor:()=>void 0,ObjectCreate:()=>void 0,ArraySlice:()=>[],patchClass:()=>ue,wrapWithCurrentZone:()=>ue,filterProperties:()=>[],attachOriginToPatched:()=>ue,_redefineProperty:()=>ue,patchCallbacks:()=>ue,nativeScheduleMicroTask:v},se={parent:null,zone:new i(null,null)},ce=null,le=0;function ue(){}return n(`Zone`,`Zone`),i}function u(){let e=globalThis,t=e[c(`forceDuplicateZoneCheck`)]===!0;if(e.Zone&&(t||typeof e.Zone.__symbol__!=`function`))throw Error(`Zone already loaded.`);return e.Zone??=l(),e.Zone}var d=Object.getOwnPropertyDescriptor,f=Object.defineProperty,p=Object.getPrototypeOf,m=Object.create,h=Array.prototype.slice,g=`addEventListener`,_=`removeEventListener`,v=c(g),y=c(_),b=`true`,ee=`false`,te=c(``);function ne(e,t){return Zone.current.wrap(e,t)}function x(e,t,n,r,i){return Zone.current.scheduleMacroTask(e,t,n,r,i)}var S=c,C=typeof window<`u`,re=C?window:void 0,w=C&&re||globalThis,ie=`removeAttribute`;function T(e,t){for(let n=e.length-1;n>=0;n--)typeof e[n]==`function`&&(e[n]=ne(e[n],t+`_`+n));return e}function ae(e,t){let n=e.constructor.name;for(let r=0;r{let t=function(){return e.apply(this,T(arguments,n+`.`+i))};return be(t,e),t})(a)}}}function oe(e){return e?e.writable===!1?!1:typeof e.get!=`function`||e.set!==void 0:!0}var se=typeof WorkerGlobalScope<`u`&&self instanceof WorkerGlobalScope,ce=!(`nw`in w)&&w.process!==void 0&&w.process.toString()===`[object process]`,le=!ce&&!se&&!!(C&&re.HTMLElement),ue=w.process!==void 0&&w.process.toString()===`[object process]`&&!se&&!!(C&&re.HTMLElement),de=Object.create(null),fe=S(`enable_beforeunload`),pe=function(e){if(e||=w.event,!e)return;let t=de[e.type];t||=de[e.type]=S(`ON_PROPERTY`+e.type);let n=this||e.target||w,r=n[t],i;if(le&&n===re&&e.type===`error`){let t=e;i=r&&r.call(this,t.message,t.filename,t.lineno,t.colno,t.error),i===!0&&e.preventDefault()}else i=r&&r.apply(this,arguments),e.type===`beforeunload`&&w[fe]&&typeof i==`string`?e.returnValue=i:i!=null&&!i&&e.preventDefault();return i};function me(e,t,n){let r=d(e,t);if(!r&&n&&d(n,t)&&(r={enumerable:!0,configurable:!0}),!r||!r.configurable)return;let i=S(`on`+t+`patched`);if(Object.hasOwn(e,i)&&e[i])return;delete r.writable,delete r.value;let a=r.get,o=r.set,s=t.slice(2),c=de[s];c||=de[s]=S(`ON_PROPERTY`+s),r.set=function(t){let n=this;!n&&e===w&&(n=w),n&&(typeof n[c]==`function`&&n.removeEventListener(s,pe),o?.call(n,null),n[c]=t,typeof t==`function`&&n.addEventListener(s,pe,!1))},r.get=function(){let n=this;if(!n&&e===w&&(n=w),!n)return null;let i=n[c];if(i)return i;if(a){let e=a.call(this);if(e)return r.set.call(this,e),typeof n[ie]==`function`&&n.removeAttribute(t),e}return null},f(e,t,r),e[i]=!0}function he(e,t,n){if(t)for(let r=0;rfunction(t,r){let a=n(t,r);return a.cbIdx>=0&&typeof r[a.cbIdx]==`function`?x(a.name,r[a.cbIdx],a,i):e.apply(t,r)})}function be(e,t){e[S(`OriginalDelegate`)]=t}function xe(e){return typeof e==`function`}function Se(e){return typeof e==`number`}var Ce={useG:!0},we=Object.create(null),Te={},Ee=RegExp(`^`+te+`(\\w+)(true|false)$`),De=S(`propagationStopped`),Oe=[`capture`,`once`,`passive`,`signal`];function ke(e,t){let n=(t?t(e):e)+ee,r=(t?t(e):e)+b,i=te+n,a=te+r;we[e]={[ee]:i,[b]:a}}function Ae(e,t,n,r){let i=r&&r.add||g,o=r&&r.rm||_,s=r&&r.listeners||`eventListeners`,c=r&&r.rmAll||`removeAllListeners`,l=S(i),u=`.`+i+`:`,d=function(e,t,n){if(e.isRemoved)return;let r=e.callback;typeof r==`object`&&r.handleEvent&&(e.callback=e=>r.handleEvent(e),e.originalDelegate=r);let i;try{e.invoke(e,t,[n])}catch(e){i=e}let a=e.options;if(a&&typeof a==`object`&&a.once){let r=e.originalDelegate?e.originalDelegate:e.callback;t[o].call(t,n.type,r,a)}return i};function f(n,r,i){if(r||=e.event,!r)return;let a=n||r.target||e,o=a[we[r.type][i?b:ee]];if(o){let e=[];if(o.length===1){let t=d(o[0],a,r);t&&e.push(t)}else{let t=o.slice();for(let n=0;n{throw r})}}}let m=function(e){return f(this,e,!1)},h=function(e){return f(this,e,!0)};function v(t,n){if(!t)return!1;let r=!0;n&&n.useG!==void 0&&(r=n.useG);let d=n&&n.vh,f=!0;n&&n.chkDup!==void 0&&(f=n.chkDup);let g=!1;n&&n.rt!==void 0&&(g=n.rt);let _=t;for(;_&&!Object.hasOwn(_,i);)_=p(_);if(!_&&t[i]&&(_=t),!_||_[l])return!1;let v=n&&n.eventNameToString,y={},ne=_[l]=_[i],x=_[S(o)]=_[o],C=_[S(s)]=_[s],re=_[S(c)]=_[c],w;n&&n.prepend&&(w=_[S(n.prepend)]=_[n.prepend]);function ie(e,t){return t?typeof e==`boolean`?{capture:e,passive:!0}:e?(typeof e==`object`&&e.passive!==!1&&(e.passive=!0),e):{passive:!0}:e}let T=function(e){if(!y.isExisting)return ne.call(y.target,y.eventName,y.capture?h:m,y.options)},ae=function(e){if(!e.isRemoved){let t=we[e.eventName],n;t&&(n=t[e.capture?b:ee]);let r=n&&e.target[n];if(r){for(let t=0;tle.zone.cancelTask(le);t.call(_,`abort`,e,{once:!0}),le.removeAbortListener=()=>_.removeEventListener(`abort`,e)}if(y.target=null,se&&(se.taskData=null),ne&&(y.options.once=!0),typeof le.options!=`boolean`&&(le.options=g),le.target=l,le.capture=te,le.eventName=u,m&&(le.originalDelegate=p),c?re.unshift(le):re.push(le),s)return l}};return _[i]=ge(ne,u,ue,de,g),w&&(_.prependListener=ge(w,`.prependListener:`,se,de,g,!0)),_[o]=function(){let t=this||e,r=arguments[0];n&&n.transferEventName&&(r=n.transferEventName(r));let i=arguments[2],a=i?typeof i==`boolean`||i.capture:!1,o=arguments[1];if(!o)return x.apply(this,arguments);if(d&&!d(x,o,t,arguments))return;let s=we[r],c;s&&(c=s[a?b:ee]);let l=c&&t[c];if(l)for(let e=0;efunction(t,n){t[De]=!0,e&&e.apply(t,n)})}function Ne(e,t){t.patchMethod(e,`queueMicrotask`,e=>function(e,t){Zone.current.scheduleMicroTask(`queueMicrotask`,t[0])})}var Pe=S(`zoneTask`);function Fe(e,t,n,r){let i=null,a=null;t+=r,n+=r;let o={};function s(t){let n=t.data;n.args[0]=function(){return t.invoke.apply(this,arguments)};let r=i.apply(e,n.args);return Se(r)?n.handleId=r:(n.handle=r,n.isRefreshable=xe(r?.refresh)),t}function c(t){let{handle:n,handleId:r}=t.data;return a.call(e,n??r)}i=ve(e,t,n=>function(i,a){if(xe(a[0])){let e={isRefreshable:!1,isPeriodic:r===`Interval`,delay:r===`Timeout`||r===`Interval`?a[1]||0:void 0,args:a},n=a[0];a[0]=function(){try{return n.apply(this,arguments)}finally{let{handle:t,handleId:n,isPeriodic:r,isRefreshable:i}=e;!r&&!i&&(n?delete o[n]:t&&(t[Pe]=null))}};let i=x(t,a[0],e,s,c);if(!i)return i;let{handleId:l,handle:u,isRefreshable:d,isPeriodic:f}=i.data;if(l)o[l]=i;else if(u&&(u[Pe]=i,d&&!f)){let e=u.refresh;u.refresh=function(){let{zone:t,state:n}=i;return n===`notScheduled`?(i._state=`scheduled`,t._updateTaskCount(i,1)):n===`running`&&(i._state=`scheduling`),e.call(this)}}return u??l??i}return n.apply(e,a)}),a=ve(e,n,t=>function(n,r){let i=r[0],a;Se(i)?(a=o[i],delete o[i]):(a=i?.[Pe],a?i[Pe]=null:a=i),a?.type?a.cancelFn&&a.zone.cancelTask(a):t.apply(e,r)})}function Ie(e,t){let{isBrowser:n,isMix:r}=t.getGlobalObjects();(n||r)&&e.customElements&&`customElements`in e&&t.patchCallbacks(t,e.customElements,`customElements`,`define`,[`connectedCallback`,`disconnectedCallback`,`adoptedCallback`,`attributeChangedCallback`,`formAssociatedCallback`,`formDisabledCallback`,`formResetCallback`,`formStateRestoreCallback`])}function Le(e,t){if(Zone[t.symbol(`patchEventTarget`)])return;let{eventNames:n,zoneSymbolEventNames:r,TRUE_STR:i,FALSE_STR:a,ZONE_SYMBOL_PREFIX:o}=t.getGlobalObjects();for(let e=0;et.target===e);if(r.length===0)return t;let i=r[0].ignoreProperties;return t.filter(e=>i.indexOf(e)===-1)}function Be(e,t,n,r){e&&he(e,ze(e,t,n),r)}function Ve(e){return Object.getOwnPropertyNames(e).filter(e=>e.startsWith(`on`)&&e.length>2).map(e=>e.substring(2))}function He(e,t){if(ce&&!ue||Zone[e.symbol(`patchEvents`)])return;let n=t.__Zone_ignore_on_properties,r=[];if(le){let e=window;r=r.concat([`Document`,`SVGElement`,`Element`,`HTMLElement`,`HTMLBodyElement`,`HTMLMediaElement`,`HTMLFrameSetElement`,`HTMLFrameElement`,`HTMLIFrameElement`,`HTMLMarqueeElement`,`Worker`]),Be(e,Ve(e),n,p(e))}r=r.concat([`XMLHttpRequest`,`XMLHttpRequestEventTarget`,`IDBIndex`,`IDBRequest`,`IDBOpenDBRequest`,`IDBDatabase`,`IDBTransaction`,`IDBCursor`,`WebSocket`]);for(let e=0;e{let t=`clear`;Fe(e,`set`,t,`Timeout`),Fe(e,`set`,t,`Interval`),Fe(e,`set`,t,`Immediate`)}),e.__load_patch(`requestAnimationFrame`,e=>{Fe(e,`request`,`cancel`,`AnimationFrame`),Fe(e,`mozRequest`,`mozCancel`,`AnimationFrame`),Fe(e,`webkitRequest`,`webkitCancel`,`AnimationFrame`)}),e.__load_patch(`blocking`,(e,t)=>{let n=[`alert`,`prompt`,`confirm`];for(let r=0;rfunction(r,a){return t.current.run(n,e,a,i)})}}),e.__load_patch(`EventTarget`,(e,t,n)=>{Re(e,n),Le(e,n);let r=e.XMLHttpRequestEventTarget;r&&r.prototype&&n.patchEventTarget(e,n,[r.prototype])}),e.__load_patch(`MutationObserver`,(e,t,n)=>{_e(`MutationObserver`),_e(`WebKitMutationObserver`)}),e.__load_patch(`IntersectionObserver`,(e,t,n)=>{_e(`IntersectionObserver`)}),e.__load_patch(`FileReader`,(e,t,n)=>{_e(`FileReader`)}),e.__load_patch(`on_property`,(e,t,n)=>{He(n,e)}),e.__load_patch(`customElements`,(e,t,n)=>{Ie(e,n)}),e.__load_patch(`XHR`,(e,t)=>{c(e);let n=S(`xhrTask`),r=S(`xhrSync`),i=S(`xhrListener`),a=S(`xhrScheduled`),o=S(`xhrURL`),s=S(`xhrErrorBeforeScheduled`);function c(e){let c=e.XMLHttpRequest;if(!c)return;let l=c.prototype;function u(e){return e[n]}let d=l[v],f=l[y];if(!d){let t=e.XMLHttpRequestEventTarget;if(t){let e=t.prototype;d=e[v],f=e[y]}}let p=`readystatechange`,m=`scheduled`;function h(e){let r=e.data,o=r.target;o[a]=!1,o[s]=!1;let c=o[i];d||(d=o[v],f=o[y]),c&&f.call(o,p,c);let l=o[i]=()=>{if(o.readyState===o.DONE){if(!r.aborted&&o[a]&&e.state===m){let n=o[t.__symbol__(`loadfalse`)];if(o.status!==0&&n&&n.length>0){let i=e.invoke;e.invoke=function(){let n=o[t.__symbol__(`loadfalse`)];for(let t=0;tfunction(e,t){return e[r]=t[2]==0,e[o]=t[1],b.apply(e,t)}),ee=S(`fetchTaskAborting`),te=S(`fetchTaskScheduling`),ne=ve(l,`send`,()=>function(e,n){if(t.current[te]===!0||e[r])return ne.apply(e,n);{let t={target:e,url:e[o],isPeriodic:!1,args:n,aborted:!1},r=x(`XMLHttpRequest.send`,g,t,h,_);e&&e[s]===!0&&!t.aborted&&r.state===m&&r.invoke()}}),C=ve(l,`abort`,()=>function(e,n){let r=u(e);if(r&&typeof r.type==`string`){if(r.cancelFn==null||r.data&&r.data.aborted)return;r.zone.cancelTask(r)}else if(t.current[ee]===!0)return C.apply(e,n)})}}),e.__load_patch(`geolocation`,e=>{e.navigator&&e.navigator.geolocation&&ae(e.navigator.geolocation,[`getCurrentPosition`,`watchPosition`])}),e.__load_patch(`PromiseRejectionEvent`,(e,t)=>{function n(t){return function(n){je(e,t).forEach(r=>{let i=e.PromiseRejectionEvent;if(i){let e=new i(t,{promise:n.promise,reason:n.rejection});r.invoke(e)}})}}e.PromiseRejectionEvent&&(t[S(`unhandledPromiseRejectionHandler`)]=n(`unhandledrejection`),t[S(`rejectionHandledHandler`)]=n(`rejectionhandled`))}),e.__load_patch(`queueMicrotask`,(e,t,n)=>{Ne(e,n)})}function We(e){e.__load_patch(`ZoneAwarePromise`,(e,t,n)=>{let r=Object.getOwnPropertyDescriptor,i=Object.defineProperty;function a(e){return e&&e.toString===Object.prototype.toString?(e.constructor&&e.constructor.name||``)+`: `+JSON.stringify(e):e?e.toString():Object.prototype.toString.call(e)}let o=n.symbol,s=[],c=e[o(`DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION`)]!==!1,l=o(`Promise`),u=o(`then`);n.onUnhandledError=e=>{if(n.showUncaughtError()){let t=e&&e.rejection;t&&e.zone&&e.task?console.error(`Unhandled Promise rejection:`,t instanceof Error?t.message:t,`; Zone:`,e.zone.name,`; Task:`,e.task&&e.task.source,`; Value:`,t,t instanceof Error?t.stack:void 0):console.error(e)}},n.microtaskDrainDone=()=>{for(;s.length;){let e=s.shift();try{e.zone.runGuarded(()=>{throw e.throwOriginal?e.rejection:e})}catch(e){f(e)}}};let d=o(`unhandledPromiseRejectionHandler`);function f(e){n.onUnhandledError(e);try{let n=t[d];typeof n==`function`&&n.call(this,e)}catch{}}function p(e){return e&&typeof e.then==`function`}function m(e){return e}function h(e){return T.reject(e)}let g=o(`state`),_=o(`value`),v=o(`finally`),y=o(`parentPromiseValue`),b=o(`parentPromiseState`);function ee(e,t){return n=>{try{x(e,t,n)}catch(t){x(e,!1,t)}}}let te=function(){let e=!1;return function(t){return function(){e||(e=!0,t.apply(null,arguments))}}},ne=o(`currentTaskTrace`);function x(e,r,o){let l=te();if(e===o)throw TypeError(`Promise resolved with itself`);if(e[g]===null){let u=null;try{(typeof o==`object`||typeof o==`function`)&&(u=o&&o.then)}catch(t){return l(()=>{x(e,!1,t)})(),e}if(r!==!1&&o instanceof T&&Object.hasOwn(o,g)&&Object.hasOwn(o,_)&&o[g]!==null)C(o),x(e,o[g],o[_]);else if(r!==!1&&typeof u==`function`)try{u.call(o,l(ee(e,r)),l(ee(e,!1)))}catch(t){l(()=>{x(e,!1,t)})()}else{e[g]=r;let l=e[_];if(e[_]=o,e[v]===v&&r===!0&&(e[g]=e[b],e[_]=e[y]),r===!1&&o instanceof Error){let e=t.currentTask&&t.currentTask.data&&t.currentTask.data.__creationTrace__;e&&i(o,ne,{configurable:!0,enumerable:!1,writable:!0,value:e})}for(let t=0;t{try{let r=e[_],i=!!n&&v===n[v];i&&(n[y]=r,n[b]=a),x(n,!0,t.run(o,void 0,i&&o!==h&&o!==m?[]:[r]))}catch(e){x(n,!1,e)}},n)}let w=function(){},ie=e.AggregateError;class T{static toString(){return`function ZoneAwarePromise() { [native code] }`}static resolve(e){return e instanceof T?e:x(new this(null),!0,e)}static reject(e){return x(new this(null),!1,e)}static withResolvers(){let e={};return e.promise=new T((t,n)=>{e.resolve=t,e.reject=n}),e}static any(e){if(!e||typeof e[Symbol.iterator]!=`function`)return Promise.reject(new ie([],`All promises were rejected`));let t=[],n=0;try{for(let r of e)n++,t.push(T.resolve(r))}catch{return Promise.reject(new ie([],`All promises were rejected`))}if(n===0)return Promise.reject(new ie([],`All promises were rejected`));let r=!1,i=[];return new T((e,a)=>{for(let o=0;o{r||(r=!0,e(t))},e=>{i.push(e),n--,n===0&&(r=!0,a(new ie(i,`All promises were rejected`)))})})}static race(e){let t,n,r=new this((e,r)=>{t=e,n=r});function i(e){t(e)}function a(e){n(e)}for(let t of e)p(t)||(t=this.resolve(t)),t.then(i,a);return r}static all(e){return T.allWithCallback(e)}static allSettled(e){return(this&&this.prototype instanceof T?this:T).allWithCallback(e,{thenCallback:e=>({status:`fulfilled`,value:e}),errorCallback:e=>({status:`rejected`,reason:e})})}static allWithCallback(e,t){let n,r,i=new this((e,t)=>{n=e,r=t}),a=2,o=0,s=[];for(let i of e){p(i)||(i=this.resolve(i));let e=o;try{i.then(r=>{s[e]=t?t.thenCallback(r):r,a--,a===0&&n(s)},i=>{t?(s[e]=t.errorCallback(i),a--,a===0&&n(s)):r(i)})}catch(e){r(e)}a++,o++}return a-=2,a===0&&n(s),i}constructor(e){let t=this;if(!(t instanceof T))throw Error(`Must be an instanceof Promise.`);t[g]=null,t[_]=[];try{let n=te();e&&e(n(ee(t,!0)),n(ee(t,!1)))}catch(e){x(t,!1,e)}}get[Symbol.toStringTag](){return`Promise`}get[Symbol.species](){return T}then(e,n){let r=this.constructor?.[Symbol.species];(!r||typeof r!=`function`)&&(r=this.constructor||T);let i=new r(w),a=t.current;return this[g]==null?this[_].push(a,i,e,n):re(this,a,i,e,n),i}catch(e){return this.then(null,e)}finally(e){let n=this.constructor?.[Symbol.species];(!n||typeof n!=`function`)&&(n=T);let r=new n(w);r[v]=v;let i=t.current;return this[g]==null?this[_].push(i,r,e,e):re(this,i,r,e,e),r}}T.resolve=T.resolve,T.reject=T.reject,T.race=T.race,T.all=T.all;let ae=e[l]=e.Promise;e.Promise=T;let oe=o(`thenPatched`);function se(e){let t=e.prototype,n=r(t,`then`);if(n&&(n.writable===!1||!n.configurable))return;let i=t.then;t[u]=i,e.prototype.then=function(e,t){return new T((e,t)=>{i.call(this,e,t)}).then(e,t)},e[oe]=!0}n.patchThen=se;function ce(e){return function(t,n){let r=e.apply(t,n);if(r instanceof T)return r;let i=r.constructor;return i[oe]||se(i),r}}if(ae){se(ae);let t=ae.try;t&&typeof t==`function`&&(T.try=t),ve(e,`fetch`,e=>ce(e))}return Promise[t.__symbol__(`uncaughtPromiseErrors`)]=s,T})}function Ge(e){e.__load_patch(`toString`,e=>{let t=Function.prototype.toString,n=S(`OriginalDelegate`),r=S(`Promise`),i=S(`Error`),a=function(){if(typeof this==`function`){let a=this[n];if(a)return typeof a==`function`?t.call(a):Object.prototype.toString.call(a);if(this===Promise){let n=e[r];if(n)return t.call(n)}if(this===Error){let n=e[i];if(n)return t.call(n)}}return t.call(this)};a[n]=t,Function.prototype.toString=a;let o=Object.prototype.toString;Object.prototype.toString=function(){return typeof Promise==`function`&&this instanceof Promise?`[object Promise]`:o.call(this)}})}function Ke(e,t,n,r,i){let a=Zone.__symbol__(r);if(t[a])return;let o=t[a]=t[r];t[r]=function(a,s,c){return s&&s.prototype&&i.forEach(function(t){let i=`${n}.${r}::`+t,a=s.prototype;try{if(Object.hasOwn(a,t)){let n=e.ObjectGetOwnPropertyDescriptor(a,t);n&&n.value?(n.value=e.wrapWithCurrentZone(n.value,i),e._redefineProperty(s.prototype,t,n)):a[t]&&(a[t]=e.wrapWithCurrentZone(a[t],i))}else a[t]&&(a[t]=e.wrapWithCurrentZone(a[t],i))}catch{}}),o.call(t,a,s,c)},e.attachOriginToPatched(t[r],o)}function qe(e){e.__load_patch(`util`,(e,t,n)=>{let r=Ve(e);n.patchOnProperties=he,n.patchMethod=ve,n.bindArguments=T,n.patchMacroTask=ye;let i=t.__symbol__(`BLACK_LISTED_EVENTS`),a=t.__symbol__(`UNPATCHED_EVENTS`);e[a]&&(e[i]=e[a]),e[i]&&(t[i]=t[a]=e[i]),n.patchEventPrototype=Me,n.patchEventTarget=Ae,n.ObjectDefineProperty=f,n.ObjectGetOwnPropertyDescriptor=d,n.ObjectCreate=m,n.ArraySlice=h,n.patchClass=_e,n.wrapWithCurrentZone=ne,n.filterProperties=ze,n.attachOriginToPatched=be,n._redefineProperty=Object.defineProperty,n.patchCallbacks=Ke,n.getGlobalObjects=()=>({globalSources:Te,zoneSymbolEventNames:we,eventNames:r,isBrowser:le,isMix:ue,isNode:ce,TRUE_STR:b,FALSE_STR:ee,ZONE_SYMBOL_PREFIX:te,ADD_EVENT_LISTENER_STR:g,REMOVE_EVENT_LISTENER_STR:_})})}function Je(e){We(e),Ge(e),qe(e)}var Ye=u();Je(Ye),Ue(Ye);var Xe=(function(e){return e[e.NONE=0]=`NONE`,e[e.HTML=1]=`HTML`,e[e.STYLE=2]=`STYLE`,e[e.SCRIPT=3]=`SCRIPT`,e[e.URL=4]=`URL`,e[e.RESOURCE_URL=5]=`RESOURCE_URL`,e[e.ATTRIBUTE_NO_BINDING=6]=`ATTRIBUTE_NO_BINDING`,e})(Xe||{}),Ze=(function(e){return e[e.None=0]=`None`,e[e.Const=1]=`Const`,e})(Ze||{}),Qe=class{modifiers;constructor(e=Ze.None){this.modifiers=e}hasModifier(e){return(this.modifiers&e)!==0}},$e=(function(e){return e[e.Dynamic=0]=`Dynamic`,e[e.Bool=1]=`Bool`,e[e.String=2]=`String`,e[e.Int=3]=`Int`,e[e.Number=4]=`Number`,e[e.Function=5]=`Function`,e[e.Inferred=6]=`Inferred`,e[e.None=7]=`None`,e})($e||{}),et=class extends Qe{name;constructor(e,t){super(t),this.name=e}visitType(e,t){return e.visitBuiltinType(this,t)}};$e.Dynamic;var tt=new et($e.Inferred);$e.Bool,$e.Int,$e.Number,$e.String,$e.Function,$e.None;var E=(function(e){return e[e.Equals=0]=`Equals`,e[e.NotEquals=1]=`NotEquals`,e[e.Assign=2]=`Assign`,e[e.Identical=3]=`Identical`,e[e.NotIdentical=4]=`NotIdentical`,e[e.Minus=5]=`Minus`,e[e.Plus=6]=`Plus`,e[e.Divide=7]=`Divide`,e[e.Multiply=8]=`Multiply`,e[e.Modulo=9]=`Modulo`,e[e.And=10]=`And`,e[e.Or=11]=`Or`,e[e.BitwiseOr=12]=`BitwiseOr`,e[e.BitwiseAnd=13]=`BitwiseAnd`,e[e.Lower=14]=`Lower`,e[e.LowerEquals=15]=`LowerEquals`,e[e.Bigger=16]=`Bigger`,e[e.BiggerEquals=17]=`BiggerEquals`,e[e.NullishCoalesce=18]=`NullishCoalesce`,e[e.Exponentiation=19]=`Exponentiation`,e[e.In=20]=`In`,e[e.InstanceOf=21]=`InstanceOf`,e[e.AdditionAssignment=22]=`AdditionAssignment`,e[e.SubtractionAssignment=23]=`SubtractionAssignment`,e[e.MultiplicationAssignment=24]=`MultiplicationAssignment`,e[e.DivisionAssignment=25]=`DivisionAssignment`,e[e.RemainderAssignment=26]=`RemainderAssignment`,e[e.ExponentiationAssignment=27]=`ExponentiationAssignment`,e[e.AndAssignment=28]=`AndAssignment`,e[e.OrAssignment=29]=`OrAssignment`,e[e.NullishCoalesceAssignment=30]=`NullishCoalesceAssignment`,e})(E||{});function nt(e,t){return e==null||t==null?e==t:e.isEquivalent(t)}function rt(e,t,n){let r=e.length;if(r!==t.length)return!1;for(let i=0;ie.isEquivalent(t))}var at=class{leadingComments;type;sourceSpan;constructor(e,t,n){this.leadingComments=n,this.type=e||null,this.sourceSpan=t||null}prop(e,t){return new ht(this,e,null,t)}key(e,t,n){return new gt(this,e,t,n)}callFn(e,t,n,r){return new ct(this,e,null,t,n,r)}instantiate(e,t,n,r){return new lt(this,e,t,n)}conditional(e,t=null,n,r){return new pt(this,e,t,null,n)}equals(e,t){return new mt(E.Equals,this,e,null,t)}notEquals(e,t){return new mt(E.NotEquals,this,e,null,t)}identical(e,t){return new mt(E.Identical,this,e,null,t)}notIdentical(e,t){return new mt(E.NotIdentical,this,e,null,t)}minus(e,t){return new mt(E.Minus,this,e,null,t)}plus(e,t){return new mt(E.Plus,this,e,null,t)}divide(e,t){return new mt(E.Divide,this,e,null,t)}multiply(e,t){return new mt(E.Multiply,this,e,null,t)}modulo(e,t){return new mt(E.Modulo,this,e,null,t)}power(e,t){return new mt(E.Exponentiation,this,e,null,t)}and(e,t){return new mt(E.And,this,e,null,t)}bitwiseOr(e,t){return new mt(E.BitwiseOr,this,e,null,t)}bitwiseAnd(e,t){return new mt(E.BitwiseAnd,this,e,null,t)}or(e,t){return new mt(E.Or,this,e,null,t)}lower(e,t){return new mt(E.Lower,this,e,null,t)}lowerEquals(e,t){return new mt(E.LowerEquals,this,e,null,t)}bigger(e,t){return new mt(E.Bigger,this,e,null,t)}biggerEquals(e,t){return new mt(E.BiggerEquals,this,e,null,t)}isBlank(e){return this.equals(xt,e)}nullishCoalesce(e,t){return new mt(E.NullishCoalesce,this,e,null,t)}toStmt(e){return new wt(this,null,e)}},ot=class e extends at{name;constructor(e,t,n,r){super(t,n,r),this.name=e}isEquivalent(t){return t instanceof e&&this.name===t.name}isConstant(){return!1}visitExpression(e,t){return e.visitReadVarExpr(this,t)}clone(){return new e(this.name,this.type,this.sourceSpan)}set(e){return new mt(E.Assign,this,e,null,this.sourceSpan)}},st=class e extends at{expr;constructor(e,t,n,r){super(t,n,r),this.expr=e}visitExpression(e,t){return e.visitTypeofExpr(this,t)}isEquivalent(t){return t instanceof e&&t.expr.isEquivalent(this.expr)}isConstant(){return this.expr.isConstant()}clone(){return new e(this.expr.clone())}},ct=class e extends at{fn;args;pure;isOptional;constructor(e,t,n,r,i=!1,a,o=!1){super(n,r,a),this.fn=e,this.args=t,this.pure=i,this.isOptional=o}get receiver(){return this.fn}isEquivalent(t){return t instanceof e&&this.fn.isEquivalent(t.fn)&&it(this.args,t.args)&&this.pure===t.pure}isConstant(){return!1}visitExpression(e,t){return e.visitInvokeFunctionExpr(this,t)}clone(){return new e(this.fn.clone(),this.args.map(e=>e.clone()),this.type,this.sourceSpan,this.pure,[],this.isOptional)}},lt=class e extends at{classExpr;args;constructor(e,t,n,r,i){super(n,r,i),this.classExpr=e,this.args=t}isEquivalent(t){return t instanceof e&&this.classExpr.isEquivalent(t.classExpr)&&it(this.args,t.args)}isConstant(){return!1}visitExpression(e,t){return e.visitInstantiateExpr(this,t)}clone(){return new e(this.classExpr.clone(),this.args.map(e=>e.clone()),this.type,this.sourceSpan)}},ut=class e extends at{body;flags;constructor(e,t,n,r){super(null,n,r),this.body=e,this.flags=t}isEquivalent(t){return t instanceof e&&this.body===t.body&&this.flags===t.flags}isConstant(){return!0}visitExpression(e,t){return e.visitRegularExpressionLiteral(this,t)}clone(){return new e(this.body,this.flags,this.sourceSpan)}},dt=class e extends at{value;constructor(e,t,n,r){super(t,n,r),this.value=e}isEquivalent(t){return t instanceof e&&this.value===t.value}isConstant(){return!0}visitExpression(e,t){return e.visitLiteralExpr(this,t)}clone(){return new e(this.value,this.type,this.sourceSpan)}},ft=class e extends at{value;typeParams;constructor(e,t,n=null,r,i){super(t,r,i),this.value=e,this.typeParams=n}isEquivalent(t){return t instanceof e&&this.value.name===t.value.name&&this.value.moduleName===t.value.moduleName}isConstant(){return!1}visitExpression(e,t){return e.visitExternalExpr(this,t)}clone(){return new e(this.value,this.type,this.typeParams,this.sourceSpan)}},pt=class e extends at{condition;falseCase;trueCase;constructor(e,t,n=null,r,i,a){super(r||t.type,i,a),this.condition=e,this.falseCase=n,this.trueCase=t}isEquivalent(t){return t instanceof e&&this.condition.isEquivalent(t.condition)&&this.trueCase.isEquivalent(t.trueCase)&&nt(this.falseCase,t.falseCase)}isConstant(){return!1}visitExpression(e,t){return e.visitConditionalExpr(this,t)}clone(){return new e(this.condition.clone(),this.trueCase.clone(),this.falseCase?.clone(),this.type,this.sourceSpan)}},mt=class e extends at{operator;rhs;lhs;constructor(e,t,n,r,i,a){super(r||t.type,i,a),this.operator=e,this.rhs=n,this.lhs=t}isEquivalent(t){return t instanceof e&&this.operator===t.operator&&this.lhs.isEquivalent(t.lhs)&&this.rhs.isEquivalent(t.rhs)}isConstant(){return!1}visitExpression(e,t){return e.visitBinaryOperatorExpr(this,t)}clone(){return new e(this.operator,this.lhs.clone(),this.rhs.clone(),this.type,this.sourceSpan)}isAssignment(){let e=this.operator;return e===E.Assign||e===E.AdditionAssignment||e===E.SubtractionAssignment||e===E.MultiplicationAssignment||e===E.DivisionAssignment||e===E.RemainderAssignment||e===E.ExponentiationAssignment||e===E.AndAssignment||e===E.OrAssignment||e===E.NullishCoalesceAssignment}},ht=class e extends at{receiver;name;isOptional;constructor(e,t,n,r,i,a=!1){super(n,r,i),this.receiver=e,this.name=t,this.isOptional=a}get index(){return this.name}isEquivalent(t){return t instanceof e&&this.receiver.isEquivalent(t.receiver)&&this.name===t.name&&this.isOptional===t.isOptional}isConstant(){return!1}visitExpression(e,t){return e.visitReadPropExpr(this,t)}set(e){return new mt(E.Assign,this.receiver.prop(this.name),e,null,this.sourceSpan)}clone(){return new e(this.receiver.clone(),this.name,this.type,this.sourceSpan,[],this.isOptional)}},gt=class e extends at{receiver;index;isOptional;constructor(e,t,n,r,i,a=!1){super(n,r,i),this.receiver=e,this.index=t,this.isOptional=a}isEquivalent(t){return t instanceof e&&this.receiver.isEquivalent(t.receiver)&&this.index.isEquivalent(t.index)&&this.isOptional===t.isOptional}isConstant(){return!1}visitExpression(e,t){return e.visitReadKeyExpr(this,t)}set(e){return new mt(E.Assign,this.receiver.key(this.index),e,null,this.sourceSpan)}clone(){return new e(this.receiver.clone(),this.index.clone(),this.type,this.sourceSpan,[],this.isOptional)}},_t=class e extends at{entries;constructor(e,t,n,r){super(t,n,r),this.entries=e}isConstant(){return this.entries.every(e=>e.isConstant())}isEquivalent(t){return t instanceof e&&it(this.entries,t.entries)}visitExpression(e,t){return e.visitLiteralArrayExpr(this,t)}clone(){return new e(this.entries.map(e=>e.clone()),this.type,this.sourceSpan)}},vt=class e{expression;constructor(e){this.expression=e}isEquivalent(t){return t instanceof e&&this.expression.isEquivalent(t.expression)}clone(){return new e(this.expression.clone())}isConstant(){return this.expression.isConstant()}},yt=class e extends at{entries;valueType=null;constructor(e,t,n,r){super(t,n,r),this.entries=e,t&&(this.valueType=t.valueType)}isEquivalent(t){return t instanceof e&&it(this.entries,t.entries)}isConstant(){return this.entries.every(e=>e.isConstant())}visitExpression(e,t){return e.visitLiteralMapExpr(this,t)}clone(){let t=this.entries.map(e=>e.clone());return new e(t,this.type,this.sourceSpan)}},bt=class e extends at{expression;constructor(e,t,n){super(null,t,n),this.expression=e}isEquivalent(t){return t instanceof e&&this.expression.isEquivalent(t.expression)}isConstant(){return this.expression.isConstant()}visitExpression(e,t){return e.visitSpreadElementExpr(this,t)}clone(){return new e(this.expression.clone(),this.sourceSpan)}},xt=new dt(null,tt,null),St=(function(e){return e[e.None=0]=`None`,e[e.Final=1]=`Final`,e[e.Private=2]=`Private`,e[e.Exported=4]=`Exported`,e[e.Static=8]=`Static`,e})(St||{}),Ct=class{modifiers;sourceSpan;leadingComments;constructor(e=St.None,t=null,n){this.modifiers=e,this.sourceSpan=t,this.leadingComments=n}hasModifier(e){return(this.modifiers&e)!==0}addLeadingComment(e){this.leadingComments=this.leadingComments??[],this.leadingComments.push(e)}},wt=class e extends Ct{expr;constructor(e,t,n){super(St.None,t,n),this.expr=e}isEquivalent(t){return t instanceof e&&this.expr.isEquivalent(t.expr)}visitStatement(e,t){return e.visitExpressionStmt(this,t)}};(class e{static INSTANCE=new e;keyOf(e){if(e instanceof dt&&typeof e.value==`string`)return`"${e.value}"`;if(e instanceof dt)return String(e.value);if(e instanceof ut)return`/${e.body}/${e.flags??``}`;if(e instanceof _t){let t=[];for(let n of e.entries)t.push(this.keyOf(n));return`[${t.join(`,`)}]`}if(e instanceof yt){let t=[];for(let n of e.entries)if(n instanceof vt)t.push(`...`+this.keyOf(n.expression));else{let e=n.key;n.quoted&&(e=`"${e}"`),t.push(e+`:`+this.keyOf(n.value))}return`{${t.join(`,`)}}`}if(e instanceof ft)return`import("${e.value.moduleName}", ${e.value.name})`;if(e instanceof ot)return`read(${e.name})`;if(e instanceof st)return`typeof(${this.keyOf(e.expr)})`;if(e instanceof bt)return`...${this.keyOf(e.expression)}`;throw Error(`${this.constructor.name} does not handle expressions of type ${e.constructor.name}`)}});var D=`@angular/core`,O=(()=>{class e{static core={name:null,moduleName:D};static namespaceHTML={name:`ɵɵnamespaceHTML`,moduleName:D};static namespaceMathML={name:`ɵɵnamespaceMathML`,moduleName:D};static namespaceSVG={name:`ɵɵnamespaceSVG`,moduleName:D};static element={name:`ɵɵelement`,moduleName:D};static elementStart={name:`ɵɵelementStart`,moduleName:D};static elementEnd={name:`ɵɵelementEnd`,moduleName:D};static foreignComponent={name:`ɵɵforeignComponent`,moduleName:D};static foreignContent={name:`ɵɵforeignContent`,moduleName:D};static foreignContentFn={name:`ɵɵforeignContentFn`,moduleName:D};static domElement={name:`ɵɵdomElement`,moduleName:D};static domElementStart={name:`ɵɵdomElementStart`,moduleName:D};static domElementEnd={name:`ɵɵdomElementEnd`,moduleName:D};static domElementContainer={name:`ɵɵdomElementContainer`,moduleName:D};static domElementContainerStart={name:`ɵɵdomElementContainerStart`,moduleName:D};static domElementContainerEnd={name:`ɵɵdomElementContainerEnd`,moduleName:D};static domTemplate={name:`ɵɵdomTemplate`,moduleName:D};static domListener={name:`ɵɵdomListener`,moduleName:D};static advance={name:`ɵɵadvance`,moduleName:D};static syntheticHostProperty={name:`ɵɵsyntheticHostProperty`,moduleName:D};static syntheticHostListener={name:`ɵɵsyntheticHostListener`,moduleName:D};static attribute={name:`ɵɵattribute`,moduleName:D};static classProp={name:`ɵɵclassProp`,moduleName:D};static elementContainerStart={name:`ɵɵelementContainerStart`,moduleName:D};static elementContainerEnd={name:`ɵɵelementContainerEnd`,moduleName:D};static elementContainer={name:`ɵɵelementContainer`,moduleName:D};static styleMap={name:`ɵɵstyleMap`,moduleName:D};static classMap={name:`ɵɵclassMap`,moduleName:D};static styleProp={name:`ɵɵstyleProp`,moduleName:D};static interpolate={name:`ɵɵinterpolate`,moduleName:D};static interpolate1={name:`ɵɵinterpolate1`,moduleName:D};static interpolate2={name:`ɵɵinterpolate2`,moduleName:D};static interpolate3={name:`ɵɵinterpolate3`,moduleName:D};static interpolate4={name:`ɵɵinterpolate4`,moduleName:D};static interpolate5={name:`ɵɵinterpolate5`,moduleName:D};static interpolate6={name:`ɵɵinterpolate6`,moduleName:D};static interpolate7={name:`ɵɵinterpolate7`,moduleName:D};static interpolate8={name:`ɵɵinterpolate8`,moduleName:D};static interpolateV={name:`ɵɵinterpolateV`,moduleName:D};static nextContext={name:`ɵɵnextContext`,moduleName:D};static resetView={name:`ɵɵresetView`,moduleName:D};static templateCreate={name:`ɵɵtemplate`,moduleName:D};static defer={name:`ɵɵdefer`,moduleName:D};static deferWhen={name:`ɵɵdeferWhen`,moduleName:D};static deferOnIdle={name:`ɵɵdeferOnIdle`,moduleName:D};static deferOnImmediate={name:`ɵɵdeferOnImmediate`,moduleName:D};static deferOnTimer={name:`ɵɵdeferOnTimer`,moduleName:D};static deferOnHover={name:`ɵɵdeferOnHover`,moduleName:D};static deferOnInteraction={name:`ɵɵdeferOnInteraction`,moduleName:D};static deferOnViewport={name:`ɵɵdeferOnViewport`,moduleName:D};static deferPrefetchWhen={name:`ɵɵdeferPrefetchWhen`,moduleName:D};static deferPrefetchOnIdle={name:`ɵɵdeferPrefetchOnIdle`,moduleName:D};static deferPrefetchOnImmediate={name:`ɵɵdeferPrefetchOnImmediate`,moduleName:D};static deferPrefetchOnTimer={name:`ɵɵdeferPrefetchOnTimer`,moduleName:D};static deferPrefetchOnHover={name:`ɵɵdeferPrefetchOnHover`,moduleName:D};static deferPrefetchOnInteraction={name:`ɵɵdeferPrefetchOnInteraction`,moduleName:D};static deferPrefetchOnViewport={name:`ɵɵdeferPrefetchOnViewport`,moduleName:D};static deferHydrateWhen={name:`ɵɵdeferHydrateWhen`,moduleName:D};static deferHydrateNever={name:`ɵɵdeferHydrateNever`,moduleName:D};static deferHydrateOnIdle={name:`ɵɵdeferHydrateOnIdle`,moduleName:D};static deferHydrateOnImmediate={name:`ɵɵdeferHydrateOnImmediate`,moduleName:D};static deferHydrateOnTimer={name:`ɵɵdeferHydrateOnTimer`,moduleName:D};static deferHydrateOnHover={name:`ɵɵdeferHydrateOnHover`,moduleName:D};static deferHydrateOnInteraction={name:`ɵɵdeferHydrateOnInteraction`,moduleName:D};static deferHydrateOnViewport={name:`ɵɵdeferHydrateOnViewport`,moduleName:D};static deferEnableTimerScheduling={name:`ɵɵdeferEnableTimerScheduling`,moduleName:D};static enableIncrementalHydrationRuntime={name:`ɵɵenableIncrementalHydrationRuntime`,moduleName:D};static conditionalCreate={name:`ɵɵconditionalCreate`,moduleName:D};static conditionalBranchCreate={name:`ɵɵconditionalBranchCreate`,moduleName:D};static conditional={name:`ɵɵconditional`,moduleName:D};static repeater={name:`ɵɵrepeater`,moduleName:D};static repeaterCreate={name:`ɵɵrepeaterCreate`,moduleName:D};static repeaterTrackByIndex={name:`ɵɵrepeaterTrackByIndex`,moduleName:D};static repeaterTrackByIdentity={name:`ɵɵrepeaterTrackByIdentity`,moduleName:D};static componentInstance={name:`ɵɵcomponentInstance`,moduleName:D};static text={name:`ɵɵtext`,moduleName:D};static enableBindings={name:`ɵɵenableBindings`,moduleName:D};static disableBindings={name:`ɵɵdisableBindings`,moduleName:D};static getCurrentView={name:`ɵɵgetCurrentView`,moduleName:D};static textInterpolate={name:`ɵɵtextInterpolate`,moduleName:D};static textInterpolate1={name:`ɵɵtextInterpolate1`,moduleName:D};static textInterpolate2={name:`ɵɵtextInterpolate2`,moduleName:D};static textInterpolate3={name:`ɵɵtextInterpolate3`,moduleName:D};static textInterpolate4={name:`ɵɵtextInterpolate4`,moduleName:D};static textInterpolate5={name:`ɵɵtextInterpolate5`,moduleName:D};static textInterpolate6={name:`ɵɵtextInterpolate6`,moduleName:D};static textInterpolate7={name:`ɵɵtextInterpolate7`,moduleName:D};static textInterpolate8={name:`ɵɵtextInterpolate8`,moduleName:D};static textInterpolateV={name:`ɵɵtextInterpolateV`,moduleName:D};static restoreView={name:`ɵɵrestoreView`,moduleName:D};static pureFunction0={name:`ɵɵpureFunction0`,moduleName:D};static pureFunction1={name:`ɵɵpureFunction1`,moduleName:D};static pureFunction2={name:`ɵɵpureFunction2`,moduleName:D};static pureFunction3={name:`ɵɵpureFunction3`,moduleName:D};static pureFunction4={name:`ɵɵpureFunction4`,moduleName:D};static pureFunction5={name:`ɵɵpureFunction5`,moduleName:D};static pureFunction6={name:`ɵɵpureFunction6`,moduleName:D};static pureFunction7={name:`ɵɵpureFunction7`,moduleName:D};static pureFunction8={name:`ɵɵpureFunction8`,moduleName:D};static pureFunctionV={name:`ɵɵpureFunctionV`,moduleName:D};static pipeBind1={name:`ɵɵpipeBind1`,moduleName:D};static pipeBind2={name:`ɵɵpipeBind2`,moduleName:D};static pipeBind3={name:`ɵɵpipeBind3`,moduleName:D};static pipeBind4={name:`ɵɵpipeBind4`,moduleName:D};static pipeBindV={name:`ɵɵpipeBindV`,moduleName:D};static domProperty={name:`ɵɵdomProperty`,moduleName:D};static ariaProperty={name:`ɵɵariaProperty`,moduleName:D};static property={name:`ɵɵproperty`,moduleName:D};static control={name:`ɵɵcontrol`,moduleName:D};static controlCreate={name:`ɵɵcontrolCreate`,moduleName:D};static animationEnterListener={name:`ɵɵanimateEnterListener`,moduleName:D};static animationLeaveListener={name:`ɵɵanimateLeaveListener`,moduleName:D};static animationEnter={name:`ɵɵanimateEnter`,moduleName:D};static animationLeave={name:`ɵɵanimateLeave`,moduleName:D};static i18n={name:`ɵɵi18n`,moduleName:D};static i18nAttributes={name:`ɵɵi18nAttributes`,moduleName:D};static i18nExp={name:`ɵɵi18nExp`,moduleName:D};static i18nStart={name:`ɵɵi18nStart`,moduleName:D};static i18nEnd={name:`ɵɵi18nEnd`,moduleName:D};static i18nApply={name:`ɵɵi18nApply`,moduleName:D};static i18nPostprocess={name:`ɵɵi18nPostprocess`,moduleName:D};static pipe={name:`ɵɵpipe`,moduleName:D};static projection={name:`ɵɵprojection`,moduleName:D};static projectionDef={name:`ɵɵprojectionDef`,moduleName:D};static reference={name:`ɵɵreference`,moduleName:D};static inject={name:`ɵɵinject`,moduleName:D};static injectAttribute={name:`ɵɵinjectAttribute`,moduleName:D};static directiveInject={name:`ɵɵdirectiveInject`,moduleName:D};static invalidFactory={name:`ɵɵinvalidFactory`,moduleName:D};static invalidFactoryDep={name:`ɵɵinvalidFactoryDep`,moduleName:D};static templateRefExtractor={name:`ɵɵtemplateRefExtractor`,moduleName:D};static forwardRef={name:`forwardRef`,moduleName:D};static resolveForwardRef={name:`resolveForwardRef`,moduleName:D};static replaceMetadata={name:`ɵɵreplaceMetadata`,moduleName:D};static getReplaceMetadataURL={name:`ɵɵgetReplaceMetadataURL`,moduleName:D};static ɵɵdefineInjectable={name:`ɵɵdefineInjectable`,moduleName:D};static declareInjectable={name:`ɵɵngDeclareInjectable`,moduleName:D};static InjectableDeclaration={name:`ɵɵInjectableDeclaration`,moduleName:D};static defineService={name:`ɵɵdefineService`,moduleName:D};static declareService={name:`ɵɵngDeclareService`,moduleName:D};static resolveWindow={name:`ɵɵresolveWindow`,moduleName:D};static resolveDocument={name:`ɵɵresolveDocument`,moduleName:D};static resolveBody={name:`ɵɵresolveBody`,moduleName:D};static getComponentDepsFactory={name:`ɵɵgetComponentDepsFactory`,moduleName:D};static defineComponent={name:`ɵɵdefineComponent`,moduleName:D};static declareComponent={name:`ɵɵngDeclareComponent`,moduleName:D};static setComponentScope={name:`ɵɵsetComponentScope`,moduleName:D};static ChangeDetectionStrategy={name:`ChangeDetectionStrategy`,moduleName:D};static ViewEncapsulation={name:`ViewEncapsulation`,moduleName:D};static ComponentDeclaration={name:`ɵɵComponentDeclaration`,moduleName:D};static FactoryDeclaration={name:`ɵɵFactoryDeclaration`,moduleName:D};static declareFactory={name:`ɵɵngDeclareFactory`,moduleName:D};static FactoryTarget={name:`ɵɵFactoryTarget`,moduleName:D};static defineDirective={name:`ɵɵdefineDirective`,moduleName:D};static declareDirective={name:`ɵɵngDeclareDirective`,moduleName:D};static DirectiveDeclaration={name:`ɵɵDirectiveDeclaration`,moduleName:D};static InjectorDef={name:`ɵɵInjectorDef`,moduleName:D};static InjectorDeclaration={name:`ɵɵInjectorDeclaration`,moduleName:D};static defineInjector={name:`ɵɵdefineInjector`,moduleName:D};static declareInjector={name:`ɵɵngDeclareInjector`,moduleName:D};static NgModuleDeclaration={name:`ɵɵNgModuleDeclaration`,moduleName:D};static ModuleWithProviders={name:`ModuleWithProviders`,moduleName:D};static defineNgModule={name:`ɵɵdefineNgModule`,moduleName:D};static declareNgModule={name:`ɵɵngDeclareNgModule`,moduleName:D};static setNgModuleScope={name:`ɵɵsetNgModuleScope`,moduleName:D};static registerNgModuleType={name:`ɵɵregisterNgModuleType`,moduleName:D};static PipeDeclaration={name:`ɵɵPipeDeclaration`,moduleName:D};static definePipe={name:`ɵɵdefinePipe`,moduleName:D};static declarePipe={name:`ɵɵngDeclarePipe`,moduleName:D};static declareClassMetadata={name:`ɵɵngDeclareClassMetadata`,moduleName:D};static declareClassMetadataAsync={name:`ɵɵngDeclareClassMetadataAsync`,moduleName:D};static setClassMetadata={name:`ɵsetClassMetadata`,moduleName:D};static setClassMetadataAsync={name:`ɵsetClassMetadataAsync`,moduleName:D};static setClassDebugInfo={name:`ɵsetClassDebugInfo`,moduleName:D};static queryRefresh={name:`ɵɵqueryRefresh`,moduleName:D};static viewQuery={name:`ɵɵviewQuery`,moduleName:D};static loadQuery={name:`ɵɵloadQuery`,moduleName:D};static contentQuery={name:`ɵɵcontentQuery`,moduleName:D};static viewQuerySignal={name:`ɵɵviewQuerySignal`,moduleName:D};static contentQuerySignal={name:`ɵɵcontentQuerySignal`,moduleName:D};static queryAdvance={name:`ɵɵqueryAdvance`,moduleName:D};static twoWayProperty={name:`ɵɵtwoWayProperty`,moduleName:D};static twoWayBindingSet={name:`ɵɵtwoWayBindingSet`,moduleName:D};static twoWayListener={name:`ɵɵtwoWayListener`,moduleName:D};static declareLet={name:`ɵɵdeclareLet`,moduleName:D};static storeLet={name:`ɵɵstoreLet`,moduleName:D};static readContextLet={name:`ɵɵreadContextLet`,moduleName:D};static arrowFunction={name:`ɵɵarrowFunction`,moduleName:D};static attachSourceLocations={name:`ɵɵattachSourceLocations`,moduleName:D};static NgOnChangesFeature={name:`ɵɵNgOnChangesFeature`,moduleName:D};static ControlFeature={name:`ɵɵControlFeature`,moduleName:D};static InheritDefinitionFeature={name:`ɵɵInheritDefinitionFeature`,moduleName:D};static ProvidersFeature={name:`ɵɵProvidersFeature`,moduleName:D};static HostDirectivesFeature={name:`ɵɵHostDirectivesFeature`,moduleName:D};static ExternalStylesFeature={name:`ɵɵExternalStylesFeature`,moduleName:D};static listener={name:`ɵɵlistener`,moduleName:D};static getInheritedFactory={name:`ɵɵgetInheritedFactory`,moduleName:D};static sanitizeHtml={name:`ɵɵsanitizeHtml`,moduleName:D};static sanitizeStyle={name:`ɵɵsanitizeStyle`,moduleName:D};static validateAttribute={name:`ɵɵvalidateAttribute`,moduleName:D};static sanitizeResourceUrl={name:`ɵɵsanitizeResourceUrl`,moduleName:D};static sanitizeScript={name:`ɵɵsanitizeScript`,moduleName:D};static sanitizeUrl={name:`ɵɵsanitizeUrl`,moduleName:D};static sanitizeUrlOrResourceUrl={name:`ɵɵsanitizeUrlOrResourceUrl`,moduleName:D};static trustConstantHtml={name:`ɵɵtrustConstantHtml`,moduleName:D};static trustConstantResourceUrl={name:`ɵɵtrustConstantResourceUrl`,moduleName:D};static inputDecorator={name:`Input`,moduleName:D};static outputDecorator={name:`Output`,moduleName:D};static viewChildDecorator={name:`ViewChild`,moduleName:D};static viewChildrenDecorator={name:`ViewChildren`,moduleName:D};static contentChildDecorator={name:`ContentChild`,moduleName:D};static contentChildrenDecorator={name:`ContentChildren`,moduleName:D};static InputSignalBrandWriteType={name:`ɵINPUT_SIGNAL_BRAND_WRITE_TYPE`,moduleName:D};static UnwrapDirectiveSignalInputs={name:`ɵUnwrapDirectiveSignalInputs`,moduleName:D};static unwrapWritableSignal={name:`ɵunwrapWritableSignal`,moduleName:D};static assertType={name:`ɵassertType`,moduleName:D}}return e})();E.And,E.Bigger,E.BiggerEquals,E.BitwiseOr,E.BitwiseAnd,E.Divide,E.Assign,E.Equals,E.Identical,E.Lower,E.LowerEquals,E.Minus,E.Modulo,E.Exponentiation,E.Multiply,E.NotEquals,E.NotIdentical,E.NullishCoalesce,E.Or,E.Plus,E.In,E.InstanceOf,E.AdditionAssignment,E.SubtractionAssignment,E.MultiplicationAssignment,E.DivisionAssignment,E.RemainderAssignment,E.ExponentiationAssignment,E.AndAssignment,E.OrAssignment,E.NullishCoalesceAssignment;var Tt=class{span;sourceSpan;constructor(e,t){this.span=e,this.sourceSpan=t}toString(){return`AST`}},Et=class extends Tt{receiver;args;argumentSpan;constructor(e,t,n,r,i){super(e,t),this.receiver=n,this.args=r,this.argumentSpan=i}visit(e,t=null){return e.visitCall(this,t)}},Dt=(function(e){return e[e.Property=0]=`Property`,e[e.Attribute=1]=`Attribute`,e[e.Class=2]=`Class`,e[e.Style=3]=`Style`,e[e.LegacyAnimation=4]=`LegacyAnimation`,e[e.TwoWay=5]=`TwoWay`,e[e.Animation=6]=`Animation`,e})(Dt||{}),Ot=`(:(where|is)\\()?`,kt=`-shadowcsshost`,At=`-shadowcsscontext`,jt=`[^)(]*`,Mt=String.raw`(?:\(${jt}\)|${jt})+?`,Nt=String.raw`(?:\(${Mt}\)|${jt})+?`,Pt=String.raw`(?:\((${Nt})\))`;String.raw`(:nth-[-\w]+)`+Pt,kt+Pt+``,`${Ot}`,At+Pt+``;var k=(function(e){return e[e.ListEnd=0]=`ListEnd`,e[e.Statement=1]=`Statement`,e[e.Variable=2]=`Variable`,e[e.ElementStart=3]=`ElementStart`,e[e.Element=4]=`Element`,e[e.ForeignComponent=5]=`ForeignComponent`,e[e.Template=6]=`Template`,e[e.ElementEnd=7]=`ElementEnd`,e[e.ContainerStart=8]=`ContainerStart`,e[e.Container=9]=`Container`,e[e.ContainerEnd=10]=`ContainerEnd`,e[e.DisableBindings=11]=`DisableBindings`,e[e.ConditionalCreate=12]=`ConditionalCreate`,e[e.ConditionalBranchCreate=13]=`ConditionalBranchCreate`,e[e.Conditional=14]=`Conditional`,e[e.EnableBindings=15]=`EnableBindings`,e[e.Text=16]=`Text`,e[e.Listener=17]=`Listener`,e[e.InterpolateText=18]=`InterpolateText`,e[e.Binding=19]=`Binding`,e[e.Property=20]=`Property`,e[e.StyleProp=21]=`StyleProp`,e[e.ClassProp=22]=`ClassProp`,e[e.StyleMap=23]=`StyleMap`,e[e.ClassMap=24]=`ClassMap`,e[e.Advance=25]=`Advance`,e[e.Pipe=26]=`Pipe`,e[e.Attribute=27]=`Attribute`,e[e.ExtractedAttribute=28]=`ExtractedAttribute`,e[e.Defer=29]=`Defer`,e[e.DeferOn=30]=`DeferOn`,e[e.DeferWhen=31]=`DeferWhen`,e[e.I18nMessage=32]=`I18nMessage`,e[e.DomProperty=33]=`DomProperty`,e[e.Namespace=34]=`Namespace`,e[e.ProjectionDef=35]=`ProjectionDef`,e[e.EnableIncrementalHydrationRuntime=36]=`EnableIncrementalHydrationRuntime`,e[e.Projection=37]=`Projection`,e[e.Content=38]=`Content`,e[e.RepeaterCreate=39]=`RepeaterCreate`,e[e.Repeater=40]=`Repeater`,e[e.TwoWayProperty=41]=`TwoWayProperty`,e[e.TwoWayListener=42]=`TwoWayListener`,e[e.DeclareLet=43]=`DeclareLet`,e[e.StoreLet=44]=`StoreLet`,e[e.I18nStart=45]=`I18nStart`,e[e.I18n=46]=`I18n`,e[e.I18nEnd=47]=`I18nEnd`,e[e.I18nExpression=48]=`I18nExpression`,e[e.I18nApply=49]=`I18nApply`,e[e.IcuStart=50]=`IcuStart`,e[e.IcuEnd=51]=`IcuEnd`,e[e.IcuPlaceholder=52]=`IcuPlaceholder`,e[e.I18nContext=53]=`I18nContext`,e[e.I18nAttributes=54]=`I18nAttributes`,e[e.SourceLocation=55]=`SourceLocation`,e[e.Animation=56]=`Animation`,e[e.AnimationString=57]=`AnimationString`,e[e.AnimationBinding=58]=`AnimationBinding`,e[e.AnimationListener=59]=`AnimationListener`,e[e.Control=60]=`Control`,e[e.ControlCreate=61]=`ControlCreate`,e})(k||{}),Ft=(function(e){return e[e.LexicalRead=0]=`LexicalRead`,e[e.Context=1]=`Context`,e[e.TrackContext=2]=`TrackContext`,e[e.ReadVariable=3]=`ReadVariable`,e[e.NextContext=4]=`NextContext`,e[e.Reference=5]=`Reference`,e[e.StoreLet=6]=`StoreLet`,e[e.ContextLetReference=7]=`ContextLetReference`,e[e.GetCurrentView=8]=`GetCurrentView`,e[e.RestoreView=9]=`RestoreView`,e[e.ResetView=10]=`ResetView`,e[e.PureFunctionExpr=11]=`PureFunctionExpr`,e[e.PureFunctionParameterExpr=12]=`PureFunctionParameterExpr`,e[e.PipeBinding=13]=`PipeBinding`,e[e.PipeBindingVariadic=14]=`PipeBindingVariadic`,e[e.SafePropertyRead=15]=`SafePropertyRead`,e[e.SafeKeyedRead=16]=`SafeKeyedRead`,e[e.SafeNavigationMigration=17]=`SafeNavigationMigration`,e[e.SafeTernaryExpr=18]=`SafeTernaryExpr`,e[e.EmptyExpr=19]=`EmptyExpr`,e[e.AssignTemporaryExpr=20]=`AssignTemporaryExpr`,e[e.ReadTemporaryExpr=21]=`ReadTemporaryExpr`,e[e.SlotLiteralExpr=22]=`SlotLiteralExpr`,e[e.ConditionalCase=23]=`ConditionalCase`,e[e.ConstCollected=24]=`ConstCollected`,e[e.TwoWayBindingSet=25]=`TwoWayBindingSet`,e[e.ForeignContent=26]=`ForeignContent`,e[e.ArrowFunction=27]=`ArrowFunction`,e})(Ft||{}),It=(function(e){return e[e.None=0]=`None`,e[e.AlwaysInline=1]=`AlwaysInline`,e})(It||{}),Lt=(function(e){return e[e.Context=0]=`Context`,e[e.Identifier=1]=`Identifier`,e[e.SavedView=2]=`SavedView`,e[e.Alias=3]=`Alias`,e})(Lt||{}),Rt=(function(e){return e[e.Attribute=0]=`Attribute`,e[e.ClassName=1]=`ClassName`,e[e.StyleProperty=2]=`StyleProperty`,e[e.Property=3]=`Property`,e[e.Template=4]=`Template`,e[e.I18n=5]=`I18n`,e[e.LegacyAnimation=6]=`LegacyAnimation`,e[e.TwoWayProperty=7]=`TwoWayProperty`,e[e.Animation=8]=`Animation`,e})(Rt||{}),zt=(function(e){return e[e.Creation=0]=`Creation`,e[e.Postproccessing=1]=`Postproccessing`,e})(zt||{}),Bt=(function(e){return e[e.I18nText=0]=`I18nText`,e[e.I18nAttribute=1]=`I18nAttribute`,e})(Bt||{}),Vt=(function(e){return e[e.None=0]=`None`,e[e.ElementTag=1]=`ElementTag`,e[e.TemplateTag=2]=`TemplateTag`,e[e.OpenTag=4]=`OpenTag`,e[e.CloseTag=8]=`CloseTag`,e[e.ExpressionIndex=16]=`ExpressionIndex`,e})(Vt||{}),Ht=(function(e){return e[e.HTML=0]=`HTML`,e[e.SVG=1]=`SVG`,e[e.Math=2]=`Math`,e})(Ht||{}),Ut=(function(e){return e[e.Idle=0]=`Idle`,e[e.Immediate=1]=`Immediate`,e[e.Timer=2]=`Timer`,e[e.Hover=3]=`Hover`,e[e.Interaction=4]=`Interaction`,e[e.Viewport=5]=`Viewport`,e[e.Never=6]=`Never`,e})(Ut||{}),Wt=(function(e){return e[e.RootI18n=0]=`RootI18n`,e[e.Icu=1]=`Icu`,e[e.Attr=2]=`Attr`,e})(Wt||{}),Gt=(function(e){return e[e.NgTemplate=0]=`NgTemplate`,e[e.Structural=1]=`Structural`,e[e.Block=2]=`Block`,e})(Gt||{}),Kt=(function(e){return e[e.None=0]=`None`,e[e.InChildOperation=1]=`InChildOperation`,e[e.InArrowFunctionOperation=2]=`InArrowFunctionOperation`,e[e.InSafeNavigationMigration=4]=`InSafeNavigationMigration`,e})(Kt||{});k.Element,k.ElementStart,k.Container,k.ContainerStart,k.Template,k.RepeaterCreate,k.ConditionalCreate,k.ConditionalBranchCreate;var A=(function(e){return e[e.Tmpl=0]=`Tmpl`,e[e.Host=1]=`Host`,e[e.Both=2]=`Both`,e})(A||{}),qt=(function(e){return e[e.Full=0]=`Full`,e[e.DomOnly=1]=`DomOnly`,e})(qt||{});O.ariaProperty,O.ariaProperty,O.attribute,O.attribute,O.classProp,O.classProp,O.element,O.element,O.elementContainer,O.elementContainer,O.elementContainerEnd,O.elementContainerEnd,O.elementContainerStart,O.elementContainerStart,O.elementEnd,O.elementEnd,O.elementStart,O.elementStart,O.domProperty,O.domProperty,O.i18nExp,O.i18nExp,O.listener,O.listener,O.listener,O.listener,O.property,O.property,O.styleProp,O.styleProp,O.syntheticHostListener,O.syntheticHostListener,O.syntheticHostProperty,O.syntheticHostProperty,O.templateCreate,O.templateCreate,O.twoWayProperty,O.twoWayProperty,O.twoWayListener,O.twoWayListener,O.declareLet,O.declareLet,O.conditionalCreate,O.conditionalBranchCreate,O.conditionalBranchCreate,O.conditionalBranchCreate,O.domElement,O.domElement,O.domElementStart,O.domElementStart,O.domElementEnd,O.domElementEnd,O.domElementContainer,O.domElementContainer,O.domElementContainerStart,O.domElementContainerStart,O.domElementContainerEnd,O.domElementContainerEnd,O.domListener,O.domListener,O.domTemplate,O.domTemplate,O.animationEnter,O.animationEnter,O.animationLeave,O.animationLeave,O.animationEnterListener,O.animationEnterListener,O.animationLeaveListener,O.animationLeaveListener,E.And,E.Bigger,E.BiggerEquals,E.BitwiseOr,E.BitwiseAnd,E.Divide,E.Assign,E.Equals,E.Identical,E.Lower,E.LowerEquals,E.Minus,E.Modulo,E.Exponentiation,E.Multiply,E.NotEquals,E.NotIdentical,E.NullishCoalesce,E.Or,E.Plus,E.In,E.InstanceOf,E.AdditionAssignment,E.SubtractionAssignment,E.MultiplicationAssignment,E.DivisionAssignment,E.RemainderAssignment,E.ExponentiationAssignment,E.AndAssignment,E.OrAssignment,E.NullishCoalesceAssignment,k.Property,k.Property,k.Property,k.Attribute,k.Attribute,k.Property,k.TwoWayProperty,k.Container,k.ContainerStart,k.ContainerEnd,k.Element,k.ElementStart,k.ElementEnd,k.Template,k.ElementEnd,k.ElementStart,k.Element,k.ContainerEnd,k.ContainerStart,k.Container,k.I18nEnd,k.I18nStart,k.I18n,k.Pipe;var Jt=` \f -\r \v ᠎ - \u2028\u2029   `;`${Jt}`,`${Jt}`;var Yt=(function(e){return e[e.Character=0]=`Character`,e[e.Identifier=1]=`Identifier`,e[e.PrivateIdentifier=2]=`PrivateIdentifier`,e[e.Keyword=3]=`Keyword`,e[e.String=4]=`String`,e[e.Operator=5]=`Operator`,e[e.Number=6]=`Number`,e[e.RegExpBody=7]=`RegExpBody`,e[e.RegExpFlags=8]=`RegExpFlags`,e[e.Error=9]=`Error`,e})(Yt||{}),Xt=(function(e){return e[e.Plain=0]=`Plain`,e[e.TemplateLiteralPart=1]=`TemplateLiteralPart`,e[e.TemplateLiteralEnd=2]=`TemplateLiteralEnd`,e})(Xt||{});Yt.Character,k.StyleMap,k.ClassMap,k.StyleProp,k.ClassProp,k.Attribute,k.Property,k.Attribute,k.Control,k.DomProperty,k.DomProperty,k.Attribute,k.StyleMap,k.ClassMap,k.StyleProp,k.ClassProp,k.Listener,k.TwoWayListener,k.AnimationListener,k.StyleMap,k.ClassMap,k.StyleProp,k.ClassProp,k.Property,k.TwoWayProperty,k.DomProperty,k.Attribute,k.Animation,k.Control,Ut.Idle,O.deferOnIdle,O.deferPrefetchOnIdle,O.deferHydrateOnIdle,Ut.Immediate,O.deferOnImmediate,O.deferPrefetchOnImmediate,O.deferHydrateOnImmediate,Ut.Timer,O.deferOnTimer,O.deferPrefetchOnTimer,O.deferHydrateOnTimer,Ut.Hover,O.deferOnHover,O.deferPrefetchOnHover,O.deferHydrateOnHover,Ut.Interaction,O.deferOnInteraction,O.deferPrefetchOnInteraction,O.deferHydrateOnInteraction,Ut.Viewport,O.deferOnViewport,O.deferPrefetchOnViewport,O.deferHydrateOnViewport,Ut.Never,O.deferHydrateNever,O.deferHydrateNever,O.deferHydrateNever,O.pipeBind1,O.pipeBind2,O.pipeBind3,O.pipeBind4,O.textInterpolate,O.textInterpolate1,O.textInterpolate2,O.textInterpolate3,O.textInterpolate4,O.textInterpolate5,O.textInterpolate6,O.textInterpolate7,O.textInterpolate8,O.textInterpolateV,O.interpolate,O.interpolate1,O.interpolate2,O.interpolate3,O.interpolate4,O.interpolate5,O.interpolate6,O.interpolate7,O.interpolate8,O.interpolateV,O.pureFunction0,O.pureFunction1,O.pureFunction2,O.pureFunction3,O.pureFunction4,O.pureFunction5,O.pureFunction6,O.pureFunction7,O.pureFunction8,O.pureFunctionV,O.resolveWindow,O.resolveDocument,O.resolveBody,Xe.HTML,O.sanitizeHtml,Xe.RESOURCE_URL,O.sanitizeResourceUrl,Xe.SCRIPT,O.sanitizeScript,Xe.STYLE,O.sanitizeStyle,Xe.URL,O.sanitizeUrl,Xe.ATTRIBUTE_NO_BINDING,O.validateAttribute,Xe.HTML,O.trustConstantHtml,Xe.RESOURCE_URL,O.trustConstantResourceUrl;var Zt=(function(e){return e[e.None=0]=`None`,e[e.ViewContextRead=1]=`ViewContextRead`,e[e.ViewContextWrite=2]=`ViewContextWrite`,e[e.SideEffectful=4]=`SideEffectful`,e})(Zt||{});A.Tmpl,A.Tmpl,A.Both,A.Host,A.Tmpl,A.Tmpl,A.Tmpl,A.Both,A.Both,A.Both,A.Tmpl,A.Both,A.Both,A.Tmpl,A.Both,A.Tmpl,A.Both,A.Both,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Both,A.Both,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Both,A.Both,A.Both,A.Tmpl,A.Tmpl,A.Both,A.Tmpl,A.Tmpl,A.Tmpl,A.Both,A.Both,A.Tmpl,A.Both,A.Both,A.Both,A.Both,A.Both,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Both,A.Tmpl,A.Both,A.Tmpl,A.Both,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Tmpl,A.Both,A.Both,A.Both,Dt.Property,Rt.Property,Dt.TwoWay,Rt.TwoWayProperty,Dt.Attribute,Rt.Attribute,Dt.Class,Rt.ClassName,Dt.Style,Rt.StyleProperty,Dt.LegacyAnimation,Rt.LegacyAnimation,Dt.Animation,Rt.Animation;var Qt=`%COMP%`;`${Qt}`,`${Qt}`,class e{static SINGLETON=new e;static veWillInferAnyFor(t){let n=e.SINGLETON;return t instanceof Et?t.visit(n):t.receiver.visit(n)}visitUnary(e){return e.expr.visit(this)}visitBinary(e){return e.left.visit(this)||e.right.visit(this)}visitChain(){return!1}visitConditional(e){return e.condition.visit(this)||e.trueExp.visit(this)||e.falseExp.visit(this)}visitCall(){return!0}visitSafeCall(){return!1}visitImplicitReceiver(){return!1}visitThisReceiver(){return!1}visitInterpolation(e){return e.expressions.some(e=>e.visit(this))}visitKeyedRead(){return!1}visitLiteralArray(){return!0}visitLiteralMap(){return!0}visitLiteralPrimitive(){return!1}visitPipe(){return!0}visitPrefixNot(e){return e.expression.visit(this)}visitTypeofExpression(e){return e.expression.visit(this)}visitVoidExpression(e){return e.expression.visit(this)}visitNonNullAssert(e){return e.expression.visit(this)}visitPropertyRead(){return!1}visitSafePropertyRead(){return!1}visitSafeKeyedRead(){return!1}visitTemplateLiteral(){return!1}visitTemplateLiteralElement(){return!1}visitTaggedTemplateLiteral(){return!1}visitParenthesizedExpression(e){return e.expression.visit(this)}visitRegularExpressionLiteral(){return!1}visitSpreadElement(e){return e.expression.visit(this)}visitArrowFunction(e,t){return!1}};var $t=null,en=!1,tn=1,nn=null,rn=Symbol(`SIGNAL`);function j(e){let t=$t;return $t=e,t}function an(){return $t}var on={version:0,lastCleanEpoch:0,dirty:!1,producers:void 0,producersTail:void 0,consumers:void 0,consumersTail:void 0,recomputing:!1,consumerAllowSignalWrites:!1,consumerIsAlwaysLive:!1,kind:`unknown`,producerMustRecompute:()=>!1,producerRecomputeValue:()=>{},consumerMarkedDirty:()=>{},consumerOnSignalRead:()=>{}};function sn(e){if(en)throw Error(``);if($t===null)return;$t.consumerOnSignalRead(e);let t=$t.producersTail;if(t!==void 0&&t.producer===e)return;let n,r=$t.recomputing;if(r&&(n=t===void 0?$t.producers:t.nextProducer,n!==void 0&&n.producer===e)){$t.producersTail=n,n.lastReadVersion=e.version,n.knownValidAtEpoch=tn;return}let i=e.consumersTail;if(i!==void 0&&i.consumer===$t&&(!r||i.knownValidAtEpoch===tn))return;let a=Sn($t),o={producer:e,consumer:$t,nextProducer:n,prevConsumer:void 0,knownValidAtEpoch:tn,lastReadVersion:e.version,nextConsumer:void 0};$t.producersTail=o,t===void 0?$t.producers=o:t.nextProducer=o,a&&bn(e,o)}function cn(){tn++}function ln(e){if((!Sn(e)||e.dirty)&&(e.dirty||e.lastCleanEpoch!==tn)){if(!e.producerMustRecompute(e)&&!vn(e)){pn(e);return}e.producerRecomputeValue(e),pn(e)}}function un(e){if(e.consumers===void 0)return;let t=en;en=!0;try{for(let t=e.consumers;t!==void 0;t=t.nextConsumer){let e=t.consumer;e.dirty||fn(e)}}finally{en=t}}function dn(){return $t?.consumerAllowSignalWrites!==!1}function fn(e){e.dirty=!0,un(e),e.consumerMarkedDirty?.(e)}function pn(e){e.dirty=!1,e.lastCleanEpoch=tn}function mn(e){return e&&hn(e),j(e)}function hn(e){if(e.producersTail?.knownValidAtEpoch===tn){let t=e.producers;for(;t!==void 0;)t.knownValidAtEpoch=null,t=t.nextProducer}e.producersTail=void 0,e.recomputing=!0}function gn(e,t){j(t),e&&_n(e)}function _n(e){e.recomputing=!1;let t=e.producersTail,n=t===void 0?e.producers:t.nextProducer;if(n!==void 0){if(Sn(e))do n=xn(n);while(n!==void 0);t===void 0?e.producers=void 0:t.nextProducer=void 0}}function vn(e){for(let t=e.producers;t!==void 0;t=t.nextProducer){let e=t.producer,n=t.lastReadVersion;if(n!==e.version||(ln(e),n!==e.version))return!0}return!1}function yn(e){if(Sn(e)){let t=e.producers;for(;t!==void 0;)t=xn(t)}e.producers=void 0,e.producersTail=void 0,e.consumers=void 0,e.consumersTail=void 0}function bn(e,t){let n=e.consumersTail,r=Sn(e);if(n===void 0?(t.nextConsumer=void 0,e.consumers=t):(t.nextConsumer=n.nextConsumer,n.nextConsumer=t),t.prevConsumer=n,e.consumersTail=t,!r)for(let t=e.producers;t!==void 0;t=t.nextProducer)bn(t.producer,t)}function xn(e){let t=e.producer,n=e.nextProducer,r=e.nextConsumer,i=e.prevConsumer;if(e.nextConsumer=void 0,e.prevConsumer=void 0,r===void 0?t.consumersTail=i:r.prevConsumer=i,i!==void 0)i.nextConsumer=r;else if(t.consumers=r,!Sn(t)){let e=t.producers;for(;e!==void 0;)e=xn(e)}return n}function Sn(e){return e.consumerIsAlwaysLive||e.consumers!==void 0}function Cn(e){nn?.(e)}function wn(e,t){return Object.is(e,t)}function Tn(e,t){let n=Object.create(kn);n.computation=e,t!==void 0&&(n.equal=t);let r=()=>{if(ln(n),sn(n),n.value===On)throw n.error;return n.value};return r[rn]=n,Cn(n),r}var En=Symbol(`UNSET`),Dn=Symbol(`COMPUTING`),On=Symbol(`ERRORED`),kn={...on,value:En,dirty:!0,error:null,equal:wn,kind:`computed`,producerMustRecompute(e){return e.value===En||e.value===Dn},producerRecomputeValue(e){if(e.value===Dn)throw Error(``);let t=e.value;e.value=Dn;let n=mn(e),r,i=!1;try{r=e.computation(),j(null),i=t!==En&&t!==On&&r!==On&&e.equal(t,r)}catch(t){r=On,e.error=t}finally{gn(e,n)}if(i){e.value=t;return}e.value=r,e.version++}};function An(){throw Error()}var jn=An;function Mn(e){jn(e)}function Nn(e){jn=e}var Pn=null;function Fn(e,t){let n=Object.create(zn);n.value=e,t!==void 0&&(n.equal=t);let r=()=>In(n);return r[rn]=n,Cn(n),[r,e=>Ln(n,e),e=>Rn(n,e)]}function In(e){return sn(e),e.value}function Ln(e,t){dn()||Mn(e),e.equal(e.value,t)||(e.value=t,Bn(e))}function Rn(e,t){dn()||Mn(e),Ln(e,t(e.value))}var zn={...on,equal:wn,value:void 0,kind:`signal`};function Bn(e){e.version++,cn(),un(e),Pn?.(e)}var Vn={...on,consumerIsAlwaysLive:!0,consumerAllowSignalWrites:!0,dirty:!0,kind:`effect`};function Hn(e){if(e.dirty=!1,e.version>0&&!vn(e))return;e.version++;let t=mn(e);try{e.cleanup(),e.fn()}finally{gn(e,t)}}var Un=void 0;function Wn(){return Un}function Gn(e){let t=Un;return Un=e,t}var Kn=Symbol(`NotFound`);function qn(e){return e===Kn||e?.name===`ɵNotFound`}function Jn(e,t,n){let r=Object.create(Zn);r.source=e,r.computation=t,n!=null&&(r.equal=n);let i=()=>{if(ln(r),sn(r),r.value===On)throw r.error;return r.value};return i[rn]=r,Cn(r),i}function Yn(e,t){ln(e),Ln(e,t),pn(e)}function Xn(e,t){if(ln(e),e.value===On)throw e.error;Rn(e,t),pn(e)}var Zn={...on,value:En,dirty:!0,error:null,equal:wn,kind:`linkedSignal`,producerMustRecompute(e){return e.value===En||e.value===Dn},producerRecomputeValue(e){if(e.value===Dn)throw Error(``);let t=e.value;e.value=Dn;let n=mn(e),r,i=!1;try{let n=e.source(),a=t!==En&&t!==On,o=a?{source:e.sourceValue,value:t}:void 0;r=e.computation(n,o),e.sourceValue=n,j(null),i=a&&r!==On&&e.equal(t,r)}catch(t){r=On,e.error=t}finally{gn(e,n)}if(i){e.value=t;return}e.value=r,e.version++}};function Qn(e){let t=j(null);try{return e()}finally{j(t)}}var $n=function(e,t){return $n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},$n(e,t)};function er(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);$n(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}function tr(e){var t=typeof Symbol==`function`&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&typeof e.length==`number`)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw TypeError(t?`Object is not iterable.`:`Symbol.iterator is not defined.`)}function nr(e,t){var n=typeof Symbol==`function`&&e[Symbol.iterator];if(!n)return e;var r=n.call(e),i,a=[],o;try{for(;(t===void 0||t-->0)&&!(i=r.next()).done;)a.push(i.value)}catch(e){o={error:e}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(o)throw o.error}}return a}function rr(e,t,n){if(n||arguments.length===2)for(var r=0,i=t.length,a;r0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(t){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,t)},t.prototype._subscribe=function(e){return this._throwIfClosed(),this._checkFinalizedStatuses(e),this._innerSubscribe(e)},t.prototype._innerSubscribe=function(e){var t=this,n=this,r=n.hasError,i=n.isStopped,a=n.observers;return r||i?lr:(this.currentObservers=null,a.push(e),new cr(function(){t.currentObservers=null,sr(a,e)}))},t.prototype._checkFinalizedStatuses=function(e){var t=this,n=t.hasError,r=t.thrownError,i=t.isStopped;n?e.error(r):i&&e.complete()},t.prototype.asObservable=function(){var e=new Fr;return e.source=this,e},t.create=function(e,t){return new Gr(e,t)},t}(Fr),Gr=function(e){er(t,e);function t(t,n){var r=e.call(this)||this;return r.destination=t,r.source=n,r}return t.prototype.next=function(e){var t,n;(n=(t=this.destination)?.next)==null||n.call(t,e)},t.prototype.error=function(e){var t,n;(n=(t=this.destination)?.error)==null||n.call(t,e)},t.prototype.complete=function(){var e,t;(t=(e=this.destination)?.complete)==null||t.call(e)},t.prototype._subscribe=function(e){return this.source?.subscribe(e)??lr},t}(Wr),Kr=function(e){er(t,e);function t(t){var n=e.call(this)||this;return n._value=t,n}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(t){var n=e.prototype._subscribe.call(this,t);return!n.closed&&t.next(this._value),n},t.prototype.getValue=function(){var e=this,t=e.hasError,n=e.thrownError,r=e._value;if(t)throw n;return this._throwIfClosed(),r},t.prototype.next=function(t){e.prototype.next.call(this,this._value=t)},t}(Wr);function qr(e,t){return Br(function(n,r){var i=0;n.subscribe(Vr(r,function(n){r.next(e.call(t,n,i++))}))})}var Jr=`https://angular.dev/best-practices/security#preventing-cross-site-scripting-xss`,M=class extends Error{code;constructor(e,t){super(Xr(e,t)),this.code=e}};function Yr(e){return`NG0${Math.abs(e)}`}function Xr(e,t){return`${Yr(e)}${t?`: `+t:``}`}function Zr(e){for(let t in e)if(e[t]===Zr)return t;throw Error(``)}function Qr(e){if(typeof e==`string`)return e;if(Array.isArray(e))return`[${e.map(Qr).join(`, `)}]`;if(e==null)return``+e;let t=e.overriddenName||e.name;if(t)return`${t}`;let n=e.toString();if(n==null)return``+n;let r=n.indexOf(` -`);return r>=0?n.slice(0,r):n}function $r(e,t){return e?t?`${e} ${t}`:e:t||``}var ei=Zr({__forward_ref__:Zr});function ti(e){return e.__forward_ref__=ti,e}function ni(e){return ri(e)?e():e}function ri(e){return typeof e==`function`&&Object.hasOwn(e,ei)&&e.__forward_ref__===ti}function ii(e){return{token:e.token,providedIn:e.providedIn||null,factory:e.factory,value:void 0}}function ai(e){return oi(e,li)}function oi(e,t){return Object.hasOwn(e,t)&&e[t]||null}function si(e){return(e?.[li]??null)||null}function ci(e){return e&&Object.hasOwn(e,ui)?e[ui]:null}var li=Zr({ɵprov:Zr}),ui=Zr({ɵinj:Zr}),N=class{_desc;ngMetadataName=`InjectionToken`;ɵprov;constructor(e,t){this._desc=e,this.ɵprov=void 0,typeof t==`number`?this.__NG_ELEMENT_ID__=t:t!==void 0&&(this.ɵprov=ii({token:this,providedIn:t.providedIn||`root`,factory:t.factory}))}get multi(){return this}toString(){return`InjectionToken ${this._desc}`}};function di(e){return e&&!!e.ɵproviders}var fi=Zr({ɵcmp:Zr}),pi=Zr({ɵdir:Zr}),mi=Zr({ɵpipe:Zr}),hi=Zr({ɵfac:Zr}),gi=Zr({__NG_ELEMENT_ID__:Zr}),_i=Zr({__NG_ENV_ID__:Zr});function vi(e){return xi(e,`@Component`),e[fi]||null}function yi(e){return xi(e,`@Directive`),e[pi]||null}function bi(e){return xi(e,`@Pipe`),e[mi]||null}function xi(e,t){if(e==null)throw new M(-919,!1)}function Si(e){return typeof e==`string`?e:e==null?``:String(e)}var Ci=Zr({ngErrorCode:Zr}),wi=Zr({ngErrorMessage:Zr}),Ti=Zr({ngTokenPath:Zr});function Ei(e,t){return Oi(``,-200,t)}function Di(e,t){throw new M(-201,!1)}function Oi(e,t,n){let r=new M(t,e);return r[Ci]=t,r[wi]=e,n&&(r[Ti]=n),r}function ki(e){return e[Ci]}var Ai;function ji(){return Ai}function Mi(e){let t=Ai;return Ai=e,t}function Ni(e,t,n){let r=ai(e);if(r&&r.providedIn==`root`)return r.value===void 0?r.value=r.factory():r.value;if(n&8)return null;if(t!==void 0)return t;Di(e,``)}var Pi=globalThis,Fi={},Ii=`__NG_DI_FLAG__`,Li=class{injector;constructor(e){this.injector=e}retrieve(e,t){let n=Bi(t)||0;try{return this.injector.get(e,n&8?null:Fi,n)}catch(e){if(qn(e))return e;throw e}}};function Ri(e,t=0){let n=Wn();if(n===void 0)throw new M(-203,!1);if(n===null)return Ni(e,void 0,t);{let r=Vi(t),i=n.retrieve(e,r);if(qn(i)){if(r.optional)return null;throw i}return i}}function zi(e,t=0){return(ji()||Ri)(ni(e),t)}function P(e,t){return zi(e,Bi(t))}function Bi(e){return e===void 0||typeof e==`number`?e:0|(e.optional&&8)|(e.host&&1)|(e.self&&2)|(e.skipSelf&&4)}function Vi(e){return{optional:!!(e&8),host:!!(e&1),self:!!(e&2),skipSelf:!!(e&4)}}function Hi(e){let t=[];for(let n=0;nArray.isArray(e)?Gi(e,t):t(e))}function Ki(e,t,n){t>=e.length?e.push(n):e.splice(t,0,n)}function qi(e,t){return t>=e.length-1?e.pop():e.splice(t,1)[0]}function Ji(e,t,n,r){let i=e.length;if(i==t)e.push(n,r);else if(i===1)e.push(r,e[0]),e[0]=n;else{for(i--,e.push(e[i-1],e[i]);i>t;){let t=i-2;e[i]=e[t],i--}e[t]=n,e[t+1]=r}}function Yi(e,t,n){let r=Zi(e,t);return r>=0?e[r|1]=n:(r=~r,Ji(e,r,t,n)),r}function Xi(e,t){let n=Zi(e,t);if(n>=0)return e[n|1]}function Zi(e,t){return Qi(e,t,1)}function Qi(e,t,n){let r=0,i=e.length>>n;for(;i!==r;){let a=r+(i-r>>1),o=e[a<t?i=a:r=a+1}return~(i<{n.push(e)};return Gi(t,e=>{let t=e;ca(t,a,[],r)&&(i||=[],i.push(t))}),i!==void 0&&sa(i,a),n}function sa(e,t){for(let n=0;n{t(e,r)})}}function ca(e,t,n,r){if(e=ni(e),!e)return!1;let i=null,a=ci(e),o=!a&&vi(e);if(!a&&!o){let t=e.ngModule;if(a=ci(t),a)i=t;else return!1}else if(o&&!o.standalone)return!1;else i=e;let s=r.has(i);if(o){if(s)return!1;if(r.add(i),o.dependencies){let e=typeof o.dependencies==`function`?o.dependencies():o.dependencies;for(let i of e)ca(i,t,n,r)}}else if(a){if(a.imports!=null&&!s){r.add(i);let e;try{Gi(a.imports,i=>{ca(i,t,n,r)&&(e||=[],e.push(i))})}finally{}e!==void 0&&sa(e,t)}if(!s){let e=Wi(i)||(()=>new i);t({provide:i,useFactory:e,deps:ea},i),t({provide:ra,useValue:i,multi:!0},i),t({provide:ta,useValue:()=>zi(i),multi:!0},i)}let o=a.providers;if(o!=null&&!s){let n=e;la(o,e=>{t(e,n)})}}else return!1;return i!==e&&e.providers!==void 0}function la(e,t){for(let n of e)di(n)&&(n=n.ɵproviders),Array.isArray(n)?la(n,t):t(n)}var ua=Zr({provide:String,useValue:Zr});function da(e){return typeof e==`object`&&!!e&&ua in e}function fa(e){return!!(e&&e.useExisting)}function pa(e){return!!(e&&e.useFactory)}function ma(e){return typeof e==`function`}var ha=new N(``),ga={},_a={},va=void 0;function ya(){return va===void 0&&(va=new ia),va}var ba=class{},xa=class extends ba{parent;source;scopes;records=new Map;_ngOnDestroyHooks=new Set;_onDestroyHooks=[];get destroyed(){return this._destroyed}_destroyed=!1;injectorDefTypes;constructor(e,t,n,r){super(),this.parent=t,this.source=n,this.scopes=r,ja(e,e=>this.processProvider(e)),this.records.set(na,Da(void 0,this)),r.has(`environment`)&&this.records.set(ba,Da(void 0,this));let i=this.records.get(ha);i!=null&&typeof i.value==`string`&&this.scopes.add(i.value),this.injectorDefTypes=new Set(this.get(ra,ea,{self:!0}))}retrieve(e,t){let n=Bi(t)||0;try{return this.get(e,Fi,n)}catch(e){if(qn(e))return e;throw e}}destroy(){Ea(this),this._destroyed=!0;let e=j(null);try{for(let e of this._ngOnDestroyHooks)e.ngOnDestroy();let e=this._onDestroyHooks;this._onDestroyHooks=[];for(let t of e)t()}finally{this.records.clear(),this._ngOnDestroyHooks.clear(),this.injectorDefTypes.clear(),j(e)}}onDestroy(e){return Ea(this),this._onDestroyHooks.push(e),()=>this.removeOnDestroy(e)}runInContext(e){Ea(this);let t=Gn(this),n=Mi(void 0);try{return e()}finally{Gn(t),Mi(n)}}get(e,t=Fi,n){if(Ea(this),Object.hasOwn(e,_i))return e[_i](this);let r=Bi(n),i=Gn(this),a=Mi(void 0);try{if(!(r&4)){let t=this.records.get(e);if(t===void 0){let n=Aa(e)&&ai(e);t=n&&this.injectableDefInScope(n)?Da(Sa(e),ga):null,this.records.set(e,t)}if(t!=null)return this.hydrate(e,t,r)}let n=r&2?ya():this.parent;return t=r&8&&t===Fi?null:t,n.get(e,t)}catch(e){let t=ki(e);throw t===-200||t===-201?new M(t,null):e}finally{Mi(a),Gn(i)}}resolveInjectorInitializers(){let e=j(null),t=Gn(this),n=Mi(void 0);try{let e=this.get(ta,ea,{self:!0});for(let t of e)t()}finally{Gn(t),Mi(n),j(e)}}toString(){return`R3Injector[...]`}processProvider(e){e=ni(e);let t=ma(e)?e:ni(e&&e.provide),n=wa(e);if(!ma(e)&&e.multi===!0){let n=this.records.get(t);n||(n=Da(void 0,ga,!0),n.factory=()=>Hi(n.multi),this.records.set(t,n)),t=e,n.multi.push(e)}this.records.set(t,n)}hydrate(e,t,n){let r=j(null);try{if(t.value===_a)throw Ei(``);return t.value===ga&&(t.value=_a,t.value=t.factory(void 0,n)),typeof t.value==`object`&&t.value&&ka(t.value)&&this._ngOnDestroyHooks.add(t.value),t.value}finally{j(r)}}injectableDefInScope(e){if(!e.providedIn)return!1;let t=ni(e.providedIn);return typeof t==`string`?t===`any`||this.scopes.has(t):this.injectorDefTypes.has(t)}removeOnDestroy(e){let t=this._onDestroyHooks.indexOf(e);t!==-1&&this._onDestroyHooks.splice(t,1)}};function Sa(e){let t=ai(e),n=t===null?Wi(e):t.factory;if(n!==null)return n;if(e instanceof N)throw new M(-204,!1);if(e instanceof Function)return Ca(e);throw new M(-204,!1)}function Ca(e){if(e.length>0)throw new M(-204,!1);let t=si(e);return t===null?()=>new e:()=>t.factory(e)}function wa(e){return da(e)?Da(void 0,e.useValue):Da(Ta(e),ga)}function Ta(e,t,n){let r;if(ma(e)){let t=ni(e);return Wi(t)||Sa(t)}if(da(e))r=()=>ni(e.useValue);else if(pa(e))r=()=>e.useFactory(...Hi(e.deps||[]));else if(fa(e))r=(t,n)=>zi(ni(e.useExisting),n!==void 0&&n&8?8:void 0);else{let t=ni(e&&(e.useClass||e.provide));if(Oa(e))r=()=>new t(...Hi(e.deps));else return Wi(t)||Sa(t)}return r}function Ea(e){if(e.destroyed)throw new M(-205,!1)}function Da(e,t,n=!1){return{factory:e,value:t,multi:n?[]:void 0}}function Oa(e){return!!e.deps}function ka(e){return typeof e==`object`&&!!e&&typeof e.ngOnDestroy==`function`}function Aa(e){return typeof e==`function`||typeof e==`object`&&e.ngMetadataName===`InjectionToken`}function ja(e,t){for(let n of e)Array.isArray(n)?ja(n,t):n&&di(n)?ja(n.ɵproviders,t):t(n)}function Ma(e,t){let n;e instanceof xa?(Ea(e),n=e):n=new Li(e);let r=Gn(n),i=Mi(void 0);try{return t()}finally{Gn(r),Mi(i)}}function Na(){return ji()!==void 0||Wn()!=null}var Pa=1;function Fa(e){return Array.isArray(e)&&typeof e[Pa]==`object`}function Ia(e){return Array.isArray(e)&&e[Pa]===!0}function La(e){return!!(e.flags&4)}function Ra(e){return e.componentOffset>-1}function za(e){return(e.flags&1)==1}function Ba(e){return!!e.template}function Va(e){return!!(e[2]&512)}function Ha(e){return(e[2]&256)==256}var Ua=`math`;function Wa(e){for(;Array.isArray(e);)e=e[0];return e}function Ga(e,t){return Wa(t[e])}function Ka(e,t){return Wa(t[e.index])}function qa(e,t){return e.data[t]}function Ja(e,t){return e[t]}function Ya(e,t,n,r){n>=e.data.length&&(e.data[n]=null,e.blueprint[n]=null),t[n]=r}function Xa(e,t){let n=t[e];return Fa(n)?n:n[0]}function Za(e){return(e[2]&128)==128}function Qa(e,t){return t==null?null:e[t]}function $a(e){e[17]=0}function eo(e){e[2]&1024||(e[2]|=1024,Za(e)&&io(e))}function to(e,t){for(;e>0;)t=t[14],e--;return t}function no(e){return!!(e[2]&9216||e[24]?.dirty)}function ro(e){e[10].changeDetectionScheduler?.notify(8),e[2]&64&&(e[2]|=1024),no(e)&&io(e)}function io(e){e[10].changeDetectionScheduler?.notify(0);let t=so(e);for(;t!==null&&!(t[2]&8192||(t[2]|=8192,!Za(t)));)t=so(t)}function ao(e,t){if(Ha(e))throw new M(911,!1);e[21]===null&&(e[21]=[]),e[21].push(t)}function oo(e,t){if(e[21]===null)return;let n=e[21].indexOf(t);n!==-1&&e[21].splice(n,1)}function so(e){let t=e[3];return Ia(t)?t[3]:t}function co(e){return e[7]??=[]}function lo(e){return e.cleanup??=[]}var F={lFrame:Go(null),bindingsEnabled:!0,skipHydrationRootTNode:null},uo=!1;function fo(){return F.lFrame.elementDepthCount}function po(){F.lFrame.elementDepthCount++}function mo(){F.lFrame.elementDepthCount--}function ho(){return F.bindingsEnabled}function go(){return F.skipHydrationRootTNode!==null}function _o(e){return F.skipHydrationRootTNode===e}function vo(){F.skipHydrationRootTNode=null}function I(){return F.lFrame.lView}function yo(){return F.lFrame.tView}function bo(e){return F.lFrame.contextLView=e,e[8]}function xo(e){return F.lFrame.contextLView=null,e}function So(){let e=Co();for(;e!==null&&e.type===64;)e=e.parent;return e}function Co(){return F.lFrame.currentTNode}function wo(){let e=F.lFrame,t=e.currentTNode;return e.isParent?t:t.parent}function To(e,t){let n=F.lFrame;n.currentTNode=e,n.isParent=t}function Eo(){return F.lFrame.isParent}function Do(){F.lFrame.isParent=!1}function Oo(){return uo}function ko(e){let t=uo;return uo=e,t}function Ao(){let e=F.lFrame,t=e.bindingRootIndex;return t===-1&&(t=e.bindingRootIndex=e.tView.bindingStartIndex),t}function jo(){return F.lFrame.bindingIndex}function Mo(e){return F.lFrame.bindingIndex=e}function No(){return F.lFrame.bindingIndex++}function Po(e){let t=F.lFrame,n=t.bindingIndex;return t.bindingIndex+=e,n}function Fo(){return F.lFrame.inI18n}function Io(e,t){let n=F.lFrame;n.bindingIndex=n.bindingRootIndex=e,Ro(t)}function Lo(){return F.lFrame.currentDirectiveIndex}function Ro(e){F.lFrame.currentDirectiveIndex=e}function zo(e){let t=F.lFrame.currentDirectiveIndex;return t===-1?null:e[t]}function Bo(e){F.lFrame.currentQueryIndex=e}function Vo(e){let t=e[1];return t.type===2?t.declTNode:t.type===1?e[5]:null}function Ho(e,t,n){if(n&4){let r=t,i=e;for(;r=r.parent,r===null&&!(n&1)&&(r=Vo(i),!(r===null||(i=i[14],r.type&10))););if(r===null)return!1;t=r,e=i}let r=F.lFrame=Wo();return r.currentTNode=t,r.lView=e,!0}function Uo(e){let t=Wo(),n=e[1];F.lFrame=t,t.currentTNode=n.firstChild,t.lView=e,t.tView=n,t.contextLView=e,t.bindingIndex=n.bindingStartIndex,t.inI18n=!1}function Wo(){let e=F.lFrame,t=e===null?null:e.child;return t===null?Go(e):t}function Go(e){let t={currentTNode:null,isParent:!0,lView:null,tView:null,selectedIndex:-1,contextLView:null,elementDepthCount:0,currentNamespace:null,currentDirectiveIndex:-1,bindingRootIndex:-1,bindingIndex:-1,currentQueryIndex:0,parent:e,child:null,inI18n:!1};return e!==null&&(e.child=t),t}function Ko(){let e=F.lFrame;return F.lFrame=e.parent,e.currentTNode=null,e.lView=null,e}var qo=Ko;function Jo(){let e=Ko();e.isParent=!0,e.tView=null,e.selectedIndex=-1,e.contextLView=null,e.elementDepthCount=0,e.currentDirectiveIndex=-1,e.currentNamespace=null,e.bindingRootIndex=-1,e.bindingIndex=-1,e.currentQueryIndex=0}function Yo(e){return(F.lFrame.contextLView=to(e,F.lFrame.contextLView))[8]}function Xo(){return F.lFrame.selectedIndex}function Zo(e){F.lFrame.selectedIndex=e}function Qo(){let e=F.lFrame;return qa(e.tView,e.selectedIndex)}function $o(){F.lFrame.currentNamespace=`svg`}function es(){ts()}function ts(){F.lFrame.currentNamespace=null}function ns(){return F.lFrame.currentNamespace}var rs=!0;function is(){return rs}function as(e){rs=e}function os(e,t=null,n=null,r){let i=ss(e,t,n,r);return i.resolveInjectorInitializers(),i}function ss(e,t=null,n=null,r,i=new Set){return new xa([n||ea,aa(e)],t||ya(),null,i)}var cs=class e{static THROW_IF_NOT_FOUND=Fi;static NULL=new ia;static create(e,t){if(Array.isArray(e))return os({name:``},t,e,``);{let t=e.name??``;return os({name:t},e.parent,e.providers,t)}}static ɵprov=ii({token:e,providedIn:`any`,factory:()=>zi(na)});static __NG_ELEMENT_ID__=-1},ls=new N(``),us=class{static __NG_ELEMENT_ID__=fs;static __NG_ENV_ID__=e=>e},ds=class extends us{_lView;constructor(e){super(),this._lView=e}get destroyed(){return Ha(this._lView)}onDestroy(e){let t=this._lView;return ao(t,e),()=>oo(t,e)}};function fs(){return new ds(I())}var ps=new N(``),ms=(()=>{class e{taskId=0;pendingTasks=new Set;destroyed=!1;pendingTask=new Kr(!1);debugTaskTracker=P(ps,{optional:!0});get hasPendingTasks(){return!this.destroyed&&this.pendingTask.value}get hasPendingTasksObservable(){return this.destroyed?new Fr(e=>{e.next(!1),e.complete()}):this.pendingTask}add(){!this.hasPendingTasks&&!this.destroyed&&this.pendingTask.next(!0);let e=this.taskId++;return this.pendingTasks.add(e),this.debugTaskTracker?.add(e),e}has(e){return this.pendingTasks.has(e)}remove(e){this.pendingTasks.delete(e),this.debugTaskTracker?.remove(e),this.pendingTasks.size===0&&this.hasPendingTasks&&this.pendingTask.next(!1)}ngOnDestroy(){this.pendingTasks.clear(),this.hasPendingTasks&&this.pendingTask.next(!1),this.destroyed=!0,this.pendingTask.unsubscribe()}static ɵprov=ii({token:e,providedIn:`root`,factory:()=>new e})}return e})(),hs=class extends Wr{__isAsync;destroyRef=void 0;pendingTasks=void 0;constructor(e=!1){super(),this.__isAsync=e,Na()&&(this.destroyRef=P(us,{optional:!0})??void 0,this.pendingTasks=P(ms,{optional:!0})??void 0)}emit(e){let t=j(null);try{super.next(e)}finally{j(t)}}subscribe(e,t,n){let r=e,i=t||(()=>null),a=n;if(e&&typeof e==`object`){let t=e;r=t.next?.bind(t),i=t.error?.bind(t),a=t.complete?.bind(t)}this.__isAsync&&(i=this.wrapInTimeout(i),r&&=this.wrapInTimeout(r),a&&=this.wrapInTimeout(a));let o=super.subscribe({next:r,error:i,complete:a});return e instanceof cr&&e.add(o),o}wrapInTimeout(e){return t=>{let n=this.pendingTasks?.add();setTimeout(()=>{try{e(t)}finally{n!==void 0&&this.pendingTasks?.remove(n)}})}}};function gs(...e){}function _s(e){let t,n;function r(){e=gs;try{n!==void 0&&typeof cancelAnimationFrame==`function`&&cancelAnimationFrame(n),t!==void 0&&clearTimeout(t)}catch{}}return t=setTimeout(()=>{e(),r()}),typeof requestAnimationFrame==`function`&&(n=requestAnimationFrame(()=>{e(),r()})),()=>r()}function vs(e){return queueMicrotask(()=>e()),()=>{e=gs}}var ys=`isAngularZone`,bs=`isAngularZone_ID`,xs=0,Ss=class e{hasPendingMacrotasks=!1;hasPendingMicrotasks=!1;isStable=!0;onUnstable=new hs(!1);onMicrotaskEmpty=new hs(!1);onStable=new hs(!1);onError=new hs(!1);constructor(e){let{enableLongStackTrace:t=!1,shouldCoalesceEventChangeDetection:n=!1,shouldCoalesceRunChangeDetection:r=!1,scheduleInRootZone:i=!1}=e;if(typeof Zone>`u`)throw new M(908,!1);Zone.assertZonePatched();let a=this;a._nesting=0,a._outer=a._inner=Zone.current,Zone.TaskTrackingZoneSpec&&(a._inner=a._inner.fork(new Zone.TaskTrackingZoneSpec)),t&&Zone.longStackTraceZoneSpec&&(a._inner=a._inner.fork(Zone.longStackTraceZoneSpec)),a.shouldCoalesceEventChangeDetection=!r&&n,a.shouldCoalesceRunChangeDetection=r,a.callbackScheduled=!1,a.scheduleInRootZone=i,Es(a)}static isInAngularZone(){return typeof Zone<`u`&&Zone.current.get(ys)===!0}static assertInAngularZone(){if(!e.isInAngularZone())throw new M(909,!1)}static assertNotInAngularZone(){if(e.isInAngularZone())throw new M(909,!1)}run(e,t,n){return this._inner.run(e,t,n)}runTask(e,t,n,r){let i=this._inner,a=i.scheduleEventTask(`NgZoneEvent: `+r,e,Cs,gs,gs);try{return i.runTask(a,t,n)}finally{i.cancelTask(a)}}runGuarded(e,t,n){return this._inner.runGuarded(e,t,n)}runOutsideAngular(e){return this._outer.run(e)}},Cs={};function ws(e){if(e._nesting==0&&!e.hasPendingMicrotasks&&!e.isStable)try{e._nesting++,e.onMicrotaskEmpty.emit(null)}finally{if(e._nesting--,!e.hasPendingMicrotasks)try{e.runOutsideAngular(()=>e.onStable.emit(null))}finally{e.isStable=!0}}}function Ts(e){if(e.isCheckStableRunning||e.callbackScheduled)return;e.callbackScheduled=!0;function t(){_s(()=>{e.callbackScheduled=!1,Ds(e),e.isCheckStableRunning=!0,ws(e),e.isCheckStableRunning=!1})}e.scheduleInRootZone?Zone.root.run(()=>{t()}):e._outer.run(()=>{t()}),Ds(e)}function Es(e){let t=()=>{Ts(e)},n=xs++;e._inner=e._inner.fork({name:`angular`,properties:{[ys]:!0,[bs]:n,[bs+n]:!0},onInvokeTask:(n,r,i,a,o,s)=>{if(js(s))return n.invokeTask(i,a,o,s);try{return Os(e),n.invokeTask(i,a,o,s)}finally{(e.shouldCoalesceEventChangeDetection&&a.type===`eventTask`||e.shouldCoalesceRunChangeDetection)&&t(),ks(e)}},onInvoke:(n,r,i,a,o,s,c)=>{try{return Os(e),n.invoke(i,a,o,s,c)}finally{e.shouldCoalesceRunChangeDetection&&!e.callbackScheduled&&!Ms(s)&&t(),ks(e)}},onHasTask:(t,n,r,i)=>{t.hasTask(r,i),n===r&&(i.change==`microTask`?(e._hasPendingMicrotasks=i.microTask,Ds(e),ws(e)):i.change==`macroTask`&&(e.hasPendingMacrotasks=i.macroTask))},onHandleError:(t,n,r,i)=>(t.handleError(r,i),e.runOutsideAngular(()=>e.onError.emit(i)),!1)})}function Ds(e){e.hasPendingMicrotasks=!!(e._hasPendingMicrotasks||(e.shouldCoalesceEventChangeDetection||e.shouldCoalesceRunChangeDetection)&&e.callbackScheduled===!0)}function Os(e){e._nesting++,e.isStable&&(e.isStable=!1,e.onUnstable.emit(null))}function ks(e){e._nesting--,ws(e)}var As=class{hasPendingMicrotasks=!1;hasPendingMacrotasks=!1;isStable=!0;onUnstable=new hs;onMicrotaskEmpty=new hs;onStable=new hs;onError=new hs;run(e,t,n){return e.apply(t,n)}runGuarded(e,t,n){return e.apply(t,n)}runOutsideAngular(e){return e()}runTask(e,t,n,r){return e.apply(t,n)}};function js(e){return Ns(e,`__ignore_ng_zone__`)}function Ms(e){return Ns(e,`__scheduler_tick__`)}function Ns(e,t){return!Array.isArray(e)||e.length!==1?!1:e[0]?.data?.[t]===!0}var Ps=class{_console=console;handleError(e){this._console.error(`ERROR`,e)}},Fs=new N(``,{factory:()=>{let e=P(Ss),t=P(ba),n;return r=>{e.runOutsideAngular(()=>{t.destroyed&&!n?setTimeout(()=>{throw r}):(n??=t.get(Ps),n.handleError(r))})}}}),Is={provide:ta,useValue:()=>{P(Ps,{optional:!0})},multi:!0};function L(e,t){let[n,r,i]=Fn(e,t?.equal),a=n;return a[rn],a.set=r,a.update=i,a.asReadonly=Ls.bind(a),a}function Ls(){let e=this[rn];if(e.readonlyFn===void 0){let t=()=>this();t[rn]=e,e.readonlyFn=t}return e.readonlyFn}var Rs=new N(``,{factory:()=>zs}),zs=`ng`,Bs=new N(``),Vs=new N(``,{providedIn:`platform`,factory:()=>`unknown`}),Hs=new N(``,{factory:()=>P(ls).body?.querySelector(`[ngCspNonce]`)?.getAttribute(`ngCspNonce`)||null}),Us=(()=>{class e{view;node;constructor(e,t){this.view=e,this.node=t}static __NG_ELEMENT_ID__=Ws}return e})();function Ws(){return new Us(I(),So())}var Gs=class{},Ks=new N(``,{factory:()=>!0}),qs=new N(``),Js=(()=>{class e{static ɵprov=ii({token:e,providedIn:`root`,factory:()=>new Ys})}return e})(),Ys=class{dirtyEffectCount=0;queues=new Map;add(e){this.enqueue(e),this.schedule(e)}schedule(e){e.dirty&&this.dirtyEffectCount++}remove(e){let t=e.zone,n=this.queues.get(t);n.has(e)&&(n.delete(e),e.dirty&&this.dirtyEffectCount--)}enqueue(e){let t=e.zone;this.queues.has(t)||this.queues.set(t,new Set);let n=this.queues.get(t);n.has(e)||n.add(e)}flush(){for(;this.dirtyEffectCount>0;){let e=!1;for(let[t,n]of this.queues)e||=t===null?this.flushQueue(n):t.run(()=>this.flushQueue(n));e||(this.dirtyEffectCount=0)}}flushQueue(e){let t=!1;for(let n of e)n.dirty&&(this.dirtyEffectCount--,t=!0,n.run());return t}},Xs=class{[rn];constructor(e){this[rn]=e}destroy(){this[rn].destroy()}};function Zs(e,t){let n=t?.injector??P(cs),r=t?.manualCleanup===!0?null:n.get(us),i,a=n.get(Us,null,{optional:!0}),o=n.get(Gs);return a===null?i=nc(e,n.get(Js),o):(i=tc(a.view,o,e),r instanceof ds&&r._lView===a.view&&(r=null)),i.injector=n,r!==null&&(i.onDestroyFns=[r.onDestroy(()=>i.destroy())]),new Xs(i)}var Qs={...Vn,cleanupFns:void 0,zone:null,onDestroyFns:null,run(){let e=ko(!1);try{Hn(this)}finally{ko(e)}},cleanup(){if(!this.cleanupFns?.length)return;let e=j(null);try{for(;this.cleanupFns.length;)this.cleanupFns.pop()()}finally{this.cleanupFns=[],j(e)}}},$s={...Qs,consumerMarkedDirty(){this.scheduler.schedule(this),this.notifier.notify(12)},destroy(){if(yn(this),this.onDestroyFns!==null)for(let e of this.onDestroyFns)e();this.cleanup(),this.scheduler.remove(this)}},ec={...Qs,consumerMarkedDirty(){this.view[2]|=8192,io(this.view),this.notifier.notify(13)},destroy(){if(yn(this),this.onDestroyFns!==null)for(let e of this.onDestroyFns)e();this.cleanup(),this.view[23]?.delete(this)}};function tc(e,t,n){let r=Object.create(ec);return r.view=e,r.zone=typeof Zone<`u`?Zone.current:null,r.notifier=t,r.fn=rc(r,n),e[23]??=new Set,e[23].add(r),r.consumerMarkedDirty(r),r}function nc(e,t,n){let r=Object.create($s);return r.fn=rc(r,e),r.scheduler=t,r.notifier=n,r.zone=typeof Zone<`u`?Zone.current:null,r.scheduler.add(r),r.notifier.notify(12),r}function rc(e,t){return()=>{t(t=>(e.cleanupFns??=[]).push(t))}}var ic=(()=>{class e{internalPendingTasks=P(ms);scheduler=P(Gs);errorHandler=P(Fs);add(){let e=this.internalPendingTasks.add();return()=>{this.internalPendingTasks.has(e)&&(this.scheduler.notify(11),this.internalPendingTasks.remove(e))}}run(e){let t=this.add();try{e().catch(this.errorHandler).finally(t)}catch(e){this.errorHandler(e),t()}}static ɵprov=ii({token:e,providedIn:`root`,factory:()=>new e})}return e})(),ac=Symbol(`InputSignalNode#UNSET`),oc={...zn,transformFn:void 0,applyValueToInputSignal(e,t){Ln(e,t)}};function sc(e){return{toString:e}.toString()}var R=(function(e){return e[e.TemplateCreateStart=0]=`TemplateCreateStart`,e[e.TemplateCreateEnd=1]=`TemplateCreateEnd`,e[e.TemplateUpdateStart=2]=`TemplateUpdateStart`,e[e.TemplateUpdateEnd=3]=`TemplateUpdateEnd`,e[e.LifecycleHookStart=4]=`LifecycleHookStart`,e[e.LifecycleHookEnd=5]=`LifecycleHookEnd`,e[e.OutputStart=6]=`OutputStart`,e[e.OutputEnd=7]=`OutputEnd`,e[e.BootstrapApplicationStart=8]=`BootstrapApplicationStart`,e[e.BootstrapApplicationEnd=9]=`BootstrapApplicationEnd`,e[e.BootstrapComponentStart=10]=`BootstrapComponentStart`,e[e.BootstrapComponentEnd=11]=`BootstrapComponentEnd`,e[e.ChangeDetectionStart=12]=`ChangeDetectionStart`,e[e.ChangeDetectionEnd=13]=`ChangeDetectionEnd`,e[e.ChangeDetectionSyncStart=14]=`ChangeDetectionSyncStart`,e[e.ChangeDetectionSyncEnd=15]=`ChangeDetectionSyncEnd`,e[e.AfterRenderHooksStart=16]=`AfterRenderHooksStart`,e[e.AfterRenderHooksEnd=17]=`AfterRenderHooksEnd`,e[e.ComponentStart=18]=`ComponentStart`,e[e.ComponentEnd=19]=`ComponentEnd`,e[e.DeferBlockStateStart=20]=`DeferBlockStateStart`,e[e.DeferBlockStateEnd=21]=`DeferBlockStateEnd`,e[e.DynamicComponentStart=22]=`DynamicComponentStart`,e[e.DynamicComponentEnd=23]=`DynamicComponentEnd`,e[e.HostBindingsUpdateStart=24]=`HostBindingsUpdateStart`,e[e.HostBindingsUpdateEnd=25]=`HostBindingsUpdateEnd`,e})(R||{});function cc(e,t,n,r){t===null?e[n]=r:t.applyValueToInputSignal(t,r)}var lc=null;function uc(){return lc}var dc=[],z=function(e,t=null,n){for(let r=0;r=r)break}else t[c]<0&&(e[17]+=65536),(s>14>16&&(e[2]&3)===t&&(e[2]+=16384,vc(o,a)):vc(o,a)}var bc=-1,xc=class{factory;name;injectImpl;resolving=!1;canSeeViewProviders;multi;componentProviders;index;providerFactory;constructor(e,t,n,r){this.factory=e,this.name=r,this.canSeeViewProviders=t,this.injectImpl=n}};function Sc(e){return!!(e.flags&8)}function Cc(e){return!!(e.flags&16)}function wc(e,t,n){let r=0;for(;rt){o=a-1;break}}}for(;a>16}function Mc(e,t){let n=jc(e),r=t;for(;n>0;)r=r[14],n--;return r}var Nc=!0;function Pc(e){let t=Nc;return Nc=e,t}var Fc=255,Ic=5,Lc=0,Rc={};function zc(e,t,n){let r;typeof n==`string`?r=n.charCodeAt(0)||0:Object.hasOwn(n,gi)&&(r=n[gi]),r??=n[gi]=Lc++;let i=r&Fc,a=1<>Ic)]|=a}function Bc(e,t){let n=Hc(e,t);if(n!==-1)return n;let r=t[1];r.firstCreatePass&&(e.injectorIndex=t.length,Vc(r.data,e),Vc(t,null),Vc(r.blueprint,null));let i=Uc(e,t),a=e.injectorIndex;if(kc(i)){let e=Ac(i),n=Mc(i,t),r=n[1].data;for(let i=0;i<8;i++)t[a+i]=n[e+i]|r[e+i]}return t[a+8]=i,a}function Vc(e,t){e.push(0,0,0,0,0,0,0,0,t)}function Hc(e,t){return e.injectorIndex===-1||e.parent&&e.parent.injectorIndex===e.injectorIndex||t[e.injectorIndex+8]===null?-1:e.injectorIndex}function Uc(e,t){if(e.parent&&e.parent.injectorIndex!==-1)return e.parent.injectorIndex;let n=0,r=null,i=t;for(;i!==null;){if(r=il(i),r===null)return bc;if(n++,i=i[14],r.injectorIndex!==-1)return r.injectorIndex|n<<16}return bc}function Wc(e,t,n){zc(e,t,n)}function Gc(e,t,n){if(n&8||e!==void 0)return e;Di(t,`NodeInjector`)}function Kc(e,t,n,r){if(n&8&&r===void 0&&(r=null),!(n&3)){let i=e[9],a=Mi(void 0);try{return i?i.get(t,r,n&8):Ni(t,r,n&8)}finally{Mi(a)}}return Gc(r,t,n)}function qc(e,t,n,r=0,i){if(e!==null){if(t[2]&2048&&!(r&2)){let i=rl(e,t,n,r,Rc);if(i!==Rc)return i}let i=Jc(e,t,n,r,Rc);if(i!==Rc)return i}return Kc(t,n,r,i)}function Jc(e,t,n,r,i){let a=Qc(n);if(typeof a==`function`){if(!Ho(t,e,r))return r&1?Gc(i,n,r):Kc(t,n,r,i);try{let e;if(e=a(r),e==null&&!(r&8))Di(n);else return e}finally{qo()}}else if(typeof a==`number`){let i=null,o=Hc(e,t),s=bc,c=r&1?t[15][5]:null;for((o===-1||r&4)&&(s=o===-1?Uc(e,t):t[o+8],s===bc||!el(r,!1)?o=-1:(i=t[1],o=Ac(s),t=Mc(s,t)));o!==-1;){let e=t[1];if($c(a,o,e.data)){let e=Yc(o,t,n,i,r,c);if(e!==Rc)return e}s=t[o+8],s!==bc&&el(r,t[1].data[o+8]===c)&&$c(a,o,t)?(i=e,o=Ac(s),t=Mc(s,t)):o=-1}}return i}function Yc(e,t,n,r,i,a){let o=t[1],s=o.data[e+8],c=Xc(s,o,n,r==null?Ra(s)&&Nc:r!=o&&!!(s.type&3),i&1&&a===s);return c===null?Rc:Zc(t,o,c,s,i)}function Xc(e,t,n,r,i){let a=e.providerIndexes,o=t.data,s=a&1048575,c=e.directiveStart,l=e.directiveEnd,u=a>>20,d=r?s:s+u,f=i?s+u:l;for(let e=d;e=c&&t.type===n)return e}if(i){let e=o[c];if(e&&Ba(e)&&e.type===n)return c}return null}function Zc(e,t,n,r,i){let a=e[n],o=t.data;if(a instanceof xc){let s=a;if(s.resolving)throw Ei(``);let c=Pc(s.canSeeViewProviders);s.resolving=!0,o[n].type||o[n];let l=s.injectImpl?Mi(s.injectImpl):null;Ho(e,r,0);try{a=e[n]=s.factory(void 0,i,o,e,r),t.firstCreatePass&&n>=r.directiveStart&&fc(n,o[n],t)}finally{l!==null&&Mi(l),Pc(c),s.resolving=!1,qo()}}return a}function Qc(e){if(typeof e==`string`)return e.charCodeAt(0)||0;let t=Object.hasOwn(e,gi)?e[gi]:void 0;return typeof t==`number`?t>=0?t&Fc:nl:t}function $c(e,t,n){let r=1<>Ic)]&r)}function el(e,t){return!(e&2)&&!(e&1&&t)}var tl=class{_tNode;_lView;constructor(e,t){this._tNode=e,this._lView=t}get(e,t,n){return qc(this._tNode,this._lView,e,Bi(n),t)}};function nl(){return new tl(So(),I())}function rl(e,t,n,r,i){let a=e,o=t;for(;a!==null&&o!==null&&o[2]&2048&&!Va(o);){let e=Jc(a,o,n,r|2,Rc);if(e!==Rc)return e;r&=-5;let t=a.parent;if(!t){let e=o[20];if(e){let t=e.get(n,Rc,r);if(t!==Rc)return t}t=il(o),o=o[14]}a=t}return i}function il(e){let t=e[1],n=t.type;return n===2?t.declTNode:n===1?e[5]:null}var al=()=>(typeof requestIdleCallback<`u`?requestIdleCallback:e=>setTimeout(e)).bind(globalThis),ol=()=>(typeof requestIdleCallback<`u`?cancelIdleCallback:clearTimeout).bind(globalThis),sl=new N(``,{factory:()=>new cl}),cl=class{requestIdleCallback=al();cancelIdleCallback=ol();requestOnIdle(e,t){return this.requestIdleCallback(e,t)}cancelOnIdle(e){return this.cancelIdleCallback(e)}};function ll(e){return{token:e.token,providedIn:e.autoProvided===!1?null:`root`,factory:e.factory,value:void 0}}function ul(){return dl(So(),I())}function dl(e,t){return new fl(Ka(e,t))}var fl=(()=>{class e{nativeElement;constructor(e){this.nativeElement=e}static __NG_ELEMENT_ID__=ul}return e})();function pl(e){return(e.flags&128)==128}var ml=(function(e){return e[e.OnPush=0]=`OnPush`,e[e.Eager=1]=`Eager`,e[e.Default=1]=`Default`,e})(ml||{}),hl=new Map,gl=0;function _l(){return gl++}function vl(e){hl.set(e[19],e)}function yl(e){hl.delete(e[19])}var bl=`__ngContext__`;function xl(e,t){Fa(t)?(e[bl]=t[19],vl(t)):e[bl]=t}function Sl(e){return wl(e[12])}function Cl(e){return wl(e[4])}function wl(e){for(;e!==null&&!Ia(e);)e=e[4];return e}var Tl=void 0;function El(e){Tl=e}function Dl(){if(Tl!==void 0)return Tl;if(typeof document<`u`)return document;throw new M(210,!1)}var Ol=!1,kl=new N(``,{factory:()=>Ol}),Al=new N(``),jl=new WeakMap;function Ml(e,t){if(typeof e!=`object`||!e)return;let n=jl.get(e);n||(n=new WeakSet,jl.set(e,n)),n.add(t)}var Nl=new N(``);function Pl(e){return(e.flags&32)==32}var Fl=()=>null;function Il(e,t,n=!1){return Fl(e,t,n)}function Ll(e){return e.get(Al,!1,{optional:!0})}function Rl(e,t){let n=e.contentQueries;if(n!==null){let r=j(null);try{for(let r=0;r|^->||--!>|)/g,Kl=`​$1​`;function ql(e){return e.replace(Wl,e=>e.replace(Gl,Kl))}function Jl(e,t){return e.createText(t)}function Yl(e,t,n){e.setValue(t,n)}function Xl(e,t){return e.createComment(ql(t))}function Zl(e,t,n){return e.createElement(t,n)}function Ql(e,t,n,r,i){e.insertBefore(t,n,r,i)}function $l(e,t,n){e.appendChild(t,n)}function eu(e,t,n,r,i){r===null?$l(e,t,n):Ql(e,t,n,r,i)}function tu(e,t,n,r){e.removeChild(null,t,n,r)}function nu(e,t,n){e.setAttribute(t,`style`,n)}function ru(e,t,n){n===``?e.removeAttribute(t,`class`):e.setAttribute(t,`class`,n)}function iu(e,t,n){let{mergedAttrs:r,classes:i,styles:a}=n;r!==null&&wc(e,t,r),i!==null&&ru(e,t,i),a!==null&&nu(e,t,a)}function au(e,t,n){let r=e.length;for(;;){let i=e.indexOf(t,n);if(i===-1)return i;if(i===0||e.charCodeAt(i-1)<=32){let n=t.length;if(i+n===r||e.charCodeAt(i+n)<=32)return i}n=i+1}}var ou=`ng-template`;function su(e,t,n,r){let i=0;if(r){for(;i-1){let e;for(;++ia?``:i[u+1].toLowerCase(),r&2&&l!==e){if(du(r))return!1;o=!0}}}}}return du(r)||o}function du(e){return!(e&1)}function fu(e,t,n,r){if(t===null)return-1;let i=0;if(r||!n){let n=!1;for(;i-1)for(n++;n0?`="`+t+`"`:``)+`]`}else r&8?i+=`.`+o:r&4&&(i+=` `+o)}else i!==``&&!du(o)&&(t+=gu(a,i),i=``),r=o,a||=!du(r);n++}return i!==``&&(t+=gu(a,i)),t}function vu(e){return e.map(_u).join(`,`)}function yu(e){let t=[],n=[],r=1,i=2;for(;r=0;e--){let{el:n,declarationView:s}=r[e],c=n.parentNode;n===t?(r.splice(e,1),Du.add(n),n.dispatchEvent(new CustomEvent(`animationend`,{detail:{cancel:!0}}))):(a&&n===a||c&&i&&c!==i&&(o===null||s===null||o===s))&&(r.splice(e,1),n.dispatchEvent(new CustomEvent(`animationend`,{detail:{cancel:!0}})),n.parentNode?.removeChild(n))}}function ku(e,t,n){let r=Eu(n),i=Tu.get(e);i?i.some(e=>e.el===t)||i.push({el:t,declarationView:r}):Tu.set(e,[{el:t,declarationView:r}])}var Au=(function(e){return e[e.CHANGE_DETECTION=0]=`CHANGE_DETECTION`,e[e.AFTER_NEXT_RENDER=1]=`AFTER_NEXT_RENDER`,e})(Au||{}),ju=new N(``),Mu=new Set;function Nu(e){Mu.has(e)||(Mu.add(e),performance?.mark?.(`mark_feature_usage`,{detail:{feature:e}}))}var Pu=(()=>{class e{impl=null;execute(){this.impl?.execute()}static ɵprov=ii({token:e,providedIn:`root`,factory:()=>new e})}return e})(),Fu=new N(``,{factory:()=>{let e=P(ba),t=new Set;return e.onDestroy(()=>t.clear()),{queue:t,isScheduled:!1,scheduler:null,injector:e}}});function Iu(e,t,n){let r=e.get(Fu);if(Array.isArray(t))for(let e of t)r.queue.add(e),n?.detachedLeaveAnimationFns?.push(e);else r.queue.add(t),n?.detachedLeaveAnimationFns?.push(t);r.scheduler&&r.scheduler(e)}function Lu(e,t){let n=e.get(Fu);if(Array.isArray(t))for(let e of t)n.queue.delete(e);else n.queue.delete(t)}function Ru(e,t){let n=e.get(Fu);if(t.detachedLeaveAnimationFns){for(let e of t.detachedLeaveAnimationFns)n.queue.delete(e);t.detachedLeaveAnimationFns=void 0}}function zu(e,t){for(let[n,r]of t)Iu(e,r.animateFns)}function Bu(e,t,n,r){let i=e?.[26]?.enter;t!==null&&i&&i.has(n.index)&&zu(r,i)}function Vu(e,t,n,r){try{n.get(na)}catch{return r(!1)}let i=e?.[26];i?.enter?.has(t.index)&&Lu(n,i.enter.get(t.index).animateFns);let a=Hu(e,t,i);if(a.size===0){let n=!1;if(e){let r=[];Wu(e,t,r),n=r.length>0}if(!n)return r(!1)}e&&wu.add(e[19]),Iu(n,()=>Uu(e,t,i||void 0,a,r),i||void 0)}function Hu(e,t,n){let r=new Map,i=n?.leave;if(i&&i.has(t.index)&&r.set(t.index,i.get(t.index)),e&&i)for(let[n,a]of i){if(r.has(n))continue;let i=e[1].data[n].parent;for(;i;){if(i===t){r.set(n,a);break}i=i.parent}}return r}function Uu(e,t,n,r,i){let a=[];if(n&&n.leave)for(let[e]of r){if(!n.leave.has(e))continue;let t=n.leave.get(e);for(let e of t.animateFns){let{promise:t}=e();a.push(t)}n.detachedLeaveAnimationFns=void 0}if(e&&Wu(e,t,a),a.length>0){let t=n||e?.[26];if(t){let n=t.running;n&&a.push(n),t.running=Promise.allSettled(a),Ku(e,t.running,i)}else Promise.allSettled(a).then(()=>{e&&wu.delete(e[19]),i(!0)})}else e&&wu.delete(e[19]),i(!1)}function Wu(e,t,n){if(t.type&12){let r=e[t.index];if(Ia(r))for(let e=10;e{e[26]?.running===t&&(e[26].running=void 0,wu.delete(e[19])),n(!0)})}function qu(e,t,n,r,i,a,o,s){if(i!=null){let c,l=!1;Ia(i)?c=i:Fa(i)&&(l=!0,i=i[0]);let u=Wa(i);e===0&&r!==null?(Bu(s,r,a,n),o==null?$l(t,r,u):Ql(t,r,u,o||null,!0)):e===1&&r!==null?(Bu(s,r,a,n),Ql(t,r,u,o||null,!0),Ou(a,u,s)):e===2?(s?.[26]?.leave?.has(a.index)&&ku(a,u,s),Du.delete(u),Vu(s,a,n,e=>{if(Du.has(u)){Du.delete(u);return}tu(t,u,l,e)})):e===3&&(Du.delete(u),Vu(s,a,n,()=>{t.destroyNode(u)})),c!=null&&gd(t,e,n,c,a,r,o)}}function Ju(e,t){Xu(e,t),t[0]=null,t[5]=null}function Yu(e,t,n,r,i,a){r[0]=i,r[5]=t,pd(e,r,n,1,i,a)}function Xu(e,t){t[10].changeDetectionScheduler?.notify(9),pd(e,t,t[11],2,null,null)}function Zu(e){let t=e[12];if(!t)return ed(e[1],e);for(;t;){let n=null;if(Fa(t))n=t[12];else{let e=t[10];e&&(n=e)}if(!n){for(;t&&!t[4]&&t!==e;)Fa(t)&&ed(t[1],t),t=t[3];t===null&&(t=e),Fa(t)&&ed(t[1],t),n=t&&t[4]}t=n}}function Qu(e,t){let n=e[9],r=n.indexOf(t);n.splice(r,1)}function $u(e,t){if(Ha(t))return;let n=t[11];n.destroyNode&&pd(e,t,n,3,null,null),Zu(t)}function ed(e,t){if(Ha(t))return;let n=j(null);try{t[2]&=-129,t[2]|=256,t[24]&&yn(t[24]),nd(e,t),td(e,t),t[1].type===1&&t[11].destroy();let n=t[16];if(n!==null&&Ia(t[3])){n!==t[3]&&Qu(n,t);let r=t[18];r!==null&&r.detachView(e)}yl(t)}finally{j(n)}}function td(e,t){let n=e.cleanup,r=t[7];if(n!==null)for(let e=0;e=0?r[t]():r[-t].unsubscribe(),e+=2}else{let t=r[n[e+1]];n[e].call(t)}r!==null&&(t[7]=null);let i=t[21];if(i!==null){t[21]=null;for(let e=0;e27&&Ed(e,t,27,!1),z(o?R.TemplateUpdateStart:R.TemplateCreateStart,i,n),n(r,i)}finally{Zo(a),z(o?R.TemplateUpdateEnd:R.TemplateCreateEnd,i,n)}}function Ad(e,t,n){Ld(e,t,n),(n.flags&64)==64&&Rd(e,t,n)}function jd(e,t,n=Ka){let r=t.localNames;if(r!==null){let i=t.index+1;for(let a=0;a{io(e.lView)},consumerOnSignalRead(){this.lView[24]=this}};function lf(e){let t=e[24]??Object.create(uf);return t.lView=e,t}var uf={...on,consumerIsAlwaysLive:!0,kind:`template`,consumerMarkedDirty:e=>{let t=so(e.lView);for(;t&&!df(t[1]);)t=so(t);t&&eo(t)},consumerOnSignalRead(){this.lView[24]=this}};function df(e){return e.type!==2}function ff(e){if(e[23]===null)return;let t=!0;for(;t;){let n=!1;for(let t of e[23])if(t.dirty&&(n=!0,t.zone===null||Zone.current===t.zone?t.run():t.zone.run(()=>t.run()),e[23]===null))return;t=n&&!!(e[2]&8192)}}var pf=100;function mf(e,t=0){let n=e[10].rendererFactory;n.begin?.();try{hf(e,t)}finally{n.end?.()}}function hf(e,t){let n=Oo();try{ko(!0),xf(e,t);let n=0;for(;no(e);){if(n===pf)throw new M(103,!1);n++,xf(e,1)}}finally{ko(n)}}function gf(e,t,n,r){if(Ha(t))return;let i=t[2];Uo(t);let a=!0,o=null,s=null;df(e)?(s=af(t),o=mn(s)):an()===null?(a=!1,s=lf(t),o=mn(s)):t[24]&&=(yn(t[24]),null);try{$a(t),Mo(e.bindingStartIndex),n!==null&&kd(e,t,n,2,r);let a=(i&3)==3;if(a){let n=e.preOrderCheckHooks;n!==null&&mc(t,n,null)}else{let n=e.preOrderHooks;n!==null&&hc(t,n,0,null),gc(t,0)}if(vf(t),ff(t),_f(t,0),e.contentQueries!==null&&Rl(e,t),a){let n=e.contentCheckHooks;n!==null&&mc(t,n)}else{let n=e.contentHooks;n!==null&&hc(t,n,1),gc(t,1)}Cf(e,t);let o=e.components;o!==null&&Sf(t,o,0);let s=e.viewQuery;if(s!==null&&zl(2,s,r),a){let n=e.viewCheckHooks;n!==null&&mc(t,n)}else{let n=e.viewHooks;n!==null&&hc(t,n,2),gc(t,2)}if(e.firstUpdatePass===!0&&(e.firstUpdatePass=!1),t[22]){for(let e of t[22])e();t[22]=null}nf(t),t[2]&=-73}catch(e){throw io(t),e}finally{s!==null&&(gn(s,o),a&&sf(s)),Jo()}}function _f(e,t){for(let n=Sl(e);n!==null;n=Cl(n))for(let e=10;e0&&(e[n-1][4]=r[4]);let a=qi(e,10+t);Ju(r[1],r);let o=a[18];o!==null&&o.detachView(a[1]),r[3]=null,r[4]=null,r[2]&=-129}return r}function Af(e,t,n,r){let i=10+r,a=n.length;r>0&&(n[i-1][4]=t),r-1&&(kf(e,n),qi(t,n))}this._attachedToViewContainer=!1}$u(this._lView[1],this._lView)}onDestroy(e){ao(this._lView,e)}markForCheck(){wf(this._cdRefInjectingView||this._lView,4)}detach(){this._lView[2]&=-129}reattach(){ro(this._lView),this._lView[2]|=128}detectChanges(){this._lView[2]|=1024,mf(this._lView)}checkNoChanges(){}attachToViewContainerRef(){if(this._appRef)throw new M(902,!1);this._attachedToViewContainer=!0}detachFromAppRef(){this._appRef=null;let e=Va(this._lView),t=this._lView[16];t!==null&&!e&&Qu(t,this._lView),Xu(this._lView[1],this._lView)}attachToAppRef(e){if(this._attachedToViewContainer)throw new M(902,!1);this._appRef=e;let t=Va(this._lView),n=this._lView[16];n!==null&&!t&&jf(n,this._lView),ro(this._lView)}};function Nf(e,t,n,r,i){let a=e.data[t];if(a===null)a=Pf(e,t,n,r,i),Fo()&&(a.flags|=32);else if(a.type&64){a.type=n,a.value=r,a.attrs=i;let e=wo();a.injectorIndex=e===null?-1:e.injectorIndex}return To(a,!0),a}function Pf(e,t,n,r,i){let a=Co(),o=Eo(),s=o?a:a&&a.parent,c=e.data[t]=If(e,s,n,t,r,i);return Ff(e,c,a,o),c}function Ff(e,t,n,r){e.firstChild===null&&(e.firstChild=t),n!==null&&(r?n.child==null&&t.parent!==null&&(n.child=t):n.next===null&&(n.next=t,t.prev=n))}function If(e,t,n,r,i,a){let o=t?t.injectorIndex:-1,s=0;return go()&&(s|=128),{type:n,index:r,insertBeforeIndex:null,injectorIndex:o,directiveStart:-1,directiveEnd:-1,directiveStylingLast:-1,componentOffset:-1,controlDirectiveIndex:-1,customControlIndex:-1,propertyBindings:null,flags:s,providerIndexes:0,value:i,namespace:ns(),attrs:a,mergedAttrs:null,localNames:null,initialInputs:null,inputs:null,hostDirectiveInputs:null,outputs:null,hostDirectiveOutputs:null,directiveToIndex:null,tView:null,next:null,prev:null,projectionNext:null,child:null,parent:t,projection:null,styles:null,stylesWithoutHost:null,residualStyles:void 0,classes:null,classesWithoutHost:null,residualClasses:void 0,classBindings:0,styleBindings:0}}function Lf(e){let t=e[6]??[],n=e[3][11],r=[];for(let e of t)e.data.di===void 0?Rf(e,n):r.push(e);e[6]=r}function Rf(e,t){let n=0,r=e.firstChild;if(r){let i=e.data.r;for(;nnull,Bf=()=>null;function Vf(e,t){return zf(e,t)}function Hf(e,t,n){return Bf(e,t,n)}var Uf=class{},Wf=class{},Gf=(()=>{class e{static ɵprov=ii({token:e,providedIn:`root`,factory:()=>null})}return e})();function Kf(e){return e.debugInfo?.className||e.type.name||null}var qf={},Jf=class{injector;parentInjector;constructor(e,t){this.injector=e,this.parentInjector=t}get(e,t,n){let r=this.injector.get(e,qf,n);return r!==qf||t===qf?r:this.parentInjector.get(e,t,n)}};function Yf(e,t,n){return e[t]=n}function Xf(e,t){return e[t]}function Zf(e,t,n){if(n===bu)return!1;let r=e[t];return!Object.is(r,n)&&(e[t]=n,!0)}function Qf(e,t,n,r){let i=Zf(e,t,n);return Zf(e,t+1,r)||i}function $f(e,t,n,r,i){let a=Qf(e,t,n,r);return Zf(e,t+2,i)||a}function ep(e,t,n){return function r(i){let a=r.__ngNativeEl__;a!==void 0&&Ml(i,a),wf(Ra(e)?Xa(e.index,t):t,5);let o=t[8],s=tp(t,o,n,i),c=r.__ngNextListenerFn__;for(;c;)s=tp(t,o,c,i)&&s,c=c.__ngNextListenerFn__;return s}}function tp(e,t,n,r){let i=j(null);try{return z(R.OutputStart,t,n),n(r)!==!1}catch(t){return Kd(e,t),!1}finally{z(R.OutputEnd,t,n),j(i)}}function np(e,t,n,r,i,a,o,s){let c=za(e),l=!1,u=null;if(!r&&c&&(u=ip(t,n,a,e.index)),u!==null){let e=u.__ngLastListenerFn__||u;e.__ngNextListenerFn__=o,u.__ngLastListenerFn__=o,l=!0}else{let o=Ka(e,n),c=r?r(o):o;r||(s.__ngNativeEl__=o);let l=i.listen(c,a,s);rp(a)||ap(r?t=>r(Wa(t[e.index])):e.index,t,n,a,s,l,!1)}return l}function rp(e){return e.startsWith(`animation`)||e.startsWith(`transition`)}function ip(e,t,n,r){let i=e.cleanup;if(i!=null)for(let e=0;er?n[r]:null}typeof a==`string`&&(e+=2)}return null}function ap(e,t,n,r,i,a,o){let s=t.firstCreatePass?lo(t):null,c=co(n),l=c.length;c.push(i,a),s&&s.push(r,e,l,(l+1)*(o?-1:1))}function op(e,t,n,r,i,a){let o=t[n],s=t[1],c=o[s.data[n].outputs[r]].subscribe(a);ap(e.index,s,t,i,a,c,!0)}var sp=Symbol(`BINDING`),cp=new N(``);function lp(e,t,n){let r=n?e.styles:null,i=n?e.classes:null,a=0;if(t!==null)for(let e=0;e0&&(n.directiveToIndex=new Map);for(let c=0;c0;){let n=e[--t];if(typeof n==`number`&&n<0)return n}return 0}function Cp(e,t,n){if(n){if(t.exportAs)for(let r=0;r{let[n,r,i]=e[t],a={propName:n,templateName:t,isSignal:(r&Dd.SignalBased)!==0};return i&&(a.transform=i),a})}function jp(e){return Object.keys(e).map(t=>({propName:e[t],templateName:t}))}function Mp(e,t,n){let r=t instanceof ba?t:t?.injector;return r&&e.getStandaloneInjector!==null&&(r=e.getStandaloneInjector(r)||r),r?new Jf(n,r):n}function Np(e){let t=e.get(Wf,null);if(t===null)throw new M(407,!1);return{rendererFactory:t,sanitizer:e.get(Gf,null),changeDetectionScheduler:e.get(Gs,null),ngReflect:!1,tracingService:e.get(ju,null,{optional:!0})}}function Pp(e,t,n){let r=Ip(e);return Zl(t,r,r===`svg`?`svg`:r===`math`?Ua:n)}function Fp(e){if((e&&`localName`in e&&typeof e.localName==`string`?e.localName:e?.tagName)?.toLowerCase()===`script`)throw new M(905,!1)}function Ip(e){return(e.selectors[0][0]||`div`).toLowerCase()}var Lp=class{componentDef;ngModule;selector;componentType;ngContentSelectors;isBoundToModule;cachedInputs=null;cachedOutputs=null;get inputs(){return this.cachedInputs??=Ap(this.componentDef.inputs),this.cachedInputs}get outputs(){return this.cachedOutputs??=jp(this.componentDef.outputs),this.cachedOutputs}constructor(e,t){this.componentDef=e,this.ngModule=t,this.componentType=e.type,this.selector=vu(e.selectors),this.ngContentSelectors=e.ngContentSelectors??[],this.isBoundToModule=!!t}create(e,t,n,r,i,a,o){z(R.DynamicComponentStart);let s=j(null);try{let s=this.componentDef,c=Mp(s,r||this.ngModule,e),l=Np(c),u=l.tracingService;return u&&u.componentCreate?u.componentCreate(Kf(s),()=>this.createComponentRef(l,c,t,n,i,a,o)):this.createComponentRef(l,c,t,n,i,a,o)}finally{j(s)}}createComponentRef(e,t,n,r,i,a,o){let s=this.componentDef,c=Rp(r,s,a,i),l=e.rendererFactory.createRenderer(null,s),u=r?Md(l,r,s.encapsulation,t):Pp(s,l,o??null);Fp(u);let d=t.get(cp,null),f=zp(u,()=>t.get(ls,null)??Dl());d&&d.addHost(f);let p=a?.some(Vp)||i?.some(e=>typeof e!=`function`&&e.bindings.some(Vp)),m=xd(null,c,null,512|Cd(s),null,null,e,l,t,null,Il(u,t,!0));d&&Op&&f instanceof ShadowRoot&&ao(m,()=>{d.removeHost(f)}),m[27]=u,Uo(m);let h=null;try{let e=Tp(27,m,2,`#host`,()=>c.directiveRegistry,!0,0);iu(l,u,e),xl(u,m),Ad(c,m,e),Bl(c,e,m),Ep(c,e),n!==void 0&&Up(e,this.ngContentSelectors,n),h=Xa(e.index,m),m[8]=h[8],Xd(c,m,null)}catch(e){throw h!==null&&yl(h),yl(m),e}finally{z(R.DynamicComponentEnd),Jo()}return new Hp(this.componentType,m,!!p)}};function Rp(e,t,n,r){let i=e?[`ng-version`,`22.1.7`]:yu(t.selectors[0]),a=null,o=null,s=0;if(n)for(let e of n)s+=e[sp].requiredVars,e.create&&(e.targetIdx=0,(a??=[]).push(e)),e.update&&(e.targetIdx=0,(o??=[]).push(e));if(r)for(let e=0;e{if(n&1&&e)for(let t of e)t.create();if(n&2&&t)for(let e of t)e.update()}}function Vp(e){let t=e[sp].kind;return t===`input`||t===`twoWay`}var Hp=class extends Uf{_rootLView;_hasInputBindings;instance;hostView;changeDetectorRef;componentType;location;previousInputValues=null;_tNode;constructor(e,t,n){super(),this._rootLView=t,this._hasInputBindings=n,this._tNode=qa(t[1],27),this.location=dl(this._tNode,t),this.instance=Xa(this._tNode.index,t)[8],this.hostView=this.changeDetectorRef=new Mf(t,void 0),this.componentType=e}setInput(e,t){this._hasInputBindings;let n=this._tNode;if(this.previousInputValues??=new Map,this.previousInputValues.has(e)&&Object.is(this.previousInputValues.get(e),t))return;let r=this._rootLView;qd(n,r[1],r,e,t),this.previousInputValues.set(e,t),wf(Xa(n.index,r),1)}get injector(){return new tl(this._tNode,this._rootLView)}destroy(){this.hostView.destroy()}onDestroy(e){this.hostView.onDestroy(e)}};function Up(e,t,n){let r=e.projection=[];for(let e=0;e!1;function Gp(e,t,n){return Wp(e,t,n)}function Kp(e){return!!e&&typeof e.then==`function`}function qp(e){return!!e&&typeof e.subscribe==`function`}var Jp=class{},Yp=class extends Jp{injector;instance=null;constructor(e){super();let t=new xa([...e.providers,{provide:Jp,useValue:this}],e.parent||ya(),e.debugName,new Set([`environment`]));this.injector=t,e.runEnvironmentInitializers&&t.resolveInjectorInitializers()}destroy(){this.injector.destroy()}onDestroy(e){this.injector.onDestroy(e)}};function Xp(e,t,n=null){return new Yp({providers:e,parent:t,debugName:n,runEnvironmentInitializers:!0}).injector}var Zp=(()=>{class e{_injector;cachedInjectors=new Map;constructor(e){this._injector=e}getOrCreateStandaloneInjector(e){if(!e.standalone)return null;if(!this.cachedInjectors.has(e)){let t=oa(!1,e.type),n=t.length>0?Xp([t],this._injector,``):null;this.cachedInjectors.set(e,n)}return this.cachedInjectors.get(e)}ngOnDestroy(){try{for(let e of this.cachedInjectors.values())e!==null&&e.destroy()}finally{this.cachedInjectors.clear()}}static ɵprov=ii({token:e,providedIn:`environment`,factory:()=>new e(zi(ba))})}return e})();function Qp(e){return sc(()=>{let t=rm(e),n={...t,decls:e.decls,vars:e.vars,template:e.template,consts:e.consts||null,ngContentSelectors:e.ngContentSelectors,onPush:e.changeDetection!==ml.Eager,directiveDefs:null,pipeDefs:null,dependencies:t.standalone&&e.dependencies||null,getStandaloneInjector:t.standalone?e=>e.get(Zp).getOrCreateStandaloneInjector(n):null,getExternalStyles:null,signals:e.signals??!1,data:e.data||{},encapsulation:e.encapsulation||Vl.Emulated,styles:e.styles||ea,_:null,schemas:e.schemas||null,tView:null,id:``};t.standalone&&Nu(`NgStandalone`),im(n);let r=e.dependencies;return n.directiveDefs=am(r,$p),n.pipeDefs=am(r,bi),n.id=om(n),n})}function $p(e){return vi(e)||yi(e)}function em(e,t){if(e==null)return $i;let n={};for(let r in e)if(Object.hasOwn(e,r)){let i=e[r],a,o,s,c;Array.isArray(i)?(s=i[0],a=i[1],o=i[2]??a,c=i[3]||null):(a=i,o=i,s=Dd.None,c=null),n[a]=[r,s,c],t[a]=o}return n}function tm(e){if(e==null)return $i;let t={};for(let n in e)Object.hasOwn(e,n)&&(t[e[n]]=n);return t}function nm(e){return{type:e.type,name:e.name,factory:null,pure:e.pure!==!1,standalone:e.standalone??!0,onDestroy:e.type.prototype.ngOnDestroy||null}}function rm(e){let t={};return{type:e.type,providersResolver:null,viewProvidersResolver:null,factory:null,hostBindings:e.hostBindings||null,hostVars:e.hostVars||0,hostAttrs:e.hostAttrs||null,contentQueries:e.contentQueries||null,declaredInputs:t,inputConfig:e.inputs||$i,exportAs:e.exportAs||null,standalone:e.standalone??!0,signals:e.signals===!0,selectors:e.selectors||ea,viewQuery:e.viewQuery||null,features:e.features||null,setInput:null,resolveHostDirectives:null,hostDirectives:null,controlDef:null,signalFormsInputPresence:null,inputs:em(e.inputs,t),outputs:tm(e.outputs),debugInfo:null}}function im(e){e.features?.forEach(t=>t(e))}function am(e,t){return e?()=>{let n=typeof e==`function`?e():e,r=[];for(let e of n){let n=t(e);n!==null&&r.push(n)}return r}:null}function om(e){let t=0,n=typeof e.consts==`function`?``:e.consts,r=[e.selectors,e.ngContentSelectors,e.hostVars,e.hostAttrs,n,e.vars,e.decls,e.encapsulation,e.standalone,e.signals,e.exportAs,JSON.stringify(e.inputs),JSON.stringify(e.outputs),Object.getOwnPropertyNames(e.type.prototype),!!e.contentQueries,!!e.viewQuery];for(let e of r.join(`|`))t=Math.imul(31,t)+e.charCodeAt(0)<<0;return t+=2147483648,`c`+t}var sm=new N(``),cm=(()=>{class e{resolve;reject;initialized=!1;done=!1;donePromise=new Promise((e,t)=>{this.resolve=e,this.reject=t});appInits=P(sm,{optional:!0})??[];injector=P(cs);constructor(){}runInitializers(){if(this.initialized)return;let e=[];for(let t of this.appInits){let n=Ma(this.injector,t);if(Kp(n))e.push(n);else if(qp(n)){let t=new Promise((e,t)=>{n.subscribe({complete:e,error:t})});e.push(t)}}let t=()=>{this.done=!0,this.resolve()};Promise.all(e).then(()=>{t()}).catch(e=>{this.reject(e)}),e.length===0&&t(),this.initialized=!0}static ɵfac=function(t){return new(t||e)};static ɵprov=ll({token:e,factory:e.ɵfac})}return e})();function lm(e,t,n,r,i,a,o,s){if(n.firstCreatePass){e.mergedAttrs=Dc(e.mergedAttrs,e.attrs);let t=e.tView=vd(2,e,i,a,o,n.directiveRegistry,n.pipeRegistry,null,n.schemas,n.consts,null);n.queries!==null&&(n.queries.template(n,e),t.queries=n.queries.embeddedTView(e))}s&&(e.flags|=s),To(e,!1);let c=fm(n,t,e,r);is()&&cd(n,t,c,e),xl(c,t);let l=Tf(c,t,c,e);t[r+27]=l,Td(t,l),Gp(l,e,t)}function um(e,t,n,r,i,a,o,s,c,l,u){let d=n+27,f;if(t.firstCreatePass){if(f=Nf(t,d,4,o||null,s||null),l!=null){let e=Qa(t.consts,l);f.localNames=[];for(let t=0;t{class e{cachedInjectors=new Map;getOrCreateInjector(e,t,n,r){if(!this.cachedInjectors.has(e)){let i=n.length>0?Xp(n,t,r):null;this.cachedInjectors.set(e,i)}return this.cachedInjectors.get(e)}ngOnDestroy(){try{for(let e of this.cachedInjectors.values())e!==null&&e.destroy()}finally{this.cachedInjectors.clear()}}static ɵprov=ii({token:e,providedIn:`environment`,factory:()=>new e})}return e})(),Hm=new N(``);function Um(e,t,n){return e.get(Vm).getOrCreateInjector(t,e,n,``)}function Wm(e,t,n){if(e instanceof Jf){let r=e.injector,i=e.parentInjector;return new Jf(r,Um(i,t,n))}let r=e.get(ba);return r===e?Um(e,t,n):new Jf(e,Um(r,t,n))}function Gm(e,t,n,r=!1){let i=n[3],a=i[1];if(Ha(i))return;let o=Mm(i,t),s=o[1],c=o[Cm];if(!(c!==null&&ee.data.s===t[1])??-1;return{dehydratedView:n>-1?e[6][n]:null,dehydratedViewIx:n}}function qm(e,t,n,r,i){z(R.DeferBlockStateStart);let a=Im(e,i,r);if(a!==null){t[1]=e;let o=i[1],s=qa(o,a+27);Of(n,0);let c;if(e===_m.Complete){let e=Pm(o,r),t=e.providers;t&&t.length>0&&(c=Wm(i[9],e,t))}let{dehydratedView:l,dehydratedViewIx:u}=Km(n,t),d=Qd(i,s,null,{injector:c,dehydratedView:l});if(Df(n,d,0,$d(s,l)),eo(d),u>-1&&n[6]?.splice(u,1),(e===_m.Complete||e===_m.Error)&&Array.isArray(t[wm])){for(let e of t[wm])e();t[wm]=null}}z(R.DeferBlockStateEnd)}function Jm(e,t){return e{e.loadingState===mm.COMPLETE?Gm(_m.Complete,t,n):e.loadingState===mm.FAILED&&Gm(_m.Error,t,n)})}var Zm=null;function Qm(e,t){return t[9].get(Hm,null,{optional:!0})?.behavior!==Em.Manual}var $m=new N(``),eh=new N(``);function th(){Nn(()=>{throw new M(600,``)})}var nh=10,rh=(()=>{class e{_runningTick=!1;_destroyed=!1;_destroyListeners=[];_views=[];internalErrorHandler=P(Fs);afterRenderManager=P(Pu);zonelessEnabled=P(Ks);rootEffectScheduler=P(Js);dirtyFlags=0;tracingSnapshot=null;allTestViews=new Set;autoDetectTestViews=new Set;includeAllTestViews=!1;afterTick=new Wr;get allViews(){return[...(this.includeAllTestViews?this.allTestViews:this.autoDetectTestViews).keys(),...this._views]}get destroyed(){return this._destroyed}componentTypes=[];components=[];internalPendingTask=P(ms);get isStable(){return this.internalPendingTask.hasPendingTasksObservable.pipe(qr(e=>!e))}constructor(){P(ju,{optional:!0})}whenStable(){let e;return new Promise(t=>{e=this.isStable.subscribe({next:e=>{e&&t()}})}).finally(()=>{e.unsubscribe()})}_injector=P(ba);_rendererFactory=null;get injector(){return this._injector}bootstrap(e,t){return this.bootstrapImpl(e,t)}bootstrapImpl(e,t,n=cs.NULL){return this._injector.get(Ss).run(()=>{if(z(R.BootstrapComponentStart),!this._injector.get(cm).done)throw new M(405,``);let r=vi(e),i=this._injector.get(Jp),a=new Lp(r,i);this.componentTypes.push(e);let{hostElement:o,directives:s,bindings:c}=ih(t),l=o||a.selector,u=a.create(n,[],l,i.injector,s,c),d=u.location.nativeElement,f=u.injector.get($m,null);return f?.registerApplication(d),u.onDestroy(()=>{this.detachView(u.hostView),ah(this.components,u),f?.unregisterApplication(d)}),this._loadComponent(u),z(R.BootstrapComponentEnd,u),u})}tick(){this.zonelessEnabled||(this.dirtyFlags|=1),this._tick()}_tick(){z(R.ChangeDetectionStart),this.tracingSnapshot===null?this.tickImpl():this.tracingSnapshot.run(Au.CHANGE_DETECTION,this.tickImpl)}tickImpl=()=>{if(this._runningTick)throw z(R.ChangeDetectionEnd),new M(101,!1);let e=j(null);try{this._runningTick=!0,this.synchronize()}finally{this._runningTick=!1,this.tracingSnapshot?.dispose(),this.tracingSnapshot=null,j(e),this.afterTick.next(),z(R.ChangeDetectionEnd)}};synchronize(){this._rendererFactory===null&&!this._injector.destroyed&&(this._rendererFactory=this._injector.get(Wf,null,{optional:!0}));let e=0;for(;this.dirtyFlags!==0&&e++no(e))){this.dirtyFlags|=2;return}this.dirtyFlags&=-8}attachView(e){let t=e;this._views.push(t),t.attachToAppRef(this)}detachView(e){let t=e;ah(this._views,t),t.detachFromAppRef()}_loadComponent(e){this.attachView(e.hostView);try{this.tick()}catch(e){this.internalErrorHandler(e)}this.components.push(e),this._injector.get(eh,[]).forEach(t=>t(e))}ngOnDestroy(){if(!this._destroyed)try{this._destroyListeners.forEach(e=>e()),this._views.slice().forEach(e=>e.destroy())}finally{this._destroyed=!0,this._views=[],this._destroyListeners=[]}}onDestroy(e){return this._destroyListeners.push(e),()=>ah(this._destroyListeners,e)}destroy(){if(this._destroyed)throw new M(406,!1);let e=this._injector;e.destroy&&!e.destroyed&&e.destroy()}get viewCount(){return this._views.length}static ɵfac=function(t){return new(t||e)};static ɵprov=ll({token:e,factory:e.ɵfac})}return e})();function ih(e){return e===void 0||typeof e==`string`||e instanceof Element?{hostElement:e}:e}function ah(e,t){let n=e.indexOf(t);n>-1&&e.splice(n,1)}function oh(e,t,n){let r=t.get(ch);return r.add(e,n),()=>r.remove(e)}function sh(e){return(t,n)=>oh(t,n,e)}var ch=(()=>{class e{buckets=new Map;callbackBucket=new Map;applicationRef=P(rh);ngZone=P(Ss);idleService=P(sl);add(e,t){let n=lh(t);this.callbackBucket.set(e,n);let r=this.buckets.get(n);r??(r={idleId:null,queue:new Set},this.buckets.set(n,r)),r.queue.add(e),this.scheduleBucket(r,t)}remove(e){let t=this.callbackBucket.get(e);if(t===void 0)return;this.callbackBucket.delete(e);let n=this.buckets.get(t);n&&(n.queue.delete(e),n.queue.size===0&&(this.cancelBucket(n),this.buckets.delete(t)))}scheduleBucket(e,t){if(e.idleId!==null)return;let n=lh(t),r=r=>{for(let t of e.queue)if(t(),this.applicationRef._tick(),e.queue.delete(t),this.callbackBucket.delete(t),r&&r.timeRemaining()===0&&!r.didTimeout)break;e.idleId=null,e.queue.size>0?this.scheduleBucket(e,t):this.buckets.delete(n)};e.idleId=this.idleService.requestOnIdle(e=>this.ngZone.run(()=>r(e)),t)}cancelBucket(e){e.idleId!==null&&(this.idleService.cancelOnIdle(e.idleId),e.idleId=null)}ngOnDestroy(){for(let e of this.buckets.values())this.cancelBucket(e);this.buckets.clear(),this.callbackBucket.clear()}static ɵprov=ii({token:e,providedIn:`root`,factory:()=>new e})}return e})();function lh(e){return!e||e.timeout==null?``:`${e.timeout}`}function uh(e){let t=I(),n=So();if(Ym(t,n),!Qm(0,t))return;let r=t[9];Dm(0,Mm(t,n),e(()=>fh(0,t,n),r))}function dh(e,t,n){let r=t[9],i=t[1];if(e.loadingState!==mm.NOT_STARTED)return e.loadingPromise??Promise.resolve();let a=Mm(t,n),o=Bm(i,e);e.loadingState=mm.IN_PROGRESS,Om(1,a);let s=e.dependencyResolverFn,c=r.get(ic).add();return s?(e.loadingPromise=Promise.allSettled(s()).then(n=>{let r=!1,i=[],a=[];for(let e=0;e0&&(t.directiveRegistry=zm(t.directiveRegistry,i),e.providers=oa(!1,...i.map(e=>e.type))),a.length>0&&(t.pipeRegistry=zm(t.pipeRegistry,a))}}),e.loadingPromise.finally(()=>{e.loadingPromise=null,c()})):(e.loadingPromise=Promise.resolve().then(()=>{e.loadingPromise=null,e.loadingState=mm.COMPLETE,c()}),e.loadingPromise)}function fh(e,t,n){let r=t[1],i=t[n.index];if(!Qm(e,t))return;let a=Mm(t,n),o=Pm(r,n);switch(km(a),o.loadingState){case mm.NOT_STARTED:Gm(_m.Loading,n,i),dh(o,t,n),o.loadingState===mm.IN_PROGRESS&&Xm(o,n,i);break;case mm.IN_PROGRESS:Gm(_m.Loading,n,i),Xm(o,n,i);break;case mm.COMPLETE:Gm(_m.Complete,n,i);break;case mm.FAILED:Gm(_m.Error,n,i)}}function ph(e,t,n){return e===0?hh(t,n):e!==2||!hh(t,n)}function mh(e){return e!=null&&(e&1)==1}function hh(e,t){let n=e[9],r=Pm(e[1],t),i=Ll(n),a=mh(r.flags),o=Mm(e,t)[Sm]!==null;return!(a&&o&&i)}function gh(e,t,n,r,i,a,o,s,c,l){let u=I(),d=yo(),f=e+27,p=um(u,d,e,null,0,0),m=u[9],h=Ll(m);if(d.firstCreatePass){Nu(`NgDefer`);let e={primaryTmplIndex:t,loadingTmplIndex:r??null,placeholderTmplIndex:i??null,errorTmplIndex:a??null,placeholderBlockConfig:null,loadingBlockConfig:null,dependencyResolverFn:n??null,loadingState:mm.NOT_STARTED,loadingPromise:null,providers:null,hydrateTriggers:null,debug:null,flags:l??0};c?.(d,e,s,o),Fm(d,f,e)}let g=u[f];Gp(g,p,u);let _=null,v=null;if(g[6]?.length>0){let e=g[6][0].data;v=e.di??null,_=e.s}let y=[null,vm.Initial,null,null,null,null,v,_,null,null];Nm(u,f,y);let b=null;v!==null&&h&&(b=m.get(Nl),b.add(v,{lView:u,tNode:p,lContainer:g}));let ee=()=>{km(y),v!==null&&b?.cleanup([v])};Dm(0,y,()=>oo(u,ee)),ao(u,ee)}function _h(e){ph(0,I(),So())&&uh(sh({timeout:e}))}function vh(e,t,n,r){let i=I();return Zf(i,No(),t)&&(yo(),Vd(Qo(),i,e,t,n,r)),vh}var yh=class{destroy(e){}updateValue(e,t){}swap(e,t){let n=Math.min(e,t),r=Math.max(e,t),i=this.detach(r);if(r-n>1){let e=this.detach(n);this.attach(n,i),this.attach(r,e)}else this.attach(n,i)}move(e,t){this.attach(t,this.detach(e))}};function bh(e,t,n,r,i){return e===n&&Object.is(t,r)?1:Object.is(i(e,t),i(n,r))?-1:0}function xh(e,t,n,r){let i,a,o=0,s=e.length-1;if(Array.isArray(t)){j(r);let c=t.length-1;for(j(null);o<=s&&o<=c;){let r=e.at(o),l=t[o],u=bh(o,r,o,l,n);if(u!==0){u<0&&e.updateValue(o,l),o++;continue}let d=e.at(s),f=t[c],p=bh(s,d,c,f,n);if(p!==0){p<0&&e.updateValue(s,f),s--,c--;continue}let m=n(o,r),h=n(s,d),g=n(o,l);if(Object.is(g,h)){let t=n(c,f);Object.is(t,m)?(e.swap(o,s),e.updateValue(s,f),c--,s--):e.move(s,o),e.updateValue(o,l),o++;continue}if(i??=new Th,a??=wh(e,o,s,n),Sh(e,i,o,g))e.updateValue(o,l),o++,s++;else if(a.has(g))i.set(m,e.detach(o)),s--;else{let n=e.create(o,t[o]);e.attach(o,n),o++,s++}}for(;o<=c;)Ch(e,i,n,o,t[o]),o++}else if(t!=null){j(r);let c=t[Symbol.iterator]();j(null);let l=c.next();for(;!l.done&&o<=s;){let t=e.at(o),r=l.value,u=bh(o,t,o,r,n);if(u!==0)u<0&&e.updateValue(o,r),o++,l=c.next();else{i??=new Th,a??=wh(e,o,s,n);let u=n(o,r);if(Sh(e,i,o,u))e.updateValue(o,r),o++,s++,l=c.next();else if(!a.has(u))e.attach(o,e.create(o,r)),o++,s++,l=c.next();else{let r=n(o,t);i.set(r,e.detach(o)),s--}}}for(;!l.done;)Ch(e,i,n,e.length,l.value),l=c.next()}for(;o<=s;)e.destroy(e.detach(s--));i?.forEach(t=>{e.destroy(t)})}function Sh(e,t,n,r){return t!==void 0&&t.has(r)?(e.attach(n,t.get(r)),t.delete(r),!0):!1}function Ch(e,t,n,r,i){if(Sh(e,t,r,n(r,i)))e.updateValue(r,i);else{let t=e.create(r,i);e.attach(r,t)}}function wh(e,t,n,r){let i=new Set;for(let a=t;a<=n;a++)i.add(r(a,e.at(a)));return i}var Th=class{kvMap=new Map;_vMap=void 0;has(e){return this.kvMap.has(e)}delete(e){if(!this.has(e))return!1;let t=this.kvMap.get(e);return this._vMap!==void 0&&this._vMap.has(t)?(this.kvMap.set(e,this._vMap.get(t)),this._vMap.delete(t)):this.kvMap.delete(e),!0}get(e){return this.kvMap.get(e)}set(e,t){if(this.kvMap.has(e)){let n=this.kvMap.get(e);this._vMap===void 0&&(this._vMap=new Map);let r=this._vMap;for(;r.has(n);)n=r.get(n);r.set(n,t)}else this.kvMap.set(e,t)}forEach(e){for(let[t,n]of this.kvMap)if(e(n,t),this._vMap!==void 0){let r=this._vMap;for(;r.has(n);)n=r.get(n),e(n,t)}}};function V(e,t,n,r,i,a,o,s){Nu(`NgControlFlow`);let c=I(),l=yo();return um(c,l,e,t,n,r,i,Qa(l.consts,a),256,o,s),Eh}function Eh(e,t,n,r,i,a,o,s){Nu(`NgControlFlow`);let c=I(),l=yo();return um(c,l,e,t,n,r,i,Qa(l.consts,a),512,o,s),Eh}function H(e,t){Nu(`NgControlFlow`);let n=I(),r=No(),i=n[r]===bu?-1:n[r],a=i===-1?void 0:Mh(n,27+i);if(Zf(n,r,e)){let r=j(null);try{if(a!==void 0&&Of(a,0),e!==-1){let r=27+e,i=Mh(n,r),a=Lh(n[1],r),o=Hf(i,a,n);Df(i,Qd(n,a,t,{dehydratedView:o}),0,$d(a,o))}}finally{j(r)}}else if(a!==void 0){let e=Ef(a,0);e!==void 0&&(e[8]=t)}}var Dh=class{lContainer;$implicit;$index;constructor(e,t,n){this.lContainer=e,this.$implicit=t,this.$index=n}get $count(){return this.lContainer.length-10}};function Oh(e){return e}function kh(e,t){return t}var Ah=class{hasEmptyBlock;trackByFn;liveCollection;constructor(e,t,n){this.hasEmptyBlock=e,this.trackByFn=t,this.liveCollection=n}};function U(e,t,n,r,i,a,o,s,c,l,u,d,f){Nu(`NgControlFlow`);let p=I(),m=yo(),h=c!==void 0,g=I(),_=new Ah(h,s?o.bind(g[15][8]):o);g[27+e]=_,um(p,m,e+1,t,n,r,i,Qa(m.consts,a),256),h&&um(p,m,e+2,c,l,u,d,Qa(m.consts,f),512)}var jh=class extends yh{lContainer;hostLView;templateTNode;operationsCounter=void 0;needsIndexUpdate=!1;constructor(e,t,n){super(),this.lContainer=e,this.hostLView=t,this.templateTNode=n}get length(){return this.lContainer.length-10}at(e){return this.getLView(e)[8].$implicit}attach(e,t){let n=t[6];this.needsIndexUpdate||=e!==this.length,Df(this.lContainer,t,e,$d(this.templateTNode,n)),Nh(this.lContainer,e)}detach(e){return this.needsIndexUpdate||=e!==this.length-1,Ph(this.lContainer,e),Fh(this.lContainer,e)}create(e,t){let n=Vf(this.lContainer,this.templateTNode.tView.ssrId);return Qd(this.hostLView,this.templateTNode,new Dh(this.lContainer,t,e),{dehydratedView:n})}destroy(e){$u(e[1],e)}updateValue(e,t){this.getLView(e)[8].$implicit=t}reset(){this.needsIndexUpdate=!1}updateIndexes(){if(this.needsIndexUpdate)for(let e=0;e0){let e=n[9];Ru(e,r),wu.delete(n[19]),r.detachedLeaveAnimationFns=void 0}}function Ph(e,t){if(e.length<=10)return;let n=e[10+t],r=n?n[26]:void 0;r&&r.leave&&r.leave.size>0&&(r.detachedLeaveAnimationFns=[])}function Fh(e,t){return kf(e,t)}function Ih(e,t){return Ef(e,t)}function Lh(e,t){return qa(e,t)}function Rh(e,t,n){let r=I();return Zf(r,No(),t)&&(yo(),Pd(Qo(),r,e,t,r[11],n)),Rh}function zh(e,t,n,r,i){qd(t,e,n,i?`class`:`style`,r)}function G(e,t,n,r){let i=I(),a=i[1],o=e+27,s=a.firstCreatePass?Tp(o,i,2,t,Bd,ho(),n,r):a.data[o];if(Ra(s)){let n=i[10].tracingService;if(n&&n.componentCreate){let o=a.data[s.directiveStart+s.componentOffset];return n.componentCreate(Kf(o),()=>(Bh(e,t,i,s,r),G))}}return Bh(e,t,i,s,r),G}function Bh(e,t,n,r,i){if(Wd(r,n,e,t,Uh),za(r)){let e=n[1];Ad(e,n,r),Bl(e,r,n)}i!=null&&jd(n,r)}function K(){let e=yo(),t=Gd(So());return e.firstCreatePass&&Ep(e,t),_o(t)&&vo(),mo(),t.classesWithoutHost!=null&&Sc(t)&&zh(e,t,I(),t.classesWithoutHost,!0),t.stylesWithoutHost!=null&&Cc(t)&&zh(e,t,I(),t.stylesWithoutHost,!1),K}function Vh(e,t,n,r){return G(e,t,n,r),K(),Vh}function q(e,t,n,r){let i=I(),a=i[1],o=e+27,s=a.firstCreatePass?Dp(o,a,2,t,n,r):a.data[o];return Wd(s,i,e,t,Uh),r!=null&&jd(i,s),q}function J(){return _o(Gd(So()))&&vo(),mo(),J}function Hh(e,t,n,r){return q(e,t,n,r),J(),Hh}var Uh=(e,t,n,r,i)=>(as(!0),Zl(t[11],r,ns()));function Wh(){let e=yo(),t=Gd(So());return e.firstCreatePass&&Ep(e,t),Wh}function Gh(e,t,n){let r=I(),i=r[1],a=e+27,o=i.firstCreatePass?Dp(a,i,8,`ng-container`,t,n):i.data[a];return Wd(o,r,e,`ng-container`,Jh),n!=null&&jd(r,o),Gh}function Kh(){return Gd(So()),Wh}function qh(e,t,n){return Gh(e,t,n),Kh(),qh}var Jh=(e,t,n,r,i)=>(as(!0),Xl(t[11],``));function Yh(){return I()}function Xh(e,t,n){let r=I();return Zf(r,No(),t)&&(yo(),Fd(Qo(),r,e,t,r[11],n)),Xh}var Zh=void 0;function Qh(e){let t=Math.floor(Math.abs(e)),n=e.toString().replace(/^[^.]*\.?/,``).length;return t===1&&n===0?1:5}var $h=[`en`,[[`a`,`p`],[`AM`,`PM`]],[[`AM`,`PM`]],[[`S`,`M`,`T`,`W`,`T`,`F`,`S`],[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`],[`Su`,`Mo`,`Tu`,`We`,`Th`,`Fr`,`Sa`]],Zh,[[`J`,`F`,`M`,`A`,`M`,`J`,`J`,`A`,`S`,`O`,`N`,`D`],[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`]],Zh,[[`B`,`A`],[`BC`,`AD`],[`Before Christ`,`Anno Domini`]],0,[6,0],[`M/d/yy`,`MMM d, y`,`MMMM d, y`,`EEEE, MMMM d, y`],[`h:mm a`,`h:mm:ss a`,`h:mm:ss a z`,`h:mm:ss a zzzz`],[`{1}, {0}`,Zh,Zh,Zh],[`.`,`,`,`;`,`%`,`+`,`-`,`E`,`×`,`‰`,`∞`,`NaN`,`:`],[`#,##0.###`,`#,##0%`,`¤#,##0.00`,`#E0`],`USD`,`$`,`US Dollar`,{},`ltr`,Qh],eg=Object.create(null);function tg(e){let t=ig(e),n=ng(t);if(n)return n;let r=t.split(`-`)[0];if(n=ng(r),n)return n;if(r===`en`)return $h;throw new M(701,!1)}function ng(e){if(!(e in eg)){let t=Pi.ng&&Pi.ng.common&&Pi.ng.common.locales&&Pi.ng.common.locales[e];return t!==void 0&&(eg[e]=t),t}return eg[e]}var rg={LocaleId:0,DayPeriodsFormat:1,DayPeriodsStandalone:2,DaysFormat:3,DaysStandalone:4,MonthsFormat:5,MonthsStandalone:6,Eras:7,FirstDayOfWeek:8,WeekendRange:9,DateFormat:10,TimeFormat:11,DateTimeFormat:12,NumberSymbols:13,NumberFormats:14,CurrencyCode:15,CurrencySymbol:16,CurrencyName:17,Currencies:18,Directionality:19,PluralCase:20,ExtraData:21};function ig(e){return e.toLowerCase().replace(/_/g,`-`)}var ag=`en-US`;function og(e){typeof e==`string`&&e.toLowerCase().replace(/_/g,`-`)}function sg(e,t,n){let r=I(),i=yo(),a=So();return cg(i,r,r[11],a,e,t,n),sg}function Y(e,t,n){let r=I(),i=yo(),a=So();return(a.type&3||n)&&np(a,i,r,n,r[11],e,t,ep(a,r,t)),Y}function cg(e,t,n,r,i,a,o){let s=!0,c=null;if((r.type&3||o)&&(c??=ep(r,t,a),np(r,e,t,o,n,i,a,c)&&(s=!1)),s){let e=r.outputs?.[i],n=r.hostDirectiveOutputs?.[i];if(n&&n.length)for(let e=0;e>17&32767}function dg(e){return(e&2)==2}function fg(e,t){return e&131071|t<<17}function pg(e){return e|2}function mg(e){return(e&131068)>>2}function hg(e,t){return e&-131069|t<<2}function gg(e){return(e&1)==1}function _g(e){return e|1}function vg(e,t,n,r,i,a){let o=a?t.classBindings:t.styleBindings,s=ug(o),c=mg(o);e[r]=n;let l=!1,u;if(Array.isArray(n)){let e=n;u=e[1],(u===null||Zi(e,u)>0)&&(l=!0)}else u=n;if(i){if(c!==0){let t=ug(e[s+1]);e[r+1]=lg(t,s),t!==0&&(e[t+1]=hg(e[t+1],r)),e[s+1]=fg(e[s+1],r)}else e[r+1]=lg(s,0),s!==0&&(e[s+1]=hg(e[s+1],r)),s=r}else e[r+1]=lg(c,0),s===0?s=r:e[c+1]=hg(e[c+1],r),c=r;l&&(e[r+1]=pg(e[r+1])),bg(e,u,r,!0),bg(e,u,r,!1),yg(t,u,e,r,a),o=lg(s,c),a?t.classBindings=o:t.styleBindings=o}function yg(e,t,n,r,i){let a=i?e.residualClasses:e.residualStyles;a!=null&&typeof t==`string`&&Zi(a,t)>=0&&(n[r+1]=_g(n[r+1]))}function bg(e,t,n,r){let i=e[n+1],a=t===null,o=r?ug(i):mg(i),s=!1;for(;o!==0&&(s===!1||a);){let n=e[o],i=e[o+1];xg(n,t)&&(s=!0,e[o+1]=r?_g(i):pg(i)),o=r?ug(i):mg(i)}s&&(e[n+1]=r?pg(i):_g(i))}function xg(e,t){return e===null||t==null||(Array.isArray(e)?e[1]:e)===t?!0:Array.isArray(e)&&typeof t==`string`?Zi(e,t)>=0:!1}var Sg={textEnd:0,key:0,keyEnd:0,value:0,valueEnd:0};function Cg(e){return e.substring(Sg.key,Sg.keyEnd)}function wg(e){return Eg(e),Tg(e,Dg(e,0,Sg.textEnd))}function Tg(e,t){let n=Sg.textEnd;return n===t?-1:(t=Sg.keyEnd=Og(e,Sg.key=t,n),Dg(e,t,n))}function Eg(e){Sg.key=0,Sg.keyEnd=0,Sg.value=0,Sg.valueEnd=0,Sg.textEnd=e.length}function Dg(e,t,n){for(;t32;)t++;return t}function kg(e,t,n){return Ng(e,t,n,!1),kg}function Ag(e,t){return Ng(e,t,null,!0),Ag}function jg(e){Pg(Wg,Mg,e,!0)}function Mg(e,t){for(let n=wg(t);n>=0;n=Tg(t,n))Yi(e,Cg(t),!0)}function Ng(e,t,n,r){let i=I(),a=yo(),o=Po(2);if(a.firstUpdatePass&&Ig(a,e,o,r),t!==bu&&Zf(i,o,t)){let s=a.data[Xo()];Kg(a,s,i,i[11],e,i[o+1]=Yg(t,n),r,o)}}function Pg(e,t,n,r){let i=yo(),a=Po(2);i.firstUpdatePass&&Ig(i,null,a,r);let o=I();if(n!==bu&&Zf(o,a,n)){let s=i.data[Xo()];if(Xg(s,r)&&!Fg(i,a)){let e=r?s.classesWithoutHost:s.stylesWithoutHost;e!==null&&(n=$r(e,n||``)),zh(i,s,o,n,r)}else Gg(i,s,o,o[11],o[a+1],o[a+1]=Ug(e,t,n),r,a)}}function Fg(e,t){return t>=e.expandoStartIndex}function Ig(e,t,n,r){let i=e.data;if(i[n+1]===null){let a=i[Xo()],o=Fg(e,n);Xg(a,r)&&t===null&&!o&&(t=!1),t=Lg(i,a,t,r),vg(i,a,t,n,o,r)}}function Lg(e,t,n,r){let i=zo(e),a=r?t.residualClasses:t.residualStyles;if(i===null)(r?t.classBindings:t.styleBindings)===0&&(n=Vg(null,e,t,n,r),n=Hg(n,t.attrs,r),a=null);else{let o=t.directiveStylingLast;if(o===-1||e[o]!==i){if(n=Vg(i,e,t,n,r),a===null){let n=Rg(e,t,r);n!==void 0&&Array.isArray(n)&&(n=Vg(null,e,t,n[1],r),n=Hg(n,t.attrs,r),zg(e,t,r,n))}else a=Bg(e,t,r)}}return a!==void 0&&(r?t.residualClasses=a:t.residualStyles=a),n}function Rg(e,t,n){let r=n?t.classBindings:t.styleBindings;if(mg(r)!==0)return e[ug(r)]}function zg(e,t,n,r){let i=n?t.classBindings:t.styleBindings;e[ug(i)]=r}function Bg(e,t,n){let r,i=t.directiveEnd;for(let a=1+t.directiveStylingLast;a0;){let t=e[i],a=Array.isArray(t),c=a?t[1]:t,l=c===null,u=n[i+1];u===bu&&(u=l?ea:void 0);let d=l?Xi(u,r):c===r?u:void 0;if(a&&!Jg(d)&&(d=Xi(t,r)),Jg(d)&&(s=d,o))return s;let f=e[i+1];i=o?ug(f):mg(f)}if(t!==null){let e=a?t.residualClasses:t.residualStyles;e!=null&&(s=Xi(e,r))}return s}function Jg(e){return e!==void 0}function Yg(e,t){return e==null||e===``||(typeof t==`string`?e=Ul(e)+t:typeof e==`object`&&(e=Qr(Ul(e)))),e}function Xg(e,t){return!!(e.flags&(t?8:16))}function Z(e,t=``){let n=I(),r=yo(),i=e+27,a=r.firstCreatePass?Nf(r,i,1,t,null):r.data[i],o=Zg(r,n,a,t);n[i]=o,is()&&cd(r,n,o,a),To(a,!1)}var Zg=(e,t,n,r)=>(as(!0),Jl(t[11],r));function Qg(e,t,n,r=``){return Zf(e,No(),n)?t+Si(n)+r:bu}function $g(e,t,n,r,i,a=``){let o=Qf(e,jo(),n,i);return Po(2),o?t+Si(n)+r+Si(i)+a:bu}function e_(e,t,n,r,i,a,o,s=``){let c=$f(e,jo(),n,i,o);return Po(3),c?t+Si(n)+r+Si(i)+a+Si(o)+s:bu}function Q(e){return $(``,e),Q}function $(e,t,n){let r=I(),i=Qg(r,e,t,n);return i!==bu&&r_(r,Xo(),i),$}function t_(e,t,n,r,i){let a=I(),o=$g(a,e,t,n,r,i);return o!==bu&&r_(a,Xo(),o),t_}function n_(e,t,n,r,i,a,o){let s=I(),c=e_(s,e,t,n,r,i,a,o);return c!==bu&&r_(s,Xo(),c),n_}function r_(e,t,n){let r=Ga(t,e);Yl(e[11],r,n)}function i_(e,t){let n=Ao()+e,r=I();return r[n]===bu?Yf(r,n,t()):Xf(r,n)}function a_(e,t,n,r){return c_(I(),Ao(),e,t,n,r)}function o_(e,t){let n=e[t];return n===bu?void 0:n}function s_(e,t,n,r,i,a){let o=t+n;return Zf(e,o,i)?Yf(e,o+1,a?r.call(a,i):r(i)):o_(e,o+1)}function c_(e,t,n,r,i,a,o){let s=t+n;return Qf(e,s,i,a)?Yf(e,s+2,o?r.call(o,i,a):r(i,a)):o_(e,s+2)}function l_(e,t){let n=yo(),r,i=e+27;n.firstCreatePass?(r=u_(t,n.pipeRegistry),n.data[i]=r,r.onDestroy&&(n.destroyHooks??=[]).push(i,r.onDestroy)):r=n.data[i];let a=r.factory||(r.factory=Wi(r.type,!0)),o=Mi(up);try{let e=Pc(!1),t=a();return Pc(e),Ya(n,I(),i,t),t}finally{Mi(o)}}function u_(e,t){if(t)for(let n=t.length-1;n>=0;n--){let r=t[n];if(e===r.name)return r}}function d_(e,t,n){let r=e+27,i=I(),a=Ja(i,r);return p_(i,r)?s_(i,Ao(),t,a.transform,n,a):a.transform(n)}function f_(e,t,n,r){let i=e+27,a=I(),o=Ja(a,i);return p_(a,i)?c_(a,Ao(),t,o.transform,n,r,o):o.transform(n,r)}function p_(e,t){return e[1].data[t].pure}var m_=(()=>{class e{applicationErrorHandler=P(Fs);appRef=P(rh);taskService=P(ms);ngZone=P(Ss);zonelessEnabled=P(Ks);tracing=P(ju,{optional:!0});zoneIsDefined=typeof Zone<`u`&&!!Zone.root.run;schedulerTickApplyArgs=[{data:{__scheduler_tick__:!0}}];subscriptions=new cr;angularZoneId=this.zoneIsDefined?this.ngZone._inner?.get(bs):null;scheduleInRootZone=!this.zonelessEnabled&&this.zoneIsDefined&&(P(qs,{optional:!0})??!1);cancelScheduledCallback=null;useMicrotaskScheduler=!1;runningTick=!1;pendingRenderTaskId=null;constructor(){this.subscriptions.add(this.appRef.afterTick.subscribe(()=>{let e=this.taskService.add();if(!this.runningTick&&(this.cleanup(),!this.zonelessEnabled||this.appRef.includeAllTestViews)){this.taskService.remove(e);return}this.switchToMicrotaskScheduler(),this.taskService.remove(e)})),this.subscriptions.add(this.ngZone.onUnstable.subscribe(()=>{this.runningTick||this.cleanup()}))}switchToMicrotaskScheduler(){this.ngZone.runOutsideAngular(()=>{let e=this.taskService.add();this.useMicrotaskScheduler=!0,queueMicrotask(()=>{this.useMicrotaskScheduler=!1,this.taskService.remove(e)})})}notify(e){if(!this.zonelessEnabled&&e===5)return;switch(e){case 0:case 2:this.appRef.dirtyFlags|=2;break;case 3:case 4:case 5:case 1:this.appRef.dirtyFlags|=4;break;case 6:this.appRef.dirtyFlags|=2;break;case 12:this.appRef.dirtyFlags|=16;break;case 13:this.appRef.dirtyFlags|=2;break;case 11:break;default:this.appRef.dirtyFlags|=8}if(this.appRef.tracingSnapshot=this.tracing?.snapshot(this.appRef.tracingSnapshot)??null,!this.shouldScheduleTick())return;let t=this.useMicrotaskScheduler?vs:_s;this.pendingRenderTaskId=this.taskService.add(),this.cancelScheduledCallback=this.scheduleInRootZone?Zone.root.run(()=>t(()=>this.tick())):this.ngZone.runOutsideAngular(()=>t(()=>this.tick()))}shouldScheduleTick(){return!(this.appRef.destroyed||this.pendingRenderTaskId!==null||this.runningTick||this.appRef._runningTick||!this.zonelessEnabled&&this.zoneIsDefined&&Zone.current.get(`isAngularZone_ID`+this.angularZoneId))}tick(){if(this.runningTick||this.appRef.destroyed)return;if(this.appRef.dirtyFlags===0){this.cleanup();return}!this.zonelessEnabled&&this.appRef.dirtyFlags&7&&(this.appRef.dirtyFlags|=1);let e=this.taskService.add();try{this.ngZone.run(()=>{this.runningTick=!0,this.appRef._tick()},void 0,this.schedulerTickApplyArgs)}catch(e){this.applicationErrorHandler(e)}finally{this.taskService.remove(e),this.cleanup()}}ngOnDestroy(){this.subscriptions.unsubscribe(),this.cleanup()}cleanup(){if(this.runningTick=!1,this.cancelScheduledCallback?.(),this.cancelScheduledCallback=null,this.pendingRenderTaskId!==null){let e=this.pendingRenderTaskId;this.pendingRenderTaskId=null,this.taskService.remove(e)}}static ɵfac=function(t){return new(t||e)};static ɵprov=ll({token:e,factory:e.ɵfac})}return e})();function h_(){return[{provide:Gs,useExisting:m_},{provide:Ss,useClass:As},{provide:Ks,useValue:!0}]}function g_(){return typeof $localize<`u`&&$localize.locale||`en-US`}var __=new N(``,{factory:()=>P(__,{optional:!0,skipSelf:!0})||g_()}),v_=class{destroyed=!1;listeners=null;errorHandler=P(Ps,{optional:!0});isEmitting=!1;hasNullListeners=!1;destroyRef=P(us);constructor(){this.destroyRef.onDestroy(()=>{this.destroyed=!0,this.listeners=null})}subscribe(e){if(this.destroyed)throw new M(953,!1);return(this.listeners??=[]).push(e),{unsubscribe:()=>{let t=this.listeners?this.listeners.indexOf(e):-1;t>-1&&(this.isEmitting?(this.hasNullListeners=!0,this.listeners[t]=null):this.listeners.splice(t,1))}}}emit(e){if(this.destroyed){console.warn(Xr(953,!1));return}if(this.listeners===null)return;this.isEmitting=!0;let t=j(null);try{for(let t of this.listeners)try{t!==null&&t(e)}catch(e){this.errorHandler?.handleError(e)}}finally{this.hasNullListeners&&(this.hasNullListeners=!1,this.listeners&&y_(this.listeners)),j(t),this.isEmitting=!1}}};function y_(e){let t=e.length-1;for(;t>-1;)e[t]===null&&e.splice(t,1),t--}function b_(e,t){return Tn(e,t?.equal)}function x_(e){return Qn(e)}(class e extends Error{_brand;constructor(e){super(e)}static IDLE=new e(`IDLE`);static LOADING=new e(`LOADING`)});var S_=e=>e;function C_(e,t){return typeof e==`function`?w_(Jn(e,S_,t?.equal),t?.debugName,t?.set):w_(Jn(e.source,e.computation,e.equal),e.debugName,e.set)}function w_(e,t,n){let r=e[rn],i=e;if(n!==void 0){let t=e=>Yn(r,e);i.set=e=>n(e,t),i.update=r=>n(r(x_(e)),t)}else i.set=e=>Yn(r,e),i.update=e=>Xn(r,e);return i.asReadonly=Ls.bind(e),i}function T_(e,t){let n=Object.create(oc);n.value=e,n.transformFn=t?.transform;function r(){if(sn(n),n.value===ac)throw new M(-950,null);return n.value}return r[rn]=n,r}function E_(e){return new v_}function D_(e,t){return T_(e,t)}function O_(e){return T_(ac,e)}var k_=(D_.required=O_,D_),A_=new N(``),j_=new N(``);function M_(e){return!e.moduleRef}function N_(e){let t=M_(e)?e.r3Injector:e.moduleRef.injector,n=t.get(Ss);return n.run(()=>{M_(e)?e.r3Injector.resolveInjectorInitializers():e.moduleRef.resolveInjectorInitializers();let r=t.get(Fs),i;if(n.runOutsideAngular(()=>{i=n.onError.subscribe({next:r})}),M_(e)){let n=()=>t.destroy(),r=e.platformInjector.get(A_);r.add(n),t.onDestroy(()=>{i.unsubscribe(),r.delete(n)})}else{let t=()=>e.moduleRef.destroy(),n=e.platformInjector.get(A_);n.add(t),e.moduleRef.onDestroy(()=>{ah(e.allPlatformModules,e.moduleRef),i.unsubscribe(),n.delete(t)})}return F_(r,n,()=>{let n=t.get(ms),r=n.add(),i=t.get(cm);return i.runInitializers(),i.donePromise.then(()=>{if(og(t.get(__,ag)||`en-US`),!t.get(j_,!0))return M_(e)?t.get(rh):(e.allPlatformModules.push(e.moduleRef),e.moduleRef);if(M_(e)){let n=t.get(rh);return e.rootComponent!==void 0&&n.bootstrap(e.rootComponent),n}return P_?.(e.moduleRef,e.allPlatformModules),e.moduleRef}).finally(()=>void n.remove(r))})})}var P_;function F_(e,t,n){try{let r=n();return Kp(r)?r.catch(n=>{throw t.runOutsideAngular(()=>e(n)),n}):r}catch(n){throw t.runOutsideAngular(()=>e(n)),n}}var I_=null;function L_(e=[],t){return cs.create({name:t,providers:[{provide:ha,useValue:`platform`},{provide:A_,useValue:new Set([()=>I_=null])},...e]})}function R_(e=[]){if(I_)return I_;let t=L_(e);return I_=t,th(),z_(t),t}function z_(e){let t=e.get(Bs,null);Ma(e,()=>{t?.forEach(e=>e())})}function B_(e){let{rootComponent:t,appProviders:n,platformProviders:r,platformRef:i}=e;z(R.BootstrapApplicationStart);try{let e=i?.injector??R_(r);return N_({r3Injector:new Yp({providers:[h_(),Is,...n||[]],parent:e,debugName:``,runEnvironmentInitializers:!1}).injector,platformInjector:e,rootComponent:t})}catch(e){return Promise.reject(e)}finally{z(R.BootstrapApplicationEnd)}}var V_=null;function H_(){return V_}function U_(e){V_??=e}var W_=class{},G_=(function(e){return e[e.Format=0]=`Format`,e[e.Standalone=1]=`Standalone`,e})(G_||{}),K_=(function(e){return e[e.Narrow=0]=`Narrow`,e[e.Abbreviated=1]=`Abbreviated`,e[e.Wide=2]=`Wide`,e[e.Short=3]=`Short`,e})(K_||{}),q_=(function(e){return e[e.Short=0]=`Short`,e[e.Medium=1]=`Medium`,e[e.Long=2]=`Long`,e[e.Full=3]=`Full`,e})(q_||{}),J_={Decimal:0,Group:1,List:2,PercentSign:3,PlusSign:4,MinusSign:5,Exponential:6,SuperscriptingExponent:7,PerMille:8,Infinity:9,NaN:10,TimeSeparator:11,CurrencyDecimal:12,CurrencyGroup:13};function Y_(e){return tg(e)[rg.LocaleId]}function X_(e,t,n){let r=tg(e);return sv(sv([r[rg.DayPeriodsFormat],r[rg.DayPeriodsStandalone]],t),n)}function Z_(e,t,n){let r=tg(e);return sv(sv([r[rg.DaysFormat],r[rg.DaysStandalone]],t),n)}function Q_(e,t,n){let r=tg(e);return sv(sv([r[rg.MonthsFormat],r[rg.MonthsStandalone]],t),n)}function $_(e,t){let n=tg(e)[rg.Eras];return sv(n,t)}function ev(e,t){return sv(tg(e)[rg.DateFormat],t)}function tv(e,t){return sv(tg(e)[rg.TimeFormat],t)}function nv(e,t){let n=tg(e)[rg.DateTimeFormat];return sv(n,t)}function rv(e,t){let n=tg(e),r=n[rg.NumberSymbols][t];if(r===void 0){if(t===J_.CurrencyDecimal)return n[rg.NumberSymbols][J_.Decimal];if(t===J_.CurrencyGroup)return n[rg.NumberSymbols][J_.Group]}return r}function iv(e){if(!e[rg.ExtraData])throw new M(2303,!1)}function av(e){let t=tg(e);return iv(t),(t[rg.ExtraData][2]||[]).map(e=>typeof e==`string`?cv(e):[cv(e[0]),cv(e[1])])}function ov(e,t,n){let r=tg(e);return iv(r),sv(sv([r[rg.ExtraData][0],r[rg.ExtraData][1]],t)||[],n)||[]}function sv(e,t){for(let n=t;n>-1;n--)if(e[n]!==void 0)return e[n];throw new M(2304,!1)}function cv(e){let[t,n]=e.split(`:`);return{hours:+t,minutes:+n}}var lv=/^(\d{4,})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/,uv=Object.create(null),dv=/((?:[^BEGHLMOSWYZabcdhmswyz']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|c{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/,fv=256;function pv(e,t,n,r){let i=Iv(e);mv(t),t=gv(n,t)||t;let a=[],o;for(;t;)if(o=dv.exec(t),o){a=a.concat(o.slice(1));let e=a.pop();if(!e)break;t=e}else{a.push(t);break}let s=i.getTimezoneOffset();r&&(s=Nv(r,s),i=Fv(i,r));let c=``;return a.forEach(e=>{let t=Mv(e);c+=t?t(i,n,s):e===`''`?`'`:e.replace(/(^'|'$)/g,``).replace(/''/g,`'`)}),c}function mv(e){if(e.length>fv)throw new M(2300,!1)}function hv(e,t,n){let r=new Date(0);return r.setFullYear(e,t,n),r.setHours(0,0,0),r}function gv(e,t){let n=Y_(e);if(uv[n]??=Object.create(null),uv[n][t])return uv[n][t];let r=``;switch(t){case`shortDate`:r=ev(e,q_.Short);break;case`mediumDate`:r=ev(e,q_.Medium);break;case`longDate`:r=ev(e,q_.Long);break;case`fullDate`:r=ev(e,q_.Full);break;case`shortTime`:r=tv(e,q_.Short);break;case`mediumTime`:r=tv(e,q_.Medium);break;case`longTime`:r=tv(e,q_.Long);break;case`fullTime`:r=tv(e,q_.Full);break;case`short`:let t=gv(e,`shortTime`),n=gv(e,`shortDate`);r=_v(nv(e,q_.Short),[t,n]);break;case`medium`:let i=gv(e,`mediumTime`),a=gv(e,`mediumDate`);r=_v(nv(e,q_.Medium),[i,a]);break;case`long`:let o=gv(e,`longTime`),s=gv(e,`longDate`);r=_v(nv(e,q_.Long),[o,s]);break;case`full`:let c=gv(e,`fullTime`),l=gv(e,`fullDate`);r=_v(nv(e,q_.Full),[c,l])}return r&&(uv[n][t]=r),r}function _v(e,t){return t&&(e=e.replace(/\{([^}]+)}/g,function(e,n){return Object.hasOwn(t,n)?t[n]:e})),e}function vv(e,t,n=`-`,r,i){let a=``;(e<0||i&&e<=0)&&(i?e=-e+1:(e=-e,a=n));let o=String(e);for(;o.length0||s>-n)&&(s+=n),e===3)s===0&&n===-12&&(s=12);else if(e===6)return yv(s,t);let c=rv(o,J_.MinusSign);return vv(s,t,c,r,i)}}function xv(e,t){switch(e){case 0:return t.getFullYear();case 1:return t.getMonth();case 2:return t.getDate();case 3:return t.getHours();case 4:return t.getMinutes();case 5:return t.getSeconds();case 6:return t.getMilliseconds();case 7:return t.getDay();default:throw new M(2301,!1)}}function Sv(e,t,n=G_.Format,r=!1){return function(i,a){return Cv(i,a,e,t,n,r)}}function Cv(e,t,n,r,i,a){switch(n){case 2:return Q_(t,i,r)[e.getMonth()];case 1:return Z_(t,i,r)[e.getDay()];case 0:let n=e.getHours(),o=e.getMinutes();if(a){let e=av(t),a=ov(t,i,r),s=e.findIndex(e=>{if(Array.isArray(e)){let[t,r]=e,i=n>=t.hours&&o>=t.minutes,a=n0?Math.floor(i/60):Math.ceil(i/60);switch(e){case 0:return(i>=0?`+`:``)+vv(o,2,a)+vv(Math.abs(i%60),2,a);case 1:return`GMT`+(i>=0?`+`:``)+vv(o,1,a);case 2:return`GMT`+(i>=0?`+`:``)+vv(o,2,a)+`:`+vv(Math.abs(i%60),2,a);case 3:return r===0?`Z`:(i>=0?`+`:``)+vv(o,2,a)+`:`+vv(Math.abs(i%60),2,a);default:throw new M(2310,!1)}}}var Tv=0,Ev=4;function Dv(e){let t=hv(e,Tv,1).getDay();return hv(e,0,1+(t<=Ev?Ev:11)-t)}function Ov(e){let t=e.getDay(),n=t===0?-3:Ev-t;return hv(e.getFullYear(),e.getMonth(),e.getDate()+n)}function kv(e,t=!1){return function(n,r){let i;if(t){let e=new Date(n.getFullYear(),n.getMonth(),1).getDay()-1,t=n.getDate();i=1+Math.floor((t+e)/7)}else{let e=Ov(n),t=Dv(e.getFullYear()),r=e.getTime()-t.getTime();i=1+Math.round(r/6048e5)}return vv(i,e,rv(r,J_.MinusSign))}}function Av(e,t=!1){return function(n,r){return vv(Ov(n).getFullYear(),e,rv(r,J_.MinusSign),t)}}var jv=Object.create(null);function Mv(e){if(jv[e])return jv[e];let t;switch(e){case`G`:case`GG`:case`GGG`:t=Sv(3,K_.Abbreviated);break;case`GGGG`:t=Sv(3,K_.Wide);break;case`GGGGG`:t=Sv(3,K_.Narrow);break;case`y`:t=bv(0,1,0,!1,!0);break;case`yy`:t=bv(0,2,0,!0,!0);break;case`yyy`:t=bv(0,3,0,!1,!0);break;case`yyyy`:t=bv(0,4,0,!1,!0);break;case`Y`:t=Av(1);break;case`YY`:t=Av(2,!0);break;case`YYY`:t=Av(3);break;case`YYYY`:t=Av(4);break;case`M`:case`L`:t=bv(1,1,1);break;case`MM`:case`LL`:t=bv(1,2,1);break;case`MMM`:t=Sv(2,K_.Abbreviated);break;case`MMMM`:t=Sv(2,K_.Wide);break;case`MMMMM`:t=Sv(2,K_.Narrow);break;case`LLL`:t=Sv(2,K_.Abbreviated,G_.Standalone);break;case`LLLL`:t=Sv(2,K_.Wide,G_.Standalone);break;case`LLLLL`:t=Sv(2,K_.Narrow,G_.Standalone);break;case`w`:t=kv(1);break;case`ww`:t=kv(2);break;case`W`:t=kv(1,!0);break;case`d`:t=bv(2,1);break;case`dd`:t=bv(2,2);break;case`c`:case`cc`:t=bv(7,1);break;case`ccc`:t=Sv(1,K_.Abbreviated,G_.Standalone);break;case`cccc`:t=Sv(1,K_.Wide,G_.Standalone);break;case`ccccc`:t=Sv(1,K_.Narrow,G_.Standalone);break;case`cccccc`:t=Sv(1,K_.Short,G_.Standalone);break;case`E`:case`EE`:case`EEE`:t=Sv(1,K_.Abbreviated);break;case`EEEE`:t=Sv(1,K_.Wide);break;case`EEEEE`:t=Sv(1,K_.Narrow);break;case`EEEEEE`:t=Sv(1,K_.Short);break;case`a`:case`aa`:case`aaa`:t=Sv(0,K_.Abbreviated);break;case`aaaa`:t=Sv(0,K_.Wide);break;case`aaaaa`:t=Sv(0,K_.Narrow);break;case`b`:case`bb`:case`bbb`:t=Sv(0,K_.Abbreviated,G_.Standalone,!0);break;case`bbbb`:t=Sv(0,K_.Wide,G_.Standalone,!0);break;case`bbbbb`:t=Sv(0,K_.Narrow,G_.Standalone,!0);break;case`B`:case`BB`:case`BBB`:t=Sv(0,K_.Abbreviated,G_.Format,!0);break;case`BBBB`:t=Sv(0,K_.Wide,G_.Format,!0);break;case`BBBBB`:t=Sv(0,K_.Narrow,G_.Format,!0);break;case`h`:t=bv(3,1,-12);break;case`hh`:t=bv(3,2,-12);break;case`H`:t=bv(3,1);break;case`HH`:t=bv(3,2);break;case`m`:t=bv(4,1);break;case`mm`:t=bv(4,2);break;case`s`:t=bv(5,1);break;case`ss`:t=bv(5,2);break;case`S`:t=bv(6,1);break;case`SS`:t=bv(6,2);break;case`SSS`:t=bv(6,3);break;case`Z`:case`ZZ`:case`ZZZ`:t=wv(0);break;case`ZZZZZ`:t=wv(3);break;case`O`:case`OO`:case`OOO`:case`z`:case`zz`:case`zzz`:t=wv(1);break;case`OOOO`:case`ZZZZ`:case`zzzz`:t=wv(2);break;default:return null}return jv[e]=t,t}function Nv(e,t){e=e.replace(/:/g,``);let n=Date.parse(`Jan 01, 1970 00:00:00 `+e)/6e4;return isNaN(n)?t:n}function Pv(e,t){return e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+t),e}function Fv(e,t,n){let r=e.getTimezoneOffset();return Pv(e,-1*(Nv(t,r)-r))}function Iv(e){if(Rv(e))return e;if(typeof e==`number`&&!isNaN(e))return new Date(e);if(typeof e==`string`){if(e=e.trim(),/^(\d{4}(-\d{1,2}(-\d{1,2})?)?)$/.test(e)){let[t,n=1,r=1]=e.split(`-`).map(e=>+e);return hv(t,n-1,r)}let t=parseFloat(e);if(!isNaN(e-t))return new Date(t);let n;if(n=e.match(lv))return Lv(n)}let t=new Date(e);if(!Rv(t))throw new M(2311,!1);return t}function Lv(e){let t=new Date(0),n=0,r=0,i=e[8]?t.setUTCFullYear:t.setFullYear,a=e[8]?t.setUTCHours:t.setHours;e[9]&&(n=Number(e[9]+e[10]),r=Number(e[9]+e[11])),i.call(t,Number(e[1]),Number(e[2])-1,Number(e[3]));let o=Number(e[4]||0)-n,s=Number(e[5]||0)-r,c=Number(e[6]||0),l=Math.floor(parseFloat(`0.`+(e[7]||0))*1e3);return a.call(t,o,s,c,l),t}function Rv(e){return e instanceof Date&&!isNaN(e.valueOf())}function zv(e,t){return new M(2100,!1)}var Bv=`mediumDate`,Vv=new N(``),Hv=new N(``),Uv=(()=>{class e{locale;defaultTimezone;defaultOptions;constructor(e,t,n){this.locale=e,this.defaultTimezone=t,this.defaultOptions=n}transform(t,n,r,i){if(t==null||t===``||t!==t)return null;try{let e=n??this.defaultOptions?.dateFormat??Bv,a=r??this.defaultOptions?.timezone??this.defaultTimezone??void 0;return pv(t,e,i||this.locale,a)}catch(t){throw zv(e,t.message)}}static ɵfac=function(t){return new(t||e)(up(__,16),up(Vv,24),up(Hv,24))};static ɵpipe=nm({name:`date`,type:e,pure:!0})}return e})(),Wv=(()=>{class e{transform(e){return JSON.stringify(e,null,2)}static ɵfac=function(t){return new(t||e)};static ɵpipe=nm({name:`json`,type:e,pure:!1})}return e})();function Gv(e,t){t=encodeURIComponent(t);for(let n of e.split(`;`)){let e=n.indexOf(`=`),[r,i]=e==-1?[n,``]:[n.slice(0,e),n.slice(e+1)];if(r.trim()!==t)continue;let a=i;try{a=decodeURIComponent(i)}catch{}return a.length>1&&a[0]===`"`&&a[a.length-1]===`"`&&(a=a.slice(1,-1)),a}return null}var Kv=`browser`,qv=class{_doc;constructor(e){this._doc=e}manager},Jv=(()=>{class e extends qv{constructor(e){super(e)}supports(e){return!0}addEventListener(e,t,n,r){return e.addEventListener(t,n,r),()=>this.removeEventListener(e,t,n,r)}removeEventListener(e,t,n,r){return e.removeEventListener(t,n,r)}static ɵfac=function(t){return new(t||e)(zi(ls))};static ɵprov=ii({token:e,factory:e.ɵfac})}return e})(),Yv=new N(``),Xv=(()=>{class e{_zone;_plugins;_eventNameToPlugin=new Map;constructor(e,t){this._zone=t,e.forEach(e=>{e.manager=this});let n=e.filter(e=>!(e instanceof Jv));this._plugins=n.slice().reverse();let r=e.find(e=>e instanceof Jv);r&&this._plugins.push(r)}addEventListener(e,t,n,r){return this._findPluginFor(t).addEventListener(e,t,n,r)}getZone(){return this._zone}_findPluginFor(e){let t=this._eventNameToPlugin.get(e);if(t)return t;if(t=this._plugins.find(t=>t.supports(e)),!t)throw new M(-5101,!1);return this._eventNameToPlugin.set(e,t),t}static ɵfac=function(t){return new(t||e)(zi(Yv),zi(Ss))};static ɵprov=ii({token:e,factory:e.ɵfac})}return e})(),Zv=`ng-app-id`;function Qv(e){for(let t of e)t.remove()}function $v(e,t){let n=t.createElement(`style`);return n.textContent=e,n}function ey(e,t,n,r){let i=e.head?.querySelectorAll(`style[${Zv}="${t}"],link[${Zv}="${t}"]`);if(!i||i.length===0)return!1;for(let e of i)e.removeAttribute(Zv),e instanceof HTMLLinkElement?r.set(e.href.slice(e.href.lastIndexOf(`/`)+1),{usage:0,elements:[e]}):e.textContent&&n.set(e.textContent,{usage:0,elements:[e]});return!0}function ty(e,t){let n=t.createElement(`link`);return n.setAttribute(`rel`,`stylesheet`),n.setAttribute(`href`,e),n}var ny=(()=>{class e{doc;appId;nonce;inline=new Map;external=new Map;hosts=new Set;constructor(e,t,n,r={}){this.doc=e,this.appId=t,this.nonce=n,ey(e,t,this.inline,this.external)&&this.hosts.add(e.head)}addStyles(e,t){for(let t of e)this.addUsage(t,this.inline,$v);t?.forEach(e=>this.addUsage(e,this.external,ty))}removeStyles(e,t){for(let t of e)this.removeUsage(t,this.inline);t?.forEach(e=>this.removeUsage(e,this.external))}addUsage(e,t,n){let r=t.get(e);r?r.usage++:t.set(e,{usage:1,elements:[...this.hosts].map(t=>this.addElement(t,n(e,this.doc)))})}removeUsage(e,t){let n=t.get(e);n&&(n.usage--,n.usage<=0&&(Qv(n.elements),t.delete(e)))}ngOnDestroy(){for(let[,{elements:e}]of[...this.inline,...this.external])Qv(e);this.hosts.clear()}addHost(e){if(!this.hosts.has(e)){this.hosts.add(e);for(let[t,{elements:n}]of this.inline)n.push(this.addElement(e,$v(t,this.doc)));for(let[t,{elements:n}]of this.external)n.push(this.addElement(e,ty(t,this.doc)))}}removeHost(e){this.hosts.delete(e);for(let t of[...this.inline.values(),...this.external.values()]){let n=[];for(let r of t.elements)r.parentNode===e?r.remove():n.push(r);t.elements=n}}addElement(e,t){return this.nonce&&t.setAttribute(`nonce`,this.nonce),e.appendChild(t)}static ɵfac=function(t){return new(t||e)(zi(ls),zi(Rs),zi(Hs,8),zi(Vs))};static ɵprov=ii({token:e,factory:e.ɵfac})}return e})(),ry={svg:`http://www.w3.org/2000/svg`,xhtml:`http://www.w3.org/1999/xhtml`,xlink:`http://www.w3.org/1999/xlink`,xml:`http://www.w3.org/XML/1998/namespace`,xmlns:`http://www.w3.org/2000/xmlns/`,math:`http://www.w3.org/1998/Math/MathML`},iy=/%COMP%/g,ay=`%COMP%`,oy=`_nghost-${ay}`,sy=`_ngcontent-${ay}`,cy=!0,ly=new N(``,{factory:()=>cy}),uy=new N(``);function dy(e){return sy.replace(iy,e)}function fy(e){return oy.replace(iy,e)}function py(e,t){return t.map(t=>t.replace(iy,e))}var my=(()=>{class e{eventManager;sharedStylesHost;appId;removeStylesOnCompDestroy;doc;ngZone;nonce;tracingService;rendererByCompId=new Map;defaultRenderer;cssVarNamespace;constructor(e,t,n,r,i,a,o=null,s=null,c=null){this.eventManager=e,this.sharedStylesHost=t,this.appId=n,this.removeStylesOnCompDestroy=r,this.doc=i,this.ngZone=a,this.nonce=o,this.tracingService=s,this.cssVarNamespace=c??``,this.defaultRenderer=new hy(e,i,a,this.tracingService,this.cssVarNamespace)}createRenderer(e,t){if(!e||!t)return this.defaultRenderer;let n=this.getOrCreateRenderer(e,t);return n instanceof yy?n.applyToHost(e):n instanceof vy&&n.applyStyles(),n}getOrCreateRenderer(e,t){let n=this.rendererByCompId,r=n.get(t.id);if(!r){let i=this.doc,a=this.ngZone,o=this.eventManager,s=this.sharedStylesHost,c=this.removeStylesOnCompDestroy,l=this.tracingService;switch(t.encapsulation){case Vl.Emulated:r=new yy(o,s,t,this.appId,c,i,a,l,this.cssVarNamespace);break;case Vl.ShadowDom:return new _y(o,e,t,i,a,this.nonce,l,this.cssVarNamespace,s);case Vl.ExperimentalIsolatedShadowDom:return new _y(o,e,t,i,a,this.nonce,l,this.cssVarNamespace);default:r=new vy(o,s,t,c,i,a,l,this.cssVarNamespace)}n.set(t.id,r)}return r}ngOnDestroy(){this.rendererByCompId.clear()}componentReplaced(e){this.rendererByCompId.delete(e)}static ɵfac=function(t){return new(t||e)(zi(Xv),zi(cp),zi(Rs),zi(ly),zi(ls),zi(Ss),zi(Hs),zi(ju,8),zi(uy,8))};static ɵprov=ii({token:e,factory:e.ɵfac})}return e})(),hy=class{eventManager;doc;ngZone;tracingService;cssVarNamespace;data=Object.create(null);throwOnSyntheticProps=!0;constructor(e,t,n,r,i=``){this.eventManager=e,this.doc=t,this.ngZone=n,this.tracingService=r,this.cssVarNamespace=i}destroy(){}destroyNode=null;createElement(e,t){return t?this.doc.createElementNS(ry[t]||t,e):this.doc.createElement(e)}createComment(e){return this.doc.createComment(e)}createText(e){return this.doc.createTextNode(e)}appendChild(e,t){(gy(e)?e.content:e).appendChild(t)}insertBefore(e,t,n){if(e){let r=gy(e)?e.content:e;if(n!=null&&n.parentNode!==r)throw new M(-5106,!1);r.insertBefore(t,n)}}removeChild(e,t){t.remove()}selectRootElement(e,t){let n=typeof e==`string`?this.doc.querySelector(e):e;if(!n)throw new M(-5104,!1);return t||(n.textContent=``),n}parentNode(e){return e.parentNode}nextSibling(e){return e.nextSibling}setAttribute(e,t,n,r){if(r){t=r+`:`+t;let i=ry[r];i?e.setAttributeNS(i,t,n):e.setAttribute(t,n)}else e.setAttribute(t,n)}removeAttribute(e,t,n){if(n){let r=ry[n];r?e.removeAttributeNS(r,t):e.removeAttribute(`${n}:${t}`)}else e.removeAttribute(t)}addClass(e,t){e.classList.add(t)}removeClass(e,t){e.classList.remove(t)}setStyle(e,t,n,r){let i=t.startsWith(`--`);i&&(t=t.replace(`%NS%`,this.cssVarNamespace)),i||r&(xu.DashCase|xu.Important)?e.style.setProperty(t,n,r&xu.Important?`important`:``):e.style[t]=n}removeStyle(e,t,n){let r=t.startsWith(`--`);r&&(t=t.replace(`%NS%`,this.cssVarNamespace)),r||n&xu.DashCase?e.style.removeProperty(t):e.style[t]=``}setProperty(e,t,n){e!=null&&(e[t]=n)}setValue(e,t){e.nodeValue=t}listen(e,t,n,r){if(typeof e==`string`&&(e=H_().getGlobalEventTarget(this.doc,e),!e))throw new M(-5102,!1);let i=this.decoratePreventDefault(n);return this.tracingService?.wrapEventListener&&(i=this.tracingService.wrapEventListener(e,t,i)),this.eventManager.addEventListener(e,t,i,r)}decoratePreventDefault(e){return t=>{if(t===`__ngUnwrap__`)return e;e(t)===!1&&t.preventDefault()}}};function gy(e){return e.tagName===`TEMPLATE`&&e.content!==void 0}var _y=class extends hy{hostEl;sharedStylesHost;shadowRoot;constructor(e,t,n,r,i,a,o,s,c){super(e,r,i,o,s),this.hostEl=t,this.sharedStylesHost=c,this.shadowRoot=t.attachShadow({mode:`open`}),this.sharedStylesHost&&this.sharedStylesHost.addHost(this.shadowRoot);let l=n.styles;l=py(n.id,l).map(e=>e.replace(/%NS%/g,s));for(let e of l){let t=document.createElement(`style`);a&&t.setAttribute(`nonce`,a),t.textContent=e,this.shadowRoot.appendChild(t)}let u=n.getExternalStyles?.();if(u)for(let e of u){let t=ty(e,r);a&&t.setAttribute(`nonce`,a),this.shadowRoot.appendChild(t)}}nodeOrShadowRoot(e){return e===this.hostEl?this.shadowRoot:e}appendChild(e,t){return super.appendChild(this.nodeOrShadowRoot(e),t)}insertBefore(e,t,n){return super.insertBefore(this.nodeOrShadowRoot(e),t,n)}removeChild(e,t){return super.removeChild(null,t)}parentNode(e){return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(e)))}destroy(){this.sharedStylesHost&&this.sharedStylesHost.removeHost(this.shadowRoot)}},vy=class extends hy{sharedStylesHost;removeStylesOnCompDestroy;styles;styleUrls;constructor(e,t,n,r,i,a,o,s,c){super(e,i,a,o,s),this.sharedStylesHost=t,this.removeStylesOnCompDestroy=r;let l=n.styles,u=c?py(c,l):l;this.styles=u.map(e=>e.replace(/%NS%/g,s)),this.styleUrls=n.getExternalStyles?.(c)}applyStyles(){this.sharedStylesHost.addStyles(this.styles,this.styleUrls)}destroy(){this.removeStylesOnCompDestroy&&wu.size===0&&this.sharedStylesHost.removeStyles(this.styles,this.styleUrls)}},yy=class extends vy{contentAttr;hostAttr;constructor(e,t,n,r,i,a,o,s,c){let l=r+`-`+n.id;super(e,t,n,i,a,o,s,c,l),this.contentAttr=dy(l),this.hostAttr=fy(l)}applyToHost(e){this.applyStyles(),this.setAttribute(e,this.hostAttr,``)}createElement(e,t){let n=super.createElement(e,t);return super.setAttribute(n,this.contentAttr,``),n}},by=class e extends W_{supportsDOMEvents=!0;static makeCurrent(){U_(new e)}onAndCancel(e,t,n,r){return e.addEventListener(t,n,r),()=>{e.removeEventListener(t,n,r)}}dispatchEvent(e,t){e.dispatchEvent(t)}remove(e){e.remove()}createElement(e,t){return t||=this.getDefaultDocument(),t.createElement(e)}createHtmlDocument(){return document.implementation.createHTMLDocument(`fakeTitle`)}getDefaultDocument(){return document}isElementNode(e){return e.nodeType===Node.ELEMENT_NODE}isShadowRoot(e){return e instanceof DocumentFragment}getGlobalEventTarget(e,t){return t===`window`?window:t===`document`?e:t===`body`?e.body:null}getBaseHref(e){let t=Sy();return t==null?null:Cy(t)}resetBaseElement(){xy=null}getUserAgent(){return window.navigator.userAgent}getCookie(e){return Gv(document.cookie,e)}},xy=null;function Sy(){return xy||=document.head.querySelector(`base`),xy?xy.getAttribute(`href`):null}function Cy(e){return new URL(e,document.baseURI).pathname}var wy=[`alt`,`control`,`meta`,`shift`],Ty={"\b":`Backspace`," ":`Tab`,"":`Delete`,"\x1B":`Escape`,Del:`Delete`,Esc:`Escape`,Left:`ArrowLeft`,Right:`ArrowRight`,Up:`ArrowUp`,Down:`ArrowDown`,Menu:`ContextMenu`,Scroll:`ScrollLock`,Win:`OS`},Ey={alt:e=>e.altKey,control:e=>e.ctrlKey,meta:e=>e.metaKey,shift:e=>e.shiftKey},Dy=(()=>{class e extends qv{constructor(e){super(e)}supports(t){return e.parseEventName(t)!=null}addEventListener(t,n,r,i){let a=e.parseEventName(n),o=e.eventCallback(a.fullKey,r,this.manager.getZone());return this.manager.getZone().runOutsideAngular(()=>H_().onAndCancel(t,a.domEventName,o,i))}static parseEventName(t){let n=t.toLowerCase().split(`.`),r=n.shift();if(n.length===0||r!==`keydown`&&r!==`keyup`)return null;let i=e._normalizeKey(n.pop()),a=``,o=n.indexOf(`code`);if(o>-1&&(n.splice(o,1),a=`code.`),wy.forEach(e=>{let t=n.indexOf(e);t>-1&&(n.splice(t,1),a+=e+`.`)}),a+=i,n.length!=0||i.length===0)return null;let s={};return s.domEventName=r,s.fullKey=a,s}static matchEventFullKeyCode(e,t){let n=Ty[e.key]||e.key,r=``;return t.indexOf(`code.`)>-1&&(n=e.code,r=`code.`),n==null||!n?!1:(n=n.toLowerCase(),n===` `?n=`space`:n===`.`&&(n=`dot`),wy.forEach(t=>{if(t!==n){let n=Ey[t];n(e)&&(r+=t+`.`)}}),r+=n,r===t)}static eventCallback(t,n,r){return i=>{e.matchEventFullKeyCode(i,t)&&r.runGuarded(()=>n(i))}}static _normalizeKey(e){return e===`esc`?`escape`:e}static ɵfac=function(t){return new(t||e)(zi(ls))};static ɵprov=ii({token:e,factory:e.ɵfac})}return e})();async function Oy(e,t,n){return B_({rootComponent:e,...ky(t,n)})}function ky(e,t){return{platformRef:t?.platformRef,appProviders:[...Py,...e?.providers??[]],platformProviders:Ny}}function Ay(){by.makeCurrent()}function jy(){return new Ps}function My(){return El(document),document}var Ny=[{provide:Vs,useValue:Kv},{provide:Bs,useValue:Ay,multi:!0},{provide:ls,useFactory:My}],Py=[{provide:ha,useValue:`root`},{provide:Ps,useFactory:jy},{provide:Yv,useClass:Jv,multi:!0},{provide:Yv,useClass:Dy,multi:!0},my,{provide:cp,useClass:ny},{provide:ny,useExisting:cp},Xv,{provide:Wf,useExisting:my},[]];function Fy(e,t){let n=`\x1B[${e}m`,r=`\x1B[${t}m`;return((e,...t)=>{if(Array.isArray(e)&&`raw`in e){let i=e,a=``;for(let e=0;e{let r=new zy({code:i,why:Ly(a.why,e),fix:Ly(a.fix,e),docs:o,cause:e.cause,sources:e.sources,data:Ly(a.data,e)},s);for(let e of t)e(r,n);return r};n[i]=s}return n}function Hy(e){return t=>{let n=`${e.bold(e.red(`[${t.name}]`))} ${t.message}`,r=[];return t.fix&&r.push(`${e.dim(`fix:`)} ${t.fix}`),t.sources?.length&&r.push(`${e.dim(`sources:`)} ${t.sources.join(`, `)}`),t.docs&&r.push(`${e.dim(`see:`)} ${e.cyan(t.docs)}`),r.length===0?n:[n,...r.map((t,n)=>`${e.dim(n{e=n,t=r}),resolve:e,reject:t}}var Jy=Math.random.bind(Math),Yy=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`;function Xy(e=21){let t=``,n=e;for(;n--;)t+=Yy[Jy()*64|0];return t}var Zy=6e4,Qy=e=>e,$y=Qy,{clearTimeout:eb,setTimeout:tb}=globalThis;function nb(e,t){let{post:n,on:r,off:i=()=>{},eventNames:a=[],serialize:o=Qy,deserialize:s=$y,resolver:c,bind:l=`rpc`,timeout:u=Zy,proxify:d=!0}=t,f=!1,p=new Map,m,h;async function g(e,r,i,a){if(f)throw Error(`[birpc] rpc is closed, cannot call "${e}"`);let s={m:e,a:r,t:`q`};a&&(s.o=!0);let c=async e=>n(o(e));if(i){await c(s);return}if(m)try{await m}finally{m=void 0}let{promise:l,resolve:d,reject:g}=qy(),_=Xy();s.i=_;let v;async function y(n=s){return u>=0&&(v=tb(()=>{try{if(t.onTimeoutError?.call(h,e,r)!==!0)throw Error(`[birpc] timeout on calling "${e}"`)}catch(e){g(e)}p.delete(_)},u),typeof v==`object`&&(v=v.unref?.())),p.set(_,{resolve:d,reject:g,timeoutId:v,method:e}),await c(n),l}try{t.onRequest?await t.onRequest.call(h,s,y,d):await y()}catch(e){if(t.onGeneralError?.call(h,e)!==!0)throw e;return}finally{eb(v),p.delete(_)}return l}let _={$call:(e,...t)=>g(e,t,!1),$callOptional:(e,...t)=>g(e,t,!1,!0),$callEvent:(e,...t)=>g(e,t,!0),$callRaw:e=>g(e.method,e.args,e.event,e.optional),$rejectPendingCalls:y,get $closed(){return f},get $meta(){return t.meta},$close:v,$functions:e};h=d?new Proxy({},{get(t,n){if(Object.hasOwn(_,n))return _[n];if(n===`then`&&!a.includes(`then`)&&!(`then`in e))return;let r=(...e)=>g(n,e,!0);if(a.includes(n))return r.asEvent=r,r;let i=(...e)=>g(n,e,!1);return i.asEvent=r,i}}):_;function v(e){f=!0,p.forEach(({reject:t,method:n})=>{let r=Error(`[birpc] rpc is closed, cannot call "${n}"`);if(e)return e.cause??=r,t(e);t(r)}),p.clear(),i(b)}function y(e){let t=Array.from(p.values()).map(({method:t,reject:n})=>e?e({method:t,reject:n}):n(Error(`[birpc]: rejected pending call "${t}".`)));return p.clear(),t}async function b(r,...i){let a;try{a=s(r)}catch(e){if(t.onGeneralError?.call(h,e)!==!0)throw e;return}if(a.t===`q`){let{m:r,a:s,o:u}=a,d,f,p=await(c?c.call(h,r,e[r]):e[r]);if(u&&(p||=()=>void 0),!p)f=Error(`[birpc] function "${r}" not found`);else try{d=await p.apply(l===`rpc`?h:e,s)}catch(e){f=e}if(a.i){if(f&&t.onFunctionError&&t.onFunctionError.call(h,f,r,s)===!0)return;if(!f)try{await n(o({t:`s`,i:a.i,r:d}),...i);return}catch(e){if(f=e,t.onGeneralError?.call(h,e,r,s)!==!0)throw e}try{await n(o({t:`s`,i:a.i,e:f}),...i)}catch(e){if(t.onGeneralError?.call(h,e,r,s)!==!0)throw e}}}else{let{i:e,r:t,e:n}=a,r=p.get(e);r&&(eb(r.timeoutId),n?r.reject(n):r.resolve(t)),p.delete(e)}}return m=r(b),h}function rb(e,t){return t.safety?t.safety:e===`static`||e===`query`||e==null?`read`:`action`}var ib=Object.freeze({type:`object`,additionalProperties:!0});function ab(e){let t=e[`~standard`];if(t.jsonSchema)try{return t.jsonSchema.input({target:`draft-2020-12`})}catch{return ib}return ib}function ob(e){if(!e||e.length===0)return{type:`object`,properties:{}};let t={},n=[];for(let r=0;rn[`arg${t}`]);if(`arg0`in n){let e=[];for(;`arg${e.length}`in n;)e.push(n[`arg${e.length}`]);return e}return Object.keys(n).length===0?[]:void 0}function cb(e,t){return sb(e,t)??[e]}function lb(e){return typeof e==`string`?`'${e}'`:new pb().serialize(e)}var ub=` _-,;:!?.'"()[]{}@*/\\&#%\`^+<=>|~$0123456789abcdefghijklmnopqrstuvwxyz`,db=(function(){let e=new Uint8Array(128);for(let t=0;t<69;t++)e[ub.charCodeAt(t)]=t+1;for(let t=65;t<=90;t++)e[t]=e[t+32];return e})();function fb(e,t){if(e===t)return 0;let n=Math.min(e.length,t.length),r=0;for(let i=0;ia?-1:1)}return e.length===t.length?r:e.lengththis.compare(e[0],t[0])),r=`${e}{`;for(let e=0;ethis.compare(e,t)))}`}$Map(e){return this.serializeObjectEntries(`Map`,e.entries())}}for(let t of[`Error`,`RegExp`,`URL`])e.prototype[`$`+t]=function(e){return`${t}(${e})`};for(let t of[`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float32Array`,`Float64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`,`)}]`};for(let t of[`BigInt64Array`,`BigUint64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`n,`)}${e.length>0?`n`:``}]`};return e})(),mb=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225],hb=[1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,-778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998],gb=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_`,_b=[],vb=class{_data=new yb;_hash=new yb([...mb]);_nDataBytes=0;_minBufferSize=0;finalize(e){e&&this._append(e);let t=this._nDataBytes*8,n=this._data.sigBytes*8;return this._data.words[n>>>5]|=128<<24-n%32,this._data.words[(n+64>>>9<<4)+14]=Math.floor(t/4294967296),this._data.words[(n+64>>>9<<4)+15]=t,this._data.sigBytes=this._data.words.length*4,this._process(),this._hash}_doProcessBlock(e,t){let n=this._hash.words,r=n[0],i=n[1],a=n[2],o=n[3],s=n[4],c=n[5],l=n[6],u=n[7];for(let n=0;n<64;n++){if(n<16)_b[n]=e[t+n]|0;else{let e=_b[n-15],t=(e<<25|e>>>7)^(e<<14|e>>>18)^e>>>3,r=_b[n-2],i=(r<<15|r>>>17)^(r<<13|r>>>19)^r>>>10;_b[n]=t+_b[n-7]+i+_b[n-16]}let d=s&c^~s&l,f=r&i^r&a^i&a,p=(r<<30|r>>>2)^(r<<19|r>>>13)^(r<<10|r>>>22),m=(s<<26|s>>>6)^(s<<21|s>>>11)^(s<<7|s>>>25),h=u+m+d+hb[n]+_b[n],g=p+f;u=l,l=c,c=s,s=o+h|0,o=a,a=i,i=r,r=h+g|0}n[0]=n[0]+r|0,n[1]=n[1]+i|0,n[2]=n[2]+a|0,n[3]=n[3]+o|0,n[4]=n[4]+s|0,n[5]=n[5]+c|0,n[6]=n[6]+l|0,n[7]=n[7]+u|0}_append(e){typeof e==`string`&&(e=yb.fromUtf8(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes}_process(e){let t,n=this._data.sigBytes/64;n=e?Math.ceil(n):Math.max((n|0)-this._minBufferSize,0);let r=n*16,i=Math.min(r*4,this._data.sigBytes);if(r){for(let e=0;e>>2]|=(n.charCodeAt(e)&255)<<24-e%4*8;return new e(i,r)}toBase64(){let e=[];for(let t=0;t>>2]>>>24-t%4*8&255,r=this.words[t+1>>>2]>>>24-(t+1)%4*8&255,i=this.words[t+2>>>2]>>>24-(t+2)%4*8&255,a=n<<16|r<<8|i;for(let n=0;n<4&&t*8+n*6>>6*(3-n)&63))}return e.join(``)}concat(e){if(this.words[this.sigBytes>>>2]&=4294967295<<32-this.sigBytes%4*8,this.words.length=Math.ceil(this.sigBytes/4),this.sigBytes%4)for(let t=0;t>>2]>>>24-t%4*8&255;this.words[this.sigBytes+t>>>2]|=n<<24-(this.sigBytes+t)%4*8}else for(let t=0;t>>2]=e.words[t>>>2];this.sigBytes+=e.sigBytes}};function bb(e){return new vb().finalize(e).toBase64()}function xb(e){return bb(lb(e))}function Sb(e){return xb(e)}function Cb(){let e={};function t(t,...n){let r=e[t]||[];for(let e=0,t=r.length;e{e[t]=e[t]?.filter(e=>n!==e)}}function i(e,t){let n=r(e,((...e)=>(n(),t(...e))));return n}return{_listeners:e,emit:t,emitOnce:n,on:r,once:i}}var wb=/^[\w+.-]{2,}:\/\//;function Tb(e){return e.endsWith(`/`)?e:`${e}/`}function Eb(e){return(e.endsWith(`/`)?e.slice(0,-1):e)||`/`}function Db(e,...t){let n=e;for(let e of t)e&&e!==`/`&&(n=n?Tb(n)+e.replace(/^\.?\//,``):e);return n}function Ob(e,t){if(!t||t===`/`||wb.test(e))return e;let n=Eb(t);return e.startsWith(n)?e:Db(n,e)}function kb(e,t){let n=e.match(wb);return t+(n?e.slice(n[0].length):e)}var Ab=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`;function jb(e=21){let t=``,n=e;for(;n--;)t+=Ab[Math.random()*64|0];return t}var Mb=Symbol.for(`immer-nothing`),Nb=Symbol.for(`immer-draftable`),Pb=Symbol.for(`immer-state`),Fb=[function(e){return`The plugin for '${e}' has not been loaded into Immer. To enable the plugin, import and call \`enable${e}()\` when initializing your application.`},function(e){return`produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '${e}'`},`This object has been frozen and should not be mutated`,function(e){return`Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? `+e},`An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.`,`Immer forbids circular references`,"The first or second argument to `produce` must be a function","The third argument to `produce` must be a function or undefined","First argument to `createDraft` must be a plain object, an array, or an immerable object","First argument to `finishDraft` must be a draft returned by `createDraft`",function(e){return`'current' expects a draft, got: ${e}`},`Object.defineProperty() cannot be used on an Immer draft`,`Object.setPrototypeOf() cannot be used on an Immer draft`,`Immer only supports deleting array indices`,`Immer only supports setting array indices and the 'length' property`,function(e){return`'original' expects a draft, got: ${e}`}];function Ib(e,...t){{let n=Fb[e],r=ox(n)?n.apply(null,t):n;throw Error(`[Immer] ${r}`)}}var Lb=Object,Rb=Lb.getPrototypeOf,zb=`constructor`,Bb=`prototype`,Vb=`configurable`,Hb=`enumerable`,Ub=`writable`,Wb=`value`,Gb=e=>!!e&&!!e[Pb];function Kb(e){return e?Yb(e)||nx(e)||!!e[Nb]||!!e[zb]?.[Nb]||rx(e)||ix(e):!1}var qb=Lb[Bb][zb].toString(),Jb=new WeakMap;function Yb(e){if(!e||!ax(e))return!1;let t=Rb(e);if(t===null||t===Lb[Bb])return!0;let n=Lb.hasOwnProperty.call(t,zb)&&t[zb];if(n===Object)return!0;if(!ox(n))return!1;let r=Jb.get(n);return r===void 0&&(r=Function.toString.call(n),Jb.set(n,r)),r===qb}function Xb(e,t,n=!0){Zb(e)===0?(n?Reflect.ownKeys(e):Lb.keys(e)).forEach(n=>{t(n,e[n],e)}):e.forEach((n,r)=>t(r,n,e))}function Zb(e){let t=e[Pb];return t?t.type_:nx(e)?1:rx(e)?2:ix(e)?3:0}var Qb=(e,t,n=Zb(e))=>n===2?e.has(t):Lb[Bb].hasOwnProperty.call(e,t),$b=(e,t,n=Zb(e))=>n===2?e.get(t):e[t],ex=(e,t,n,r=Zb(e))=>{r===2?e.set(t,n):r===3?e.add(n):e[t]=n};function tx(e,t){return e===t?e!==0||1/e==1/t:e!==e&&t!==t}var nx=Array.isArray,rx=e=>e instanceof Map,ix=e=>e instanceof Set,ax=e=>typeof e==`object`,ox=e=>typeof e==`function`,sx=e=>typeof e==`boolean`;function cx(e){let t=+e;return Number.isInteger(t)&&String(t)===e}var lx=e=>ax(e)?e?.[Pb]:null,ux=e=>e.copy_||e.base_,dx=e=>e.modified_?e.copy_:e.base_;function fx(e,t){if(rx(e))return new Map(e);if(ix(e))return new Set(e);if(nx(e))return Array[Bb].slice.call(e);let n=Yb(e);if(t===!0||t===`class_only`&&!n){let t=Lb.getOwnPropertyDescriptors(e);delete t[Pb];let n=Reflect.ownKeys(t);for(let r=0;r1&&Lb.defineProperties(e,{set:hx,add:hx,clear:hx,delete:hx}),Lb.freeze(e),t&&Xb(e,(e,t)=>{px(t,!0)},!1),e)}function mx(){Ib(2)}var hx={[Wb]:mx};function gx(e){return e===null||!ax(e)||Lb.isFrozen(e)}var _x=`MapSet`,vx=`Patches`,yx=`ArrayMethods`,bx={};function xx(e){let t=bx[e];return t||Ib(0,e),t}var Sx=e=>!!bx[e];function Cx(e,t){bx[e]||(bx[e]=t)}var wx,Tx=()=>wx,Ex=(e,t)=>({drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0,handledSet_:new Set,processedForPatches_:new Set,mapSetPlugin_:Sx(_x)?xx(_x):void 0,arrayMethodsPlugin_:Sx(yx)?xx(yx):void 0});function Dx(e,t){t&&(e.patchPlugin_=xx(vx),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function Ox(e){kx(e),e.drafts_.forEach(jx),e.drafts_=null}function kx(e){e===wx&&(wx=e.parent_)}var Ax=e=>wx=Ex(wx,e);function jx(e){let t=e[Pb];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function Mx(e,t){t.unfinalizedDrafts_=t.drafts_.length;let n=t.drafts_[0];if(e!==void 0&&e!==n){n[Pb].modified_&&(Ox(t),Ib(4)),Kb(e)&&(e=Nx(t,e));let{patchPlugin_:r}=t;r&&r.generateReplacementPatches_(n[Pb].base_,e,t)}else e=Nx(t,n);return Px(t,e,!0),Ox(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e===Mb?void 0:e}function Nx(e,t){if(gx(t))return t;let n=t[Pb];if(!n)return Hx(t,e.handledSet_,e);if(!Ix(n,e))return t;if(!n.modified_)return n.base_;if(!n.finalized_){let{callbacks_:t}=n;if(t)for(;t.length>0;)t.pop()(e);Bx(n,e)}return n.copy_}function Px(e,t,n=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&px(t,n)}function Fx(e){e.finalized_=!0,e.scope_.unfinalizedDrafts_--}var Ix=(e,t)=>e.scope_===t,Lx=[];function Rx(e,t,n,r){let i=ux(e),a=e.type_;if(r!==void 0&&$b(i,r,a)===t){ex(i,r,n,a);return}if(!e.draftLocations_){let t=e.draftLocations_=new Map;Xb(i,(e,n)=>{if(Gb(n)){let r=t.get(n)||[];r.push(e),t.set(n,r)}})}let o=e.draftLocations_.get(t)??Lx;for(let e of o)ex(i,e,n,a)}function zx(e,t,n){e.callbacks_.push(function(r){let i=t;if(!i||!Ix(i,r))return;r.mapSetPlugin_?.fixSetContents(i);let a=dx(i);Rx(e,i.draft_??i,a,n),Bx(i,r)})}function Bx(e,t){if(e.modified_&&!e.finalized_&&(e.type_===3||e.type_===1&&e.allIndicesReassigned_||(e.assigned_?.size??0)>0)){let{patchPlugin_:n}=t;if(n){let r=n.getPath(e);r&&n.generatePatches_(e,r,t)}Fx(e)}}function Vx(e,t,n){let{scope_:r}=e;if(Gb(n)){let i=n[Pb];Ix(i,r)&&i.callbacks_.push(function(){Zx(e),Rx(e,n,dx(i),t)})}else Kb(n)&&e.callbacks_.push(function(){let i=ux(e);e.type_===3?i.has(n)&&Hx(n,r.handledSet_,r):$b(i,t,e.type_)===n&&r.drafts_.length>1&&(e.assigned_.get(t)??!1)===!0&&e.copy_&&Hx($b(e.copy_,t,e.type_),r.handledSet_,r)})}function Hx(e,t,n){return!n.immer_.autoFreeze_&&n.unfinalizedDrafts_<1||Gb(e)||t.has(e)||!Kb(e)||gx(e)?e:(t.add(e),Xb(e,(r,i)=>{if(Gb(i)){let t=i[Pb];Ix(t,n)&&(ex(e,r,dx(t),e.type_),Fx(t))}else Kb(i)&&Hx(i,t,n)}),e)}function Ux(e,t){let n=nx(e),r={type_:+!!n,scope_:t?t.scope_:Tx(),modified_:!1,finalized_:!1,assigned_:void 0,parent_:t,base_:e,draft_:null,copy_:null,revoke_:null,isManual_:!1,callbacks_:void 0},i=r,a=Wx;n&&(i=[r],a=Gx);let{revoke:o,proxy:s}=Proxy.revocable(i,a);return r.draft_=s,r.revoke_=o,[s,r]}var Wx={get(e,t){if(t===Pb)return e;let n=e.scope_.arrayMethodsPlugin_,r=e.type_===1&&typeof t==`string`;if(r&&n?.isArrayOperationMethod(t))return n.createMethodInterceptor(e,t);let i=ux(e);if(!Qb(i,t,e.type_))return Jx(e,i,t);let a=i[t];if(e.finalized_||!Kb(a)||r&&e.operationMethod&&n?.isMutatingArrayMethod(e.operationMethod)&&cx(t))return a;if(a===Kx(e.base_,t)||qx(e,t,a)){Zx(e);let n=e.type_===1?+t:t,r=$x(e.scope_,a,e,n);return e.copy_[n]=r}return a},has(e,t){return t in ux(e)},ownKeys(e){return Reflect.ownKeys(ux(e))},set(e,t,n){let r=Yx(ux(e),t);if(r?.set)return r.set.call(e.draft_,n),!0;if(!e.modified_){let r=Kx(ux(e),t),i=r?.[Pb];if(i&&i.base_===n)return e.copy_[t]=n,e.assigned_.set(t,!1),!0;if(tx(n,r)&&(n!==void 0||Qb(e.base_,t,e.type_)))return!0;Zx(e),Xx(e)}return e.copy_[t]===n&&(n!==void 0||Qb(e.copy_,t,e.type_))||Number.isNaN(n)&&Number.isNaN(e.copy_[t])?!0:(e.copy_[t]=n,e.assigned_.set(t,!0),Vx(e,t,n),!0)},deleteProperty(e,t){return Zx(e),Kx(e.base_,t)!==void 0||t in e.base_?(e.assigned_.set(t,!1),Xx(e)):e.assigned_.delete(t),e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){let n=ux(e),r=Reflect.getOwnPropertyDescriptor(n,t);return r&&{[Ub]:!0,[Vb]:e.type_!==1||t!==`length`,[Hb]:r[Hb],[Wb]:n[t]}},defineProperty(){Ib(11)},getPrototypeOf(e){return Rb(e.base_)},setPrototypeOf(){Ib(12)}},Gx={};for(let e in Wx){let t=Wx[e];Gx[e]=function(){let e=arguments;return e[0]=e[0][0],t.apply(this,e)}}Gx.deleteProperty=function(e,t){return isNaN(parseInt(t))&&Ib(13),Gx.set.call(this,e,t,void 0)},Gx.set=function(e,t,n){return t!==`length`&&isNaN(parseInt(t))&&Ib(14),Wx.set.call(this,e[0],t,n,e[0])};function Kx(e,t){let n=e[Pb];return(n?ux(n):e)[t]}function qx(e,t,n){return e.type_!==1||!e.allIndicesReassigned_||e.assigned_?.get(t)||!Kb(n)||n[Pb]?!1:e.baseRefs_.has(n)}function Jx(e,t,n){let r=Yx(t,n);return r?Wb in r?r[Wb]:r.get?.call(e.draft_):void 0}function Yx(e,t){if(!(t in e))return;let n=Rb(e);for(;n;){let e=Object.getOwnPropertyDescriptor(n,t);if(e)return e;n=Rb(n)}}function Xx(e){e.modified_||(e.modified_=!0,e.parent_&&Xx(e.parent_))}function Zx(e){e.copy_||=(e.assigned_=new Map,fx(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var Qx=class{constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!1,this.produce=(e,t,n)=>{if(ox(e)&&!ox(t)){let n=t;t=e;let r=this;return function(e=n,...i){return r.produce(e,e=>t.call(this,e,...i))}}ox(t)||Ib(6),n!==void 0&&!ox(n)&&Ib(7);let r;if(Kb(e)){let i=Ax(this),a=$x(i,e,void 0),o=!0;try{r=t(a),o=!1}finally{o?Ox(i):kx(i)}return Dx(i,n),Mx(r,i)}if(!e||!ax(e)){if(r=t(e),r===void 0&&(r=e),r===Mb&&(r=void 0),this.autoFreeze_&&px(r,!0),n){let t=[],i=[];xx(vx).generateReplacementPatches_(e,r,{patches_:t,inversePatches_:i}),n(t,i)}return r}Ib(1,e)},this.produceWithPatches=(e,t)=>{if(ox(e))return(t,...n)=>this.produceWithPatches(t,t=>e(t,...n));let n,r;return[this.produce(e,t,(e,t)=>{n=e,r=t}),n,r]},sx(e?.autoFreeze)&&this.setAutoFreeze(e.autoFreeze),sx(e?.useStrictShallowCopy)&&this.setUseStrictShallowCopy(e.useStrictShallowCopy),sx(e?.useStrictIteration)&&this.setUseStrictIteration(e.useStrictIteration)}createDraft(e){Kb(e)||Ib(8),Gb(e)&&(e=eS(e));let t=Ax(this),n=$x(t,e,void 0);return n[Pb].isManual_=!0,kx(t),n}finishDraft(e,t){let n=e&&e[Pb];(!n||!n.isManual_)&&Ib(9);let{scope_:r}=n;return Dx(r,t),Mx(void 0,r)}setAutoFreeze(e){this.autoFreeze_=e}setUseStrictShallowCopy(e){this.useStrictShallowCopy_=e}setUseStrictIteration(e){this.useStrictIteration_=e}shouldUseStrictIteration(){return this.useStrictIteration_}applyPatches(e,t){let n;for(n=t.length-1;n>=0;n--){let r=t[n];if(r.path.length===0&&r.op===`replace`){e=r.value;break}}n>-1&&(t=t.slice(n+1));let r=xx(vx).applyPatches_;return Gb(e)?r(e,t):this.produce(e,e=>r(e,t))}};function $x(e,t,n,r){let[i,a]=rx(t)?xx(_x).proxyMap_(t,n):ix(t)?xx(_x).proxySet_(t,n):Ux(t,n);return(n?.scope_??Tx()).drafts_.push(i),a.callbacks_=n?.callbacks_??[],a.key_=r,n&&r!==void 0?zx(n,a,r):a.callbacks_.push(function(e){e.mapSetPlugin_?.fixSetContents(a);let{patchPlugin_:t}=e;a.modified_&&t&&t.generatePatches_(a,[],e)}),i}function eS(e){return Gb(e)||Ib(10,e),tS(e)}function tS(e){if(!Kb(e)||gx(e))return e;let t=e[Pb],n,r=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,n=fx(e,t.scope_.immer_.useStrictShallowCopy_),r=t.scope_.immer_.shouldUseStrictIteration()}else n=fx(e,!0);return Xb(n,(e,t)=>{ex(n,e,tS(t))},r),t&&(t.finalized_=!1),n}function nS(){Fb.push(`Sets cannot have "replace" patches.`,function(e){return`Unsupported patch operation: `+e},function(e){return`Cannot apply patch, path doesn't resolve: `+e},`Patching reserved attributes like __proto__, prototype and constructor is not allowed`);function e(n,r=[]){if(n.key_!==void 0){let e=n.parent_.copy_??n.parent_.base_,t=lx($b(e,n.key_)),i=$b(e,n.key_);if(i===void 0||i!==n.draft_&&i!==n.base_&&i!==n.copy_||t!=null&&t.base_!==n.base_)return null;let a=n.parent_.type_===3,o;if(a){let e=n.parent_;o=Array.from(e.drafts_.keys()).indexOf(n.key_)}else o=n.key_;if(!(a&&e.size>o||Qb(e,o)))return null;r.push(o)}if(n.parent_)return e(n.parent_,r);r.reverse();try{t(n.copy_,r)}catch{return null}return r}function t(e,t){let n=e;for(let e=0;e{let u=$b(o,e,c),f=$b(s,e,c),p=l?Qb(o,e)?n:`add`:r;if(u===f&&p===n)return;let m=t.concat(e);i.push(p===r?{op:p,path:m}:{op:p,path:m,value:d(f)}),a.push(p===`add`?{op:r,path:m}:p===r?{op:`add`,path:m,value:d(u)}:{op:n,path:m,value:d(u)})})}function s(e,t,n,i){let{base_:a,copy_:o}=e,s=0;a.forEach(e=>{if(!o.has(e)){let a=t.concat([s]);n.push({op:r,path:a,value:e}),i.unshift({op:`add`,path:a,value:e})}s++}),s=0,o.forEach(e=>{if(!a.has(e)){let a=t.concat([s]);n.push({op:`add`,path:a,value:e}),i.unshift({op:r,path:a,value:e})}s++})}function c(e,t,r){let{patches_:i,inversePatches_:a}=r;i.push({op:n,path:[],value:t===Mb?void 0:t}),a.push({op:n,path:[],value:e})}function l(e,t){return t.forEach(t=>{let{path:i,op:a}=t,o=e;for(let e=0;e[e,u(t)]));if(ix(e))return new Set(Array.from(e).map(u));let t=Object.create(Rb(e));for(let n in e)t[n]=u(e[n]);return Qb(e,Nb)&&(t[Nb]=e[Nb]),t}function d(e){return Gb(e)?u(e):e}Cx(vx,{applyPatches_:l,generatePatches_:i,generateReplacementPatches_:c,getPath:e})}globalThis.Iterator?.from;var rS=new Qx,iS=rS.produce,aS=rS.produceWithPatches.bind(rS),oS=rS.applyPatches.bind(rS),sS=1e3;function cS(e,t){if(e.add(t),e.size>sS){let t=e.values().next().value;t!==void 0&&e.delete(t)}}function lS(e){let{enablePatches:t=!1}=e;t&&nS();let n=Cb(),r=e.initialValue,i=new Set;return{on:n.on,value:()=>r,patch:(e,t=jb())=>{i.has(t)||(nS(),r=oS(r,e),cS(i,t),n.emit(`updated`,r,void 0,t))},mutate:(e,a=jb())=>{if(!i.has(a)){if(cS(i,a),t){let[t,i]=aS(r,e);if(t===r)return;r=t,n.emit(`updated`,r,i,a)}else{let t=iS(r,e);if(t===r)return;r=t,n.emit(`updated`,r,void 0,a)}}},syncIds:i}}var uS=typeof self==`object`?self:globalThis,dS=new Set([`Error`,`EvalError`,`RangeError`,`ReferenceError`,`SyntaxError`,`TypeError`,`URIError`,`AggregateError`]),fS=new Set([`Boolean`,`Number`,`String`,`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float16Array`,`Float32Array`,`Float64Array`,`BigInt64Array`,`BigUint64Array`]);function pS(e,t){let n=(t,n)=>(e.set(n,t),t),r=i=>{if(e.has(i))return e.get(i);let[a,o]=t[i];switch(a){case 0:case-1:return n(o,i);case 1:{let e=n([],i);for(let t of o)e.push(r(t));return e}case 2:{let e=n({},i);for(let[t,n]of o)e[r(t)]=r(n);return e}case 3:return n(new Date(o),i);case 4:{let{source:e,flags:t}=o;return n(new RegExp(e,t),i)}case 5:{let e=n(new Map,i);for(let[t,n]of o)e.set(r(t),r(n));return e}case 6:{let e=n(new Set,i);for(let t of o)e.add(r(t));return e}case 7:{let{name:e,message:t}=o,r=dS.has(e)?uS[e]:void 0;return n(new(r??uS.Error)(t),i)}case 8:return n(BigInt(o),i);case`BigInt`:return n(Object(BigInt(o)),i);case`ArrayBuffer`:return n(new Uint8Array(o).buffer,o);case`DataView`:{let{buffer:e}=new Uint8Array(o);return n(new DataView(e),o)}}if(typeof a==`string`&&fS.has(a))return n(new uS[a](o),i);throw TypeError(`unable to deserialize unsafe or unknown type: ${String(a)}`)};return r}function mS(e){return pS(new Map,e)(0)}var hS=``,{toString:gS}={},{keys:_S}=Object;function vS(e){let t=typeof e;if(t!==`object`||!e)return[0,t];let n=gS.call(e).slice(8,-1);switch(n){case`Array`:return[1,hS];case`Object`:return[2,hS];case`Date`:return[3,hS];case`RegExp`:return[4,hS];case`Map`:return[5,hS];case`Set`:return[6,hS];case`DataView`:return[1,n]}return n.includes(`Array`)?[1,n]:n.includes(`Error`)?[7,n]:[2,n]}function yS([e,t]){return e===0&&(t===`function`||t===`symbol`)}function bS(e,t,n,r){let i=(e,t)=>{let i=r.push(e)-1;return n.set(t,i),i},a=r=>{if(n.has(r))return n.get(r);let[o,s]=vS(r);switch(o){case 0:{let t=r;switch(s){case`bigint`:o=8,t=r.toString();break;case`function`:case`symbol`:if(e)throw TypeError(`unable to serialize ${s}`);t=null;break;case`undefined`:return i([-1],r)}return i([o,t],r)}case 1:{if(s){let e=r;return s===`DataView`?e=new Uint8Array(r.buffer):s===`ArrayBuffer`&&(e=new Uint8Array(r)),i([s,[...e]],r)}let e=[],t=i([o,e],r);for(let t of r)e.push(a(t));return t}case 2:{if(s)switch(s){case`BigInt`:return i([s,r.toString()],r);case`Boolean`:case`Number`:case`String`:return i([s,r.valueOf()],r)}if(t&&`toJSON`in r)return a(r.toJSON());let n=[],c=i([o,n],r);for(let t of _S(r))(e||!yS(vS(r[t])))&&n.push([a(t),a(r[t])]);return c}case 3:return i([o,r.toISOString()],r);case 4:{let{source:e,flags:t}=r;return i([o,{source:e,flags:t}],r)}case 5:{let t=[],n=i([o,t],r);for(let[n,i]of r)(e||!(yS(vS(n))||yS(vS(i))))&&t.push([a(n),a(i)]);return n}case 6:{let t=[],n=i([o,t],r);for(let n of r)(e||!yS(vS(n)))&&t.push(a(n));return n}}let{message:c}=r;return i([o,{name:s,message:c}],r)};return a}function xS(e,t={}){let n=[];return bS(!(t.json||t.lossy),!!t.json,new Map,n)(e),n}var{parse:SS,stringify:CS}=JSON,wS={json:!0,lossy:!0};function TS(e){return mS(SS(e))}function ES(e){return CS(xS(e,wS))}function DS(e){return mS(e)}function OS(e){return ES(e)}function kS(e){return TS(e)}var AS=256,jS=class extends Error{name=`StreamClosedError`};function MS(e={}){let t=e.id??jb(),n=Math.max(0,e.replayWindow??0),r=Cb(),i=new AbortController,a=[],o=!1,s=0;function c(e){if(o)throw new jS(`Cannot write to a closed stream "${t}"`);s+=1,n>0&&(a.push({seq:s,chunk:e}),a.length>n&&(a.length-n===1?a.shift():a.splice(0,a.length-n))),r.emit(`chunk`,s,e)}function l(e){if(o)return;o=!0;let t=PS(e);i.abort(e),r.emit(`end`,t)}function u(){o||(o=!0,i.signal.aborted||i.abort(`stream closed`),r.emit(`end`,void 0))}function d(e){o||i.signal.aborted||i.abort(e??`aborted`)}let f=new WritableStream({write(e){c(e)},close(){u()},abort(e){l(e)}});return{id:t,signal:i.signal,get closed(){return o},get lastSeq(){return s},write:c,error:l,close:u,abort:d,writable:f,events:r,buffer:a}}function NS(e={}){let t=e.id??jb(),n=Math.max(1,e.highWaterMark??AS),r=[],i=0,a=!1,o=!1,s,c,l,u;function d(){if(c){if(r.length>0){let e=r.shift(),t=c;c=void 0,t.resolve({value:e,done:!1});return}if(a){let e=c;if(c=void 0,s){let t=Error(s.message);t.name=s.name,e.reject(t)}else e.resolve({value:void 0,done:!0})}}}function f(){if(l){for(;r.length>0;){let e=r.shift();try{l.enqueue(e)}catch{break}}if(a&&l){try{if(s){let e=Error(s.message);e.name=s.name,l.error(e)}else l.close()}catch{}l=void 0}}}function p(t,s){if(!(a||o)&&!(t<=i)){if(i=t,r.push(s),r.length>n){let t=r.length-n;r.splice(0,t),e.onOverflow?.(t)}d(),u&&f()}}function m(e){a||(a=!0,s=e,d(),u&&f())}function h(){o||a||(o=!0,e.onCancel?.(),m(void 0))}function g(){return u||(u=new ReadableStream({start(e){l=e,f()},cancel(){h()}}),u)}return{id:t,get cancelled(){return o},get done(){return a},get lastSeenSeq(){return i},get readable(){return g()},cancel:h,_push:p,_end:m,[Symbol.asyncIterator](){return{next(){if(r.length>0)return Promise.resolve({value:r.shift(),done:!1});if(a){if(s){let e=Error(s.message);return e.name=s.name,Promise.reject(e)}return Promise.resolve({value:void 0,done:!0})}return new Promise((e,t)=>{c={resolve:e,reject:t}})},return(){return h(),Promise.resolve({value:void 0,done:!0})}}}}}function PS(e){if(e instanceof Error)return{name:e.name||`Error`,message:e.message};if(typeof e==`string`)return{name:`Error`,message:e};try{return{name:`Error`,message:JSON.stringify(e)}}catch{return{name:`Error`,message:String(e)}}}var FS=128;function IS(e){return e.replace(/[^\w-]+/g,`_`).slice(0,FS)}var LS=`modulepreload`,RS=function(e,t){return new URL(e,t).href},zS={},BS=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=RS(t,n),t=s(t),t in zS)return;zS[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:LS,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},VS=`__connection.json`,HS=`__DEVFRAME_CONNECTION__`,US=`x-birpc-session`,WS=`__rpc-dump/index.json`,GS=`devframe:services`,KS=`devframe_otp`,qS=`devframe_auth_token`;Uy.postMessage.remoteAssetsError;var JS=class{cacheMap=new Map;options;keySerializer;constructor(e){this.options=e,this.keySerializer=e.keySerializer||(e=>Sb(e))}updateOptions(e){this.options={...this.options,...e}}cached(e,t){let n=this.cacheMap.get(e);if(n)return n.get(this.keySerializer(t))}has(e,t){return this.cacheMap.get(e)?.has(this.keySerializer(t))??!1}apply(e,t){let n=this.cacheMap.get(e.m)||new Map;n.set(this.keySerializer(e.a),t),this.cacheMap.set(e.m,n)}validate(e){return this.options.functions.includes(e)}clear(e){e?this.cacheMap.delete(e):this.cacheMap.clear()}},YS=Ky({docsBase:`https://devfra.me/errors`,codes:{DF0019:{why:e=>`RPC function "${e.name}" has \`agent\` set but \`jsonSerializable\` is \`false\`; MCP requires JSON-serializable data.`,fix:"Remove `jsonSerializable: false`, or remove `agent` to keep it RPC-only."},DF0020:{why:e=>`RPC function "${e.name}" declares \`jsonSerializable: true\` but the value at "${e.path}" is a ${e.type}.`,fix:"Either drop `jsonSerializable: true` (falls back to structured-clone) or change the value to a JSON-safe shape."},DF0021:{why:e=>`RPC function "${e.name}" is already registered`,fix:"Use the `force` parameter to overwrite an existing registration."},DF0022:{why:e=>`RPC function "${e.name}" is not registered. Use register() to add new functions.`},DF0023:{why:e=>`RPC function "${e.name}" is not registered`},DF0024:{why:e=>`Either handler or setup function must be provided for RPC function "${e.name}"`},DF0025:{why:e=>`Function "${e.name}" not found in dump store`},DF0026:{why:e=>`No dump match for "${e.name}" with args: ${e.args}`},DF0027:{why:e=>`Function "${e.name}" with type "${e.type}" cannot have dump configuration. Only "static" and "query" types support dumps.`},DF0028:{why:e=>`Function "${e.name}" with type "${e.type}" cannot use \`snapshot: true\`. Only "query" functions support this sugar; "static" functions have equivalent default behavior already.`,fix:"Remove `snapshot: true`, or change the function type to `query`."},DF0043:{why:e=>`RPC function "${e.name}" received an invalid argument at position ${e.index}: ${e.issues}`,fix:"Pass a value that satisfies the `args` schema declared for this function."},DF0044:{why:e=>`RPC function "${e.name}" returned a value that failed its \`returns\` schema: ${e.issues}`,fix:"Make the handler return a value that satisfies the `returns` schema, or relax the schema."}}});function XS(e){if(e.agent&&e.jsonSerializable===!1)throw YS.DF0019({name:e.name});e.agent&&!e.jsonSerializable&&(e.jsonSerializable=!0)}async function ZS(e,t){let n=e[`~standard`].validate(t);return n instanceof Promise?await n:n}function QS(e){return e.map(e=>{let t=e.path?.map(e=>typeof e==`object`?e.key:e).join(`.`);return t?`${t}: ${e.message}`:e.message}).join(`; `)}async function $S(e,t,n){let r=n.slice();if(!t||t.length===0)return r;for(let r=0;r{n.get(t)===r&&n.delete(t)}),n.set(t,r)),await r}if(!e.__promise){let n=Promise.resolve(e.setup(t));n.catch(()=>{e.__promise===n&&(e.__promise=void 0)}),e.__promise=n}return await e.__promise}async function nC(e,t){let n=e.handler;if(!n){let r=await tC(e,t);if(!r.handler)throw YS.DF0024({name:e.name});n=r.handler}let r=e.args,i=e.returns;if(!r&&!i)return n;let a=n;return async(...t)=>{let n=await $S(e.name,r,t),o=await a(...n);return await eC(e.name,i,o)}}var rC=class{context;definitions=new Map;functions;_onChanged=[];constructor(e){this.context=e;let t=this.definitions,n=this;this.functions=new Proxy({},{get(e,r){let i=t.get(r);if(i)return nC(i,n.context)},has(e,n){return t.has(n)},getOwnPropertyDescriptor(e,n){return{value:t.get(n)?.handler,configurable:!0,enumerable:!0}},ownKeys(){return Array.from(t.keys())}})}register(e,t=!1){if(this.definitions.has(e.name)&&!t)throw YS.DF0021({name:e.name});XS(e),this.definitions.set(e.name,e),this._onChanged.forEach(t=>t(e.name))}update(e,t=!1){if(!this.definitions.has(e.name)&&!t)throw YS.DF0022({name:e.name});XS(e),this.definitions.set(e.name,e),this._onChanged.forEach(t=>t(e.name))}onChanged(e){return this._onChanged.push(e),()=>{let t=this._onChanged.indexOf(e);t!==-1&&this._onChanged.splice(t,1)}}async getHandler(e){return await nC(this.definitions.get(e),this.context)}getSchema(e){let t=this.definitions.get(e);if(!t)throw YS.DF0023({name:String(e)});return{args:t.args,returns:t.returns}}has(e){return this.definitions.has(e)}get(e){return this.definitions.get(e)}list(){return Array.from(this.definitions.keys())}};function iC(e,t=``){return JSON.stringify(e,function(e,n){let r=this,i=r==null?n:r[e];if(i===void 0){if(Array.isArray(r))throw oC(t,`undefined`,r,e);return n}return i!==null&&aC(i,r,e,t),n})}function aC(e,t,n,r){if(typeof e==`bigint`)throw oC(r,`BigInt`,t,n);if(typeof e!=`object`)return;if(e instanceof Map)throw oC(r,`Map`,t,n);if(e instanceof Set)throw oC(r,`Set`,t,n);if(e instanceof Date)throw oC(r,`Date`,t,n);if(Array.isArray(e))return;let i=Object.getPrototypeOf(e);if(i!==null&&i!==Object.prototype)throw oC(r,e.constructor?.name??`class instance`,t,n)}function oC(e,t,n,r){let i=sC(n,r);return YS.DF0020({name:e||``,type:t,path:i})}function sC(e,t){return Array.isArray(e)?`[${t}]`:t===``?``:t}var cC=`__DEVFRAME_CONNECTION_META__`,lC=`__DEVFRAME_CONNECTION_AUTH_TOKEN__`;function uC(e){let t=[()=>window?.[e],()=>globalThis?.[e],()=>parent.window?.[e]];for(let e of t)try{let t=e();if(t)return t}catch{}}function dC(){return uC(HS)}function fC(){return uC(cC)}function pC(e){if(e)return e;try{let e=localStorage.getItem(lC);if(e)return e}catch{}return uC(lC)}function mC(e){globalThis[HS]=e,globalThis[cC]={...e.connectionMeta,baseUrl:e.metaBaseUrl},e.authToken&&hC(e.authToken)}function hC(e){try{localStorage.setItem(lC,e)}catch{}globalThis[lC]=e;let t=dC();t&&(globalThis[HS]={...t,authToken:e})}function gC(e){let t=Ob(VS,e);try{return new URL(t,globalThis.location?.href).href}catch{return t}}function _C(e,t){return t&&t!==e.authToken?{...e,authToken:t}:e}function vC(){let e=dC();if(e)return _C(e,pC()??e.authToken??e.connectionMeta.authToken);let t=fC();if(t)return{connectionMeta:t,metaBaseUrl:t.baseUrl??gC(`./`),authToken:pC(t.authToken)}}async function yC(e={}){if(e.connection){let t=_C(e.connection,pC(e.authToken??e.connection.authToken??e.connection.connectionMeta.authToken));return mC(t),t}let t=Array.isArray(e.baseURL)?e.baseURL:[e.baseURL??`./`];if(e.connectionMeta){let n={connectionMeta:e.connectionMeta,metaBaseUrl:gC(t[0]??`./`),authToken:pC(e.authToken??e.connectionMeta.authToken)};return mC(n),n}let n=vC();if(n){let t=_C(n,pC(e.authToken??n.authToken??n.connectionMeta.authToken));return mC(t),t}let r=[];for(let n of t){let t=Ob(VS,n),i=gC(n);try{let n=await fetch(t);if(!n.ok)throw Error(`Failed to fetch connection meta from ${i}: ${n.status}`);let r=await n.json(),a=n.url||i,o={connectionMeta:r,metaBaseUrl:r.baseUrl?new URL(r.baseUrl,a).href:a,authToken:pC(e.authToken??r.authToken)};return mC(o),o}catch(e){r.push(e)}}throw Error(`Failed to get connection meta from ${t.join(`, `)}`,{cause:r})}var bC=class extends Error{name=`DevframeConnectionError`;kind;constructor(e,t,n){super(t,n),this.kind=e}};function xC(e=KS){try{let t=globalThis.location?.hash?.replace(/^#/,``)??``;return new URLSearchParams(t).get(e)||void 0}catch{return}}function SC(e){try{let t=new URL(globalThis.location.href),n=new URLSearchParams(t.hash.replace(/^#/,``));if(!n.has(e))return;n.delete(e),t.hash=n.toString(),globalThis.history?.replaceState(globalThis.history.state,``,t.href)}catch{}}function CC(e=KS){let t=xC(e);return t&&SC(e),t}async function wC(e,t={}){let n=CC(t.param??`devframe_otp`);return n?e.isTrusted?!0:e.requestTrustWithCode(n):!1}function TC(e){let t={},n=new WeakMap,r,i=()=>(r??=e.sharedState.get(GS,{initialValue:{}}).then(e=>(t=e.value(),e.on(`updated`,e=>{t=e}),e)),r);return i(),{state:i,has:e=>e in t,keys:()=>Object.keys(t),get:r=>{let i=t[r];if(!i)return;let a=n.get(i);return a||(a={...i,rpc:e.scope(i.scope).rpc},n.set(i,a)),a}}}function EC(e){let t=new Map,n=new Map,r=new Map,i=new Set,a=e.connectionMeta.backend===`static`;function o(e,t){let n=r.get(e);return n&&typeof n==`object`&&!Array.isArray(n)&&typeof t==`object`&&!Array.isArray(t)?{...n,...t}:t}e.client.register({name:Uy.broadcast.clientStateUpdated,type:`event`,handler:(e,n,r)=>{let i=t.get(e);i&&!i.syncIds.has(r)&&i.mutate(()=>o(e,n),r)}}),e.client.register({name:Uy.broadcast.clientStatePatch,type:`event`,handler:(e,n,r)=>{let i=t.get(e);i&&!i.syncIds.has(r)&&i.patch(n,r)}});function s(t,n){let r=[];return r.push(n.on(`updated`,(n,r,i)=>{a||(r?e.callEvent(`devframe:rpc:server-state:patch`,t,r,i):e.callEvent(`devframe:rpc:server-state:set`,t,n,i))})),()=>{for(let e of r)e()}}return{keys:()=>Array.from(t.keys()),onKeyAdded(e){return i.add(e),()=>{i.delete(e)}},delete(e){let i=n.get(e);n.delete(e);let a=t.delete(e);return r.delete(e),i?.(),a},get:async(c,l)=>{if(l?.initialValue!==void 0&&r.set(c,l.initialValue),t.has(c))return t.get(c);let u=lS({initialValue:l?.initialValue,enablePatches:!1});async function d(){if(a||e.callEvent(`devframe:rpc:server-state:subscribe`,c),l?.initialValue!==void 0){t.set(c,u);for(let e of i)e(c);return e.call(`devframe:rpc:server-state:get`,c).then(e=>{e!==void 0&&u.mutate(()=>o(c,e))}).catch(e=>{console.error(`Error getting server state`,e)}),n.set(c,s(c,u)),u}{let r=await e.call(`devframe:rpc:server-state:get`,c);u.mutate(()=>o(c,r)),t.set(c,u);for(let e of i)e(c);return n.set(c,s(c,u)),u}}return new Promise(t=>{if(e.isTrusted)d().then(t);else{t(u);let n=!1;e.events.on(Uy.client.isTrustedUpdated,e=>{e&&!n&&(n=!0,d())})}})}}}var DC=new Map;function OC(e=DC){let t=new Map;return{serialize:n=>{let r;return n.t===`q`?r=n.m:(r=t.get(n.i),t.delete(n.i)),!(n.t===`s`&&`e`in n)&&r&&e.get(r)?.jsonSerializable===!0?iC(n,r??``):`s:${OS(n)}`},deserialize:e=>{let n=e.startsWith(`s:`)?kS(e.slice(2)):JSON.parse(e);return n.t===`q`&&n.i&&n.m&&t.set(n.i,n.m),n}}}function kC(){}function AC(e){let t=e.search(/\n\n|\r\n\r\n/);if(!(t<0))return{frame:e.slice(0,t),rest:e.slice(t+(e[t]===`\r`?4:2))}}function jC(e){let t=`message`,n=[];for(let r of e.split(/\r?\n/))r.startsWith(`:`)||(r.startsWith(`event:`)?t=r.slice(6).trimStart():r.startsWith(`data:`)&&n.push(r.slice(5).replace(/^ /,``)));return{event:t,data:n}}function MC(e){let{onConnected:t=kC,onError:n=kC,onDisconnected:r=kC,definitions:i,fetch:a=globalThis.fetch.bind(globalThis)}=e,o=e.url;e.authToken&&(o=`${o}${o.includes(`?`)?`&`:`?`}${qS}=${encodeURIComponent(e.authToken)}`);let s=OC(i),c=new AbortController,l=!1,u,d,f,p,m=new Promise((e,t)=>{f=e,p=t});m.catch(()=>{});function h(e){l||(l=!0,p(e),n(e),r())}function g(){l||(l=!0,p(Error(`Devframe SSE stream closed`)),r())}function _(e,n){if(e===`session`){f(n),t();return}u?.(n)}async function v(e){let t=e.getReader();d=t;let n=new TextDecoder,r=``;for(;;){let{done:e,value:i}=await t.read();if(e)break;for(r+=n.decode(i,{stream:!0});;){let e=AC(r);if(!e)break;r=e.rest;let{event:t,data:n}=jC(e.frame);n.length>0&&_(t,n.join(` -`))}}g()}return(async()=>{try{let e=await a(o,{headers:{accept:`text/event-stream`},signal:c.signal});if(!e.ok||!e.body)throw Error(`Devframe SSE stream request failed: ${e.status}`);await v(e.body)}catch(e){if(c.signal.aborted){g();return}h(e instanceof Error?e:Error(String(e)))}})(),{close:()=>{l=!0,c.abort(),d?.cancel().catch(()=>{})},on:e=>{u=e},post:async e=>{let t;try{t=await m}catch{return}if(l){n(Error(`Devframe SSE channel is closed; message dropped`));return}try{let n=await a(o,{method:`POST`,headers:{"content-type":`text/plain; charset=utf-8`,[US]:t},body:e});if(n.status===200){let e=await n.text();e&&u?.(e);return}if(!n.ok)throw Error(`Devframe SSE POST failed: ${n.status}`)}catch(e){n(e instanceof Error?e:Error(String(e)))}},serialize:s.serialize,deserialize:s.deserialize}}function NC(e,t){let{channel:n,rpcOptions:r={}}=t;return nb(e,{...n,timeout:-1,...r,proxify:!1})}function PC(e){let{transport:t,authToken:n,connectionMeta:r,events:i,clientRpc:a,rpcOptions:o={},callTimeout:s=0}=e,c=!1,l=`connecting`,u=null,d=Promise.withResolvers();function f(e,t=null){if(t?u=t:e===`connected`&&(u=null),e===l)return;let n=l;l=e,i.emit(Uy.client.connectionStatus,e,n)}let p=new Set;function m(e){for(let t of[...p])t.reject(e)}function h(){return l===`disconnected`||l===`error`?new bC(`connection`,`[devframe] Not connected to the devframe server`,{cause:u??void 0}):l===`unauthorized`?new bC(`auth`,`[devframe] Not authorized by the devframe server`,{cause:u??void 0}):null}function g(e,t){return new Promise((n,r)=>{let a=!1,o,c={reject(e){a||(l(),i.emit(Uy.client.error,e,t),r(e))}};function l(){a=!0,p.delete(c),o&&clearTimeout(o)}p.add(c),s>0&&(o=setTimeout(()=>{c.reject(new bC(`timeout`,`[devframe] RPC call "${t}" timed out after ${s}ms`))},s)),e.then(e=>{a||(l(),n(e))},e=>{if(a)return;l();let n=e instanceof Error?e:Error(String(e));i.emit(Uy.client.error,n,t),r(n)})})}let _=new Map;for(let e of r.jsonSerializableMethods??[])_.set(e,{jsonSerializable:!0});let v=e.createChannel({definitions:_,onError(e){f(`error`,e),i.emit(Uy.client.connectionError,e),m(new bC(`connection`,`[devframe] Connection to the devframe server failed`,{cause:e}))},onDisconnected(){l!==`error`&&f(`disconnected`),m(new bC(`connection`,`[devframe] Disconnected from the devframe server`,{cause:u??void 0}))}}),y=NC(a.functions,{channel:v,rpcOptions:o});a.register({name:Uy.broadcast.authRevoked,type:`event`,handler:()=>{c=!1;let e=new bC(`auth`,`[devframe] The devframe server revoked this client's trust`);f(`unauthorized`,e),i.emit(Uy.client.connectionError,e),m(e),i.emit(Uy.client.isTrustedUpdated,!1)}});let b=n;async function ee(e){b=e;let t=await y.$call(`anonymous:devframe:auth`,{authToken:e,ua:navigator.userAgent,origin:location.origin});if(c=t.isTrusted,c)d.resolve(!0),f(`connected`);else{let e=new bC(`auth`,`[devframe] The devframe server refused this client's credentials`);f(`unauthorized`,e),i.emit(Uy.client.connectionError,e)}return i.emit(Uy.client.isTrustedUpdated,c),t.isTrusted}async function te(e){let t=(await y.$call(`anonymous:devframe:auth:exchange`,{code:e,ua:navigator.userAgent,origin:location.origin}))?.authToken??null;return t&&(b=t,c=!0,d.resolve(!0),f(`connected`),i.emit(Uy.client.isTrustedUpdated,!0)),t}async function ne(e={}){await y.$call(`anonymous:devframe:auth:request-code`,{ua:navigator.userAgent,origin:location.origin,...e.reissue?{reissue:!0}:{}})}async function x(){return c?!0:ee(b??``)}async function S(e=6e4){if(c&&d.resolve(!0),e<=0)return d.promise;let t;try{return await Promise.race([d.promise,new Promise((n,r)=>{t=setTimeout(()=>{r(Error(`[devframe] Timeout waiting for rpc to be trusted`))},e)})]),c}finally{clearTimeout(t)}}return{transport:t,get isTrusted(){return c},get status(){return l},get connectionError(){return u},requestTrust:x,requestTrustWithToken:ee,requestTrustWithCode:te,requestAuthCode:ne,ensureTrusted:S,call:(...e)=>{let t=String(e[0]),n=h();return n?(i.emit(Uy.client.error,n,t),Promise.reject(n)):g(y.$call(...e),t)},callEvent:(...e)=>{let t=h();if(t){i.emit(Uy.client.error,t,String(e[0]));return}return y.$callEvent(...e)},callOptional:(...e)=>{let t=String(e[0]),n=h();return n?(i.emit(Uy.client.error,n,t),Promise.reject(n)):g(y.$callOptional(...e),t)},close:()=>{v.close()}}}function FC(e,t,n){let r=(()=>{try{return new URL(t,n.href)}catch{return new URL(n.href)}})();if(e&&typeof e==`object`){if(e.host!=null||e.port!=null){let t=e.host??`${r.hostname}:${e.port}`;return new URL(e.path??`/`,`${r.protocol}//${t}`).href}return new URL(e.path??``,r).href}let i=e??``;return/^https?:\/\//i.test(i)?i:new URL(i,r).href}function IC(e){let{authToken:t,connectionMeta:n,metaBaseUrl:r,events:i,clientRpc:a,rpcOptions:o={},sseOptions:s={},callTimeout:c=0}=e,l=FC(n.sse,r??`./`,location);return PC({transport:`sse`,authToken:t,connectionMeta:n,events:i,clientRpc:a,rpcOptions:o,callTimeout:c,createChannel:e=>MC({url:l,authToken:t,definitions:e.definitions,...s,onConnected(){s.onConnected?.()},onError(t){e.onError(t),s.onError?.(t)},onDisconnected(){e.onDisconnected(),s.onDisconnected?.()}})})}function LC(e){let{name:t,message:n,cause:r,...i}=e,a=r instanceof Error?r:RC(r)?LC(r):r,o=a===void 0?Error(n):Error(n,{cause:a});return o.name=t,Object.assign(o,i),o}function RC(e){return typeof e==`object`&&!!e&&typeof e.message==`string`&&typeof e.name==`string`}function zC(e){return typeof e==`object`&&!!e&&e.type===`static`&&typeof e.path==`string`}function BC(e){return typeof e==`object`&&!!e&&e.type===`query`&&typeof e.records==`object`&&e.records!==null}function VC(e){return typeof e==`object`&&!!e&&(`output`in e||`error`in e)}function HC(e){if(e.error)throw LC(e.error);return e.output}function UC(e){return e.some(e=>e!=null)}function WC(e){return typeof e==`object`&&e&&`serialization`in e&&`data`in e?e.data:e}function GC(e,t){let n=new Map,r=new Map;function i(e,t){return t===`structured-clone`&&Array.isArray(e)?DS(e):e}function a(e,t){return i(WC(e),t)}async function o(e){n.has(e.path)||n.set(e.path,t(e.path).then(t=>a(t,e.serialization)));let r=await n.get(e.path);return VC(r)?HC(r):r}async function s(e,n){return r.has(e)||r.set(e,t(e).then(e=>a(e,n))),await r.get(e)}async function c(t,n){if(!(t in e))throw Error(`[devframe-rpc] Function "${t}" not found in dump store`);let r=e[t];if(zC(r)){if(UC(n))throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`);return await o(r)}if(BC(r)){let e=Sb(n),i=r.records[e];if(i)return HC(await s(i,r.serialization));if(r.fallback)return HC(await s(r.fallback,r.serialization));throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`)}if(!UC(n))return r;throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`)}return{call:async(e,t)=>await c(e,t),callOptional:async(t,n)=>{if(t in e)return await c(t,n)},callEvent:async(e,t)=>{}}}async function KC(e){let t=GC(await e.fetchJsonFromBases(WS),e.fetchJsonFromBases);return{transport:`static`,isTrusted:!0,status:`connected`,connectionError:null,requestTrust:async()=>!0,requestTrustWithToken:async()=>!0,requestTrustWithCode:async()=>null,requestAuthCode:async()=>{},ensureTrusted:async()=>!0,call:(...e)=>t.call(e[0],e.slice(1)),callEvent:(...e)=>t.callEvent(e[0],e.slice(1)),callOptional:(...e)=>t.callOptional(e[0],e.slice(1)),close:()=>{}}}var qC=``;function JC(e,t){return`${e}${qC}${t}`}function YC(e){let t=new Map,n=new Map;e.client.register({name:Uy.broadcast.streamingChunk,type:`event`,handler(e,n,r,i){t.get(JC(e,n))?._push(r,i)}}),e.client.register({name:Uy.broadcast.streamingEnd,type:`event`,handler(e,n,r){let i=JC(e,n),a=t.get(i);a&&(a._end(r),t.delete(i))}}),e.client.register({name:Uy.broadcast.streamingUploadCancel,type:`event`,handler(e,t){let r=JC(e,t),i=n.get(r);i&&(i.abort(`server cancelled upload`),n.delete(r))}}),e.events.on(Uy.client.isTrustedUpdated,n=>{if(n)for(let[n,r]of t){if(r.cancelled||r.done)continue;let t=n.indexOf(qC);if(t<0)continue;let i=n.slice(0,t),a=n.slice(t+1);e.callEvent(`devframe:streaming:subscribe`,i,a,{afterSeq:r.lastSeenSeq})}});function r(n,r,i={}){let a=JC(n,r),o=t.get(a);if(o)return o;let s=NS({id:r,highWaterMark:i.highWaterMark,onOverflow(e){console.warn(`[devframe] DF0029: Stream "${n}#${r}" dropped ${e} chunk(s) after exceeding the client high-water mark.`)},onCancel(){e.callEvent(`devframe:streaming:cancel`,n,r),t.delete(a)}});if(t.set(a,s),e.isTrusted)e.callEvent(`devframe:streaming:subscribe`,n,r,{afterSeq:0});else{let i=e.events.on(Uy.client.isTrustedUpdated,o=>{o&&(i(),t.has(a)&&!s.cancelled&&!s.done&&e.callEvent(`devframe:streaming:subscribe`,n,r,{afterSeq:s.lastSeenSeq}))})}return s}function i(t,r){let i=JC(t,r),a=n.get(i);if(a)return a;let o=MS({id:r});return o.events.on(`chunk`,(n,i)=>{e.callEvent(`devframe:streaming:upload-chunk`,t,r,n,i)}),o.events.on(`end`,a=>{e.callEvent(`devframe:streaming:upload-end`,t,r,a),n.delete(i)}),n.set(i,o),o}return{subscribe:r,upload:i}}function XC(){}var ZC=new Map;function QC(e){let t=e.url;e.authToken&&(t=`${t}?${qS}=${encodeURIComponent(e.authToken)}`);let n=new WebSocket(t),{onConnected:r=XC,onError:i=XC,onDisconnected:a=XC,definitions:o=ZC}=e;n.addEventListener(`open`,e=>{r(e)}),n.addEventListener(`error`,e=>{let t=e instanceof Error?e:Error(e.type);i(t)}),n.addEventListener(`close`,e=>{a(e)});let s=OC(o);return{close:()=>{n.close()},on:e=>{n.addEventListener(`message`,t=>{e(t.data)})},post:e=>{if(n.readyState===WebSocket.OPEN){n.send(e);return}if(n.readyState===WebSocket.CONNECTING){let t=()=>{i(),n.readyState===WebSocket.OPEN&&n.send(e)},r=()=>i();function i(){n.removeEventListener(`open`,t),n.removeEventListener(`close`,r)}n.addEventListener(`open`,t),n.addEventListener(`close`,r);return}i(Error(`Devframe WebSocket is not open; message dropped`))},serialize:s.serialize,deserialize:s.deserialize}}function $C(e,t,n){let r=(()=>{try{return new URL(t,n.href)}catch{return new URL(n.href)}})(),i=r.protocol===`https:`?`wss:`:`ws:`;if(e&&typeof e==`object`){if(e.host!=null||e.port!=null){let t=e.host??`${r.hostname}:${e.port}`,n=new URL(e.path??`/`,`${i}//${t}`);return n.protocol=i,n.href}let t=new URL(e.path??``,r);return t.protocol=i,t.href}if(typeof e==`number`)return`${i}//${r.hostname}:${e}`;let a=e??``;if(/^wss?:\/\//i.test(a))return a;if(/^https?:\/\//i.test(a))return kb(a,/^https/i.test(a)?`wss://`:`ws://`);let o=new URL(a,r);return o.protocol=i,o.href}function ew(e){let{authToken:t,connectionMeta:n,metaBaseUrl:r,events:i,clientRpc:a,rpcOptions:o={},wsOptions:s={},callTimeout:c=0}=e,l=$C(n.websocket,r??`./`,location);return PC({transport:`websocket`,authToken:t,connectionMeta:n,events:i,clientRpc:a,rpcOptions:o,callTimeout:c,createChannel:e=>QC({url:l,authToken:t,definitions:e.definitions,...s,onConnected(e){s.onConnected?.(e)},onError(t){e.onError(t),s.onError?.(t)},onDisconnected(t){e.onDisconnected(),s.onDisconnected?.(t)}})})}function tw(e){return e.includes(`:`)}function nw(e,t){return tw(t)?t:`${e}:${t}`}function rw(e){return{async get(t){return(await e()).value()[t]},async set(t,n){(await e()).mutate(e=>{e[t]=n})},async delete(t){(await e()).mutate(e=>{delete e[t]})},async all(){return(await e()).value()},async onChange(t){return(await e()).on(`updated`,e=>t(e))}}}function iw(e,t,n){let r=`devframe:settings:${n}:${t}`,i;function a(){return i||=e.sharedState.get(r,{initialValue:{}}),i}return rw(a)}function aw(e,t){return{global:iw(e,t,`global`),project:iw(e,t,`project`)}}function ow(e,t){return{namespace:t,base:e,rpc:{namespace:t,register(n){if(tw(n.name))throw Error(`[devframe] Scoped client RPC registration for namespace "${t}" received an already-namespaced function name "${n.name}". Pass a bare name without a ":" separator.`);e.client.register({...n,name:`${t}:${n.name}`})},call:((n,...r)=>e.call(nw(t,n),...r)),callEvent:((n,...r)=>e.callEvent(nw(t,n),...r)),callOptional:((n,...r)=>e.callOptional(nw(t,n),...r)),sharedState:((n,r)=>e.sharedState.get(nw(t,n),r)),streaming:{subscribe:(n,r,i)=>e.streaming.subscribe(nw(t,n),r,i),upload:(n,r)=>e.streaming.upload(nw(t,n),r)}},settings:aw(e,t),scope:e.scope}}function sw(){if(typeof document<`u`){let e=document.modelContext;if(e)return e}if(typeof navigator<`u`){let e=navigator.modelContext;if(e)return e}}function cw(e,t={}){let n=t.modelContext??sw();if(!n)return()=>{};let r=n,i=new Map,a=new Map;function o(t,n){let o=IS(t.name),s=a.get(o);if(s&&s!==t.name){console.warn(`[devframe] WebMCP tool name "${o}" (from "${t.name}") collides with "${s}"; keeping the first registration.`);return}let c=new AbortController,l=rb(t.type,n),u=r.registerTool({name:o,description:n.description,inputSchema:ob(t.args),annotations:{title:n.title??t.name,readOnlyHint:l===`read`,destructiveHint:l===`destructive`},execute:n=>lw(t,e.context,n)},{signal:c.signal});u&&`then`in u&&u.then(()=>{},()=>{}),a.set(o,t.name),i.set(t.name,()=>{c.abort(),u&&`unregister`in u&&typeof u.unregister==`function`&&u.unregister(),a.delete(o)})}function s(t){let n=t?[t]:[...e.definitions.keys()];for(let t of n){i.get(t)?.(),i.delete(t);let n=e.definitions.get(t),r=n?.agent;n&&r&&o(n,r)}}s();let c=e.onChanged(e=>s(e));return()=>{c();for(let e of i.values())e();i.clear()}}async function lw(e,t,n){try{let r=cb(n,e.args?.length);return{content:[{type:`text`,text:uw(await(await nC(e,t))(...r))}]}}catch(e){return{isError:!0,content:[{type:`text`,text:dw(e)}]}}}function uw(e){return e===void 0?`undefined`:typeof e==`string`?e:JSON.stringify(e,null,2)}function dw(e){if(!(e instanceof Error))return String(e);let t=e.cause instanceof Error?` (cause: ${e.cause.message})`:``;return`${e.name}: ${e.message}${t}`}function fw(e,t){if(t.backend===`static`)return`static`;let n=t.websocket!==void 0,r=t.sse!==void 0;if(e===`websocket`){if(!n)throw Error(`[devframe] transport: 'websocket' was requested, but this server does not advertise a WebSocket endpoint`);return`websocket`}if(e===`sse`){if(!r)throw Error(`[devframe] transport: 'sse' was requested, but this server does not advertise an SSE endpoint`);return`sse`}if(t.backend===`sse`&&r)return`sse`;if(n)return`websocket`;if(r)return`sse`;throw Error(`[devframe] This server advertises no RPC transport (backend "none"), so there is nothing to connect to. Enable the WebSocket or SSE endpoint on the server, or use its static/MCP surfaces instead.`)}async function pw(e={}){let{baseURL:t=`./`,rpcOptions:n={},cacheOptions:r=!1}=e,i=Cb(),a=Array.isArray(t)?t:[t],o=await yC(e),{connectionMeta:s,metaBaseUrl:c,authToken:l}=o,u=a[0]??`./`;try{u=new URL(`.`,c).href}catch{}let d=new JS({functions:[],...typeof e.cacheOptions==`object`?e.cacheOptions:{}}),f={rpc:void 0},p=new rC(f),m=e.webmcp===!1?void 0:cw(p),h,g=!1;async function _(e){let t=[u,...a.filter(e=>e!==u)].filter(e=>e!=null),n=[];for(let r of t)try{return await fetch(Ob(e,r)).then(t=>{if(!t.ok)throw Error(`Failed to fetch ${e} from ${r}: ${t.status}`);return t.json()})}catch(e){n.push(e)}throw Error(`Failed to load ${e} from ${t.join(`, `)}`,{cause:n})}let v={authToken:l,connectionMeta:s,metaBaseUrl:c,events:i,clientRpc:p,callTimeout:e.callTimeout,rpcOptions:{...n,async onRequest(e,t,i){if(await n.onRequest?.call(this,e,t,i),r&&d?.validate(e.m)){if(d.has(e.m,e.a))return i(d.cached(e.m,e.a));let n=await t(e);d.apply(e,n)}else await t(e)}}},y=fw(e.transport??`auto`,s),b=y===`static`?await KC({fetchJsonFromBases:_}):y===`sse`?IC({...v,sseOptions:e.sseOptions}):ew({...v,wsOptions:e.wsOptions}),ee;try{ee=new BroadcastChannel(`devframe-auth`)}catch{}let te,ne=!1;function x(e){return((...t)=>ne||!te?e(...t):te.then(()=>e(...t)))}function S(){g=!0;try{h?.(),m?.()}finally{try{ee?.close()}finally{b.close?.()}}}let C={events:i,get isTrusted(){return b.isTrusted},get status(){return b.status},get connectionError(){return b.connectionError},get transport(){return b.transport??y},get connection(){return o},connectionMeta:s,ensureTrusted:b.ensureTrusted,requestTrust:b.requestTrust,requestTrustWithToken:async e=>(hC(e),o={...o,authToken:e},b.requestTrustWithToken(e)),requestTrustWithCode:async e=>{let t=await b.requestTrustWithCode(e);if(!t)return!1;hC(t),o={...o,authToken:t};try{ee?.postMessage({type:`auth-update`,authToken:t})}catch{}return!0},requestAuthCode:e=>b.requestAuthCode(e),call:x(b.call),callEvent:x(b.callEvent),callOptional:x(b.callOptional),client:p,sharedState:void 0,services:void 0,streaming:void 0,cacheManager:d,scope:void 0,close:S};C.sharedState=EC(C),C.streaming=YC(C),C.services=TC(C);let re=new Map;C.scope=(e=>{if(!e)return C;let t=re.get(e);return t||(t=ow(C,e),re.set(e,t)),t}),f.rpc=C;function w(){try{return typeof window<`u`&&window.self===window.top}catch{return!1}}async function ie(){if(e.simpleAuth!==!1&&w()&&typeof globalThis.prompt==`function`)for(await C.requestAuthCode().catch(()=>{});!C.isTrusted;){let e=globalThis.prompt(`devframe: enter the authentication code shown in your terminal`);if(e==null)return;let t=e.trim();if(t&&await C.requestTrustWithCode(t))return}}async function T(){let t=await b.requestTrust(),n=e.otpParam??`devframe_otp`,r=n?await wC(C,{param:n}):!1;t||r||C.isTrusted||await ie()}return te=T().then(()=>{ne=!0},()=>{ne=!0}),s.mcp&&BS(async()=>{let{setupBrowserAgentRpcBridge:e}=await import(`./browser-agent-rpc-BXhoSh1z-BTrINugR.js`);return{setupBrowserAgentRpcBridge:e}},[],import.meta.url).then(({setupBrowserAgentRpcBridge:e})=>{g||(h=e(C))}).catch(()=>{}),ee&&(ee.onmessage=e=>{e.data?.type===`auth-update`&&e.data.authToken&&C.requestTrustWithToken(e.data.authToken)}),C}var mw=pw,hw=class e{rpc=k_(null);navigate=E_();meta=L(null);componentCount=L(0);routeCount=L(0);signalCount=L(0);providerCount=L(0);storeCount=L(0);constructor(){Zs(()=>{let e=this.rpc();if(!e)return;let t=e.scope(`ng-devtools`);t.rpc.call(`build-meta`).then(e=>this.meta.set(e)).catch(()=>{}),t.rpc.call(`get-components`).then(e=>this.componentCount.set(e.length)).catch(()=>{}),t.rpc.call(`get-routes`).then(e=>this.routeCount.set(e.length)).catch(()=>{}),t.rpc.call(`get-signals`).then(e=>this.signalCount.set(e.length)).catch(()=>{}),t.rpc.call(`get-providers`).then(e=>this.providerCount.set(e.length)).catch(()=>{}),t.rpc.call(`get-ngrx-store`).then(e=>this.storeCount.set(e.length)).catch(()=>{})})}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-dashboard`]],inputs:{rpc:[1,`rpc`]},outputs:{navigate:`navigate`},decls:56,vars:9,consts:[[1,`grid`],[1,`card`],[1,`card`,`clickable`,3,`click`],[1,`big`],[1,`sub`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`div`,1)(2,`h2`),Z(3,`Project`),J(),q(4,`dl`)(5,`dt`),Z(6,`Name`),J(),q(7,`dd`),Z(8),J(),q(9,`dt`),Z(10,`Angular`),J(),q(11,`dd`),Z(12),J(),q(13,`dt`),Z(14,`TypeScript`),J(),q(15,`dd`),Z(16),J(),q(17,`dt`),Z(18,`SSR`),J(),q(19,`dd`),Z(20),J()()(),q(21,`div`,2),Y(`click`,function(){return t.navigate.emit(`components`)}),q(22,`h2`),Z(23,`Components`),J(),q(24,`p`,3),Z(25),J(),q(26,`p`,4),Z(27,`discovered in source`),J()(),q(28,`div`,2),Y(`click`,function(){return t.navigate.emit(`routes`)}),q(29,`h2`),Z(30,`Routes`),J(),q(31,`p`,3),Z(32),J(),q(33,`p`,4),Z(34,`registered paths`),J()(),q(35,`div`,2),Y(`click`,function(){return t.navigate.emit(`signals`)}),q(36,`h2`),Z(37,`Signals`),J(),q(38,`p`,3),Z(39),J(),q(40,`p`,4),Z(41,`reactive primitives`),J()(),q(42,`div`,2),Y(`click`,function(){return t.navigate.emit(`injectors`)}),q(43,`h2`),Z(44,`Injectors`),J(),q(45,`p`,3),Z(46),J(),q(47,`p`,4),Z(48,`DI providers`),J()(),q(49,`div`,2),Y(`click`,function(){return t.navigate.emit(`store`)}),q(50,`h2`),Z(51,`NgRx Store`),J(),q(52,`p`,3),Z(53),J(),q(54,`p`,4),Z(55,`store entries`),J()()()),e&2&&(B(8),Q(t.meta()?.projectName??`…`),B(4),Q(t.meta()?.angularVersion??`…`),B(4),Q(t.meta()?.typescript??`…`),B(4),Q(t.meta()?.ssr?`Yes`:`No`),B(5),Q(t.componentCount()),B(7),Q(t.routeCount()),B(7),Q(t.signalCount()),B(7),Q(t.providerCount()),B(7),Q(t.storeCount()))},styles:[`.grid[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - gap: 16px; - } - .card[_ngcontent-%COMP%] { - background: #18181b; - border: 1px solid #27272a; - border-radius: 10px; - padding: 20px; - } - .card.clickable[_ngcontent-%COMP%] { - cursor: pointer; - transition: border-color 0.15s; - } - .card.clickable[_ngcontent-%COMP%]:hover { - border-color: var(--%NS%accent); - } - h2[_ngcontent-%COMP%] { - font-size: 13px; - text-transform: uppercase; - color: #71717a; - margin-bottom: 12px; - letter-spacing: 0.05em; - } - dl[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: auto 1fr; - gap: 6px 12px; - font-size: 14px; - } - dt[_ngcontent-%COMP%] { - color: #a1a1aa; - } - dd[_ngcontent-%COMP%] { - color: #e4e4e7; - font-weight: 500; - } - .big[_ngcontent-%COMP%] { - font-size: 36px; - font-weight: 700; - color: var(--%NS%accent); - } - .sub[_ngcontent-%COMP%] { - font-size: 13px; - color: #71717a; - margin-top: 4px; - }`]})},gw=()=>[],_w=(e,t)=>t.selector,vw=(e,t)=>t.outlet+t.route,yw=(e,t)=>t.token+t.line;function bw(e,t){e&1&&(q(0,`p`,3),Z(1,`Scanning components…`),J())}function xw(e,t){e&1&&(q(0,`p`,3),Z(1,`No components found.`),J())}function Sw(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=t.$implicit;B(),t_(`routed `,e.route,` · outlet `,e.outlet)}}function Cw(e,t){if(e&1&&(q(0,`li`,14),Z(1),J()),e&2){let e=t.$implicit;B(),Q(e)}}function ww(e,t){if(e&1&&(q(0,`h4`),Z(1,`Inputs`),J(),q(2,`ul`,13),U(3,Cw,2,1,`li`,14,kh),J()),e&2){let e=X(2).$implicit;B(3),W(e.inputs)}}function Tw(e,t){if(e&1&&(q(0,`li`,15),Z(1),J()),e&2){let e=t.$implicit;B(),Q(e)}}function Ew(e,t){if(e&1&&(q(0,`h4`),Z(1,`Outputs`),J(),q(2,`ul`,13),U(3,Tw,2,1,`li`,15,kh),J()),e&2){let e=X(2).$implicit;B(3),W(e.outputs)}}function Dw(e,t){if(e&1&&(q(0,`span`,20),Z(1),J()),e&2){let e=X().$implicit;B(),$(`→ `,e.source)}}function Ow(e,t){if(e&1&&(q(0,`li`,17)(1,`span`,18),Z(2),J(),q(3,`span`,19),Z(4),J(),V(5,Dw,2,1,`span`,20),J()),e&2){let e=t.$implicit;B(2),Q(e.token),B(2),Q(e.type),B(),H(e.source&&e.source!==`class`&&e.source!==`providers array`?5:-1)}}function kw(e,t){if(e&1&&(q(0,`h4`),Z(1,`Injected Providers`),J(),q(2,`ul`,16),U(3,Ow,6,3,`li`,17,yw),J()),e&2){let e=X(4);B(3),W(e.selectedProviders())}}function Aw(e,t){e&1&&(q(0,`p`,12),Z(1,`No injected providers detected.`),J())}function jw(e,t){if(e&1&&(q(0,`div`,11)(1,`dl`)(2,`dt`),Z(3,`File`),J(),q(4,`dd`),Z(5),J(),q(6,`dt`),Z(7,`Standalone`),J(),q(8,`dd`),Z(9),J()(),V(10,ww,5,0),V(11,Ew,5,0),V(12,kw,5,0)(13,Aw,2,0,`p`,12),J()),e&2){let e=X().$implicit,t=X(2);B(5),Q(e.file),B(4),Q(e.isStandalone?`Yes`:`No`),B(),H(e.inputs.length?10:-1),B(),H(e.outputs.length?11:-1),B(),H(t.selectedProviders().length?12:13)}}function Mw(e,t){if(e&1){let e=Yh();q(0,`li`,6)(1,`button`,7),Y(`click`,function(){let t=bo(e).$implicit;return xo(X(2).select(t))}),q(2,`div`,8),Z(3),J(),q(4,`div`,9),Z(5),J(),U(6,Sw,2,2,`span`,10,vw),J(),V(8,jw,14,5,`div`,11),J()}if(e&2){let e=t.$implicit,n=X(2);Ag(`expanded`,n.isSelected(e)),B(),vh(`aria-expanded`,n.isSelected(e)),B(2),$(`<`,e.selector,`>`),B(2),Q(e.file),B(),W(n.routedBy().get(e.selector)??i_(6,gw)),B(2),H(n.isSelected(e)?8:-1)}}function Nw(e,t){if(e&1&&(q(0,`ul`,4),U(1,Mw,9,7,`li`,5,_w),J()),e&2){let e=X();B(),W(e.filtered())}}var Pw=class e{rpc=k_(null);components=L([]);allProviders=L([]);filter=L(``);loading=L(!1);selected=L(null);selectedProviders=L([]);filtered=L([]);outlets=L([]);unsubscribeRouter=null;destroyRef=P(us);routedBy=b_(()=>{let e=new Map,t=n=>{for(let r of n)r.activated&&r.element&&r.route&&e.set(r.element,[...e.get(r.element)??[],{route:r.route,outlet:r.outlet}]),r.children&&t(r.children)};return t(this.outlets()),e});constructor(){Zs(()=>{let e=this.filter().toLowerCase(),t=this.components();this.filtered.set(e?t.filter(t=>t.selector.includes(e)||t.file.includes(e)):t)}),Zs(()=>{let e=this.rpc();e&&(this.refresh(),this.watchRouter(e))}),this.destroyRef.onDestroy(()=>this.unsubscribeRouter?.())}async watchRouter(e){try{let t=await e.scope(`ng-devtools`).rpc.sharedState(`router`);if(this.destroyRef.destroyed)return;let n=e=>{let t=e?.pages??[],n=t.find(e=>e.snapshot)??t[0];this.outlets.set(n?.outlets??[])};n(t.value()),this.unsubscribeRouter?.(),this.unsubscribeRouter=t.on(`updated`,n)}catch{this.outlets.set([])}}async refresh(){let e=this.rpc();if(e){this.loading.set(!0);try{let t=e.scope(`ng-devtools`),[n,r]=await Promise.all([t.rpc.call(`get-components`),t.rpc.call(`get-providers`)]);this.components.set(n),this.allProviders.set(r);let i=this.selected();if(i){let e=n.find(e=>e.selector===i.selector);e?(this.selected.set(e),this.selectedProviders.set(r.filter(t=>t.file===e.file))):(this.selected.set(null),this.selectedProviders.set([]))}}finally{this.loading.set(!1)}}}isSelected(e){return this.selected()?.selector===e.selector}select(e){if(this.isSelected(e)){this.selected.set(null),this.selectedProviders.set([]);let e=this.rpc();e&&e.scope(`ng-devtools`).rpc.callEvent(`select-component`,null);return}this.selected.set(e),this.selectedProviders.set(this.allProviders().filter(t=>t.file===e.file));let t=this.rpc();t&&t.scope(`ng-devtools`).rpc.callEvent(`select-component`,e.selector)}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-component-tree`]],inputs:{rpc:[1,`rpc`]},decls:7,vars:2,consts:[[1,`toolbar`],[`type`,`text`,`placeholder`,`Filter components…`,3,`input`,`value`],[3,`click`],[1,`muted`],[`role`,`list`,1,`component-list`],[1,`component-item`,3,`expanded`],[1,`component-item`],[1,`component-toggle`,3,`click`],[1,`selector`],[1,`file`],[1,`routed`],[1,`inline-detail`],[1,`no-providers`],[`role`,`list`,1,`prop-list`],[1,`prop-chip`,`input-chip`],[1,`prop-chip`,`output-chip`],[`role`,`list`,1,`provider-list`],[1,`provider-item`],[1,`provider-token`],[1,`provider-type`],[1,`provider-source`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`input`,1),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(2,`button`,2),Y(`click`,function(){return t.refresh()}),Z(3,`Refresh`),J()(),V(4,bw,2,0,`p`,3)(5,xw,2,0,`p`,3)(6,Nw,3,0,`ul`,4)),e&2&&(B(),Xh(`value`,t.filter()),B(3),H(t.loading()?4:t.filtered().length===0?5:6))},styles:[`.toolbar[_ngcontent-%COMP%] { - display: flex; - gap: 8px; - margin-bottom: 16px; - } - input[_ngcontent-%COMP%] { - flex: 1; - padding: 8px 12px; - background: #18181b; - border: 1px solid #27272a; - border-radius: 6px; - color: #e4e4e7; - font-size: 14px; - outline: none; - } - input[_ngcontent-%COMP%]:focus { - border-color: var(--%NS%accent); - } - button[_ngcontent-%COMP%] { - padding: 8px 16px; - background: #3f3f46; - border: none; - border-radius: 6px; - color: #e4e4e7; - cursor: pointer; - font-size: 13px; - } - button[_ngcontent-%COMP%]:hover { - background: #52525b; - } - .muted[_ngcontent-%COMP%] { - color: #71717a; - font-size: 14px; - } - .component-list[_ngcontent-%COMP%] { - list-style: none; - padding: 0; - display: flex; - flex-direction: column; - gap: 8px; - } - .component-item[_ngcontent-%COMP%] { - background: #18181b; - border: 1px solid #27272a; - border-radius: 8px; - padding: 0; - transition: border-color 0.15s; - } - .component-item[_ngcontent-%COMP%]:has(.component-toggle:hover) { - border-color: var(--%NS%accent); - } - .component-item.expanded[_ngcontent-%COMP%] { - border-color: var(--%NS%accent); - } - .component-toggle[_ngcontent-%COMP%] { - display: block; - width: 100%; - padding: 12px 16px; - background: none; - border: none; - color: inherit; - text-align: left; - cursor: pointer; - font: inherit; - } - .selector[_ngcontent-%COMP%] { - font-family: monospace; - font-size: 15px; - color: var(--%NS%accent); - font-weight: 600; - } - .file[_ngcontent-%COMP%] { - font-size: 12px; - color: #71717a; - margin-top: 2px; - } - .io[_ngcontent-%COMP%] { - font-size: 13px; - color: #a1a1aa; - margin-top: 4px; - } - .io[_ngcontent-%COMP%] .label[_ngcontent-%COMP%] { - color: #71717a; - } - .inline-detail[_ngcontent-%COMP%] { - padding: 0 16px 12px; - border-top: 1px solid #27272a; - margin-top: 0; - padding-top: 12px; - } - .prop-list[_ngcontent-%COMP%] { - list-style: none; - padding: 0; - display: flex; - flex-wrap: wrap; - gap: 6px; - margin-bottom: 12px; - } - .prop-chip[_ngcontent-%COMP%] { - font-family: monospace; - font-size: 12px; - padding: 3px 8px; - border-radius: 4px; - } - .input-chip[_ngcontent-%COMP%] { - background: #1e3a5f; - color: #93c5fd; - } - .output-chip[_ngcontent-%COMP%] { - background: #3b1d1d; - color: #fca5a5; - } - dl[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: auto 1fr; - gap: 4px 12px; - font-size: 13px; - margin-bottom: 16px; - } - dt[_ngcontent-%COMP%] { - color: #71717a; - } - dd[_ngcontent-%COMP%] { - color: #e4e4e7; - } - h4[_ngcontent-%COMP%] { - font-size: 12px; - text-transform: uppercase; - letter-spacing: 0.05em; - color: #71717a; - margin-bottom: 8px; - } - .provider-list[_ngcontent-%COMP%] { - list-style: none; - padding: 0; - display: flex; - flex-direction: column; - gap: 6px; - } - .provider-item[_ngcontent-%COMP%] { - display: flex; - align-items: center; - gap: 8px; - padding: 6px 10px; - background: #09090b; - border: 1px solid #27272a; - border-radius: 6px; - font-size: 13px; - } - .provider-token[_ngcontent-%COMP%] { - font-family: monospace; - color: #e4e4e7; - font-weight: 600; - } - .provider-type[_ngcontent-%COMP%] { - font-size: 11px; - padding: 1px 6px; - border-radius: 4px; - background: #3f3f46; - color: #a1a1aa; - } - .routed[_ngcontent-%COMP%] { - display: inline-block; - margin-top: 4px; - padding: 1px 6px; - border: 1px solid #52525b; - border-radius: 4px; - color: #d4d4d8; - font-size: 11px; - font-family: monospace; - } - .provider-source[_ngcontent-%COMP%] { - font-size: 12px; - color: #a1a1aa; - } - .no-providers[_ngcontent-%COMP%] { - font-size: 13px; - color: #52525b; - }`]})};function Fw(e,t,n){return e?e.scope(`ng-devtools`).rpc.call(t,...n===void 0?[]:[n]).then(e=>e,()=>null):Promise.resolve(null)}function Iw(e,t,n){return Fw(e,`request-router-action`,{pageId:t,request:n})}function Lw(e){return e===`succeeded`?`good`:e===`redirected`||e===`pending`||e===`skipped`?`warn`:e===`cancelled`||e===`failed`?`bad`:``}var Rw=()=>[],zw=(e,t)=>t[0],Bw=(e,t)=>t.input;function Vw(e,t){if(e&1&&(q(0,`p`,2),Z(1,` The browser shows `),q(2,`code`),Z(3),J(),Z(4,`, not the router URL (skipLocationChange, browserUrl, a failed navigation or code that changed history). `),J()),e&2){let e=X();B(3),Q(e.browserUrl)}}function Hw(e,t){if(e&1){let e=Yh();q(0,`div`,3),Z(1,` Navigating to `),q(2,`code`),Z(3),J(),Z(4),q(5,`button`,8),Y(`click`,function(){return bo(e),xo(X(2).abort())}),Z(6,`Abort`),J()()}if(e&2){let e=t;B(3),Q(e.url),B(),$(` (#`,e.id,`) `)}}function Uw(e,t){if(e&1&&(q(0,`p`,4),Z(1),J()),e&2){let e=X(2);B(),Q(e.message())}}function Ww(e,t){if(e&1&&(q(0,`dt`),Z(1,`Document title`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X();B(3),Q(e.title)}}function Gw(e,t){if(e&1&&(q(0,`dt`),Z(1,`Query params`),J(),q(2,`dd`)(3,`code`),Z(4),l_(5,`json`),J()()),e&2){let e=X();B(4),Q(d_(5,1,e.queryParams))}}function Kw(e,t){if(e&1&&(q(0,`dt`),Z(1,`Fragment`),J(),q(2,`dd`)(3,`code`),Z(4),J()()),e&2){let e=X();B(4),Q(e.fragment)}}function qw(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=X().$implicit;B(),Q(e.route.outlet)}}function Jw(e,t){e&1&&(q(0,`span`,10),Z(1,`lazy`),J())}function Yw(e,t){if(e&1&&(q(0,`div`,11),Z(1),J()),e&2){let e=X().$implicit;B(),t_(` title `,e.route.title,``,e.route.ownTitle===!1?` (inherited)`:``,` `)}}function Xw(e,t){e&1&&(q(0,`span`,10),Z(1,`inherited`),J())}function Zw(e,t){if(e&1&&(q(0,`div`)(1,`code`),Z(2),l_(3,`json`),J(),V(4,Xw,2,0,`span`,10),J()),e&2){let e=t.$implicit,n=X().$implicit;B(2),t_(``,e[0],`: `,d_(3,3,e[1])),B(2),H(n.route.paramSources?.[e[0]]===`inherited`?4:-1)}}function Qw(e,t){e&1&&Z(0,` — `)}function $w(e,t){e&1&&(q(0,`span`,10),Z(1),J()),e&2&&(B(),Q(t))}function eT(e,t){if(e&1&&(q(0,`div`,12)(1,`code`),Z(2),l_(3,`json`),J(),V(4,$w,2,1,`span`,10),J()),e&2){let e,n=t.$implicit,r=X().$implicit;B(2),t_(``,n[0],`: `,d_(3,3,n[1])),B(2),H((e=r.route.dataSources?.[n[0]])?4:-1,e)}}function tT(e,t){e&1&&Z(0,` — `)}function nT(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=t.$implicit;B(),Q(e)}}function rT(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=t.$implicit;B(),$(`resolve `,e)}}function iT(e,t){e&1&&Z(0,` — `)}function aT(e,t){if(e&1&&(q(0,`tr`)(1,`td`,9),Z(2),V(3,qw,2,1,`span`,10),V(4,Jw,2,0,`span`,10),V(5,Yw,2,2,`div`,11),J(),q(6,`td`),Z(7),J(),q(8,`td`),U(9,Zw,5,5,`div`,null,zw,!1,Qw,1,0),J(),q(12,`td`),U(13,eT,5,5,`div`,12,zw,!1,tT,1,0),J(),q(16,`td`),U(17,nT,2,1,`span`,10,kh),U(19,rT,2,1,`span`,10,kh),V(21,iT,1,0),J()()),e&2){let e=t.$implicit,n=X(2);B(),kg(`padding-left`,12+e.depth*16,`px`),B(),$(` `,e.depth===0&&!e.route.path?`(root)`:`/`+e.route.path,` `),B(),H(e.route.outlet===`primary`?-1:3),B(),H(e.route.lazy?4:-1),B(),H(e.route.title?5:-1),B(2),Q(e.route.component??`—`),B(2),W(n.entries(e.route.params)),B(4),W(n.entries(e.route.data)),B(4),W(n.guardList(e.route)),B(2),W(e.route.resolvers??i_(10,Rw)),B(2),H(!n.guardList(e.route).length&&!e.route.resolvers?21:-1)}}function oT(e,t){if(e&1&&(q(0,`code`),Z(1),J(),Z(2,` for `),q(3,`code`),Z(4),J()),e&2){let e=X().$implicit;B(),Q(e.outlet.component??`?`),B(3),Q(e.outlet.route??`?`)}}function sT(e,t){e&1&&(q(0,`span`,0),Z(1,`not activated`),J())}function cT(e,t){e&1&&(q(0,`span`,10),Z(1,`detached by reuse strategy`),J())}function lT(e,t){if(e&1&&(q(0,`span`,10),Z(1),J()),e&2){let e=t.$implicit;B(),t_(`input `,e.input,` ← `,e.source)}}function uT(e,t){if(e&1&&(q(0,`li`)(1,`span`,10),Z(2),J(),V(3,oT,5,2)(4,sT,2,0,`span`,0),V(5,cT,2,0,`span`,10),U(6,lT,2,2,`span`,10,Bw),J()),e&2){let e=t.$implicit,n=X(3);kg(`padding-left`,e.depth*16,`px`),B(2),Q(e.outlet.outlet),B(),H(e.outlet.activated?3:4),B(2),H(e.outlet.detached?5:-1),B(),W(n.boundInputs(e.outlet))}}function dT(e,t){if(e&1&&(q(0,`h3`),Z(1,`Outlets`),J(),q(2,`ul`,13),U(3,uT,8,5,`li`,14,Oh),J()),e&2){let e=X(2);B(3),W(e.outletRows())}}function fT(e,t){if(e&1&&(q(0,`p`,1)(1,`code`),Z(2),J()(),V(3,Vw,5,1,`p`,2),V(4,Hw,7,2,`div`,3),V(5,Uw,2,1,`p`,4),q(6,`dl`,5),V(7,Ww,4,1),V(8,Gw,6,3),V(9,Kw,5,1),J(),q(10,`h3`),Z(11,`Active routes`),J(),q(12,`div`,6)(13,`table`)(14,`thead`)(15,`tr`)(16,`th`,7),Z(17,`Route`),J(),q(18,`th`,7),Z(19,`Component`),J(),q(20,`th`,7),Z(21,`Params`),J(),q(22,`th`,7),Z(23,`Data`),J(),q(24,`th`,7),Z(25,`Guards and resolvers`),J()()(),q(26,`tbody`),U(27,aT,22,11,`tr`,null,Oh),J()()(),V(29,dT,5,0)),e&2){let e,n=t,r=X();B(2),Q(n.url),B(),H(n.urlDrift&&n.browserUrl?3:-1),B(),H((e=n.pending)?4:-1,e),B(),H(r.message()?5:-1),B(2),H(n.title?7:-1),B(),H(r.hasKeys(n.queryParams)?8:-1),B(),H(n.fragment?9:-1),B(18),W(r.rows()),B(2),H(r.outletRows().length?29:-1)}}function pT(e,t){e&1&&(q(0,`p`,0),Z(1,`This page reports no Router.`),J())}var mT=class e{page=k_.required();rpc=k_(null);message=L(``);rows=b_(()=>{let e=[],t=(n,r)=>{e.push({route:n,depth:r});for(let e of n.children)t(e,r+1)},n=this.page().snapshot?.root;return n&&t(n,0),e});outletRows=b_(()=>{let e=[],t=(n,r)=>{for(let i of n)e.push({outlet:i,depth:r}),i.children&&t(i.children,r+1)};return t(this.page().outlets??[],0),e});hasKeys(e){return Object.keys(e).length>0}entries(e){return Object.entries(e)}guardList(e){return Object.entries(e.guards??{}).flatMap(([e,t])=>t.map(t=>`${e} ${t}`))}boundInputs(e){return(e.inputs??[]).filter(e=>e.source!==`unset`)}async abort(){let e=await Iw(this.rpc(),this.page().pageId,{action:`abort`});this.message.set(e?.error?String(e.error):`Aborted navigation #${e?.aborted}`)}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-route-current`]],inputs:{page:[1,`page`],rpc:[1,`rpc`]},decls:2,vars:1,consts:[[1,`muted`],[1,`url`],[`role`,`note`,1,`note`],[`role`,`status`,1,`pending`],[`role`,`status`,1,`muted`],[1,`facts`],[`role`,`region`,`aria-label`,`Active routes`,`tabindex`,`0`,1,`table-scroll`],[`scope`,`col`],[`type`,`button`,1,`small`,3,`click`],[1,`path`],[1,`tag`],[1,`sub`],[1,`data`],[1,`outlets`],[3,`padding-left`]],template:function(e,t){if(e&1&&V(0,fT,30,8)(1,pT,2,0,`p`,0),e&2){let e;H((e=t.page().snapshot)?0:1,e)}},dependencies:[Wv],styles:[`.muted[_ngcontent-%COMP%] { - color: #a1a1aa; - font-size: 13px; - } - code[_ngcontent-%COMP%] { - font-family: monospace; - color: #d4d4d8; - overflow-wrap: anywhere; - } - .tag[_ngcontent-%COMP%] { - display: inline-block; - margin: 0 4px 4px 0; - padding: 1px 6px; - border: 1px solid #52525b; - border-radius: 4px; - color: #d4d4d8; - font-size: 11px; - font-family: monospace; - } - .badge[_ngcontent-%COMP%] { - padding: 1px 6px; - border-radius: 4px; - background: #3f3f46; - color: #e4e4e7; - font-size: 11px; - font-weight: 600; - } - .badge[data-tone='good'][_ngcontent-%COMP%] { - background: #14532d; - color: #bbf7d0; - } - .badge[data-tone='warn'][_ngcontent-%COMP%] { - background: #713f12; - color: #fef08a; - } - .badge[data-tone='bad'][_ngcontent-%COMP%] { - background: #7f1d1d; - color: #fecaca; - } - button.small[_ngcontent-%COMP%] { - padding: 3px 10px; - background: #3f3f46; - border: none; - border-radius: 6px; - color: #e4e4e7; - cursor: pointer; - font-size: 12px; - } - button.small[_ngcontent-%COMP%]:hover { - background: #52525b; - } - button.small[_ngcontent-%COMP%]:focus-visible, - input[_ngcontent-%COMP%]:focus-visible, - select[_ngcontent-%COMP%]:focus-visible, - .table-scroll[_ngcontent-%COMP%]:focus-visible { - outline: 2px solid var(--%NS%accent); - outline-offset: 2px; - } - input.field[_ngcontent-%COMP%] { - padding: 6px 10px; - background: #18181b; - border: 1px solid #52525b; - border-radius: 6px; - color: #e4e4e7; - font-size: 13px; - } - .table-scroll[_ngcontent-%COMP%] { - overflow-x: auto; - } - table[_ngcontent-%COMP%] { - width: 100%; - border-collapse: collapse; - font-size: 13px; - } - th[_ngcontent-%COMP%] { - text-align: left; - padding: 6px 12px; - color: #a1a1aa; - font-size: 12px; - border-bottom: 1px solid #27272a; - } - td[_ngcontent-%COMP%] { - padding: 8px 12px; - border-bottom: 1px solid #1e1e22; - vertical-align: top; - } - h3[_ngcontent-%COMP%] { - margin: 0 0 8px; - font-size: 14px; - color: #e4e4e7; - } - .visually-hidden[_ngcontent-%COMP%] { - position: absolute; - width: 1px; - height: 1px; - overflow: hidden; - clip-path: inset(50%); - white-space: nowrap; - } - - [_nghost-%COMP%] { - display: grid; - gap: 12px; - } - .url[_ngcontent-%COMP%] code[_ngcontent-%COMP%] { - font-size: 14px; - color: var(--%NS%accent); - } - .note[_ngcontent-%COMP%] { - margin: 0; - padding: 8px 10px; - border-left: 3px solid #fef08a; - background: #27272a; - color: #e4e4e7; - font-size: 13px; - } - .pending[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 8px; - align-items: center; - font-size: 13px; - color: #fef08a; - } - .facts[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: max-content 1fr; - gap: 4px 12px; - margin: 0; - font-size: 13px; - } - dt[_ngcontent-%COMP%] { - color: #a1a1aa; - } - dd[_ngcontent-%COMP%] { - margin: 0; - color: #e4e4e7; - } - .path[_ngcontent-%COMP%] { - font-family: monospace; - color: var(--%NS%accent); - white-space: nowrap; - } - .sub[_ngcontent-%COMP%] { - font-family: inherit; - color: #a1a1aa; - font-size: 12px; - white-space: normal; - } - .data[_ngcontent-%COMP%] { - max-width: 360px; - } - .outlets[_ngcontent-%COMP%] { - list-style: none; - margin: 0; - padding: 0; - display: grid; - gap: 6px; - font-size: 13px; - color: #e4e4e7; - }`]})};function hT(e,t){e&1&&(q(0,`p`,2),Z(1,`Checking…`),J())}function gT(e,t){if(e&1&&(q(0,`li`)(1,`div`,4)(2,`span`,5),Z(3),J(),q(4,`code`),Z(5),J(),q(6,`code`,6),Z(7),J()(),q(8,`p`),Z(9),J(),q(10,`p`,7),Z(11),q(12,`span`,2),Z(13),J()()()),e&2){let e=t.$implicit;B(2),vh(`data-tone`,e.severity===`error`?`bad`:e.severity===`warning`?`warn`:``),B(),Q(e.severity),B(2),Q(e.rule),B(2),Q(e.route),B(2),Q(e.message),B(2),$(` Fix: `,e.fix,` `),B(2),$(`(Angular `,e.angular===`throws`?`throws`:e.angular===`warns`?`warns`:`does not warn`,`)`)}}function _T(e,t){if(e&1&&(q(0,`ul`,3),U(1,gT,14,7,`li`,null,Oh),J()),e&2){let e=X();B(),W(e.findings())}}function vT(e,t){e&1&&(q(0,`p`,2),Z(1,`No route config problems found.`),J())}var yT=class e{page=k_.required();rpc=k_(null);findings=L([]);loading=L(!1);key=b_(()=>`${this.page().pageId}:${this.page().generation}:${this.page().navigations.length}`);constructor(){Zs(()=>{this.key(),x_(()=>void this.run())})}async run(){this.loading.set(!0),this.findings.set(await Fw(this.rpc(),`router-lint`,this.page().pageId)??[]),this.loading.set(!1)}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-route-lint`]],inputs:{page:[1,`page`],rpc:[1,`rpc`]},decls:8,vars:1,consts:[[1,`toolbar`],[`type`,`button`,1,`small`,3,`click`],[1,`muted`],[1,`findings`],[1,`head`],[1,`badge`],[1,`route`],[1,`fix`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`button`,1),Y(`click`,function(){return t.run()}),Z(2,`Check again`),J(),q(3,`span`,2),Z(4,`Checks the live config, links and recent navigations. Lazy routes that have not loaded are skipped.`),J()(),V(5,hT,2,0,`p`,2)(6,_T,3,0,`ul`,3)(7,vT,2,0,`p`,2)),e&2&&(B(5),H(t.loading()?5:t.findings().length?6:7))},styles:[`.muted[_ngcontent-%COMP%] { - color: #a1a1aa; - font-size: 13px; - } - code[_ngcontent-%COMP%] { - font-family: monospace; - color: #d4d4d8; - overflow-wrap: anywhere; - } - .tag[_ngcontent-%COMP%] { - display: inline-block; - margin: 0 4px 4px 0; - padding: 1px 6px; - border: 1px solid #52525b; - border-radius: 4px; - color: #d4d4d8; - font-size: 11px; - font-family: monospace; - } - .badge[_ngcontent-%COMP%] { - padding: 1px 6px; - border-radius: 4px; - background: #3f3f46; - color: #e4e4e7; - font-size: 11px; - font-weight: 600; - } - .badge[data-tone='good'][_ngcontent-%COMP%] { - background: #14532d; - color: #bbf7d0; - } - .badge[data-tone='warn'][_ngcontent-%COMP%] { - background: #713f12; - color: #fef08a; - } - .badge[data-tone='bad'][_ngcontent-%COMP%] { - background: #7f1d1d; - color: #fecaca; - } - button.small[_ngcontent-%COMP%] { - padding: 3px 10px; - background: #3f3f46; - border: none; - border-radius: 6px; - color: #e4e4e7; - cursor: pointer; - font-size: 12px; - } - button.small[_ngcontent-%COMP%]:hover { - background: #52525b; - } - button.small[_ngcontent-%COMP%]:focus-visible, - input[_ngcontent-%COMP%]:focus-visible, - select[_ngcontent-%COMP%]:focus-visible, - .table-scroll[_ngcontent-%COMP%]:focus-visible { - outline: 2px solid var(--%NS%accent); - outline-offset: 2px; - } - input.field[_ngcontent-%COMP%] { - padding: 6px 10px; - background: #18181b; - border: 1px solid #52525b; - border-radius: 6px; - color: #e4e4e7; - font-size: 13px; - } - .table-scroll[_ngcontent-%COMP%] { - overflow-x: auto; - } - table[_ngcontent-%COMP%] { - width: 100%; - border-collapse: collapse; - font-size: 13px; - } - th[_ngcontent-%COMP%] { - text-align: left; - padding: 6px 12px; - color: #a1a1aa; - font-size: 12px; - border-bottom: 1px solid #27272a; - } - td[_ngcontent-%COMP%] { - padding: 8px 12px; - border-bottom: 1px solid #1e1e22; - vertical-align: top; - } - h3[_ngcontent-%COMP%] { - margin: 0 0 8px; - font-size: 14px; - color: #e4e4e7; - } - .visually-hidden[_ngcontent-%COMP%] { - position: absolute; - width: 1px; - height: 1px; - overflow: hidden; - clip-path: inset(50%); - white-space: nowrap; - } - - [_nghost-%COMP%] { - display: grid; - gap: 10px; - } - .toolbar[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 10px; - align-items: center; - } - .findings[_ngcontent-%COMP%] { - list-style: none; - margin: 0; - padding: 0; - display: grid; - gap: 8px; - } - .findings[_ngcontent-%COMP%] li[_ngcontent-%COMP%] { - padding: 10px; - border: 1px solid #27272a; - border-radius: 6px; - font-size: 13px; - color: #e4e4e7; - } - .head[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 8px; - align-items: center; - } - .route[_ngcontent-%COMP%] { - color: var(--%NS%accent); - } - p[_ngcontent-%COMP%] { - margin: 6px 0 0; - } - .fix[_ngcontent-%COMP%] { - color: #d4d4d8; - }`]})},bT=(e,t)=>t.name,xT=(e,t)=>t[0];function ST(e,t){e&1&&(q(0,`p`,1),Z(1,` Events-only mode: this build has no debug utils (production build or unusual setup), so the route config, lint and actions are limited. `),J())}function CT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Angular`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X();B(3),Q(e.angularVersion)}}function wT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Base href`),J(),q(2,`dd`)(3,`code`),Z(4),J()()),e&2){let e=X();B(4),Q(e.baseHref)}}function TT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Hydration`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X();B(3),$(``,e.hydrated,` component(s) hydrated from server HTML`)}}function ET(e,t){if(e&1&&(q(0,`tr`)(1,`td`)(2,`code`),Z(3),J()(),q(4,`td`)(5,`code`),Z(6),J()(),q(7,`td`)(8,`span`,6),Z(9),J()()()),e&2){let e=t.$implicit;B(3),Q(e.name),B(3),Q(e.value),B(2),vh(`data-tone`,e.set?`warn`:``),B(),Q(e.set?`set`:`default`)}}function DT(e,t){if(e&1&&(q(0,`li`)(1,`span`,6),Z(2),J()()),e&2){let e=t.$implicit;B(),vh(`data-tone`,e[1]===`off`?``:`good`),B(),t_(``,e[0],`: `,e[1])}}function OT(e,t){if(e&1&&(q(0,`dt`),Z(1),J(),q(2,`dd`)(3,`code`),Z(4),J()()),e&2){let e=t.$implicit;B(),Q(e[0]),B(3),Q(e[1])}}function kT(e,t){if(e&1&&(V(0,ST,2,0,`p`,1),q(1,`dl`,2)(2,`dt`),Z(3,`Set up with`),J(),q(4,`dd`),Z(5),J(),V(6,CT,4,1),V(7,wT,5,1),V(8,TT,4,1),J(),q(9,`h3`),Z(10,`Options`),J(),q(11,`div`,3)(12,`table`)(13,`thead`)(14,`tr`)(15,`th`,4),Z(16,`Option`),J(),q(17,`th`,4),Z(18,`Value`),J(),q(19,`th`,4),Z(20,`Source`),J()()(),q(21,`tbody`),U(22,ET,10,4,`tr`,null,bT),J()()(),q(24,`h3`),Z(25,`Features`),J(),q(26,`ul`,5),U(27,DT,3,3,`li`,null,xT),J(),q(29,`h3`),Z(30,`Strategies`),J(),q(31,`dl`,2),U(32,OT,5,2,null,null,xT),J()),e&2){let e=t,n=X();H(e.mode===`events-only`?0:-1),B(5),t_(` `,e.setupKind,``,e.routers>1?`, `+e.routers+` routers on the page`:``,` `),B(),H(e.angularVersion?6:-1),B(),H(e.baseHref?7:-1),B(),H(e.hydrated?8:-1),B(14),W(e.options),B(5),W(n.entries(e.features)),B(5),W(n.entries(e.strategies))}}function AT(e,t){e&1&&(q(0,`p`,0),Z(1,`The page has not reported its router setup yet.`),J())}var jT=class e{page=k_.required();entries(e){return Object.entries(e)}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-route-setup`]],inputs:{page:[1,`page`]},decls:2,vars:1,consts:[[1,`muted`],[`role`,`note`,1,`note`],[1,`facts`],[`role`,`region`,`aria-label`,`Router options`,`tabindex`,`0`,1,`table-scroll`],[`scope`,`col`],[1,`chips`],[1,`badge`]],template:function(e,t){if(e&1&&V(0,kT,34,6)(1,AT,2,0,`p`,0),e&2){let e;H((e=t.page().setup)?0:1,e)}},styles:[`.muted[_ngcontent-%COMP%] { - color: #a1a1aa; - font-size: 13px; - } - code[_ngcontent-%COMP%] { - font-family: monospace; - color: #d4d4d8; - overflow-wrap: anywhere; - } - .tag[_ngcontent-%COMP%] { - display: inline-block; - margin: 0 4px 4px 0; - padding: 1px 6px; - border: 1px solid #52525b; - border-radius: 4px; - color: #d4d4d8; - font-size: 11px; - font-family: monospace; - } - .badge[_ngcontent-%COMP%] { - padding: 1px 6px; - border-radius: 4px; - background: #3f3f46; - color: #e4e4e7; - font-size: 11px; - font-weight: 600; - } - .badge[data-tone='good'][_ngcontent-%COMP%] { - background: #14532d; - color: #bbf7d0; - } - .badge[data-tone='warn'][_ngcontent-%COMP%] { - background: #713f12; - color: #fef08a; - } - .badge[data-tone='bad'][_ngcontent-%COMP%] { - background: #7f1d1d; - color: #fecaca; - } - button.small[_ngcontent-%COMP%] { - padding: 3px 10px; - background: #3f3f46; - border: none; - border-radius: 6px; - color: #e4e4e7; - cursor: pointer; - font-size: 12px; - } - button.small[_ngcontent-%COMP%]:hover { - background: #52525b; - } - button.small[_ngcontent-%COMP%]:focus-visible, - input[_ngcontent-%COMP%]:focus-visible, - select[_ngcontent-%COMP%]:focus-visible, - .table-scroll[_ngcontent-%COMP%]:focus-visible { - outline: 2px solid var(--%NS%accent); - outline-offset: 2px; - } - input.field[_ngcontent-%COMP%] { - padding: 6px 10px; - background: #18181b; - border: 1px solid #52525b; - border-radius: 6px; - color: #e4e4e7; - font-size: 13px; - } - .table-scroll[_ngcontent-%COMP%] { - overflow-x: auto; - } - table[_ngcontent-%COMP%] { - width: 100%; - border-collapse: collapse; - font-size: 13px; - } - th[_ngcontent-%COMP%] { - text-align: left; - padding: 6px 12px; - color: #a1a1aa; - font-size: 12px; - border-bottom: 1px solid #27272a; - } - td[_ngcontent-%COMP%] { - padding: 8px 12px; - border-bottom: 1px solid #1e1e22; - vertical-align: top; - } - h3[_ngcontent-%COMP%] { - margin: 0 0 8px; - font-size: 14px; - color: #e4e4e7; - } - .visually-hidden[_ngcontent-%COMP%] { - position: absolute; - width: 1px; - height: 1px; - overflow: hidden; - clip-path: inset(50%); - white-space: nowrap; - } - - [_nghost-%COMP%] { - display: grid; - gap: 12px; - } - .note[_ngcontent-%COMP%] { - margin: 0; - padding: 8px 10px; - border-left: 3px solid #fef08a; - background: #27272a; - color: #e4e4e7; - font-size: 13px; - } - .facts[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: max-content 1fr; - gap: 4px 12px; - margin: 0; - font-size: 13px; - } - dt[_ngcontent-%COMP%] { - color: #a1a1aa; - } - dd[_ngcontent-%COMP%] { - margin: 0; - color: #e4e4e7; - } - .chips[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 6px; - margin: 0; - padding: 0; - list-style: none; - }`]})},MT=(e,t)=>[e,t],NT=(e,t)=>t.id,PT=(e,t)=>t.phase;function FT(e,t){if(e&1&&(q(0,`p`,5),Z(1),J()),e&2){let e=X();B(),Q(e.message())}}function IT(e,t){if(e&1&&(q(0,`span`),Hh(1,`i`),Z(2),J()),e&2){let e=t.$implicit,n=X();B(),kg(`background`,n.color(e)),B(),Q(e)}}function LT(e,t){if(e&1&&(q(0,`time`),Z(1),J()),e&2){let e=X().$implicit,t=X(2);B(),Q(t.time(e.startedAt))}}function RT(e,t){if(e&1&&(q(0,`span`,15),Z(1,`→`),J(),q(2,`span`,16),Z(3,`redirected to`),J(),q(4,`code`),Z(5),J()),e&2){let e=X().$implicit;B(5),Q(e.finalUrl)}}function zT(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;B(),Q(e.endedAt===void 0&&e.outcome!==`pending`?`before DevTools connected`:`started before DevTools connected`)}}function BT(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;B(),$(``,e.phases?.total,`ms`)}}function VT(e,t){if(e&1&&(q(0,`span`,8),Z(1),J()),e&2){let e=X().$implicit;B(),$(``,e.endedAt-e.startedAt,`ms`)}}function HT(e,t){e&1&&(q(0,`span`,11),Z(1,`probe`),J())}function UT(e,t){if(e&1&&Hh(0,`span`),e&2){let e=t.$implicit,n=X(4);kg(`width`,e.width,`%`)(`background`,n.color(e.phase)),vh(`title`,e.phase+` `+e.ms+`ms`)}}function WT(e,t){if(e&1&&(q(0,`div`,12),U(1,UT,1,5,`span`,17,PT),J()),e&2){let e=X().$implicit,t=X(2);vh(`aria-label`,t.barLabel(e)),B(),W(t.bars(e))}}function GT(e,t){if(e&1&&(q(0,`dt`),Z(1,`From`),J(),q(2,`dd`)(3,`code`),Z(4),J()()),e&2){let e=X().$implicit;B(4),Q(e.from)}}function KT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Started by`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),t_(``,e.caller,` (`,e.trigger,`)`)}}function qT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Extras`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),Q(e.extras?.join(`, `))}}function JT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Redirect of`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),$(`#`,e.redirectedFrom)}}function YT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Redirects to`),J(),q(2,`dd`)(3,`code`),Z(4),J(),Z(5),J()),e&2){let e=X().$implicit;B(4),Q(e.redirectTo),B(),$(` (`,e.redirectKind,`) `)}}function XT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Guards`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit,t=X(2);B(3),t_(``,e.guards.names.join(`, `)||`none`,`: `,t.guardResult(e))}}function ZT(e,t){if(e&1&&(q(0,`div`)(1,`code`),Z(2),J(),Z(3),q(4,`code`),Z(5),J(),Z(6,`: `),q(7,`strong`),Z(8),J(),Z(9),J()),e&2){let e=t.$implicit,n=X(4);B(2),Q(e.guard),B(),$(` `,e.kind,` on `),B(2),Q(e.route),B(2),Ag(`bad`,n.isBad(e.result)),B(),Q(e.result),B(),$(` (`,e.ms,`ms) `)}}function QT(e,t){if(e&1&&(q(0,`dt`),Z(1,`Runs`),J(),q(2,`dd`),U(3,ZT,10,7,`div`,null,Oh),J()),e&2){let e=X().$implicit;B(3),W(e.runs)}}function $T(e,t){if(e&1&&Z(0),e&2){let e=X(2).$implicit;$(` leaving `,e.checked.deactivate.join(`, `),`; `)}}function eE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Checked`),J(),q(2,`dd`),V(3,$T,1,1),Z(4),J()),e&2){let e=X().$implicit;B(3),H(e.checked.deactivate.length?3:-1),B(),$(` entering `,e.checked.activate.join(`, `)||`nothing new`,` `)}}function tE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Resolvers`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),Q(e.resolvers?.names?.join(`, `))}}function nE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Lazy loaded`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),Q(e.lazyLoaded?.join(`, `))}}function rE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Reused`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),$(` `,e.reused?.join(`, `),` (component kept, only inputs and params change) `)}}function iE(e,t){if(e&1&&(q(0,`dt`),Z(1,`HTTP`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),t_(``,e.requests.count,` request(s): `,e.requests.urls.join(`, `))}}function aE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Scroll`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),Q(e.scroll)}}function oE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Title after`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),Q(e.title)}}function sE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Warnings`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),Q(e.warnings?.join(` · `))}}function cE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Reason`),J(),q(2,`dd`,18),Z(3),J()),e&2){let e=X().$implicit,t=X(2);B(3),Q(a_(1,MT,e.code,e.reason).filter(t.Boolean).join(`: `))}}function lE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Error`),J(),q(2,`dd`,18),Z(3),J()),e&2){let e=X().$implicit;B(3),Q(e.errorCode)}}function uE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Error handler`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),Q(e.errorHandler)}}function dE(e,t){if(e&1&&(q(0,`dt`),Z(1,`Earlier`),J(),q(2,`dd`),Z(3),J()),e&2){let e=X().$implicit;B(3),$(``,e.earlier,` navigation(s) before DevTools connected`)}}function fE(e,t){if(e&1){let e=Yh();q(0,`li`)(1,`div`,9),V(2,LT,2,1,`time`),q(3,`span`,8),Z(4),J(),q(5,`code`),Z(6),J(),V(7,RT,6,1),q(8,`span`,10),Z(9),J(),V(10,zT,2,1,`span`,8)(11,BT,2,1,`span`,8)(12,VT,2,1,`span`,8),V(13,HT,2,0,`span`,11),J(),V(14,WT,3,1,`div`,12),q(15,`dl`,13),V(16,GT,5,1),V(17,KT,4,2),V(18,qT,4,1),V(19,JT,4,1),V(20,YT,6,2),V(21,XT,4,2),V(22,QT,5,0),V(23,eE,5,2),V(24,tE,4,1),V(25,nE,4,1),V(26,rE,4,1),V(27,iE,4,2),V(28,aE,4,1),V(29,oE,4,1),V(30,sE,4,1),V(31,cE,4,4),V(32,lE,4,1),V(33,uE,4,1),V(34,dE,4,1),J(),q(35,`div`,14)(36,`button`,4),Y(`click`,function(){let t=bo(e).$implicit;return xo(X(2).replay(t))}),Z(37,` Replay `),J(),q(38,`button`,4),Y(`click`,function(){let t=bo(e).$implicit;return xo(X(2).copy(t))}),Z(39,` Copy repro `),J()()()}if(e&2){let e=t.$implicit,n=X(2);B(2),H(e.beforeConnect?-1:2),B(2),$(`#`,e.id),B(2),Q(e.url),B(),H(e.finalUrl&&e.finalUrl!==e.url?7:-1),B(),vh(`data-tone`,n.tone(e.outcome)),B(),Q(e.outcome),B(),H(e.beforeConnect?10:e.phases?.total===void 0?e.endedAt===void 0?-1:12:11),B(3),H(e.probe?13:-1),B(),H(n.bars(e).length?14:-1),B(2),H(e.from?16:-1),B(),H(e.caller?17:-1),B(),H(e.extras?.length?18:-1),B(),H(e.redirectedFrom===void 0?-1:19),B(),H(e.redirectTo?20:-1),B(),H(e.guards&&(e.guards.names.length||e.guards.passed===!1)?21:-1),B(),H(e.runs?.length?22:-1),B(),H(e.checked&&(e.checked.activate.length||e.checked.deactivate.length)?23:-1),B(),H(e.resolvers?.names?.length?24:-1),B(),H(e.lazyLoaded?.length?25:-1),B(),H(e.reused?.length?26:-1),B(),H(e.requests?27:-1),B(),H(e.scroll?28:-1),B(),H(e.title?29:-1),B(),H(e.warnings?.length?30:-1),B(),H(e.reason||e.code?31:-1),B(),H(e.errorCode?32:-1),B(),H(e.errorHandler?33:-1),B(),H(e.earlier?34:-1),B(2),vh(`aria-label`,`Replay navigation `+e.id),B(2),vh(`aria-label`,`Copy repro for navigation `+e.id)}}function pE(e,t){if(e&1&&(q(0,`ol`,7),U(1,fE,40,30,`li`,null,NT),J()),e&2){let e=X();B(),W(e.items())}}function mE(e,t){e&1&&(q(0,`p`,8),Z(1,` No navigations since DevTools connected; earlier ones are not visible. Click a link in the app. `),J())}var hE=[`recognize`,`guards`,`resolve`,`activate`],gE={recognize:`#60a5fa`,guards:`#f59e0b`,resolve:`#a78bfa`,activate:`#34d399`},_E=class e{page=k_.required();rpc=k_(null);phases=hE;filter=L(``);onlyProblems=L(!1);message=L(``);items=b_(()=>{let e=this.filter().toLowerCase();return[...this.page().navigations].reverse().filter(t=>(!e||t.url.toLowerCase().includes(e)||!!t.finalUrl?.toLowerCase().includes(e))&&(!this.onlyProblems()||![`succeeded`,`pending`].includes(t.outcome)))});tone(e){return Lw(e)}color(e){return gE[e]}bars(e){let t=e.phases?.total;return t?hE.filter(t=>(e.phases?.[t]??0)>0).map(n=>({phase:n,ms:e.phases[n],width:Math.max(1,e.phases[n]/t*100)})):[]}barLabel(e){return`Phases: ${this.bars(e).map(e=>`${e.phase} ${e.ms}ms`).join(`, `)}`}guardResult(e){let t=e.guards?.passed;return t===!0?`passed`:t===!1?e.outcome===`redirected`?`redirected`:`blocked`:e.outcome===`pending`?`running`:`did not finish, navigation ${e.outcome}`}isBad(e){return e===`false`||/^(UrlTree|RedirectCommand|threw)/.test(e)}time(e){return new Date(e).toLocaleTimeString()}async toggleInstrument(e){let t=e.target.checked,n=await Iw(this.rpc(),this.page().pageId,{action:`instrument`,on:t});this.message.set(n?.error?String(n.error):t?`Recording each guard and resolver.`:`Stopped recording guards and resolvers.`)}async replay(e){this.message.set(`Replaying #${e.id}…`);let t=await Iw(this.rpc(),this.page().pageId,{action:`replay`,id:e.id});if(!t||t.error){this.message.set(String(t?.error??`Replay failed.`));return}let n=t.replay;this.message.set(`Replay of #${e.id}: ${n?.outcome??`unknown`}${t.same?` (same as before)`:` (different from before)`}.`)}async copy(e){let t=await Fw(this.rpc(),`router-export`,{pageId:this.page().pageId,id:e.id});if(!t){this.message.set(`Could not build the repro.`);return}try{await navigator.clipboard.writeText(t),this.message.set(`Copied a markdown repro of #${e.id}.`)}catch{this.message.set(`The clipboard is not available here.`)}}exportJson(){let e=new Blob([JSON.stringify(this.page().navigations,null,2)],{type:`application/json`}),t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`navigations-${this.page().pageId}.json`,n.click(),URL.revokeObjectURL(t)}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-route-timeline`]],inputs:{page:[1,`page`],rpc:[1,`rpc`]},decls:16,vars:5,consts:[[1,`toolbar`],[1,`check`],[`type`,`checkbox`,3,`change`,`checked`],[`type`,`text`,`aria-label`,`Filter navigations by URL`,`placeholder`,`Filter by URL`,1,`field`,3,`input`,`value`],[`type`,`button`,1,`small`,3,`click`],[`role`,`status`,1,`muted`],[`aria-hidden`,`true`,1,`legend`],[1,`navs`],[1,`muted`],[1,`head`],[1,`badge`],[1,`tag`],[`role`,`img`,1,`bar`],[1,`details`],[1,`actions`],[`aria-hidden`,`true`],[1,`visually-hidden`],[3,`width`,`background`],[1,`reason`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`label`,1)(2,`input`,2),Y(`change`,function(e){return t.toggleInstrument(e)}),J(),Z(3,` Record each guard and resolver `),J(),q(4,`input`,3),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(5,`label`,1)(6,`input`,2),Y(`change`,function(e){return t.onlyProblems.set(e.target.checked)}),J(),Z(7,` Only problems `),J(),q(8,`button`,4),Y(`click`,function(){return t.exportJson()}),Z(9,`Export JSON`),J()(),V(10,FT,2,1,`p`,5),q(11,`div`,6),U(12,IT,3,3,`span`,null,kh),J(),V(14,pE,3,0,`ol`,7)(15,mE,2,0,`p`,8)),e&2&&(B(2),Xh(`checked`,t.page().instrumented),B(2),Xh(`value`,t.filter()),B(2),Xh(`checked`,t.onlyProblems()),B(4),H(t.message()?10:-1),B(2),W(t.phases),B(2),H(t.items().length?14:15))},styles:[`.muted[_ngcontent-%COMP%] { - color: #a1a1aa; - font-size: 13px; - } - code[_ngcontent-%COMP%] { - font-family: monospace; - color: #d4d4d8; - overflow-wrap: anywhere; - } - .tag[_ngcontent-%COMP%] { - display: inline-block; - margin: 0 4px 4px 0; - padding: 1px 6px; - border: 1px solid #52525b; - border-radius: 4px; - color: #d4d4d8; - font-size: 11px; - font-family: monospace; - } - .badge[_ngcontent-%COMP%] { - padding: 1px 6px; - border-radius: 4px; - background: #3f3f46; - color: #e4e4e7; - font-size: 11px; - font-weight: 600; - } - .badge[data-tone='good'][_ngcontent-%COMP%] { - background: #14532d; - color: #bbf7d0; - } - .badge[data-tone='warn'][_ngcontent-%COMP%] { - background: #713f12; - color: #fef08a; - } - .badge[data-tone='bad'][_ngcontent-%COMP%] { - background: #7f1d1d; - color: #fecaca; - } - button.small[_ngcontent-%COMP%] { - padding: 3px 10px; - background: #3f3f46; - border: none; - border-radius: 6px; - color: #e4e4e7; - cursor: pointer; - font-size: 12px; - } - button.small[_ngcontent-%COMP%]:hover { - background: #52525b; - } - button.small[_ngcontent-%COMP%]:focus-visible, - input[_ngcontent-%COMP%]:focus-visible, - select[_ngcontent-%COMP%]:focus-visible, - .table-scroll[_ngcontent-%COMP%]:focus-visible { - outline: 2px solid var(--%NS%accent); - outline-offset: 2px; - } - input.field[_ngcontent-%COMP%] { - padding: 6px 10px; - background: #18181b; - border: 1px solid #52525b; - border-radius: 6px; - color: #e4e4e7; - font-size: 13px; - } - .table-scroll[_ngcontent-%COMP%] { - overflow-x: auto; - } - table[_ngcontent-%COMP%] { - width: 100%; - border-collapse: collapse; - font-size: 13px; - } - th[_ngcontent-%COMP%] { - text-align: left; - padding: 6px 12px; - color: #a1a1aa; - font-size: 12px; - border-bottom: 1px solid #27272a; - } - td[_ngcontent-%COMP%] { - padding: 8px 12px; - border-bottom: 1px solid #1e1e22; - vertical-align: top; - } - h3[_ngcontent-%COMP%] { - margin: 0 0 8px; - font-size: 14px; - color: #e4e4e7; - } - .visually-hidden[_ngcontent-%COMP%] { - position: absolute; - width: 1px; - height: 1px; - overflow: hidden; - clip-path: inset(50%); - white-space: nowrap; - } - - [_nghost-%COMP%] { - display: grid; - gap: 10px; - } - .toolbar[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 8px 14px; - align-items: center; - font-size: 13px; - color: #e4e4e7; - } - .check[_ngcontent-%COMP%] { - display: flex; - gap: 6px; - align-items: center; - } - .legend[_ngcontent-%COMP%] { - display: flex; - gap: 12px; - font-size: 12px; - color: #a1a1aa; - } - .legend[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { - display: inline-block; - width: 10px; - height: 10px; - margin-right: 4px; - border-radius: 2px; - } - .navs[_ngcontent-%COMP%] { - list-style: none; - margin: 0; - padding: 0; - display: grid; - gap: 8px; - } - .navs[_ngcontent-%COMP%] > li[_ngcontent-%COMP%] { - padding: 10px; - border: 1px solid #27272a; - border-radius: 6px; - font-size: 13px; - } - .head[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 8px; - align-items: center; - } - time[_ngcontent-%COMP%] { - color: #a1a1aa; - font-size: 12px; - } - .bar[_ngcontent-%COMP%] { - display: flex; - height: 6px; - margin: 8px 0 4px; - border-radius: 3px; - overflow: hidden; - background: #27272a; - } - .bar[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { - display: block; - min-width: 2px; - } - .details[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: max-content 1fr; - gap: 3px 12px; - margin: 6px 0 0; - font-size: 12px; - } - dt[_ngcontent-%COMP%] { - color: #a1a1aa; - } - dd[_ngcontent-%COMP%] { - margin: 0; - color: #e4e4e7; - overflow-wrap: anywhere; - } - .reason[_ngcontent-%COMP%], - .bad[_ngcontent-%COMP%] { - color: #fecaca; - } - .actions[_ngcontent-%COMP%] { - display: flex; - gap: 8px; - margin-top: 8px; - }`]})},vE=()=>[],yE=(e,t)=>t.node.id;function bE(e,t){if(e&1&&(Z(0,` with `),q(1,`code`),Z(2),l_(3,`json`),J()),e&2){let e=X(2);B(2),Q(d_(3,1,e.params))}}function xE(e,t){if(e&1&&(Z(0),V(1,bE,4,3)),e&2){let e=X(),t=X();$(` Matches `,t.chainText(e),` `),B(),H(t.hasKeys(e.params)?1:-1)}}function SE(e,t){e&1&&Z(0),e&2&&$(` Nearest: `,X(2).nearest.join(`, `),` `)}function CE(e,t){if(e&1&&(Z(0,` Matches no route (NG04002). `),V(1,SE,1,1)),e&2){let e=X();B(),H(e.nearest.length?1:-1)}}function wE(e,t){if(e&1&&(q(0,`div`,8),Z(1),J()),e&2){let e=t.$implicit;B(),Q(e)}}function TE(e,t){if(e&1&&(q(0,`div`,5),V(1,xE,2,2)(2,CE,2,1),U(3,wE,2,1,`div`,8,kh),J()),e&2){let e=t;B(),H(e.matched?1:2),B(2),W(e.notes)}}function EE(e,t){if(e&1&&(q(0,`p`,6),Z(1),J()),e&2){let e=X();B(),Q(e.message())}}function DE(e,t){if(e&1&&(q(0,`p`,8),Z(1),J()),e&2){let e=X();B(),$(` `,e.page().setup?.mode===`events-only`?`This build has no debug utils, so the live config cannot be read.`:`The page has not reported its route config yet.`,` `)}}function OE(e,t){e&1&&(q(0,`span`,14),Z(1,`active`),J())}function kE(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=X().$implicit;B(),$(`lazy `,e.node.lazy)}}function AE(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=X().$implicit;B(),$(`outlet `,e.node.outlet)}}function jE(e,t){if(e&1&&(Z(0,` redirect → `),q(1,`code`),Z(2),J()),e&2){let e=X().$implicit;B(2),Q(e.node.redirectTo)}}function ME(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` `,e.node.component??(e.node.lazy===`unloaded`?`lazy, not loaded yet`:e.node.kind),` `)}}function NE(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=t.$implicit;B(),Q(e)}}function PE(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=t.$implicit;B(),$(`resolve `,e)}}function FE(e,t){if(e&1){let e=Yh();q(0,`input`,18),Y(`input`,function(t){let n=bo(e).$implicit,r=X(2).$implicit;return xo(X(2).setParam(r.node.id,n,t.target.value))}),J()}if(e&2){let e=t.$implicit,n=X(2).$implicit;Xh(`placeholder`,e),vh(`aria-label`,e+` for `+n.node.fullPath)}}function IE(e,t){if(e&1){let e=Yh();U(0,FE,1,2,`input`,17,kh),q(2,`button`,4),Y(`click`,function(){bo(e);let t=X().$implicit;return xo(X(2).navigate(t.node))}),Z(3,` Go `),J()}if(e&2){let e=X().$implicit;W(X(2).params(e.node)),B(2),vh(`aria-label`,`Navigate to `+e.node.fullPath)}}function LE(e,t){if(e&1){let e=Yh();q(0,`button`,4),Y(`click`,function(){bo(e);let t=X().$implicit;return xo(X(2).resolveLazy(t.node))}),Z(1,` Read lazy `),J()}if(e&2){let e=X().$implicit;vh(`aria-label`,`Read lazy routes of `+e.node.fullPath)}}function RE(e,t){if(e&1&&(q(0,`tr`)(1,`td`,13),Z(2),V(3,OE,2,0,`span`,14),V(4,kE,2,1,`span`,14),V(5,AE,2,1,`span`,14),J(),q(6,`td`),V(7,jE,3,1)(8,ME,1,1),J(),q(9,`td`),U(10,NE,2,1,`span`,14,kh),U(12,PE,2,1,`span`,14,kh),J(),q(14,`td`),Z(15),J(),q(16,`td`,15),V(17,IE,4,1),V(18,LE,2,1,`button`,16),J()()),e&2){let e=t.$implicit,n=X(2);Ag(`active`,n.isActive(e.node)),B(),kg(`padding-left`,12+e.depth*16,`px`),B(),$(` `,e.node.fullPath,` `),B(),H(n.isActive(e.node)?3:-1),B(),H(e.node.lazy?4:-1),B(),H(e.node.outlet?5:-1),B(2),H(e.node.redirectTo===void 0?8:7),B(3),W(n.guardList(e.node)),B(2),W(e.node.resolvers??i_(12,vE)),B(3),Q(e.node.title??``),B(2),H(n.canNavigate(e.node)?17:-1),B(),H(e.node.kind===`lazy`&&e.node.lazy===`unloaded`?18:-1)}}function zE(e,t){if(e&1&&(q(0,`p`,8),Z(1),J(),q(2,`div`,9)(3,`table`)(4,`thead`)(5,`tr`)(6,`th`,10),Z(7,`Path`),J(),q(8,`th`,10),Z(9,`Target`),J(),q(10,`th`,10),Z(11,`Guards and resolvers`),J(),q(12,`th`,10),Z(13,`Title`),J(),q(14,`th`,10)(15,`span`,11),Z(16,`Actions`),J()()()(),q(17,`tbody`),U(18,RE,19,13,`tr`,12,yE),J()()()),e&2){let e=X();B(),t_(` Generation `,e.page().generation,` · `,e.rows().length,` route(s). Lazy routes show their children once loaded. `),B(17),W(e.rows())}}var BE=class e{page=k_.required();rpc=k_(null);filter=L(``);testUrl=L(``);match=L(null);message=L(``);paramValues=new Map;active=b_(()=>new Set(this.page().activeIds??[]));rows=b_(()=>{let e=this.filter().toLowerCase(),t=[],n=(r,i)=>{for(let a of r)(!e||a.fullPath.toLowerCase().includes(e)||a.component?.toLowerCase().includes(e))&&t.push({node:a,depth:i}),a.children&&n(a.children,i+1)};return n(this.page().config??[],0),t});hasKeys(e){return Object.keys(e).length>0}isActive(e){return this.active().has(e.id)}guardList(e){return Object.entries(e.guards??{}).flatMap(([e,t])=>t.map(t=>`${e} ${t}`))}params(e){return(e.fullPath.match(/:([A-Za-z0-9_]+)/g)??[]).map(e=>e.slice(1))}canNavigate(e){return e.redirectTo===void 0&&!e.outlet&&!e.fullPath.includes(`**`)&&(!!e.component||e.kind===`component`||e.kind===`lazy`)}setParam(e,t,n){this.paramValues.set(e,{...this.paramValues.get(e),[t]:n})}chainText(e){return e.chain.map(e=>e.fullPath).join(` → `)}async predict(){let e=this.testUrl().trim();e&&this.match.set(await Fw(this.rpc(),`router-match`,{pageId:this.page().pageId,url:e}))}async probe(){let e=this.testUrl().trim();if(!e)return;this.message.set(`Running the real matcher in the app…`);let t=await Iw(this.rpc(),this.page().pageId,{action:`probe`,url:e});if(!t||t.error){this.message.set(String(t?.error??`Probe failed.`));return}this.message.set(t.matched?`The app matched ${e} (see the probe entry in Navigations).`:`The app did not match ${e}: ${String(t.reason??``)}`)}async navigate(e){let t=this.paramValues.get(e.id)??{};this.message.set(`Navigating to ${e.fullPath}…`);let n=await Iw(this.rpc(),this.page().pageId,{action:`navigate`,pattern:e.fullPath,params:t});this.message.set(!n||n.error?String(n?.error??`Navigation failed.`):`Navigation #${n.id}: ${n.outcome}${n.finalUrl?` at ${n.finalUrl}`:``}.`)}async resolveLazy(e){let t=await Iw(this.rpc(),this.page().pageId,{action:`resolve-lazy`,id:e.id});if(!t||t.error){this.message.set(String(t?.error??`Could not read the lazy routes.`));return}let n=t.routes??[];this.message.set(`${e.fullPath} declares ${n.length} route(s): ${n.map(e=>`/${e.path}`).join(`, `)}. The router loads them for real on the first navigation that needs them.`)}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-route-tree`]],inputs:{page:[1,`page`],rpc:[1,`rpc`]},decls:13,vars:5,consts:[[1,`test`,3,`submit`],[`for`,`test-url`],[`id`,`test-url`,`type`,`text`,`placeholder`,`/users/42`,1,`field`,3,`input`,`value`],[`type`,`submit`,1,`small`],[`type`,`button`,1,`small`,3,`click`],[`role`,`status`,1,`result`],[`role`,`status`,1,`muted`],[`type`,`text`,`aria-label`,`Filter routes`,`placeholder`,`Filter by path or component`,1,`field`,`filter`,3,`input`,`value`],[1,`muted`],[`role`,`region`,`aria-label`,`Live route config`,`tabindex`,`0`,1,`table-scroll`],[`scope`,`col`],[1,`visually-hidden`],[3,`active`],[1,`path`],[1,`tag`],[1,`actions`],[`type`,`button`,1,`small`],[`type`,`text`,1,`field`,`param`,3,`placeholder`],[`type`,`text`,1,`field`,`param`,3,`input`,`placeholder`]],template:function(e,t){if(e&1&&(q(0,`form`,0),Y(`submit`,function(e){return e.preventDefault(),t.predict()}),q(1,`label`,1),Z(2,`Test a URL`),J(),q(3,`input`,2),Y(`input`,function(e){return t.testUrl.set(e.target.value)}),J(),q(4,`button`,3),Z(5,`Predict`),J(),q(6,`button`,4),Y(`click`,function(){return t.probe()}),Z(7,`Probe in app`),J()(),V(8,TE,5,1,`div`,5),V(9,EE,2,1,`p`,6),q(10,`input`,7),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),V(11,DE,2,1,`p`,8)(12,zE,20,2)),e&2){let e;B(3),Xh(`value`,t.testUrl()),B(5),H((e=t.match())?8:-1,e),B(),H(t.message()?9:-1),B(),Xh(`value`,t.filter()),B(),H(t.page().config?12:11)}},dependencies:[Wv],styles:[`.muted[_ngcontent-%COMP%] { - color: #a1a1aa; - font-size: 13px; - } - code[_ngcontent-%COMP%] { - font-family: monospace; - color: #d4d4d8; - overflow-wrap: anywhere; - } - .tag[_ngcontent-%COMP%] { - display: inline-block; - margin: 0 4px 4px 0; - padding: 1px 6px; - border: 1px solid #52525b; - border-radius: 4px; - color: #d4d4d8; - font-size: 11px; - font-family: monospace; - } - .badge[_ngcontent-%COMP%] { - padding: 1px 6px; - border-radius: 4px; - background: #3f3f46; - color: #e4e4e7; - font-size: 11px; - font-weight: 600; - } - .badge[data-tone='good'][_ngcontent-%COMP%] { - background: #14532d; - color: #bbf7d0; - } - .badge[data-tone='warn'][_ngcontent-%COMP%] { - background: #713f12; - color: #fef08a; - } - .badge[data-tone='bad'][_ngcontent-%COMP%] { - background: #7f1d1d; - color: #fecaca; - } - button.small[_ngcontent-%COMP%] { - padding: 3px 10px; - background: #3f3f46; - border: none; - border-radius: 6px; - color: #e4e4e7; - cursor: pointer; - font-size: 12px; - } - button.small[_ngcontent-%COMP%]:hover { - background: #52525b; - } - button.small[_ngcontent-%COMP%]:focus-visible, - input[_ngcontent-%COMP%]:focus-visible, - select[_ngcontent-%COMP%]:focus-visible, - .table-scroll[_ngcontent-%COMP%]:focus-visible { - outline: 2px solid var(--%NS%accent); - outline-offset: 2px; - } - input.field[_ngcontent-%COMP%] { - padding: 6px 10px; - background: #18181b; - border: 1px solid #52525b; - border-radius: 6px; - color: #e4e4e7; - font-size: 13px; - } - .table-scroll[_ngcontent-%COMP%] { - overflow-x: auto; - } - table[_ngcontent-%COMP%] { - width: 100%; - border-collapse: collapse; - font-size: 13px; - } - th[_ngcontent-%COMP%] { - text-align: left; - padding: 6px 12px; - color: #a1a1aa; - font-size: 12px; - border-bottom: 1px solid #27272a; - } - td[_ngcontent-%COMP%] { - padding: 8px 12px; - border-bottom: 1px solid #1e1e22; - vertical-align: top; - } - h3[_ngcontent-%COMP%] { - margin: 0 0 8px; - font-size: 14px; - color: #e4e4e7; - } - .visually-hidden[_ngcontent-%COMP%] { - position: absolute; - width: 1px; - height: 1px; - overflow: hidden; - clip-path: inset(50%); - white-space: nowrap; - } - - [_nghost-%COMP%] { - display: grid; - gap: 10px; - } - .test[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 8px; - align-items: center; - font-size: 13px; - color: #e4e4e7; - } - .result[_ngcontent-%COMP%] { - padding: 8px 10px; - border: 1px solid #27272a; - border-radius: 6px; - font-size: 13px; - color: #e4e4e7; - } - .filter[_ngcontent-%COMP%] { - max-width: 320px; - } - .path[_ngcontent-%COMP%] { - font-family: monospace; - color: var(--%NS%accent); - white-space: nowrap; - } - tr.active[_ngcontent-%COMP%] td[_ngcontent-%COMP%] { - background: #1c1917; - } - .actions[_ngcontent-%COMP%] { - white-space: nowrap; - } - .param[_ngcontent-%COMP%] { - width: 80px; - margin-right: 4px; - }`]})},VE=(e,t)=>t.id,HE=(e,t)=>t.pageId;function UE(e,t){e&1&&(G(0,`p`,0),Z(1,`Could not load the live router state.`),K())}function WE(e,t){e&1&&(G(0,`p`,0),Z(1,`Loading the live router state…`),K())}function GE(e,t){if(e&1&&(G(0,`option`,8),Z(1),K()),e&2){let e=t.$implicit,n=X(2);Rh(`value`,e.pageId)(`selected`,e.pageId===n.pageId),B(),t_(` `,e.snapshot?.url??e.pageId,` (`,e.pageId,`) `)}}function KE(e,t){if(e&1){let e=Yh();G(0,`label`,1),Z(1,` Page `),G(2,`select`,7),sg(`change`,function(t){return bo(e),xo(X(2).pickPage(t))}),U(3,GE,2,4,`option`,8,HE),K()()}if(e&2){let e=X(2);B(3),W(e.pages())}}function qE(e,t){if(e&1&&(G(0,`span`,10),Z(1),K()),e&2){let e=X(3);vh(`aria-label`,e.problems()+` problem navigations`),B(),Q(e.problems())}}function JE(e,t){if(e&1){let e=Yh();G(0,`button`,9),sg(`click`,function(){let t=bo(e).$implicit;return xo(X(2).selected.set(t.id))}),Z(1),V(2,qE,2,2,`span`,10),K()}if(e&2){let e=t.$implicit,n=X(2);Rh(`id`,`router-tab-`+e.id),vh(`aria-selected`,e.id===n.selected())(`aria-controls`,`router-panel-`+e.id)(`tabindex`,e.id===n.selected()?0:-1),B(),$(` `,e.label,` `),B(),H(e.id===`navigations`&&n.problems()>0?2:-1)}}function YE(e,t){if(e&1&&Vh(0,`app-route-current`,5),e&2){let e=X(),t=X();Rh(`page`,e)(`rpc`,t.rpc())}}function XE(e,t){if(e&1&&Vh(0,`app-route-timeline`,5),e&2){let e=X(),t=X();Rh(`page`,e)(`rpc`,t.rpc())}}function ZE(e,t){if(e&1&&Vh(0,`app-route-tree`,5),e&2){let e=X(),t=X();Rh(`page`,e)(`rpc`,t.rpc())}}function QE(e,t){e&1&&Vh(0,`app-route-setup`,6),e&2&&Rh(`page`,X())}function $E(e,t){if(e&1&&Vh(0,`app-route-lint`,5),e&2){let e=X(),t=X();Rh(`page`,e)(`rpc`,t.rpc())}}function eD(e,t){if(e&1){let e=Yh();V(0,KE,5,0,`label`,1),G(1,`div`,2),sg(`keydown`,function(t){return bo(e),xo(X().onKey(t))}),U(2,JE,3,6,`button`,3,VE),K(),G(4,`div`,4),V(5,YE,1,2,`app-route-current`,5)(6,XE,1,2,`app-route-timeline`,5)(7,ZE,1,2,`app-route-tree`,5)(8,QE,1,1,`app-route-setup`,6)(9,$E,1,2,`app-route-lint`,5),K()}if(e&2){let e,t=X();H(t.pages().length>1?0:-1),B(2),W(t.tabs),B(2),Rh(`id`,`router-panel-`+t.selected()),vh(`aria-labelledby`,`router-tab-`+t.selected()),B(),H((e=t.selected())===`current`?5:e===`navigations`?6:e===`routes`?7:e===`setup`?8:e===`lint`?9:-1)}}function tD(e,t){e&1&&(G(0,`p`,0),Z(1,`No page is reporting router state yet. Open the app in a browser.`),K())}var nD=[{id:`current`,label:`Current`},{id:`navigations`,label:`Navigations`},{id:`routes`,label:`Routes`},{id:`setup`,label:`Setup`},{id:`lint`,label:`Lint`}],rD=class e{rpc=k_(null);tabs=nD;selected=L(`current`);pages=L([]);loading=L(!0);failed=L(!1);pageId=C_({source:this.pages,computation:(e,t)=>t?.value&&e.some(e=>e.pageId===t.value)?t.value:e.find(e=>e.snapshot)?.pageId??e[0]?.pageId??null});unsubscribe=null;destroyRef=P(us);page=b_(()=>{let e=this.pages();return e.find(e=>e.pageId===this.pageId())??e[0]??null});problems=b_(()=>(this.page()?.navigations??[]).filter(e=>!e.probe&&[`failed`,`cancelled`,`redirected`].includes(e.outcome)).length);constructor(){Zs(()=>{let e=this.rpc();e&&this.load(e)}),this.destroyRef.onDestroy(()=>this.unsubscribe?.())}async load(e){this.loading.set(!0),this.failed.set(!1);try{let t=await e.scope(`ng-devtools`).rpc.sharedState(`router`);if(this.destroyRef.destroyed)return;let n=e=>{this.pages.set(e?.pages??[])};n(t.value()),this.unsubscribe?.(),this.unsubscribe=t.on(`updated`,n)}catch{this.failed.set(!0)}finally{this.loading.set(!1)}}pickPage(e){this.pageId.set(e.target.value)}onKey(e){let t=this.tabs.map(e=>e.id),n=t.indexOf(this.selected()),r=n;if(e.key===`ArrowRight`)r=(n+1)%t.length;else if(e.key===`ArrowLeft`)r=(n-1+t.length)%t.length;else if(e.key===`Home`)r=0;else if(e.key===`End`)r=t.length-1;else return;e.preventDefault(),this.selected.set(t[r]);let i=e.currentTarget;queueMicrotask(()=>i.querySelector(`#router-tab-${t[r]}`)?.focus())}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-live-route`]],inputs:{rpc:[1,`rpc`]},decls:4,vars:1,consts:[[1,`muted`],[1,`page-pick`],[`role`,`tablist`,`aria-label`,`Router views`,1,`tabs`,3,`keydown`],[`type`,`button`,`role`,`tab`,3,`id`],[`role`,`tabpanel`,1,`panel`,3,`id`],[3,`page`,`rpc`],[3,`page`],[3,`change`],[3,`value`,`selected`],[`type`,`button`,`role`,`tab`,3,`click`,`id`],[1,`count`]],template:function(e,t){if(e&1&&V(0,UE,2,0,`p`,0)(1,WE,2,0,`p`,0)(2,eD,10,4)(3,tD,2,0,`p`,0),e&2){let e;H(t.failed()?0:t.loading()?1:(e=t.page())?2:3,e)}},dependencies:[mT,yT,jT,_E,BE],styles:[`[_nghost-%COMP%] { - display: grid; - gap: 12px; - margin-bottom: 28px; - } - .muted[_ngcontent-%COMP%] { - color: #a1a1aa; - font-size: 13px; - } - .page-pick[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 8px; - align-items: center; - font-size: 13px; - color: #d4d4d8; - } - select[_ngcontent-%COMP%] { - max-width: 100%; - min-width: 0; - padding: 4px 8px; - background: #18181b; - border: 1px solid #52525b; - border-radius: 6px; - color: #e4e4e7; - } - .tabs[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 4px; - border-bottom: 1px solid #27272a; - } - [role='tab'][_ngcontent-%COMP%] { - padding: 6px 12px; - background: none; - border: none; - border-bottom: 2px solid transparent; - color: #a1a1aa; - cursor: pointer; - font-size: 13px; - } - [role='tab'][aria-selected='true'][_ngcontent-%COMP%] { - color: #e4e4e7; - border-bottom-color: var(--%NS%accent); - } - [role='tab'][_ngcontent-%COMP%]:focus-visible, - select[_ngcontent-%COMP%]:focus-visible { - outline: 2px solid var(--%NS%accent); - outline-offset: 2px; - } - .count[_ngcontent-%COMP%] { - margin-left: 4px; - padding: 0 5px; - border-radius: 8px; - background: #7f1d1d; - color: #fecaca; - font-size: 11px; - }`]})};function iD(e,t){e&1&&(G(0,`p`,5),Z(1,`Scanning routes…`),K())}function aD(e,t){e&1&&(G(0,`p`,5),Z(1,`No routes found.`),K())}function oD(e,t){if(e&1&&(G(0,`span`,9),Z(1),K()),e&2){let e=X().$implicit;B(),$(`➜ `,e.redirectTo)}}function sD(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` `,e.component??`—`,` `)}}function cD(e,t){if(e&1&&(G(0,`tr`)(1,`td`,8),Z(2),K(),G(3,`td`),V(4,oD,2,1,`span`,9)(5,sD,1,1),K(),G(6,`td`),Z(7),K(),G(8,`td`,10),Z(9),K(),G(10,`td`),Z(11),K()()),e&2){let e=t.$implicit;B(2),$(`/`,e.path),B(2),H(e.redirectTo===void 0?5:4),B(3),Q(e.title??`—`),B(2),Q(e.file),B(2),Q(e.hasChildren?`Yes`:`—`)}}function lD(e,t){if(e&1&&(G(0,`table`,6)(1,`thead`)(2,`tr`)(3,`th`,7),Z(4,`Path`),K(),G(5,`th`,7),Z(6,`Component / Target`),K(),G(7,`th`,7),Z(8,`Title`),K(),G(9,`th`,7),Z(10,`File`),K(),G(11,`th`,7),Z(12,`Children`),K()()(),G(13,`tbody`),U(14,cD,12,5,`tr`,null,Oh),K()()),e&2){let e=X();B(14),W(e.filtered())}}var uD=class e{rpc=k_(null);routes=L([]);filter=L(``);loading=L(!1);filtered=b_(()=>{let e=this.filter().toLowerCase().trim(),t=this.routes();return e?t.filter(t=>t.path.toLowerCase().includes(e)||t.component&&t.component.toLowerCase().includes(e)||t.redirectTo&&t.redirectTo.toLowerCase().includes(e)||t.title&&t.title.toLowerCase().includes(e)||t.file.toLowerCase().includes(e)):t});constructor(){Zs(()=>{this.rpc()&&this.refresh()})}onFilterInput(e){let t=e.target;this.filter.set(t?.value??``)}async refresh(){let e=this.rpc();if(e){this.loading.set(!0);try{let t=await e.scope(`ng-devtools`).rpc.call(`get-routes`);this.routes.set(t)}finally{this.loading.set(!1)}}}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-route-inspector`]],inputs:{rpc:[1,`rpc`]},decls:10,vars:3,consts:[[3,`rpc`],[1,`config-heading`],[1,`toolbar`],[`type`,`text`,`aria-label`,`Filter routes`,`placeholder`,`Filter routes…`,3,`input`,`value`],[`type`,`button`,3,`click`],[1,`muted`],[`role`,`table`],[`scope`,`col`],[1,`path`],[1,`redirect`],[1,`file`]],template:function(e,t){e&1&&(Vh(0,`app-live-route`,0),G(1,`h2`,1),Z(2,`Route config`),K(),G(3,`div`,2)(4,`input`,3),sg(`input`,function(e){return t.onFilterInput(e)}),K(),G(5,`button`,4),sg(`click`,function(){return t.refresh()}),Z(6,`Refresh`),K()(),V(7,iD,2,0,`p`,5)(8,aD,2,0,`p`,5)(9,lD,16,0,`table`,6)),e&2&&(Rh(`rpc`,t.rpc()),B(4),Rh(`value`,t.filter()),B(3),H(t.loading()?7:t.filtered().length===0?8:9))},dependencies:[rD],styles:[`.config-heading[_ngcontent-%COMP%] { - margin: 0 0 8px; - font-size: 15px; - color: #e4e4e7; - } - .toolbar[_ngcontent-%COMP%] { - display: flex; - gap: 8px; - margin-bottom: 16px; - } - input[_ngcontent-%COMP%] { - flex: 1; - padding: 8px 12px; - background: #18181b; - border: 1px solid #27272a; - border-radius: 6px; - color: #e4e4e7; - font-size: 14px; - outline: none; - } - input[_ngcontent-%COMP%]:focus { - border-color: var(--%NS%accent); - } - button[_ngcontent-%COMP%] { - padding: 8px 16px; - background: #3f3f46; - border: none; - border-radius: 6px; - color: #e4e4e7; - cursor: pointer; - font-size: 13px; - } - button[_ngcontent-%COMP%]:hover { - background: #52525b; - } - .muted[_ngcontent-%COMP%] { - color: #a1a1aa; - font-size: 14px; - } - table[_ngcontent-%COMP%] { - width: 100%; - border-collapse: collapse; - font-size: 14px; - } - thead[_ngcontent-%COMP%] { - position: sticky; - top: 0; - } - th[_ngcontent-%COMP%] { - text-align: left; - padding: 8px 12px; - background: #18181b; - color: #a1a1aa; - font-size: 12px; - text-transform: uppercase; - letter-spacing: 0.05em; - border-bottom: 1px solid #27272a; - } - td[_ngcontent-%COMP%] { - padding: 10px 12px; - border-bottom: 1px solid #1e1e22; - } - tr[_ngcontent-%COMP%]:hover td[_ngcontent-%COMP%] { - background: #18181b; - } - .path[_ngcontent-%COMP%] { - font-family: monospace; - color: var(--%NS%accent); - font-weight: 500; - } - .redirect[_ngcontent-%COMP%] { - font-family: monospace; - color: #38bdf8; - } - .file[_ngcontent-%COMP%] { - font-size: 12px; - color: #a1a1aa; - }`]})},dD=(e,t)=>t.name+t.file+t.line,fD=(e,t)=>t.kind,pD=(e,t)=>t.id,mD=(e,t)=>t.epoch;function hD(e,t){e&1&&(q(0,`div`,3)(1,`p`,4),Z(2,`No signals found.`),J(),q(3,`p`,5),Z(4,` No signal(), computed(), effect() calls found in source. Runtime graph requires Angular 19+ with the overlay connected. `),J()())}function gD(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · in <`,e.component,`> `)}}function _D(e,t){if(e&1&&(q(0,`div`,8)(1,`div`,9)(2,`span`,10),Z(3),J(),q(4,`span`,11),Z(5),J()(),q(6,`div`,12),Z(7),V(8,gD,1,1),J()()),e&2){let e=t.$implicit,n=X(2);B(2),kg(`background`,n.kindColor(e.kind)),B(),Q(e.kind),B(2),Q(e.name),B(2),t_(` `,e.file,`:`,e.line,` `),B(),H(e.component?8:-1)}}function vD(e,t){if(e&1&&(q(0,`p`,6),Z(1,`Signals from source scan (static analysis):`),J(),q(2,`div`,7),U(3,_D,9,7,`div`,8,dD),J()),e&2){let e=X();B(3),W(e.filteredSourceSignals())}}function yD(e,t){if(e&1&&(q(0,`span`,14),Hh(1,`span`,16),Z(2),J()),e&2){let e=t.$implicit;B(),kg(`background`,e.color),B(),$(` `,e.kind,` `)}}function bD(e,t){e&1&&(q(0,`span`,18),Z(1,`watching`),J())}function xD(e,t){if(e&1&&(q(0,`span`,19),Z(1),J()),e&2){let e=t;B(),t_(``,e,` `,e===1?`change`:`changes`)}}function SD(e,t){if(e&1&&(q(0,`span`,20),Z(1),l_(2,`json`),J()),e&2){let e=X().$implicit;B(),Q(d_(2,1,e.value))}}function CD(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · Deps: `,X(2).getDependencies(e).length,` `)}}function wD(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · Consumers: `,X(2).getConsumers(e).length,` `)}}function TD(e,t){if(e&1&&(q(0,`dt`),Z(1,`Value`),J(),q(2,`dd`)(3,`pre`),Z(4),l_(5,`json`),J()()),e&2){let e=X(4);B(4),Q(d_(5,1,e.selectedNode().value))}}function ED(e,t){if(e&1&&(q(0,`li`)(1,`span`,22),Z(2),J(),Z(3),J()),e&2){let e=t.$implicit,n=X(5);B(),kg(`background`,n.kindColor(e.kind)),B(),Q(e.kind),B(),$(` `,e.label??e.id,` `)}}function DD(e,t){if(e&1&&(q(0,`h4`),Z(1,`Dependencies (producers)`),J(),q(2,`ul`),U(3,ED,4,4,`li`,null,pD),J()),e&2){let e=X(4);B(3),W(e.getDependencies(e.selectedNode()))}}function OD(e,t){if(e&1&&(q(0,`li`)(1,`span`,22),Z(2),J(),Z(3),J()),e&2){let e=t.$implicit,n=X(5);B(),kg(`background`,n.kindColor(e.kind)),B(),Q(e.kind),B(),$(` `,e.label??e.id,` `)}}function kD(e,t){if(e&1&&(q(0,`h4`),Z(1,`Consumers`),J(),q(2,`ul`),U(3,OD,4,4,`li`,null,pD),J()),e&2){let e=X(4);B(3),W(e.getConsumers(e.selectedNode()))}}function AD(e,t){if(e&1&&(q(0,`span`,28),Z(1),J()),e&2){let e=X().$implicit;B(),$(``,e.missed,` earlier not captured`)}}function jD(e,t){if(e&1&&(q(0,`li`)(1,`span`,26)(2,`time`),Z(3),l_(4,`date`),J(),q(5,`span`,27),Z(6),J(),q(7,`span`),Z(8),J(),V(9,AD,2,1,`span`,28),J(),q(10,`pre`),Z(11),l_(12,`json`),J()()),e&2){let e=t.$implicit,n=X(5);B(3),Q(f_(4,7,e.at,`HH:mm:ss.SSS`)),B(2),jg(`source-`+e.source),B(),Q(n.sourceLabel(e.source)),B(2),$(`epoch `,e.epoch),B(),H(e.missed?9:-1),B(2),Q(d_(12,10,e.value))}}function MD(e,t){if(e&1&&(q(0,`h4`,23),Z(1,`Value history`),J(),q(2,`p`,24),Z(3),J(),q(4,`ol`,25),U(5,jD,13,12,`li`,null,mD),J()),e&2){let e=X(4);B(3),$(` `,e.changeCount(e.selectedNode().id),` changes recorded, newest first. `),B(2),W(e.selectedHistory())}}function ND(e,t){if(e&1&&(q(0,`div`,21)(1,`h3`),Z(2),J(),q(3,`dl`)(4,`dt`),Z(5,`Kind`),J(),q(6,`dd`),Z(7),J(),q(8,`dt`),Z(9,`Epoch`),J(),q(10,`dd`),Z(11),J(),V(12,TD,6,3),J(),V(13,DD,5,0),V(14,kD,5,0),V(15,MD,7,1),J()),e&2){let e=X().$implicit,t=X(2);Xh(`id`,`signal-detail-`+e.id),B(2),Q(t.selectedNode().label??t.selectedNode().id),B(5),Q(t.selectedNode().kind),B(4),Q(t.selectedNode().epoch),B(),H(t.selectedNode().value===void 0?-1:12),B(),H(t.getDependencies(t.selectedNode()).length?13:-1),B(),H(t.getConsumers(t.selectedNode()).length?14:-1),B(),H(t.selectedHistory().length?15:-1)}}function PD(e,t){if(e&1){let e=Yh();q(0,`li`)(1,`button`,17),Y(`click`,function(){let t=bo(e).$implicit;return xo(X(2).selectNode(t))}),q(2,`span`,9)(3,`span`,10),Z(4),J(),q(5,`span`,11),Z(6),J(),V(7,bD,2,0,`span`,18),V(8,xD,2,2,`span`,19),J(),V(9,SD,3,3,`span`,20),q(10,`span`,12),Z(11),V(12,CD,1,1),V(13,wD,1,1),J()(),V(14,ND,16,8,`div`,21),J()}if(e&2){let e,n=t.$implicit,r=X(2);B(),Ag(`selected`,r.selectedId()===n.id),vh(`aria-expanded`,r.selectedId()===n.id)(`aria-controls`,`signal-detail-`+n.id),B(2),kg(`background`,r.kindColor(n.kind)),B(),Q(n.kind),B(2),Q(n.label??`(unnamed)`),B(),H(n.watched?7:-1),B(),H((e=r.changeCount(n.id))?8:-1,e),B(),H(n.value===void 0?-1:9),B(2),$(` Epoch: `,n.epoch,` `),B(),H(r.getDependencies(n).length?12:-1),B(),H(r.getConsumers(n).length?13:-1),B(),H(r.selectedId()===n.id&&r.selectedNode()?14:-1)}}function FD(e,t){if(e&1&&(q(0,`div`,13),U(1,yD,3,3,`span`,14,fD),J(),q(3,`ul`,15),U(4,PD,15,15,`li`,null,pD),J()),e&2){let e=X();B(),W(e.kindLegend),B(3),W(e.filteredNodes())}}var ID={write:`set`,sample:`sampled`,initial:`initial`},LD={signal:`#a78bfa`,computed:`#60a5fa`,linkedSignal:`#34d399`,effect:`#fb923c`,template:`#94a3b8`,afterRenderEffectPhase:`#f472b6`,childSignalProp:`#c084fc`,"input (signal)":`#f59e0b`,"input.required (signal)":`#f59e0b`,"output (signal)":`#ec4899`,"model (signal)":`#14b8a6`,"model.required (signal)":`#14b8a6`,"viewChild (signal)":`#8b5cf6`,"viewChild.required (signal)":`#8b5cf6`,"viewChildren (signal)":`#8b5cf6`,"contentChild (signal)":`#6366f1`,"contentChild.required (signal)":`#6366f1`,"contentChildren (signal)":`#6366f1`,resource:`#06b6d4`,unknown:`#71717a`},RD=class e{rpc=k_(null);graph=L(null);sourceSignals=L([]);filter=L(``);selectedId=L(null);selectedNode=b_(()=>this.graph()?.nodes.find(e=>e.id===this.selectedId())??null);selectedHistory=b_(()=>{let e=this.selectedId();return e?[...this.graph()?.history?.[e]??[]].reverse():[]});kindLegend=Object.entries(LD).map(([e,t])=>({kind:e,color:t}));filteredNodes=b_(()=>{let e=this.graph();if(!e)return[];let t=this.filter().toLowerCase();return(t?e.nodes.filter(e=>(e.label??``).toLowerCase().includes(t)||e.kind.includes(t)):[...e.nodes]).sort((e,t)=>e.id.localeCompare(t.id,void 0,{numeric:!0}))});filteredSourceSignals=b_(()=>{let e=this.filter().toLowerCase(),t=this.sourceSignals();return e?t.filter(t=>t.name.toLowerCase().includes(e)||t.kind.includes(e)||t.file.includes(e)):t});constructor(){Zs(()=>{let e=this.rpc();e&&(this.loadSignalGraph(e),this.loadSourceSignals(e))})}async loadSignalGraph(e){let t=await e.scope(`ng-devtools`).rpc.sharedState(`signal-graph`),n=new URLSearchParams(location.search).get(`pageId`),r=e=>n&&e?.pages?.[n]||e?.graph,i=r(t.value());i&&this.graph.set(i),t.on(`updated`,e=>{let t=r(e);t&&this.graph.set(t)})}async loadSourceSignals(e){let t=e.scope(`ng-devtools`);try{let e=await t.rpc.call(`get-signals`);this.sourceSignals.set(e)}catch{}}selectNode(e){this.selectedId.set(this.selectedId()===e.id?null:e.id)}changeCount(e){return(this.graph()?.history?.[e]??[]).reduce((e,t)=>e+(t.source===`initial`?0:1+(t.missed??0)),0)}sourceLabel(e){return ID[e]}kindColor(e){return LD[e]??LD.unknown}getDependencies(e){let t=this.graph();if(!t)return[];let n=t.nodes.findIndex(t=>t.id===e.id);return t.edges.filter(e=>e.consumer===n).map(e=>t.nodes[e.producer]).filter(Boolean)}getConsumers(e){let t=this.graph();if(!t)return[];let n=t.nodes.findIndex(t=>t.id===e.id);return t.edges.filter(e=>e.producer===n).map(e=>t.nodes[e.consumer]).filter(Boolean)}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-signal-inspector`]],inputs:{rpc:[1,`rpc`]},decls:7,vars:5,consts:[[1,`toolbar`],[`type`,`text`,`placeholder`,`Filter by name or kind…`,3,`input`,`value`],[1,`label`],[1,`empty`],[1,`muted`],[1,`hint`],[1,`source-label`],[1,`nodes`],[1,`node-card`],[1,`node-header`],[1,`kind-badge`],[1,`node-label`],[1,`node-meta`],[1,`legend`],[1,`legend-item`],[`role`,`list`,1,`nodes`],[1,`dot`],[`type`,`button`,1,`node-card`,3,`click`],[1,`watched-badge`],[1,`changed-badge`],[1,`node-value`],[1,`detail-panel`,3,`id`],[1,`kind-badge`,`sm`],[`id`,`value-history-heading`],[`aria-live`,`polite`,1,`history-summary`],[`aria-labelledby`,`value-history-heading`,1,`history`],[1,`history-meta`],[1,`source-tag`],[1,`missed`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`input`,1),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(2,`span`,2),Z(3),J()(),V(4,hD,5,0,`div`,3),V(5,vD,5,0),V(6,FD,6,0)),e&2&&(B(),Xh(`value`,t.filter()),B(2),$(`Component: `,t.graph()?.componentSelector??`—`),B(),H(!t.graph()&&t.sourceSignals().length===0?4:-1),B(),H(!t.graph()&&t.sourceSignals().length>0?5:-1),B(),H(t.graph()?6:-1))},dependencies:[Uv,Wv],styles:[`.toolbar[_ngcontent-%COMP%] { - display: flex; - gap: 12px; - align-items: center; - margin-bottom: 16px; - } - input[_ngcontent-%COMP%] { - flex: 1; - padding: 8px 12px; - background: #18181b; - border: 1px solid #27272a; - border-radius: 6px; - color: #e4e4e7; - font-size: 14px; - outline: none; - } - input[_ngcontent-%COMP%]:focus { - border-color: var(--%NS%accent); - } - .label[_ngcontent-%COMP%] { - font-size: 13px; - color: #71717a; - white-space: nowrap; - } - .empty[_ngcontent-%COMP%] { - text-align: center; - padding: 48px 16px; - } - .muted[_ngcontent-%COMP%] { - color: #71717a; - font-size: 14px; - } - .hint[_ngcontent-%COMP%] { - color: #52525b; - font-size: 12px; - margin-top: 8px; - } - .source-label[_ngcontent-%COMP%] { - font-size: 13px; - color: #71717a; - margin-bottom: 12px; - } - .legend[_ngcontent-%COMP%] { - display: flex; - gap: 12px; - flex-wrap: wrap; - margin-bottom: 16px; - } - .legend-item[_ngcontent-%COMP%] { - display: flex; - align-items: center; - gap: 4px; - font-size: 12px; - color: #a1a1aa; - } - .dot[_ngcontent-%COMP%] { - width: 8px; - height: 8px; - border-radius: 50%; - } - .nodes[_ngcontent-%COMP%] { - display: flex; - flex-direction: column; - gap: 8px; - list-style: none; - padding: 0; - margin: 0; - } - .node-card[_ngcontent-%COMP%] { - display: block; - width: 100%; - text-align: left; - font: inherit; - color: inherit; - background: #18181b; - border: 1px solid #27272a; - border-radius: 8px; - padding: 12px 16px; - cursor: pointer; - transition: border-color 0.15s; - } - .node-card[_ngcontent-%COMP%]:hover { - border-color: #3f3f46; - } - .node-card[_ngcontent-%COMP%]:focus-visible { - outline: 2px solid var(--%NS%accent); - outline-offset: 2px; - } - .node-value[_ngcontent-%COMP%], - .node-meta[_ngcontent-%COMP%] { - display: block; - } - .changed-badge[_ngcontent-%COMP%] { - font-size: 10px; - padding: 1px 6px; - border-radius: 4px; - background: #422006; - color: #fbbf24; - } - .history-summary[_ngcontent-%COMP%] { - font-size: 12px; - color: #a1a1aa; - margin: 0 0 6px; - } - .history[_ngcontent-%COMP%] { - list-style: none; - padding: 0; - margin: 0; - max-height: 320px; - overflow: auto; - } - .history[_ngcontent-%COMP%] li[_ngcontent-%COMP%] { - display: block; - padding: 6px 0; - border-top: 1px solid #27272a; - } - .history-meta[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 8px; - align-items: center; - font-size: 11px; - color: #a1a1aa; - margin-bottom: 2px; - } - .source-tag[_ngcontent-%COMP%] { - padding: 0 5px; - border-radius: 3px; - background: #27272a; - color: #e4e4e7; - } - .source-write[_ngcontent-%COMP%] { - background: #1e3a8a; - color: #dbeafe; - } - .missed[_ngcontent-%COMP%] { - color: #fbbf24; - } - .node-card.selected[_ngcontent-%COMP%] { - border-color: var(--%NS%accent); - } - .node-header[_ngcontent-%COMP%] { - display: flex; - align-items: center; - gap: 8px; - } - .kind-badge[_ngcontent-%COMP%] { - font-size: 11px; - padding: 2px 8px; - border-radius: 4px; - color: #fff; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; - } - .kind-badge.sm[_ngcontent-%COMP%] { - font-size: 10px; - padding: 1px 5px; - } - .node-label[_ngcontent-%COMP%] { - font-family: monospace; - font-size: 14px; - color: #e4e4e7; - } - .watched-badge[_ngcontent-%COMP%] { - font-size: 10px; - padding: 1px 6px; - border-radius: 4px; - background: #14532d; - color: #4ade80; - } - .node-value[_ngcontent-%COMP%] { - font-family: monospace; - font-size: 12px; - color: #a1a1aa; - margin-top: 4px; - max-height: 40px; - overflow: hidden; - } - .node-meta[_ngcontent-%COMP%] { - font-size: 11px; - color: #52525b; - margin-top: 4px; - } - .detail-panel[_ngcontent-%COMP%] { - margin-top: 16px; - padding: 16px; - background: #18181b; - border: 1px solid #27272a; - border-radius: 8px; - } - .detail-panel[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { - font-family: monospace; - color: var(--%NS%accent); - margin-bottom: 12px; - } - .detail-panel[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] { - font-size: 12px; - color: #71717a; - margin: 12px 0 4px; - text-transform: uppercase; - letter-spacing: 0.05em; - } - dl[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: auto 1fr; - gap: 4px 12px; - font-size: 13px; - } - dt[_ngcontent-%COMP%] { - color: #71717a; - } - dd[_ngcontent-%COMP%] { - color: #e4e4e7; - } - pre[_ngcontent-%COMP%] { - font-size: 12px; - white-space: pre-wrap; - margin: 0; - } - ul[_ngcontent-%COMP%] { - list-style: none; - padding: 0; - font-size: 13px; - } - li[_ngcontent-%COMP%] { - padding: 2px 0; - color: #a1a1aa; - display: flex; - align-items: center; - gap: 6px; - }`]})},zD=(e,t)=>t.type,BD=(e,t)=>t.token+t.file+t.line,VD=(e,t)=>t.injector.id,HD=(e,t)=>t.node.injector.id,UD=(e,t)=>t.token;function WD(e,t){e&1&&(q(0,`div`,4)(1,`p`,5),Z(2,`No DI data found.`),J(),q(3,`p`,6),Z(4,` No providers, injectables, or inject() calls found. Runtime tree requires Angular 17+ with the overlay connected. `),J()())}function GD(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=X().$implicit;B(),$(`providedIn: `,e.providedIn)}}function KD(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · as `,e.source,` `)}}function qD(e,t){if(e&1&&(q(0,`div`,11)(1,`div`,12)(2,`span`,13),Z(3),J(),V(4,GD,2,1,`span`,14),J(),q(5,`div`,15),Z(6),V(7,KD,1,1),J()()),e&2){let e=t.$implicit;B(3),Q(e.token),B(),H(e.providedIn?4:-1),B(2),t_(` `,e.file,`:`,e.line,` `),B(),H(e.source!==`class`&&e.source!==`providers array`?7:-1)}}function JD(e,t){if(e&1&&(q(0,`div`,9)(1,`h3`),Z(2),J(),q(3,`div`,10),U(4,qD,8,5,`div`,11,BD),J()()),e&2){let e=t.$implicit;B(2),t_(``,e.label,` (`,e.items.length,`)`),B(2),W(e.items)}}function YD(e,t){if(e&1&&(q(0,`p`,7),Z(1,`DI from source scan (static analysis):`),J(),q(2,`div`,8),U(3,JD,6,2,`div`,9,zD),J()),e&2){let e=X();B(3),W(e.groupedProviders())}}function XD(e,t){e&1&&qh(0)}function ZD(e,t){if(e&1&&(q(0,`span`,24),Z(1),J()),e&2){let e=X().$implicit;B(),$(``,e.node.injector.providerCount,` providers`)}}function QD(e,t){if(e&1){let e=Yh();q(0,`div`,21),Y(`click`,function(){let t=bo(e).$implicit;return xo(X(4).select(t.node))}),q(1,`span`,22),Z(2),J(),q(3,`span`,23),Z(4),J(),V(5,ZD,2,1,`span`,24),J()}if(e&2){let e=t.$implicit,n=X(4);kg(`padding-left`,e.depth*24+12,`px`),Ag(`selected`,n.selectedId()===e.node.injector.id),B(),kg(`background`,n.typeColor(e.node.injector.type)),B(),$(` `,e.node.injector.type,` `),B(2),Q(e.node.injector.name),B(),H(e.node.injector.providerCount>0?5:-1)}}function $D(e,t){if(e&1&&(q(0,`div`,19),U(1,QD,6,9,`div`,20,HD),J()),e&2){let e=X().$implicit,t=X(2);B(),W(t.flattenTree(e))}}function eO(e,t){e&1&&(dm(0,XD,1,0,`ng-container`,18)(1,$D,3,0),gh(2,1),_h()),e&2&&Xh(`ngTemplateOutlet`,void 0)}function tO(e,t){e&1&&(q(0,`p`,5),Z(1,`No providers configured on this injector.`),J())}function nO(e,t){if(e&1&&(q(0,`tr`)(1,`td`,13),Z(2),J(),q(3,`td`),Z(4),J(),q(5,`td`),Z(6),J()()),e&2){let e=t.$implicit;B(2),Q(e.token),B(2),Q(e.type),B(2),Q(e.isViewProvider?`Yes`:`—`)}}function rO(e,t){if(e&1&&(q(0,`table`,26)(1,`thead`)(2,`tr`)(3,`th`),Z(4,`Token`),J(),q(5,`th`),Z(6,`Type`),J(),q(7,`th`),Z(8,`View`),J()()(),q(9,`tbody`),U(10,nO,7,3,`tr`,null,UD),J()()),e&2){let e=X(3);B(10),W(e.selectedInjector().providers)}}function iO(e,t){if(e&1&&(q(0,`aside`,17)(1,`div`,25)(2,`span`,22),Z(3),J(),q(4,`h3`),Z(5),J()(),V(6,tO,2,0,`p`,5)(7,rO,12,0,`table`,26),J()),e&2){let e=X(2);B(2),kg(`background`,e.typeColor(e.selectedInjector().injector.type)),B(),$(` `,e.selectedInjector().injector.type,` `),B(2),Q(e.selectedInjector().injector.name),B(),H(e.selectedInjector().providers.length===0?6:7)}}function aO(e,t){if(e&1&&(q(0,`div`,16),U(1,eO,4,1,null,null,VD),J(),V(3,iO,8,5,`aside`,17)),e&2){let e=X();B(),W(e.filteredRoots()),B(2),H(e.selectedInjector()?3:-1)}}var oO={element:`#60a5fa`,environment:`#34d399`,null:`#71717a`},sO=class e{rpc=k_(null);roots=L([]);sourceProviders=L([]);filter=L(``);hideEmpty=L(!1);selectedId=L(null);selectedInjector=b_(()=>{let e=this.selectedId();return e?this.findNode(this.roots(),e):null});filteredRoots=b_(()=>{let e=this.roots();this.hideEmpty()&&(e=this.filterEmpty(e));let t=this.filter().toLowerCase();return t&&(e=this.filterByQuery(e,t)),e});groupedProviders=b_(()=>{let e=this.sourceProviders(),t=this.filter().toLowerCase(),n=t?e.filter(e=>e.token.toLowerCase().includes(t)||e.file.includes(t)):e,r=[{type:`root-provider`,label:`Root Providers (provide*)`,items:[]},{type:`injectable`,label:`Injectable Services`,items:[]},{type:`injection`,label:`inject() Calls`,items:[]},{type:`provider`,label:`Component Providers`,items:[]}];for(let e of n){let t=r.find(t=>t.type===e.type);t&&t.items.push(e)}return r.filter(e=>e.items.length>0)});constructor(){Zs(()=>{let e=this.rpc();e&&(this.loadInjectorTree(e),this.loadSourceProviders(e))})}async loadInjectorTree(e){let t=await e.scope(`ng-devtools`).rpc.sharedState(`injector-tree`),n=t.value();n?.roots?.length&&this.roots.set(n.roots),t.on(`updated`,e=>{e?.roots&&this.roots.set(e.roots)})}async loadSourceProviders(e){let t=e.scope(`ng-devtools`);try{let e=await t.rpc.call(`get-providers`);this.sourceProviders.set(e)}catch{}}select(e){this.selectedId.set(this.selectedId()===e.injector.id?null:e.injector.id)}typeColor(e){return oO[e]??oO.null}flattenTree(e){let t=[],n=(e,r)=>{t.push({node:e,depth:r});for(let t of e.children)n(t,r+1)};return n(e,0),t}findNode(e,t){for(let n of e){if(n.injector.id===t)return n;let e=this.findNode(n.children,t);if(e)return e}return null}filterEmpty(e){return e.map(e=>({...e,children:this.filterEmpty(e.children)})).filter(e=>e.injector.providerCount>0||e.children.length>0)}filterByQuery(e,t){return e.map(e=>({...e,children:this.filterByQuery(e.children,t)})).filter(e=>e.injector.name.toLowerCase().includes(t)||e.providers.some(e=>e.token.toLowerCase().includes(t))||e.children.length>0)}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-di-inspector`]],inputs:{rpc:[1,`rpc`]},decls:8,vars:5,consts:[[1,`toolbar`],[`type`,`text`,`placeholder`,`Filter by injector name or token…`,3,`input`,`value`],[1,`checkbox`],[`type`,`checkbox`,3,`change`,`checked`],[1,`empty`],[1,`muted`],[1,`hint`],[1,`source-label`],[1,`source-providers`],[1,`provider-group`],[1,`provider-list`],[1,`provider-card`],[1,`provider-header`],[1,`token`],[1,`provided-in`],[1,`provider-meta`],[1,`tree-container`],[1,`detail-panel`],[4,`ngTemplateOutlet`],[1,`injector-tree`],[1,`injector-row`,3,`selected`,`paddingLeft`],[1,`injector-row`,3,`click`],[1,`type-badge`],[1,`name`],[1,`provider-count`],[1,`detail-header`],[`role`,`table`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`input`,1),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(2,`label`,2)(3,`input`,3),Y(`change`,function(){return t.hideEmpty.set(!t.hideEmpty())}),J(),Z(4,` Hide empty injectors `),J()(),V(5,WD,5,0,`div`,4),V(6,YD,5,0),V(7,aO,4,1)),e&2&&(B(),Xh(`value`,t.filter()),B(2),Xh(`checked`,t.hideEmpty()),B(2),H(t.roots().length===0&&t.sourceProviders().length===0?5:-1),B(),H(t.roots().length===0&&t.sourceProviders().length>0?6:-1),B(),H(t.roots().length>0?7:-1))},styles:[`.toolbar[_ngcontent-%COMP%] { - display: flex; - gap: 12px; - align-items: center; - margin-bottom: 16px; - } - input[type='text'][_ngcontent-%COMP%] { - flex: 1; - padding: 8px 12px; - background: #18181b; - border: 1px solid #27272a; - border-radius: 6px; - color: #e4e4e7; - font-size: 14px; - outline: none; - } - input[type='text'][_ngcontent-%COMP%]:focus { - border-color: var(--%NS%accent); - } - .checkbox[_ngcontent-%COMP%] { - display: flex; - align-items: center; - gap: 6px; - font-size: 13px; - color: #a1a1aa; - white-space: nowrap; - cursor: pointer; - } - .empty[_ngcontent-%COMP%] { - text-align: center; - padding: 48px 16px; - } - .muted[_ngcontent-%COMP%] { - color: #71717a; - font-size: 14px; - } - .hint[_ngcontent-%COMP%] { - color: #52525b; - font-size: 12px; - margin-top: 8px; - } - .tree-container[_ngcontent-%COMP%] { - display: flex; - flex-direction: column; - } - .injector-row[_ngcontent-%COMP%] { - display: flex; - align-items: center; - gap: 8px; - padding: 8px 12px; - cursor: pointer; - border-bottom: 1px solid #1e1e22; - transition: background 0.1s; - } - .injector-row[_ngcontent-%COMP%]:hover { - background: #18181b; - } - .injector-row.selected[_ngcontent-%COMP%] { - background: color-mix(in srgb, var(--%NS%accent) 22%, transparent); - border-color: var(--%NS%accent); - } - .type-badge[_ngcontent-%COMP%] { - font-size: 10px; - padding: 2px 6px; - border-radius: 4px; - color: #fff; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; - } - .name[_ngcontent-%COMP%] { - font-family: monospace; - font-size: 13px; - color: #e4e4e7; - } - .provider-count[_ngcontent-%COMP%] { - font-size: 11px; - color: #71717a; - margin-left: auto; - } - .detail-panel[_ngcontent-%COMP%] { - margin-top: 16px; - padding: 16px; - background: #18181b; - border: 1px solid #27272a; - border-radius: 8px; - } - .detail-header[_ngcontent-%COMP%] { - display: flex; - align-items: center; - gap: 8px; - margin-bottom: 12px; - } - .detail-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { - font-family: monospace; - color: #e4e4e7; - margin: 0; - } - table[_ngcontent-%COMP%] { - width: 100%; - border-collapse: collapse; - font-size: 13px; - } - th[_ngcontent-%COMP%] { - text-align: left; - padding: 6px 10px; - background: #0f0f11; - color: #71717a; - font-size: 11px; - text-transform: uppercase; - letter-spacing: 0.05em; - border-bottom: 1px solid #27272a; - } - td[_ngcontent-%COMP%] { - padding: 8px 10px; - border-bottom: 1px solid #1e1e22; - } - .token[_ngcontent-%COMP%] { - font-family: monospace; - color: var(--%NS%accent); - } - .source-label[_ngcontent-%COMP%] { - font-size: 13px; - color: #71717a; - margin-bottom: 12px; - } - .source-providers[_ngcontent-%COMP%] { - display: flex; - flex-direction: column; - gap: 20px; - } - .provider-group[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { - font-size: 13px; - color: #71717a; - text-transform: uppercase; - letter-spacing: 0.05em; - margin-bottom: 8px; - } - .provider-list[_ngcontent-%COMP%] { - display: flex; - flex-direction: column; - gap: 6px; - } - .provider-card[_ngcontent-%COMP%] { - background: #18181b; - border: 1px solid #27272a; - border-radius: 8px; - padding: 10px 14px; - } - .provider-header[_ngcontent-%COMP%] { - display: flex; - align-items: center; - gap: 8px; - } - .provider-header[_ngcontent-%COMP%] .token[_ngcontent-%COMP%] { - font-size: 14px; - font-weight: 500; - } - .provided-in[_ngcontent-%COMP%] { - font-size: 11px; - padding: 1px 6px; - border-radius: 4px; - background: #14532d; - color: #4ade80; - } - .provider-meta[_ngcontent-%COMP%] { - font-size: 11px; - color: #52525b; - margin-top: 4px; - }`]})},cO=(e,t)=>t.kind,lO=(e,t)=>t.name+t.file+t.line;function uO(e,t){e&1&&Hh(0,`span`,4)}function dO(e,t){e&1&&(q(0,`div`,5)(1,`p`,6),Z(2,`No NgRx store patterns found.`),J(),q(3,`p`,7),Z(4,` No createAction, createReducer, createEffect, createSelector, or createFeature calls found in source. Make sure your app uses @ngrx/store. `),J()())}function fO(e,t){if(e&1&&(q(0,`span`,9),Hh(1,`span`,14),Z(2),J()),e&2){let e=t.$implicit;B(),kg(`background`,e.color),B(),$(` `,e.kind,` `)}}function pO(e,t){if(e&1&&(q(0,`span`,15),Z(1),J()),e&2){let e=t.$implicit;kg(`border-color`,X(3).kindColor(e.kind)),B(),n_(` `,e.count,` `,e.kind,``,e.count===1?``:`s`,` `)}}function mO(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · `,e.detail,` `)}}function hO(e,t){if(e&1&&(q(0,`div`,13)(1,`div`,16)(2,`span`,17),Z(3),J(),q(4,`span`,18),Z(5),J()(),q(6,`div`,19),Z(7),V(8,mO,1,1),J()()),e&2){let e=t.$implicit,n=X(3);B(2),kg(`background`,n.kindColor(e.kind)),B(),$(` `,e.kind,` `),B(2),Q(e.name),B(2),t_(` `,e.file,`:`,e.line,` `),B(),H(e.detail?8:-1)}}function gO(e,t){if(e&1&&(q(0,`div`,8),U(1,fO,3,3,`span`,9,cO),J(),q(3,`div`,10),U(4,pO,2,5,`span`,11,cO),J(),q(6,`div`,12),U(7,hO,9,7,`div`,13,lO),J()),e&2){let e=X(2);B(),W(e.kindLegend),B(3),W(e.groupedEntries()),B(3),W(e.filteredEntries())}}function _O(e,t){e&1&&V(0,dO,5,0,`div`,5)(1,gO,9,0),e&2&&H(X().sourceEntries().length===0?0:1)}function vO(e,t){e&1&&(q(0,`div`,5)(1,`p`,6),Z(2,`No NgRx store connection detected.`),J(),q(3,`p`,7),Z(4,` Runtime inspection requires @ngrx/store-devtools to be configured in your app. The store devtools use the Redux DevTools protocol to expose state. `),J()())}function yO(e,t){if(e&1){let e=Yh();q(0,`div`,28),Y(`click`,function(){let t=bo(e).$implicit;return xo(X(3).selectedAction.set(t))}),q(1,`div`,29),Z(2),J(),q(3,`div`,30),Z(4),J()()}if(e&2){let e=t.$implicit,n=X(3);Ag(`selected`,n.selectedAction()===e),B(2),Q(e.type),B(2),Q(n.formatTime(e.timestamp))}}function bO(e,t){e&1&&(q(0,`p`,6),Z(1,`No actions dispatched yet.`),J())}function xO(e,t){if(e&1&&(q(0,`dt`),Z(1,`Payload`),J(),q(2,`dd`)(3,`pre`),Z(4),l_(5,`json`),J()()),e&2){let e=X(4);B(4),Q(d_(5,1,e.selectedAction().payload))}}function SO(e,t){if(e&1&&(q(0,`aside`,27)(1,`h3`),Z(2),J(),q(3,`dl`)(4,`dt`),Z(5,`Type`),J(),q(6,`dd`),Z(7),J(),q(8,`dt`),Z(9,`Time`),J(),q(10,`dd`),Z(11),J(),V(12,xO,6,3),J()()),e&2){let e=X(3);B(2),Q(e.selectedAction().type),B(5),Q(e.selectedAction().type),B(4),Q(e.formatTime(e.selectedAction().timestamp)),B(),H(e.selectedAction().payload===void 0?-1:12)}}function CO(e,t){if(e&1&&(q(0,`div`,20)(1,`section`,21)(2,`h3`),Z(3,`Current State`),J(),q(4,`pre`,22),Z(5),l_(6,`json`),J()(),q(7,`section`,23)(8,`h3`),Z(9,` Recent Actions `),q(10,`span`,24),Z(11),J()(),q(12,`div`,25),U(13,yO,5,4,`div`,26,Oh,!1,bO,2,0,`p`,6),J()()(),V(16,SO,13,4,`aside`,27)),e&2){let e=X(2);B(5),Q(d_(6,4,e.runtimeState()?.state)),B(6),Q(e.filteredActions().length),B(2),W(e.filteredActions()),B(3),H(e.selectedAction()?16:-1)}}function wO(e,t){e&1&&V(0,vO,5,0,`div`,5)(1,CO,17,6),e&2&&H(+!!X().runtimeState()?.connected)}var TO={action:`#f59e0b`,reducer:`#a78bfa`,effect:`#fb923c`,selector:`#60a5fa`,feature:`#34d399`,"store-setup":`#94a3b8`,"signal-store":`#e879f9`,"signal-state":`#22d3ee`,"signal-method":`#fb7185`},EO=class e{rpc=k_(null);filter=L(``);mode=L(`source`);sourceEntries=L([]);runtimeState=L(null);selectedAction=L(null);kindLegend=Object.entries(TO).map(([e,t])=>({kind:e,color:t}));filteredEntries=b_(()=>{let e=this.filter().toLowerCase();return this.sourceEntries().filter(t=>t.name.toLowerCase().includes(e)||t.kind.toLowerCase().includes(e))});groupedEntries=b_(()=>{let e=this.sourceEntries(),t=new Map;for(let n of e)t.set(n.kind,(t.get(n.kind)??0)+1);return[...t.entries()].map(([e,t])=>({kind:e,count:t}))});filteredActions=b_(()=>{let e=this.filter().toLowerCase(),t=[...this.runtimeState()?.actions??[]].reverse();return e?t.filter(t=>t.type.toLowerCase().includes(e)):t});constructor(){Zs(()=>{let e=this.rpc();if(!e)return;let t=e.scope(`ng-devtools`);t.rpc.call(`get-ngrx-store`).then(e=>{this.sourceEntries.set(e),e.length===0&&this.mode.set(`runtime`)}).catch(()=>this.sourceEntries.set([])),t.rpc.sharedState(`ngrx-store`).then(e=>{e?.subscribe&&e.subscribe(e=>this.runtimeState.set(e))})})}kindColor(e){return TO[e]??`#71717a`}formatTime(e){return new Date(e).toLocaleTimeString()}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-store-inspector`]],inputs:{rpc:[1,`rpc`]},decls:10,vars:8,consts:[[1,`toolbar`],[`type`,`text`,`placeholder`,`Filter by name or kind…`,3,`input`,`value`],[1,`toggle-group`],[3,`click`],[1,`live-dot`],[1,`empty`],[1,`muted`],[1,`hint`],[1,`legend`],[1,`legend-item`],[1,`summary`],[1,`summary-badge`,3,`border-color`],[1,`nodes`],[1,`node-card`],[1,`dot`],[1,`summary-badge`],[1,`node-header`],[1,`kind-badge`],[1,`node-label`],[1,`node-meta`],[1,`runtime-layout`],[1,`state-panel`],[1,`state-tree`],[1,`actions-panel`],[1,`action-count`],[1,`action-list`],[1,`action-card`,3,`selected`],[1,`detail-panel`],[1,`action-card`,3,`click`],[1,`action-type`],[1,`action-time`]],template:function(e,t){e&1&&(q(0,`div`,0)(1,`input`,1),Y(`input`,function(e){return t.filter.set(e.target.value)}),J(),q(2,`div`,2)(3,`button`,3),Y(`click`,function(){return t.mode.set(`source`)}),Z(4,`Source`),J(),q(5,`button`,3),Y(`click`,function(){return t.mode.set(`runtime`)}),Z(6,` Runtime `),V(7,uO,1,0,`span`,4),J()()(),V(8,_O,2,1),V(9,wO,2,1)),e&2&&(B(),Xh(`value`,t.filter()),B(2),Ag(`active`,t.mode()===`source`),B(2),Ag(`active`,t.mode()===`runtime`),B(2),H(t.runtimeState()?.connected?7:-1),B(),H(t.mode()===`source`?8:-1),B(),H(t.mode()===`runtime`?9:-1))},dependencies:[Wv],styles:[`.toolbar[_ngcontent-%COMP%] { - display: flex; - gap: 12px; - align-items: center; - margin-bottom: 16px; - } - input[_ngcontent-%COMP%] { - flex: 1; - padding: 8px 12px; - background: #18181b; - border: 1px solid #27272a; - border-radius: 6px; - color: #e4e4e7; - font-size: 14px; - outline: none; - } - input[_ngcontent-%COMP%]:focus { - border-color: var(--%NS%accent); - } - .toggle-group[_ngcontent-%COMP%] { - display: flex; - border: 1px solid #27272a; - border-radius: 6px; - overflow: hidden; - } - .toggle-group[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { - padding: 6px 14px; - border: none; - background: transparent; - color: #a1a1aa; - cursor: pointer; - font-size: 13px; - display: flex; - align-items: center; - gap: 6px; - } - .toggle-group[_ngcontent-%COMP%] button.active[_ngcontent-%COMP%] { - background: #3f3f46; - color: #fff; - } - .live-dot[_ngcontent-%COMP%] { - width: 6px; - height: 6px; - border-radius: 50%; - background: #4ade80; - animation: _ngcontent-%COMP%_pulse 2s infinite; - } - @keyframes _ngcontent-%COMP%_pulse { - 0%, - 100% { - opacity: 1; - } - 50% { - opacity: 0.4; - } - } - .empty[_ngcontent-%COMP%] { - text-align: center; - padding: 48px 16px; - } - .muted[_ngcontent-%COMP%] { - color: #71717a; - font-size: 14px; - } - .hint[_ngcontent-%COMP%] { - color: #52525b; - font-size: 12px; - margin-top: 8px; - } - .legend[_ngcontent-%COMP%] { - display: flex; - gap: 12px; - flex-wrap: wrap; - margin-bottom: 12px; - } - .legend-item[_ngcontent-%COMP%] { - display: flex; - align-items: center; - gap: 4px; - font-size: 12px; - color: #a1a1aa; - } - .dot[_ngcontent-%COMP%] { - width: 8px; - height: 8px; - border-radius: 50%; - } - .summary[_ngcontent-%COMP%] { - display: flex; - gap: 8px; - flex-wrap: wrap; - margin-bottom: 16px; - } - .summary-badge[_ngcontent-%COMP%] { - font-size: 12px; - padding: 3px 10px; - border-radius: 99px; - border: 1px solid; - color: #e4e4e7; - } - .nodes[_ngcontent-%COMP%] { - display: flex; - flex-direction: column; - gap: 8px; - } - .node-card[_ngcontent-%COMP%] { - background: #18181b; - border: 1px solid #27272a; - border-radius: 8px; - padding: 12px 16px; - transition: border-color 0.15s; - } - .node-card[_ngcontent-%COMP%]:hover { - border-color: #3f3f46; - } - .node-header[_ngcontent-%COMP%] { - display: flex; - align-items: center; - gap: 8px; - } - .kind-badge[_ngcontent-%COMP%] { - font-size: 11px; - padding: 2px 8px; - border-radius: 4px; - color: #fff; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; - } - .node-label[_ngcontent-%COMP%] { - font-family: monospace; - font-size: 14px; - color: #e4e4e7; - } - .node-meta[_ngcontent-%COMP%] { - font-size: 12px; - color: #71717a; - margin-top: 4px; - } - .runtime-layout[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 16px; - } - .state-panel[_ngcontent-%COMP%], - .actions-panel[_ngcontent-%COMP%] { - background: #18181b; - border: 1px solid #27272a; - border-radius: 10px; - padding: 16px; - } - h3[_ngcontent-%COMP%] { - font-size: 13px; - text-transform: uppercase; - color: #71717a; - margin-bottom: 12px; - letter-spacing: 0.05em; - display: flex; - align-items: center; - gap: 8px; - } - .action-count[_ngcontent-%COMP%] { - font-size: 11px; - padding: 1px 6px; - border-radius: 99px; - background: #3f3f46; - color: #a1a1aa; - } - .state-tree[_ngcontent-%COMP%] { - font-family: monospace; - font-size: 12px; - color: #a1a1aa; - white-space: pre-wrap; - word-break: break-all; - max-height: 500px; - overflow: auto; - } - .action-list[_ngcontent-%COMP%] { - display: flex; - flex-direction: column; - gap: 6px; - max-height: 500px; - overflow: auto; - } - .action-card[_ngcontent-%COMP%] { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 12px; - background: #09090b; - border: 1px solid #27272a; - border-radius: 6px; - cursor: pointer; - transition: border-color 0.15s; - } - .action-card[_ngcontent-%COMP%]:hover { - border-color: #3f3f46; - } - .action-card.selected[_ngcontent-%COMP%] { - border-color: var(--%NS%accent); - } - .action-type[_ngcontent-%COMP%] { - font-family: monospace; - font-size: 13px; - color: #e4e4e7; - } - .action-time[_ngcontent-%COMP%] { - font-size: 11px; - color: #71717a; - } - .detail-panel[_ngcontent-%COMP%] { - margin-top: 16px; - background: #18181b; - border: 1px solid var(--%NS%accent); - border-radius: 10px; - padding: 16px; - } - dl[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: auto 1fr; - gap: 6px 12px; - font-size: 14px; - } - dt[_ngcontent-%COMP%] { - color: #a1a1aa; - } - dd[_ngcontent-%COMP%] { - color: #e4e4e7; - } - pre[_ngcontent-%COMP%] { - font-family: monospace; - font-size: 12px; - white-space: pre-wrap; - word-break: break-all; - }`]})},DO=()=>[],OO=(e,t)=>t.id,kO=(e,t)=>t.node.path,AO=(e,t)=>t.formId+`#`+t.seq;function jO(e,t){e&1&&(q(0,`p`,0),Z(1,`Connecting…`),J())}function MO(e,t){e&1&&(q(0,`p`,0),Z(1,`Could not load forms from the devtools server. Reload to try again.`),J())}function NO(e,t){e&1&&(q(0,`p`,0),Z(1,`Loading forms…`),J())}function PO(e,t){e&1&&(q(0,`div`,0)(1,`p`),Z(2,`No forms on the page yet.`),J(),q(3,`p`,2),Z(4,` Open a page that renders a form. Signal Forms, reactive and template-driven forms all show up here, in development builds. `),J()())}function FO(e,t){e&1&&(q(0,`span`,10),Z(1),q(2,`span`,9),Z(3,` errors`),J()()),e&2&&(B(),Q(t))}function IO(e,t){if(e&1){let e=Yh();q(0,`li`)(1,`button`,5),Y(`click`,function(){let t=bo(e).$implicit;return xo(X(2).selectForm(t.id))}),Hh(2,`span`,6),q(3,`span`,7),Z(4),J(),q(5,`span`,8),Z(6),q(7,`span`,9),Z(8),J()(),V(9,FO,4,1,`span`,10),J()()}if(e&2){let e,n=t.$implicit,r=X(2);B(),Ag(`active`,n.id===r.selected()?.id),vh(`aria-current`,n.id===r.selected()?.id?`true`:null),B(),vh(`data-status`,n.root.status),B(2),Q(n.label),B(2),t_(``,r.kindLabel(n.kind),` · `,n.id,` `),B(2),$(`, `,n.root.status),B(),H((e=r.counts().get(n.id)?.errors)?9:-1,e)}}function LO(e,t){if(e&1&&(q(0,`span`),Z(1),J()),e&2){let e=X();B(),Q(e.submitted?`submitted`:`not submitted`)}}function RO(e,t){e&1&&(q(0,`span`),Z(1,`submitting`),J())}function zO(e,t){if(e&1&&(q(0,`div`,2),Z(1,` resets to `),q(2,`code`),Z(3),l_(4,`json`),J()()),e&2){let e=X(2).$implicit;B(3),Q(d_(4,1,e.node.defaultValue))}}function BO(e,t){if(e&1&&(q(0,`code`),Z(1),l_(2,`json`),J(),V(3,zO,5,3,`div`,2)),e&2){let e=X().$implicit;B(),Q(d_(2,2,e.node.value)),B(2),H(e.node.defaultValue===void 0?-1:3)}}function VO(e,t){e&1&&(q(0,`span`,2),Z(1,`not created yet`),J())}function HO(e,t){if(e&1&&(q(0,`span`,12),Z(1),J()),e&2){let e=X().$implicit;vh(`data-status`,e.node.status),B(),Q(e.node.status)}}function UO(e,t){e&1&&(q(0,`span`),Z(1,`touched`),J())}function WO(e,t){e&1&&(q(0,`span`),Z(1,`dirty`),J())}function GO(e,t){e&1&&(q(0,`span`),Z(1,`required`),J())}function KO(e,t){e&1&&(q(0,`span`),Z(1,`readonly`),J())}function qO(e,t){e&1&&(q(0,`span`),Z(1,`hidden`),J())}function JO(e,t){if(e&1&&(q(0,`span`),Z(1),J()),e&2){let e=X().$implicit;B(),$(`updates on `,e.node.updateOn)}}function YO(e,t){e&1&&(q(0,`span`),Z(1,`debouncing`),J())}function XO(e,t){e&1&&(q(0,`span`),Z(1,`validators`),J())}function ZO(e,t){e&1&&(q(0,`span`),Z(1,`async validator`),J())}function QO(e,t){if(e&1&&(q(0,`span`),Z(1),J()),e&2){let e=t.$implicit;B(),Q(e)}}function $O(e,t){if(e&1&&(q(0,`span`),Z(1),J()),e&2){let e=X().$implicit;B(),Q(e.node.accessor)}}function ek(e,t){if(e&1&&(q(0,`span`),Z(1),J()),e&2){let e=t.$implicit;B(),$(`disabled: `,e)}}function tk(e,t){if(e&1&&(q(0,`div`),Z(1),q(2,`code`,25),Z(3),J()()),e&2){let e=t.$implicit,n=X().$implicit,r=X(3);B(),$(` `,r.errorText(n.node,e),` `),B(2),Q(e.kind)}}function nk(e,t){if(e&1&&(q(0,`tr`)(1,`td`,26),Z(2),J()()),e&2){let e=X().$implicit;B(),kg(`padding-left`,24+e.depth*16,`px`),B(),t_(` `,e.node.truncated,` more fields under `,e.node.path||`the form`,` not shown `)}}function rk(e,t){if(e&1){let e=Yh();q(0,`tr`,18),Y(`mouseenter`,function(){let t=bo(e).$implicit,n=X();return xo(X(2).highlight(n.id,t.node.path))})(`mouseleave`,function(){return bo(e),xo(X(3).highlight(null,``))}),q(1,`th`,19)(2,`button`,20),Y(`focus`,function(){let t=bo(e).$implicit,n=X();return xo(X(2).highlight(n.id,t.node.path))})(`blur`,function(){return bo(e),xo(X(3).highlight(null,``))}),Z(3),J(),q(4,`span`,21),Z(5),J()(),q(6,`td`,22),V(7,BO,4,4),J(),q(8,`td`),V(9,VO,2,0,`span`,2)(10,HO,2,2,`span`,12),J(),q(11,`td`,23),V(12,UO,2,0,`span`),V(13,WO,2,0,`span`),V(14,GO,2,0,`span`),V(15,KO,2,0,`span`),V(16,qO,2,0,`span`),V(17,JO,2,1,`span`),V(18,YO,2,0,`span`),V(19,XO,2,0,`span`),V(20,ZO,2,0,`span`),U(21,QO,2,1,`span`,null,kh),V(23,$O,2,1,`span`),U(24,ek,2,1,`span`,null,Oh),J(),q(26,`td`,24),U(27,tk,4,2,`div`,null,Oh),J()(),V(29,nk,3,4,`tr`)}if(e&2){let e=t.$implicit,n=X(3);Ag(`invalid`,e.node.errors.length),B(),kg(`padding-left`,8+e.depth*16,`px`),B(),vh(`aria-label`,`Highlight `+(e.node.path||`the form`)+` on the page`),B(),$(` `,e.node.key||`(form)`,` `),B(2),Q(e.node.type),B(2),H(e.node.type===`control`?7:-1),B(2),H(e.node.materialized===!1?9:10),B(3),H(e.node.touched?12:-1),B(),H(e.node.dirty?13:-1),B(),H(e.node.required?14:-1),B(),H(e.node.readonly?15:-1),B(),H(e.node.hidden?16:-1),B(),H(e.node.updateOn?17:-1),B(),H(e.node.debouncing?18:-1),B(),H(e.node.validators?.sync?19:-1),B(),H(e.node.validators?.async?20:-1),B(),W(n.constraintList(e.node)),B(2),H(e.node.accessor?23:-1),B(),W(e.node.disabledReasons??i_(20,DO)),B(3),W(e.node.errors),B(2),H(e.node.truncated?29:-1)}}function ik(e,t){if(e&1&&(q(0,`tr`)(1,`td`,26),Z(2),J()()),e&2){let e=X(3);B(2),$(`No field path matches "`,e.filter(),`".`)}}function ak(e,t){if(e&1&&(q(0,`span`,2),Z(1),J()),e&2){let e=X().$implicit;B(),Q(e.detail)}}function ok(e,t){if(e&1&&(q(0,`li`)(1,`time`),Z(2),J(),q(3,`code`),Z(4),J(),q(5,`span`,27),Z(6),J(),V(7,ak,2,1,`span`,2),J()),e&2){let e=t.$implicit,n=X(4);B(2),Q(n.time(e.timestamp)),B(2),Q(e.path||`(form)`),B(2),Q(e.type),B(),H(e.detail?7:-1)}}function sk(e,t){if(e&1&&(q(0,`ol`,17),U(1,ok,8,4,`li`,null,AO),J()),e&2){let e=X(3);B(),W(e.selectedEvents())}}function ck(e,t){e&1&&(q(0,`p`,2),Z(1,`No changes yet. Type into the form to see them here.`),J())}function lk(e,t){if(e&1){let e=Yh();q(0,`section`,4)(1,`div`,11)(2,`span`,12),Z(3),J(),q(4,`span`),Z(5),J(),q(6,`span`),Z(7),J(),V(8,LO,2,1,`span`),V(9,RO,2,0,`span`),q(10,`span`,2),Z(11),J()(),q(12,`input`,13),Y(`input`,function(t){return bo(e),xo(X(2).onFilter(t))}),J(),q(13,`div`,14)(14,`table`,15)(15,`thead`)(16,`tr`)(17,`th`,16),Z(18,`Field`),J(),q(19,`th`,16),Z(20,`Value`),J(),q(21,`th`,16),Z(22,`Status`),J(),q(23,`th`,16),Z(24,`State`),J(),q(25,`th`,16),Z(26,`Errors`),J()()(),q(27,`tbody`),U(28,rk,30,21,null,null,kO,!1,ik,3,1,`tr`),J()()(),q(31,`h2`),Z(32,`Recent changes`),J(),V(33,sk,3,0,`ol`,17)(34,ck,2,0,`p`,2),J()}if(e&2){let e=t,n=X(2);vh(`aria-label`,e.label),B(2),vh(`data-status`,e.root.status),B(),Q(e.root.status),B(2),Q(e.root.dirty?`dirty`:`pristine`),B(2),Q(e.root.touched?`touched`:`untouched`),B(),H(e.submitted===void 0?-1:8),B(),H(e.root.submitting?9:-1),B(2),t_(``,n.counts().get(e.id)?.fields,` fields, `,n.counts().get(e.id)?.errors,` errors`),B(),Xh(`value`,n.filter()),B(16),W(n.rows()),B(5),H(n.selectedEvents().length?33:34)}}function uk(e,t){if(e&1&&(q(0,`div`,1)(1,`ul`,3),U(2,IO,10,9,`li`,null,OO),J(),V(4,lk,35,12,`section`,4),J()),e&2){let e,t=X();B(2),W(t.forms()),B(2),H((e=t.selected())?4:-1,e)}}var dk={signal:`Signal Forms`,reactive:`Reactive`,template:`Template-driven`};function fk(e){return e.errors.length+(e.children??[]).reduce((e,t)=>e+fk(t),0)}function pk(e){return 1+(e.children??[]).reduce((e,t)=>e+pk(t),0)}var mk=class e{rpc=k_(null);forms=L([]);events=L([]);loading=L(!0);failed=L(!1);selectedId=L(null);filter=L(``);unsubscribe=null;destroyRef=P(us);counts=b_(()=>new Map(this.forms().map(e=>[e.id,{fields:pk(e.root),errors:fk(e.root)}])));selected=b_(()=>{let e=this.forms();return e.find(e=>e.id===this.selectedId())??e[0]??null});rows=b_(()=>{let e=this.selected();if(!e)return[];let t=this.filter().toLowerCase(),n=[],r=(e,i)=>{let a=n.length,o=!t||e.path.toLowerCase().includes(t);for(let t of e.children??[])o=r(t,i+1)||o;return o&&n.splice(a,0,{node:e,depth:i}),o};return r(e.root,0),n});selectedEvents=b_(()=>{let e=this.selected()?.id;return this.events().filter(t=>t.formId===e).slice(-50).reverse()});constructor(){Zs(()=>{let e=this.rpc();e&&this.load(e)}),this.destroyRef.onDestroy(()=>{this.unsubscribe?.(),this.highlight(null,``)})}async load(e){this.loading.set(!0),this.failed.set(!1);try{let t=await e.scope(`ng-devtools`).rpc.sharedState(`forms`);if(this.destroyRef.destroyed)return;let n=e=>{let t=e;this.forms.set(t?.forms??[]),this.events.set(t?.events??[])};n(t.value()),this.unsubscribe?.(),this.unsubscribe=t.on(`updated`,n)}catch{this.failed.set(!0)}finally{this.loading.set(!1)}}selectForm(e){this.selectedId.set(e),this.filter.set(``)}onFilter(e){this.filter.set(e.target.value)}highlight(e,t){let n=this.rpc();n&&n.scope(`ng-devtools`).rpc.callEvent(`request-form-highlight`,e?{formId:e,path:t}:null)}kindLabel(e){return dk[e]}constraintList(e){return Object.entries(e.constraints??{}).map(([e,t])=>`${e} ${t}`)}errorText(e,t){return/^[a-z]/.test(t.message)?`${e.key||`The form`} ${t.message}`:t.message}time(e){return new Date(e).toLocaleTimeString()}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-forms-inspector`]],inputs:{rpc:[1,`rpc`]},decls:5,vars:1,consts:[[1,`empty`],[1,`layout`],[1,`muted`],[`aria-label`,`Forms on the page`,1,`form-list`],[1,`detail`],[`type`,`button`,1,`form-item`,3,`click`],[`aria-hidden`,`true`,1,`dot`],[1,`label`],[1,`kind`],[1,`sr-only`],[1,`count`],[1,`summary`],[1,`badge`],[`type`,`search`,`placeholder`,`Filter fields by path`,`aria-label`,`Filter fields by path`,1,`filter`,3,`input`,`value`],[`role`,`region`,`aria-label`,`Fields`,`tabindex`,`0`,1,`table-scroll`],[1,`fields`],[`scope`,`col`],[1,`events`],[3,`mouseenter`,`mouseleave`],[`scope`,`row`],[`type`,`button`,1,`field`,3,`focus`,`blur`],[1,`type`],[1,`value`],[1,`flags`],[1,`errors`],[1,`kind-tag`],[`colspan`,`5`,1,`muted`],[1,`event-type`]],template:function(e,t){e&1&&V(0,jO,2,0,`p`,0)(1,MO,2,0,`p`,0)(2,NO,2,0,`p`,0)(3,PO,5,0,`div`,0)(4,uk,5,1,`div`,1),e&2&&H(t.rpc()?t.failed()?1:t.loading()?2:t.forms().length?4:3:0)},dependencies:[Wv],styles:[`.layout[_ngcontent-%COMP%] { - display: grid; - grid-template-columns: minmax(200px, 260px) minmax(0, 1fr); - gap: 16px; - } - @media (max-width: 720px) { - .layout[_ngcontent-%COMP%] { - grid-template-columns: 1fr; - } - } - .form-list[_ngcontent-%COMP%] { - display: grid; - gap: 4px; - align-content: start; - margin: 0; - padding: 0; - list-style: none; - } - .form-item[_ngcontent-%COMP%] { - width: 100%; - display: grid; - grid-template-columns: auto 1fr auto; - grid-template-areas: 'dot label count' '. kind kind'; - gap: 2px 8px; - align-items: center; - padding: 8px 10px; - border: 1px solid #27272a; - border-radius: 6px; - background: transparent; - color: #e4e4e7; - text-align: left; - cursor: pointer; - } - .form-item.active[_ngcontent-%COMP%] { - border-color: var(--%NS%accent); - background: #18181b; - } - .form-item[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%] { - grid-area: dot; - } - .form-item[_ngcontent-%COMP%] .label[_ngcontent-%COMP%] { - grid-area: label; - overflow-wrap: anywhere; - font-size: 13px; - } - .form-item[_ngcontent-%COMP%] .kind[_ngcontent-%COMP%] { - grid-area: kind; - color: #a1a1aa; - font-size: 12px; - } - .form-item[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] { - grid-area: count; - padding: 0 6px; - border-radius: 999px; - background: #7f1d1d; - color: #fecaca; - font-size: 12px; - } - .dot[_ngcontent-%COMP%] { - width: 8px; - height: 8px; - border-radius: 50%; - background: #22c55e; - } - .dot[data-status='INVALID'][_ngcontent-%COMP%] { - background: #ef4444; - } - .dot[data-status='PENDING'][_ngcontent-%COMP%] { - background: #eab308; - } - .dot[data-status='DISABLED'][_ngcontent-%COMP%] { - background: #71717a; - } - .detail[_ngcontent-%COMP%] { - display: grid; - gap: 12px; - min-width: 0; - } - .summary[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 8px 14px; - align-items: center; - color: #d4d4d8; - font-size: 13px; - } - .badge[_ngcontent-%COMP%] { - padding: 1px 6px; - border-radius: 4px; - background: #14532d; - color: #bbf7d0; - font-size: 11px; - font-weight: 600; - } - .badge[data-status='INVALID'][_ngcontent-%COMP%] { - background: #7f1d1d; - color: #fecaca; - } - .badge[data-status='PENDING'][_ngcontent-%COMP%] { - background: #713f12; - color: #fef08a; - } - .badge[data-status='DISABLED'][_ngcontent-%COMP%] { - background: #3f3f46; - color: #e4e4e7; - } - .filter[_ngcontent-%COMP%] { - padding: 8px 12px; - background: #18181b; - border: 1px solid #52525b; - border-radius: 6px; - color: #e4e4e7; - font-size: 14px; - } - .filter[_ngcontent-%COMP%]:focus-visible, - .form-item[_ngcontent-%COMP%]:focus-visible { - outline: 2px solid var(--%NS%accent); - outline-offset: 2px; - } - .table-scroll[_ngcontent-%COMP%] { - overflow-x: auto; - } - .table-scroll[_ngcontent-%COMP%]:focus-visible, - .field[_ngcontent-%COMP%]:focus-visible { - outline: 2px solid var(--%NS%accent); - outline-offset: 2px; - } - .field[_ngcontent-%COMP%] { - padding: 0; - border: none; - background: none; - color: inherit; - font: inherit; - cursor: pointer; - } - .sr-only[_ngcontent-%COMP%] { - position: absolute; - width: 1px; - height: 1px; - overflow: hidden; - clip-path: inset(50%); - white-space: nowrap; - } - .fields[_ngcontent-%COMP%] { - width: 100%; - border-collapse: collapse; - font-size: 13px; - } - .fields[_ngcontent-%COMP%] th[_ngcontent-%COMP%], - .fields[_ngcontent-%COMP%] td[_ngcontent-%COMP%] { - padding: 6px 8px; - border-bottom: 1px solid #27272a; - text-align: left; - vertical-align: top; - } - .fields[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%] { - color: #a1a1aa; - font-weight: 500; - } - .fields[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] th[_ngcontent-%COMP%] { - color: #e4e4e7; - font-weight: 500; - white-space: nowrap; - } - .fields[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover { - background: #18181b; - } - .type[_ngcontent-%COMP%] { - margin-left: 6px; - color: #a1a1aa; - font-size: 11px; - font-weight: 400; - } - .value[_ngcontent-%COMP%] code[_ngcontent-%COMP%], - .errors[_ngcontent-%COMP%] code[_ngcontent-%COMP%], - .events[_ngcontent-%COMP%] code[_ngcontent-%COMP%] { - color: #c4b5fd; - overflow-wrap: anywhere; - } - .flags[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { - display: inline-block; - margin: 0 4px 2px 0; - padding: 0 5px; - border: 1px solid #3f3f46; - border-radius: 4px; - color: #d4d4d8; - font-size: 11px; - } - .errors[_ngcontent-%COMP%] div[_ngcontent-%COMP%] { - color: #fca5a5; - } - .kind-tag[_ngcontent-%COMP%] { - margin-left: 6px; - color: #a1a1aa; - font-size: 11px; - } - h2[_ngcontent-%COMP%] { - margin: 8px 0 0; - color: #d4d4d8; - font-size: 14px; - } - .events[_ngcontent-%COMP%] { - display: grid; - gap: 4px; - margin: 0; - padding: 0; - list-style: none; - font-size: 13px; - } - .events[_ngcontent-%COMP%] li[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 8px; - color: #d4d4d8; - } - .events[_ngcontent-%COMP%] time[_ngcontent-%COMP%] { - color: #a1a1aa; - font-variant-numeric: tabular-nums; - } - .event-type[_ngcontent-%COMP%] { - color: #93c5fd; - } - .muted[_ngcontent-%COMP%] { - color: #a1a1aa; - } - .empty[_ngcontent-%COMP%] { - padding: 32px; - text-align: center; - color: #d4d4d8; - }`]})},hk=(e,t)=>t.id;function gk(e,t){if(e&1){let e=Yh();G(0,`button`,13),sg(`click`,function(){let t=bo(e).$implicit;return xo(X().switchTab(t.id))}),Z(1),K()}if(e&2){let e=t.$implicit;Ag(`active`,X().tab()===e.id),B(),Q(e.label)}}function _k(e,t){if(e&1){let e=Yh();G(0,`app-dashboard`,14),sg(`navigate`,function(t){return bo(e),xo(X().switchTab(t))}),K()}e&2&&Rh(`rpc`,X().rpc())}function vk(e,t){e&1&&Vh(0,`app-component-tree`,12),e&2&&Rh(`rpc`,X().rpc())}function yk(e,t){e&1&&Vh(0,`app-route-inspector`,12),e&2&&Rh(`rpc`,X().rpc())}function bk(e,t){e&1&&Vh(0,`app-signal-inspector`,12),e&2&&Rh(`rpc`,X().rpc())}function xk(e,t){e&1&&Vh(0,`app-di-inspector`,12),e&2&&Rh(`rpc`,X().rpc())}function Sk(e,t){e&1&&Vh(0,`app-store-inspector`,12),e&2&&Rh(`rpc`,X().rpc())}function Ck(e,t){e&1&&Vh(0,`app-forms-inspector`,12),e&2&&Rh(`rpc`,X().rpc())}var wk=class e{tabs=[{id:`dashboard`,label:`Dashboard`},{id:`components`,label:`Components`},{id:`routes`,label:`Routes`},{id:`signals`,label:`Signals`},{id:`injectors`,label:`Injectors`},{id:`store`,label:`Store`},{id:`forms`,label:`Forms`}];tab=L(`dashboard`);rpc=L(null);connected=L(!1);ngOnInit(){let e=new URLSearchParams(location.hash.replace(/^#/,``)).get(`tab`);e&&this.tabs.some(t=>t.id===e)&&this.tab.set(e);let t=Ek();mw(t?{baseURL:t}:{}).then(e=>{this.rpc.set(e),this.connected.set(!0),e.events.on(`connection:status`,e=>{this.connected.set(e===`connected`)})})}ngOnDestroy(){}switchTab(e){this.tab.set(e),history.replaceState(history.state,``,`#tab=${e}`)}static ɵfac=function(t){return new(t||e)};static ɵcmp=Qp({type:e,selectors:[[`app-root`]],decls:27,vars:4,consts:[[1,`brand`],[`width`,`20`,`height`,`22`,`viewBox`,`0 0 223 236`,`fill`,`url(#ng-logo)`,`aria-hidden`,`true`],[`id`,`ng-logo`,`x1`,`49`,`x2`,`226`,`y1`,`214`,`y2`,`130`,`gradientUnits`,`userSpaceOnUse`],[`stop-color`,`#E40035`],[`offset`,`.24`,`stop-color`,`#F60A48`],[`offset`,`.352`,`stop-color`,`#F20755`],[`offset`,`.494`,`stop-color`,`#DC087D`],[`offset`,`.745`,`stop-color`,`#9717E7`],[`offset`,`1`,`stop-color`,`#6C00F5`],[`d`,`m222.077 39.192-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z`],[3,`active`],[1,`status`],[3,`rpc`],[3,`click`],[3,`navigate`,`rpc`]],template:function(e,t){if(e&1&&(G(0,`header`)(1,`h1`,0),$o(),G(2,`svg`,1)(3,`defs`)(4,`linearGradient`,2),Vh(5,`stop`,3)(6,`stop`,4)(7,`stop`,5)(8,`stop`,6)(9,`stop`,7)(10,`stop`,8),K()(),Vh(11,`path`,9),K(),es(),G(12,`span`),Z(13,`Angular DevTools`),K()(),G(14,`nav`),U(15,gk,2,3,`button`,10,hk),K(),G(17,`span`,11),Z(18),K()(),G(19,`main`),V(20,_k,1,1,`app-dashboard`,12)(21,vk,1,1,`app-component-tree`,12)(22,yk,1,1,`app-route-inspector`,12)(23,bk,1,1,`app-signal-inspector`,12)(24,xk,1,1,`app-di-inspector`,12)(25,Sk,1,1,`app-store-inspector`,12)(26,Ck,1,1,`app-forms-inspector`,12),K()),e&2){let e;B(15),W(t.tabs),B(2),Ag(`connected`,t.connected()),B(),$(` `,t.connected()?`Connected`:`Connecting…`,` `),B(2),H((e=t.tab())===`dashboard`?20:e===`components`?21:e===`routes`?22:e===`signals`?23:e===`injectors`?24:e===`store`?25:e===`forms`?26:-1)}},dependencies:[hw,Pw,uD,RD,sO,EO,mk],styles:[`[_nghost-%COMP%] { - display: flex; - flex-direction: column; - height: 100vh; - } - header[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 16px; - padding: 8px 16px; - background: #18181b; - border-bottom: 1px solid #27272a; - } - .brand[_ngcontent-%COMP%] { - margin: 0; - font-size: inherit; - display: flex; - align-items: center; - gap: 8px; - font-weight: 600; - color: var(--%NS%accent); - } - .brand[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { - color: var(--%NS%accent); - white-space: nowrap; - } - nav[_ngcontent-%COMP%] { - display: flex; - flex-wrap: wrap; - gap: 4px; - flex: 1; - min-width: 0; - } - @media (max-width: 640px) { - nav[_ngcontent-%COMP%] { - order: 3; - flex-basis: 100%; - } - } - nav[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { - padding: 6px 14px; - border: none; - border-radius: 6px; - background: transparent; - color: #a1a1aa; - cursor: pointer; - font-size: 13px; - transition: all 0.15s; - } - nav[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover { - background: #27272a; - color: #e4e4e7; - } - nav[_ngcontent-%COMP%] button.active[_ngcontent-%COMP%] { - background: #3f3f46; - color: #fff; - } - .status[_ngcontent-%COMP%] { - margin-left: auto; - font-size: 12px; - padding: 3px 10px; - border-radius: 99px; - background: #44403c; - color: #a8a29e; - } - .status.connected[_ngcontent-%COMP%] { - background: #14532d; - color: #4ade80; - } - main[_ngcontent-%COMP%] { - flex: 1; - overflow: auto; - padding: 16px; - }`]})};function Tk(e){try{return new URL(e,location.href).origin===location.origin}catch{return!1}}function Ek(){let e=new URLSearchParams(location.search).get(`baseURL`);if(e&&Tk(e))return e;if(!location.pathname.includes(`__ng-devtools`))return`/__ng-devtools/`}Oy(wk).catch(console.error);export{jb as t}; \ No newline at end of file diff --git a/extension/ui/index.html b/extension/ui/index.html index 65f7d36..79d5e18 100644 --- a/extension/ui/index.html +++ b/extension/ui/index.html @@ -5,7 +5,7 @@ Angular DevTools - + diff --git a/packages/ng-devtools/src/__tests__/forms-actions.test.ts b/packages/ng-devtools/src/__tests__/forms-actions.test.ts new file mode 100644 index 0000000..14fc2f5 --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-actions.test.ts @@ -0,0 +1,419 @@ +// @vitest-environment jsdom +import '@angular/compiler'; +import { Component, signal } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { + FormControl, + FormGroup, + FormsModule, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; +import { FormField, FormRoot, form, hidden, required } from '@angular/forms/signals'; +import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; +import { afterEach, describe, expect, it } from 'vitest'; +import { findForms } from '../forms.ts'; +import { + isFormAction, + keepSecrets, + runFormAction, + secretInside, + type ActionContext, +} from '../forms-actions.ts'; + +try { + TestBed.initTestEnvironment(BrowserTestingModule, platformBrowserTesting()); +} catch { + // already initialized in this worker +} + +afterEach(() => TestBed.resetTestingModule()); + +function contextFor(host: HTMLElement): ActionContext { + const ng = (globalThis as any).ng; + const all = () => host.querySelectorAll('*'); + const found = findForms(ng, all()); + const forms = new Map(found.forms.map((f, i) => [`form-${i + 1}`, f])); + return { ng, forms, elements: found.elements, all }; +} + +class Signup { + submits = 0; + form = new FormGroup({ + name: new FormControl('', Validators.required), + age: new FormControl(null), + password: new FormControl(''), + nickname: new FormControl({ value: 'kam', disabled: true }), + }); +} +Component({ + selector: 'signup-form', + imports: [ReactiveFormsModule], + template: ` +
    + + + + + +
    + `, +})(Signup); + +class Notes { + title = ''; +} +Component({ + selector: 'notes-form', + imports: [FormsModule], + template: `
    `, +})(Notes); + +class Profile { + saved: unknown[] = []; + model = signal({ name: '', promo: '' }); + form = form( + this.model, + (p) => { + required(p.name); + hidden(p.promo, () => true); + }, + { submission: { action: async (f) => void this.saved.push(f().value()) } }, + ); +} +Component({ + selector: 'profile-form', + imports: [FormField, FormRoot], + template: `
    `, +})(Profile); + +async function render(type: new () => T) { + const fixture = TestBed.createComponent(type); + fixture.detectChanges(); + await fixture.whenStable(); + fixture.detectChanges(); + return fixture; +} + +describe('form actions on reactive forms', () => { + it('types through the input, refuses secrets and disabled fields', async () => { + const fixture = await render(Signup); + const ctx = contextFor(fixture.nativeElement); + const form = fixture.componentInstance.form; + + let result = await runFormAction(ctx, { + action: 'set-value', + formId: 'form-1', + path: 'age', + value: 42, + mode: 'user', + }); + expect(result.ok).toBe(true); + expect(form.controls.age.value).toBe(42); + expect(form.controls.age.dirty).toBe(true); + + result = await runFormAction(ctx, { + action: 'set-value', + formId: 'form-1', + path: 'password', + value: 'x', + }); + expect(result).toMatchObject({ ok: false }); + expect(result.error).toContain('looks secret'); + expect(form.controls.password.value).toBe(''); + + result = await runFormAction(ctx, { + action: 'set-value', + formId: 'form-1', + path: 'nickname', + value: 'ada', + }); + expect(result.error).toContain('disabled (pass force'); + result = await runFormAction(ctx, { + action: 'set-value', + formId: 'form-1', + path: 'nickname', + value: 'ada', + force: true, + }); + expect(form.controls.nickname.value).toBe('ada'); + }); + + it('needs confirm for submit and reset, then submits through the
    ', async () => { + const fixture = await render(Signup); + const ctx = contextFor(fixture.nativeElement); + const refused = await runFormAction(ctx, { action: 'submit', formId: 'form-1' }); + expect(refused.error).toContain('confirm: true'); + expect(fixture.componentInstance.submits).toBe(0); + const result = await runFormAction(ctx, { action: 'submit', formId: 'form-1', confirm: true }); + expect(result).toMatchObject({ ok: true, status: 'INVALID', invalid: ['name'] }); + expect(fixture.componentInstance.submits).toBe(1); + }); + + it('marks, focuses the first invalid field and stores the form as a global', async () => { + const fixture = await render(Signup); + document.body.appendChild(fixture.nativeElement); + const ctx = contextFor(fixture.nativeElement); + await runFormAction(ctx, { action: 'touch-all', formId: 'form-1' }); + expect(fixture.componentInstance.form.controls.name.touched).toBe(true); + const focus = await runFormAction(ctx, { action: 'focus-first-invalid', formId: 'form-1' }); + expect(focus.path).toBe('name'); + expect(document.activeElement?.id).toBe('name'); + const stored = await runFormAction(ctx, { + action: 'store-as-global', + formId: 'form-1', + path: 'name', + }); + expect(stored.expression).toBe("$form.get('name')"); + expect((window as any).$control).toBe(fixture.componentInstance.form.controls.name); + fixture.nativeElement.remove(); + }); + + it('snapshots and restores values, and locates a field by selector', async () => { + const fixture = await render(Signup); + const ctx = contextFor(fixture.nativeElement); + const form = fixture.componentInstance.form; + form.controls.name.setValue('Ada'); + const snap = await runFormAction(ctx, { action: 'snapshot', formId: 'form-1' }); + form.controls.name.setValue('Bob'); + expect( + (await runFormAction(ctx, { action: 'restore', formId: 'form-1', snapshot: snap.snapshot })) + .ok, + ).toBe(false); + await runFormAction(ctx, { + action: 'restore', + formId: 'form-1', + snapshot: snap.snapshot, + confirm: true, + }); + expect(form.controls.name.value).toBe('Ada'); + + document.body.appendChild(fixture.nativeElement); + expect(await runFormAction(ctx, { action: 'locate', selector: '#age' })).toMatchObject({ + ok: true, + formId: 'form-1', + path: 'age', + }); + expect((await runFormAction(ctx, { action: 'locate', selector: '[[' })).error).toContain( + 'not a valid CSS selector', + ); + fixture.nativeElement.remove(); + }); + + it('fills several fields and lists the skipped ones', async () => { + const fixture = await render(Signup); + const ctx = contextFor(fixture.nativeElement); + const result = await runFormAction(ctx, { + action: 'fill', + formId: 'form-1', + values: { name: 'Ada', password: 'secret', missing: 1 }, + }); + expect(result.skipped?.map((s) => s.path)).toEqual(['password', 'missing']); + expect(result).toMatchObject({ ok: true, status: 'VALID' }); + expect(fixture.componentInstance.form.controls.name.value).toBe('Ada'); + }); +}); + +describe('form actions on template-driven and Signal Forms', () => { + it('writes ngModel through the input so the component property updates', async () => { + const fixture = await render(Notes); + const ctx = contextFor(fixture.nativeElement); + const result = await runFormAction(ctx, { + action: 'set-value', + formId: 'form-1', + path: 'title', + value: 'Hello', + }); + expect(result.ok).toBe(true); + expect(fixture.componentInstance.title).toBe('Hello'); + expect( + (await runFormAction(ctx, { action: 'disable', formId: 'form-1', path: 'title' })).error, + ).toContain('ngModel'); + }); + + it('writes Signal Forms fields, refuses hidden ones and submits through the form root', async () => { + const fixture = await render(Profile); + const ctx = contextFor(fixture.nativeElement); + const component = fixture.componentInstance; + expect( + ( + await runFormAction(ctx, { + action: 'set-value', + formId: 'form-1', + path: 'promo', + value: '1', + }) + ).error, + ).toContain('is hidden'); + expect((await runFormAction(ctx, { action: 'disable', formId: 'form-1' })).error).toContain( + 'disabled() rules', + ); + await runFormAction(ctx, { action: 'set-value', formId: 'form-1', path: 'name', value: 'Ada' }); + expect(component.model().name).toBe('Ada'); + const submitted = await runFormAction(ctx, { + action: 'submit', + formId: 'form-1', + confirm: true, + }); + expect(submitted.message).toContain('the action runs'); + await new Promise((resolve) => setTimeout(resolve, 0)); + expect(component.saved).toEqual([{ name: 'Ada', promo: '' }]); + }); +}); + +describe('secret safety for group writes', () => { + it('refuses a group write that would touch a secret field', async () => { + const fixture = await render(Signup); + const ctx = contextFor(fixture.nativeElement); + const account = new FormGroup({ + account: new FormGroup({ name: new FormControl('a'), apiKey: new FormControl('k') }), + }); + ctx.forms.set('form-3', { kind: 'reactive', root: account as never, owner: null }); + const result = await runFormAction(ctx, { + action: 'set-value', + formId: 'form-3', + path: 'account', + value: { name: 'b', apiKey: 'stolen' }, + }); + expect(result.error).toContain('secret field "apiKey"'); + expect(account.controls.account.controls.apiKey.value).toBe('k'); + const allowed = await runFormAction(ctx, { + action: 'set-value', + formId: 'form-3', + path: 'account.name', + value: 'b', + }); + expect(allowed.ok).toBe(true); + }); + + it('finds secrets inside values and keeps them on restore', () => { + expect(secretInside({ account: { apiKey: 'x' } })).toBe('account.apiKey'); + expect(secretInside({ items: [{ name: 'a' }] })).toBeNull(); + expect(keepSecrets({ name: 'old', password: 'old' }, { name: 'new', password: 'now' })).toEqual( + { + name: 'old', + password: 'now', + }, + ); + }); + + it('refuses to restore a snapshot into another form', async () => { + const fixture = await render(Signup); + const ctx = contextFor(fixture.nativeElement); + const other = { + ...ctx.forms.get('form-1')!, + root: new FormGroup({ name: new FormControl('') }), + }; + ctx.forms.set('form-2', other as never); + const snap = await runFormAction(ctx, { action: 'snapshot', formId: 'form-1' }); + const result = await runFormAction(ctx, { + action: 'restore', + formId: 'form-2', + snapshot: snap.snapshot, + confirm: true, + }); + expect(result.error).toContain('another form'); + }); +}); + +class Security { + form = new FormGroup({ + question: new FormControl('first pet'), + answer: new FormControl('rex'), + }); +} +Component({ + selector: 'security-form', + imports: [ReactiveFormsModule], + template: ` + + + +
    + `, +})(Security); + +describe('protected descendants', () => { + it('finds a secret nested deeper than any fixed limit', async () => { + const fixture = await render(Signup); + const ctx = contextFor(fixture.nativeElement); + let inner: FormGroup = new FormGroup({ apiKey: new FormControl('k') }); + const value: Record = { apiKey: 'stolen' }; + let wrapped: Record = value; + for (let i = 0; i < 15; i++) { + inner = new FormGroup({ level: inner }); + wrapped = { level: wrapped }; + } + ctx.forms.set('deep', { kind: 'reactive', root: inner as never, owner: null }); + const result = await runFormAction(ctx, { + action: 'set-value', + formId: 'deep', + path: '', + value: wrapped, + }); + expect(result.ok).toBe(false); + expect(JSON.stringify(inner.getRawValue())).toContain('"apiKey":"k"'); + }); + + it('keeps a password-input field on restore even when its name looks harmless', async () => { + const fixture = await render(Security); + document.body.appendChild(fixture.nativeElement); + const ctx = contextFor(fixture.nativeElement); + const form = fixture.componentInstance.form; + const snap = await runFormAction(ctx, { action: 'snapshot', formId: 'form-1' }); + form.controls.answer.setValue('fido'); + form.controls.question.setValue('first car'); + await runFormAction(ctx, { + action: 'restore', + formId: 'form-1', + snapshot: snap.snapshot, + confirm: true, + }); + expect(form.controls.question.value).toBe('first pet'); + expect(form.controls.answer.value).toBe('fido'); + fixture.nativeElement.remove(); + }); + + it('refuses a group write that changes a hidden Signal Forms child, and restore keeps it', async () => { + const fixture = await render(Profile); + const ctx = contextFor(fixture.nativeElement); + const component = fixture.componentInstance; + const refused = await runFormAction(ctx, { + action: 'set-value', + formId: 'form-1', + path: '', + value: { name: 'Ada', promo: 'FREE' }, + }); + expect(refused.error).toContain('would change promo, which is hidden'); + const allowed = await runFormAction(ctx, { + action: 'set-value', + formId: 'form-1', + path: '', + value: { name: 'Ada', promo: '' }, + }); + expect(allowed.ok).toBe(true); + const snap = await runFormAction(ctx, { action: 'snapshot', formId: 'form-1' }); + component.model.set({ name: 'Bob', promo: 'LATER' }); + await runFormAction(ctx, { + action: 'restore', + formId: 'form-1', + snapshot: snap.snapshot, + confirm: true, + }); + expect(component.model()).toEqual({ name: 'Ada', promo: 'LATER' }); + }); +}); + +describe('request validation', () => { + it('accepts known actions and rejects the rest', () => { + expect(isFormAction({ action: 'focus', formId: 'form-1' })).toBe(true); + expect(isFormAction({ action: 'eval', formId: 'form-1' })).toBe(false); + expect( + isFormAction({ + action: 'fill', + values: Object.fromEntries(Array.from({ length: 201 }, (_, i) => [`k${i}`, i])), + }), + ).toBe(false); + expect(isFormAction({ action: 'focus', path: 'x'.repeat(600) })).toBe(false); + }); +}); diff --git a/packages/ng-devtools/src/__tests__/forms-collector.test.ts b/packages/ng-devtools/src/__tests__/forms-collector.test.ts new file mode 100644 index 0000000..56d3fa3 --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-collector.test.ts @@ -0,0 +1,251 @@ +// @vitest-environment jsdom +import '@angular/compiler'; +import { Component, signal } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { FormField, FormRoot, form, required } from '@angular/forms/signals'; +import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; +import { afterEach, describe, expect, it } from 'vitest'; +import { attachForms, setupErrorOf } from '../forms-collector.ts'; +import type { FormEvent } from '../forms.ts'; + +try { + TestBed.initTestEnvironment(BrowserTestingModule, platformBrowserTesting()); +} catch { + // already initialized in this worker +} + +const stops: (() => void)[] = []; +afterEach(() => { + stops.splice(0).forEach((stop) => stop()); + TestBed.resetTestingModule(); + document.body.innerHTML = ''; +}); + +class Login { + form = new FormGroup({ + email: new FormControl('', Validators.required), + }); +} +Component({ + selector: 'login-form', + imports: [ReactiveFormsModule], + template: `
    `, +})(Login); + +class Profile { + form = form(signal({ name: '' }), (p) => required(p.name), { + submission: { action: async () => undefined }, + }); +} +Component({ + selector: 'profile-form', + imports: [FormField, FormRoot], + template: `
    `, +})(Profile); + +function harness() { + const calls: { name: string; args: any[] }[] = []; + const handlers = new Map unknown>(); + const my = { + rpc: { + call: async (name: string, ...args: unknown[]) => { + calls.push({ name, args }); + }, + register: (def: { name: string; handler: (...args: any[]) => unknown }) => { + handlers.set(def.name, def.handler); + }, + }, + }; + const collector = attachForms(my, 'pg', () => (globalThis as any).ng, { + show: () => {}, + clear: () => {}, + }); + stops.push(collector.stop); + const reports = () => calls.filter((c) => c.name === 'push-forms').map((c) => c.args[0]); + const lastEvents = (): FormEvent[] => reports().at(-1)?.events ?? []; + return { calls, handlers, collector, reports, lastEvents }; +} + +const tick = (ms = 120) => new Promise((resolve) => setTimeout(resolve, ms)); + +async function mount(type: new () => T) { + const fixture = TestBed.createComponent(type); + document.body.appendChild(fixture.nativeElement); + fixture.detectChanges(); + await fixture.whenStable(); + return fixture; +} + +describe('forms collector', () => { + it('tags typing as user and code changes as code, with prev and repeat counts', async () => { + const fixture = await mount(Login); + const h = harness(); + h.collector.push(); + await tick(); + const input = document.getElementById('email') as HTMLInputElement; + for (const text of ['a', 'ab', 'abc']) { + input.value = text; + input.dispatchEvent(new Event('input', { bubbles: true })); + } + await tick(); + fixture.componentInstance.form.controls.email.setValue('code@x.io'); + await tick(); + const values = h.lastEvents().filter((e) => e.type === 'value' && e.path === 'email'); + expect(values[0]).toMatchObject({ origin: 'user', count: 3, detail: '"abc"', prev: '""' }); + expect(values[1]).toMatchObject({ origin: 'code', detail: '"code@x.io"', prev: '"abc"' }); + expect(h.reports().at(-1).forms[0].submitDom.buttons).toBe(1); + }); + + it('records Signal Forms submits as blocked or ran', async () => { + const fixture = await mount(Profile); + const h = harness(); + h.collector.push(); + await tick(); + const formEl = fixture.nativeElement.querySelector('form') as HTMLFormElement; + formEl.requestSubmit(); + await tick(); + fixture.componentInstance.form.name().value.set('Ada'); + formEl.requestSubmit(); + await tick(); + const submits = h.lastEvents().filter((e) => e.type === 'submit'); + expect(submits.map((e) => e.outcome)).toEqual(['blocked', 'ran']); + }); + + it('tags Signal Forms changes found by diffing as user or unknown', async () => { + const fixture = await mount(Profile); + const h = harness(); + h.collector.push(); + await tick(); + const input = document.getElementById('pname') as HTMLInputElement; + input.value = 'Ada'; + input.dispatchEvent(new Event('input', { bubbles: true })); + await tick(); + fixture.componentInstance.form.name().value.set('Bob'); + h.collector.push(); + await tick(); + const values = h.lastEvents().filter((e) => e.type === 'value' && e.path === 'name'); + expect(values.map((e) => [e.detail, e.origin])).toEqual([ + ['"Ada"', 'user'], + ['"Bob"', undefined], + ]); + }); + + it('answers form actions for its own forms only', async () => { + const fixture = await mount(Login); + const h = harness(); + h.collector.push(); + await tick(); + const formId = h.reports().at(-1).forms[0].id; + h.handlers.get('form-action')!({ + requestId: 'r1', + pageId: 'other', + request: { action: 'touch-all', formId }, + }); + h.handlers.get('form-action')!({ + requestId: 'r2', + pageId: 'pg', + request: { action: 'touch-all', formId }, + }); + h.handlers.get('form-action')!({ requestId: 'r3', request: { action: 'drop-tables', formId } }); + await tick(200); + const answers = h.calls.filter((c) => c.name === 'form-action-result').map((c) => c.args[0]); + expect(answers.map((a) => a.requestId)).toEqual(['r3', 'r2']); + expect(answers[0].result.error).toBe('Unknown form action.'); + expect(answers[1].result).toMatchObject({ ok: true }); + expect(fixture.componentInstance.form.controls.email.touched).toBe(true); + }); + + it('records callers, validator changes and async timing once instrumented', async () => { + const fixture = await mount(Login); + const h = harness(); + h.collector.push(); + await tick(); + const formId = h.reports().at(-1).forms[0].id; + h.handlers.get('form-action')!({ + requestId: 'i1', + request: { action: 'instrument', formId, value: true }, + }); + await tick(); + expect(h.reports().at(-1).instrumented).toBe(true); + const email = fixture.componentInstance.form.controls.email; + function prefillFromProfile() { + email.setValue('kam@example.com'); + } + prefillFromProfile(); + function checkAvailability() { + email.setAsyncValidators(() => new Promise((resolve) => setTimeout(() => resolve(null), 40))); + } + checkAvailability(); + email.updateValueAndValidity(); + await tick(200); + const events = h.lastEvents(); + const value = events.find((e) => e.type === 'value' && e.detail === '"kam@example.com"'); + expect(value).toMatchObject({ origin: 'code' }); + expect(value?.caller).toContain('prefillFromProfile'); + expect(events.find((e) => e.type === 'validators')).toMatchObject({ + path: 'email', + detail: 'setAsyncValidators', + }); + const settled = events.filter( + (e) => e.type === 'status' && e.path === 'email' && e.ms !== undefined, + ); + expect(settled.at(-1)!.ms).toBeGreaterThanOrEqual(30); + h.handlers.get('form-action')!({ + requestId: 'i2', + request: { action: 'instrument', formId, value: false }, + }); + await tick(); + expect(h.reports().at(-1).instrumented).toBe(false); + }); + + it('lets the user pick a field on the page', async () => { + await mount(Login); + const h = harness(); + h.collector.push(); + await tick(); + const formId = h.reports().at(-1).forms[0].id; + h.handlers.get('form-action')!({ requestId: 'p1', request: { action: 'pick', formId } }); + await tick(20); + const clicked = document.getElementById('email')!; + let reachedApp = false; + clicked.addEventListener('click', () => (reachedApp = true)); + clicked.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true })); + await tick(20); + const answer = h.calls.find((c) => c.name === 'form-action-result')!.args[0]; + expect(answer.result).toMatchObject({ ok: true, formId, path: 'email' }); + expect(reachedApp).toBe(false); + }); + + it('captures NG01xxx setup errors from console.error without leaking tokens', async () => { + const original = console.error; + console.error = () => {}; + try { + const h = harness(); + console.error(new Error("NG01203: No value accessor for form control name: 'age'")); + console.error('unrelated'); + await tick(); + expect(h.reports().at(-1)?.setupErrors).toEqual([ + "NG01203: No value accessor for form control name: 'age'", + ]); + } finally { + stops.splice(0).forEach((stop) => stop()); + console.error = original; + } + expect( + setupErrorOf([ + 'NG01050: formControlName must be used with a parent formGroup Bearer abc.def', + ]), + ).toContain('Bearer [redacted]'); + expect(setupErrorOf(['plain error'])).toBeNull(); + }); + + it('restores console.error and stops listening on stop', () => { + const original = console.error; + const h = harness(); + expect(console.error).not.toBe(original); + stops.pop()!(); + expect(console.error).toBe(original); + expect(h.calls).toEqual([]); + }); +}); diff --git a/packages/ng-devtools/src/__tests__/forms-instrument.test.ts b/packages/ng-devtools/src/__tests__/forms-instrument.test.ts new file mode 100644 index 0000000..2d580de --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-instrument.test.ts @@ -0,0 +1,161 @@ +// @vitest-environment jsdom +import '@angular/compiler'; +import { signal } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms'; +import { form } from '@angular/forms/signals'; +import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; +import { describe, expect, it } from 'vitest'; +import { collectForms, diffForms } from '../forms.ts'; +import { + TEMPLATE_UPDATE_START, + callerFrom, + countRenders, + instrumentForms, + type InstrumentCall, +} from '../forms-instrument.ts'; + +try { + TestBed.initTestEnvironment(BrowserTestingModule, platformBrowserTesting()); +} catch { + // already initialized in this worker +} + +describe('caller frames', () => { + it('skips framework and devtools frames and trims URLs', () => { + const stack = [ + 'Error', + ' at FormControl.setValue (http://localhost:4200/@fs/x/node_modules/.vite/deps/@angular_forms.js:10:5)', + ' at wrapper (http://localhost:4200/@fs/x/ng-devtools/src/forms-instrument.ts:88:12)', + ' at CheckoutPage.applyCoupon (http://localhost:4200/src/app/checkout.ts?t=123:42:17)', + ' at onClick (http://localhost:4200/src/app/checkout.ts:10:1)', + ].join('\n'); + expect(callerFrom(stack)).toBe('CheckoutPage.applyCoupon (src/app/checkout.ts:42:17)'); + expect(callerFrom('Error\n at Subscriber.next (rxjs.js:1:1)')).toBeUndefined(); + expect(callerFrom(undefined)).toBeUndefined(); + }); + + it('prefers the form owner and skips Angular internals bundled into app chunks', () => { + const bundled = [ + 'Error', + ' at updateControl (http://localhost:4100/chunk-BTUX.js:1923:11)', + ' at Object.next (http://localhost:4100/chunk-BTUX.js:1210:14)', + ' at OperatorSubscriber._next (http://localhost:4100/chunk-4PW.js:1141:9)', + ' at DefaultValueAccessor_input_HostBindingHandler (http://localhost:4100/chunk-BTUX.js:257:22)', + ' at _FormControlName.ngOnChanges (http://localhost:4100/chunk-BTUX.js:900:3)', + ' at CartService.load (http://localhost:4100/main.js:40:3)', + ' at _ReactiveFormExample.addPhone (http://localhost:4100/chunk-BTUX.js:5213:34)', + ].join('\n'); + expect(callerFrom(bundled, new Set(['ReactiveFormExample']))).toBe( + 'ReactiveFormExample.addPhone (chunk-BTUX.js:5213:34)', + ); + expect(callerFrom(bundled)).toBe('CartService.load (main.js:40:3)'); + expect( + callerFrom( + 'Error\n at setUpValidators (chunk.js:1:1)\n at executeTemplate (chunk.js:2:2)', + ), + ).toBeUndefined(); + }); +}); + +describe('instrumentation', () => { + it('reports the outermost reactive call and restores the prototypes', () => { + const calls: InstrumentCall[] = []; + const group = new FormGroup({ a: new FormControl(''), b: new FormControl('') }); + const original = Object.getPrototypeOf(group).patchValue; + const instrumentation = instrumentForms((call) => calls.push(call)); + instrumentation.addControl(group); + function applyDefaults() { + group.patchValue({ a: 'x', b: 'y' }); + } + applyDefaults(); + group.controls.a.setValidators(Validators.required); + expect(calls.map((c) => c.method)).toEqual(['patchValue', 'setValidators']); + expect(calls[0].caller).toContain('applyDefaults'); + expect(calls[1].target).toBe(group.controls.a); + instrumentation.stop(); + expect(Object.getPrototypeOf(group).patchValue).toBe(original); + group.patchValue({ a: 'z' }); + expect(calls).toHaveLength(2); + }); + + it('wraps a Signal Forms root model, which child writes go through', () => { + const calls: InstrumentCall[] = []; + const tree = TestBed.runInInjectionContext(() => form(signal({ name: '', age: 1 }))); + const root = tree() as never; + const instrumentation = instrumentForms((call) => calls.push(call)); + instrumentation.addSignalRoot(root); + tree.name().value.set('Ada'); + expect(calls).toHaveLength(1); + expect(calls[0].method).toBe('update'); + expect(calls[0].signalRoot).toBe(root); + instrumentation.stop(); + tree.age().value.set(2); + expect(calls).toHaveLength(1); + expect(tree().value()).toEqual({ name: 'Ada', age: 2 }); + }); + + it('counts template updates per component through a chained profiler', () => { + let profiler: ((event: number, instance: unknown) => void) | null = null; + let removed = false; + const ng = { + ɵsetProfiler: (fn: typeof profiler) => { + profiler = fn; + return () => (removed = true); + }, + }; + const counter = countRenders(ng)!; + class Checkout { + static ɵcmp = {}; + } + class Summary { + static ɵcmp = {}; + } + class RepeaterContext {} + profiler!(TEMPLATE_UPDATE_START, new Checkout()); + counter.start(); + profiler!(TEMPLATE_UPDATE_START, new Checkout()); + profiler!(TEMPLATE_UPDATE_START, new Checkout()); + profiler!(TEMPLATE_UPDATE_START, new Summary()); + profiler!(0, new Summary()); + profiler!(TEMPLATE_UPDATE_START, new RepeaterContext()); + expect(counter.take()).toEqual({ total: 3, top: ['Checkout×2', 'Summary×1'] }); + expect(counter.take()).toBeNull(); + counter.stop(); + expect(removed).toBe(true); + expect(countRenders({})).toBeNull(); + }); +}); + +describe('array identity', () => { + it('reports moves, inserts and removals by control identity, without value noise', () => { + const items = new FormArray([new FormControl('a'), new FormControl('b'), new FormControl('c')]); + const group = new FormGroup({ items }); + const snapshot = () => + collectForms( + { + forms: [{ kind: 'reactive', root: group as never, owner: null }], + elements: new WeakMap(), + }, + () => 'f', + ); + const before = snapshot(); + const moved = items.at(2); + items.removeAt(2); + items.insert(0, moved); + items.removeAt(2); + items.push(new FormControl('d')); + const events = diffForms(before, snapshot()).map((e) => + `${e.type} ${e.path} ${e.detail ?? ''}`.trim(), + ); + expect(events).toEqual( + expect.arrayContaining([ + 'moved items.0 items.2 → items.0', + 'moved items.1 items.0 → items.1', + 'added items.2 inserted at 2', + 'removed items.1 was at 1', + ]), + ); + expect(events.filter((e) => e.startsWith('value'))).toEqual([]); + }); +}); diff --git a/packages/ng-devtools/src/__tests__/forms-lint.test.ts b/packages/ng-devtools/src/__tests__/forms-lint.test.ts new file mode 100644 index 0000000..9ae2825 --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-lint.test.ts @@ -0,0 +1,119 @@ +import { describe, expect, it } from 'vitest'; +import type { CollectedForm, FormFieldNode } from '../forms.ts'; +import { lintForm } from '../rpc/forms-lint.ts'; + +function leaf(key: string, extra: Partial = {}): FormFieldNode { + return { + key, + path: key, + type: 'control', + status: 'VALID', + touched: false, + dirty: false, + bound: true, + errors: [], + dom: { labelled: true }, + ...extra, + }; +} + +function formOf(kind: CollectedForm['kind'], children: FormFieldNode[]): CollectedForm { + return { + id: 'form-1@p', + kind, + owner: 'C', + label: 'C.form', + root: { + key: '', + path: '', + type: 'group', + status: 'VALID', + touched: false, + dirty: false, + bound: false, + errors: [], + children, + }, + }; +} + +const rules = (form: CollectedForm) => + lintForm(form, [], 10_000).map((f) => `${f.rule}:${f.path ?? ''}`); + +describe('forms lint', () => { + it('stays quiet on a clean form', () => { + expect( + rules( + formOf('reactive', [ + leaf('a'), + leaf('b', { dom: { labelled: true, required: true }, validatorNames: ['required'] }), + ]), + ), + ).toEqual([]); + }); + + it('flags Signal Forms schema problems', () => { + const form = formOf('signal', [ + leaf('promo', { hidden: true, hiddenBy: 'self' }), + leaf('bio', { required: true, bound: false, dom: undefined }), + leaf('name', { + status: 'INVALID', + errors: [{ kind: 'taken', message: 'Taken', source: 'submission' }], + dom: { labelled: true }, + }), + ]); + expect(rules(form)).toEqual( + expect.arrayContaining([ + 'hidden-field-rendered:promo', + 'unbound-required:bio', + 'submission-error:name', + ]), + ); + }); + + it('flags reactive view problems', () => { + const form = formOf('reactive', [ + leaf('a', { dom: { labelled: true, disabled: true } }), + leaf('b', { modelDrift: { model: 1, viewModel: 2 } }), + leaf('c', { pendingSince: 1000, status: 'PENDING' }), + ]); + expect(rules(form)).toEqual( + expect.arrayContaining(['disabled-attr-reactive:a', 'ngmodel-drift:b', 'stuck-pending:c']), + ); + }); + + it('flags model-aware accessibility gaps', () => { + const invalid = { + status: 'INVALID' as const, + touched: true, + errors: [{ kind: 'required', message: 'is required' }], + }; + const form = formOf('reactive', [ + leaf('a', { + ...invalid, + dom: { labelled: true, ariaInvalid: false, required: true, errorShown: false }, + }), + leaf('b', { ...invalid, dom: { labelled: true, required: true, errorShown: true } }), + leaf('c', { ...invalid, dom: { labelled: true, errorShown: true, describedBy: true } }), + ]); + expect(rules(form)).toEqual( + expect.arrayContaining([ + 'aria-invalid-desync:a', + 'error-not-shown:a', + 'error-not-described:b', + 'required-not-exposed:c', + ]), + ); + expect(rules(form)).not.toContain('error-not-described:c'); + }); + + it('matches aria-invalid against invalid and touched', () => { + const form = formOf('reactive', [ + leaf('a', { status: 'INVALID', touched: false, dom: { labelled: true, ariaInvalid: false } }), + leaf('b', { status: 'VALID', dom: { labelled: true, ariaInvalid: true } }), + leaf('c', { status: 'INVALID', touched: true, dom: { labelled: true, ariaInvalid: true } }), + ]); + const found = rules(form).filter((rule) => rule.startsWith('aria-invalid-desync')); + expect(found).toEqual(['aria-invalid-desync:b']); + }); +}); diff --git a/packages/ng-devtools/src/__tests__/forms-mcp.test.ts b/packages/ng-devtools/src/__tests__/forms-mcp.test.ts new file mode 100644 index 0000000..c61ffd0 --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-mcp.test.ts @@ -0,0 +1,507 @@ +import { createHostContext } from 'devframe/node'; +import { describe, expect, it, vi } from 'vitest'; +import ngDevtools from '../devframe.ts'; +import type { CollectedForm, FormEvent, FormFieldNode } from '../forms.ts'; + +async function boot() { + const host = { + mountStatic: () => {}, + resolveOrigin: () => 'http://localhost', + getStorageDir: () => '', + }; + const ctx = await createHostContext({ cwd: process.cwd(), mode: 'dev', host: host as never }); + await ngDevtools.setup(ctx as never); + const push = (name: string, payload: unknown) => + ctx.rpc.invokeLocal(`ng-devtools:${name}` as never, ...([payload] as never)); + const call = async (tool: string, args: Record = {}) => + ((await ctx.agent.invoke(`ng-devtools:${tool}`, args)) as { markdown: string }).markdown; + return { ctx, push, call }; +} + +function leaf(key: string, extra: Partial = {}): FormFieldNode { + return { + key, + path: key, + type: 'control', + status: 'VALID', + touched: false, + dirty: false, + bound: true, + errors: [], + value: '', + ...extra, + }; +} + +const signup: CollectedForm = { + id: 'form-1@pg1', + kind: 'reactive', + owner: 'Signup', + property: 'form', + label: 'Signup.form', + submitted: false, + submitDom: { + tag: 'form', + buttons: 0, + disabledButtons: 0, + novalidate: true, + nativeInvalid: 0, + reasons: [ + 'No submit button: the buttons in this form are type="button", so clicking them does not submit.', + ], + }, + root: { + key: 'form', + path: '', + type: 'group', + status: 'INVALID', + touched: true, + dirty: true, + bound: false, + errors: [], + children: [ + leaf('email', { + status: 'INVALID', + touched: true, + value: 'x', + errors: [{ kind: 'email', message: 'is not a valid email address', source: 'own' }], + validatorNames: ['email', 'required (template)'], + binding: { kind: 'native', accessor: 'DefaultValueAccessor', element: 'input' }, + dom: { labelled: false, errorShown: false, required: true }, + }), + leaf('password', { value: '[redacted]', redacted: 'key' }), + leaf('nickname', { status: 'DISABLED', value: 'kam' }), + leaf('age', { + value: 3, + stale: ['min'], + updateOn: 'blur', + uncommitted: 30, + binding: { + kind: 'accessor', + accessor: 'AgePicker', + element: 'age-picker', + disabledHook: false, + }, + dom: { drift: '7', labelled: true }, + }), + leaf('code', { status: 'PENDING', pendingSince: Date.now() - 9000 }), + ], + }, +}; + +const profile: CollectedForm = { + id: 'form-2@pg2', + kind: 'signal', + owner: 'Profile', + property: 'form', + label: 'Profile.form', + submit: { hasAction: false, hasOnInvalid: false, submitting: false, willRun: true }, + submitDom: { + tag: 'form', + buttons: 1, + disabledButtons: 0, + novalidate: true, + nativeInvalid: 0, + reasons: [], + }, + root: { + key: 'form', + path: '', + type: 'group', + status: 'INVALID', + touched: false, + dirty: false, + bound: false, + errors: [], + children: [ + leaf('confirm', { + status: 'INVALID', + errors: [{ kind: 'mismatch', message: 'Must match', source: 'tree', from: '' }], + rules: { tree: 1 }, + }), + leaf('card', { hidden: true, skipped: 'hidden', required: true }), + leaf('bio', { required: true, bound: false }), + ], + }, +}; + +const events: FormEvent[] = [ + { + formId: 'form-1@pg1', + path: 'email', + type: 'value', + detail: '"x"', + prev: '""', + origin: 'user', + count: 3, + timestamp: 1000, + seq: 1, + }, + { + formId: 'form-1@pg1', + path: 'email', + type: 'status', + detail: 'VALID → INVALID', + origin: 'user', + timestamp: 1001, + seq: 2, + }, + { + formId: 'form-1@pg1', + path: '', + type: 'submit', + detail: 'status INVALID at submit', + outcome: 'ran', + origin: 'user', + timestamp: 1002, + seq: 3, + }, + { + formId: 'form-1@pg1', + path: 'email', + type: 'value', + detail: '"xy"', + prev: '"x"', + origin: 'code', + timestamp: 1003, + seq: 4, + }, +]; + +async function withForms() { + const booted = await boot(); + await booted.push('push-forms', { + pageId: 'pg1', + forms: [signup], + events, + setupErrors: [ + "NG01203: No value accessor for form control name: 'age'", + 'NG01050: formControlName in page header must be inside a formGroup', + ], + }); + await booted.push('push-forms', { pageId: 'pg2', forms: [profile], events: [] }); + return booted; +} + +describe('forms MCP tools', () => { + it('every tool says so when no page reported forms', async () => { + const { call } = await boot(); + for (const tool of [ + 'inspect-forms', + 'explain-form-invalid', + 'explain-field', + 'explain-submit', + 'form-payload', + 'form-history', + 'form-diff', + 'lint-forms', + 'explain-custom-control', + 'export-form', + 'form-action', + 'fill-form', + ]) { + expect(await call(tool, { form: 'x', action: 'focus', values: {} }), tool).toMatch( + /No forms have been reported/, + ); + } + }); + + it('inspect-forms and explain-form-invalid filter by page and label sources', async () => { + const { call } = await withForms(); + const list = await call('inspect-forms', { page: 'pg2' }); + expect(list).toContain('Profile.form'); + expect(list).not.toContain('Signup.form'); + const explained = await call('explain-form-invalid', { form: 'Signup' }); + expect(explained).toContain( + '[email] is not a valid email address (validator; touched: yes, error not shown)', + ); + expect(explained).toContain('validators now report min'); + expect(explained).toMatch(/`code` = "" is waiting for an async validator for \d+s/); + expect(await call('explain-form-invalid', { form: 'Profile' })).toContain( + 'cross-field rule on the form', + ); + }); + + it('explain-field covers sources, uncommitted input, bindings and DOM', async () => { + const { call } = await withForms(); + const email = await call('explain-field', { form: 'form-1', path: 'email' }); + expect(email).toContain('[email] is not a valid email address (validator)'); + expect(email).toContain('Validators: email, required (template).'); + expect(email).toContain("through Angular's DefaultValueAccessor"); + expect(email).toContain('no accessible label'); + expect(email).toMatch(/#4 .* value "x" → "xy" \(code\)/); + const age = await call('explain-field', { form: 'form-1', path: 'age' }); + expect(age).toContain('Uncommitted: the input holds 30, which reaches the model on blur.'); + expect(age).toContain('Stale:'); + const card = await call('explain-field', { form: 'Profile', path: 'card' }); + expect(card).toContain('Validation is skipped because the field is hidden.'); + expect(await call('explain-field', { form: 'Profile', path: 'nope' })).toContain( + 'No field at `nope`', + ); + }); + + it('explain-field resolves a selector through the page', async () => { + const { ctx, call } = await withForms(); + const broadcast = vi.spyOn(ctx.rpc, 'broadcast').mockImplementation((async (options: any) => { + const { requestId, request } = options.args[0]; + expect(request).toEqual({ action: 'locate', selector: '#email' }); + await ctx.rpc.invokeLocal( + 'ng-devtools:form-action-result' as never, + ...([{ requestId, result: { ok: true, formId: 'form-1@pg1', path: 'email' } }] as never), + ); + }) as never); + expect(await call('explain-field', { selector: '#email' })).toContain( + '`email` in `Signup.form`', + ); + expect(broadcast).toHaveBeenCalledOnce(); + }); + + it('explain-submit explains ngSubmit, DOM reasons and missing actions', async () => { + const { call } = await withForms(); + const reactive = await call('explain-submit', { form: 'Signup' }); + expect(reactive).toContain('ngSubmit fires on every submit, valid or not'); + expect(reactive).toContain('DOM: No submit button'); + expect(reactive).toContain('- `email`: email (validator)'); + expect(reactive).toMatch(/Recent submits:\n- #3 .*\(user, ran\)/); + expect(await call('explain-submit', { form: 'Profile' })).toContain('throws NG01915'); + expect(await call('explain-submit', {})).toContain('2 forms match'); + }); + + it('form-payload shows what value drops and what Signal Forms keeps', async () => { + const { call } = await withForms(); + const reactive = await call('form-payload', { form: 'Signup' }); + expect(reactive).toContain('Left out of form.value because they are disabled: `nickname`'); + expect(reactive).toContain('"nickname":"kam"'); + expect(reactive).toContain('Secret values show as [redacted].'); + expect(await call('form-payload', { form: 'Profile' })).toContain('`card (hidden)`'); + }); + + it('form-history filters by origin and returns a marker; form-diff nets changes', async () => { + const { call } = await withForms(); + const history = await call('form-history', { form: 'Signup', origin: 'user' }); + expect(history).toContain('×3'); + expect(history).not.toContain('"xy"'); + expect(history).toContain('Marker: 4'); + const diff = await call('form-diff', { form: 'Signup', since: 0 }); + expect(diff).toContain('- `email` value: "" → "xy" (4 changes)'); + expect(diff).toContain('- `email` status: VALID → INVALID'); + expect(await call('form-diff', { form: 'Signup', since: 4 })).toContain( + 'Nothing changed since marker 4', + ); + }); + + it('form-history shows callers, async timing, render counts and moves', async () => { + const { push, call } = await boot(); + await push('push-forms', { + pageId: 'pg1', + forms: [signup], + instrumented: true, + events: [ + { + formId: 'form-1@pg1', + path: 'email', + type: 'value', + detail: '"a@b.co"', + origin: 'code', + caller: 'setValue in Checkout.prefill (src/app/checkout.ts:42:7)', + timestamp: 1, + seq: 1, + }, + { + formId: 'form-1@pg1', + path: 'code', + type: 'status', + detail: 'VALID', + ms: 820, + timestamp: 2, + seq: 2, + }, + { + formId: 'form-1@pg1', + path: 'email', + type: 'value', + detail: '"a"', + origin: 'user', + renders: 14, + rendered: ['Checkout×9', 'Summary×5'], + timestamp: 3, + seq: 3, + }, + { + formId: 'form-1@pg1', + path: 'items.0', + type: 'moved', + detail: 'items.2 → items.0', + timestamp: 4, + seq: 4, + }, + { + formId: 'form-1@pg1', + path: 'age', + type: 'validators', + detail: 'setValidators', + origin: 'code', + timestamp: 5, + seq: 5, + }, + ], + }); + const text = await call('form-history', { form: 'Signup' }); + expect(text).toContain('from setValue in Checkout.prefill (src/app/checkout.ts:42:7)'); + expect(text).toContain('pending 820ms'); + expect(text).toContain('14 template updates: Checkout×9, Summary×5'); + expect(text).toContain('`items.0` moved items.2 → items.0'); + expect(await call('form-history', { form: 'Signup', type: 'validators' })).toContain( + 'setValidators', + ); + }); + + it('lint-forms reports model-aware findings and setup errors', async () => { + const { call } = await withForms(); + const text = await call('lint-forms', {}); + for (const rule of [ + 'setup-error', + 'formroot-no-submission', + 'stale-validity', + 'stuck-pending', + 'view-out-of-sync', + 'missing-label', + 'submit-unreachable', + 'unbound-required', + 'no-focus-on-invalid-submit', + ]) { + expect(text, rule).toContain(rule); + } + expect(await call('lint-forms', { form: 'Profile' })).not.toContain('setup-error'); + }); + + it('explain-custom-control explains accessor contracts and setup errors', async () => { + const { call } = await withForms(); + const text = await call('explain-custom-control', { form: 'Signup', path: 'age' }); + expect(text).toContain('custom ControlValueAccessor AgePicker'); + expect(text).toContain('has no setDisabledState'); + expect(text).toContain('Drift:'); + expect(text).toContain('NG01203'); + expect(text).not.toContain('NG01050'); + }); + + it('export-form writes a snapshot or a fixture with the secret still redacted', async () => { + const { call } = await withForms(); + const fixture = await call('export-form', { form: 'Signup', format: 'fixture' }); + expect(fixture).toContain('form.patchValue('); + expect(fixture).toContain("form.get('nickname')?.disable();"); + expect(fixture).toContain("expect(form.status).toBe('INVALID');"); + expect(fixture).toContain('[redacted]'); + const snapshot = await call('export-form', { form: 'Profile' }); + expect(snapshot).toContain('"kind": "signal"'); + }); + + it('wait-for-form resolves when the condition holds and times out otherwise', async () => { + const { call, push } = await withForms(); + expect(await call('wait-for-form', { form: 'Profile', until: 'not-pending' })).toMatch( + /holds after \d+ms/, + ); + expect( + await call('wait-for-form', { form: 'Signup', until: 'valid', timeoutMs: 150 }), + ).toContain('Timed out after 150ms'); + const waiting = call('wait-for-form', { + form: 'Signup', + until: 'submitted', + since: 3, + timeoutMs: 3000, + }); + await new Promise((resolve) => setTimeout(resolve, 150)); + await push('push-forms', { + pageId: 'pg1', + forms: [signup], + events: [ + ...events, + { formId: 'form-1@pg1', path: '', type: 'submit', outcome: 'ran', timestamp: 2000, seq: 5 }, + ], + }); + expect(await waiting).toContain('Marker: 5'); + }); + + it('form-action and fill-form ask the right page and report refusals', async () => { + const { ctx, call } = await withForms(); + const seen: any[] = []; + vi.spyOn(ctx.rpc, 'broadcast').mockImplementation((async (options: any) => { + const { requestId, pageId, request } = options.args[0]; + seen.push({ pageId, request }); + const result = + request.action === 'fill' + ? { + ok: true, + message: 'Wrote 1 field(s), skipped 1.', + skipped: [{ path: 'password', reason: 'looks secret' }], + status: 'INVALID', + invalid: ['email'], + } + : { ok: false, error: 'reset changes app state; call again with confirm: true.' }; + await ctx.rpc.invokeLocal( + 'ng-devtools:form-action-result' as never, + ...([{ requestId, result }] as never), + ); + }) as never); + const refused = await call('form-action', { action: 'reset', form: 'form-1' }); + expect(refused).toContain('Refused: reset changes app state'); + const filled = await call('fill-form', { + form: 'form-1@pg1', + values: { email: 'a@b.co', password: 'x' }, + }); + expect(filled).toContain('Skipped: `password` looks secret.'); + expect(filled).toContain('Fields with errors: `email`.'); + expect(seen.map((s) => s.pageId)).toEqual(['pg1', 'pg1']); + expect(seen[1].request).toMatchObject({ + action: 'fill', + formId: 'form-1@pg1', + values: { email: 'a@b.co' }, + }); + expect(await call('form-action', { action: 'focus', form: 'nope' })).toContain('No form nope'); + }); + + it('form-action times out when no page answers', async () => { + vi.useFakeTimers({ toFake: ['setTimeout'] }); + try { + const { ctx, call } = await withForms(); + vi.spyOn(ctx.rpc, 'broadcast').mockImplementation((async () => {}) as never); + const pending = call('form-action', { action: 'focus', form: 'form-1', path: 'email' }); + await vi.advanceTimersByTimeAsync(15_001); + expect(await pending).toContain('No page answered within 15s'); + } finally { + vi.useRealTimers(); + } + }); + + it('refuses a short form id that matches forms on several pages', async () => { + const { push, call } = await withForms(); + await push('push-forms', { + pageId: 'pg3', + forms: [{ ...signup, id: 'form-1@pg3' }], + events: [], + }); + for (const text of [ + await call('explain-field', { form: 'form-1', path: 'email' }), + await call('form-action', { action: 'focus', form: 'form-1', path: 'email' }), + await call('fill-form', { form: 'form-1', values: { email: 'a' } }), + ]) { + expect(text).toContain('pass the full `form` id'); + expect(text).toContain('form-1@pg1'); + expect(text).toContain('form-1@pg3'); + } + expect(await call('explain-field', { form: 'form-1@pg3', path: 'email' })).not.toContain( + 'forms match', + ); + }); + + it('rejects reports with malformed new fields', async () => { + const { push, call } = await boot(); + const bad = { + ...signup, + root: { ...signup.root, children: [leaf('a', { stale: [1 as never] })] }, + }; + await push('push-forms', { pageId: 'x', forms: [bad], events: [] }); + await push('push-forms', { pageId: 'y', forms: [signup], events: [], setupErrors: 'NG01203' }); + expect(await call('inspect-forms')).toMatch(/No forms have been reported/); + }); +}); diff --git a/packages/ng-devtools/src/__tests__/forms-read.test.ts b/packages/ng-devtools/src/__tests__/forms-read.test.ts new file mode 100644 index 0000000..0666dba --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-read.test.ts @@ -0,0 +1,343 @@ +// @vitest-environment jsdom +import '@angular/compiler'; +import { Component, signal } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { + FormControl, + FormGroup, + FormsModule, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; +import { + disabled, + form, + hidden, + required, + submit, + validate, + validateTree, +} from '@angular/forms/signals'; +import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; +import { afterEach, describe, expect, it } from 'vitest'; +import { + collectForms, + forgetFormSecrets, + redactFormText, + findForms, + serializeControl, + serializeField, + watchControlEvents, +} from '../forms.ts'; +import { domFacts, submitDom } from '../forms-dom.ts'; +import { isSecretKey, redactMessage, redactReason } from '../forms-privacy.ts'; +import { controlFacts, fieldPath, submitSetup, validatorNames } from '../forms-read.ts'; + +try { + TestBed.initTestEnvironment(BrowserTestingModule, platformBrowserTesting()); +} catch { + // already initialized by another suite in this worker +} + +function signalForm(model: T, schema?: unknown, options?: unknown) { + return TestBed.runInInjectionContext(() => (form as any)(signal(model), schema, options)) as any; +} + +function byKey(node: { children?: { key: string }[] }) { + return Object.fromEntries((node.children ?? []).map((c) => [c.key, c])) as Record; +} + +function ngApi() { + const ng = (globalThis as any).ng; + if (!ng?.getDirectives) throw new Error('ng debug API missing'); + return ng; +} + +afterEach(() => TestBed.resetTestingModule()); + +describe('Signal Forms internals', () => { + it('attributes tree, own and submission errors, with the ancestor path', async () => { + const tree = signalForm({ pass: 'a', confirm: 'b', name: '' }, (p: any) => { + required(p.name); + validateTree(p, ({ value, fieldTreeOf }: any) => + value().pass === value().confirm + ? null + : { kind: 'mismatch', fieldTree: fieldTreeOf(p.confirm), message: 'Must match' }, + ); + }); + tree.confirm(); + tree.name(); + expect(fieldPath(tree.confirm())).toBe('confirm'); + let root = serializeField(tree()); + expect(byKey(root)['confirm'].errors[0]).toMatchObject({ + kind: 'mismatch', + source: 'tree', + from: '', + }); + expect(byKey(root)['name'].errors[0]).toMatchObject({ kind: 'required', source: 'own' }); + + tree.name().value.set('Kam'); + tree.confirm().value.set('a'); + await submit(tree, async () => [{ kind: 'server', message: 'Taken', fieldTree: tree.name }]); + root = serializeField(tree()); + expect(byKey(root)['name'].errors).toEqual([ + expect.objectContaining({ kind: 'server', source: 'submission' }), + ]); + }); + + it('explains skipped validation, inherited state and rule counts', () => { + const tree = signalForm({ card: { number: '' }, note: '', locked: { a: '' } }, (p: any) => { + required(p.card.number); + hidden(p.card, () => true); + required(p.note); + validate(p.note, () => null); + disabled(p.locked, () => 'Locked while reviewing'); + }); + tree.card.number(); + tree.note(); + tree.locked.a(); + const root = serializeField(tree()); + const number = byKey(byKey(root)['card'])['number']; + expect(number).toMatchObject({ skipped: 'hidden', hiddenBy: 'parent', errors: [] }); + expect(byKey(root)['note'].rules).toMatchObject({ sync: 2 }); + expect(byKey(root)['note'].rules.metadata).toBeGreaterThan(0); + expect(byKey(byKey(root)['locked'])['a']).toMatchObject({ + skipped: 'disabled', + inheritedDisabled: 1, + }); + }); + + it('dry-runs submit like Angular', () => { + const action = async () => undefined; + const invalid = signalForm({ a: '' }, (p: any) => required(p.a), { submission: { action } }); + expect(submitSetup(invalid())).toMatchObject({ hasAction: true, willRun: false }); + const forced = signalForm({ a: '' }, (p: any) => required(p.a), { + submission: { action, ignoreValidators: 'all' }, + }); + expect(submitSetup(forced())).toMatchObject({ willRun: true, ignoreValidators: 'all' }); + expect(submitSetup(signalForm({ a: 'x' })())).toMatchObject({ hasAction: false }); + }); + + it('reports a buffered value and dirty-but-unchanged fields', () => { + const tree = signalForm({ name: 'kam' }); + tree.name(); + serializeField(tree()); + tree.name().markAsDirty(); + let node = byKey(serializeField(tree()))['name']; + expect(node).toMatchObject({ dirty: true, changed: false }); + tree.name().value.set('ada'); + node = byKey(serializeField(tree()))['name']; + expect(node.changed).toBe(true); + }); +}); + +describe('reactive internals', () => { + it('flags stale validity, manual errors and validator names', () => { + const name = new FormControl(''); + name.setValidators([Validators.required, Validators.minLength(3)]); + const facts = controlFacts(name as any); + expect(facts.stale).toEqual(['required']); + expect(facts.validators).toContain('required'); + + const email = new FormControl('a@b.co', Validators.email); + email.setErrors({ taken: true }); + expect(controlFacts(email as any).origins).toEqual({ taken: { source: 'manual' } }); + const node = serializeControl(email as any); + expect(node.errors[0]).toMatchObject({ kind: 'taken', source: 'manual' }); + expect(validatorNames(email as any)).toEqual(['email']); + }); + + it('drops control events caused by probing a validator', async () => { + const group = new FormGroup({ a: new FormControl(''), noisy: new FormControl('x') }); + group.controls.noisy.setValidators(() => { + group.controls.a.setErrors({ side: true }); + return null; + }); + const events: unknown[] = []; + const stop = watchControlEvents(group as any, 'f', (event) => events.push(event)); + controlFacts(group.controls.noisy as any); + await Promise.resolve(); + stop?.(); + expect(events).toEqual([]); + }); +}); + +class BlurForm { + form = new FormGroup({ + name: new FormControl('', { updateOn: 'blur', validators: Validators.required }), + }); +} +Component({ + selector: 'blur-form', + imports: [ReactiveFormsModule], + template: ` +
    + + + Name is required + +
    + `, +})(BlurForm); + +class ModelForm { + city = 'ab'; +} +Component({ + selector: 'model-form', + imports: [FormsModule], + template: ` +
    + + +
    + `, +})(ModelForm); + +describe('real components', () => { + it('reads uncommitted text, bindings, DOM facts and submit reasons', () => { + const fixture = TestBed.createComponent(BlurForm); + fixture.detectChanges(); + const input = fixture.nativeElement.querySelector('input') as HTMLInputElement; + input.value = 'Ada'; + input.dispatchEvent(new Event('input')); + const [collected] = collectForms( + findForms(ngApi(), fixture.nativeElement.querySelectorAll('*')), + ); + const name = byKey(collected.root)['name']; + expect(name).toMatchObject({ value: '', uncommitted: 'Ada', updateOn: 'blur' }); + expect(name.binding).toMatchObject({ kind: 'native', accessor: 'DefaultValueAccessor' }); + expect(name.dom).toMatchObject({ labelled: true, required: true, describedBy: true }); + expect(name.errors[0]).toMatchObject({ kind: 'required', source: 'own' }); + expect(collected.submitDom?.reasons.join(' ')).toContain('type="button"'); + }); + + it('labels template validators and flags a disabled submit button', async () => { + const fixture = TestBed.createComponent(ModelForm); + fixture.detectChanges(); + await fixture.whenStable(); + fixture.detectChanges(); + const [collected] = collectForms( + findForms(ngApi(), fixture.nativeElement.querySelectorAll('*')), + ); + const city = byKey(collected.root)['city']; + expect(city.errors[0]).toMatchObject({ kind: 'minlength', source: 'directive' }); + expect(city.validatorNames).toEqual(expect.arrayContaining(['required (template)'])); + expect(collected.submitDom?.reasons.join(' ')).toContain('disabled'); + }); +}); + +describe('privacy', () => { + it('splits words so passenger and discard stay visible', () => { + for (const key of [ + 'password', + 'newPassword', + 'apiKey', + 'api_key', + 'cardNumber', + 'passwords', + 'cvv', + 'PIN', + ]) { + expect(isSecretKey(key), key).toBe(true); + } + for (const key of [ + 'passenger', + 'discard', + 'compass', + 'bypass', + 'cardinal', + 'keyword', + 'pinned', + ]) { + expect(isSecretKey(key), key).toBe(false); + } + }); + + it('honors masking markers and the unmask marker', () => { + document.body.innerHTML = ` +
    + + `; + expect(redactReason('city', document.getElementById('a'))).toBe('marker'); + expect(redactReason('token', document.getElementById('b'))).toBeNull(); + expect(redactReason('x', document.getElementById('c'))).toBe('autocomplete'); + document.body.innerHTML = ` +
    + +
    `; + expect(redactReason('x', document.getElementById('d'))).toBeNull(); + expect(redactReason('x', document.getElementById('e'))).toBeNull(); + }); + + it('collects secrets from a circular value without overflowing', () => { + const secret: Record = { pin: '98765' }; + secret['self'] = secret; + const group = new FormGroup({ + password: new FormControl(secret), + note: new FormControl('98765'), + }); + const [collected] = collectForms({ + forms: [{ kind: 'reactive', root: group as any, owner: null }], + elements: new WeakMap(), + }); + expect(JSON.stringify(collected.root.children)).not.toContain('98765'); + }); + + it('removes a secret value from every serialized string', () => { + const group = new FormGroup({ + password: new FormControl('hunter2'), + hint: new FormControl('hunter2 backwards'), + }); + group.controls.hint.setErrors({ pattern: { requiredPattern: '^hunter2$', actualValue: 'x' } }); + const [collected] = collectForms({ + forms: [{ kind: 'reactive', root: group as any, owner: null }], + elements: new WeakMap(), + }); + const text = JSON.stringify(collected); + expect(text).not.toContain('hunter2'); + expect(text).toContain('"path":"hint"'); + }); + + it('removes a secret value quoted in another field error', () => { + const group = new FormGroup({ + password: new FormControl('hunter2'), + confirm: new FormControl('hunter3'), + }); + group.controls.confirm.setErrors({ mismatch: 'hunter3 does not match hunter2' }); + const [collected] = collectForms({ + forms: [{ kind: 'reactive', root: group as any, owner: null }], + elements: new WeakMap(), + }); + const text = JSON.stringify(collected); + expect(text).not.toContain('hunter2'); + expect(redactFormText(collected.id, 'Invalid password hunter2')).toBe( + 'Invalid password [redacted]', + ); + forgetFormSecrets([collected.id]); + expect(redactFormText(collected.id, 'Invalid password hunter2')).toBe( + 'Invalid password hunter2', + ); + expect(redactMessage('Bearer abc.def and eyJhbGciOiJI.eyJzdWIiOiIx.c2lnbmF0dXJl')).toBe( + 'Bearer [redacted] and [redacted]', + ); + }); +}); + +describe('DOM facts', () => { + it('detects a stale view and hidden error text', () => { + document.body.innerHTML = ` +
    `; + const el = document.getElementById('x')!; + expect(domFacts(el, { value: 'new', hasErrors: true })).toMatchObject({ + drift: 'old', + errorShown: false, + }); + expect(domFacts(el, { value: 'old', secret: true }).drift).toBeUndefined(); + }); + + it('explains why a non-form host never submits', () => { + document.body.innerHTML = '
    '; + expect(submitDom(document.getElementById('f')!).reasons[0]).toContain('not a
    '); + }); +}); diff --git a/packages/ng-devtools/src/__tests__/forms-real.test.ts b/packages/ng-devtools/src/__tests__/forms-real.test.ts index 28b423d..d3f65ab 100644 --- a/packages/ng-devtools/src/__tests__/forms-real.test.ts +++ b/packages/ng-devtools/src/__tests__/forms-real.test.ts @@ -66,7 +66,7 @@ describe('real Signal Forms', () => { const byKey = Object.fromEntries(root.children!.map((c) => [c.key, c])); expect(root.status).toBe(tree().invalid() ? 'INVALID' : 'VALID'); expect(byKey['name'].errors).toEqual([ - { kind: 'required', message: 'Name is required', params: undefined }, + { kind: 'required', message: 'Name is required', params: undefined, source: 'own' }, ]); expect(byKey['tags'].errors[0].message).toBe('needs at least 2 items'); expect(byKey['plan'].status).toBe('DISABLED'); diff --git a/packages/ng-devtools/src/__tests__/forms-source.test.ts b/packages/ng-devtools/src/__tests__/forms-source.test.ts new file mode 100644 index 0000000..2a4f367 --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-source.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from 'vitest'; +import { formSourceIn, sourceText } from '../rpc/forms-source.ts'; + +const file = `import { form, required, min } from '@angular/forms/signals'; + +// class Signup is mentioned in a comment +export class Signup { + model = signal({ name: '', age: 0 }); + signup = form(this.model, (p) => { + required(p.name, { message: 'Name is required' }); + min(p.age, 13); + }); +} + +export class Account { + account = new FormGroup({ + username: new FormControl('', Validators.required), + }); +} +`; + +describe('form source scan', () => { + it('finds the form property and the rules of a Signal Forms field', () => { + const found = formSourceIn(file, 'src/signup.ts', 'Signup', 'signup', 'name'); + expect(found?.form).toMatchObject({ file: 'src/signup.ts', line: 6 }); + expect(found?.rules.map((r) => r.line)).toEqual([7]); + expect(sourceText(found)).toContain('Defined at src/signup.ts:6: signup = form(this.model'); + }); + + it('finds reactive control declarations and ignores array indexes', () => { + const found = formSourceIn(file, 'a.ts', 'Account', 'account', 'username'); + expect(found?.form?.line).toBe(13); + expect(found?.rules.map((r) => r.text)).toEqual([ + "username: new FormControl('', Validators.required),", + ]); + expect(formSourceIn(file, 'a.ts', 'Account', 'account', '0')?.rules).toEqual([]); + expect(formSourceIn(file, 'a.ts', 'Missing', 'x', '')).toBeNull(); + }); +}); diff --git a/packages/ng-devtools/src/__tests__/forms-tools.test.ts b/packages/ng-devtools/src/__tests__/forms-tools.test.ts index b664f6a..0ee91db 100644 --- a/packages/ng-devtools/src/__tests__/forms-tools.test.ts +++ b/packages/ng-devtools/src/__tests__/forms-tools.test.ts @@ -56,8 +56,8 @@ describe('explainForm', () => { expect(text).toBe( [ '**Signup.form** (reactive, id form-1) is INVALID.', - '- `email` = "x" [email] is not a valid email address (touched: no)', - '- `nested.age` = 3 [min] must be at least 13 (is 3) (touched: no)', + '- `email` = "x" [email] is not a valid email address (validator; touched: no)', + '- `nested.age` = 3 [min] must be at least 13 (is 3) (validator; touched: no)', ].join('\n'), ); }); @@ -210,7 +210,13 @@ describe('mergePageReport', () => { expect(expirePages(pages, 300_000)).toBeNull(); const gone = expirePages(pages, 400_000); - expect(gone).toEqual({ forms: [], events: [], reportedAt: 0 }); + expect(gone).toEqual({ + forms: [], + events: [], + reportedAt: 0, + setupErrors: [], + instrumented: [], + }); }); }); diff --git a/packages/ng-devtools/src/__tests__/forms.test.ts b/packages/ng-devtools/src/__tests__/forms.test.ts index b5faddf..a391671 100644 --- a/packages/ng-devtools/src/__tests__/forms.test.ts +++ b/packages/ng-devtools/src/__tests__/forms.test.ts @@ -182,6 +182,7 @@ describe('reactive serialization', () => { kind: 'minlength', params: { requiredLength: 3, actualLength: 2 }, message: 'needs at least 3 characters (has 2)', + source: 'own', }, ]); @@ -893,7 +894,7 @@ describe('Angular spec edge cases', () => { const email = new FormControl('a@b.co'); email.setErrors({ server: 'Email already taken' }); expect(serializeControl(email).errors).toEqual([ - { kind: 'server', message: 'Email already taken' }, + { kind: 'server', message: 'Email already taken', source: 'manual' }, ]); }); diff --git a/packages/ng-devtools/src/devframe.ts b/packages/ng-devtools/src/devframe.ts index ed12b74..f9c5a9a 100644 --- a/packages/ng-devtools/src/devframe.ts +++ b/packages/ng-devtools/src/devframe.ts @@ -19,6 +19,23 @@ import { type FormsState, type InspectFormsArgs, } from './rpc/forms-tools.ts'; +import { + explainCustomControlText, + explainFieldText, + explainSubmitText, + fieldOwner, + exportFormText, + formDiffText, + formHistoryText, + formPayloadText, + latestMarker, + lintFormsFor, + lintFormsText, + resolveForm, + waitSatisfied, + type WaitUntil, +} from './rpc/forms-explain.ts'; +import { findFormSource, sourceText } from './rpc/forms-source.ts'; import { currentRouter, expireRouterPages, @@ -115,7 +132,7 @@ const ngDevtools = defineDevframe({ const formPages = new Map(); const formsState = await my.rpc.sharedState('forms', { - initialValue: { forms: [], events: [], reportedAt: 0 } as FormsState, + initialValue: { forms: [], events: [], reportedAt: 0, setupErrors: [] } as FormsState, }); const applyForms = (next: FormsState) => @@ -123,6 +140,8 @@ const ngDevtools = defineDevframe({ draft.forms = next.forms; draft.events = next.events; draft.reportedAt = next.reportedAt; + draft.setupErrors = next.setupErrors ?? []; + draft.instrumented = next.instrumented ?? []; }); my.rpc.register({ @@ -304,6 +323,106 @@ const ngDevtools = defineDevframe({ }, }); + const pendingFormActions = new Map void>(); + let formActionSeq = 0; + + const requestFormAction = (request: Record, timeoutMs = 15_000) => + new Promise>((resolve) => { + const requestId = `f${++formActionSeq}`; + const formId = typeof request['formId'] === 'string' ? request['formId'] : undefined; + const explicit = typeof request['page'] === 'string' ? request['page'] : undefined; + const pageId = explicit ?? (formId?.includes('@') ? formId.split('@')[1] : undefined); + const { page: _page, ...payload } = request; + const timer = setTimeout(() => { + pendingFormActions.delete(requestId); + resolve({ + ok: false, + error: `No page answered within ${Math.round(timeoutMs / 1000)}s. Is the app open in a browser, with that form on screen?`, + }); + }, timeoutMs); + timer.unref?.(); + pendingFormActions.set(requestId, (result) => { + clearTimeout(timer); + pendingFormActions.delete(requestId); + resolve( + (result && typeof result === 'object' + ? result + : { ok: false, error: 'Empty answer.' }) as Record, + ); + }); + void my.rpc.broadcast({ + method: 'form-action', + args: [{ requestId, pageId, request: payload }], + optional: true, + }); + }); + + my.rpc.register({ + name: 'form-action-result', + type: 'action', + jsonSerializable: true, + handler: (message: { requestId?: unknown; result?: unknown }) => { + if (typeof message?.requestId !== 'string') return; + pendingFormActions.get(message.requestId)?.(message.result); + }, + }); + + my.rpc.register({ + name: 'request-form-action', + type: 'action', + jsonSerializable: true, + handler: (request: unknown) => + request && typeof request === 'object' + ? requestFormAction(request as Record) + : { ok: false, error: 'Bad request.' }, + }); + + my.rpc.register({ + name: 'forms-lint', + type: 'query', + jsonSerializable: true, + handler: (args: { form?: unknown; page?: unknown } | null) => + lintFormsFor(formsState.value() as FormsState, { + form: typeof args?.form === 'string' ? args.form : undefined, + page: typeof args?.page === 'string' ? args.page : undefined, + }), + }); + + my.rpc.register({ + name: 'forms-owners', + type: 'query', + jsonSerializable: true, + handler: () => + (formsState.value() as FormsState).forms.map((form) => ({ + formId: form.id, + label: form.label, + file: findFormSource(ctx.cwd, form.owner, form.property)?.form?.file ?? null, + })), + }); + + my.rpc.register({ + name: 'forms-explain', + type: 'query', + jsonSerializable: true, + handler: (args: { kind?: unknown; form?: unknown; path?: unknown } | null) => { + const state = formsState.value() as FormsState; + const target = { + form: typeof args?.form === 'string' ? args.form : undefined, + path: typeof args?.path === 'string' ? args.path : undefined, + }; + switch (args?.kind) { + case 'submit': + return explainSubmitText(state, target); + case 'payload': + return formPayloadText(state, target); + case 'fixture': + return exportFormText(state, { ...target, format: 'fixture' }); + default: + return explainFieldText(state, target); + } + }, + }); + my.rpc.register({ name: 'push-component-tree', type: 'action', @@ -784,6 +903,10 @@ const ngDevtools = defineDevframe({ type: 'object', properties: { form: formProperty, + page: { + type: 'string', + description: 'Page id (the part after @ in a form id) when several tabs are connected.', + }, path: { type: 'string', description: @@ -814,14 +937,337 @@ const ngDevtools = defineDevframe({ safety: 'read', inputSchema: { type: 'object', - properties: { form: formProperty }, + properties: { + form: formProperty, + page: { + type: 'string', + description: 'Page id (the part after @ in a form id) when several tabs are connected.', + }, + }, }, - handler: async (args: { form?: string }) => { + handler: async (args: { form?: string; page?: string }) => { const state = formsState.value() as FormsState; if (!state.forms.length) return { markdown: noForms }; return { markdown: explainFormsText(state, args) }; }, }); + + const formPageProperty = { + type: 'string', + description: 'Page id (the part after @ in a form id) when several tabs are connected.', + }; + const pathProperty = { + type: 'string', + description: + 'Dotted field path, e.g. address.city or items.0.qty. Empty for the form itself.', + }; + const withForms = + (fn: (state: FormsState, args: A) => string) => + async (args: A) => { + const state = formsState.value() as FormsState; + if (!state.forms.length) return { markdown: noForms }; + return { markdown: fn(state, args ?? ({} as A)) }; + }; + const str = (value: unknown) => (typeof value === 'string' ? value : undefined); + + ctx.agent.registerTool({ + id: 'ng-devtools:explain-field', + description: + 'Explain one form field: value, flags, every error with where it comes from (validator, template attribute, cross-field rule and which ancestor, async, parse, server/submission, setErrors), why validation is skipped (hidden, disabled, readonly), inherited disabled reasons, uncommitted or debounced input, stale validity, rules and validator names, the binding (accessor or [formField]) and DOM facts (label, visible error text, drift). Pass `selector` instead of form/path to start from a CSS selector.', + safety: 'read', + inputSchema: { + type: 'object', + properties: { + form: formProperty, + path: pathProperty, + selector: { type: 'string', description: 'CSS selector of an input bound to a field.' }, + page: formPageProperty, + }, + }, + handler: async (args: { form?: string; path?: string; selector?: string; page?: string }) => { + const state = formsState.value() as FormsState; + if (!state.forms.length) return { markdown: noForms }; + let target = { form: args?.form, path: args?.path, page: args?.page }; + if (args?.selector) { + const located = await requestFormAction( + { action: 'locate', selector: args.selector, page: args.page }, + 5000, + ); + if (!located['ok']) return { markdown: String(located['error'] ?? 'Not found.') }; + target = { + form: str(located['formId']), + path: str(located['path']) ?? '', + page: undefined, + }; + } + const owner = fieldOwner(state, target); + const source = owner + ? sourceText(findFormSource(ctx.cwd, owner.owner, owner.property, owner.path)) + : ''; + return { markdown: explainFieldText(state, target, Date.now(), source) }; + }, + }); + + ctx.agent.registerTool({ + id: 'ng-devtools:explain-submit', + description: + 'Explain what submitting a form will do and why it might do nothing: Signal Forms submit() dry-run (action present, ignoreValidators, already submitting), ngSubmit semantics for reactive and template forms, DOM reasons (no submit button, type="button", disabled button, directive not on a , native validation), blocking and pending fields, and recent submits with their outcome (ran, blocked, threw).', + safety: 'read', + inputSchema: { type: 'object', properties: { form: formProperty, page: formPageProperty } }, + handler: withForms(explainSubmitText), + }); + + ctx.agent.registerTool({ + id: 'ng-devtools:form-payload', + description: + 'Show what a form would send: form.value vs getRawValue() with the disabled fields form.value drops (reactive), or the hidden/disabled/readonly fields Signal Forms keeps in the value without validating them, plus which fields the user changed.', + safety: 'read', + inputSchema: { type: 'object', properties: { form: formProperty, page: formPageProperty } }, + handler: withForms(formPayloadText), + }); + + ctx.agent.registerTool({ + id: 'ng-devtools:form-history', + description: + 'Timeline of form changes: value (with previous value and repeat count), status, submit (ran, blocked, threw), added and removed fields, each tagged with its origin (user, code, devtools). Filter by form, path, type, origin or `since` (a marker from an earlier call). Returns the current marker.', + safety: 'read', + inputSchema: { + type: 'object', + properties: { + form: formProperty, + path: pathProperty, + type: { + type: 'string', + enum: [ + 'value', + 'status', + 'touched', + 'dirty', + 'submit', + 'reset', + 'added', + 'removed', + 'moved', + 'validators', + ], + }, + origin: { type: 'string', enum: ['user', 'code', 'devtools', 'binding'] }, + since: { type: 'number', description: 'Only events after this marker.' }, + limit: { type: 'number', description: 'Max events (default 50, max 200).' }, + page: formPageProperty, + }, + }, + handler: withForms(formHistoryText), + }); + + ctx.agent.registerTool({ + id: 'ng-devtools:form-diff', + description: + 'Net change of a form since a marker: each field whose value or status ended different, with from → to and how many changes happened in between. Get a marker from form-history, inspect-forms or a form-action result, act, then call this.', + safety: 'read', + inputSchema: { + type: 'object', + properties: { + form: formProperty, + since: { + type: 'number', + description: 'Marker to diff from (default: everything buffered).', + }, + page: formPageProperty, + }, + }, + handler: withForms(formDiffText), + }); + + ctx.agent.registerTool({ + id: 'ng-devtools:lint-forms', + description: + 'Deterministic checks on live forms: stale validity after validator changes, stuck PENDING, unreachable submit, missing submission action, hidden fields still rendered, view out of sync with the model, [disabled] on reactive controls, required-but-unbound fields, NG01xxx setup errors, and model-aware accessibility (missing label, aria-invalid desync, required not exposed, error text not shown or not linked, no focus after invalid submit).', + safety: 'read', + inputSchema: { type: 'object', properties: { form: formProperty, page: formPageProperty } }, + handler: async (args: { form?: string; page?: string }) => { + const state = formsState.value() as FormsState; + if (!state.forms.length && !state.setupErrors?.length) return { markdown: noForms }; + return { markdown: lintFormsText(state, args ?? {}) }; + }, + }); + + ctx.agent.registerTool({ + id: 'ng-devtools:explain-custom-control', + description: + 'Explain how a field is bound to its element (built-in accessor, custom ControlValueAccessor, custom control, [formField]) and what is wrong with it: value drift, missing setDisabledState, touched never set, captured NG01xxx setup errors.', + safety: 'read', + inputSchema: { + type: 'object', + properties: { form: formProperty, path: pathProperty, page: formPageProperty }, + }, + handler: withForms(explainCustomControlText), + }); + + ctx.agent.registerTool({ + id: 'ng-devtools:export-form', + description: + 'Export a form as a JSON snapshot (tree, status, raw value) or as a test fixture (setValue / signal model plus the expected status) with a repro header. Secret values stay [redacted].', + safety: 'read', + inputSchema: { + type: 'object', + properties: { + form: formProperty, + format: { type: 'string', enum: ['snapshot', 'fixture'] }, + page: formPageProperty, + }, + }, + handler: withForms(exportFormText), + }); + + ctx.agent.registerTool({ + id: 'ng-devtools:wait-for-form', + description: + 'Wait until a form is settled (no pending async validation, debounce or submit in flight), valid, not pending, or submitted after a marker. Resolves as soon as the condition holds, or reports the state on timeout.', + safety: 'read', + inputSchema: { + type: 'object', + properties: { + form: formProperty, + until: { type: 'string', enum: ['settled', 'valid', 'not-pending', 'submitted'] }, + since: { type: 'number', description: 'Marker for `submitted`.' }, + timeoutMs: { type: 'number', description: 'Default 5000, max 30000.' }, + page: formPageProperty, + }, + }, + handler: async (args: { + form?: string; + until?: WaitUntil; + since?: number; + timeoutMs?: number; + page?: string; + }) => { + const timeout = Math.min(Math.max(Number(args?.timeoutMs) || 5000, 100), 30_000); + const start = Date.now(); + while (true) { + const state = formsState.value() as FormsState; + if (waitSatisfied(state, args ?? {})) { + return { + markdown: `Condition \`${args?.until ?? 'settled'}\` holds after ${Date.now() - start}ms. Marker: ${latestMarker(state)}.\n\n${explainFormsText(state, { form: args?.form, page: args?.page })}`, + }; + } + if (Date.now() - start >= timeout) { + return { + markdown: `Timed out after ${timeout}ms waiting for \`${args?.until ?? 'settled'}\`.\n\n${explainFormsText(state, { form: args?.form, page: args?.page })}`, + }; + } + await new Promise((resolve) => setTimeout(resolve, 100)); + } + }, + }); + + const actionText = (result: Record, state: FormsState) => { + const lines = [ + result['ok'] + ? `Done: ${String(result['message'] ?? '')}` + : `Refused: ${String(result['error'] ?? result['message'] ?? 'failed')}`, + ]; + const skipped = Array.isArray(result['skipped']) + ? (result['skipped'] as { path: string; reason: string }[]) + : []; + if (skipped.length) + lines.push(`Skipped: ${skipped.map((s) => `\`${s.path}\` ${s.reason}`).join('; ')}.`); + if (typeof result['status'] === 'string') lines.push(`Form status now: ${result['status']}.`); + const invalid = Array.isArray(result['invalid']) ? (result['invalid'] as string[]) : []; + if (invalid.length) + lines.push(`Fields with errors: ${invalid.map((p) => `\`${p || '(form)'}\``).join(', ')}.`); + if (typeof result['expression'] === 'string') lines.push(`Console: ${result['expression']}`); + if (typeof result['snapshot'] === 'string') + lines.push(`Snapshot id: ${result['snapshot']} (use with restore).`); + lines.push( + `Marker: ${latestMarker(state)}. Call form-diff with since set to the marker you had before this action to see what changed.`, + ); + return lines.join('\n'); + }; + + ctx.agent.registerTool({ + id: 'ng-devtools:form-action', + description: + 'Act on a live form (dev mode). Actions: set-value (mode code or user; user goes through the input like typing), mark-touched, mark-untouched, mark-dirty, mark-pristine, touch-all, revalidate (Signal Forms: reloads async/HTTP validation), reset, enable, disable (reactive only), submit, focus, focus-first-invalid, store-as-global ($form in the page console), snapshot, restore, instrument (value true or false: record the calling code of form changes, validator changes and template updates per keystroke, shown by form-history). reset, submit and restore need confirm: true. Secret, hidden and readonly fields are never written; disabled reactive fields need force.', + safety: 'action', + inputSchema: { + type: 'object', + required: ['action', 'form'], + properties: { + action: { + type: 'string', + enum: [ + 'set-value', + 'mark-touched', + 'mark-untouched', + 'mark-dirty', + 'mark-pristine', + 'touch-all', + 'revalidate', + 'reset', + 'enable', + 'disable', + 'submit', + 'focus', + 'focus-first-invalid', + 'store-as-global', + 'snapshot', + 'restore', + 'instrument', + ], + }, + form: { type: 'string', description: 'Full form id, e.g. form-1@ab12.' }, + path: pathProperty, + value: { description: 'New value for set-value.' }, + mode: { type: 'string', enum: ['code', 'user'] }, + confirm: { type: 'boolean' }, + force: { type: 'boolean' }, + snapshot: { type: 'string', description: 'Snapshot id for restore.' }, + }, + }, + handler: async (args: Record) => { + const state = formsState.value() as FormsState; + if (!state.forms.length) return { markdown: noForms }; + const match = resolveForm(state.forms, str(args?.['form'])); + if (typeof match === 'string') return { markdown: match }; + const { form: _form, ...rest } = args; + const result = await requestFormAction({ ...rest, formId: match.id }); + return { markdown: actionText(result, formsState.value() as FormsState) }; + }, + }); + + ctx.agent.registerTool({ + id: 'ng-devtools:fill-form', + description: + 'Fill several fields at once, by dotted path, through the inputs like a user would (so parsing, dirty and touched run for real). Reports written and skipped fields (secret, hidden, readonly, disabled, missing) and the resulting status. Optionally submits afterwards (needs confirm: true).', + safety: 'action', + inputSchema: { + type: 'object', + required: ['form', 'values'], + properties: { + form: { type: 'string', description: 'Full form id, e.g. form-1@ab12.' }, + values: { type: 'object', description: 'Map of field path to value.' }, + mode: { type: 'string', enum: ['code', 'user'] }, + submit: { type: 'boolean' }, + confirm: { type: 'boolean' }, + }, + }, + handler: async (args: Record) => { + const state = formsState.value() as FormsState; + if (!state.forms.length) return { markdown: noForms }; + const match = resolveForm(state.forms, str(args?.['form'])); + if (typeof match === 'string') return { markdown: match }; + const result = await requestFormAction({ + action: 'fill', + formId: match.id, + values: args['values'], + mode: args['mode'], + submit: args['submit'], + confirm: args['confirm'], + }); + return { markdown: actionText(result, formsState.value() as FormsState) }; + }, + }); }, }); diff --git a/packages/ng-devtools/src/forms-actions.ts b/packages/ng-devtools/src/forms-actions.ts new file mode 100644 index 0000000..4223d5b --- /dev/null +++ b/packages/ng-devtools/src/forms-actions.ts @@ -0,0 +1,764 @@ +import { + controlPathOf, + directivesOf, + findFieldElement, + isAbstractControl, + nodeAt, + serializeFormValue, + type FormsDebugApi, + type FoundForm, +} from './forms.ts'; +import { isSecretKey, redactReason } from './forms-privacy.ts'; +import { fieldPath, submitSetup } from './forms-read.ts'; + +type AnyRecord = Record; + +export const FORM_ACTIONS = [ + 'set-value', + 'mark-touched', + 'mark-untouched', + 'mark-dirty', + 'mark-pristine', + 'touch-all', + 'revalidate', + 'reset', + 'enable', + 'disable', + 'submit', + 'focus', + 'focus-first-invalid', + 'store-as-global', + 'snapshot', + 'restore', + 'fill', + 'locate', + 'instrument', + 'pick', +] as const; + +export type FormActionName = (typeof FORM_ACTIONS)[number]; + +export const CONFIRM_ACTIONS: FormActionName[] = ['reset', 'submit', 'restore']; + +export interface FormActionRequest { + action: FormActionName; + formId?: string; + path?: string; + value?: unknown; + values?: Record; + mode?: 'code' | 'user'; + confirm?: boolean; + force?: boolean; + submit?: boolean; + snapshot?: string; + selector?: string; +} + +export interface Skipped { + path: string; + reason: string; +} + +export interface FormActionResult { + ok: boolean; + message: string; + error?: string; + skipped?: Skipped[]; + status?: string; + invalid?: string[]; + expression?: string; + snapshot?: string; + formId?: string; + path?: string; +} + +export interface ActionContext { + ng: FormsDebugApi & { applyChanges?: (component: unknown) => void }; + forms: Map; + elements: WeakMap; + all: () => Iterable; +} + +let devtoolsDepth = 0; + +export function isDevtoolsAction(): boolean { + return devtoolsDepth > 0; +} + +const snapshots = new Map< + string, + { root: object; formId: string; value: unknown; shape: string } +>(); + +const MAX_GUARDED_NODES = 5000; + +export function secretInside( + value: unknown, + prefix = '', + seen: WeakSet = new WeakSet(), +): string | null { + if (!value || typeof value !== 'object' || value instanceof Date || seen.has(value)) return null; + seen.add(value); + for (const [key, child] of Object.entries(value as AnyRecord)) { + const path = prefix ? `${prefix}.${key}` : key; + if (!/^\d+$/.test(key) && isSecretKey(key)) return path; + const nested = secretInside(child, path, seen); + if (nested) return nested; + } + return null; +} + +export function keepSecrets( + saved: unknown, + current: unknown, + seen: WeakSet = new WeakSet(), +): unknown { + if (!saved || typeof saved !== 'object' || saved instanceof Date || seen.has(saved)) return saved; + if (!current || typeof current !== 'object') return saved; + seen.add(saved); + const out: AnyRecord = Array.isArray(saved) ? [...saved] : { ...(saved as AnyRecord) }; + for (const key of Object.keys(out)) { + const now = (current as AnyRecord)[key]; + out[key] = !/^\d+$/.test(key) && isSecretKey(key) ? now : keepSecrets(out[key], now, seen); + } + return out; +} + +function keysOf(path: string): string[] { + return path ? path.split('.') : []; +} + +export function valueAt(value: unknown, path: string): unknown { + let current = value; + for (const key of keysOf(path)) { + if (!current || typeof current !== 'object') return undefined; + current = (current as AnyRecord)[key]; + } + return current; +} + +function hasPath(value: unknown, path: string): boolean { + let current = value; + for (const key of keysOf(path)) { + if (!current || typeof current !== 'object' || !(key in (current as object))) return false; + current = (current as AnyRecord)[key]; + } + return true; +} + +export function setAt(value: unknown, path: string, next: unknown): unknown { + const keys = keysOf(path); + if (!keys.length) return next; + if (!value || typeof value !== 'object') return value; + const copy: AnyRecord = Array.isArray(value) ? [...value] : { ...(value as AnyRecord) }; + copy[keys[0]] = setAt(copy[keys[0]], keys.slice(1).join('.'), next); + return copy; +} + +function sameValue(a: unknown, b: unknown): boolean { + if (Object.is(a, b)) return true; + try { + return JSON.stringify(a) === JSON.stringify(b); + } catch { + return false; + } +} + +function relativePath(path: string, base: string): string { + return base ? path.slice(base.length + 1) : path; +} + +let snapshotSeq = 0; + +function read(fn: () => T, fallback: T): T { + try { + return fn(); + } catch { + return fallback; + } +} + +export function isFormAction(value: unknown): value is FormActionRequest { + if (!value || typeof value !== 'object') return false; + const request = value as Partial; + return ( + typeof request.action === 'string' && + (FORM_ACTIONS as readonly string[]).includes(request.action) && + (request.formId === undefined || + (typeof request.formId === 'string' && request.formId.length < 80)) && + (request.path === undefined || + (typeof request.path === 'string' && request.path.length < 500)) && + (request.selector === undefined || + (typeof request.selector === 'string' && request.selector.length < 500)) && + (request.values === undefined || + (typeof request.values === 'object' && + request.values !== null && + Object.keys(request.values).length <= 200)) + ); +} + +function fail(error: string): FormActionResult { + return { ok: false, message: error, error }; +} + +function shapeOf(value: unknown): string { + if (Array.isArray(value)) return `[${value.map(shapeOf).join(',')}]`; + if (value && typeof value === 'object' && !(value instanceof Date)) { + return `{${Object.keys(value) + .sort() + .map((k) => `${k}:${shapeOf((value as AnyRecord)[k])}`) + .join(',')}}`; + } + return ''; +} + +function rawValue(found: FoundForm, node: AnyRecord): unknown { + if (found.kind === 'signal') return read(() => node['value'](), undefined); + return read( + () => node['getRawValue'](), + read(() => node['value'], undefined), + ); +} + +function lastKey(path: string, found: FoundForm): string { + return path ? path.split('.').pop()! : ''; +} + +function isSecretPath(path: string): boolean { + return path.split('.').some((key) => !!redactReason(key)); +} + +function elementFor(ctx: ActionContext, found: FoundForm, path: string): Element | null { + return read(() => findFieldElement(ctx.ng, ctx.all(), found, path, ctx.elements), null); +} + +function refusal( + ctx: ActionContext, + found: FoundForm, + node: AnyRecord, + path: string, + force = false, +): string | null { + const element = elementFor(ctx, found, path); + if (isSecretPath(path) || (element && redactReason(lastKey(path, found), element))) { + return 'looks secret (password, token, card…); DevTools never writes secret fields'; + } + if (found.kind === 'signal') { + if (read(() => node['hidden'](), false)) return 'is hidden'; + if (read(() => node['readonly'](), false)) return 'is readonly'; + if (read(() => node['disabled'](), false)) return 'is disabled by a disabled() rule'; + return null; + } + if (!force && read(() => node['disabled'], false)) return 'is disabled (pass force to write it)'; + return null; +} + +function childrenOf(found: FoundForm, node: AnyRecord): [string, AnyRecord][] { + if (found.kind === 'signal') { + const value = read(() => node['value'](), undefined); + if (!value || typeof value !== 'object' || value instanceof Date) return []; + const tree = read(() => node['fieldTree'] as AnyRecord, null); + if (!tree) return []; + return Object.keys(value).flatMap((key) => { + const child = read(() => tree[key]?.() as AnyRecord | undefined, undefined); + return child ? [[key, child] as [string, AnyRecord]] : []; + }); + } + const controls = read(() => node['controls'], null); + if (!controls || typeof controls !== 'object') return []; + return Array.isArray(controls) + ? controls.map((child, index) => [String(index), child] as [string, AnyRecord]) + : Object.entries(controls as AnyRecord); +} + +export interface GuardedField { + path: string; + reason: string; +} + +export function guardedFields( + ctx: ActionContext, + found: FoundForm, + node: AnyRecord, + path: string, + force = false, +): GuardedField[] | null { + const out: GuardedField[] = []; + const seen = new WeakSet(); + let count = 0; + let overflow = false; + const visit = (current: AnyRecord, currentPath: string) => { + if (overflow || !current || seen.has(current)) return; + seen.add(current); + if (++count > MAX_GUARDED_NODES) { + overflow = true; + return; + } + const reason = currentPath !== path ? refusal(ctx, found, current, currentPath, force) : null; + if (reason) { + out.push({ path: currentPath, reason }); + return; + } + for (const [key, child] of childrenOf(found, current)) { + visit(child, currentPath ? `${currentPath}.${key}` : key); + } + }; + visit(node, path); + return overflow ? null : out; +} + +function nativeWrite(element: Element, value: unknown): boolean { + if (element instanceof HTMLInputElement) { + if (element.type === 'file') return false; + if (element.type === 'checkbox') { + element.checked = !!value; + element.dispatchEvent(new Event('change', { bubbles: true })); + return true; + } + if (element.type === 'radio') { + const scope = element.form ?? element.ownerDocument; + const target = Array.from(scope.querySelectorAll('input[type="radio"]')).find( + (radio) => + (radio as HTMLInputElement).name === element.name && + (radio as HTMLInputElement).value === String(value), + ) as HTMLInputElement | undefined; + if (!target) return false; + target.checked = true; + target.dispatchEvent(new Event('change', { bubbles: true })); + return true; + } + element.value = value == null ? '' : String(value); + element.dispatchEvent(new Event('input', { bubbles: true })); + element.dispatchEvent(new Event('change', { bubbles: true })); + return true; + } + if (element instanceof HTMLTextAreaElement) { + element.value = value == null ? '' : String(value); + element.dispatchEvent(new Event('input', { bubbles: true })); + return true; + } + if (element instanceof HTMLSelectElement) { + element.value = value == null ? '' : String(value); + element.dispatchEvent(new Event('change', { bubbles: true })); + return true; + } + return false; +} + +function writeValue( + ctx: ActionContext, + found: FoundForm, + path: string, + value: unknown, + mode: 'code' | 'user', + force: boolean, +): string | null { + const node = nodeAt(found, path, true); + if (!node) return 'does not exist'; + const refused = refusal(ctx, found, node, path, force); + if (refused) return refused; + const current = rawValue(found, node); + const secret = secretInside(value); + if (secret) { + return `contains the secret field "${secret}"; DevTools never writes secret fields`; + } + if (current && typeof current === 'object' && !(current instanceof Date)) { + const guarded = guardedFields(ctx, found, node, path, force); + if (!guarded) return 'is too large to check for protected fields; write the fields one by one'; + for (const field of guarded) { + const rel = relativePath(field.path, path); + if (found.kind !== 'signal' && !hasPath(value, rel)) continue; + if (!sameValue(valueAt(value, rel), valueAt(current, rel))) { + return `would change ${field.path}, which ${field.reason}`; + } + } + } + if (current && typeof current === 'object' && shapeOf(current) !== shapeOf(value)) { + if (!value || typeof value !== 'object') return 'is a group or array; pass an object or array'; + } + const leaf = !current || typeof current !== 'object' || current instanceof Date; + const element = leaf ? elementFor(ctx, found, path) : null; + const viaDom = element && (mode === 'user' || found.kind === 'template'); + if (viaDom && nativeWrite(element, value)) { + if (mode === 'user') element.dispatchEvent(new Event('blur')); + return null; + } + if (found.kind === 'template' && leaf) { + const dir = directivesOf(node); + if (!dir || typeof dir['viewToModelUpdate'] !== 'function') { + return 'is an ngModel without a native input; set the component property instead'; + } + node['setValue'](value); + dir['viewToModelUpdate'](value); + return null; + } + if (found.kind === 'signal') { + if (mode === 'user' && typeof node['controlValue']?.set === 'function') { + node['controlValue'].set(value); + node['markAsDirty']?.(); + } else node['value'].set(value); + return null; + } + if (Array.isArray(current) || !leaf) node['patchValue'](value); + else node['setValue'](value); + if (mode === 'user') { + node['markAsDirty']?.(); + node['markAsTouched']?.(); + } + return null; +} + +function invalidPaths(found: FoundForm): string[] { + const out: string[] = []; + const visit = (node: AnyRecord, path: string, depth: number) => { + if (depth > 12 || out.length > 50) return; + if (found.kind === 'signal') { + const children = read(() => node['structure'].materializedChildren() as AnyRecord[], []); + const ownErrors = read(() => (node['errors']() as unknown[]).length, 0); + if (ownErrors) out.push(path); + for (const child of children) { + const key = String(read(() => child['keyInParent'](), '')); + visit(child, path ? `${path}.${key}` : key, depth + 1); + } + return; + } + const errors = read(() => node['errors'], null); + if (errors && Object.keys(errors).length) out.push(path); + const controls = read(() => node['controls'], null); + if (!controls) return; + const entries: [string, AnyRecord][] = Array.isArray(controls) + ? controls.map((c, i) => [String(i), c]) + : Object.entries(controls); + for (const [key, child] of entries) visit(child, path ? `${path}.${key}` : key, depth + 1); + }; + visit(found.root, '', 0); + return out; +} + +function statusOf(found: FoundForm): string { + if (found.kind === 'signal') { + const root = found.root; + if (read(() => root['pending'](), false)) return 'PENDING'; + if (read(() => root['invalid'](), false)) return 'INVALID'; + return 'VALID'; + } + return String(read(() => found.root['status'], 'VALID')); +} + +async function settle(ctx: ActionContext, found: FoundForm, timeout = 2000) { + read(() => found.owner && ctx.ng.applyChanges?.(found.owner), undefined); + const start = Date.now(); + await new Promise((resolve) => setTimeout(resolve, 30)); + while (statusOf(found) === 'PENDING' && Date.now() - start < timeout) { + await new Promise((resolve) => setTimeout(resolve, 50)); + } + read(() => found.owner && ctx.ng.applyChanges?.(found.owner), undefined); +} + +function directiveWith(ctx: ActionContext, element: Element | undefined, method: string) { + if (!element) return null; + const directives = read(() => ctx.ng.getDirectives(element) ?? [], [] as unknown[]); + return (directives.find((d) => typeof (d as AnyRecord)?.[method] === 'function') ?? + null) as AnyRecord | null; +} + +function expressionFor(found: FoundForm, path: string): string { + if (!path) return '$form'; + if (found.kind === 'signal') { + return `$form${path + .split('.') + .map((key) => (/^\d+$/.test(key) ? `[${key}]` : `.${key}`)) + .join('')}`; + } + return `$form.get('${path.replace(/'/g, "\\'")}')`; +} + +function locate(ctx: ActionContext, selector: string): FormActionResult { + let target: Element | null = null; + try { + target = document.querySelector(selector); + } catch { + return fail(`${selector} is not a valid CSS selector.`); + } + if (!target) return fail(`Nothing on the page matches ${selector}.`); + return locateElement(ctx, target) ?? fail(`${selector} is not bound to a form field.`); +} + +export function locateElement(ctx: ActionContext, target: Element): FormActionResult | null { + const directives = read(() => ctx.ng.getDirectives(target) ?? [], [] as unknown[]) as AnyRecord[]; + for (const [formId, found] of ctx.forms) { + for (const dir of directives) { + const state = read(() => dir['state']?.() as AnyRecord | undefined, undefined); + if (state && read(() => state['structure'].root, null) === found.root) { + return { ok: true, message: 'Found', formId, path: fieldPath(state) }; + } + const control = read(() => dir['control'] as unknown, undefined); + if (isAbstractControl(control) && read(() => control['root'], null) === found.root) { + const path = controlPathOf(found.root, control); + if (!path && control !== found.root) continue; + return { ok: true, message: 'Found', formId, path }; + } + } + } + return null; +} + +export async function runFormAction( + ctx: ActionContext, + request: FormActionRequest, +): Promise { + if (request.action === 'locate') { + if (!request.selector) return fail('Pass a CSS selector.'); + return locate(ctx, request.selector); + } + const found = request.formId ? ctx.forms.get(request.formId) : ctx.forms.values().next().value; + if (!found) return fail(`No form ${request.formId ?? ''} on this page.`); + if (CONFIRM_ACTIONS.includes(request.action) || (request.action === 'fill' && request.submit)) { + if (request.confirm !== true) { + return fail(`${request.action} changes app state; call again with confirm: true.`); + } + } + const path = request.path ?? ''; + devtoolsDepth++; + try { + const result = await perform(ctx, found, request, path); + if (result.ok && !['focus', 'store-as-global', 'snapshot'].includes(request.action)) { + await settle(ctx, found); + } + return { ...result, status: statusOf(found), invalid: invalidPaths(found).slice(0, 20) }; + } catch (error) { + return fail(String((error as Error)?.message ?? error).slice(0, 300)); + } finally { + devtoolsDepth--; + } +} + +async function perform( + ctx: ActionContext, + found: FoundForm, + request: FormActionRequest, + path: string, +): Promise { + const signal = found.kind === 'signal'; + const node = () => nodeAt(found, path, true); + const need = () => { + const n = node(); + if (!n) throw new Error(`No field at ${path || '(form)'}.`); + return n; + }; + switch (request.action) { + case 'set-value': { + const problem = writeValue( + ctx, + found, + path, + request.value, + request.mode ?? 'code', + !!request.force, + ); + return problem + ? { ...fail(`${path || '(form)'} ${problem}.`), skipped: [{ path, reason: problem }] } + : { ok: true, message: `Set ${path || '(form)'}.` }; + } + case 'fill': { + const skipped: Skipped[] = []; + let written = 0; + for (const [fieldPathKey, value] of Object.entries(request.values ?? {})) { + const problem = writeValue(ctx, found, fieldPathKey, value, request.mode ?? 'user', false); + if (problem) skipped.push({ path: fieldPathKey, reason: problem }); + else written++; + } + let message = `Wrote ${written} field(s)${skipped.length ? `, skipped ${skipped.length}` : ''}.`; + if (request.submit) { + await settle(ctx, found); + const submitted = await perform(ctx, found, { ...request, action: 'submit' }, ''); + message += ` ${submitted.message}`; + } + return { ok: written > 0 || !skipped.length, message, skipped }; + } + case 'mark-touched': + case 'mark-untouched': + case 'mark-dirty': + case 'mark-pristine': { + const n = need(); + const method = { + 'mark-touched': 'markAsTouched', + 'mark-untouched': 'markAsUntouched', + 'mark-dirty': 'markAsDirty', + 'mark-pristine': 'markAsPristine', + }[request.action]; + if (signal && read(() => n['nodeState']['isNonInteractive'](), false)) { + return { + ok: false, + message: `${path || '(form)'} is hidden, disabled or readonly, so Signal Forms ignores touched and dirty on it.`, + }; + } + n[method](); + return { ok: true, message: `${method} on ${path || '(form)'}.` }; + } + case 'touch-all': { + const n = need(); + if (signal) n['markAsTouched'](); + else n['markAllAsTouched'](); + return { ok: true, message: 'Marked every interactive field as touched.' }; + } + case 'revalidate': { + const n = need(); + if (signal) { + if (typeof n['reloadValidation'] !== 'function') + return fail('This Angular version has no reloadValidation.'); + n['reloadValidation'](); + return { ok: true, message: 'Reloaded async validation (HTTP validators fire again).' }; + } + n['updateValueAndValidity'](); + return { ok: true, message: `Revalidated ${path || '(form)'}.` }; + } + case 'reset': { + need()['reset'](); + return { ok: true, message: `Reset ${path || '(form)'}.` }; + } + case 'enable': + case 'disable': { + if (signal) { + return fail( + 'Signal Forms fields are disabled by disabled() rules in the schema, not imperatively. Change the rule or the value it reads.', + ); + } + const n = need(); + if (found.kind === 'template' && path) { + const dir = directivesOf(n); + if (dir) { + return fail( + 'This field uses ngModel, which syncs disabled from its [disabled] input on the next change detection. Change the bound property instead.', + ); + } + } + n[request.action](); + return { + ok: true, + message: `${request.action === 'enable' ? 'Enabled' : 'Disabled'} ${path || '(form)'}.`, + }; + } + case 'submit': { + if (signal) { + const setup = submitSetup(found.root); + const formRoot = directiveWith(ctx, found.formElement, 'onSubmit'); + if (formRoot) { + formRoot['onSubmit'](new Event('submit', { cancelable: true })); + return { + ok: true, + message: setup.willRun + ? 'Submitted through the form root; the action runs.' + : 'Submitted through the form root; the form is invalid, so the action did not run (fields are now touched).', + }; + } + return fail( + setup.hasAction + ? 'This Signal Form has no [formRoot] element to submit through. Call submit(form) from app code.' + : 'This Signal Form has no submission action (NG01915 on submit). Add { submission: { action } } to form().', + ); + } + const el = found.formElement; + if (el instanceof HTMLFormElement) { + if (!el.noValidate && !el.checkValidity()) { + return fail( + 'The browser would block this submit: native validation fails and the form has no novalidate.', + ); + } + el.requestSubmit(); + return { + ok: true, + message: 'Submitted the (ngSubmit fires even when the form is invalid).', + }; + } + const dir = found.directive; + if (dir && typeof dir['onSubmit'] === 'function') { + dir['onSubmit'](new Event('submit', { cancelable: true })); + return { + ok: true, + message: 'Called onSubmit on the form directive (it is not on a ).', + }; + } + return fail('No form element or form directive to submit.'); + } + case 'focus': { + const el = elementFor(ctx, found, path); + if (!(el instanceof HTMLElement)) + return fail(`${path || '(form)'} is not bound to an element.`); + el.scrollIntoView?.({ block: 'center' }); + el.focus(); + return { ok: true, message: `Focused ${path || '(form)'}.` }; + } + case 'focus-first-invalid': { + const candidates = invalidPaths(found) + .map((p) => ({ path: p, el: elementFor(ctx, found, p) })) + .filter((c): c is { path: string; el: HTMLElement } => c.el instanceof HTMLElement); + candidates.sort((a, b) => + a.el.compareDocumentPosition(b.el) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1, + ); + const first = candidates[0]; + if (!first) return fail('No invalid field is bound to an element.'); + first.el.scrollIntoView?.({ block: 'center' }); + first.el.focus(); + return { ok: true, message: `Focused ${first.path}.`, path: first.path }; + } + case 'store-as-global': { + const target = signal ? read(() => found.root['fieldTree'], found.root) : found.root; + const w = window as unknown as AnyRecord; + w['$form'] = target; + w['$control'] = signal ? read(() => nodeAt(found, path, true)?.['fieldTree'], null) : node(); + const expression = expressionFor(found, path); + return { + ok: true, + message: + `Stored as $form in the page console. ${path ? `The field is ${expression} (also $control).` : ''}`.trim(), + expression, + }; + } + case 'snapshot': { + const value = rawValue(found, found.root); + const id = `s${++snapshotSeq}`; + snapshots.set(id, { + root: found.root, + formId: request.formId ?? '', + value: structuredCloneSafe(value), + shape: shapeOf(value), + }); + if (snapshots.size > 20) snapshots.delete(snapshots.keys().next().value!); + return { ok: true, message: `Saved snapshot ${id}.`, snapshot: id }; + } + case 'restore': { + const saved = request.snapshot ? snapshots.get(request.snapshot) : undefined; + if (!saved) + return fail(`No snapshot ${request.snapshot ?? ''} (snapshots live until reload).`); + if (saved.root !== found.root) { + return fail(`Snapshot ${request.snapshot} was taken from another form.`); + } + const currentValue = rawValue(found, found.root); + if (shapeOf(currentValue) !== saved.shape) { + return fail( + 'The form structure changed since the snapshot (arrays or groups differ), so it cannot be restored.', + ); + } + const guarded = guardedFields(ctx, found, found.root, ''); + if (!guarded) return fail('The form is too large to check for protected fields.'); + let restored = keepSecrets(structuredCloneSafe(saved.value), currentValue); + for (const field of guarded) { + restored = setAt(restored, field.path, valueAt(currentValue, field.path)); + } + if (signal) found.root['value'].set(restored); + else found.root['patchValue'](restored); + return { ok: true, message: `Restored snapshot ${request.snapshot}.` }; + } + default: + return fail('Unknown action.'); + } +} + +function structuredCloneSafe(value: T): T { + try { + return structuredClone(value); + } catch { + return serializeFormValue(value) as T; + } +} diff --git a/packages/ng-devtools/src/forms-collector.ts b/packages/ng-devtools/src/forms-collector.ts new file mode 100644 index 0000000..ae564c7 --- /dev/null +++ b/packages/ng-devtools/src/forms-collector.ts @@ -0,0 +1,628 @@ +import { + collectForms, + controlPathOf, + detailOf, + diffForms, + findFieldElement, + findForms, + formIdFor, + propertyHolding, + serializeControl, + watchControlEvents, + type CollectedForm, + type EventOrigin, + type FormEvent, + type FormFieldNode, + type FoundForm, + forgetFormSecrets, + redactFormText, +} from './forms.ts'; +import { + isDevtoolsAction, + isFormAction, + locateElement, + runFormAction, + type ActionContext, + type FormActionResult, +} from './forms-actions.ts'; +import { + VALIDATOR_METHODS, + countRenders, + instrumentForms, + type InstrumentCall, + type Instrumentation, + type RenderCounter, +} from './forms-instrument.ts'; +import { redactMessage } from './forms-privacy.ts'; + +type AnyRecord = Record; + +interface Rpc { + rpc: { + call(name: string, ...args: unknown[]): Promise; + register(definition: { + name: string; + type: 'event'; + jsonSerializable: boolean; + handler: (...args: any[]) => unknown; + }): void; + }; +} + +const MAX_FORM_EVENTS = 200; +const HEARTBEAT_MS = 5000; +const PUSH_DELAY_MS = 80; +const MAX_SETUP_ERRORS = 20; +const MERGE_MS = 2000; +const PICK_TIMEOUT_MS = 12_000; +const DIFFED_FOR_ALL: FormEvent['type'][] = [ + 'value', + 'status', + 'touched', + 'dirty', + 'added', + 'removed', +]; +const USER_EVENTS = ['input', 'change', 'focusout', 'submit', 'reset', 'click', 'keydown']; + +function read(fn: () => T, fallback: T): T { + try { + return fn(); + } catch { + return fallback; + } +} + +function isFieldTarget(target: unknown): target is { formId: string; path: string } { + const t = target as { formId?: unknown; path?: unknown } | null; + return ( + typeof t?.formId === 'string' && + typeof t.path === 'string' && + t.formId.length < 50 && + t.path.length < 500 + ); +} + +export function describeElement(el: Element | null): string | undefined { + if (!el || el === document.body) return undefined; + const tag = el.tagName.toLowerCase(); + const name = el.getAttribute('name') || el.getAttribute('formcontrolname') || el.id; + return name ? `${tag}[${name}]` : tag; +} + +export function setupErrorOf(args: unknown[]): string | null { + const text = args + .map((arg) => (arg instanceof Error ? arg.message : typeof arg === 'string' ? arg : '')) + .join(' '); + const match = text.match(/NG0?1\d{3}[^\n]*/); + return match ? redactMessage(match[0]).slice(0, 300) : null; +} + +function afterPaint(fn: () => void) { + if (typeof requestAnimationFrame === 'function') requestAnimationFrame(fn); + else setTimeout(fn, 16); +} + +export interface FormsCollector { + push(): void; + stop(): void; +} + +export function attachForms( + my: Rpc, + pageId: string, + getNg: () => any, + highlight: { show(el: HTMLElement): void; clear(): void }, +): FormsCollector { + const idOf = (root: object) => `${formIdFor(root)}@${pageId}`; + let lastForms: CollectedForm[] = []; + let lastPayload = ''; + let lastPushAt = 0; + const formEvents: FormEvent[] = []; + const watched = new Map void }>(); + const lastStatus = new Map(); + const lastValue = new Map(); + const pendingSince = new Map(); + const wrappedSubmits = new WeakSet(); + const unwrapSubmits: (() => void)[] = []; + const setupErrors: string[] = []; + let foundById = new Map(); + let fieldElements = new WeakMap(); + let eventSeq = 0; + let userActive = false; + let userSincePush = false; + let devtoolsSincePush = false; + let userTimer: ReturnType | undefined; + let pushTimer: ReturnType | undefined; + let submittingForm: string | null = null; + let instrumentation: Instrumentation | null = null; + let renders: RenderCounter | null = null; + let renderSince: number | null = null; + let pendingCaller: { formId: string; text: string } | null = null; + const signalCallers = new Map(); + const pendingStarted = new Map(); + let cancelPick: (() => void) | null = null; + const ownerNames = new Set(); + + const originNow = (): EventOrigin => + isDevtoolsAction() ? 'devtools' : userActive ? 'user' : 'code'; + + function recordFormEvent(input: FormEvent, infer = true) { + const event: FormEvent = { ...input, seq: ++eventSeq }; + if (infer) event.origin ??= originNow(); + const key = `${event.formId}:${event.path}`; + if (pendingCaller?.formId === event.formId && !event.caller && event.origin !== 'devtools') { + event.caller = pendingCaller.text; + } + if (event.type === 'status') { + const next = event.detail?.split('→').pop()?.trim(); + if (next === 'PENDING') pendingStarted.set(key, event.timestamp); + else if (pendingStarted.has(key)) { + event.ms = event.timestamp - pendingStarted.get(key)!; + pendingStarted.delete(key); + } + } + if (event.type === 'value') { + const previous = lastValue.get(key); + if (previous === event.detail) return; + if (previous !== undefined) event.prev = previous; + lastValue.set(key, event.detail ?? ''); + } + if (event.type === 'status') { + const status = event.detail?.split('→').pop()?.trim() ?? ''; + if (lastStatus.get(key) === status) return; + lastStatus.set(key, status); + } + if (event.type === 'value') { + for (let i = formEvents.length - 1; i >= Math.max(0, formEvents.length - 6); i--) { + const earlier = formEvents[i]; + if (earlier.formId !== event.formId || earlier.path !== event.path) break; + if (earlier.type !== 'value') continue; + if (earlier.origin !== event.origin || event.timestamp - earlier.timestamp > MERGE_MS) + break; + formEvents.splice(i, 1); + formEvents.push({ ...event, prev: earlier.prev, count: (earlier.count ?? 1) + 1 }); + return; + } + } + formEvents.push(event); + if (formEvents.length > MAX_FORM_EVENTS) { + formEvents.splice(0, formEvents.length - MAX_FORM_EVENTS); + } + } + + function seedStatuses(formId: string, node: FormFieldNode) { + lastStatus.set(`${formId}:${node.path}`, node.status); + if (node.type === 'control') lastValue.set(`${formId}:${node.path}`, detailOf(node.value)); + for (const child of node.children ?? []) seedStatuses(formId, child); + } + + function watchRoots(found: FoundForm[]) { + const live = new Set(); + for (const form of found) { + if (form.kind === 'signal') { + wrapSignalSubmit(form); + continue; + } + live.add(form.root); + if (watched.has(form.root)) continue; + const formId = idOf(form.root); + const stop = watchControlEvents( + form.root, + formId, + (event) => { + if (event.type !== 'touched' && event.type !== 'dirty') recordFormEvent(event); + schedulePush(); + }, + { + elements: () => fieldElements, + rootKey: form.property ?? propertyHolding(form) ?? '', + submitted: () => form.directive?.['submitted'], + }, + ); + if (!stop) continue; + watched.set(form.root, { formId, stop }); + seedStatuses(formId, serializeControl(form.root, fieldElements)); + } + for (const [root, { formId, stop }] of watched) { + if (live.has(root)) continue; + stop(); + watched.delete(root); + for (const map of [lastStatus, lastValue, pendingSince]) { + for (const key of map.keys()) { + if (key.startsWith(`${formId}:`)) map.delete(key); + } + } + } + } + + function wrapSignalSubmit(form: FoundForm) { + const flag = read(() => form.root['submitState']['selfSubmitting'] as AnyRecord, null); + if (!flag || wrappedSubmits.has(flag) || typeof flag['set'] !== 'function') return; + wrappedSubmits.add(flag); + const formId = idOf(form.root); + const original = flag['set']; + unwrapSubmits.push(() => { + flag['set'] = original; + wrappedSubmits.delete(flag); + }); + let started = false; + flag['set'] = function (this: unknown, value: boolean) { + const result = original.call(this, value); + if (value) { + started = true; + submittingForm = formId; + recordFormEvent({ + formId, + path: '', + type: 'submit', + outcome: 'ran', + timestamp: Date.now(), + }); + } else { + if (!started) { + recordFormEvent({ + formId, + path: '', + type: 'submit', + outcome: 'blocked', + detail: 'invalid, so the action did not run', + timestamp: Date.now(), + }); + } + started = false; + if (submittingForm === formId) setTimeout(() => (submittingForm = null), 0); + } + schedulePush(); + return result; + }; + } + + function stampPending(formId: string, node: FormFieldNode, now: number) { + const key = `${formId}:${node.path}`; + if (node.status === 'PENDING') { + if (!pendingSince.has(key)) pendingSince.set(key, now); + node.pendingSince = pendingSince.get(key); + } else pendingSince.delete(key); + for (const child of node.children ?? []) stampPending(formId, child, now); + } + + async function pushForms() { + try { + const ng = getNg(); + if (!ng?.getDirectives) return; + const found = findForms(ng, document.querySelectorAll('*')); + foundById = new Map(found.forms.map((form) => [idOf(form.root), form])); + fieldElements = found.elements; + watchRoots(found.forms); + const forms = collectForms(found, idOf); + const now = Date.now(); + for (const form of forms) stampPending(form.id, form.root, now); + const streamed = new Set(Array.from(watched.values(), ({ formId }) => formId)); + for (const event of diffForms(lastForms, forms)) { + if (!streamed.has(event.formId) || DIFFED_FOR_ALL.includes(event.type)) { + const caller = signalCallers.get(event.formId); + const origin: EventOrigin | undefined = devtoolsSincePush + ? 'devtools' + : userSincePush + ? 'user' + : caller !== undefined + ? 'code' + : undefined; + const tagged: FormEvent = origin ? { ...event, origin } : event; + if (caller && origin !== 'devtools') tagged.caller = caller; + recordFormEvent(tagged, false); + } + } + lastForms = forms; + for (const form of forms) ownerNames.add(form.owner); + userSincePush = false; + devtoolsSincePush = false; + signalCallers.clear(); + attachRenders(); + if (instrumentation) { + for (const form of found.forms) { + if (form.kind === 'signal') instrumentation.addSignalRoot(form.root); + else instrumentation.addControl(form.root); + } + } + const report = { + pageId, + forms, + events: formEvents, + setupErrors, + instrumented: !!instrumentation, + }; + const payload = JSON.stringify(report); + if (payload === lastPayload && now - lastPushAt < HEARTBEAT_MS) return; + lastPayload = payload; + lastPushAt = now; + await my.rpc.call('push-forms', report); + } catch { + return; + } + } + + function schedulePush() { + if (pushTimer) return; + pushTimer = setTimeout(() => { + pushTimer = undefined; + void pushForms(); + }, PUSH_DELAY_MS); + } + + function attachRenders() { + if (!renders || renderSince === null) return; + const since = renderSince; + const taken = renders.take(); + renderSince = null; + if (!taken) return; + for (let i = formEvents.length - 1; i >= 0; i--) { + const event = formEvents[i]; + if ((event.seq ?? 0) <= since) break; + if (event.type === 'value' && event.origin === 'user') { + event.renders = taken.total; + event.rendered = taken.top; + return; + } + } + } + + function onInstrumentedCall(call: InstrumentCall) { + if (isDevtoolsAction()) return; + const root = call.signalRoot ?? read(() => call.target['root'] as AnyRecord, null); + if (!root) return; + const formId = idOf(root); + if (!foundById.has(formId)) return; + const text = call.caller ? `${call.method} in ${call.caller}` : ''; + if (call.signalRoot) { + if (!signalCallers.get(formId)) signalCallers.set(formId, text); + schedulePush(); + return; + } + if (VALIDATOR_METHODS.includes(call.method)) { + if (!call.caller) return; + recordFormEvent({ + formId, + path: read(() => controlPathOf(root, call.target), ''), + type: 'validators', + detail: call.method, + caller: call.caller, + origin: 'code', + timestamp: Date.now(), + }); + schedulePush(); + return; + } + if (!text) return; + pendingCaller = { formId, text }; + setTimeout(() => { + if (pendingCaller?.text === text) pendingCaller = null; + }, 0); + } + + function setInstrumented(on: boolean): FormActionResult { + if (on && !instrumentation) { + instrumentation = instrumentForms(onInstrumentedCall, ownerNames); + renders = countRenders(getNg()); + void pushForms(); + return { + ok: true, + message: renders + ? 'Recording callers, validator changes and renders per keystroke.' + : 'Recording callers and validator changes (render counts need Angular debug APIs).', + }; + } + if (!on && instrumentation) { + instrumentation.stop(); + renders?.stop(); + instrumentation = null; + renders = null; + void pushForms(); + } + return { ok: true, message: on ? 'Already recording.' : 'Stopped recording.' }; + } + + function pick(ctx: ActionContext): Promise { + cancelPick?.(); + const failed = (message: string): FormActionResult => ({ ok: false, message, error: message }); + return new Promise((resolve) => { + const finish = (result: FormActionResult) => { + document.removeEventListener('click', onClick, true); + document.removeEventListener('mouseover', onHover, true); + document.removeEventListener('keydown', onKey, true); + clearTimeout(timer); + highlight.clear(); + cancelPick = null; + resolve(result); + }; + const onHover = (event: Event) => { + if (event.target instanceof HTMLElement) highlight.show(event.target); + }; + const onClick = (event: Event) => { + event.preventDefault(); + event.stopPropagation(); + const target = event.target instanceof Element ? event.target : null; + const field = + target?.closest('input, select, textarea, [formcontrolname], [ngmodel]') ?? target; + finish( + (field && locateElement(ctx, field)) ?? + failed('That element is not bound to a form field.'), + ); + }; + const onKey = (event: KeyboardEvent) => { + if (event.key === 'Escape') finish(failed('Picking cancelled.')); + }; + const timer = setTimeout(() => finish(failed('No field was picked.')), PICK_TIMEOUT_MS); + cancelPick = () => finish(failed('Picking cancelled.')); + document.addEventListener('click', onClick, true); + document.addEventListener('mouseover', onHover, true); + document.addEventListener('keydown', onKey, true); + }); + } + + const onUserEvent = (event: Event) => { + if (!isDevtoolsAction()) userSincePush = true; + if (renders && renderSince === null && (event.type === 'input' || event.type === 'change')) { + renderSince = eventSeq; + renders.start(); + } + userActive = true; + clearTimeout(userTimer); + userTimer = setTimeout(() => (userActive = false), 0); + if (event.type === 'submit') onSubmit(event); + if (event.type !== 'click' && event.type !== 'keydown') schedulePush(); + }; + + function onSubmit(event: Event) { + const target = event.target; + for (const [formId, form] of foundById) { + if (form.formElement !== target || form.kind === 'signal') continue; + const status = String(read(() => form.root['status'], '')); + setTimeout(() => { + afterPaint(() => { + const focus = describeElement(document.activeElement); + recordFormEvent({ + formId, + path: '', + type: 'submit', + outcome: 'ran', + detail: `status ${status} at submit${focus ? `, focus on ${focus}` : ''}`, + origin: isDevtoolsAction() ? 'devtools' : 'user', + timestamp: Date.now(), + }); + schedulePush(); + }); + }, 0); + } + } + + const onRejection = (event: PromiseRejectionEvent) => { + if (!submittingForm) return; + recordFormEvent({ + formId: submittingForm, + path: '', + type: 'submit', + outcome: 'threw', + detail: redactFormText( + submittingForm, + String(event.reason?.message ?? event.reason ?? 'error'), + ).slice(0, 200), + timestamp: Date.now(), + }); + schedulePush(); + }; + + for (const type of USER_EVENTS) document.addEventListener(type, onUserEvent, true); + addEventListener('unhandledrejection', onRejection); + + const originalError = console.error; + const patchedError = function (this: unknown, ...args: unknown[]) { + const setup = read(() => setupErrorOf(args), null); + if (setup && !setupErrors.includes(setup)) { + setupErrors.push(setup); + if (setupErrors.length > MAX_SETUP_ERRORS) setupErrors.shift(); + schedulePush(); + } + return originalError.apply(this, args as []); + }; + console.error = patchedError; + + my.rpc.register({ + name: 'highlight-form-field', + type: 'event', + jsonSerializable: true, + handler: (target: { formId: string; path: string } | null) => { + highlight.clear(); + const ng = getNg(); + if (!isFieldTarget(target) || !ng?.getDirectives) return; + const found = foundById.get(target.formId); + if (!found) return; + try { + const el = findFieldElement( + ng, + document.querySelectorAll('*'), + found, + target.path, + fieldElements, + ); + if (el instanceof HTMLElement) highlight.show(el); + } catch { + return; + } + }, + }); + + my.rpc.register({ + name: 'form-action', + type: 'event', + jsonSerializable: true, + handler: (message: { requestId?: string; pageId?: string; request?: unknown }) => { + if (!message || typeof message.requestId !== 'string') return; + if (message.pageId && message.pageId !== pageId) return; + const respond = (result: unknown) => + void my.rpc + .call('form-action-result', { requestId: message.requestId, pageId, result }) + .catch(() => {}); + const ng = getNg(); + if (!ng?.getDirectives) + return respond({ + ok: false, + error: 'This page has no Angular debug API (production build?).', + }); + if (!isFormAction(message.request)) + return respond({ ok: false, error: 'Unknown form action.' }); + const request = message.request; + if (request.formId && !foundById.has(request.formId) && request.action !== 'locate') return; + if (!request.formId && !foundById.size && request.action !== 'locate') return; + if (request.action === 'locate') { + let el: Element | null = null; + try { + el = request.selector ? document.querySelector(request.selector) : null; + } catch { + el = null; + } + if (!el) return; + } + const ctx: ActionContext = { + ng, + forms: foundById, + elements: fieldElements, + all: () => document.querySelectorAll('*'), + }; + if (request.action === 'instrument') return respond(setInstrumented(request.value !== false)); + if (request.action === 'pick') { + void pick(ctx).then(respond); + return; + } + devtoolsSincePush = true; + runFormAction(ctx, request).then( + (result) => { + respond(result); + void pushForms(); + }, + (error) => respond({ ok: false, error: String((error as Error)?.message ?? error) }), + ); + }, + }); + + return { + push: () => void pushForms(), + stop() { + clearTimeout(pushTimer); + clearTimeout(userTimer); + for (const type of USER_EVENTS) document.removeEventListener(type, onUserEvent, true); + removeEventListener('unhandledrejection', onRejection); + if (console.error === patchedError) console.error = originalError; + for (const { stop } of watched.values()) stop(); + watched.clear(); + for (const unwrap of unwrapSubmits.splice(0)) unwrap(); + cancelPick?.(); + instrumentation?.stop(); + renders?.stop(); + instrumentation = null; + renders = null; + forgetFormSecrets(lastForms.map((form) => form.id)); + }, + }; +} diff --git a/packages/ng-devtools/src/forms-dom.ts b/packages/ng-devtools/src/forms-dom.ts new file mode 100644 index 0000000..dd573fd --- /dev/null +++ b/packages/ng-devtools/src/forms-dom.ts @@ -0,0 +1,174 @@ +export interface DomFacts { + ariaInvalid?: boolean; + required?: boolean; + labelled?: boolean; + describedBy?: boolean; + errorShown?: boolean; + disabled?: boolean; + drift?: string | true; + classes?: string[]; +} + +export interface SubmitDom { + tag: string; + buttons: number; + disabledButtons: number; + novalidate: boolean; + nativeInvalid: number; + reasons: string[]; +} + +const ERROR_TEXT = + 'mat-error, [role="alert"], .invalid-feedback, .error, .errors, .field-error, .error-message, [data-error]'; +const CONTAINER = + 'mat-form-field, .mat-mdc-form-field, .form-group, .form-field, .field, fieldset, label'; +const STATUS_CLASS = /^ng-(valid|invalid|pending|dirty|pristine|touched|untouched|submitted)$/; + +function safe(fn: () => T, fallback: T): T { + try { + return fn(); + } catch { + return fallback; + } +} + +export function isShown(el: Element): boolean { + if (!el.textContent?.trim()) return false; + if (el.closest('[hidden], [aria-hidden="true"]')) return false; + const check = (el as Element & { checkVisibility?: () => boolean }).checkVisibility; + if (typeof check === 'function') return safe(() => check.call(el), true); + const view = el.ownerDocument?.defaultView; + for (let node: Element | null = el; node; node = node.parentElement) { + const style = view ? safe(() => view.getComputedStyle(node!), null) : null; + if (style && (style.display === 'none' || style.visibility === 'hidden')) return false; + } + return true; +} + +function referenced(el: Element, attr: string): Element[] { + const ids = (el.getAttribute(attr) ?? '').split(/\s+/).filter(Boolean); + return ids + .map((id) => el.ownerDocument?.getElementById(id)) + .filter((target): target is HTMLElement => !!target); +} + +function isLabelled(el: Element): boolean { + if (el.getAttribute('aria-label')?.trim()) return true; + if (referenced(el, 'aria-labelledby').some((l) => l.textContent?.trim())) return true; + const labels = (el as HTMLInputElement).labels; + if (labels && Array.from(labels).some((l) => l.textContent?.trim())) return true; + if (el.closest('label')?.textContent?.trim()) return true; + return !!el.getAttribute('title')?.trim(); +} + +function errorElements(el: Element): Element[] { + const linked = [...referenced(el, 'aria-describedby'), ...referenced(el, 'aria-errormessage')]; + const container = el.closest(CONTAINER) ?? el.parentElement; + const near = container + ? Array.from(safe(() => container.querySelectorAll(ERROR_TEXT), [] as never)).filter( + (candidate: Element) => candidate !== el && !candidate.contains(el), + ) + : []; + return [...new Set([...linked, ...near])]; +} + +function domValue(el: Element): string | boolean | undefined { + if (el instanceof HTMLInputElement) { + if (el.type === 'file') return undefined; + if (el.type === 'checkbox') return el.checked; + if (el.type === 'radio') return undefined; + return el.value; + } + if (el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) return el.value; + return undefined; +} + +function sameValue(dom: string | boolean, model: unknown): boolean { + if (typeof dom === 'boolean') return dom === !!model; + if (model === null || model === undefined) return dom === ''; + if (typeof model === 'number') return dom === '' ? Number.isNaN(model) : Number(dom) === model; + if (typeof model === 'string' || typeof model === 'boolean') return dom === String(model); + if (model instanceof Date) return true; + return true; +} + +export function domFacts( + el: Element, + model: { value?: unknown; disabled?: boolean; secret?: boolean; hasErrors?: boolean }, +): DomFacts { + const facts: DomFacts = {}; + const aria = el.getAttribute('aria-invalid'); + if (aria !== null) facts.ariaInvalid = aria === 'true'; + facts.required = + el.hasAttribute('required') || el.getAttribute('aria-required') === 'true' ? true : undefined; + if (facts.required === undefined) delete facts.required; + facts.labelled = isLabelled(el); + const describedBy = [ + ...referenced(el, 'aria-describedby'), + ...referenced(el, 'aria-errormessage'), + ]; + if (describedBy.length) facts.describedBy = describedBy.some((d) => !!d.textContent?.trim()); + if (model.hasErrors) facts.errorShown = errorElements(el).some(isShown); + const disabled = (el as HTMLInputElement).disabled; + if (typeof disabled === 'boolean' && disabled !== !!model.disabled) facts.disabled = disabled; + const dom = domValue(el); + if (dom !== undefined && 'value' in model && !sameValue(dom, model.value)) { + facts.drift = model.secret ? true : String(dom).slice(0, 200); + } + const classes = Array.from(el.classList).filter((c) => STATUS_CLASS.test(c)); + if (classes.length) facts.classes = classes; + return facts; +} + +function isSubmitter(el: Element): boolean { + if (el instanceof HTMLButtonElement) return (el.getAttribute('type') ?? 'submit') === 'submit'; + if (el instanceof HTMLInputElement) return el.type === 'submit' || el.type === 'image'; + return false; +} + +export function submitDom(el: Element): SubmitDom { + const tag = el.tagName.toLowerCase(); + const reasons: string[] = []; + if (!(el instanceof HTMLFormElement)) { + reasons.push( + `The form directive sits on a <${tag}>, not a , so the browser never fires submit or ngSubmit.`, + ); + return { tag, buttons: 0, disabledButtons: 0, novalidate: false, nativeInvalid: 0, reasons }; + } + const inside = Array.from(el.querySelectorAll('button, input')); + const outside = el.id + ? Array.from(el.ownerDocument.querySelectorAll(`[form="${el.id.replace(/["\\]/g, '\\$&')}"]`)) + : []; + const candidates = [...inside, ...outside].filter((b) => { + const owner = (b as HTMLButtonElement).form; + return owner === el || (owner === undefined && inside.includes(b)); + }); + const submitters = candidates.filter(isSubmitter); + const disabledButtons = submitters.filter((b) => (b as HTMLButtonElement).disabled).length; + const typed = candidates.filter((b) => b instanceof HTMLButtonElement && !isSubmitter(b)); + if (!submitters.length) { + reasons.push( + typed.length + ? 'No submit button: the buttons in this form are type="button", so clicking them does not submit.' + : 'No submit button in the form (or linked with form="id"). Enter submits only with a single text input or a submit button.', + ); + } else if (disabledButtons === submitters.length) { + reasons.push('Every submit button is disabled, so the form cannot be submitted by clicking.'); + } + const nativeInvalid = el.noValidate + ? 0 + : safe(() => el.querySelectorAll('input:invalid, select:invalid, textarea:invalid').length, 0); + if (nativeInvalid) { + reasons.push( + `The form has no novalidate and ${nativeInvalid} input(s) fail native validation, so the browser blocks submit before Angular sees it (ngNativeValidate or ngNoForm?).`, + ); + } + return { + tag, + buttons: submitters.length, + disabledButtons, + novalidate: el.noValidate, + nativeInvalid, + reasons, + }; +} diff --git a/packages/ng-devtools/src/forms-instrument.ts b/packages/ng-devtools/src/forms-instrument.ts new file mode 100644 index 0000000..b41cd9e --- /dev/null +++ b/packages/ng-devtools/src/forms-instrument.ts @@ -0,0 +1,216 @@ +type AnyRecord = Record; + +export interface InstrumentCall { + method: string; + target: AnyRecord; + caller?: string; + signalRoot?: AnyRecord; +} + +export interface Instrumentation { + addControl(control: AnyRecord): void; + addSignalRoot(root: AnyRecord): void; + stop(): void; +} + +const VALUE_METHODS = ['setValue', 'patchValue', 'reset']; +const STRUCTURE_METHODS = [ + 'push', + 'insert', + 'removeAt', + 'setControl', + 'addControl', + 'removeControl', + 'clear', +]; +const STATE_METHODS = [ + 'markAsTouched', + 'markAsUntouched', + 'markAsDirty', + 'markAsPristine', + 'markAllAsTouched', + 'enable', + 'disable', + 'setErrors', +]; +export const VALIDATOR_METHODS = [ + 'setValidators', + 'setAsyncValidators', + 'addValidators', + 'addAsyncValidators', + 'removeValidators', + 'removeAsyncValidators', + 'clearValidators', + 'clearAsyncValidators', +]; +const METHODS = [...VALUE_METHODS, ...STRUCTURE_METHODS, ...STATE_METHODS, ...VALIDATOR_METHODS]; + +const FRAMEWORK = + /@angular|node_modules|\.vite\/deps|rxjs|zone\.js|zone-|forms-(instrument|collector|actions)\.[mc]?[jt]s|ng-devtools\/(dist|src\/(?!__tests__))||\(native\)/; +const FRAMEWORK_CLASS = + /^(Abstract|Form|Ng|Default|Operator|Checkbox|Select|Radio|Number|Range|Subscriber|Safe|Consumer|Observable|Subject|EventEmitter|Zone|Object|Array|Function|Proxy|Promise|Router|Renderer|Dom|EventManager|ApplicationRef|ChangeDetection|ViewRef|ComponentRef|Injector|R3Injector|NodeInjector|Listener|Task|Scheduler|Interop|Signal|Field|Deep)/; +const FRAMEWORK_FUNCTION = + /^(updateControl|setUp\w*|cleanUp\w*|syncPendingControls|next|onInvoke\w*|invoke\w*|run\w*|execute\w*|refresh\w*|detectChanges\w*|wrapListener\w*|handleEvent|dispatch\w*|callHook\w*|process\w*|flush\w*|tick|markViewDirty|emit|onChange|onTouched|writeValue|setValue|patchValue|reset|signal\w*|producer\w*|consumer\w*|wrapper|listener|anonymous)$/; + +function frameName(line: string): { name: string; where: string } { + const match = line.match(/^(.*?)\s*\((.*)\)$/) ?? line.match(/^(.*?)@(.*)$/); + const name = (match ? match[1] : '').trim().replace(/^async\s+/, ''); + const where = (match ? match[2] : line) + .replace(/^https?:\/\/[^/]+\//, '') + .replace(/\?[^:]*(?=:\d)/, ''); + return { name, where }; +} + +function isFrameworkName(name: string): boolean { + const bare = name.replace(/^new\s+/, '').replace(/^_+/, ''); + if (/_(HostBindingHandler|Template|Factory|Listener|listener)\b|^ɵ/.test(bare)) return true; + if (bare.includes('.')) return FRAMEWORK_CLASS.test(bare); + return FRAMEWORK_FUNCTION.test(bare.replace(/^_+/, '')); +} + +export function callerFrom( + stack: string | undefined, + preferred: ReadonlySet = new Set(), +): string | undefined { + if (!stack) return undefined; + const frames = stack + .split('\n') + .slice(1) + .map((raw) => raw.trim().replace(/^at\s+/, '')) + .filter((line) => line && !FRAMEWORK.test(line)) + .map(frameName); + const format = ({ name, where }: { name: string; where: string }) => + (name ? `${name.replace(/^_+/, '')} (${where})` : where).slice(0, 200); + const owned = frames.find(({ name }) => { + const owner = name.replace(/^_+/, '').split('.')[0]; + return name.includes('.') && preferred.has(owner); + }); + if (owned) return format(owned); + const fallback = frames.find(({ name }) => name && !isFrameworkName(name)); + return fallback ? format(fallback) : undefined; +} + +const WRAPPED = Symbol('ng-devtools-wrapped'); + +export function instrumentForms( + onCall: (call: InstrumentCall) => void, + preferred: ReadonlySet = new Set(), +): Instrumentation { + const restores: (() => void)[] = []; + const seenProtos = new WeakSet(); + const seenRoots = new WeakSet(); + let depth = 0; + + const wrap = (holder: AnyRecord, method: string, signalRoot?: AnyRecord) => { + const original = holder[method]; + if (typeof original !== 'function' || original[WRAPPED]) return; + const wrapper = function (this: AnyRecord, ...args: unknown[]) { + if (depth === 0) { + try { + onCall({ + method, + target: signalRoot ?? this, + caller: callerFrom(new Error().stack, preferred), + signalRoot, + }); + } catch { + // never break the app + } + } + depth++; + try { + return original.apply(this, args); + } finally { + depth--; + } + }; + Object.defineProperty(wrapper, WRAPPED, { value: true }); + try { + holder[method] = wrapper; + } catch { + return; + } + restores.push(() => { + if (holder[method] === wrapper) holder[method] = original; + }); + }; + + const wrapPrototypes = (control: AnyRecord) => { + for ( + let proto = Object.getPrototypeOf(control); + proto && proto !== Object.prototype; + proto = Object.getPrototypeOf(proto) + ) { + if (seenProtos.has(proto)) continue; + seenProtos.add(proto); + for (const method of METHODS) { + if (Object.prototype.hasOwnProperty.call(proto, method)) wrap(proto, method); + } + } + }; + + return { + addControl(control) { + const visit = (node: AnyRecord, depth: number) => { + wrapPrototypes(node); + if (depth > 12) return; + let controls: unknown; + try { + controls = node['controls']; + } catch { + return; + } + if (!controls || typeof controls !== 'object') return; + for (const child of Object.values(controls as object)) { + if (child && typeof child === 'object') visit(child as AnyRecord, depth + 1); + } + }; + visit(control, 0); + }, + addSignalRoot(root) { + const model = root?.['structure']?.['value'] as AnyRecord | undefined; + if (!model || seenRoots.has(model)) return; + seenRoots.add(model); + for (const method of ['set', 'update']) wrap(model, method, root); + }, + stop() { + for (const restore of restores.splice(0).reverse()) restore(); + }, + }; +} + +export const TEMPLATE_UPDATE_START = 2; + +export interface RenderCounter { + start(): void; + take(): { total: number; top: string[] } | null; + stop(): void; +} + +export function countRenders(ng: AnyRecord): RenderCounter | null { + if (typeof ng?.['ɵsetProfiler'] !== 'function') return null; + let counts: Map | null = null; + const profiler = (event: number, instance: unknown) => { + if (!counts || event !== TEMPLATE_UPDATE_START || !instance) return; + if (!((instance as AnyRecord).constructor as AnyRecord | undefined)?.['ɵcmp']) return; + const name = String((instance as AnyRecord).constructor?.name ?? '?').replace(/^_+/, ''); + counts.set(name, (counts.get(name) ?? 0) + 1); + }; + const remove = ng['ɵsetProfiler'](profiler); + return { + start() { + counts = new Map(); + }, + take() { + if (!counts) return null; + const entries = Array.from(counts.entries()).sort((a, b) => b[1] - a[1]); + counts = null; + const total = entries.reduce((sum, [, n]) => sum + n, 0); + return total ? { total, top: entries.slice(0, 3).map(([name, n]) => `${name}×${n}`) } : null; + }, + stop() { + counts = null; + if (typeof remove === 'function') remove(); + }, + }; +} diff --git a/packages/ng-devtools/src/forms-privacy.ts b/packages/ng-devtools/src/forms-privacy.ts new file mode 100644 index 0000000..172b443 --- /dev/null +++ b/packages/ng-devtools/src/forms-privacy.ts @@ -0,0 +1,136 @@ +export const REDACTED = '[redacted]'; + +export type RedactReason = 'key' | 'input-type' | 'autocomplete' | 'marker' | 'parent' | 'config'; + +const SECRET_WORDS = new Set([ + 'password', + 'passwd', + 'passphrase', + 'passcode', + 'pass', + 'pwd', + 'secret', + 'token', + 'otp', + 'totp', + 'pin', + 'cvv', + 'cvc', + 'csc', + 'ssn', + 'iban', + 'card', + 'cc', + 'credential', + 'credentials', +]); + +const SECRET_PAIRS = new Set([ + 'apikey', + 'privatekey', + 'secretkey', + 'accesskey', + 'ccnum', + 'ccnumber', + 'securitycode', +]); + +const SECRET_AUTOCOMPLETE = /password|one-time-code|cc-/i; +const MASK_MARKERS = '.sentry-mask, .rr-mask, [data-private], [data-ng-devtools="mask"]'; +const UNMASK_MARKER = '[data-ng-devtools="unmask"]'; +const JWT = /\beyJ[\w-]{5,}\.[\w-]{5,}\.[\w-]{5,}/g; +const BEARER = /\bBearer\s+[\w.~+/=-]+/gi; + +interface PrivacyConfig { + mask?: string[]; + unmask?: string[]; +} + +function config(): PrivacyConfig { + try { + const value = (globalThis as { __NG_DEVTOOLS_FORMS__?: unknown }).__NG_DEVTOOLS_FORMS__; + return value && typeof value === 'object' ? (value as PrivacyConfig) : {}; + } catch { + return {}; + } +} + +export function wordsOf(key: string): string[] { + return key + .replace(/([a-z0-9])([A-Z])/g, '$1 $2') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2') + .toLowerCase() + .split(/[^a-z0-9]+/) + .filter(Boolean); +} + +function singular(word: string): string { + return word.length > 3 && word.endsWith('s') && !word.endsWith('ss') ? word.slice(0, -1) : word; +} + +export function isSecretKey(key: string): boolean { + const words = wordsOf(key).map(singular); + if (words.some((word) => SECRET_WORDS.has(word))) return true; + if (SECRET_PAIRS.has(words.join(''))) return true; + return words.some((word, i) => i > 0 && SECRET_PAIRS.has(words[i - 1] + word)); +} + +function listed(list: string[] | undefined, key: string): boolean { + return Array.isArray(list) && list.some((entry) => entry === key); +} + +export function redactReason(key: string, element?: Element | null): RedactReason | null { + const { mask, unmask } = config(); + if (listed(unmask, key)) return null; + const unmasked = !!element && safeClosest(element, UNMASK_MARKER); + if (listed(mask, key)) return 'config'; + if (!unmasked && isSecretKey(key)) return 'key'; + if (!element || unmasked) return null; + if (element.getAttribute('type') === 'password') return 'input-type'; + if (SECRET_AUTOCOMPLETE.test(element.getAttribute('autocomplete') ?? '')) return 'autocomplete'; + if (safeClosest(element, MASK_MARKERS)) return 'marker'; + if (safeQuery(element, 'input[type="password"]')) return 'input-type'; + return null; +} + +function safeClosest(element: Element, selector: string): boolean { + try { + return !!element.closest(selector); + } catch { + return false; + } +} + +function safeQuery(element: Element, selector: string): boolean { + try { + return !!element.querySelector(selector); + } catch { + return false; + } +} + +export function redactMessage(text: string, secrets: Iterable = []): string { + let out = text.replace(JWT, REDACTED).replace(BEARER, `Bearer ${REDACTED}`); + for (const secret of secrets) { + if (secret.length < 3) continue; + out = out.split(secret).join(REDACTED); + } + return out; +} + +export class SecretSet { + private readonly values = new Set(); + + add(value: unknown) { + if (typeof value === 'string' && value.length >= 3) this.values.add(value); + else if (typeof value === 'number' && String(value).length >= 3) this.values.add(String(value)); + } + + get size() { + return this.values.size; + } + + redact(text: string): string { + return redactMessage(text, this.values); + } +} diff --git a/packages/ng-devtools/src/forms-read.ts b/packages/ng-devtools/src/forms-read.ts new file mode 100644 index 0000000..f8c7556 --- /dev/null +++ b/packages/ng-devtools/src/forms-read.ts @@ -0,0 +1,375 @@ +type AnyRecord = Record; + +export type ErrorSource = + 'parse' | 'own' | 'tree' | 'async' | 'submission' | 'schema' | 'directive' | 'manual'; + +export interface ErrorOrigin { + source: ErrorSource; + from?: string; +} + +export type SkipReason = 'hidden' | 'disabled' | 'readonly' | 'orphaned'; + +export interface RuleCounts { + sync?: number; + tree?: number; + async?: number; + hidden?: number; + disabled?: number; + readonly?: number; + metadata?: number; +} + +export interface SignalFacts { + skipped?: SkipReason; + asyncWaiting?: boolean; + inheritedDisabled?: number; + hiddenBy?: 'self' | 'parent'; + readonlyBy?: 'self' | 'parent'; + rules?: RuleCounts; +} + +export interface SubmitSetup { + hasAction: boolean; + hasOnInvalid: boolean; + ignoreValidators?: string; + submitting: boolean; + willRun: boolean; +} + +export interface ControlFacts { + origins: Record; + stale?: string[]; + validators?: string[]; + asyncValidators?: string[]; + pending?: { value: unknown }; + model?: { model: unknown; viewModel: unknown }; +} + +let probing = 0; + +export function isProbing(): boolean { + return probing > 0; +} + +export function withoutEvents(fn: () => T): T { + probing++; + try { + return fn(); + } finally { + probing--; + } +} + +function read(fn: () => T, fallback: T): T { + try { + return fn(); + } catch { + return fallback; + } +} + +function list(fn: () => unknown): T[] { + const value = read(fn, []); + return Array.isArray(value) ? (value as T[]) : []; +} + +function parentOf(node: AnyRecord): AnyRecord | null { + return read(() => (node['structure']['parent'] as AnyRecord) ?? null, null); +} + +export function fieldPath(node: AnyRecord): string { + const keys: string[] = []; + let current: AnyRecord | null = node; + for (let guard = 0; current && guard < 64; guard++) { + const parent = parentOf(current); + if (!parent) break; + keys.unshift(String(read(() => current!['keyInParent'](), '?'))); + current = parent; + } + return keys.join('.'); +} + +function originLevel(node: AnyRecord, error: unknown, raw: string): AnyRecord { + let level = node; + for (let guard = 0; guard < 64; guard++) { + const parent = parentOf(level); + if (!parent) break; + const inherited = list(() => parent['validationState'][raw]()); + if (!inherited.includes(error)) break; + level = parent; + } + return level; +} + +export function signalErrorOrigins(node: AnyRecord): Map { + const state = read(() => node['validationState'] as AnyRecord, null); + const out = new Map(); + if (!state) return out; + for (const error of list(() => state['parseErrors']())) out.set(error, { source: 'parse' }); + const submission = read(() => node['submitState']['submissionErrors'](), undefined); + for (const error of Array.isArray(submission) ? submission : submission ? [submission] : []) { + out.set(error, { source: 'submission' }); + } + const self = fieldPath(node); + for (const error of list(() => state['syncTreeErrors']())) { + if (out.has(error)) continue; + const from = fieldPath(originLevel(node, error, 'rawSyncTreeErrors')); + out.set(error, from === self ? { source: 'tree' } : { source: 'tree', from }); + } + for (const error of list(() => state['asyncErrors']())) { + if (error === 'pending' || out.has(error)) continue; + const from = fieldPath(originLevel(node, error, 'rawAsyncErrors')); + out.set(error, from === self ? { source: 'async' } : { source: 'async', from }); + } + for (const error of list(() => state['errors']())) { + if (out.has(error)) continue; + out.set(error, { source: error?.['kind'] === 'standardSchema' ? 'schema' : 'own' }); + } + return out; +} + +function ruleCount(logic: AnyRecord, name: string): number { + return list(() => logic[name]['fns']).length; +} + +export function ruleCounts(node: AnyRecord): RuleCounts | undefined { + const logic = read(() => node['logicNode']['logic'] as AnyRecord, null); + if (!logic) return undefined; + const counts: RuleCounts = {}; + for (const [name, key] of [ + ['syncErrors', 'sync'], + ['syncTreeErrors', 'tree'], + ['asyncErrors', 'async'], + ['hidden', 'hidden'], + ['disabledReasons', 'disabled'], + ['readonly', 'readonly'], + ] as const) { + const n = ruleCount(logic, name); + if (n) counts[key] = n; + } + const metadata = read(() => (logic['metadata'] as Map).size, 0); + if (metadata) counts.metadata = metadata; + return Object.keys(counts).length ? counts : undefined; +} + +export function signalFacts(node: AnyRecord): SignalFacts { + const facts: SignalFacts = {}; + const state = read(() => node['nodeState'] as AnyRecord, null); + const parent = parentOf(node); + const flag = (name: string) => !!read(() => state?.[name](), false); + if (read(() => node['structure']['isOrphaned'](), false)) facts.skipped = 'orphaned'; + else if (flag('hidden')) facts.skipped = 'hidden'; + else if (flag('disabled')) facts.skipped = 'disabled'; + else if (flag('readonly')) facts.skipped = 'readonly'; + const inherited = parent ? list(() => parent['nodeState']['disabledReasons']()).length : 0; + if (inherited) facts.inheritedDisabled = inherited; + for (const name of ['hidden', 'readonly'] as const) { + if (!flag(name)) continue; + const byParent = !!parent && !!read(() => parent['nodeState'][name](), false); + facts[name === 'hidden' ? 'hiddenBy' : 'readonlyBy'] = byParent ? 'parent' : 'self'; + } + const rules = ruleCounts(node); + if (rules) facts.rules = rules; + const hasAsync = !!rules?.async || hasAncestorAsync(parent); + if (hasAsync && !facts.skipped && !read(() => node['validationState']['syncValid'](), true)) { + facts.asyncWaiting = true; + } + return facts; +} + +function hasAncestorAsync(node: AnyRecord | null): boolean { + for (let guard = 0; node && guard < 64; guard++) { + if ( + ruleCount( + read(() => node!['logicNode']['logic'], {}), + 'asyncErrors', + ) + ) + return true; + node = parentOf(node); + } + return false; +} + +export function metadataKeyCount(node: AnyRecord): number { + return read(() => Array.from(node['logicNode']['logic'].getMetadataKeys()).length, 0); +} + +export function submitSetup(root: AnyRecord): SubmitSetup { + const options = read( + () => root['structure']['fieldManager']['submitOptions'] as AnyRecord | undefined, + undefined, + ); + const normalized = typeof options === 'function' ? { action: options } : options; + const ignore = read(() => normalized?.['ignoreValidators'] as string | undefined, undefined); + const submitting = !!read(() => root['submitState']['submitting'](), false); + const valid = !!read(() => root['valid'](), false); + const invalid = !!read(() => root['invalid'](), false); + const passes = ignore === 'all' ? true : ignore === 'none' ? valid : !invalid; + const setup: SubmitSetup = { + hasAction: typeof normalized?.['action'] === 'function', + hasOnInvalid: typeof normalized?.['onInvalid'] === 'function', + submitting, + willRun: !submitting && passes, + }; + if (ignore) setup.ignoreValidators = ignore; + return setup; +} + +export function fnName(fn: unknown): string { + const name = read(() => String((fn as AnyRecord)?.['name'] ?? ''), ''); + return name.replace(/^bound /, '').replace(/^_+/, '') || 'anonymous'; +} + +function asList(value: unknown): unknown[] { + if (value == null) return []; + return Array.isArray(value) ? value : [value]; +} + +function directiveName(item: unknown): string { + if (typeof item === 'function') return fnName(item); + const name = read(() => String((item as AnyRecord).constructor.name), '').replace(/^_+/, ''); + const base = name.replace(/Validator$/, ''); + return base ? base[0].toLowerCase() + base.slice(1) : 'directive'; +} + +export function validatorNames( + control: AnyRecord, + dir?: AnyRecord | null, + kind: 'sync' | 'async' = 'sync', +): string[] { + const raw = asList( + read(() => control[kind === 'sync' ? '_rawValidators' : '_rawAsyncValidators'], null), + ); + const dirFn = dir + ? read(() => dir[kind === 'sync' ? 'validator' : 'asyncValidator'], null) + : null; + const dirItems = dir + ? asList(read(() => dir[kind === 'sync' ? '_rawValidators' : '_rawAsyncValidators'], null)) + : []; + const parseFn = dir ? read(() => dir['parseErrorsValidator'], null) : null; + return raw.flatMap((fn) => { + if (fn && fn === parseFn) return []; + if (fn && fn === dirFn) return dirItems.map((item) => `${directiveName(item)} (template)`); + return [fnName(fn)]; + }); +} + +function keysOf(errors: unknown): string[] { + return errors && typeof errors === 'object' ? Object.keys(errors) : []; +} + +export function controlFacts( + control: AnyRecord, + dir?: AnyRecord | null, + isLeaf = true, +): ControlFacts { + const facts: ControlFacts = { origins: {} }; + const errors = keysOf(read(() => control['errors'], null)); + const parseFn = dir ? read(() => dir['parseErrorsValidator'], null) : null; + const parseKeys = new Set( + typeof parseFn === 'function' ? keysOf(read(() => parseFn(control), null)) : [], + ); + const validator = read(() => control['validator'] as ((c: unknown) => unknown) | null, null); + const hasAsync = !!read(() => control['asyncValidator'], null); + const status = read(() => String(control['status']), ''); + const canProbe = isLeaf && typeof validator === 'function' && status !== 'DISABLED'; + const run = (fn: unknown) => + typeof fn === 'function' + ? keysOf(withoutEvents(() => read(() => (fn as (c: unknown) => unknown)(control), null))) + : []; + const fresh = canProbe ? new Set(run(validator)) : null; + const dirFn = dir ? read(() => dir['validator'], null) : null; + const ownFns = asList(read(() => control['_rawValidators'], null)).filter( + (fn) => fn !== dirFn && fn !== parseFn, + ); + const ownKeys = new Set(canProbe ? ownFns.flatMap(run) : []); + const dirKeys = new Set(canProbe ? run(dirFn) : []); + for (const key of errors) { + if (parseKeys.has(key)) facts.origins[key] = { source: 'parse' }; + else if (ownKeys.has(key)) facts.origins[key] = { source: 'own' }; + else if (dirKeys.has(key)) facts.origins[key] = { source: 'directive' }; + else if (fresh ? fresh.has(key) : !!validator) facts.origins[key] = { source: 'own' }; + else if (hasAsync) facts.origins[key] = { source: 'async' }; + else facts.origins[key] = { source: 'manual' }; + } + if (fresh && status !== 'PENDING') { + const stale = Array.from(fresh).filter((key) => !errors.includes(key)); + if (stale.length) facts.stale = stale; + } + const sync = validatorNames(control, dir, 'sync'); + const async = validatorNames(control, dir, 'async'); + if (sync.length) facts.validators = sync; + if (async.length) facts.asyncValidators = async; + if (read(() => control['_pendingChange'] === true, false)) { + facts.pending = { value: read(() => control['_pendingValue'], undefined) }; + } + if (dir && read(() => 'viewModel' in dir && 'model' in dir, false)) { + const model = read(() => dir['model'], undefined); + const viewModel = read(() => dir['viewModel'], undefined); + if (!Object.is(model, viewModel)) facts.model = { model, viewModel }; + } + return facts; +} + +export type BindingKind = 'native' | 'accessor' | 'custom-control' | 'signal-field' | 'none'; + +export interface BindingInfo { + kind: BindingKind; + accessor?: string; + element?: string; + count?: number; + disabledHook?: boolean; +} + +function nameOf(value: unknown): string { + return read(() => String((value as AnyRecord).constructor.name), '').replace(/^_+/, ''); +} + +function tagOf(element: unknown): string | undefined { + const tag = read(() => (element as Element).tagName?.toLowerCase(), undefined); + return tag || undefined; +} + +const BUILT_IN_ACCESSORS = new Set([ + 'DefaultValueAccessor', + 'CheckboxControlValueAccessor', + 'NumberValueAccessor', + 'RangeValueAccessor', + 'RadioControlValueAccessor', + 'SelectControlValueAccessor', + 'SelectMultipleControlValueAccessor', +]); + +export function directiveBinding(dir: AnyRecord, element?: Element): BindingInfo { + if (read(() => dir['isCustomControlBased'] === true, false)) { + return { kind: 'custom-control', element: tagOf(element) }; + } + const accessor = read(() => dir['valueAccessor'] as AnyRecord | null, null); + if (!accessor) return { kind: 'none', element: tagOf(element) }; + const name = nameOf(accessor); + return { + kind: BUILT_IN_ACCESSORS.has(name) ? 'native' : 'accessor', + accessor: name, + element: tagOf(element), + disabledHook: typeof accessor['setDisabledState'] === 'function', + }; +} + +export function fieldBinding(node: AnyRecord): BindingInfo { + const bindings = list(() => node['formFieldBindings']()); + if (!bindings.length) return { kind: 'none' }; + const first = bindings[0]; + const accessors = list(() => first['controlValueAccessors']); + const info: BindingInfo = accessors.length + ? { + kind: BUILT_IN_ACCESSORS.has(nameOf(accessors[0])) ? 'native' : 'accessor', + accessor: nameOf(accessors[0]), + } + : { kind: 'signal-field' }; + const tag = tagOf(first['element']); + if (tag) info.element = tag; + if (bindings.length > 1) info.count = bindings.length; + return info; +} diff --git a/packages/ng-devtools/src/forms.ts b/packages/ng-devtools/src/forms.ts index 3e3cd06..d0b87b2 100644 --- a/packages/ng-devtools/src/forms.ts +++ b/packages/ng-devtools/src/forms.ts @@ -1,3 +1,30 @@ +import { domFacts, submitDom, type DomFacts, type SubmitDom } from './forms-dom.ts'; +import { + REDACTED, + SecretSet, + redactMessage, + isSecretKey, + redactReason, + type RedactReason, +} from './forms-privacy.ts'; +import { + controlFacts, + directiveBinding, + fieldBinding, + isProbing, + signalErrorOrigins, + signalFacts, + submitSetup, + type BindingInfo, + type ErrorOrigin, + type ErrorSource, + type RuleCounts, + type SkipReason, + type SubmitSetup, +} from './forms-read.ts'; + +export { REDACTED } from './forms-privacy.ts'; + export type FormKind = 'signal' | 'reactive' | 'template'; export type FieldStatus = 'VALID' | 'INVALID' | 'PENDING' | 'DISABLED'; @@ -5,6 +32,8 @@ export interface FormFieldError { kind: string; message: string; params?: Record; + source?: ErrorSource; + from?: string; } export interface FormFieldNode { @@ -31,6 +60,23 @@ export interface FormFieldNode { errors: FormFieldError[]; children?: FormFieldNode[]; truncated?: number; + uid?: string; + skipped?: SkipReason; + asyncWaiting?: boolean; + inheritedDisabled?: number; + hiddenBy?: 'self' | 'parent'; + readonlyBy?: 'self' | 'parent'; + rules?: RuleCounts; + validatorNames?: string[]; + asyncValidatorNames?: string[]; + stale?: string[]; + uncommitted?: unknown; + modelDrift?: { model: unknown; viewModel: unknown }; + changed?: boolean; + binding?: BindingInfo; + dom?: DomFacts; + redacted?: RedactReason; + pendingSince?: number; } export interface CollectedForm { @@ -40,18 +86,40 @@ export interface CollectedForm { property?: string; label: string; submitted?: boolean; + submit?: SubmitSetup; + submitDom?: SubmitDom; root: FormFieldNode; } export interface FormEvent { formId: string; path: string; - type: 'value' | 'status' | 'touched' | 'dirty' | 'submit' | 'reset' | 'added' | 'removed'; + type: + | 'value' + | 'status' + | 'touched' + | 'dirty' + | 'submit' + | 'reset' + | 'added' + | 'removed' + | 'moved' + | 'validators'; detail?: string; timestamp: number; seq?: number; + origin?: EventOrigin; + caller?: string; + prev?: string; + count?: number; + outcome?: 'ran' | 'blocked' | 'threw' | 'busy'; + ms?: number; + renders?: number; + rendered?: string[]; } +export type EventOrigin = 'user' | 'code' | 'devtools' | 'binding'; + export interface FormsDebugApi { getComponent(el: Element): unknown; getDirectives(el: Element): unknown[]; @@ -65,6 +133,7 @@ export interface FoundForm { property?: string; directive?: AnyRecord; element?: Element; + formElement?: Element; } export interface FoundForms { @@ -72,20 +141,56 @@ export interface FoundForms { elements: WeakMap; } -export const REDACTED = '[redacted]'; - const MAX_DEPTH = 8; const MAX_CHILDREN = 100; const MAX_STRING = 200; const MAX_VALUE_ITEMS = 20; const MAX_VALUE_DEPTH = 3; const MAX_DETAIL = 120; -const SENSITIVE_KEY = /pass|pwd|secret|token|api.?key|card|cc.?num|cvv|cvc|ssn|iban|otp/i; -const SENSITIVE_AUTOCOMPLETE = /password|one-time-code|cc-/i; type AnyRecord = Record; const accessorNames = new WeakMap(); +const controlDirectives = new WeakMap(); +const uids = new WeakMap(); +const baselines = new WeakMap(); +let nextUid = 0; +let secrets: SecretSet | null = null; +let formSecrets = new Map(); + +function uidOf(target: object): string { + let uid = uids.get(target); + if (!uid) { + uid = `f${++nextUid}`; + uids.set(target, uid); + } + return uid; +} + +function changedOf(target: object, value: unknown, dirty: boolean): boolean | undefined { + const text = JSON.stringify(serializeFormValue(value)) ?? 'undefined'; + if (!dirty || !baselines.has(target)) { + baselines.set(target, text); + return undefined; + } + return baselines.get(target) !== text; +} + +function remember(value: unknown, seen = new WeakSet()) { + if (!secrets) return; + if (value && typeof value === 'object') { + if (seen.has(value)) return; + seen.add(value); + for (const item of Object.values(value).slice(0, 50)) remember(item, seen); + } else secrets.add(value); +} + +function withOrigin(error: FormFieldError, origin: ErrorOrigin | undefined): FormFieldError { + if (!origin) return error; + return origin.from !== undefined + ? { ...error, source: origin.source, from: origin.from } + : { ...error, source: origin.source }; +} function read(fn: () => T, fallback: T): T { try { @@ -156,12 +261,7 @@ export function detailOf(value: unknown): string { } export function isSensitive(key: string, element?: Element | null): boolean { - if (SENSITIVE_KEY.test(key)) return true; - if (!element) return false; - return ( - element.getAttribute('type') === 'password' || - SENSITIVE_AUTOCOMPLETE.test(element.getAttribute('autocomplete') ?? '') - ); + return !!redactReason(key, element); } function isoOf(date: Date): string { @@ -193,7 +293,7 @@ export function serializeFormValue(value: unknown, depth = 0): unknown { const out: Record = {}; const keys = Object.keys(value as object).filter((key) => !key.startsWith('__ng')); for (const key of keys.slice(0, MAX_VALUE_ITEMS)) { - out[key] = SENSITIVE_KEY.test(key) + out[key] = isSecretKey(key) ? REDACTED : serializeFormValue( read(() => (value as AnyRecord)[key], undefined), @@ -330,28 +430,65 @@ export function serializeControl( const type = controlType(control); const updateOn = read(() => control['updateOn'], 'change'); const element = elements.get(control); - const secret = parentSecret || isSensitive(key, element); + const reason: RedactReason | null = parentSecret ? 'parent' : redactReason(key, element); + const secret = !!reason; + const dir = controlDirectives.get(control); + const facts = read(() => controlFacts(control, dir, type === 'control'), { origins: {} }); + const status = read(() => control['status'], 'VALID') as FieldStatus; + const dirty = !!read(() => control['dirty'], false); const node: FormFieldNode = { key, path, type, - status: read(() => control['status'], 'VALID'), + status, touched: !!read(() => control['touched'], false), - dirty: !!read(() => control['dirty'], false), + dirty, bound: !!element, - errors: controlErrors(control, type, secret), + errors: controlErrors(control, type, secret).map((e) => withOrigin(e, facts.origins[e.kind])), + uid: uidOf(control), }; + if (reason && !parentSecret) node.redacted = reason; if (updateOn === 'blur' || updateOn === 'submit') node.updateOn = updateOn; const sync = !!read(() => control['validator'], null); const async = !!read(() => control['asyncValidator'], null); if (sync || async) node.validators = { sync, async }; + if (facts.validators) node.validatorNames = facts.validators; + if (facts.asyncValidators) node.asyncValidatorNames = facts.asyncValidators; + if (facts.stale) node.stale = facts.stale; + if (dir) node.binding = directiveBinding(dir, element); if (type === 'control') { - node.value = secret ? REDACTED : serializeFormValue(read(() => control['value'], undefined)); + const raw = read(() => control['value'], undefined); + if (secret) { + remember(raw); + if (facts.pending) remember(facts.pending.value); + } + node.value = secret ? REDACTED : serializeFormValue(raw); if ('defaultValue' in control) { node.defaultValue = secret ? REDACTED : serializeFormValue(control['defaultValue']); } + if (facts.pending) { + node.uncommitted = secret ? REDACTED : serializeFormValue(facts.pending.value); + } + if (facts.model) { + node.modelDrift = secret + ? { model: REDACTED, viewModel: REDACTED } + : { + model: serializeFormValue(facts.model.model), + viewModel: serializeFormValue(facts.model.viewModel), + }; + } + const changed = changedOf(control, raw, dirty); + if (changed !== undefined) node.changed = changed; const accessor = accessorNames.get(control); if (accessor) node.accessor = accessor; + if (element) { + node.dom = domFacts(element, { + value: facts.pending ? facts.pending.value : raw, + disabled: status === 'DISABLED', + secret, + hasErrors: node.errors.length > 0, + }); + } return node; } const controls = read(() => control['controls'] as AnyRecord, {}); @@ -391,9 +528,13 @@ function fieldErrors( secret: boolean, ): FormFieldError[] { const errors = read(() => state['errors']() as AnyRecord[], []); + const origins = errors.length ? read(() => signalErrorOrigins(state), new Map()) : new Map(); return errors.map((error) => { const message = typeof error['message'] === 'string' ? error['message'] : undefined; - return toError(String(error['kind']), withoutValues(errorParams(error), secret), type, message); + return withOrigin( + toError(String(error['kind']), withoutValues(errorParams(error), secret), type, message), + origins.get(error), + ); }); } @@ -418,7 +559,7 @@ function unmaterializedField( dirty: false, bound: false, materialized: false, - value: parentSecret || SENSITIVE_KEY.test(key) ? REDACTED : serializeFormValue(value), + value: parentSecret || isSecretKey(key) ? REDACTED : serializeFormValue(value), errors: [], }; } @@ -460,20 +601,26 @@ export function serializeField( const value = read(() => state['value'](), undefined); const type = valueType(value); const element = fieldElement(state, elements); - const secret = parentSecret || isSensitive(key, element); + const reason: RedactReason | null = parentSecret ? 'parent' : redactReason(key, element); + const secret = !!reason; + const dirty = !!read(() => state['dirty'](), false); const node: FormFieldNode = { key, path, type, status: fieldStatus(state), touched: !!read(() => state['touched'](), false), - dirty: !!read(() => state['dirty'](), false), + dirty, required: !!read(() => state['required'](), false), readonly: !!read(() => state['readonly'](), false), hidden: !!read(() => state['hidden'](), false), bound: !!element, errors: fieldErrors(state, type, secret), + uid: uidOf(state), + ...read(() => signalFacts(state), {}), }; + if (reason && !parentSecret) node.redacted = reason; + if (element) node.binding = read(() => fieldBinding(state), { kind: 'none' as const }); const reasons = read(() => state['disabledReasons']() as AnyRecord[], []); if (reasons.length) { node.disabledReasons = reasons.map((r) => @@ -484,14 +631,26 @@ export function serializeField( if (constraints) node.constraints = constraints; if (!path && read(() => state['submitting'](), false)) node.submitting = true; if (type === 'control') { + const buffered = read(() => state['controlValue'](), value); + if (secret) { + remember(value); + remember(buffered); + } node.value = secret ? REDACTED : serializeFormValue(value); - if ( - !Object.is( - read(() => state['controlValue'](), value), - value, - ) - ) + if (!Object.is(buffered, value)) { node.debouncing = true; + node.uncommitted = secret ? REDACTED : serializeFormValue(buffered); + } + const changed = changedOf(state, value, dirty); + if (changed !== undefined) node.changed = changed; + if (element) { + node.dom = domFacts(element, { + value: buffered, + disabled: node.status === 'DISABLED', + secret, + hasErrors: node.errors.length > 0, + }); + } return node; } const keys = Object.keys(value as object); @@ -580,6 +739,7 @@ export function findForms(ng: FormsDebugApi, elements: Iterable): Found existing.owner ??= found.owner; existing.directive ??= found.directive; existing.element ??= found.element; + existing.formElement ??= found.formElement; }; for (const el of elements) { @@ -600,7 +760,7 @@ export function findForms(ng: FormsDebugApi, elements: Iterable): Found const state = isFieldTree(tree) ? tree() : read(() => dir['state']() as AnyRecord, null); const root = read(() => state?.['structure'].root as AnyRecord, null); const element = selectors.has('formRoot') ? el : undefined; - if (root) add({ kind: 'signal', root, owner: ownerOf(), element }); + if (root) add({ kind: 'signal', root, owner: ownerOf(), element, formElement: element }); return; } const ownControl = read(() => dir['control'] as unknown, undefined); @@ -609,6 +769,7 @@ export function findForms(ng: FormsDebugApi, elements: Iterable): Found const binds = CONTROL_SELECTORS.some((token) => selectors.has(token)); if (binds && ownControl === control && !controlElements.has(control)) { controlElements.set(control, el); + controlDirectives.set(control, dir); const accessor = read( () => String(dir['valueAccessor']?.constructor?.name ?? '').replace(/^_+/, ''), '', @@ -621,12 +782,14 @@ export function findForms(ng: FormsDebugApi, elements: Iterable): Found if (template && isGroup && empty) return; const found = rootOf(control); if (!found) return; + const isRootDirective = read(() => dir['form'], undefined) === found.root; add({ kind: found.kind === 'signal' ? 'signal' : template ? 'template' : 'reactive', root: found.root, owner: ownerOf(), - directive: read(() => dir['form'], undefined) === found.root ? dir : undefined, + directive: isRootDirective ? dir : undefined, element: el, + formElement: isRootDirective ? el : undefined, }); }); } @@ -660,15 +823,29 @@ export function collectForms( idOf: (root: object) => string = formIdFor, ): CollectedForm[] { const seen = new Map(); - return forms.map((found) => { + const kept = new Map(); + const collected = forms.map((found) => { const property = found.property ?? propertyHolding(found); const owner = ownerName(found.owner); let label = `${owner}.${property ?? fallbackName(found)}`; const count = (seen.get(label) ?? 0) + 1; seen.set(label, count); if (count > 1) label = `${label} #${count}`; - return { - id: idOf(found.root), + const id = idOf(found.root); + secrets = new SecretSet(); + kept.set(id, secrets); + let root: FormFieldNode; + try { + root = + found.kind === 'signal' + ? serializeField(found.root, elements, property ?? '') + : serializeControl(found.root, elements, property ?? ''); + if (secrets.size) redactTree(root, secrets); + } finally { + secrets = null; + } + const form: CollectedForm = { + id, kind: found.kind, owner, property, @@ -677,12 +854,53 @@ export function collectForms( found.kind === 'signal' ? undefined : read(() => found.directive?.['submitted'] as boolean | undefined, undefined), - root: - found.kind === 'signal' - ? serializeField(found.root, elements, property ?? '') - : serializeControl(found.root, elements, property ?? ''), + root, }; + if (found.kind === 'signal') form.submit = read(() => submitSetup(found.root), undefined); + if (found.formElement) form.submitDom = read(() => submitDom(found.formElement!), undefined); + return form; }); + formSecrets = kept; + return collected; +} + +export function forgetFormSecrets(formIds: Iterable) { + for (const id of formIds) formSecrets.delete(id); +} + +export function redactFormText(formId: string, text: string): string { + return formSecrets.get(formId)?.redact(text) ?? redactMessage(text); +} + +const STRUCTURAL_KEYS = new Set([ + 'key', + 'path', + 'uid', + 'type', + 'status', + 'updateOn', + 'skipped', + 'hiddenBy', + 'readonlyBy', + 'redacted', + 'children', +]); + +function redactTree(node: FormFieldNode, set: SecretSet) { + const fields = node as unknown as Record; + for (const [key, value] of Object.entries(fields)) { + if (!STRUCTURAL_KEYS.has(key)) fields[key] = redactStrings(value, set, 0); + } + for (const child of node.children ?? []) redactTree(child, set); +} + +function redactStrings(value: unknown, set: SecretSet, depth: number): unknown { + if (typeof value === 'string') return set.redact(value); + if (!value || typeof value !== 'object' || depth > 20) return value; + if (Array.isArray(value)) return value.map((item) => redactStrings(item, set, depth + 1)); + return Object.fromEntries( + Object.entries(value).map(([key, item]) => [key, redactStrings(item, set, depth + 1)]), + ); } function flatten(node: FormFieldNode, out = new Map()) { @@ -691,6 +909,16 @@ function flatten(node: FormFieldNode, out = new Map()) { return out; } +function byUid(node: FormFieldNode, out = new Map()) { + if (node.uid) out.set(node.uid, node); + for (const child of node.children ?? []) byUid(child, out); + return out; +} + +function parentPath(path: string): string { + return path.includes('.') ? path.slice(0, path.lastIndexOf('.')) : ''; +} + export function diffForms( previous: CollectedForm[], next: CollectedForm[], @@ -705,24 +933,58 @@ export function diffForms( events.push({ formId: form.id, path, type, detail, timestamp: now }); const old = flatten(prevForm.root); const current = flatten(form.root); + const oldUids = byUid(prevForm.root); + const currentUids = byUid(form.root); + const find = ( + node: FormFieldNode, + uids: Map, + paths: Map, + ) => (node.uid && uids.size ? uids.get(node.uid) : paths.get(node.path)); + const reportable = ( + node: FormFieldNode, + paths: Map, + otherUids: Map, + otherPaths: Map, + ) => { + if (!node.path) return false; + const parent = paths.get(parentPath(node.path)); + return !!parent && parent.type !== 'array' && !!find(parent, otherUids, otherPaths); + }; const resized: string[] = []; for (const [path, node] of current) { const prev = old.get(path); if (node.type !== 'array' || prev?.type !== 'array') continue; - const was = prev.children?.length ?? 0; - const is = node.children?.length ?? 0; - if (was !== is) { + const kids = node.children ?? []; + const was = prev.children ?? []; + if (currentUids.size && oldUids.size && [...kids, ...was].every((c) => !!c.uid)) { + kids.forEach((child, index) => { + const earlier = oldUids.get(child.uid!); + if (!earlier) push(child.path, 'added', `inserted at ${index}`); + else if (earlier.path !== child.path) { + push(child.path, 'moved', `${earlier.path} → ${child.path}`); + } + }); + for (const child of was) { + if (!currentUids.has(child.uid!)) push(child.path, 'removed', `was at ${child.key}`); + } + continue; + } + if (was.length !== kids.length) { resized.push(path); - push(path, is > was ? 'added' : 'removed', `${was} → ${is} items`); + push( + path, + kids.length > was.length ? 'added' : 'removed', + `${was.length} → ${kids.length} items`, + ); } } const inResized = (path: string) => resized.some((array) => (array ? path.startsWith(`${array}.`) : path !== '')); for (const [path, node] of current) { if (inResized(path)) continue; - const prev = old.get(path); + const prev = find(node, oldUids, old); if (!prev) { - push(path, 'added'); + if (reportable(node, current, oldUids, old)) push(path, 'added'); continue; } if (node.type === 'control' && JSON.stringify(prev.value) !== JSON.stringify(node.value)) @@ -731,8 +993,9 @@ export function diffForms( if (prev.touched !== node.touched) push(path, 'touched', String(node.touched)); if (prev.dirty !== node.dirty) push(path, 'dirty', String(node.dirty)); } - for (const path of old.keys()) { - if (!current.has(path) && !inResized(path)) push(path, 'removed'); + for (const [path, node] of old) { + if (inResized(path) || find(node, currentUids, current)) continue; + if (reportable(node, old, currentUids, current)) push(path, 'removed'); } } return events; @@ -748,15 +1011,18 @@ function valueOf(node: FormFieldNode): unknown { return node.type === 'array' ? entries.map(([, v]) => v) : Object.fromEntries(entries); } -function pathTo(root: AnyRecord, target: AnyRecord): string { +export function controlPathOf(root: AnyRecord, target: AnyRecord): string { const keys: string[] = []; let current: AnyRecord | null = target; while (current && current !== root) { const parent: AnyRecord | null = read(() => current!['parent'], null); if (!parent) return ''; const controls = read(() => parent['controls'], {}); + const index = Array.isArray(controls) ? controls.indexOf(current) : -1; const key = Array.isArray(controls) - ? String(controls.indexOf(current)) + ? index >= 0 + ? String(index) + : undefined : Object.keys(controls).find((k) => controls[k] === current); if (key === undefined) return ''; keys.unshift(key); @@ -779,13 +1045,13 @@ export function controlEventOf( { elements = new WeakMap(), rootKey = '', submitted, now = Date.now() }: ControlEventOptions = {}, ): FormEvent | null { const source = read(() => event['source'] as AnyRecord, null); - const path = source ? pathTo(root, source) : ''; + const path = source ? controlPathOf(root, source) : ''; const base = { formId, path, timestamp: now }; const of = (key: string) => read(() => (source ?? event)[key], event[key]); if ('value' in event) { const keys = [rootKey, ...(path ? path.split('.') : [])]; const key = keys[keys.length - 1]; - const secret = keys.slice(0, -1).some((k) => SENSITIVE_KEY.test(k)); + const secret = keys.slice(0, -1).some((k) => isSecretKey(k)); const value = isAbstractControl(source) ? valueOf(serializeControl(source, elements, key, path, 0, secret)) : serializeFormValue(of('value')); @@ -816,6 +1082,7 @@ export function watchControlEvents( const subscription = read( () => events['subscribe']((event: AnyRecord) => { + if (isProbing()) return; const emit = () => { const mapped = read( () => @@ -848,6 +1115,29 @@ function childAt(node: AnyRecord, kind: FormKind, key: string): AnyRecord | null return (Array.isArray(controls) ? controls[Number(key)] : controls[key]) ?? null; } +export function nodeAt( + found: Pick, + path: string, + create = false, +): AnyRecord | null { + const keys = path ? path.split('.') : []; + if (found.kind === 'signal' && create) { + let tree: unknown = read(() => found.root['fieldTree'], null); + for (const key of keys) { + tree = read(() => (tree as AnyRecord)[key], null); + if (typeof tree !== 'function') return null; + } + return read(() => (tree as () => AnyRecord)(), null); + } + let node: AnyRecord | null = found.root; + for (const key of keys) node = node && childAt(node, found.kind, key); + return node; +} + +export function directivesOf(control: object): AnyRecord | undefined { + return controlDirectives.get(control); +} + export function findFieldElement( ng: FormsDebugApi, elements: Iterable, diff --git a/packages/ng-devtools/src/overlay.ts b/packages/ng-devtools/src/overlay.ts index a2ed3f5..c3ac7f4 100644 --- a/packages/ng-devtools/src/overlay.ts +++ b/packages/ng-devtools/src/overlay.ts @@ -1,18 +1,5 @@ import { connectDevframe } from 'devframe/client'; -import { - collectForms, - diffForms, - findFieldElement, - findForms, - formIdFor, - propertyHolding, - serializeControl, - watchControlEvents, - type CollectedForm, - type FormEvent, - type FormFieldNode, - type FoundForm, -} from './forms.ts'; +import { attachForms } from './forms-collector.ts'; import { findRouters, setGeneration, @@ -38,18 +25,8 @@ import { createSignalHistory, type RawSignalNode } from './signal-history.ts'; let highlightEl: HTMLElement | null = null; let highlightTimer: ReturnType | undefined; let highlightFrame = 0; -const MAX_FORM_EVENTS = 200; -const FORMS_HEARTBEAT_MS = 5000; -const DIFFED_FOR_ALL: FormEvent['type'][] = [ - 'value', - 'status', - 'touched', - 'dirty', - 'added', - 'removed', -]; - const PAGE_ID_KEY = 'ng-devtools-page-id'; +const ROUTER_HEARTBEAT_MS = 5000; function storedPageId(): string | null { try { @@ -94,16 +71,6 @@ async function claimPageId(): Promise<{ id: string; release: () => void }> { return { id, release: () => channel.close() }; } -function isFieldTarget(target: unknown): target is { formId: string; path: string } { - const t = target as { formId?: unknown; path?: unknown } | null; - return ( - typeof t?.formId === 'string' && - typeof t.path === 'string' && - t.formId.length < 50 && - t.path.length < 500 - ); -} - export async function initOverlay(options: { baseURL?: string | string[] } = {}) { // `connectDevframe()` alone looks for the connection next to the page, which // misses the documented `/__ng-devtools/` mount in a host app. @@ -142,113 +109,8 @@ export async function initOverlay(options: { baseURL?: string | string[] } = {}) } const { id: pageId, release: releasePageId } = await claimPageId(); - const idOf = (root: object) => `${formIdFor(root)}@${pageId}`; - let lastForms: CollectedForm[] = []; - let lastPayload = ''; - let lastPushAt = 0; - const formEvents: FormEvent[] = []; - const watched = new Map void }>(); - const lastStatus = new Map(); - const lastValue = new Map(); - let foundById = new Map(); - let fieldElements = new WeakMap(); - - let eventSeq = 0; - - function recordFormEvent(input: FormEvent) { - const event = { ...input, seq: ++eventSeq }; - if (event.type === 'value') { - const key = `${event.formId}:${event.path}`; - if (lastValue.get(key) === event.detail) return; - lastValue.set(key, event.detail ?? ''); - } - if (event.type === 'status') { - const key = `${event.formId}:${event.path}`; - const status = event.detail?.split('→').pop()?.trim() ?? ''; - if (lastStatus.get(key) === status) return; - lastStatus.set(key, status); - } - const last = formEvents[formEvents.length - 1]; - if ( - event.type === 'value' && - last?.type === 'value' && - last.formId === event.formId && - last.path === event.path - ) { - formEvents[formEvents.length - 1] = event; - return; - } - formEvents.push(event); - if (formEvents.length > MAX_FORM_EVENTS) { - formEvents.splice(0, formEvents.length - MAX_FORM_EVENTS); - } - } - - function seedStatuses(formId: string, node: FormFieldNode) { - lastStatus.set(`${formId}:${node.path}`, node.status); - for (const child of node.children ?? []) seedStatuses(formId, child); - } - - function watchRoots(found: FoundForm[]) { - const live = new Set(); - for (const form of found) { - if (form.kind === 'signal') continue; - live.add(form.root); - if (watched.has(form.root)) continue; - const formId = idOf(form.root); - const stop = watchControlEvents( - form.root, - formId, - (event) => { - if (event.type !== 'touched' && event.type !== 'dirty') recordFormEvent(event); - }, - { - elements: () => fieldElements, - rootKey: form.property ?? propertyHolding(form) ?? '', - submitted: () => form.directive?.['submitted'], - }, - ); - if (!stop) continue; - watched.set(form.root, { formId, stop }); - seedStatuses(formId, serializeControl(form.root, fieldElements)); - } - for (const [root, { formId, stop }] of watched) { - if (live.has(root)) continue; - stop(); - watched.delete(root); - for (const map of [lastStatus, lastValue]) { - for (const key of map.keys()) { - if (key.startsWith(`${formId}:`)) map.delete(key); - } - } - } - } - - async function pushForms() { - try { - const ng = getNg(); - if (!ng?.getDirectives) return; - const found = findForms(ng, document.querySelectorAll('*')); - foundById = new Map(found.forms.map((form) => [idOf(form.root), form])); - fieldElements = found.elements; - watchRoots(found.forms); - const forms = collectForms(found, idOf); - const streamed = new Set(Array.from(watched.values(), ({ formId }) => formId)); - for (const event of diffForms(lastForms, forms)) { - if (!streamed.has(event.formId) || DIFFED_FOR_ALL.includes(event.type)) { - recordFormEvent(event); - } - } - lastForms = forms; - const payload = JSON.stringify({ forms, events: formEvents }); - if (payload === lastPayload && Date.now() - lastPushAt < FORMS_HEARTBEAT_MS) return; - lastPayload = payload; - lastPushAt = Date.now(); - await my.rpc.call('push-forms', { pageId, forms, events: formEvents }); - } catch { - return; - } - } + const forms = attachForms(my, pageId, getNg, { show: showHighlight, clear: clearHighlight }); + const pushForms = forms.push; const navigations: NavigationRecord[] = []; const preloads: PreloadRecord[] = []; @@ -320,7 +182,7 @@ export async function initOverlay(options: { baseURL?: string | string[] } = {}) report['instrumented'] = instrumented; } const payload = JSON.stringify(report); - if (payload === lastRouterPayload && Date.now() - lastRouterPushAt < FORMS_HEARTBEAT_MS) { + if (payload === lastRouterPayload && Date.now() - lastRouterPushAt < ROUTER_HEARTBEAT_MS) { return; } lastRouterPayload = payload; @@ -401,31 +263,6 @@ export async function initOverlay(options: { baseURL?: string | string[] } = {}) }, }); - my.rpc.register({ - name: 'highlight-form-field', - type: 'event', - jsonSerializable: true, - handler: (target: { formId: string; path: string } | null) => { - clearHighlight(); - const ng = getNg(); - if (!isFieldTarget(target) || !ng?.getDirectives) return; - const found = foundById.get(target.formId); - if (!found) return; - try { - const el = findFieldElement( - ng, - document.querySelectorAll('*'), - found, - target.path, - fieldElements, - ); - if (el instanceof HTMLElement) showHighlight(el); - } catch { - return; - } - }, - }); - const leave = () => { void my.rpc.call('forget-forms-page', pageId).catch(() => {}); void my.rpc.call('forget-router-page', pageId).catch(() => {}); @@ -438,14 +275,13 @@ export async function initOverlay(options: { baseURL?: string | string[] } = {}) clearInterval(interval); restoreSignalHook(); removeEventListener('pagehide', leave); + forms.stop(); removeEventListener('pageshow', resendConfig); - for (const { stop } of watched.values()) stop(); for (const cleanup of routerCleanup) cleanup(); routerCleanup = []; stopInstrument?.(); clearTimeout(routerPushTimer); releasePageId(); - watched.clear(); clearHighlight(); }; } diff --git a/packages/ng-devtools/src/rpc/forms-explain.ts b/packages/ng-devtools/src/rpc/forms-explain.ts new file mode 100644 index 0000000..d16ed9f --- /dev/null +++ b/packages/ng-devtools/src/rpc/forms-explain.ts @@ -0,0 +1,576 @@ +import { + REDACTED, + detailOf, + type CollectedForm, + type FormEvent, + type FormFieldNode, +} from '../forms.ts'; +import { lintForm, lintSetupErrors, type FormLintFinding } from './forms-lint.ts'; +import { + UNTRUSTED, + code, + freshness, + matchForms, + noMatch, + onPage, + sourceLabel, + subtreeAt, + type FormsState, +} from './forms-tools.ts'; + +export interface FieldArgs { + form?: string; + path?: string; + page?: string; +} + +const MAX_HISTORY = 200; + +function walk(node: FormFieldNode, visit: (node: FormFieldNode) => void) { + visit(node); + for (const child of node.children ?? []) walk(child, visit); +} + +function pickForm(state: FormsState, args: FieldArgs): CollectedForm | string { + const forms = matchForms(state.forms, args.form, args.page); + if (!forms.length) { + return state.forms.length + ? noMatch(onPage(state.forms, args.page), args.form ?? '') + : 'No forms have been reported.'; + } + if (forms.length === 1) return forms[0]; + return exactForm(forms, args.form) ?? ambiguous(forms); +} + +function exactForm(forms: CollectedForm[], query: string | undefined): CollectedForm | null { + if (!query) return null; + const full = forms.find((f) => f.id === query); + if (full) return full; + const short = forms.filter((f) => f.id.split('@')[0] === query); + return short.length === 1 ? short[0] : null; +} + +function ambiguous(forms: CollectedForm[]): string { + return `${forms.length} forms match; pass the full \`form\` id: ${forms.map((f) => `${f.id} ${code(f.label)}`).join(', ')}.`; +} + +export function resolveForm( + forms: CollectedForm[], + query: string | undefined, +): CollectedForm | string { + const match = exactForm(forms, query); + if (match) return match; + const short = forms.filter((f) => f.id.split('@')[0] === query); + return short.length > 1 + ? ambiguous(short) + : `No form ${query ?? ''}. Forms: ${forms.map((f) => f.id).join(', ')}.`; +} + +export function latestMarker(state: FormsState): number { + return state.events.reduce((max, event) => Math.max(max, event.seq ?? 0), 0); +} + +function flags(node: FormFieldNode): string { + const out = [ + node.status, + node.touched ? 'touched' : 'untouched', + node.dirty + ? node.changed === false + ? 'dirty (value back to its original)' + : 'dirty' + : 'pristine', + ]; + if (node.required) out.push('required'); + if (node.hidden) out.push(`hidden${node.hiddenBy === 'parent' ? ' (by a parent)' : ''}`); + if (node.readonly) out.push(`readonly${node.readonlyBy === 'parent' ? ' (by a parent)' : ''}`); + if (node.updateOn) out.push(`updateOn ${node.updateOn}`); + return out.join(', '); +} + +export function fieldOwner( + state: FormsState, + args: FieldArgs, +): { owner: string; property?: string; path: string } | null { + const form = pickForm(state, args); + return typeof form === 'string' + ? null + : { owner: form.owner, property: form.property, path: args.path ?? '' }; +} + +export function explainFieldText( + state: FormsState, + args: FieldArgs, + now = Date.now(), + source = '', +): string { + const form = pickForm(state, args); + if (typeof form === 'string') return form; + const node = subtreeAt(form.root, args.path ?? ''); + if (!node) { + const top = (form.root.children ?? []).map((c) => c.key).join(', '); + return `No field at ${code(args.path ?? '')} in ${form.id}; top-level fields: ${top}.`; + } + const where = code(node.path || '(form)'); + const lines = [`${where} in ${code(form.label)} (${form.kind}, ${form.id}): ${flags(node)}.`]; + if (node.type === 'control') { + lines.push( + `Value: ${detailOf(node.value)}${node.redacted ? ` (redacted: ${node.redacted})` : ''}.`, + ); + } + if (node.uncommitted !== undefined) { + lines.push( + node.debouncing + ? `Typed but debounced: the control shows ${detailOf(node.uncommitted)}; the model updates after the debounce.` + : `Uncommitted: the input holds ${detailOf(node.uncommitted)}, which reaches the model on ${node.updateOn ?? 'the next update'}.`, + ); + } + if (node.modelDrift) { + lines.push( + `ngModel drift: [ngModel] is ${detailOf(node.modelDrift.model)}, the view model ${detailOf(node.modelDrift.viewModel)}.`, + ); + } + if (node.errors.length) { + lines.push('Errors:'); + for (const error of node.errors) { + lines.push(`- [${error.kind}] ${error.message} (${sourceLabel(error)})`); + } + } else if (node.status === 'INVALID') { + lines.push('No error of its own; a descendant is invalid.'); + } + if (node.skipped) { + lines.push( + `Validation is skipped because the field is ${node.skipped}. Hidden, disabled and readonly fields never report errors and never become touched or dirty.`, + ); + } + if (node.asyncWaiting) lines.push('Async rules wait until the sync rules pass.'); + if (node.status === 'PENDING' && node.pendingSince) { + lines.push(`Pending for ${Math.round((now - node.pendingSince) / 1000)}s.`); + } + if (node.stale?.length) { + lines.push( + `Stale: validators now report ${node.stale.join(', ')}, but errors were computed before the validators changed. Call updateValueAndValidity().`, + ); + } + if (node.disabledReasons?.length) { + const inherited = node.inheritedDisabled ?? 0; + lines.push( + `Disabled: ${node.disabledReasons + .map((reason, i) => (i < inherited ? `${reason} (from a parent)` : reason)) + .join('; ')}.`, + ); + } + if (node.rules) { + lines.push( + `Rules: ${Object.entries(node.rules) + .map(([kind, count]) => `${count} ${kind}`) + .join(', ')}.`, + ); + } + if (node.validatorNames?.length) lines.push(`Validators: ${node.validatorNames.join(', ')}.`); + if (node.asyncValidatorNames?.length) + lines.push(`Async validators: ${node.asyncValidatorNames.join(', ')}.`); + if (node.constraints) { + lines.push( + `Constraints: ${Object.entries(node.constraints) + .map(([k, v]) => `${k} ${v}`) + .join(', ')}.`, + ); + } + lines.push(bindingText(node)); + const dom = domText(node); + if (dom) lines.push(dom); + const recent = state.events + .filter((e) => e.formId === form.id && e.path === node.path) + .slice(-5) + .map(eventLine); + if (source) lines.push(source); + if (recent.length) lines.push('Recent changes:', ...recent); + return `${UNTRUSTED}\n\n${lines.join('\n')}${freshness(state, now)}`; +} + +function bindingText(node: FormFieldNode): string { + const b = node.binding; + if (!node.bound || !b) return 'Not bound to any element on the page.'; + const el = b.element ? `<${b.element}>` : 'an element'; + switch (b.kind) { + case 'native': + return `Bound to ${el} through Angular's ${b.accessor}.`; + case 'accessor': + return `Bound to ${el} through the custom ControlValueAccessor ${b.accessor}.`; + case 'custom-control': + return `Bound to ${el}, a custom control (FormValueControl) used through a reactive directive.`; + case 'signal-field': + return `Bound with [formField] to ${el}${b.count ? ` (${b.count} bindings)` : ''}.`; + default: + return `Bound to ${el}.`; + } +} + +function domText(node: FormFieldNode): string { + const dom = node.dom; + if (!dom) return ''; + const parts: string[] = []; + if (dom.drift !== undefined) + parts.push( + `the element shows ${dom.drift === true ? 'a different value' : detailOf(dom.drift)}, not the model value`, + ); + if (dom.labelled === false) parts.push('no accessible label'); + if (dom.errorShown === false) parts.push('no visible error text'); + if (dom.ariaInvalid !== undefined) parts.push(`aria-invalid=${dom.ariaInvalid}`); + if (dom.disabled !== undefined) + parts.push(`element ${dom.disabled ? 'is' : 'is not'} disabled, unlike the model`); + return parts.length ? `DOM: ${parts.join('; ')}.` : ''; +} + +function eventLine(event: FormEvent): string { + const time = new Date(event.timestamp).toISOString().slice(11, 23); + const change = + event.prev !== undefined ? `${event.prev} → ${event.detail ?? ''}` : (event.detail ?? ''); + const extra = [ + event.origin, + event.count && event.count > 1 ? `×${event.count}` : '', + event.outcome ?? '', + event.ms !== undefined ? `pending ${event.ms}ms` : '', + event.renders ? `${event.renders} template updates: ${(event.rendered ?? []).join(', ')}` : '', + ] + .filter(Boolean) + .join(', '); + const caller = event.caller ? ` from ${event.caller}` : ''; + return `- #${event.seq ?? '?'} ${time} ${code(event.path || '(form)')} ${event.type} ${change}${extra ? ` (${extra})` : ''}${caller}`; +} + +function blockingLeaves(root: FormFieldNode) { + const invalid: FormFieldNode[] = []; + const pending: FormFieldNode[] = []; + walk(root, (node) => { + if (node.errors.length) invalid.push(node); + if (node.status === 'PENDING' && !(node.children ?? []).some((c) => c.status === 'PENDING')) { + pending.push(node); + } + }); + return { invalid, pending }; +} + +export function explainSubmitText(state: FormsState, args: FieldArgs, now = Date.now()): string { + const form = pickForm(state, args); + if (typeof form === 'string') return form; + const { invalid, pending } = blockingLeaves(form.root); + const lines: string[] = []; + if (form.kind === 'signal') { + const s = form.submit; + if (!s) lines.push('Submit setup unknown (older page script).'); + else { + lines.push( + s.hasAction + ? `submit() ${s.willRun ? 'will run the action' : 'will not run the action'}${s.ignoreValidators ? ` (ignoreValidators: ${s.ignoreValidators})` : ''}.` + : 'The form has no submission action: submit(form) without an action throws NG01915.', + ); + if (s.submitting) + lines.push('A submit is in progress; a second submit() returns false right away.'); + if (!s.willRun && s.hasAction) { + lines.push( + s.hasOnInvalid + ? 'onInvalid runs instead, and every interactive field is marked touched.' + : 'Nothing visible happens except fields becoming touched (no onInvalid).', + ); + } + } + } else { + lines.push( + `ngSubmit fires on every submit, valid or not; the handler must check form.valid. Status now: ${form.root.status}${form.submitted ? ', already submitted' : ''}.`, + ); + } + for (const reason of form.submitDom?.reasons ?? []) lines.push(`DOM: ${reason}`); + if (!form.submitDom) + lines.push('No element was found for this form, so only code can submit it.'); + if (invalid.length) { + lines.push('Blocking fields:'); + for (const node of invalid.slice(0, 20)) { + lines.push( + `- ${code(node.path || '(form)')}: ${node.errors.map((e) => `${e.kind} (${sourceLabel(e)})`).join(', ')}${node.touched ? '' : ', not touched yet'}`, + ); + } + } + if (pending.length) { + lines.push(`Pending: ${pending.map((n) => code(n.path || '(form)')).join(', ')}.`); + } + const submits = state.events.filter((e) => e.formId === form.id && e.type === 'submit').slice(-5); + if (submits.length) lines.push('Recent submits:', ...submits.map(eventLine)); + return `${UNTRUSTED}\n\n**${form.label.replace(/[`*]/g, "'")}** (${form.id})\n${lines.join('\n')}${freshness(state, now)}`; +} + +interface Payload { + value: unknown; + raw: unknown; + excluded: string[]; + unvalidated: string[]; + changed: string[]; +} + +export function payloadOf(form: CollectedForm): Payload { + const excluded: string[] = []; + const unvalidated: string[] = []; + const changed: string[] = []; + const build = (node: FormFieldNode, raw: boolean): unknown => { + if (node.type === 'control' || !node.children) return node.value; + const kids = node.children.filter((child) => { + if (raw || form.kind === 'signal') return true; + const drop = node.status !== 'DISABLED' && child.status === 'DISABLED'; + return !drop; + }); + const entries = kids.map((child) => [child.key, build(child, raw)] as const); + return node.type === 'array' ? entries.map(([, v]) => v) : Object.fromEntries(entries); + }; + walk(form.root, (node) => { + if (!node.path) return; + if (form.kind !== 'signal' && node.status === 'DISABLED') excluded.push(node.path); + if (form.kind === 'signal' && node.skipped && node.hiddenBy !== 'parent') + unvalidated.push(`${node.path} (${node.skipped})`); + if (node.type === 'control' && node.dirty && node.changed !== false) changed.push(node.path); + }); + const topExcluded = excluded.filter( + (p) => !excluded.some((q) => q !== p && p.startsWith(`${q}.`)), + ); + return { + value: build(form.root, false), + raw: build(form.root, true), + excluded: topExcluded, + unvalidated, + changed, + }; +} + +export function formPayloadText(state: FormsState, args: FieldArgs, now = Date.now()): string { + const form = pickForm(state, args); + if (typeof form === 'string') return form; + const p = payloadOf(form); + const lines = [ + `${form.kind === 'signal' ? 'form().value()' : 'form.value'}: ${JSON.stringify(p.value)}`, + ]; + if (form.kind !== 'signal') { + lines.push( + p.excluded.length + ? `Left out of form.value because they are disabled: ${p.excluded.map(code).join(', ')}. Use getRawValue() to include them: ${JSON.stringify(p.raw)}` + : 'getRawValue() is the same (nothing disabled).', + ); + } else if (p.unvalidated.length) { + lines.push( + `Sent but not validated (Signal Forms keeps hidden, disabled and readonly fields in the value): ${p.unvalidated.map(code).join(', ')}. Strip them before sending if the server should not get them.`, + ); + } + lines.push( + p.changed.length + ? `Changed by the user: ${p.changed.map(code).join(', ')}.` + : 'No field changed since it was created or last reset.', + ); + if (JSON.stringify(p.raw).includes(REDACTED)) lines.push('Secret values show as [redacted].'); + return `${UNTRUSTED}\n\n${lines.join('\n')}${freshness(state, now)}`; +} + +export interface HistoryArgs extends FieldArgs { + type?: string; + origin?: string; + since?: number; + limit?: number; +} + +export function formHistoryText(state: FormsState, args: HistoryArgs): string { + const forms = matchForms(state.forms, args.form, args.page); + const ids = new Set(forms.map((f) => f.id)); + const limit = Math.min(Math.max(args.limit ?? 50, 1), MAX_HISTORY); + const events = state.events.filter( + (e) => + (ids.has(e.formId) || (!args.form && !args.page)) && + (args.path === undefined || e.path === args.path || e.path.startsWith(`${args.path}.`)) && + (!args.type || e.type === args.type) && + (!args.origin || e.origin === args.origin) && + (args.since === undefined || (e.seq ?? 0) > args.since), + ); + const marker = latestMarker(state); + if (!events.length) return `No matching form events. Marker: ${marker}.`; + const byForm = new Map(state.forms.map((f) => [f.id, f.label])); + const lines = events + .slice(-limit) + .map((e) => `${eventLine(e)} in ${code(byForm.get(e.formId) ?? e.formId)}`); + return `${UNTRUSTED}\n\n${lines.join('\n')}\n\nMarker: ${marker} (pass as \`since\` to form-diff or form-history).`; +} + +export function formDiffText(state: FormsState, args: FieldArgs & { since?: number }): string { + const since = args.since ?? 0; + const forms = matchForms(state.forms, args.form, args.page); + const ids = new Set(forms.map((f) => f.id)); + const net = new Map< + string, + { from?: string; to?: string; count: number; type: string; formId: string; path: string } + >(); + for (const event of state.events) { + if ((event.seq ?? 0) <= since || !ids.has(event.formId)) continue; + const key = `${event.formId}|${event.path}|${event.type}`; + const entry = net.get(key); + if (!entry) { + net.set(key, { + from: + event.prev ?? (event.type === 'status' ? event.detail?.split('→')[0]?.trim() : undefined), + to: event.detail, + count: event.count ?? 1, + type: event.type, + formId: event.formId, + path: event.path, + }); + } else { + entry.to = event.detail; + entry.count += event.count ?? 1; + } + } + const marker = latestMarker(state); + if (!net.size) return `Nothing changed since marker ${since}. Marker now: ${marker}.`; + const oldest = state.events[0]?.seq ?? 0; + const lines = Array.from(net.values()) + .map((entry) => { + const to = entry.type === 'status' ? entry.to?.split('→').pop()?.trim() : entry.to; + if (entry.from !== undefined && entry.from === to) return null; + const change = entry.from !== undefined ? `${entry.from} → ${to ?? ''}` : (to ?? ''); + return `- ${code(entry.path || '(form)')} ${entry.type}: ${change}${entry.count > 1 ? ` (${entry.count} changes)` : ''}`; + }) + .filter(Boolean); + const gap = + since && oldest > since + 1 + ? '\n\n_Older events were dropped from the buffer; the diff may be incomplete._' + : ''; + return `${UNTRUSTED}\n\n${lines.length ? lines.join('\n') : 'Changes cancelled out.'}\n\nMarker now: ${marker}.${gap}`; +} + +export function lintFormsFor( + state: FormsState, + args: { form?: string; page?: string }, + now = Date.now(), +): FormLintFinding[] { + const forms = matchForms(state.forms, args.form, args.page); + const setup = (state.setupErrors ?? []) + .filter((e) => !args.page || e.pageId === args.page) + .map((e) => e.message); + return [ + ...lintSetupErrors(args.form ? [] : setup), + ...forms.flatMap((form) => lintForm(form, state.events, now)), + ]; +} + +export function lintFormsText( + state: FormsState, + args: { form?: string; page?: string }, + now = Date.now(), +): string { + const findings = lintFormsFor(state, args, now); + if (!findings.length) + return 'No form problems found by the lint rules. For generic accessibility, run axe-core scoped to the form.'; + const order = { error: 0, warning: 1, info: 2 }; + const lines = findings + .sort((a, b) => order[a.severity] - order[b.severity]) + .map( + (f) => + `- **${f.severity}** ${f.rule}${f.label ? ` in ${code(f.label)}` : ''}${f.path ? ` at ${code(f.path)}` : ''}: ${f.message} Fix: ${f.fix}`, + ); + return `${UNTRUSTED}\n\n${lines.join('\n')}`; +} + +export function explainCustomControlText(state: FormsState, args: FieldArgs): string { + const form = pickForm(state, args); + if (typeof form === 'string') return form; + const node = subtreeAt(form.root, args.path ?? ''); + if (!node) return `No field at ${code(args.path ?? '')} in ${form.id}.`; + const lines = [bindingText(node)]; + const b = node.binding; + if (b?.kind === 'accessor') { + lines.push( + `${b.accessor} must call the onChange callback from registerOnChange on every user edit, the onTouched callback on blur, and render the value it gets in writeValue.`, + ); + if (!b.disabledHook) { + lines.push( + `${b.accessor} has no setDisabledState, so control.disable() never disables the element.`, + ); + } + } + if (b?.kind === 'custom-control') { + lines.push( + 'Custom controls built on FormValueControl expose a value model(); the directive writes it and listens to it.', + ); + } + if (node.dom?.drift !== undefined) { + lines.push( + 'Drift: the element shows a different value than the model, so writeValue (or the value model) is not rendering updates.', + ); + } + if (node.dom?.disabled !== undefined) { + lines.push( + `Disabled drift: the element ${node.dom.disabled ? 'is' : 'is not'} disabled, the model says ${node.status === 'DISABLED' ? 'disabled' : 'enabled'}.`, + ); + } + if (node.bound && !node.touched && node.dirty) { + lines.push( + 'The value changed but the field was never touched: check that onTouched is called on blur.', + ); + } + const pageId = form.id.split('@')[1]; + const keyPattern = node.key + ? new RegExp(`(^|[^\\w])${node.key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}([^\\w]|$)`) + : null; + const setup = (state.setupErrors ?? []) + .filter((e) => !pageId || e.pageId === pageId) + .map((e) => e.message) + .filter((m) => !keyPattern || keyPattern.test(m)); + if (setup.length) lines.push('Setup errors:', ...setup.map((m) => `- ${m}`)); + return `${UNTRUSTED}\n\n${code(node.path || '(form)')} in ${code(form.label)}\n${lines.join('\n')}`; +} + +function literal(value: unknown): string { + return JSON.stringify(value, null, 2) ?? 'undefined'; +} + +export function exportFormText( + state: FormsState, + args: FieldArgs & { format?: 'snapshot' | 'fixture' }, +): string { + const form = pickForm(state, args); + if (typeof form === 'string') return form; + const p = payloadOf(form); + const { invalid } = blockingLeaves(form.root); + const header = [ + `// ${form.label} (${form.kind}) captured ${new Date(state.reportedAt).toISOString()}`, + `// status ${form.root.status}${invalid.length ? `; errors: ${invalid.map((n) => `${n.path || '(form)'} ${n.errors.map((e) => e.kind).join('+')}`).join(', ')}` : ''}`, + '// Secret values are [redacted]; replace them before running.', + ].join('\n'); + if (args.format !== 'fixture') { + return `${UNTRUSTED}\n\n\`\`\`json\n${literal({ id: form.id, label: form.label, kind: form.kind, status: form.root.status, value: p.raw, root: form.root })}\n\`\`\``; + } + const body = + form.kind === 'signal' + ? `const model = signal(${literal(p.raw)});\n// const f = form(model, schema);\n// expect(f().valid()).toBe(${form.root.status === 'VALID'});` + : `form.${p.excluded.length ? 'patchValue' : 'setValue'}(${literal(p.raw)});\n${p.excluded.map((path) => `form.get('${path}')?.disable();`).join('\n')}\nexpect(form.status).toBe('${form.root.status}');`; + return `${UNTRUSTED}\n\n\`\`\`ts\n${header}\n${body}\n\`\`\``; +} + +export type WaitUntil = 'settled' | 'valid' | 'not-pending' | 'submitted'; + +export function waitSatisfied( + state: FormsState, + args: FieldArgs & { until?: WaitUntil; since?: number }, +): boolean { + const forms = matchForms(state.forms, args.form, args.page); + if (!forms.length) return false; + const until = args.until ?? 'settled'; + return forms.every((form) => { + const status = form.root.status; + if (until === 'valid') return status === 'VALID'; + if (until === 'not-pending') return status !== 'PENDING'; + if (until === 'submitted') { + return state.events.some( + (e) => e.formId === form.id && e.type === 'submit' && (e.seq ?? 0) > (args.since ?? 0), + ); + } + let debouncing = false; + walk(form.root, (node) => { + if (node.debouncing) debouncing = true; + }); + return status !== 'PENDING' && !debouncing && !form.submit?.submitting; + }); +} diff --git a/packages/ng-devtools/src/rpc/forms-lint.ts b/packages/ng-devtools/src/rpc/forms-lint.ts new file mode 100644 index 0000000..2d7497d --- /dev/null +++ b/packages/ng-devtools/src/rpc/forms-lint.ts @@ -0,0 +1,229 @@ +import type { CollectedForm, FormEvent, FormFieldNode } from '../forms.ts'; + +export type LintSeverity = 'error' | 'warning' | 'info'; + +export interface FormLintFinding { + rule: string; + severity: LintSeverity; + form: string; + label: string; + path?: string; + message: string; + fix: string; +} + +const STUCK_PENDING_MS = 5000; + +function walk(node: FormFieldNode, visit: (node: FormFieldNode) => void) { + visit(node); + for (const child of node.children ?? []) walk(child, visit); +} + +function isLeaf(node: FormFieldNode): boolean { + return node.type === 'control' && node.materialized !== false; +} + +function requiredByModel(node: FormFieldNode): boolean { + return ( + !!node.required || + !!node.validatorNames?.some((name) => name === 'required' || name.startsWith('required ')) || + node.errors.some((error) => error.kind === 'required') + ); +} + +export function lintForm( + form: CollectedForm, + events: FormEvent[] = [], + now = Date.now(), +): FormLintFinding[] { + const out: FormLintFinding[] = []; + const add = ( + rule: string, + severity: LintSeverity, + path: string | undefined, + message: string, + fix: string, + ) => out.push({ rule, severity, form: form.id, label: form.label, path, message, fix }); + let bound = 0; + walk(form.root, (node) => { + if (node.bound) bound++; + }); + + for (const reason of form.submitDom?.reasons ?? []) { + add( + 'submit-unreachable', + 'warning', + undefined, + reason, + 'Add a type="submit" button inside the , or link it with form="id".', + ); + } + if (form.kind === 'signal' && form.submitDom && form.submit && !form.submit.hasAction) { + add( + 'formroot-no-submission', + 'error', + undefined, + 'The [formRoot] form has no submission action, so submitting throws NG01915.', + 'Pass { submission: { action: async (form) => … } } as the third argument of form().', + ); + } + + walk(form.root, (node) => { + const at = node.path || undefined; + if (node.stale?.length) { + add( + 'stale-validity', + 'warning', + at, + `Validators now report ${node.stale.join(', ')} but the control's errors do not: validators changed without revalidating.`, + 'Call control.updateValueAndValidity() after setValidators, addValidators or removeValidators.', + ); + } + if (node.pendingSince && now - node.pendingSince > STUCK_PENDING_MS) { + add( + 'stuck-pending', + 'warning', + at, + `Pending for ${Math.round((now - node.pendingSince) / 1000)}s. An async validator that never completes keeps the form PENDING forever.`, + 'Make the async validator observable complete (take(1), first()) or add a timeout.', + ); + } + if (form.kind === 'signal' && node.hidden && node.bound && node.hiddenBy !== 'parent') { + add( + 'hidden-field-rendered', + 'warning', + at, + 'The field is hidden() in the schema but still bound to an element, so users can edit a field that skips validation.', + 'Wrap the element in @if (!field().hidden()) { … }.', + ); + } + if (node.dom?.drift !== undefined) { + add( + 'view-out-of-sync', + 'warning', + at, + 'The element shows a different value than the model. Usually a change made outside change detection (FormArray.push without markForCheck) or a custom control that ignores writeValue.', + "Trigger change detection after the change, or check the control's writeValue.", + ); + } + if (node.dom?.disabled !== undefined && form.kind === 'reactive') { + add( + 'disabled-attr-reactive', + 'warning', + at, + `The element is ${node.dom.disabled ? '' : 'not '}disabled but the control is ${node.status === 'DISABLED' ? '' : 'not '}disabled. The [disabled] attribute does not work with reactive forms.`, + 'Use control.disable() / enable(), or { value, disabled } when creating the control.', + ); + } + if (node.modelDrift) { + add( + 'ngmodel-drift', + 'info', + at, + 'ngModel holds a different value than its [ngModel] input: the bound property changed and the view has not caught up yet.', + 'Run change detection, or check for a (ngModelChange) handler that rewrites the value.', + ); + } + for (const error of node.errors) { + if (error.source === 'submission') { + add( + 'submission-error', + 'info', + at, + `Server/submission error "${error.kind}" stays until this field's value changes.`, + 'Clear it on the next submit, or when a related field changes.', + ); + } + } + if (!isLeaf(node) || !node.dom) return; + if (node.dom.labelled === false) { + add( + 'missing-label', + 'warning', + at, + 'The input has no accessible name.', + 'Add a