From 808b30d04d4bbee7b4c04e0607bc5ffde5476e7a Mon Sep 17 00:00:00 2001 From: Kam Date: Sat, 26 Sep 2026 16:39:23 +0300 Subject: [PATCH 1/6] feat(forms): explain, act on and lint live forms, with MCP tools --- README.md | 42 +- app/src/pages/forms-field-detail.ts | 123 ++ app/src/pages/forms-inspector.ts | 635 ++++--- app/src/pages/forms-report.ts | 142 ++ app/src/pages/forms-timeline.ts | 130 ++ app/src/pages/forms-types.ts | 208 +++ ...=> browser-agent-rpc-BXhoSh1z-qqnMwn9c.js} | 2 +- extension/ui/assets/index-1aLPIIno.js | 1623 +++++++++++++++++ extension/ui/assets/index-ruy7p20M.js | 1170 ------------ extension/ui/index.html | 2 +- .../src/__tests__/forms-actions.test.ts | 270 +++ .../src/__tests__/forms-collector.test.ts | 190 ++ .../src/__tests__/forms-lint.test.ts | 109 ++ .../src/__tests__/forms-mcp.test.ts | 416 +++++ .../src/__tests__/forms-read.test.ts | 299 +++ .../src/__tests__/forms-real.test.ts | 2 +- .../src/__tests__/forms-source.test.ts | 39 + .../src/__tests__/forms-tools.test.ts | 6 +- .../ng-devtools/src/__tests__/forms.test.ts | 3 +- packages/ng-devtools/src/devframe.ts | 434 ++++- packages/ng-devtools/src/forms-actions.ts | 612 +++++++ packages/ng-devtools/src/forms-collector.ts | 444 +++++ packages/ng-devtools/src/forms-dom.ts | 174 ++ packages/ng-devtools/src/forms-privacy.ts | 136 ++ packages/ng-devtools/src/forms-read.ts | 375 ++++ packages/ng-devtools/src/forms.ts | 263 ++- packages/ng-devtools/src/overlay.ts | 173 +- packages/ng-devtools/src/rpc/forms-explain.ts | 550 ++++++ packages/ng-devtools/src/rpc/forms-lint.ts | 228 +++ packages/ng-devtools/src/rpc/forms-source.ts | 142 ++ packages/ng-devtools/src/rpc/forms-tools.ts | 121 +- 31 files changed, 7423 insertions(+), 1640 deletions(-) create mode 100644 app/src/pages/forms-field-detail.ts create mode 100644 app/src/pages/forms-report.ts create mode 100644 app/src/pages/forms-timeline.ts create mode 100644 app/src/pages/forms-types.ts rename extension/ui/assets/{browser-agent-rpc-BXhoSh1z-Drr9EpwB.js => browser-agent-rpc-BXhoSh1z-qqnMwn9c.js} (93%) create mode 100644 extension/ui/assets/index-1aLPIIno.js delete mode 100644 extension/ui/assets/index-ruy7p20M.js create mode 100644 packages/ng-devtools/src/__tests__/forms-actions.test.ts create mode 100644 packages/ng-devtools/src/__tests__/forms-collector.test.ts create mode 100644 packages/ng-devtools/src/__tests__/forms-lint.test.ts create mode 100644 packages/ng-devtools/src/__tests__/forms-mcp.test.ts create mode 100644 packages/ng-devtools/src/__tests__/forms-read.test.ts create mode 100644 packages/ng-devtools/src/__tests__/forms-source.test.ts create mode 100644 packages/ng-devtools/src/forms-actions.ts create mode 100644 packages/ng-devtools/src/forms-collector.ts create mode 100644 packages/ng-devtools/src/forms-dom.ts create mode 100644 packages/ng-devtools/src/forms-privacy.ts create mode 100644 packages/ng-devtools/src/forms-read.ts create mode 100644 packages/ng-devtools/src/rpc/forms-explain.ts create mode 100644 packages/ng-devtools/src/rpc/forms-lint.ts create mode 100644 packages/ng-devtools/src/rpc/forms-source.ts diff --git a/README.md b/README.md index 1914b3a..862ca26 100644 --- a/README.md +++ b/README.md @@ -88,19 +88,30 @@ 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 | +| 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 | #### Forms @@ -110,8 +121,11 @@ 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. -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. #### Agent Resources diff --git a/app/src/pages/forms-field-detail.ts b/app/src/pages/forms-field-detail.ts new file mode 100644 index 0000000..99cf6bb --- /dev/null +++ b/app/src/pages/forms-field-detail.ts @@ -0,0 +1,123 @@ +import { Component, effect, input, 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(''); + readonly draft = signal(''); + readonly message = signal(''); + + 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..f2a764d 100644 --- a/app/src/pages/forms-inspector.ts +++ b/app/src/pages/forms-inspector.ts @@ -1,57 +1,52 @@ import { Component, DestroyRef, computed, effect, inject, input, signal } 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 { @@ -64,12 +59,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 +69,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 +131,307 @@ 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 +
    + No field path matches "{{ filter() }}". +
    +
    + + @if (selectedNode(); as node) { + + } } -
- } @else { -

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

- } + @case ('timeline') { + + } + @case ('submit') { + + } + @case ('lint') { + + } + } +
} } `, 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 +606,7 @@ function countFields(node: FormFieldNode): number { font-weight: 400; } .value code, - .errors code, - .events code { + .errors code { color: #c4b5fd; overflow-wrap: anywhere; } @@ -485,32 +627,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; } @@ -530,6 +646,15 @@ export class FormsInspector { readonly failed = signal(false); readonly selectedId = signal(null); 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 +678,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 +693,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() { @@ -594,6 +730,7 @@ export class FormsInspector { const snapshot = value as FormsSnapshot | undefined; this.forms.set(snapshot?.forms ?? []); this.events.set(snapshot?.events ?? []); + this.version.update((v) => v + 1); }; apply(state.value()); this.unsubscribe?.(); @@ -608,6 +745,56 @@ export class FormsInspector { 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 +822,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..35556e0 --- /dev/null +++ b/app/src/pages/forms-report.ts @@ -0,0 +1,142 @@ +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] ?? ''; + 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..5241b5a --- /dev/null +++ b/app/src/pages/forms-timeline.ts @@ -0,0 +1,130 @@ +import { Component, computed, input, 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 }} + } +
  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; + } + `, +}) +export class FormsTimeline { + events = input.required(); + + 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..24e1107 --- /dev/null +++ b/app/src/pages/forms-types.ts @@ -0,0 +1,208 @@ +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; +} + +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-Drr9EpwB.js b/extension/ui/assets/browser-agent-rpc-BXhoSh1z-qqnMwn9c.js similarity index 93% rename from extension/ui/assets/browser-agent-rpc-BXhoSh1z-Drr9EpwB.js rename to extension/ui/assets/browser-agent-rpc-BXhoSh1z-qqnMwn9c.js index 1ac902e..d3211b6 100644 --- a/extension/ui/assets/browser-agent-rpc-BXhoSh1z-Drr9EpwB.js +++ b/extension/ui/assets/browser-agent-rpc-BXhoSh1z-qqnMwn9c.js @@ -1 +1 @@ -import{t as e}from"./index-ruy7p20M.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-1aLPIIno.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-1aLPIIno.js b/extension/ui/assets/index-1aLPIIno.js new file mode 100644 index 0000000..67fdd99 --- /dev/null +++ b/extension/ui/assets/index-1aLPIIno.js @@ -0,0 +1,1623 @@ +(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){let t=j(null);try{return e()}finally{j(t)}}var Yn=function(e,t){return Yn=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])},Yn(e,t)};function Xn(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);Yn(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}function Zn(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 Qn(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 $n(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?ar:(this.currentObservers=null,a.push(e),new ir(function(){t.currentObservers=null,rr(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 jr;return e.source=this,e},t.create=function(e,t){return new Vr(e,t)},t}(jr),Vr=function(e){Xn(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)??ar},t}(Br),Hr=function(e){Xn(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}(Br);function Ur(e,t){return Ir(function(n,r){var i=0;n.subscribe(Lr(r,function(n){r.next(e.call(t,n,i++))}))})}var Wr=`https://angular.dev/best-practices/security#preventing-cross-site-scripting-xss`,M=class extends Error{code;constructor(e,t){super(Kr(e,t)),this.code=e}};function Gr(e){return`NG0${Math.abs(e)}`}function Kr(e,t){return`${Gr(e)}${t?`: `+t:``}`}function qr(e){for(let t in e)if(e[t]===qr)return t;throw Error(``)}function Jr(e){if(typeof e==`string`)return e;if(Array.isArray(e))return`[${e.map(Jr).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 Yr(e,t){return e?t?`${e} ${t}`:e:t||``}var Xr=qr({__forward_ref__:qr});function Zr(e){return e.__forward_ref__=Zr,e}function Qr(e){return $r(e)?e():e}function $r(e){return typeof e==`function`&&Object.hasOwn(e,Xr)&&e.__forward_ref__===Zr}function ei(e){return{token:e.token,providedIn:e.providedIn||null,factory:e.factory,value:void 0}}function ti(e){return ni(e,ai)}function ni(e,t){return Object.hasOwn(e,t)&&e[t]||null}function ri(e){return(e?.[ai]??null)||null}function ii(e){return e&&Object.hasOwn(e,oi)?e[oi]:null}var ai=qr({ɵprov:qr}),oi=qr({ɵinj:qr}),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=ei({token:this,providedIn:t.providedIn||`root`,factory:t.factory}))}get multi(){return this}toString(){return`InjectionToken ${this._desc}`}};function si(e){return e&&!!e.ɵproviders}var ci=qr({ɵcmp:qr}),li=qr({ɵdir:qr}),ui=qr({ɵpipe:qr}),di=qr({ɵfac:qr}),fi=qr({__NG_ELEMENT_ID__:qr}),pi=qr({__NG_ENV_ID__:qr});function mi(e){return _i(e,`@Component`),e[ci]||null}function hi(e){return _i(e,`@Directive`),e[li]||null}function gi(e){return _i(e,`@Pipe`),e[ui]||null}function _i(e,t){if(e==null)throw new M(-919,!1)}function vi(e){return typeof e==`string`?e:e==null?``:String(e)}var yi=qr({ngErrorCode:qr}),bi=qr({ngErrorMessage:qr}),xi=qr({ngTokenPath:qr});function Si(e,t){return wi(``,-200,t)}function Ci(e,t){throw new M(-201,!1)}function wi(e,t,n){let r=new M(t,e);return r[yi]=t,r[bi]=e,n&&(r[xi]=n),r}function Ti(e){return e[yi]}var Ei;function Di(){return Ei}function Oi(e){let t=Ei;return Ei=e,t}function ki(e,t,n){let r=ti(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;Ci(e,``)}var Ai={},ji=`__NG_DI_FLAG__`,Mi=class{injector;constructor(e){this.injector=e}retrieve(e,t){let n=Fi(t)||0;try{return this.injector.get(e,n&8?null:Ai,n)}catch(e){if(qn(e))return e;throw e}}};function Ni(e,t=0){let n=Wn();if(n===void 0)throw new M(-203,!1);if(n===null)return ki(e,void 0,t);{let r=Ii(t),i=n.retrieve(e,r);if(qn(i)){if(r.optional)return null;throw i}return i}}function Pi(e,t=0){return(Di()||Ni)(Qr(e),t)}function P(e,t){return Pi(e,Fi(t))}function Fi(e){return e===void 0||typeof e==`number`?e:0|(e.optional&&8)|(e.host&&1)|(e.self&&2)|(e.skipSelf&&4)}function Ii(e){return{optional:!!(e&8),host:!!(e&1),self:!!(e&2),skipSelf:!!(e&4)}}function Li(e){let t=[];for(let n=0;nArray.isArray(e)?Bi(e,t):t(e))}function Vi(e,t,n){t>=e.length?e.push(n):e.splice(t,0,n)}function Hi(e,t){return t>=e.length-1?e.pop():e.splice(t,1)[0]}function Ui(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 Wi(e,t,n){let r=Ki(e,t);return r>=0?e[r|1]=n:(r=~r,Ui(e,r,t,n)),r}function Gi(e,t){let n=Ki(e,t);if(n>=0)return e[n|1]}function Ki(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 Bi(t,e=>{let t=e;ra(t,a,[],r)&&(i||=[],i.push(t))}),i!==void 0&&na(i,a),n}function na(e,t){for(let n=0;n{t(e,r)})}}function ra(e,t,n,r){if(e=Qr(e),!e)return!1;let i=null,a=ii(e),o=!a&&mi(e);if(!a&&!o){let t=e.ngModule;if(a=ii(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)ra(i,t,n,r)}}else if(a){if(a.imports!=null&&!s){r.add(i);let e;try{Bi(a.imports,i=>{ra(i,t,n,r)&&(e||=[],e.push(i))})}finally{}e!==void 0&&na(e,t)}if(!s){let e=zi(i)||(()=>new i);t({provide:i,useFactory:e,deps:Yi},i),t({provide:Qi,useValue:i,multi:!0},i),t({provide:Xi,useValue:()=>Pi(i),multi:!0},i)}let o=a.providers;if(o!=null&&!s){let n=e;ia(o,e=>{t(e,n)})}}else return!1;return i!==e&&e.providers!==void 0}function ia(e,t){for(let n of e)si(n)&&(n=n.ɵproviders),Array.isArray(n)?ia(n,t):t(n)}var aa=qr({provide:String,useValue:qr});function oa(e){return typeof e==`object`&&!!e&&aa in e}function sa(e){return!!(e&&e.useExisting)}function ca(e){return!!(e&&e.useFactory)}function la(e){return typeof e==`function`}var ua=new N(``),da={},fa={},pa=void 0;function ma(){return pa===void 0&&(pa=new $i),pa}var ha=class{},ga=class extends ha{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,Ea(e,e=>this.processProvider(e)),this.records.set(Zi,Sa(void 0,this)),r.has(`environment`)&&this.records.set(ha,Sa(void 0,this));let i=this.records.get(ua);i!=null&&typeof i.value==`string`&&this.scopes.add(i.value),this.injectorDefTypes=new Set(this.get(Qi,Yi,{self:!0}))}retrieve(e,t){let n=Fi(t)||0;try{return this.get(e,Ai,n)}catch(e){if(qn(e))return e;throw e}}destroy(){xa(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 xa(this),this._onDestroyHooks.push(e),()=>this.removeOnDestroy(e)}runInContext(e){xa(this);let t=Gn(this),n=Oi(void 0);try{return e()}finally{Gn(t),Oi(n)}}get(e,t=Ai,n){if(xa(this),Object.hasOwn(e,pi))return e[pi](this);let r=Fi(n),i=Gn(this),a=Oi(void 0);try{if(!(r&4)){let t=this.records.get(e);if(t===void 0){let n=Ta(e)&&ti(e);t=n&&this.injectableDefInScope(n)?Sa(_a(e),da):null,this.records.set(e,t)}if(t!=null)return this.hydrate(e,t,r)}let n=r&2?ma():this.parent;return t=r&8&&t===Ai?null:t,n.get(e,t)}catch(e){let t=Ti(e);throw t===-200||t===-201?new M(t,null):e}finally{Oi(a),Gn(i)}}resolveInjectorInitializers(){let e=j(null),t=Gn(this),n=Oi(void 0);try{let e=this.get(Xi,Yi,{self:!0});for(let t of e)t()}finally{Gn(t),Oi(n),j(e)}}toString(){return`R3Injector[...]`}processProvider(e){e=Qr(e);let t=la(e)?e:Qr(e&&e.provide),n=ya(e);if(!la(e)&&e.multi===!0){let n=this.records.get(t);n||(n=Sa(void 0,da,!0),n.factory=()=>Li(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===fa)throw Si(``);return t.value===da&&(t.value=fa,t.value=t.factory(void 0,n)),typeof t.value==`object`&&t.value&&wa(t.value)&&this._ngOnDestroyHooks.add(t.value),t.value}finally{j(r)}}injectableDefInScope(e){if(!e.providedIn)return!1;let t=Qr(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 _a(e){let t=ti(e),n=t===null?zi(e):t.factory;if(n!==null)return n;if(e instanceof N)throw new M(-204,!1);if(e instanceof Function)return va(e);throw new M(-204,!1)}function va(e){if(e.length>0)throw new M(-204,!1);let t=ri(e);return t===null?()=>new e:()=>t.factory(e)}function ya(e){return oa(e)?Sa(void 0,e.useValue):Sa(ba(e),da)}function ba(e,t,n){let r;if(la(e)){let t=Qr(e);return zi(t)||_a(t)}if(oa(e))r=()=>Qr(e.useValue);else if(ca(e))r=()=>e.useFactory(...Li(e.deps||[]));else if(sa(e))r=(t,n)=>Pi(Qr(e.useExisting),n!==void 0&&n&8?8:void 0);else{let t=Qr(e&&(e.useClass||e.provide));if(Ca(e))r=()=>new t(...Li(e.deps));else return zi(t)||_a(t)}return r}function xa(e){if(e.destroyed)throw new M(-205,!1)}function Sa(e,t,n=!1){return{factory:e,value:t,multi:n?[]:void 0}}function Ca(e){return!!e.deps}function wa(e){return typeof e==`object`&&!!e&&typeof e.ngOnDestroy==`function`}function Ta(e){return typeof e==`function`||typeof e==`object`&&e.ngMetadataName===`InjectionToken`}function Ea(e,t){for(let n of e)Array.isArray(n)?Ea(n,t):n&&si(n)?Ea(n.ɵproviders,t):t(n)}function Da(e,t){let n;e instanceof ga?(xa(e),n=e):n=new Mi(e);let r=Gn(n),i=Oi(void 0);try{return t()}finally{Gn(r),Oi(i)}}function Oa(){return Di()!==void 0||Wn()!=null}var ka=1;function Aa(e){return Array.isArray(e)&&typeof e[ka]==`object`}function ja(e){return Array.isArray(e)&&e[ka]===!0}function Ma(e){return!!(e.flags&4)}function Na(e){return e.componentOffset>-1}function Pa(e){return(e.flags&1)==1}function Fa(e){return!!e.template}function Ia(e){return!!(e[2]&512)}function La(e){return(e[2]&256)==256}var Ra=`math`;function za(e){for(;Array.isArray(e);)e=e[0];return e}function Ba(e,t){return za(t[e])}function Va(e,t){return za(t[e.index])}function Ha(e,t){return e.data[t]}function Ua(e,t){return e[t]}function Wa(e,t,n,r){n>=e.data.length&&(e.data[n]=null,e.blueprint[n]=null),t[n]=r}function Ga(e,t){let n=t[e];return Aa(n)?n:n[0]}function Ka(e){return(e[2]&128)==128}function qa(e,t){return t==null?null:e[t]}function Ja(e){e[17]=0}function Ya(e){e[2]&1024||(e[2]|=1024,Ka(e)&&$a(e))}function Xa(e,t){for(;e>0;)t=t[14],e--;return t}function Za(e){return!!(e[2]&9216||e[24]?.dirty)}function Qa(e){e[10].changeDetectionScheduler?.notify(8),e[2]&64&&(e[2]|=1024),Za(e)&&$a(e)}function $a(e){e[10].changeDetectionScheduler?.notify(0);let t=no(e);for(;t!==null&&!(t[2]&8192||(t[2]|=8192,!Ka(t)));)t=no(t)}function eo(e,t){if(La(e))throw new M(911,!1);e[21]===null&&(e[21]=[]),e[21].push(t)}function to(e,t){if(e[21]===null)return;let n=e[21].indexOf(t);n!==-1&&e[21].splice(n,1)}function no(e){let t=e[3];return ja(t)?t[3]:t}function ro(e){return e[7]??=[]}function io(e){return e.cleanup??=[]}var F={lFrame:Bo(null),bindingsEnabled:!0,skipHydrationRootTNode:null},ao=!1;function oo(){return F.lFrame.elementDepthCount}function so(){F.lFrame.elementDepthCount++}function co(){F.lFrame.elementDepthCount--}function lo(){return F.bindingsEnabled}function uo(){return F.skipHydrationRootTNode!==null}function fo(e){return F.skipHydrationRootTNode===e}function po(){F.skipHydrationRootTNode=null}function I(){return F.lFrame.lView}function mo(){return F.lFrame.tView}function ho(e){return F.lFrame.contextLView=e,e[8]}function go(e){return F.lFrame.contextLView=null,e}function _o(){let e=vo();for(;e!==null&&e.type===64;)e=e.parent;return e}function vo(){return F.lFrame.currentTNode}function yo(){let e=F.lFrame,t=e.currentTNode;return e.isParent?t:t.parent}function bo(e,t){let n=F.lFrame;n.currentTNode=e,n.isParent=t}function xo(){return F.lFrame.isParent}function So(){F.lFrame.isParent=!1}function Co(){return ao}function wo(e){let t=ao;return ao=e,t}function To(){let e=F.lFrame,t=e.bindingRootIndex;return t===-1&&(t=e.bindingRootIndex=e.tView.bindingStartIndex),t}function Eo(){return F.lFrame.bindingIndex}function Do(e){return F.lFrame.bindingIndex=e}function Oo(){return F.lFrame.bindingIndex++}function ko(e){let t=F.lFrame,n=t.bindingIndex;return t.bindingIndex+=e,n}function Ao(){return F.lFrame.inI18n}function jo(e,t){let n=F.lFrame;n.bindingIndex=n.bindingRootIndex=e,No(t)}function Mo(){return F.lFrame.currentDirectiveIndex}function No(e){F.lFrame.currentDirectiveIndex=e}function Po(e){let t=F.lFrame.currentDirectiveIndex;return t===-1?null:e[t]}function Fo(e){F.lFrame.currentQueryIndex=e}function Io(e){let t=e[1];return t.type===2?t.declTNode:t.type===1?e[5]:null}function Lo(e,t,n){if(n&4){let r=t,i=e;for(;r=r.parent,r===null&&!(n&1)&&(r=Io(i),!(r===null||(i=i[14],r.type&10))););if(r===null)return!1;t=r,e=i}let r=F.lFrame=zo();return r.currentTNode=t,r.lView=e,!0}function Ro(e){let t=zo(),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 zo(){let e=F.lFrame,t=e===null?null:e.child;return t===null?Bo(e):t}function Bo(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 Vo(){let e=F.lFrame;return F.lFrame=e.parent,e.currentTNode=null,e.lView=null,e}var Ho=Vo;function Uo(){let e=Vo();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 Wo(e){return(F.lFrame.contextLView=Xa(e,F.lFrame.contextLView))[8]}function Go(){return F.lFrame.selectedIndex}function Ko(e){F.lFrame.selectedIndex=e}function qo(){let e=F.lFrame;return Ha(e.tView,e.selectedIndex)}function Jo(){F.lFrame.currentNamespace=`svg`}function Yo(){Xo()}function Xo(){F.lFrame.currentNamespace=null}function Zo(){return F.lFrame.currentNamespace}var Qo=!0;function $o(){return Qo}function es(e){Qo=e}function ts(e,t=null,n=null,r){let i=ns(e,t,n,r);return i.resolveInjectorInitializers(),i}function ns(e,t=null,n=null,r,i=new Set){return new ga([n||Yi,ea(e)],t||ma(),null,i)}var rs=class e{static THROW_IF_NOT_FOUND=Ai;static NULL=new $i;static create(e,t){if(Array.isArray(e))return ts({name:``},t,e,``);{let t=e.name??``;return ts({name:t},e.parent,e.providers,t)}}static ɵprov=ei({token:e,providedIn:`any`,factory:()=>Pi(Zi)});static __NG_ELEMENT_ID__=-1},is=new N(``),as=class{static __NG_ELEMENT_ID__=ss;static __NG_ENV_ID__=e=>e},os=class extends as{_lView;constructor(e){super(),this._lView=e}get destroyed(){return La(this._lView)}onDestroy(e){let t=this._lView;return eo(t,e),()=>to(t,e)}};function ss(){return new os(I())}var cs=new N(``),ls=(()=>{class e{taskId=0;pendingTasks=new Set;destroyed=!1;pendingTask=new Hr(!1);debugTaskTracker=P(cs,{optional:!0});get hasPendingTasks(){return!this.destroyed&&this.pendingTask.value}get hasPendingTasksObservable(){return this.destroyed?new jr(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=ei({token:e,providedIn:`root`,factory:()=>new e})}return e})(),us=class extends Br{__isAsync;destroyRef=void 0;pendingTasks=void 0;constructor(e=!1){super(),this.__isAsync=e,Oa()&&(this.destroyRef=P(as,{optional:!0})??void 0,this.pendingTasks=P(ls,{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 ir&&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 ds(...e){}function fs(e){let t,n;function r(){e=ds;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 ps(e){return queueMicrotask(()=>e()),()=>{e=ds}}var ms=`isAngularZone`,hs=`isAngularZone_ID`,gs=0,_s=class e{hasPendingMacrotasks=!1;hasPendingMicrotasks=!1;isStable=!0;onUnstable=new us(!1);onMicrotaskEmpty=new us(!1);onStable=new us(!1);onError=new us(!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,xs(a)}static isInAngularZone(){return typeof Zone<`u`&&Zone.current.get(ms)===!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,vs,ds,ds);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)}},vs={};function ys(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 bs(e){if(e.isCheckStableRunning||e.callbackScheduled)return;e.callbackScheduled=!0;function t(){fs(()=>{e.callbackScheduled=!1,Ss(e),e.isCheckStableRunning=!0,ys(e),e.isCheckStableRunning=!1})}e.scheduleInRootZone?Zone.root.run(()=>{t()}):e._outer.run(()=>{t()}),Ss(e)}function xs(e){let t=()=>{bs(e)},n=gs++;e._inner=e._inner.fork({name:`angular`,properties:{[ms]:!0,[hs]:n,[hs+n]:!0},onInvokeTask:(n,r,i,a,o,s)=>{if(Es(s))return n.invokeTask(i,a,o,s);try{return Cs(e),n.invokeTask(i,a,o,s)}finally{(e.shouldCoalesceEventChangeDetection&&a.type===`eventTask`||e.shouldCoalesceRunChangeDetection)&&t(),ws(e)}},onInvoke:(n,r,i,a,o,s,c)=>{try{return Cs(e),n.invoke(i,a,o,s,c)}finally{e.shouldCoalesceRunChangeDetection&&!e.callbackScheduled&&!Ds(s)&&t(),ws(e)}},onHasTask:(t,n,r,i)=>{t.hasTask(r,i),n===r&&(i.change==`microTask`?(e._hasPendingMicrotasks=i.microTask,Ss(e),ys(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 Ss(e){e.hasPendingMicrotasks=!!(e._hasPendingMicrotasks||(e.shouldCoalesceEventChangeDetection||e.shouldCoalesceRunChangeDetection)&&e.callbackScheduled===!0)}function Cs(e){e._nesting++,e.isStable&&(e.isStable=!1,e.onUnstable.emit(null))}function ws(e){e._nesting--,ys(e)}var Ts=class{hasPendingMicrotasks=!1;hasPendingMacrotasks=!1;isStable=!0;onUnstable=new us;onMicrotaskEmpty=new us;onStable=new us;onError=new us;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 Es(e){return Os(e,`__ignore_ng_zone__`)}function Ds(e){return Os(e,`__scheduler_tick__`)}function Os(e,t){return!Array.isArray(e)||e.length!==1?!1:e[0]?.data?.[t]===!0}var ks=class{_console=console;handleError(e){this._console.error(`ERROR`,e)}},As=new N(``,{factory:()=>{let e=P(_s),t=P(ha),n;return r=>{e.runOutsideAngular(()=>{t.destroyed&&!n?setTimeout(()=>{throw r}):(n??=t.get(ks),n.handleError(r))})}}}),js={provide:Xi,useValue:()=>{P(ks,{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=Ms.bind(a),a}function Ms(){let e=this[rn];if(e.readonlyFn===void 0){let t=()=>this();t[rn]=e,e.readonlyFn=t}return e.readonlyFn}var Ns=new N(``,{factory:()=>Ps}),Ps=`ng`,Fs=new N(``),Is=new N(``,{providedIn:`platform`,factory:()=>`unknown`}),Ls=new N(``,{factory:()=>P(is).body?.querySelector(`[ngCspNonce]`)?.getAttribute(`ngCspNonce`)||null}),Rs=(()=>{class e{view;node;constructor(e,t){this.view=e,this.node=t}static __NG_ELEMENT_ID__=zs}return e})();function zs(){return new Rs(I(),_o())}var Bs=class{},Vs=new N(``,{factory:()=>!0}),Hs=new N(``),Us=(()=>{class e{static ɵprov=ei({token:e,providedIn:`root`,factory:()=>new Ws})}return e})(),Ws=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}},Gs=class{[rn];constructor(e){this[rn]=e}destroy(){this[rn].destroy()}};function Ks(e,t){let n=t?.injector??P(rs),r=t?.manualCleanup===!0?null:n.get(as),i,a=n.get(Rs,null,{optional:!0}),o=n.get(Bs);return a===null?i=Zs(e,n.get(Us),o):(i=Xs(a.view,o,e),r instanceof os&&r._lView===a.view&&(r=null)),i.injector=n,r!==null&&(i.onDestroyFns=[r.onDestroy(()=>i.destroy())]),new Gs(i)}var qs={...Vn,cleanupFns:void 0,zone:null,onDestroyFns:null,run(){let e=wo(!1);try{Hn(this)}finally{wo(e)}},cleanup(){if(!this.cleanupFns?.length)return;let e=j(null);try{for(;this.cleanupFns.length;)this.cleanupFns.pop()()}finally{this.cleanupFns=[],j(e)}}},Js={...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)}},Ys={...qs,consumerMarkedDirty(){this.view[2]|=8192,$a(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 Xs(e,t,n){let r=Object.create(Ys);return r.view=e,r.zone=typeof Zone<`u`?Zone.current:null,r.notifier=t,r.fn=Qs(r,n),e[23]??=new Set,e[23].add(r),r.consumerMarkedDirty(r),r}function Zs(e,t,n){let r=Object.create(Js);return r.fn=Qs(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 Qs(e,t){return()=>{t(t=>(e.cleanupFns??=[]).push(t))}}var $s=(()=>{class e{internalPendingTasks=P(ls);scheduler=P(Bs);errorHandler=P(As);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=ei({token:e,providedIn:`root`,factory:()=>new e})}return e})(),ec=Symbol(`InputSignalNode#UNSET`),tc={...zn,transformFn:void 0,applyValueToInputSignal(e,t){Ln(e,t)}};function nc(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 rc(e,t,n,r){t===null?e[n]=r:t.applyValueToInputSignal(t,r)}var ic=null;function ac(){return ic}var oc=[],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,pc(o,a)):pc(o,a)}var hc=-1,gc=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 _c(e){return!!(e.flags&8)}function vc(e){return!!(e.flags&16)}function yc(e,t,n){let r=0;for(;rt){o=a-1;break}}}for(;a>16}function Dc(e,t){let n=Ec(e),r=t;for(;n>0;)r=r[14],n--;return r}var Oc=!0;function kc(e){let t=Oc;return Oc=e,t}var Ac=255,jc=5,Mc=0,Nc={};function Pc(e,t,n){let r;typeof n==`string`?r=n.charCodeAt(0)||0:Object.hasOwn(n,fi)&&(r=n[fi]),r??=n[fi]=Mc++;let i=r&Ac,a=1<>jc)]|=a}function Fc(e,t){let n=Lc(e,t);if(n!==-1)return n;let r=t[1];r.firstCreatePass&&(e.injectorIndex=t.length,Ic(r.data,e),Ic(t,null),Ic(r.blueprint,null));let i=Rc(e,t),a=e.injectorIndex;if(wc(i)){let e=Tc(i),n=Dc(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 Ic(e,t){e.push(0,0,0,0,0,0,0,0,t)}function Lc(e,t){return e.injectorIndex===-1||e.parent&&e.parent.injectorIndex===e.injectorIndex||t[e.injectorIndex+8]===null?-1:e.injectorIndex}function Rc(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=$c(i),r===null)return hc;if(n++,i=i[14],r.injectorIndex!==-1)return r.injectorIndex|n<<16}return hc}function zc(e,t,n){Pc(e,t,n)}function Bc(e,t,n){if(n&8||e!==void 0)return e;Ci(t,`NodeInjector`)}function Vc(e,t,n,r){if(n&8&&r===void 0&&(r=null),!(n&3)){let i=e[9],a=Oi(void 0);try{return i?i.get(t,r,n&8):ki(t,r,n&8)}finally{Oi(a)}}return Bc(r,t,n)}function Hc(e,t,n,r=0,i){if(e!==null){if(t[2]&2048&&!(r&2)){let i=Qc(e,t,n,r,Nc);if(i!==Nc)return i}let i=Uc(e,t,n,r,Nc);if(i!==Nc)return i}return Vc(t,n,r,i)}function Uc(e,t,n,r,i){let a=qc(n);if(typeof a==`function`){if(!Lo(t,e,r))return r&1?Bc(i,n,r):Vc(t,n,r,i);try{let e;if(e=a(r),e==null&&!(r&8))Ci(n);else return e}finally{Ho()}}else if(typeof a==`number`){let i=null,o=Lc(e,t),s=hc,c=r&1?t[15][5]:null;for((o===-1||r&4)&&(s=o===-1?Rc(e,t):t[o+8],s===hc||!Yc(r,!1)?o=-1:(i=t[1],o=Tc(s),t=Dc(s,t)));o!==-1;){let e=t[1];if(Jc(a,o,e.data)){let e=Wc(o,t,n,i,r,c);if(e!==Nc)return e}s=t[o+8],s!==hc&&Yc(r,t[1].data[o+8]===c)&&Jc(a,o,t)?(i=e,o=Tc(s),t=Dc(s,t)):o=-1}}return i}function Wc(e,t,n,r,i,a){let o=t[1],s=o.data[e+8],c=Gc(s,o,n,r==null?Na(s)&&Oc:r!=o&&!!(s.type&3),i&1&&a===s);return c===null?Nc:Kc(t,o,c,s,i)}function Gc(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&&Fa(e)&&e.type===n)return c}return null}function Kc(e,t,n,r,i){let a=e[n],o=t.data;if(a instanceof gc){let s=a;if(s.resolving)throw Si(``);let c=kc(s.canSeeViewProviders);s.resolving=!0,o[n].type||o[n];let l=s.injectImpl?Oi(s.injectImpl):null;Lo(e,r,0);try{a=e[n]=s.factory(void 0,i,o,e,r),t.firstCreatePass&&n>=r.directiveStart&&sc(n,o[n],t)}finally{l!==null&&Oi(l),kc(c),s.resolving=!1,Ho()}}return a}function qc(e){if(typeof e==`string`)return e.charCodeAt(0)||0;let t=Object.hasOwn(e,fi)?e[fi]:void 0;return typeof t==`number`?t>=0?t&Ac:Zc:t}function Jc(e,t,n){let r=1<>jc)]&r)}function Yc(e,t){return!(e&2)&&!(e&1&&t)}var Xc=class{_tNode;_lView;constructor(e,t){this._tNode=e,this._lView=t}get(e,t,n){return Hc(this._tNode,this._lView,e,Fi(n),t)}};function Zc(){return new Xc(_o(),I())}function Qc(e,t,n,r,i){let a=e,o=t;for(;a!==null&&o!==null&&o[2]&2048&&!Ia(o);){let e=Uc(a,o,n,r|2,Nc);if(e!==Nc)return e;r&=-5;let t=a.parent;if(!t){let e=o[20];if(e){let t=e.get(n,Nc,r);if(t!==Nc)return t}t=$c(o),o=o[14]}a=t}return i}function $c(e){let t=e[1],n=t.type;return n===2?t.declTNode:n===1?e[5]:null}var el=()=>(typeof requestIdleCallback<`u`?requestIdleCallback:e=>setTimeout(e)).bind(globalThis),tl=()=>(typeof requestIdleCallback<`u`?cancelIdleCallback:clearTimeout).bind(globalThis),nl=new N(``,{factory:()=>new rl}),rl=class{requestIdleCallback=el();cancelIdleCallback=tl();requestOnIdle(e,t){return this.requestIdleCallback(e,t)}cancelOnIdle(e){return this.cancelIdleCallback(e)}};function il(e){return{token:e.token,providedIn:e.autoProvided===!1?null:`root`,factory:e.factory,value:void 0}}function al(){return ol(_o(),I())}function ol(e,t){return new sl(Va(e,t))}var sl=(()=>{class e{nativeElement;constructor(e){this.nativeElement=e}static __NG_ELEMENT_ID__=al}return e})();function cl(e){return(e.flags&128)==128}var ll=(function(e){return e[e.OnPush=0]=`OnPush`,e[e.Eager=1]=`Eager`,e[e.Default=1]=`Default`,e})(ll||{}),ul=new Map,dl=0;function fl(){return dl++}function pl(e){ul.set(e[19],e)}function ml(e){ul.delete(e[19])}var hl=`__ngContext__`;function gl(e,t){Aa(t)?(e[hl]=t[19],pl(t)):e[hl]=t}function _l(e){return yl(e[12])}function vl(e){return yl(e[4])}function yl(e){for(;e!==null&&!ja(e);)e=e[4];return e}var bl=void 0;function xl(e){bl=e}function Sl(){if(bl!==void 0)return bl;if(typeof document<`u`)return document;throw new M(210,!1)}var Cl=!1,wl=new N(``,{factory:()=>Cl}),Tl=new N(``),El=new WeakMap;function Dl(e,t){if(typeof e!=`object`||!e)return;let n=El.get(e);n||(n=new WeakSet,El.set(e,n)),n.add(t)}var Ol=new N(``);function kl(e){return(e.flags&32)==32}var Al=()=>null;function jl(e,t,n=!1){return Al(e,t,n)}function Ml(e){return e.get(Tl,!1,{optional:!0})}function Nl(e,t){let n=e.contentQueries;if(n!==null){let r=j(null);try{for(let r=0;r|^->||--!>|)/g,Vl=`​$1​`;function Hl(e){return e.replace(zl,e=>e.replace(Bl,Vl))}function Ul(e,t){return e.createText(t)}function Wl(e,t,n){e.setValue(t,n)}function Gl(e,t){return e.createComment(Hl(t))}function Kl(e,t,n){return e.createElement(t,n)}function ql(e,t,n,r,i){e.insertBefore(t,n,r,i)}function Jl(e,t,n){e.appendChild(t,n)}function Yl(e,t,n,r,i){r===null?Jl(e,t,n):ql(e,t,n,r,i)}function Xl(e,t,n,r){e.removeChild(null,t,n,r)}function Zl(e,t,n){e.setAttribute(t,`style`,n)}function Ql(e,t,n){n===``?e.removeAttribute(t,`class`):e.setAttribute(t,`class`,n)}function $l(e,t,n){let{mergedAttrs:r,classes:i,styles:a}=n;r!==null&&yc(e,t,r),i!==null&&Ql(e,t,i),a!==null&&Zl(e,t,a)}function eu(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 tu=`ng-template`;function nu(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(ou(r))return!1;o=!0}}}}}return ou(r)||o}function ou(e){return!(e&1)}function su(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!==``&&!ou(o)&&(t+=du(a,i),i=``),r=o,a||=!ou(r);n++}return i!==``&&(t+=du(a,i)),t}function pu(e){return e.map(fu).join(`,`)}function mu(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),Su.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 wu(e,t,n){let r=xu(n),i=bu.get(e);i?i.some(e=>e.el===t)||i.push({el:t,declarationView:r}):bu.set(e,[{el:t,declarationView:r}])}var Tu=(function(e){return e[e.CHANGE_DETECTION=0]=`CHANGE_DETECTION`,e[e.AFTER_NEXT_RENDER=1]=`AFTER_NEXT_RENDER`,e})(Tu||{}),Eu=new N(``),Du=new Set;function Ou(e){Du.has(e)||(Du.add(e),performance?.mark?.(`mark_feature_usage`,{detail:{feature:e}}))}var ku=(()=>{class e{impl=null;execute(){this.impl?.execute()}static ɵprov=ei({token:e,providedIn:`root`,factory:()=>new e})}return e})(),Au=new N(``,{factory:()=>{let e=P(ha),t=new Set;return e.onDestroy(()=>t.clear()),{queue:t,isScheduled:!1,scheduler:null,injector:e}}});function ju(e,t,n){let r=e.get(Au);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 Mu(e,t){let n=e.get(Au);if(Array.isArray(t))for(let e of t)n.queue.delete(e);else n.queue.delete(t)}function Nu(e,t){let n=e.get(Au);if(t.detachedLeaveAnimationFns){for(let e of t.detachedLeaveAnimationFns)n.queue.delete(e);t.detachedLeaveAnimationFns=void 0}}function Pu(e,t){for(let[n,r]of t)ju(e,r.animateFns)}function Fu(e,t,n,r){let i=e?.[26]?.enter;t!==null&&i&&i.has(n.index)&&Pu(r,i)}function Iu(e,t,n,r){try{n.get(Zi)}catch{return r(!1)}let i=e?.[26];i?.enter?.has(t.index)&&Mu(n,i.enter.get(t.index).animateFns);let a=Lu(e,t,i);if(a.size===0){let n=!1;if(e){let r=[];zu(e,t,r),n=r.length>0}if(!n)return r(!1)}e&&yu.add(e[19]),ju(n,()=>Ru(e,t,i||void 0,a,r),i||void 0)}function Lu(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 Ru(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&&zu(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),Vu(e,t.running,i)}else Promise.allSettled(a).then(()=>{e&&yu.delete(e[19]),i(!0)})}else e&&yu.delete(e[19]),i(!1)}function zu(e,t,n){if(t.type&12){let r=e[t.index];if(ja(r))for(let e=10;e{e[26]?.running===t&&(e[26].running=void 0,yu.delete(e[19])),n(!0)})}function Hu(e,t,n,r,i,a,o,s){if(i!=null){let c,l=!1;ja(i)?c=i:Aa(i)&&(l=!0,i=i[0]);let u=za(i);e===0&&r!==null?(Fu(s,r,a,n),o==null?Jl(t,r,u):ql(t,r,u,o||null,!0)):e===1&&r!==null?(Fu(s,r,a,n),ql(t,r,u,o||null,!0),Cu(a,u,s)):e===2?(s?.[26]?.leave?.has(a.index)&&wu(a,u,s),Su.delete(u),Iu(s,a,n,e=>{if(Su.has(u)){Su.delete(u);return}Xl(t,u,l,e)})):e===3&&(Su.delete(u),Iu(s,a,n,()=>{t.destroyNode(u)})),c!=null&&dd(t,e,n,c,a,r,o)}}function Uu(e,t){Gu(e,t),t[0]=null,t[5]=null}function Wu(e,t,n,r,i,a){r[0]=i,r[5]=t,cd(e,r,n,1,i,a)}function Gu(e,t){t[10].changeDetectionScheduler?.notify(9),cd(e,t,t[11],2,null,null)}function Ku(e){let t=e[12];if(!t)return Yu(e[1],e);for(;t;){let n=null;if(Aa(t))n=t[12];else{let e=t[10];e&&(n=e)}if(!n){for(;t&&!t[4]&&t!==e;)Aa(t)&&Yu(t[1],t),t=t[3];t===null&&(t=e),Aa(t)&&Yu(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 Ju(e,t){if(La(t))return;let n=t[11];n.destroyNode&&cd(e,t,n,3,null,null),Ku(t)}function Yu(e,t){if(La(t))return;let n=j(null);try{t[2]&=-129,t[2]|=256,t[24]&&yn(t[24]),Zu(e,t),Xu(e,t),t[1].type===1&&t[11].destroy();let n=t[16];if(n!==null&&ja(t[3])){n!==t[3]&&qu(n,t);let r=t[18];r!==null&&r.detachView(e)}ml(t)}finally{j(n)}}function Xu(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&&xd(e,t,27,!1),z(o?R.TemplateUpdateStart:R.TemplateCreateStart,i,n),n(r,i)}finally{Ko(a),z(o?R.TemplateUpdateEnd:R.TemplateCreateEnd,i,n)}}function Td(e,t,n){Md(e,t,n),(n.flags&64)==64&&Nd(e,t,n)}function Ed(e,t,n=Va){let r=t.localNames;if(r!==null){let i=t.index+1;for(let a=0;a{$a(e.lView)},consumerOnSignalRead(){this.lView[24]=this}};function rf(e){let t=e[24]??Object.create(af);return t.lView=e,t}var af={...on,consumerIsAlwaysLive:!0,kind:`template`,consumerMarkedDirty:e=>{let t=no(e.lView);for(;t&&!of(t[1]);)t=no(t);t&&Ya(t)},consumerOnSignalRead(){this.lView[24]=this}};function of(e){return e.type!==2}function sf(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 cf=100;function lf(e,t=0){let n=e[10].rendererFactory;n.begin?.();try{uf(e,t)}finally{n.end?.()}}function uf(e,t){let n=Co();try{wo(!0),gf(e,t);let n=0;for(;Za(e);){if(n===cf)throw new M(103,!1);n++,gf(e,1)}}finally{wo(n)}}function df(e,t,n,r){if(La(t))return;let i=t[2];Ro(t);let a=!0,o=null,s=null;of(e)?(s=$d(t),o=mn(s)):an()===null?(a=!1,s=rf(t),o=mn(s)):t[24]&&=(yn(t[24]),null);try{Ja(t),Do(e.bindingStartIndex),n!==null&&wd(e,t,n,2,r);let a=(i&3)==3;if(a){let n=e.preOrderCheckHooks;n!==null&&lc(t,n,null)}else{let n=e.preOrderHooks;n!==null&&uc(t,n,0,null),dc(t,0)}if(pf(t),sf(t),ff(t,0),e.contentQueries!==null&&Nl(e,t),a){let n=e.contentCheckHooks;n!==null&&lc(t,n)}else{let n=e.contentHooks;n!==null&&uc(t,n,1),dc(t,1)}vf(e,t);let o=e.components;o!==null&&_f(t,o,0);let s=e.viewQuery;if(s!==null&&Pl(2,s,r),a){let n=e.viewCheckHooks;n!==null&&lc(t,n)}else{let n=e.viewHooks;n!==null&&uc(t,n,2),dc(t,2)}if(e.firstUpdatePass===!0&&(e.firstUpdatePass=!1),t[22]){for(let e of t[22])e();t[22]=null}Zd(t),t[2]&=-73}catch(e){throw $a(t),e}finally{s!==null&&(gn(s,o),a&&tf(s)),Uo()}}function ff(e,t){for(let n=_l(e);n!==null;n=vl(n))for(let e=10;e0&&(e[n-1][4]=r[4]);let a=Hi(e,10+t);Uu(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 Tf(e,t,n,r){let i=10+r,a=n.length;r>0&&(n[i-1][4]=t),r-1&&(wf(e,n),Hi(t,n))}this._attachedToViewContainer=!1}Ju(this._lView[1],this._lView)}onDestroy(e){eo(this._lView,e)}markForCheck(){yf(this._cdRefInjectingView||this._lView,4)}detach(){this._lView[2]&=-129}reattach(){Qa(this._lView),this._lView[2]|=128}detectChanges(){this._lView[2]|=1024,lf(this._lView)}checkNoChanges(){}attachToViewContainerRef(){if(this._appRef)throw new M(902,!1);this._attachedToViewContainer=!0}detachFromAppRef(){this._appRef=null;let e=Ia(this._lView),t=this._lView[16];t!==null&&!e&&qu(t,this._lView),Gu(this._lView[1],this._lView)}attachToAppRef(e){if(this._attachedToViewContainer)throw new M(902,!1);this._appRef=e;let t=Ia(this._lView),n=this._lView[16];n!==null&&!t&&Ef(n,this._lView),Qa(this._lView)}};function Of(e,t,n,r,i){let a=e.data[t];if(a===null)a=kf(e,t,n,r,i),Ao()&&(a.flags|=32);else if(a.type&64){a.type=n,a.value=r,a.attrs=i;let e=yo();a.injectorIndex=e===null?-1:e.injectorIndex}return bo(a,!0),a}function kf(e,t,n,r,i){let a=vo(),o=xo(),s=o?a:a&&a.parent,c=e.data[t]=jf(e,s,n,t,r,i);return Af(e,c,a,o),c}function Af(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 jf(e,t,n,r,i,a){let o=t?t.injectorIndex:-1,s=0;return uo()&&(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:Zo(),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 Mf(e){let t=e[6]??[],n=e[3][11],r=[];for(let e of t)e.data.di===void 0?Nf(e,n):r.push(e);e[6]=r}function Nf(e,t){let n=0,r=e.firstChild;if(r){let i=e.data.r;for(;nnull,Ff=()=>null;function If(e,t){return Pf(e,t)}function Lf(e,t,n){return Ff(e,t,n)}var Rf=class{},zf=class{},Bf=(()=>{class e{static ɵprov=ei({token:e,providedIn:`root`,factory:()=>null})}return e})();function Vf(e){return e.debugInfo?.className||e.type.name||null}var Hf={},Uf=class{injector;parentInjector;constructor(e,t){this.injector=e,this.parentInjector=t}get(e,t,n){let r=this.injector.get(e,Hf,n);return r!==Hf||t===Hf?r:this.parentInjector.get(e,t,n)}};function Wf(e,t,n){return e[t]=n}function Gf(e,t){return e[t]}function Kf(e,t,n){if(n===hu)return!1;let r=e[t];return!Object.is(r,n)&&(e[t]=n,!0)}function qf(e,t,n,r){let i=Kf(e,t,n);return Kf(e,t+1,r)||i}function Jf(e,t,n,r,i){let a=qf(e,t,n,r);return Kf(e,t+2,i)||a}function Yf(e,t,n){return function r(i){let a=r.__ngNativeEl__;a!==void 0&&Dl(i,a),yf(Na(e)?Ga(e.index,t):t,5);let o=t[8],s=Xf(t,o,n,i),c=r.__ngNextListenerFn__;for(;c;)s=Xf(t,o,c,i)&&s,c=c.__ngNextListenerFn__;return s}}function Xf(e,t,n,r){let i=j(null);try{return z(R.OutputStart,t,n),n(r)!==!1}catch(t){return Vd(e,t),!1}finally{z(R.OutputEnd,t,n),j(i)}}function Zf(e,t,n,r,i,a,o,s){let c=Pa(e),l=!1,u=null;if(!r&&c&&(u=$f(t,n,a,e.index)),u!==null){let e=u.__ngLastListenerFn__||u;e.__ngNextListenerFn__=o,u.__ngLastListenerFn__=o,l=!0}else{let o=Va(e,n),c=r?r(o):o;r||(s.__ngNativeEl__=o);let l=i.listen(c,a,s);Qf(a)||ep(r?t=>r(za(t[e.index])):e.index,t,n,a,s,l,!1)}return l}function Qf(e){return e.startsWith(`animation`)||e.startsWith(`transition`)}function $f(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 ep(e,t,n,r,i,a,o){let s=t.firstCreatePass?io(t):null,c=ro(n),l=c.length;c.push(i,a),s&&s.push(r,e,l,(l+1)*(o?-1:1))}function tp(e,t,n,r,i,a){let o=t[n],s=t[1],c=o[s.data[n].outputs[r]].subscribe(a);ep(e.index,s,t,i,a,c,!0)}var np=Symbol(`BINDING`),rp=new N(``);function ip(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 vp(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&Sd.SignalBased)!==0};return i&&(a.transform=i),a})}function Ep(e){return Object.keys(e).map(t=>({propName:e[t],templateName:t}))}function Dp(e,t,n){let r=t instanceof ha?t:t?.injector;return r&&e.getStandaloneInjector!==null&&(r=e.getStandaloneInjector(r)||r),r?new Uf(n,r):n}function Op(e){let t=e.get(zf,null);if(t===null)throw new M(407,!1);return{rendererFactory:t,sanitizer:e.get(Bf,null),changeDetectionScheduler:e.get(Bs,null),ngReflect:!1,tracingService:e.get(Eu,null,{optional:!0})}}function kp(e,t,n){let r=jp(e);return Kl(t,r,r===`svg`?`svg`:r===`math`?Ra:n)}function Ap(e){if((e&&`localName`in e&&typeof e.localName==`string`?e.localName:e?.tagName)?.toLowerCase()===`script`)throw new M(905,!1)}function jp(e){return(e.selectors[0][0]||`div`).toLowerCase()}var Mp=class{componentDef;ngModule;selector;componentType;ngContentSelectors;isBoundToModule;cachedInputs=null;cachedOutputs=null;get inputs(){return this.cachedInputs??=Tp(this.componentDef.inputs),this.cachedInputs}get outputs(){return this.cachedOutputs??=Ep(this.componentDef.outputs),this.cachedOutputs}constructor(e,t){this.componentDef=e,this.ngModule=t,this.componentType=e.type,this.selector=pu(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=Dp(s,r||this.ngModule,e),l=Op(c),u=l.tracingService;return u&&u.componentCreate?u.componentCreate(Vf(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=Np(r,s,a,i),l=e.rendererFactory.createRenderer(null,s),u=r?Dd(l,r,s.encapsulation,t):kp(s,l,o??null);Ap(u);let d=t.get(rp,null),f=Pp(u,()=>t.get(is,null)??Sl());d&&d.addHost(f);let p=a?.some(Ip)||i?.some(e=>typeof e!=`function`&&e.bindings.some(Ip)),m=gd(null,c,null,512|vd(s),null,null,e,l,t,null,jl(u,t,!0));d&&Cp&&f instanceof ShadowRoot&&eo(m,()=>{d.removeHost(f)}),m[27]=u,Ro(m);let h=null;try{let e=bp(27,m,2,`#host`,()=>c.directiveRegistry,!0,0);$l(l,u,e),gl(u,m),Td(c,m,e),Fl(c,e,m),xp(c,e),n!==void 0&&Rp(e,this.ngContentSelectors,n),h=Ga(e.index,m),m[8]=h[8],Gd(c,m,null)}catch(e){throw h!==null&&ml(h),ml(m),e}finally{z(R.DynamicComponentEnd),Uo()}return new Lp(this.componentType,m,!!p)}};function Np(e,t,n,r){let i=e?[`ng-version`,`22.1.7`]:mu(t.selectors[0]),a=null,o=null,s=0;if(n)for(let e of n)s+=e[np].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 Ip(e){let t=e[np].kind;return t===`input`||t===`twoWay`}var Lp=class extends Rf{_rootLView;_hasInputBindings;instance;hostView;changeDetectorRef;componentType;location;previousInputValues=null;_tNode;constructor(e,t,n){super(),this._rootLView=t,this._hasInputBindings=n,this._tNode=Ha(t[1],27),this.location=ol(this._tNode,t),this.instance=Ga(this._tNode.index,t)[8],this.hostView=this.changeDetectorRef=new Df(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;Hd(n,r[1],r,e,t),this.previousInputValues.set(e,t),yf(Ga(n.index,r),1)}get injector(){return new Xc(this._tNode,this._rootLView)}destroy(){this.hostView.destroy()}onDestroy(e){this.hostView.onDestroy(e)}};function Rp(e,t,n){let r=e.projection=[];for(let e=0;e!1;function Bp(e,t,n){return zp(e,t,n)}function Vp(e){return!!e&&typeof e.then==`function`}function Hp(e){return!!e&&typeof e.subscribe==`function`}var Up=class{},Wp=class extends Up{injector;instance=null;constructor(e){super();let t=new ga([...e.providers,{provide:Up,useValue:this}],e.parent||ma(),e.debugName,new Set([`environment`]));this.injector=t,e.runEnvironmentInitializers&&t.resolveInjectorInitializers()}destroy(){this.injector.destroy()}onDestroy(e){this.injector.onDestroy(e)}};function Gp(e,t,n=null){return new Wp({providers:e,parent:t,debugName:n,runEnvironmentInitializers:!0}).injector}var Kp=(()=>{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=ta(!1,e.type),n=t.length>0?Gp([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=ei({token:e,providedIn:`environment`,factory:()=>new e(Pi(ha))})}return e})();function qp(e){return nc(()=>{let t=Qp(e),n={...t,decls:e.decls,vars:e.vars,template:e.template,consts:e.consts||null,ngContentSelectors:e.ngContentSelectors,onPush:e.changeDetection!==ll.Eager,directiveDefs:null,pipeDefs:null,dependencies:t.standalone&&e.dependencies||null,getStandaloneInjector:t.standalone?e=>e.get(Kp).getOrCreateStandaloneInjector(n):null,getExternalStyles:null,signals:e.signals??!1,data:e.data||{},encapsulation:e.encapsulation||Il.Emulated,styles:e.styles||Yi,_:null,schemas:e.schemas||null,tView:null,id:``};t.standalone&&Ou(`NgStandalone`),$p(n);let r=e.dependencies;return n.directiveDefs=em(r,Jp),n.pipeDefs=em(r,gi),n.id=tm(n),n})}function Jp(e){return mi(e)||hi(e)}function Yp(e,t){if(e==null)return Ji;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=Sd.None,c=null),n[a]=[r,s,c],t[a]=o}return n}function Xp(e){if(e==null)return Ji;let t={};for(let n in e)Object.hasOwn(e,n)&&(t[e[n]]=n);return t}function Zp(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 Qp(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||Ji,exportAs:e.exportAs||null,standalone:e.standalone??!0,signals:e.signals===!0,selectors:e.selectors||Yi,viewQuery:e.viewQuery||null,features:e.features||null,setInput:null,resolveHostDirectives:null,hostDirectives:null,controlDef:null,signalFormsInputPresence:null,inputs:Yp(e.inputs,t),outputs:Xp(e.outputs),debugInfo:null}}function $p(e){e.features?.forEach(t=>t(e))}function em(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 tm(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 nm=new N(``),rm=(()=>{class e{resolve;reject;initialized=!1;done=!1;donePromise=new Promise((e,t)=>{this.resolve=e,this.reject=t});appInits=P(nm,{optional:!0})??[];injector=P(rs);constructor(){}runInitializers(){if(this.initialized)return;let e=[];for(let t of this.appInits){let n=Da(this.injector,t);if(Vp(n))e.push(n);else if(Hp(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=il({token:e,factory:e.ɵfac})}return e})();function im(e,t,n,r,i,a,o,s){if(n.firstCreatePass){e.mergedAttrs=Sc(e.mergedAttrs,e.attrs);let t=e.tView=pd(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),bo(e,!1);let c=sm(n,t,e,r);$o()&&rd(n,t,c,e),gl(c,t);let l=bf(c,t,c,e);t[r+27]=l,bd(t,l),Bp(l,e,t)}function am(e,t,n,r,i,a,o,s,c,l,u){let d=n+27,f;if(t.firstCreatePass){if(f=Of(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?Gp(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=ei({token:e,providedIn:`environment`,factory:()=>new e})}return e})(),Lm=new N(``);function Rm(e,t,n){return e.get(Im).getOrCreateInjector(t,e,n,``)}function zm(e,t,n){if(e instanceof Uf){let r=e.injector,i=e.parentInjector;return new Uf(r,Rm(i,t,n))}let r=e.get(ha);return r===e?Rm(e,t,n):new Uf(e,Rm(r,t,n))}function Bm(e,t,n,r=!1){let i=n[3],a=i[1];if(La(i))return;let o=Dm(i,t),s=o[1],c=o[vm];if(!(c!==null&&ee.data.s===t[1])??-1;return{dehydratedView:n>-1?e[6][n]:null,dehydratedViewIx:n}}function Hm(e,t,n,r,i){z(R.DeferBlockStateStart);let a=jm(e,i,r);if(a!==null){t[1]=e;let o=i[1],s=Ha(o,a+27);Cf(n,0);let c;if(e===fm.Complete){let e=km(o,r),t=e.providers;t&&t.length>0&&(c=zm(i[9],e,t))}let{dehydratedView:l,dehydratedViewIx:u}=Vm(n,t),d=qd(i,s,null,{injector:c,dehydratedView:l});if(Sf(n,d,0,Jd(s,l)),Ya(d),u>-1&&n[6]?.splice(u,1),(e===fm.Complete||e===fm.Error)&&Array.isArray(t[ym])){for(let e of t[ym])e();t[ym]=null}}z(R.DeferBlockStateEnd)}function Um(e,t){return e{e.loadingState===lm.COMPLETE?Bm(fm.Complete,t,n):e.loadingState===lm.FAILED&&Bm(fm.Error,t,n)})}var Km=null;function qm(e,t){return t[9].get(Lm,null,{optional:!0})?.behavior!==xm.Manual}var Jm=new N(``),Ym=new N(``);function Xm(){Nn(()=>{throw new M(600,``)})}var Zm=10,Qm=(()=>{class e{_runningTick=!1;_destroyed=!1;_destroyListeners=[];_views=[];internalErrorHandler=P(As);afterRenderManager=P(ku);zonelessEnabled=P(Vs);rootEffectScheduler=P(Us);dirtyFlags=0;tracingSnapshot=null;allTestViews=new Set;autoDetectTestViews=new Set;includeAllTestViews=!1;afterTick=new Br;get allViews(){return[...(this.includeAllTestViews?this.allTestViews:this.autoDetectTestViews).keys(),...this._views]}get destroyed(){return this._destroyed}componentTypes=[];components=[];internalPendingTask=P(ls);get isStable(){return this.internalPendingTask.hasPendingTasksObservable.pipe(Ur(e=>!e))}constructor(){P(Eu,{optional:!0})}whenStable(){let e;return new Promise(t=>{e=this.isStable.subscribe({next:e=>{e&&t()}})}).finally(()=>{e.unsubscribe()})}_injector=P(ha);_rendererFactory=null;get injector(){return this._injector}bootstrap(e,t){return this.bootstrapImpl(e,t)}bootstrapImpl(e,t,n=rs.NULL){return this._injector.get(_s).run(()=>{if(z(R.BootstrapComponentStart),!this._injector.get(rm).done)throw new M(405,``);let r=mi(e),i=this._injector.get(Up),a=new Mp(r,i);this.componentTypes.push(e);let{hostElement:o,directives:s,bindings:c}=$m(t),l=o||a.selector,u=a.create(n,[],l,i.injector,s,c),d=u.location.nativeElement,f=u.injector.get(Jm,null);return f?.registerApplication(d),u.onDestroy(()=>{this.detachView(u.hostView),eh(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(Tu.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(zf,null,{optional:!0}));let e=0;for(;this.dirtyFlags!==0&&e++Za(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;eh(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(Ym,[]).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),()=>eh(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=il({token:e,factory:e.ɵfac})}return e})();function $m(e){return e===void 0||typeof e==`string`||e instanceof Element?{hostElement:e}:e}function eh(e,t){let n=e.indexOf(t);n>-1&&e.splice(n,1)}function th(e,t,n){let r=t.get(rh);return r.add(e,n),()=>r.remove(e)}function nh(e){return(t,n)=>th(t,n,e)}var rh=(()=>{class e{buckets=new Map;callbackBucket=new Map;applicationRef=P(Qm);ngZone=P(_s);idleService=P(nl);add(e,t){let n=ih(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=ih(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=ei({token:e,providedIn:`root`,factory:()=>new e})}return e})();function ih(e){return!e||e.timeout==null?``:`${e.timeout}`}function ah(e){let t=I(),n=_o();if(Wm(t,n),!qm(0,t))return;let r=t[9];Sm(0,Dm(t,n),e(()=>sh(0,t,n),r))}function oh(e,t,n){let r=t[9],i=t[1];if(e.loadingState!==lm.NOT_STARTED)return e.loadingPromise??Promise.resolve();let a=Dm(t,n),o=Fm(i,e);e.loadingState=lm.IN_PROGRESS,Cm(1,a);let s=e.dependencyResolverFn,c=r.get($s).add();return s?(e.loadingPromise=Promise.allSettled(s()).then(n=>{let r=!1,i=[],a=[];for(let e=0;e0&&(t.directiveRegistry=Pm(t.directiveRegistry,i),e.providers=ta(!1,...i.map(e=>e.type))),a.length>0&&(t.pipeRegistry=Pm(t.pipeRegistry,a))}}),e.loadingPromise.finally(()=>{e.loadingPromise=null,c()})):(e.loadingPromise=Promise.resolve().then(()=>{e.loadingPromise=null,e.loadingState=lm.COMPLETE,c()}),e.loadingPromise)}function sh(e,t,n){let r=t[1],i=t[n.index];if(!qm(e,t))return;let a=Dm(t,n),o=km(r,n);switch(wm(a),o.loadingState){case lm.NOT_STARTED:Bm(fm.Loading,n,i),oh(o,t,n),o.loadingState===lm.IN_PROGRESS&&Gm(o,n,i);break;case lm.IN_PROGRESS:Bm(fm.Loading,n,i),Gm(o,n,i);break;case lm.COMPLETE:Bm(fm.Complete,n,i);break;case lm.FAILED:Bm(fm.Error,n,i)}}function ch(e,t,n){return e===0?uh(t,n):e!==2||!uh(t,n)}function lh(e){return e!=null&&(e&1)==1}function uh(e,t){let n=e[9],r=km(e[1],t),i=Ml(n),a=lh(r.flags),o=Dm(e,t)[_m]!==null;return!(a&&o&&i)}function dh(e,t,n,r,i,a,o,s,c,l){let u=I(),d=mo(),f=e+27,p=am(u,d,e,null,0,0),m=u[9],h=Ml(m);if(d.firstCreatePass){Ou(`NgDefer`);let e={primaryTmplIndex:t,loadingTmplIndex:r??null,placeholderTmplIndex:i??null,errorTmplIndex:a??null,placeholderBlockConfig:null,loadingBlockConfig:null,dependencyResolverFn:n??null,loadingState:lm.NOT_STARTED,loadingPromise:null,providers:null,hydrateTriggers:null,debug:null,flags:l??0};c?.(d,e,s,o),Am(d,f,e)}let g=u[f];Bp(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,pm.Initial,null,null,null,null,v,_,null,null];Om(u,f,y);let b=null;v!==null&&h&&(b=m.get(Ol),b.add(v,{lView:u,tNode:p,lContainer:g}));let ee=()=>{wm(y),v!==null&&b?.cleanup([v])};Sm(0,y,()=>to(u,ee)),eo(u,ee)}function fh(e){ch(0,I(),_o())&&ah(nh({timeout:e}))}function ph(e,t,n,r){let i=I();return Kf(i,Oo(),t)&&(mo(),Id(qo(),i,e,t,n,r)),ph}var mh=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 hh(e,t,n,r,i){return e===n&&Object.is(t,r)?1:Object.is(i(e,t),i(n,r))?-1:0}function gh(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=hh(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=hh(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 bh,a??=yh(e,o,s,n),_h(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;)vh(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=hh(o,t,o,r,n);if(u!==0)u<0&&e.updateValue(o,r),o++,l=c.next();else{i??=new bh,a??=yh(e,o,s,n);let u=n(o,r);if(_h(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;)vh(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 _h(e,t,n,r){return t!==void 0&&t.has(r)?(e.attach(n,t.get(r)),t.delete(r),!0):!1}function vh(e,t,n,r,i){if(_h(e,t,r,n(r,i)))e.updateValue(r,i);else{let t=e.create(r,i);e.attach(r,t)}}function yh(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 bh=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){Ou(`NgControlFlow`);let c=I(),l=mo();return am(c,l,e,t,n,r,i,qa(l.consts,a),256,o,s),xh}function xh(e,t,n,r,i,a,o,s){Ou(`NgControlFlow`);let c=I(),l=mo();return am(c,l,e,t,n,r,i,qa(l.consts,a),512,o,s),xh}function H(e,t){Ou(`NgControlFlow`);let n=I(),r=Oo(),i=n[r]===hu?-1:n[r],a=i===-1?void 0:Dh(n,27+i);if(Kf(n,r,e)){let r=j(null);try{if(a!==void 0&&Cf(a,0),e!==-1){let r=27+e,i=Dh(n,r),a=Mh(n[1],r),o=Lf(i,a,n);Sf(i,qd(n,a,t,{dehydratedView:o}),0,Jd(a,o))}}finally{j(r)}}else if(a!==void 0){let e=xf(a,0);e!==void 0&&(e[8]=t)}}var Sh=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 Ch(e){return e}function wh(e,t){return t}var Th=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){Ou(`NgControlFlow`);let p=I(),m=mo(),h=c!==void 0,g=I(),_=new Th(h,s?o.bind(g[15][8]):o);g[27+e]=_,am(p,m,e+1,t,n,r,i,qa(m.consts,a),256),h&&am(p,m,e+2,c,l,u,d,qa(m.consts,f),512)}var Eh=class extends mh{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,Sf(this.lContainer,t,e,Jd(this.templateTNode,n)),Oh(this.lContainer,e)}detach(e){return this.needsIndexUpdate||=e!==this.length-1,kh(this.lContainer,e),Ah(this.lContainer,e)}create(e,t){let n=If(this.lContainer,this.templateTNode.tView.ssrId);return qd(this.hostLView,this.templateTNode,new Sh(this.lContainer,t,e),{dehydratedView:n})}destroy(e){Ju(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];Nu(e,r),yu.delete(n[19]),r.detachedLeaveAnimationFns=void 0}}function kh(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 Ah(e,t){return wf(e,t)}function jh(e,t){return xf(e,t)}function Mh(e,t){return Ha(e,t)}function Nh(e,t,n){let r=I();return Kf(r,Oo(),t)&&(mo(),kd(qo(),r,e,t,r[11],n)),Nh}function Ph(e,t,n,r,i){Hd(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?bp(o,i,2,t,Fd,lo(),n,r):a.data[o];if(Na(s)){let n=i[10].tracingService;if(n&&n.componentCreate){let o=a.data[s.directiveStart+s.componentOffset];return n.componentCreate(Vf(o),()=>(Fh(e,t,i,s,r),G))}}return Fh(e,t,i,s,r),G}function Fh(e,t,n,r,i){if(zd(r,n,e,t,Rh),Pa(r)){let e=n[1];Td(e,n,r),Fl(e,r,n)}i!=null&&Ed(n,r)}function K(){let e=mo(),t=Bd(_o());return e.firstCreatePass&&xp(e,t),fo(t)&&po(),co(),t.classesWithoutHost!=null&&_c(t)&&Ph(e,t,I(),t.classesWithoutHost,!0),t.stylesWithoutHost!=null&&vc(t)&&Ph(e,t,I(),t.stylesWithoutHost,!1),K}function Ih(e,t,n,r){return G(e,t,n,r),K(),Ih}function q(e,t,n,r){let i=I(),a=i[1],o=e+27,s=a.firstCreatePass?Sp(o,a,2,t,n,r):a.data[o];return zd(s,i,e,t,Rh),r!=null&&Ed(i,s),q}function J(){return fo(Bd(_o()))&&po(),co(),J}function Lh(e,t,n,r){return q(e,t,n,r),J(),Lh}var Rh=(e,t,n,r,i)=>(es(!0),Kl(t[11],r,Zo()));function zh(){let e=mo(),t=Bd(_o());return e.firstCreatePass&&xp(e,t),zh}function Bh(e,t,n){let r=I(),i=r[1],a=e+27,o=i.firstCreatePass?Sp(a,i,8,`ng-container`,t,n):i.data[a];return zd(o,r,e,`ng-container`,Uh),n!=null&&Ed(r,o),Bh}function Vh(){return Bd(_o()),zh}function Hh(e,t,n){return Bh(e,t,n),Vh(),Hh}var Uh=(e,t,n,r,i)=>(es(!0),Gl(t[11],``));function Wh(){return I()}function Gh(e,t,n){let r=I();return Kf(r,Oo(),t)&&(mo(),Ad(qo(),r,e,t,r[11],n)),Gh}var Kh=`en-US`;function qh(e){typeof e==`string`&&e.toLowerCase().replace(/_/g,`-`)}function Jh(e,t,n){let r=I(),i=mo(),a=_o();return Yh(i,r,r[11],a,e,t,n),Jh}function Y(e,t,n){let r=I(),i=mo(),a=_o();return(a.type&3||n)&&Zf(a,i,r,n,r[11],e,t,Yf(a,r,t)),Y}function Yh(e,t,n,r,i,a,o){let s=!0,c=null;if((r.type&3||o)&&(c??=Yf(r,t,a),Zf(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 Qh(e){return(e&2)==2}function $h(e,t){return e&131071|t<<17}function eg(e){return e|2}function tg(e){return(e&131068)>>2}function ng(e,t){return e&-131069|t<<2}function rg(e){return(e&1)==1}function ig(e){return e|1}function ag(e,t,n,r,i,a){let o=a?t.classBindings:t.styleBindings,s=Zh(o),c=tg(o);e[r]=n;let l=!1,u;if(Array.isArray(n)){let e=n;u=e[1],(u===null||Ki(e,u)>0)&&(l=!0)}else u=n;if(i){if(c!==0){let t=Zh(e[s+1]);e[r+1]=Xh(t,s),t!==0&&(e[t+1]=ng(e[t+1],r)),e[s+1]=$h(e[s+1],r)}else e[r+1]=Xh(s,0),s!==0&&(e[s+1]=ng(e[s+1],r)),s=r}else e[r+1]=Xh(c,0),s===0?s=r:e[c+1]=ng(e[c+1],r),c=r;l&&(e[r+1]=eg(e[r+1])),sg(e,u,r,!0),sg(e,u,r,!1),og(t,u,e,r,a),o=Xh(s,c),a?t.classBindings=o:t.styleBindings=o}function og(e,t,n,r,i){let a=i?e.residualClasses:e.residualStyles;a!=null&&typeof t==`string`&&Ki(a,t)>=0&&(n[r+1]=ig(n[r+1]))}function sg(e,t,n,r){let i=e[n+1],a=t===null,o=r?Zh(i):tg(i),s=!1;for(;o!==0&&(s===!1||a);){let n=e[o],i=e[o+1];cg(n,t)&&(s=!0,e[o+1]=r?ig(i):eg(i)),o=r?Zh(i):tg(i)}s&&(e[n+1]=r?eg(i):ig(i))}function cg(e,t){return e===null||t==null||(Array.isArray(e)?e[1]:e)===t?!0:Array.isArray(e)&&typeof t==`string`?Ki(e,t)>=0:!1}function lg(e,t,n){return dg(e,t,n,!1),lg}function ug(e,t){return dg(e,t,null,!0),ug}function dg(e,t,n,r){let i=I(),a=mo(),o=ko(2);if(a.firstUpdatePass&&pg(a,e,o,r),t!==hu&&Kf(i,o,t)){let s=a.data[Go()];bg(a,s,i,i[11],e,i[o+1]=Cg(t,n),r,o)}}function fg(e,t){return t>=e.expandoStartIndex}function pg(e,t,n,r){let i=e.data;if(i[n+1]===null){let a=i[Go()],o=fg(e,n);wg(a,r)&&t===null&&!o&&(t=!1),t=mg(i,a,t,r),ag(i,a,t,n,o,r)}}function mg(e,t,n,r){let i=Po(e),a=r?t.residualClasses:t.residualStyles;if(i===null)(r?t.classBindings:t.styleBindings)===0&&(n=vg(null,e,t,n,r),n=yg(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=hg(e,t,r);n!==void 0&&Array.isArray(n)&&(n=vg(null,e,t,n[1],r),n=yg(n,t.attrs,r),gg(e,t,r,n))}else a=_g(e,t,r)}}return a!==void 0&&(r?t.residualClasses=a:t.residualStyles=a),n}function hg(e,t,n){let r=n?t.classBindings:t.styleBindings;if(tg(r)!==0)return e[Zh(r)]}function gg(e,t,n,r){let i=n?t.classBindings:t.styleBindings;e[Zh(i)]=r}function _g(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===hu&&(u=l?Yi:void 0);let d=l?Gi(u,r):c===r?u:void 0;if(a&&!Sg(d)&&(d=Gi(t,r)),Sg(d)&&(s=d,o))return s;let f=e[i+1];i=o?Zh(f):tg(f)}if(t!==null){let e=a?t.residualClasses:t.residualStyles;e!=null&&(s=Gi(e,r))}return s}function Sg(e){return e!==void 0}function Cg(e,t){return e==null||e===``||(typeof t==`string`?e=Rl(e)+t:typeof e==`object`&&(e=Jr(Rl(e)))),e}function wg(e,t){return!!(e.flags&(t?8:16))}function Z(e,t=``){let n=I(),r=mo(),i=e+27,a=r.firstCreatePass?Of(r,i,1,t,null):r.data[i],o=Tg(r,n,a,t);n[i]=o,$o()&&rd(r,n,o,a),bo(a,!1)}var Tg=(e,t,n,r)=>(es(!0),Ul(t[11],r));function Eg(e,t,n,r=``){return Kf(e,Oo(),n)?t+vi(n)+r:hu}function Dg(e,t,n,r,i,a=``){let o=qf(e,Eo(),n,i);return ko(2),o?t+vi(n)+r+vi(i)+a:hu}function Og(e,t,n,r,i,a,o,s=``){let c=Jf(e,Eo(),n,i,o);return ko(3),c?t+vi(n)+r+vi(i)+a+vi(o)+s:hu}function Q(e){return $(``,e),Q}function $(e,t,n){let r=I(),i=Eg(r,e,t,n);return i!==hu&&jg(r,Go(),i),$}function kg(e,t,n,r,i){let a=I(),o=Dg(a,e,t,n,r,i);return o!==hu&&jg(a,Go(),o),kg}function Ag(e,t,n,r,i,a,o){let s=I(),c=Og(s,e,t,n,r,i,a,o);return c!==hu&&jg(s,Go(),c),Ag}function jg(e,t,n){let r=Ba(t,e);Wl(e[11],r,n)}function Mg(e,t){let n=To()+e,r=I();return r[n]===hu?Wf(r,n,t()):Gf(r,n)}function Ng(e,t){let n=e[t];return n===hu?void 0:n}function Pg(e,t,n,r,i,a){let o=t+n;return Kf(e,o,i)?Wf(e,o+1,a?r.call(a,i):r(i)):Ng(e,o+1)}function Fg(e,t){let n=mo(),r,i=e+27;n.firstCreatePass?(r=Ig(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=zi(r.type,!0)),o=Oi(ap);try{let e=kc(!1),t=a();return kc(e),Wa(n,I(),i,t),t}finally{Oi(o)}}function Ig(e,t){if(t)for(let n=t.length-1;n>=0;n--){let r=t[n];if(e===r.name)return r}}function Lg(e,t,n){let r=e+27,i=I(),a=Ua(i,r);return Rg(i,r)?Pg(i,To(),t,a.transform,n,a):a.transform(n)}function Rg(e,t){return e[1].data[t].pure}var zg=(()=>{class e{applicationErrorHandler=P(As);appRef=P(Qm);taskService=P(ls);ngZone=P(_s);zonelessEnabled=P(Vs);tracing=P(Eu,{optional:!0});zoneIsDefined=typeof Zone<`u`&&!!Zone.root.run;schedulerTickApplyArgs=[{data:{__scheduler_tick__:!0}}];subscriptions=new ir;angularZoneId=this.zoneIsDefined?this.ngZone._inner?.get(hs):null;scheduleInRootZone=!this.zonelessEnabled&&this.zoneIsDefined&&(P(Hs,{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?ps:fs;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=il({token:e,factory:e.ɵfac})}return e})();function Bg(){return[{provide:Bs,useExisting:zg},{provide:_s,useClass:Ts},{provide:Vs,useValue:!0}]}function Vg(){return typeof $localize<`u`&&$localize.locale||`en-US`}var Hg=new N(``,{factory:()=>P(Hg,{optional:!0,skipSelf:!0})||Vg()}),Ug=class{destroyed=!1;listeners=null;errorHandler=P(ks,{optional:!0});isEmitting=!1;hasNullListeners=!1;destroyRef=P(as);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(Kr(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&&Wg(this.listeners)),j(t),this.isEmitting=!1}}};function Wg(e){let t=e.length-1;for(;t>-1;)e[t]===null&&e.splice(t,1),t--}function Gg(e,t){return Tn(e,t?.equal)}function Kg(e){return Jn(e)}(class e extends Error{_brand;constructor(e){super(e)}static IDLE=new e(`IDLE`);static LOADING=new e(`LOADING`)});function qg(e,t){let n=Object.create(tc);n.value=e,n.transformFn=t?.transform;function r(){if(sn(n),n.value===ec)throw new M(-950,null);return n.value}return r[rn]=n,r}function Jg(e){return new Ug}function Yg(e,t){return qg(e,t)}function Xg(e){return qg(ec,e)}var Zg=(Yg.required=Xg,Yg),Qg=new N(``),$g=new N(``);function e_(e){return!e.moduleRef}function t_(e){let t=e_(e)?e.r3Injector:e.moduleRef.injector,n=t.get(_s);return n.run(()=>{e_(e)?e.r3Injector.resolveInjectorInitializers():e.moduleRef.resolveInjectorInitializers();let r=t.get(As),i;if(n.runOutsideAngular(()=>{i=n.onError.subscribe({next:r})}),e_(e)){let n=()=>t.destroy(),r=e.platformInjector.get(Qg);r.add(n),t.onDestroy(()=>{i.unsubscribe(),r.delete(n)})}else{let t=()=>e.moduleRef.destroy(),n=e.platformInjector.get(Qg);n.add(t),e.moduleRef.onDestroy(()=>{eh(e.allPlatformModules,e.moduleRef),i.unsubscribe(),n.delete(t)})}return r_(r,n,()=>{let n=t.get(ls),r=n.add(),i=t.get(rm);return i.runInitializers(),i.donePromise.then(()=>{if(qh(t.get(Hg,Kh)||`en-US`),!t.get($g,!0))return e_(e)?t.get(Qm):(e.allPlatformModules.push(e.moduleRef),e.moduleRef);if(e_(e)){let n=t.get(Qm);return e.rootComponent!==void 0&&n.bootstrap(e.rootComponent),n}return n_?.(e.moduleRef,e.allPlatformModules),e.moduleRef}).finally(()=>void n.remove(r))})})}var n_;function r_(e,t,n){try{let r=n();return Vp(r)?r.catch(n=>{throw t.runOutsideAngular(()=>e(n)),n}):r}catch(n){throw t.runOutsideAngular(()=>e(n)),n}}var i_=null;function a_(e=[],t){return rs.create({name:t,providers:[{provide:ua,useValue:`platform`},{provide:Qg,useValue:new Set([()=>i_=null])},...e]})}function o_(e=[]){if(i_)return i_;let t=a_(e);return i_=t,Xm(),s_(t),t}function s_(e){let t=e.get(Fs,null);Da(e,()=>{t?.forEach(e=>e())})}function c_(e){let{rootComponent:t,appProviders:n,platformProviders:r,platformRef:i}=e;z(R.BootstrapApplicationStart);try{let e=i?.injector??o_(r);return t_({r3Injector:new Wp({providers:[Bg(),js,...n||[]],parent:e,debugName:``,runEnvironmentInitializers:!1}).injector,platformInjector:e,rootComponent:t})}catch(e){return Promise.reject(e)}finally{z(R.BootstrapApplicationEnd)}}var l_=null;function u_(){return l_}function d_(e){l_??=e}var f_=class{},p_=(()=>{class e{transform(e){return JSON.stringify(e,null,2)}static ɵfac=function(t){return new(t||e)};static ɵpipe=Zp({name:`json`,type:e,pure:!1})}return e})();function m_(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 h_=`browser`,g_=class{_doc;constructor(e){this._doc=e}manager},__=(()=>{class e extends g_{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)(Pi(is))};static ɵprov=ei({token:e,factory:e.ɵfac})}return e})(),v_=new N(``),y_=(()=>{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 __));this._plugins=n.slice().reverse();let r=e.find(e=>e instanceof __);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)(Pi(v_),Pi(_s))};static ɵprov=ei({token:e,factory:e.ɵfac})}return e})(),b_=`ng-app-id`;function x_(e){for(let t of e)t.remove()}function S_(e,t){let n=t.createElement(`style`);return n.textContent=e,n}function C_(e,t,n,r){let i=e.head?.querySelectorAll(`style[${b_}="${t}"],link[${b_}="${t}"]`);if(!i||i.length===0)return!1;for(let e of i)e.removeAttribute(b_),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 w_(e,t){let n=t.createElement(`link`);return n.setAttribute(`rel`,`stylesheet`),n.setAttribute(`href`,e),n}var T_=(()=>{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,C_(e,t,this.inline,this.external)&&this.hosts.add(e.head)}addStyles(e,t){for(let t of e)this.addUsage(t,this.inline,S_);t?.forEach(e=>this.addUsage(e,this.external,w_))}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&&(x_(n.elements),t.delete(e)))}ngOnDestroy(){for(let[,{elements:e}]of[...this.inline,...this.external])x_(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,S_(t,this.doc)));for(let[t,{elements:n}]of this.external)n.push(this.addElement(e,w_(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)(Pi(is),Pi(Ns),Pi(Ls,8),Pi(Is))};static ɵprov=ei({token:e,factory:e.ɵfac})}return e})(),E_={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`},D_=/%COMP%/g,O_=`%COMP%`,k_=`_nghost-${O_}`,A_=`_ngcontent-${O_}`,j_=!0,M_=new N(``,{factory:()=>j_}),N_=new N(``);function P_(e){return A_.replace(D_,e)}function F_(e){return k_.replace(D_,e)}function I_(e,t){return t.map(t=>t.replace(D_,e))}var L_=(()=>{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 R_(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 H_?n.applyToHost(e):n instanceof V_&&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 Il.Emulated:r=new H_(o,s,t,this.appId,c,i,a,l,this.cssVarNamespace);break;case Il.ShadowDom:return new B_(o,e,t,i,a,this.nonce,l,this.cssVarNamespace,s);case Il.ExperimentalIsolatedShadowDom:return new B_(o,e,t,i,a,this.nonce,l,this.cssVarNamespace);default:r=new V_(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)(Pi(y_),Pi(rp),Pi(Ns),Pi(M_),Pi(is),Pi(_s),Pi(Ls),Pi(Eu,8),Pi(N_,8))};static ɵprov=ei({token:e,factory:e.ɵfac})}return e})(),R_=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(E_[t]||t,e):this.doc.createElement(e)}createComment(e){return this.doc.createComment(e)}createText(e){return this.doc.createTextNode(e)}appendChild(e,t){(z_(e)?e.content:e).appendChild(t)}insertBefore(e,t,n){if(e){let r=z_(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=E_[r];i?e.setAttributeNS(i,t,n):e.setAttribute(t,n)}else e.setAttribute(t,n)}removeAttribute(e,t,n){if(n){let r=E_[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&(gu.DashCase|gu.Important)?e.style.setProperty(t,n,r&gu.Important?`important`:``):e.style[t]=n}removeStyle(e,t,n){let r=t.startsWith(`--`);r&&(t=t.replace(`%NS%`,this.cssVarNamespace)),r||n&gu.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=u_().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 z_(e){return e.tagName===`TEMPLATE`&&e.content!==void 0}var B_=class extends R_{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=I_(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=w_(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)}},V_=class extends R_{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?I_(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&&yu.size===0&&this.sharedStylesHost.removeStyles(this.styles,this.styleUrls)}},H_=class extends V_{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=P_(l),this.hostAttr=F_(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}},U_=class e extends f_{supportsDOMEvents=!0;static makeCurrent(){d_(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=G_();return t==null?null:K_(t)}resetBaseElement(){W_=null}getUserAgent(){return window.navigator.userAgent}getCookie(e){return m_(document.cookie,e)}},W_=null;function G_(){return W_||=document.head.querySelector(`base`),W_?W_.getAttribute(`href`):null}function K_(e){return new URL(e,document.baseURI).pathname}var q_=[`alt`,`control`,`meta`,`shift`],J_={"\b":`Backspace`," ":`Tab`,"":`Delete`,"\x1B":`Escape`,Del:`Delete`,Esc:`Escape`,Left:`ArrowLeft`,Right:`ArrowRight`,Up:`ArrowUp`,Down:`ArrowDown`,Menu:`ContextMenu`,Scroll:`ScrollLock`,Win:`OS`},Y_={alt:e=>e.altKey,control:e=>e.ctrlKey,meta:e=>e.metaKey,shift:e=>e.shiftKey},X_=(()=>{class e extends g_{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(()=>u_().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.`),q_.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=J_[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`),q_.forEach(t=>{if(t!==n){let n=Y_[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)(Pi(is))};static ɵprov=ei({token:e,factory:e.ɵfac})}return e})();async function Z_(e,t,n){return c_({rootComponent:e,...Q_(t,n)})}function Q_(e,t){return{platformRef:t?.platformRef,appProviders:[...rv,...e?.providers??[]],platformProviders:nv}}function $_(){U_.makeCurrent()}function ev(){return new ks}function tv(){return xl(document),document}var nv=[{provide:Is,useValue:h_},{provide:Fs,useValue:$_,multi:!0},{provide:is,useFactory:tv}],rv=[{provide:ua,useValue:`root`},{provide:ks,useFactory:ev},{provide:v_,useClass:__,multi:!0},{provide:v_,useClass:X_,multi:!0},L_,{provide:rp,useClass:T_},{provide:T_,useExisting:rp},y_,{provide:zf,useExisting:L_},[]];function iv(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 cv({code:i,why:ov(a.why,e),fix:ov(a.fix,e),docs:o,cause:e.cause,sources:e.sources,data:ov(a.data,e)},s);for(let e of t)e(r,n);return r};n[i]=s}return n}function dv(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 _v=Math.random.bind(Math),vv=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`;function yv(e=21){let t=``,n=e;for(;n--;)t+=vv[_v()*64|0];return t}var bv=6e4,xv=e=>e,Sv=xv,{clearTimeout:Cv,setTimeout:wv}=globalThis;function Tv(e,t){let{post:n,on:r,off:i=()=>{},eventNames:a=[],serialize:o=xv,deserialize:s=Sv,resolver:c,bind:l=`rpc`,timeout:u=bv,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}=gv(),_=yv();s.i=_;let v;async function y(n=s){return u>=0&&(v=wv(()=>{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{Cv(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&&(Cv(r.timeoutId),n?r.reject(n):r.resolve(t)),p.delete(e)}}return m=r(b),h}function Ev(e,t){return t.safety?t.safety:e===`static`||e===`query`||e==null?`read`:`action`}var Dv=Object.freeze({type:`object`,additionalProperties:!0});function Ov(e){let t=e[`~standard`];if(t.jsonSchema)try{return t.jsonSchema.input({target:`draft-2020-12`})}catch{return Dv}return Dv}function kv(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 jv(e,t){return Av(e,t)??[e]}function Mv(e){return typeof e==`string`?`'${e}'`:new Iv().serialize(e)}var Nv=` _-,;:!?.'"()[]{}@*/\\&#%\`^+<=>|~$0123456789abcdefghijklmnopqrstuvwxyz`,Pv=(function(){let e=new Uint8Array(128);for(let t=0;t<69;t++)e[Nv.charCodeAt(t)]=t+1;for(let t=65;t<=90;t++)e[t]=e[t+32];return e})();function Fv(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})(),Lv=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225],Rv=[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],zv=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_`,Bv=[],Vv=class{_data=new Hv;_hash=new Hv([...Lv]);_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)Bv[n]=e[t+n]|0;else{let e=Bv[n-15],t=(e<<25|e>>>7)^(e<<14|e>>>18)^e>>>3,r=Bv[n-2],i=(r<<15|r>>>17)^(r<<13|r>>>19)^r>>>10;Bv[n]=t+Bv[n-7]+i+Bv[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+Rv[n]+Bv[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=Hv.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 Uv(e){return new Vv().finalize(e).toBase64()}function Wv(e){return Uv(Mv(e))}function Gv(e){return Wv(e)}function Kv(){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 qv=/^[\w+.-]{2,}:\/\//;function Jv(e){return e.endsWith(`/`)?e:`${e}/`}function Yv(e){return(e.endsWith(`/`)?e.slice(0,-1):e)||`/`}function Xv(e,...t){let n=e;for(let e of t)e&&e!==`/`&&(n=n?Jv(n)+e.replace(/^\.?\//,``):e);return n}function Zv(e,t){if(!t||t===`/`||qv.test(e))return e;let n=Yv(t);return e.startsWith(n)?e:Xv(n,e)}function Qv(e,t){let n=e.match(qv);return t+(n?e.slice(n[0].length):e)}var $v=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`;function ey(e=21){let t=``,n=e;for(;n--;)t+=$v[Math.random()*64|0];return t}var ty=Symbol.for(`immer-nothing`),ny=Symbol.for(`immer-draftable`),ry=Symbol.for(`immer-state`),iy=[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 ay(e,...t){{let n=iy[e],r=ky(n)?n.apply(null,t):n;throw Error(`[Immer] ${r}`)}}var oy=Object,sy=oy.getPrototypeOf,cy=`constructor`,ly=`prototype`,uy=`configurable`,dy=`enumerable`,fy=`writable`,py=`value`,my=e=>!!e&&!!e[ry];function hy(e){return e?vy(e)||Ty(e)||!!e[ny]||!!e[cy]?.[ny]||Ey(e)||Dy(e):!1}var gy=oy[ly][cy].toString(),_y=new WeakMap;function vy(e){if(!e||!Oy(e))return!1;let t=sy(e);if(t===null||t===oy[ly])return!0;let n=oy.hasOwnProperty.call(t,cy)&&t[cy];if(n===Object)return!0;if(!ky(n))return!1;let r=_y.get(n);return r===void 0&&(r=Function.toString.call(n),_y.set(n,r)),r===gy}function yy(e,t,n=!0){by(e)===0?(n?Reflect.ownKeys(e):oy.keys(e)).forEach(n=>{t(n,e[n],e)}):e.forEach((n,r)=>t(r,n,e))}function by(e){let t=e[ry];return t?t.type_:Ty(e)?1:Ey(e)?2:Dy(e)?3:0}var xy=(e,t,n=by(e))=>n===2?e.has(t):oy[ly].hasOwnProperty.call(e,t),Sy=(e,t,n=by(e))=>n===2?e.get(t):e[t],Cy=(e,t,n,r=by(e))=>{r===2?e.set(t,n):r===3?e.add(n):e[t]=n};function wy(e,t){return e===t?e!==0||1/e==1/t:e!==e&&t!==t}var Ty=Array.isArray,Ey=e=>e instanceof Map,Dy=e=>e instanceof Set,Oy=e=>typeof e==`object`,ky=e=>typeof e==`function`,Ay=e=>typeof e==`boolean`;function jy(e){let t=+e;return Number.isInteger(t)&&String(t)===e}var My=e=>Oy(e)?e?.[ry]:null,Ny=e=>e.copy_||e.base_,Py=e=>e.modified_?e.copy_:e.base_;function Fy(e,t){if(Ey(e))return new Map(e);if(Dy(e))return new Set(e);if(Ty(e))return Array[ly].slice.call(e);let n=vy(e);if(t===!0||t===`class_only`&&!n){let t=oy.getOwnPropertyDescriptors(e);delete t[ry];let n=Reflect.ownKeys(t);for(let r=0;r1&&oy.defineProperties(e,{set:Ry,add:Ry,clear:Ry,delete:Ry}),oy.freeze(e),t&&yy(e,(e,t)=>{Iy(t,!0)},!1),e)}function Ly(){ay(2)}var Ry={[py]:Ly};function zy(e){return e===null||!Oy(e)||oy.isFrozen(e)}var By=`MapSet`,Vy=`Patches`,Hy=`ArrayMethods`,Uy={};function Wy(e){let t=Uy[e];return t||ay(0,e),t}var Gy=e=>!!Uy[e];function Ky(e,t){Uy[e]||(Uy[e]=t)}var qy,Jy=()=>qy,Yy=(e,t)=>({drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0,handledSet_:new Set,processedForPatches_:new Set,mapSetPlugin_:Gy(By)?Wy(By):void 0,arrayMethodsPlugin_:Gy(Hy)?Wy(Hy):void 0});function Xy(e,t){t&&(e.patchPlugin_=Wy(Vy),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function Zy(e){Qy(e),e.drafts_.forEach(eb),e.drafts_=null}function Qy(e){e===qy&&(qy=e.parent_)}var $y=e=>qy=Yy(qy,e);function eb(e){let t=e[ry];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function tb(e,t){t.unfinalizedDrafts_=t.drafts_.length;let n=t.drafts_[0];if(e!==void 0&&e!==n){n[ry].modified_&&(Zy(t),ay(4)),hy(e)&&(e=nb(t,e));let{patchPlugin_:r}=t;r&&r.generateReplacementPatches_(n[ry].base_,e,t)}else e=nb(t,n);return rb(t,e,!0),Zy(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e===ty?void 0:e}function nb(e,t){if(zy(t))return t;let n=t[ry];if(!n)return db(t,e.handledSet_,e);if(!ab(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);lb(n,e)}return n.copy_}function rb(e,t,n=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&Iy(t,n)}function ib(e){e.finalized_=!0,e.scope_.unfinalizedDrafts_--}var ab=(e,t)=>e.scope_===t,ob=[];function sb(e,t,n,r){let i=Ny(e),a=e.type_;if(r!==void 0&&Sy(i,r,a)===t){Cy(i,r,n,a);return}if(!e.draftLocations_){let t=e.draftLocations_=new Map;yy(i,(e,n)=>{if(my(n)){let r=t.get(n)||[];r.push(e),t.set(n,r)}})}let o=e.draftLocations_.get(t)??ob;for(let e of o)Cy(i,e,n,a)}function cb(e,t,n){e.callbacks_.push(function(r){let i=t;if(!i||!ab(i,r))return;r.mapSetPlugin_?.fixSetContents(i);let a=Py(i);sb(e,i.draft_??i,a,n),lb(i,r)})}function lb(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)}ib(e)}}function ub(e,t,n){let{scope_:r}=e;if(my(n)){let i=n[ry];ab(i,r)&&i.callbacks_.push(function(){bb(e),sb(e,n,Py(i),t)})}else hy(n)&&e.callbacks_.push(function(){let i=Ny(e);e.type_===3?i.has(n)&&db(n,r.handledSet_,r):Sy(i,t,e.type_)===n&&r.drafts_.length>1&&(e.assigned_.get(t)??!1)===!0&&e.copy_&&db(Sy(e.copy_,t,e.type_),r.handledSet_,r)})}function db(e,t,n){return!n.immer_.autoFreeze_&&n.unfinalizedDrafts_<1||my(e)||t.has(e)||!hy(e)||zy(e)?e:(t.add(e),yy(e,(r,i)=>{if(my(i)){let t=i[ry];ab(t,n)&&(Cy(e,r,Py(t),e.type_),ib(t))}else hy(i)&&db(i,t,n)}),e)}function fb(e,t){let n=Ty(e),r={type_:+!!n,scope_:t?t.scope_:Jy(),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=pb;n&&(i=[r],a=mb);let{revoke:o,proxy:s}=Proxy.revocable(i,a);return r.draft_=s,r.revoke_=o,[s,r]}var pb={get(e,t){if(t===ry)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=Ny(e);if(!xy(i,t,e.type_))return _b(e,i,t);let a=i[t];if(e.finalized_||!hy(a)||r&&e.operationMethod&&n?.isMutatingArrayMethod(e.operationMethod)&&jy(t))return a;if(a===hb(e.base_,t)||gb(e,t,a)){bb(e);let n=e.type_===1?+t:t,r=Sb(e.scope_,a,e,n);return e.copy_[n]=r}return a},has(e,t){return t in Ny(e)},ownKeys(e){return Reflect.ownKeys(Ny(e))},set(e,t,n){let r=vb(Ny(e),t);if(r?.set)return r.set.call(e.draft_,n),!0;if(!e.modified_){let r=hb(Ny(e),t),i=r?.[ry];if(i&&i.base_===n)return e.copy_[t]=n,e.assigned_.set(t,!1),!0;if(wy(n,r)&&(n!==void 0||xy(e.base_,t,e.type_)))return!0;bb(e),yb(e)}return e.copy_[t]===n&&(n!==void 0||xy(e.copy_,t,e.type_))||Number.isNaN(n)&&Number.isNaN(e.copy_[t])?!0:(e.copy_[t]=n,e.assigned_.set(t,!0),ub(e,t,n),!0)},deleteProperty(e,t){return bb(e),hb(e.base_,t)!==void 0||t in e.base_?(e.assigned_.set(t,!1),yb(e)):e.assigned_.delete(t),e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){let n=Ny(e),r=Reflect.getOwnPropertyDescriptor(n,t);return r&&{[fy]:!0,[uy]:e.type_!==1||t!==`length`,[dy]:r[dy],[py]:n[t]}},defineProperty(){ay(11)},getPrototypeOf(e){return sy(e.base_)},setPrototypeOf(){ay(12)}},mb={};for(let e in pb){let t=pb[e];mb[e]=function(){let e=arguments;return e[0]=e[0][0],t.apply(this,e)}}mb.deleteProperty=function(e,t){return isNaN(parseInt(t))&&ay(13),mb.set.call(this,e,t,void 0)},mb.set=function(e,t,n){return t!==`length`&&isNaN(parseInt(t))&&ay(14),pb.set.call(this,e[0],t,n,e[0])};function hb(e,t){let n=e[ry];return(n?Ny(n):e)[t]}function gb(e,t,n){return e.type_!==1||!e.allIndicesReassigned_||e.assigned_?.get(t)||!hy(n)||n[ry]?!1:e.baseRefs_.has(n)}function _b(e,t,n){let r=vb(t,n);return r?py in r?r[py]:r.get?.call(e.draft_):void 0}function vb(e,t){if(!(t in e))return;let n=sy(e);for(;n;){let e=Object.getOwnPropertyDescriptor(n,t);if(e)return e;n=sy(n)}}function yb(e){e.modified_||(e.modified_=!0,e.parent_&&yb(e.parent_))}function bb(e){e.copy_||=(e.assigned_=new Map,Fy(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var xb=class{constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!1,this.produce=(e,t,n)=>{if(ky(e)&&!ky(t)){let n=t;t=e;let r=this;return function(e=n,...i){return r.produce(e,e=>t.call(this,e,...i))}}ky(t)||ay(6),n!==void 0&&!ky(n)&&ay(7);let r;if(hy(e)){let i=$y(this),a=Sb(i,e,void 0),o=!0;try{r=t(a),o=!1}finally{o?Zy(i):Qy(i)}return Xy(i,n),tb(r,i)}if(!e||!Oy(e)){if(r=t(e),r===void 0&&(r=e),r===ty&&(r=void 0),this.autoFreeze_&&Iy(r,!0),n){let t=[],i=[];Wy(Vy).generateReplacementPatches_(e,r,{patches_:t,inversePatches_:i}),n(t,i)}return r}ay(1,e)},this.produceWithPatches=(e,t)=>{if(ky(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]},Ay(e?.autoFreeze)&&this.setAutoFreeze(e.autoFreeze),Ay(e?.useStrictShallowCopy)&&this.setUseStrictShallowCopy(e.useStrictShallowCopy),Ay(e?.useStrictIteration)&&this.setUseStrictIteration(e.useStrictIteration)}createDraft(e){hy(e)||ay(8),my(e)&&(e=Cb(e));let t=$y(this),n=Sb(t,e,void 0);return n[ry].isManual_=!0,Qy(t),n}finishDraft(e,t){let n=e&&e[ry];(!n||!n.isManual_)&&ay(9);let{scope_:r}=n;return Xy(r,t),tb(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=Wy(Vy).applyPatches_;return my(e)?r(e,t):this.produce(e,e=>r(e,t))}};function Sb(e,t,n,r){let[i,a]=Ey(t)?Wy(By).proxyMap_(t,n):Dy(t)?Wy(By).proxySet_(t,n):fb(t,n);return(n?.scope_??Jy()).drafts_.push(i),a.callbacks_=n?.callbacks_??[],a.key_=r,n&&r!==void 0?cb(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 Cb(e){return my(e)||ay(10,e),wb(e)}function wb(e){if(!hy(e)||zy(e))return e;let t=e[ry],n,r=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,n=Fy(e,t.scope_.immer_.useStrictShallowCopy_),r=t.scope_.immer_.shouldUseStrictIteration()}else n=Fy(e,!0);return yy(n,(e,t)=>{Cy(n,e,wb(t))},r),t&&(t.finalized_=!1),n}function Tb(){iy.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=My(Sy(e,n.key_)),i=Sy(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||xy(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=Sy(o,e,c),f=Sy(s,e,c),p=l?xy(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===ty?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(Dy(e))return new Set(Array.from(e).map(u));let t=Object.create(sy(e));for(let n in e)t[n]=u(e[n]);return xy(e,ny)&&(t[ny]=e[ny]),t}function d(e){return my(e)?u(e):e}Ky(Vy,{applyPatches_:l,generatePatches_:i,generateReplacementPatches_:c,getPath:e})}globalThis.Iterator?.from;var Eb=new xb,Db=Eb.produce,Ob=Eb.produceWithPatches.bind(Eb),kb=Eb.applyPatches.bind(Eb),Ab=1e3;function jb(e,t){if(e.add(t),e.size>Ab){let t=e.values().next().value;t!==void 0&&e.delete(t)}}function Mb(e){let{enablePatches:t=!1}=e;t&&Tb();let n=Kv(),r=e.initialValue,i=new Set;return{on:n.on,value:()=>r,patch:(e,t=ey())=>{i.has(t)||(Tb(),r=kb(r,e),jb(i,t),n.emit(`updated`,r,void 0,t))},mutate:(e,a=ey())=>{if(!i.has(a)){if(jb(i,a),t){let[t,i]=Ob(r,e);if(t===r)return;r=t,n.emit(`updated`,r,i,a)}else{let t=Db(r,e);if(t===r)return;r=t,n.emit(`updated`,r,void 0,a)}}},syncIds:i}}var Nb=typeof self==`object`?self:globalThis,Pb=new Set([`Error`,`EvalError`,`RangeError`,`ReferenceError`,`SyntaxError`,`TypeError`,`URIError`,`AggregateError`]),Fb=new Set([`Boolean`,`Number`,`String`,`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float16Array`,`Float32Array`,`Float64Array`,`BigInt64Array`,`BigUint64Array`]);function Ib(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=Pb.has(e)?Nb[e]:void 0;return n(new(r??Nb.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`&&Fb.has(a))return n(new Nb[a](o),i);throw TypeError(`unable to deserialize unsafe or unknown type: ${String(a)}`)};return r}function Lb(e){return Ib(new Map,e)(0)}var Rb=``,{toString:zb}={},{keys:Bb}=Object;function Vb(e){let t=typeof e;if(t!==`object`||!e)return[0,t];let n=zb.call(e).slice(8,-1);switch(n){case`Array`:return[1,Rb];case`Object`:return[2,Rb];case`Date`:return[3,Rb];case`RegExp`:return[4,Rb];case`Map`:return[5,Rb];case`Set`:return[6,Rb];case`DataView`:return[1,n]}return n.includes(`Array`)?[1,n]:n.includes(`Error`)?[7,n]:[2,n]}function Hb([e,t]){return e===0&&(t===`function`||t===`symbol`)}function Ub(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]=Vb(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 Bb(r))(e||!Hb(Vb(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||!(Hb(Vb(n))||Hb(Vb(i))))&&t.push([a(n),a(i)]);return n}case 6:{let t=[],n=i([o,t],r);for(let n of r)(e||!Hb(Vb(n)))&&t.push(a(n));return n}}let{message:c}=r;return i([o,{name:s,message:c}],r)};return a}function Wb(e,t={}){let n=[];return Ub(!(t.json||t.lossy),!!t.json,new Map,n)(e),n}var{parse:Gb,stringify:Kb}=JSON,qb={json:!0,lossy:!0};function Jb(e){return Lb(Gb(e))}function Yb(e){return Kb(Wb(e,qb))}function Xb(e){return Lb(e)}function Zb(e){return Yb(e)}function Qb(e){return Jb(e)}var $b=256,ex=class extends Error{name=`StreamClosedError`};function tx(e={}){let t=e.id??ey(),n=Math.max(0,e.replayWindow??0),r=Kv(),i=new AbortController,a=[],o=!1,s=0;function c(e){if(o)throw new ex(`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=rx(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 nx(e={}){let t=e.id??ey(),n=Math.max(1,e.highWaterMark??$b),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 rx(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 ix=128;function ax(e){return e.replace(/[^\w-]+/g,`_`).slice(0,ix)}var ox=`modulepreload`,sx=function(e,t){return new URL(e,t).href},cx={},lx=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=sx(t,n),t=s(t),t in cx)return;cx[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`:ox,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)})},ux=`__connection.json`,dx=`__DEVFRAME_CONNECTION__`,fx=`x-birpc-session`,px=`__rpc-dump/index.json`,mx=`devframe:services`,hx=`devframe_otp`,gx=`devframe_auth_token`;fv.postMessage.remoteAssetsError;var _x=class{cacheMap=new Map;options;keySerializer;constructor(e){this.options=e,this.keySerializer=e.keySerializer||(e=>Gv(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()}},vx=hv({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 yx(e){if(e.agent&&e.jsonSerializable===!1)throw vx.DF0019({name:e.name});e.agent&&!e.jsonSerializable&&(e.jsonSerializable=!0)}async function bx(e,t){let n=e[`~standard`].validate(t);return n instanceof Promise?await n:n}function xx(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 Sx(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 Tx(e,t){let n=e.handler;if(!n){let r=await wx(e,t);if(!r.handler)throw vx.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 Sx(e.name,r,t),o=await a(...n);return await Cx(e.name,i,o)}}var Ex=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 Tx(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 vx.DF0021({name:e.name});yx(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 vx.DF0022({name:e.name});yx(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 Tx(this.definitions.get(e),this.context)}getSchema(e){let t=this.definitions.get(e);if(!t)throw vx.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 Dx(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 kx(t,`undefined`,r,e);return n}return i!==null&&Ox(i,r,e,t),n})}function Ox(e,t,n,r){if(typeof e==`bigint`)throw kx(r,`BigInt`,t,n);if(typeof e!=`object`)return;if(e instanceof Map)throw kx(r,`Map`,t,n);if(e instanceof Set)throw kx(r,`Set`,t,n);if(e instanceof Date)throw kx(r,`Date`,t,n);if(Array.isArray(e))return;let i=Object.getPrototypeOf(e);if(i!==null&&i!==Object.prototype)throw kx(r,e.constructor?.name??`class instance`,t,n)}function kx(e,t,n,r){let i=Ax(n,r);return vx.DF0020({name:e||``,type:t,path:i})}function Ax(e,t){return Array.isArray(e)?`[${t}]`:t===``?``:t}var jx=`__DEVFRAME_CONNECTION_META__`,Mx=`__DEVFRAME_CONNECTION_AUTH_TOKEN__`;function Nx(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 Px(){return Nx(dx)}function Fx(){return Nx(jx)}function Ix(e){if(e)return e;try{let e=localStorage.getItem(Mx);if(e)return e}catch{}return Nx(Mx)}function Lx(e){globalThis[dx]=e,globalThis[jx]={...e.connectionMeta,baseUrl:e.metaBaseUrl},e.authToken&&Rx(e.authToken)}function Rx(e){try{localStorage.setItem(Mx,e)}catch{}globalThis[Mx]=e;let t=Px();t&&(globalThis[dx]={...t,authToken:e})}function zx(e){let t=Zv(ux,e);try{return new URL(t,globalThis.location?.href).href}catch{return t}}function Bx(e,t){return t&&t!==e.authToken?{...e,authToken:t}:e}function Vx(){let e=Px();if(e)return Bx(e,Ix()??e.authToken??e.connectionMeta.authToken);let t=Fx();if(t)return{connectionMeta:t,metaBaseUrl:t.baseUrl??zx(`./`),authToken:Ix(t.authToken)}}async function Hx(e={}){if(e.connection){let t=Bx(e.connection,Ix(e.authToken??e.connection.authToken??e.connection.connectionMeta.authToken));return Lx(t),t}let t=Array.isArray(e.baseURL)?e.baseURL:[e.baseURL??`./`];if(e.connectionMeta){let n={connectionMeta:e.connectionMeta,metaBaseUrl:zx(t[0]??`./`),authToken:Ix(e.authToken??e.connectionMeta.authToken)};return Lx(n),n}let n=Vx();if(n){let t=Bx(n,Ix(e.authToken??n.authToken??n.connectionMeta.authToken));return Lx(t),t}let r=[];for(let n of t){let t=Zv(ux,n),i=zx(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:Ix(e.authToken??r.authToken)};return Lx(o),o}catch(e){r.push(e)}}throw Error(`Failed to get connection meta from ${t.join(`, `)}`,{cause:r})}var Ux=class extends Error{name=`DevframeConnectionError`;kind;constructor(e,t,n){super(t,n),this.kind=e}};function Wx(e=hx){try{let t=globalThis.location?.hash?.replace(/^#/,``)??``;return new URLSearchParams(t).get(e)||void 0}catch{return}}function Gx(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 Kx(e=hx){let t=Wx(e);return t&&Gx(e),t}async function qx(e,t={}){let n=Kx(t.param??`devframe_otp`);return n?e.isTrusted?!0:e.requestTrustWithCode(n):!1}function Jx(e){let t={},n=new WeakMap,r,i=()=>(r??=e.sharedState.get(mx,{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 Yx(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:fv.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:fv.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=Mb({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(fv.client.isTrustedUpdated,e=>{e&&!n&&(n=!0,d())})}})}}}var Xx=new Map;function Zx(e=Xx){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?Dx(n,r??``):`s:${Zb(n)}`},deserialize:e=>{let n=e.startsWith(`s:`)?Qb(e.slice(2)):JSON.parse(e);return n.t===`q`&&n.i&&n.m&&t.set(n.i,n.m),n}}}function Qx(){}function $x(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 eS(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 tS(e){let{onConnected:t=Qx,onError:n=Qx,onDisconnected:r=Qx,definitions:i,fetch:a=globalThis.fetch.bind(globalThis)}=e,o=e.url;e.authToken&&(o=`${o}${o.includes(`?`)?`&`:`?`}${gx}=${encodeURIComponent(e.authToken)}`);let s=Zx(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=$x(r);if(!e)break;r=e.rest;let{event:t,data:n}=eS(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`,[fx]: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 nS(e,t){let{channel:n,rpcOptions:r={}}=t;return Tv(e,{...n,timeout:-1,...r,proxify:!1})}function rS(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(fv.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 Ux(`connection`,`[devframe] Not connected to the devframe server`,{cause:u??void 0}):l===`unauthorized`?new Ux(`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(fv.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 Ux(`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(fv.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(fv.client.connectionError,e),m(new Ux(`connection`,`[devframe] Connection to the devframe server failed`,{cause:e}))},onDisconnected(){l!==`error`&&f(`disconnected`),m(new Ux(`connection`,`[devframe] Disconnected from the devframe server`,{cause:u??void 0}))}}),y=nS(a.functions,{channel:v,rpcOptions:o});a.register({name:fv.broadcast.authRevoked,type:`event`,handler:()=>{c=!1;let e=new Ux(`auth`,`[devframe] The devframe server revoked this client's trust`);f(`unauthorized`,e),i.emit(fv.client.connectionError,e),m(e),i.emit(fv.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 Ux(`auth`,`[devframe] The devframe server refused this client's credentials`);f(`unauthorized`,e),i.emit(fv.client.connectionError,e)}return i.emit(fv.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(fv.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(fv.client.error,n,t),Promise.reject(n)):g(y.$call(...e),t)},callEvent:(...e)=>{let t=h();if(t){i.emit(fv.client.error,t,String(e[0]));return}return y.$callEvent(...e)},callOptional:(...e)=>{let t=String(e[0]),n=h();return n?(i.emit(fv.client.error,n,t),Promise.reject(n)):g(y.$callOptional(...e),t)},close:()=>{v.close()}}}function iS(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 aS(e){let{authToken:t,connectionMeta:n,metaBaseUrl:r,events:i,clientRpc:a,rpcOptions:o={},sseOptions:s={},callTimeout:c=0}=e,l=iS(n.sse,r??`./`,location);return rS({transport:`sse`,authToken:t,connectionMeta:n,events:i,clientRpc:a,rpcOptions:o,callTimeout:c,createChannel:e=>tS({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 oS(e){let{name:t,message:n,cause:r,...i}=e,a=r instanceof Error?r:sS(r)?oS(r):r,o=a===void 0?Error(n):Error(n,{cause:a});return o.name=t,Object.assign(o,i),o}function sS(e){return typeof e==`object`&&!!e&&typeof e.message==`string`&&typeof e.name==`string`}function cS(e){return typeof e==`object`&&!!e&&e.type===`static`&&typeof e.path==`string`}function lS(e){return typeof e==`object`&&!!e&&e.type===`query`&&typeof e.records==`object`&&e.records!==null}function uS(e){return typeof e==`object`&&!!e&&(`output`in e||`error`in e)}function dS(e){if(e.error)throw oS(e.error);return e.output}function fS(e){return e.some(e=>e!=null)}function pS(e){return typeof e==`object`&&e&&`serialization`in e&&`data`in e?e.data:e}function mS(e,t){let n=new Map,r=new Map;function i(e,t){return t===`structured-clone`&&Array.isArray(e)?Xb(e):e}function a(e,t){return i(pS(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 uS(r)?dS(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(cS(r)){if(fS(n))throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`);return await o(r)}if(lS(r)){let e=Gv(n),i=r.records[e];if(i)return dS(await s(i,r.serialization));if(r.fallback)return dS(await s(r.fallback,r.serialization));throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`)}if(!fS(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 hS(e){let t=mS(await e.fetchJsonFromBases(px),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 gS=``;function _S(e,t){return`${e}${gS}${t}`}function vS(e){let t=new Map,n=new Map;e.client.register({name:fv.broadcast.streamingChunk,type:`event`,handler(e,n,r,i){t.get(_S(e,n))?._push(r,i)}}),e.client.register({name:fv.broadcast.streamingEnd,type:`event`,handler(e,n,r){let i=_S(e,n),a=t.get(i);a&&(a._end(r),t.delete(i))}}),e.client.register({name:fv.broadcast.streamingUploadCancel,type:`event`,handler(e,t){let r=_S(e,t),i=n.get(r);i&&(i.abort(`server cancelled upload`),n.delete(r))}}),e.events.on(fv.client.isTrustedUpdated,n=>{if(n)for(let[n,r]of t){if(r.cancelled||r.done)continue;let t=n.indexOf(gS);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=_S(n,r),o=t.get(a);if(o)return o;let s=nx({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(fv.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=_S(t,r),a=n.get(i);if(a)return a;let o=tx({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 yS(){}var bS=new Map;function xS(e){let t=e.url;e.authToken&&(t=`${t}?${gx}=${encodeURIComponent(e.authToken)}`);let n=new WebSocket(t),{onConnected:r=yS,onError:i=yS,onDisconnected:a=yS,definitions:o=bS}=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=Zx(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 SS(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 Qv(a,/^https/i.test(a)?`wss://`:`ws://`);let o=new URL(a,r);return o.protocol=i,o.href}function CS(e){let{authToken:t,connectionMeta:n,metaBaseUrl:r,events:i,clientRpc:a,rpcOptions:o={},wsOptions:s={},callTimeout:c=0}=e,l=SS(n.websocket,r??`./`,location);return rS({transport:`websocket`,authToken:t,connectionMeta:n,events:i,clientRpc:a,rpcOptions:o,callTimeout:c,createChannel:e=>xS({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 wS(e){return e.includes(`:`)}function TS(e,t){return wS(t)?t:`${e}:${t}`}function ES(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 DS(e,t,n){let r=`devframe:settings:${n}:${t}`,i;function a(){return i||=e.sharedState.get(r,{initialValue:{}}),i}return ES(a)}function OS(e,t){return{global:DS(e,t,`global`),project:DS(e,t,`project`)}}function kS(e,t){return{namespace:t,base:e,rpc:{namespace:t,register(n){if(wS(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(TS(t,n),...r)),callEvent:((n,...r)=>e.callEvent(TS(t,n),...r)),callOptional:((n,...r)=>e.callOptional(TS(t,n),...r)),sharedState:((n,r)=>e.sharedState.get(TS(t,n),r)),streaming:{subscribe:(n,r,i)=>e.streaming.subscribe(TS(t,n),r,i),upload:(n,r)=>e.streaming.upload(TS(t,n),r)}},settings:OS(e,t),scope:e.scope}}function AS(){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 jS(e,t={}){let n=t.modelContext??AS();if(!n)return()=>{};let r=n,i=new Map,a=new Map;function o(t,n){let o=ax(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=Ev(t.type,n),u=r.registerTool({name:o,description:n.description,inputSchema:kv(t.args),annotations:{title:n.title??t.name,readOnlyHint:l===`read`,destructiveHint:l===`destructive`},execute:n=>MS(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 MS(e,t,n){try{let r=jv(n,e.args?.length);return{content:[{type:`text`,text:NS(await(await Tx(e,t))(...r))}]}}catch(e){return{isError:!0,content:[{type:`text`,text:PS(e)}]}}}function NS(e){return e===void 0?`undefined`:typeof e==`string`?e:JSON.stringify(e,null,2)}function PS(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 FS(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 IS(e={}){let{baseURL:t=`./`,rpcOptions:n={},cacheOptions:r=!1}=e,i=Kv(),a=Array.isArray(t)?t:[t],o=await Hx(e),{connectionMeta:s,metaBaseUrl:c,authToken:l}=o,u=a[0]??`./`;try{u=new URL(`.`,c).href}catch{}let d=new _x({functions:[],...typeof e.cacheOptions==`object`?e.cacheOptions:{}}),f={rpc:void 0},p=new Ex(f),m=e.webmcp===!1?void 0:jS(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(Zv(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=FS(e.transport??`auto`,s),b=y===`static`?await hS({fetchJsonFromBases:_}):y===`sse`?aS({...v,sseOptions:e.sseOptions}):CS({...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=>(Rx(e),o={...o,authToken:e},b.requestTrustWithToken(e)),requestTrustWithCode:async e=>{let t=await b.requestTrustWithCode(e);if(!t)return!1;Rx(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=Yx(C),C.streaming=vS(C),C.services=Jx(C);let re=new Map;C.scope=(e=>{if(!e)return C;let t=re.get(e);return t||(t=kS(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 qx(C,{param:n}):!1;t||r||C.isTrusted||await ie()}return te=T().then(()=>{ne=!0},()=>{ne=!0}),s.mcp&&lx(async()=>{let{setupBrowserAgentRpcBridge:e}=await import(`./browser-agent-rpc-BXhoSh1z-qqnMwn9c.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 LS=IS,RS=class e{rpc=Zg(null);navigate=Jg();meta=L(null);componentCount=L(0);routeCount=L(0);signalCount=L(0);providerCount=L(0);storeCount=L(0);constructor(){Ks(()=>{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; + }`]})},zS=(e,t)=>t.selector,BS=(e,t)=>t.token+t.line;function VS(e,t){e&1&&(q(0,`p`,3),Z(1,`Scanning components…`),J())}function HS(e,t){e&1&&(q(0,`p`,3),Z(1,`No components found.`),J())}function US(e,t){if(e&1&&(q(0,`li`,13),Z(1),J()),e&2){let e=t.$implicit;B(),Q(e)}}function WS(e,t){if(e&1&&(q(0,`h4`),Z(1,`Inputs`),J(),q(2,`ul`,12),U(3,US,2,1,`li`,13,wh),J()),e&2){let e=X(2).$implicit;B(3),W(e.inputs)}}function GS(e,t){if(e&1&&(q(0,`li`,14),Z(1),J()),e&2){let e=t.$implicit;B(),Q(e)}}function KS(e,t){if(e&1&&(q(0,`h4`),Z(1,`Outputs`),J(),q(2,`ul`,12),U(3,GS,2,1,`li`,14,wh),J()),e&2){let e=X(2).$implicit;B(3),W(e.outputs)}}function qS(e,t){if(e&1&&(q(0,`span`,19),Z(1),J()),e&2){let e=X().$implicit;B(),$(`→ `,e.source)}}function JS(e,t){if(e&1&&(q(0,`li`,16)(1,`span`,17),Z(2),J(),q(3,`span`,18),Z(4),J(),V(5,qS,2,1,`span`,19),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 YS(e,t){if(e&1&&(q(0,`h4`),Z(1,`Injected Providers`),J(),q(2,`ul`,15),U(3,JS,6,3,`li`,16,BS),J()),e&2){let e=X(4);B(3),W(e.selectedProviders())}}function XS(e,t){e&1&&(q(0,`p`,11),Z(1,`No injected providers detected.`),J())}function ZS(e,t){if(e&1&&(q(0,`div`,10)(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,WS,5,0),V(11,KS,5,0),V(12,YS,5,0)(13,XS,2,0,`p`,11),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 QS(e,t){if(e&1){let e=Wh();q(0,`li`,6)(1,`button`,7),Y(`click`,function(){let t=ho(e).$implicit;return go(X(2).select(t))}),q(2,`div`,8),Z(3),J(),q(4,`div`,9),Z(5),J()(),V(6,ZS,14,5,`div`,10),J()}if(e&2){let e=t.$implicit,n=X(2);ug(`expanded`,n.isSelected(e)),B(),ph(`aria-expanded`,n.isSelected(e)),B(2),$(`<`,e.selector,`>`),B(2),Q(e.file),B(),H(n.isSelected(e)?6:-1)}}function $S(e,t){if(e&1&&(q(0,`ul`,4),U(1,QS,7,6,`li`,5,zS),J()),e&2){let e=X();B(),W(e.filtered())}}var eC=class e{rpc=Zg(null);components=L([]);allProviders=L([]);filter=L(``);loading=L(!1);selected=L(null);selectedProviders=L([]);filtered=L([]);constructor(){Ks(()=>{let e=this.filter().toLowerCase(),t=this.components();this.filtered.set(e?t.filter(t=>t.selector.includes(e)||t.file.includes(e)):t)}),Ks(()=>{this.rpc()&&this.refresh()})}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,`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,VS,2,0,`p`,3)(5,HS,2,0,`p`,3)(6,$S,3,0,`ul`,4)),e&2&&(B(),Gh(`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; + } + .provider-source[_ngcontent-%COMP%] { + font-size: 12px; + color: #71717a; + } + .no-providers[_ngcontent-%COMP%] { + font-size: 13px; + color: #52525b; + }`]})};function tC(e,t){e&1&&(q(0,`p`,3),Z(1,`Scanning routes…`),J())}function nC(e,t){e&1&&(q(0,`p`,3),Z(1,`No routes found.`),J())}function rC(e,t){if(e&1&&(q(0,`span`,7),Z(1),J()),e&2){let e=X().$implicit;B(),$(`➜ `,e.redirectTo)}}function iC(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` `,e.component??`—`,` `)}}function aC(e,t){if(e&1&&(q(0,`tr`)(1,`td`,6),Z(2),J(),q(3,`td`),V(4,rC,2,1,`span`,7)(5,iC,1,1),J(),q(6,`td`),Z(7),J(),q(8,`td`,8),Z(9),J(),q(10,`td`),Z(11),J()()),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 oC(e,t){if(e&1&&(q(0,`table`,4)(1,`thead`)(2,`tr`)(3,`th`,5),Z(4,`Path`),J(),q(5,`th`,5),Z(6,`Component / Target`),J(),q(7,`th`,5),Z(8,`Title`),J(),q(9,`th`,5),Z(10,`File`),J(),q(11,`th`,5),Z(12,`Children`),J()()(),q(13,`tbody`),U(14,aC,12,5,`tr`,null,Ch),J()()),e&2){let e=X();B(14),W(e.filtered())}}var sC=class e{rpc=Zg(null);routes=L([]);filter=L(``);loading=L(!1);filtered=Gg(()=>{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(){Ks(()=>{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:7,vars:2,consts:[[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&&(q(0,`div`,0)(1,`input`,1),Y(`input`,function(e){return t.onFilterInput(e)}),J(),q(2,`button`,2),Y(`click`,function(){return t.refresh()}),Z(3,`Refresh`),J()(),V(4,tC,2,0,`p`,3)(5,nC,2,0,`p`,3)(6,oC,16,0,`table`,4)),e&2&&(B(),Gh(`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; + } + 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: #71717a; + 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: #71717a; + }`]})},cC=(e,t)=>t.name+t.file+t.line,lC=(e,t)=>t.kind,uC=(e,t)=>t.id;function dC(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 fC(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · in <`,e.component,`> `)}}function pC(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,fC,1,1),J()()),e&2){let e=t.$implicit,n=X(2);B(2),lg(`background`,n.kindColor(e.kind)),B(),Q(e.kind),B(2),Q(e.name),B(2),kg(` `,e.file,`:`,e.line,` `),B(),H(e.component?8:-1)}}function mC(e,t){if(e&1&&(q(0,`p`,6),Z(1,`Signals from source scan (static analysis):`),J(),q(2,`div`,7),U(3,pC,9,7,`div`,8,cC),J()),e&2){let e=X();B(3),W(e.filteredSourceSignals())}}function hC(e,t){if(e&1&&(q(0,`span`,14),Lh(1,`span`,17),Z(2),J()),e&2){let e=t.$implicit;B(),lg(`background`,e.color),B(),$(` `,e.kind,` `)}}function gC(e,t){e&1&&(q(0,`span`,19),Z(1,`watching`),J())}function _C(e,t){if(e&1&&(q(0,`div`,20),Z(1),Fg(2,`json`),J()),e&2){let e=X().$implicit;B(),Q(Lg(2,1,e.value))}}function vC(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · Deps: `,X(2).getDependencies(e).length,` `)}}function yC(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · Consumers: `,X(2).getConsumers(e).length,` `)}}function bC(e,t){if(e&1){let e=Wh();q(0,`div`,18),Y(`click`,function(){let t=ho(e).$implicit;return go(X(2).selectNode(t))}),q(1,`div`,9)(2,`span`,10),Z(3),J(),q(4,`span`,11),Z(5),J(),V(6,gC,2,0,`span`,19),J(),V(7,_C,3,3,`div`,20),q(8,`div`,12),Z(9),V(10,vC,1,1),V(11,yC,1,1),J()()}if(e&2){let e=t.$implicit,n=X(2);ug(`selected`,n.selectedNode()?.id===e.id),B(2),lg(`background`,n.kindColor(e.kind)),B(),Q(e.kind),B(2),Q(e.label??`(unnamed)`),B(),H(e.watched?6:-1),B(),H(e.value===void 0?-1:7),B(2),$(` Epoch: `,e.epoch,` `),B(),H(n.getDependencies(e).length?10:-1),B(),H(n.getConsumers(e).length?11:-1)}}function xC(e,t){if(e&1&&(q(0,`dt`),Z(1,`Value`),J(),q(2,`dd`)(3,`pre`),Z(4),Fg(5,`json`),J()()),e&2){let e=X(3);B(4),Q(Lg(5,1,e.selectedNode().value))}}function SC(e,t){if(e&1&&(q(0,`li`)(1,`span`,21),Z(2),J(),Z(3),J()),e&2){let e=t.$implicit,n=X(4);B(),lg(`background`,n.kindColor(e.kind)),B(),Q(e.kind),B(),$(` `,e.label??e.id,` `)}}function CC(e,t){if(e&1&&(q(0,`h4`),Z(1,`Dependencies (producers)`),J(),q(2,`ul`),U(3,SC,4,4,`li`,null,uC),J()),e&2){let e=X(3);B(3),W(e.getDependencies(e.selectedNode()))}}function wC(e,t){if(e&1&&(q(0,`li`)(1,`span`,21),Z(2),J(),Z(3),J()),e&2){let e=t.$implicit,n=X(4);B(),lg(`background`,n.kindColor(e.kind)),B(),Q(e.kind),B(),$(` `,e.label??e.id,` `)}}function TC(e,t){if(e&1&&(q(0,`h4`),Z(1,`Consumers`),J(),q(2,`ul`),U(3,wC,4,4,`li`,null,uC),J()),e&2){let e=X(3);B(3),W(e.getConsumers(e.selectedNode()))}}function EC(e,t){if(e&1&&(q(0,`aside`,16)(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,xC,6,3),J(),V(13,CC,5,0),V(14,TC,5,0),J()),e&2){let e=X(2);B(2),Q(e.selectedNode().label??e.selectedNode().id),B(5),Q(e.selectedNode().kind),B(4),Q(e.selectedNode().epoch),B(),H(e.selectedNode().value===void 0?-1:12),B(),H(e.getDependencies(e.selectedNode()).length?13:-1),B(),H(e.getConsumers(e.selectedNode()).length?14:-1)}}function DC(e,t){if(e&1&&(q(0,`div`,13),U(1,hC,3,3,`span`,14,lC),J(),q(3,`div`,7),U(4,bC,12,11,`div`,15,uC),J(),V(6,EC,15,6,`aside`,16)),e&2){let e=X();B(),W(e.kindLegend),B(3),W(e.filteredNodes()),B(2),H(e.selectedNode()?6:-1)}}var OC={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`},kC=class e{rpc=Zg(null);graph=L(null);sourceSignals=L([]);filter=L(``);selectedNode=L(null);kindLegend=Object.entries(OC).map(([e,t])=>({kind:e,color:t}));filteredNodes=Gg(()=>{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});filteredSourceSignals=Gg(()=>{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(){Ks(()=>{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=t.value();n?.graph&&this.graph.set(n.graph),t.on(`updated`,e=>{e?.graph&&this.graph.set(e.graph)})}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.selectedNode.set(this.selectedNode()?.id===e.id?null:e)}kindColor(e){return OC[e]??OC.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`],[1,`node-card`,3,`selected`],[1,`detail-panel`],[1,`dot`],[1,`node-card`,3,`click`],[1,`watched-badge`],[1,`node-value`],[1,`kind-badge`,`sm`]],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,dC,5,0,`div`,3),V(5,mC,5,0),V(6,DC,7,1)),e&2&&(B(),Gh(`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:[p_],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; + } + .node-card[_ngcontent-%COMP%] { + 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.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; + }`]})},AC=(e,t)=>t.type,jC=(e,t)=>t.token+t.file+t.line,MC=(e,t)=>t.injector.id,NC=(e,t)=>t.node.injector.id,PC=(e,t)=>t.token;function FC(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 IC(e,t){if(e&1&&(q(0,`span`,14),Z(1),J()),e&2){let e=X().$implicit;B(),$(`providedIn: `,e.providedIn)}}function LC(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · as `,e.source,` `)}}function RC(e,t){if(e&1&&(q(0,`div`,11)(1,`div`,12)(2,`span`,13),Z(3),J(),V(4,IC,2,1,`span`,14),J(),q(5,`div`,15),Z(6),V(7,LC,1,1),J()()),e&2){let e=t.$implicit;B(3),Q(e.token),B(),H(e.providedIn?4:-1),B(2),kg(` `,e.file,`:`,e.line,` `),B(),H(e.source!==`class`&&e.source!==`providers array`?7:-1)}}function zC(e,t){if(e&1&&(q(0,`div`,9)(1,`h3`),Z(2),J(),q(3,`div`,10),U(4,RC,8,5,`div`,11,jC),J()()),e&2){let e=t.$implicit;B(2),kg(``,e.label,` (`,e.items.length,`)`),B(2),W(e.items)}}function BC(e,t){if(e&1&&(q(0,`p`,7),Z(1,`DI from source scan (static analysis):`),J(),q(2,`div`,8),U(3,zC,6,2,`div`,9,AC),J()),e&2){let e=X();B(3),W(e.groupedProviders())}}function VC(e,t){e&1&&Hh(0)}function HC(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 UC(e,t){if(e&1){let e=Wh();q(0,`div`,21),Y(`click`,function(){let t=ho(e).$implicit;return go(X(4).select(t.node))}),q(1,`span`,22),Z(2),J(),q(3,`span`,23),Z(4),J(),V(5,HC,2,1,`span`,24),J()}if(e&2){let e=t.$implicit,n=X(4);lg(`padding-left`,e.depth*24+12,`px`),ug(`selected`,n.selectedId()===e.node.injector.id),B(),lg(`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 WC(e,t){if(e&1&&(q(0,`div`,19),U(1,UC,6,9,`div`,20,NC),J()),e&2){let e=X().$implicit,t=X(2);B(),W(t.flattenTree(e))}}function GC(e,t){e&1&&(om(0,VC,1,0,`ng-container`,18)(1,WC,3,0),dh(2,1),fh()),e&2&&Gh(`ngTemplateOutlet`,void 0)}function KC(e,t){e&1&&(q(0,`p`,5),Z(1,`No providers configured on this injector.`),J())}function qC(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 JC(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,qC,7,3,`tr`,null,PC),J()()),e&2){let e=X(3);B(10),W(e.selectedInjector().providers)}}function YC(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,KC,2,0,`p`,5)(7,JC,12,0,`table`,26),J()),e&2){let e=X(2);B(2),lg(`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 XC(e,t){if(e&1&&(q(0,`div`,16),U(1,GC,4,1,null,null,MC),J(),V(3,YC,8,5,`aside`,17)),e&2){let e=X();B(),W(e.filteredRoots()),B(2),H(e.selectedInjector()?3:-1)}}var ZC={element:`#60a5fa`,environment:`#34d399`,null:`#71717a`},QC=class e{rpc=Zg(null);roots=L([]);sourceProviders=L([]);filter=L(``);hideEmpty=L(!1);selectedId=L(null);selectedInjector=Gg(()=>{let e=this.selectedId();return e?this.findNode(this.roots(),e):null});filteredRoots=Gg(()=>{let e=this.roots();this.hideEmpty()&&(e=this.filterEmpty(e));let t=this.filter().toLowerCase();return t&&(e=this.filterByQuery(e,t)),e});groupedProviders=Gg(()=>{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(){Ks(()=>{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 ZC[e]??ZC.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,FC,5,0,`div`,4),V(6,BC,5,0),V(7,XC,4,1)),e&2&&(B(),Gh(`value`,t.filter()),B(2),Gh(`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; + }`]})},$C=(e,t)=>t.kind,ew=(e,t)=>t.name+t.file+t.line;function tw(e,t){e&1&&Lh(0,`span`,4)}function nw(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 rw(e,t){if(e&1&&(q(0,`span`,9),Lh(1,`span`,14),Z(2),J()),e&2){let e=t.$implicit;B(),lg(`background`,e.color),B(),$(` `,e.kind,` `)}}function iw(e,t){if(e&1&&(q(0,`span`,15),Z(1),J()),e&2){let e=t.$implicit;lg(`border-color`,X(3).kindColor(e.kind)),B(),Ag(` `,e.count,` `,e.kind,``,e.count===1?``:`s`,` `)}}function aw(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · `,e.detail,` `)}}function ow(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,aw,1,1),J()()),e&2){let e=t.$implicit,n=X(3);B(2),lg(`background`,n.kindColor(e.kind)),B(),$(` `,e.kind,` `),B(2),Q(e.name),B(2),kg(` `,e.file,`:`,e.line,` `),B(),H(e.detail?8:-1)}}function sw(e,t){if(e&1&&(q(0,`div`,8),U(1,rw,3,3,`span`,9,$C),J(),q(3,`div`,10),U(4,iw,2,5,`span`,11,$C),J(),q(6,`div`,12),U(7,ow,9,7,`div`,13,ew),J()),e&2){let e=X(2);B(),W(e.kindLegend),B(3),W(e.groupedEntries()),B(3),W(e.filteredEntries())}}function cw(e,t){e&1&&V(0,nw,5,0,`div`,5)(1,sw,9,0),e&2&&H(X().sourceEntries().length===0?0:1)}function lw(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 uw(e,t){if(e&1){let e=Wh();q(0,`div`,28),Y(`click`,function(){let t=ho(e).$implicit;return go(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);ug(`selected`,n.selectedAction()===e),B(2),Q(e.type),B(2),Q(n.formatTime(e.timestamp))}}function dw(e,t){e&1&&(q(0,`p`,6),Z(1,`No actions dispatched yet.`),J())}function fw(e,t){if(e&1&&(q(0,`dt`),Z(1,`Payload`),J(),q(2,`dd`)(3,`pre`),Z(4),Fg(5,`json`),J()()),e&2){let e=X(4);B(4),Q(Lg(5,1,e.selectedAction().payload))}}function pw(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,fw,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 mw(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),Fg(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,uw,5,4,`div`,26,Ch,!1,dw,2,0,`p`,6),J()()(),V(16,pw,13,4,`aside`,27)),e&2){let e=X(2);B(5),Q(Lg(6,4,e.runtimeState()?.state)),B(6),Q(e.filteredActions().length),B(2),W(e.filteredActions()),B(3),H(e.selectedAction()?16:-1)}}function hw(e,t){e&1&&V(0,lw,5,0,`div`,5)(1,mw,17,6),e&2&&H(+!!X().runtimeState()?.connected)}var gw={action:`#f59e0b`,reducer:`#a78bfa`,effect:`#fb923c`,selector:`#60a5fa`,feature:`#34d399`,"store-setup":`#94a3b8`,"signal-store":`#e879f9`,"signal-state":`#22d3ee`,"signal-method":`#fb7185`},_w=class e{rpc=Zg(null);filter=L(``);mode=L(`source`);sourceEntries=L([]);runtimeState=L(null);selectedAction=L(null);kindLegend=Object.entries(gw).map(([e,t])=>({kind:e,color:t}));filteredEntries=Gg(()=>{let e=this.filter().toLowerCase();return this.sourceEntries().filter(t=>t.name.toLowerCase().includes(e)||t.kind.toLowerCase().includes(e))});groupedEntries=Gg(()=>{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=Gg(()=>{let e=this.filter().toLowerCase(),t=[...this.runtimeState()?.actions??[]].reverse();return e?t.filter(t=>t.type.toLowerCase().includes(e)):t});constructor(){Ks(()=>{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 gw[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,tw,1,0,`span`,4),J()()(),V(8,cw,2,1),V(9,hw,2,1)),e&2&&(B(),Gh(`value`,t.filter()),B(2),ug(`active`,t.mode()===`source`),B(2),ug(`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:[p_],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; + }`]})},vw={signal:`Signal Forms`,reactive:`Reactive`,template:`Template-driven`},yw={own:`validator`,directive:`template attribute`,tree:`cross-field rule`,async:`async`,parse:`parse`,submission:`server`,schema:`schema`,manual:`setErrors`};function bw(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 xw(e,t){return await bw(e,`request-form-action`,t)??{ok:!1,error:`The devtools server did not answer.`}}function Sw(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 Cw(e){return(e??``).replace(/^_Labels, paths.*_\n\n/,``).replace(/`/g,``).replace(/\*\*/g,``)}function ww(e,t){if(e&1){let e=Wh();q(0,`label`,4),Z(1),J(),q(2,`input`,5),Y(`input`,function(t){return ho(e),go(X().draft.set(t.target.value))})(`keydown.enter`,function(){return ho(e),go(X().setValue())}),J(),q(3,`button`,2),Y(`click`,function(){return ho(e),go(X().setValue())}),Z(4,`Set`),J()}if(e&2){let e=X();B(),$(`New value for `,e.node().path),B(),Gh(`value`,e.draft())}}var Tw=class e{form=Zg.required();node=Zg.required();version=Zg(0);rpc=Zg(null);text=L(``);draft=L(``);message=L(``);constructor(){Ks(()=>{let e=this.form().id,t=this.node().path;this.version();let n=this.rpc();Kg(()=>this.load(n,e,t))})}async load(e,t,n){let r=await bw(e,`forms-explain`,{kind:`field`,form:t,path:n});this.form().id===t&&this.node().path===n&&this.text.set(Cw(r))}async act(e){let t=await xw(this.rpc(),{action:e,formId:this.form().id,path:this.node().path});this.message.set(t.expression?`${Sw(t)} ${t.expression}`:Sw(t))}async setValue(){let e=this.draft(),t=e;try{t=JSON.parse(e)}catch{t=e}let n=await xw(this.rpc(),{action:`set-value`,formId:this.form().id,path:this.node().path,value:t,mode:`user`});this.message.set(Sw(n))}static ɵfac=function(t){return new(t||e)};static ɵcmp=qp({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,ww,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&&(B(),Q(t.node().path||`(form)`),B(2),Q(t.text()||`Loading…`),B(2),H(t.node().type===`control`&&!t.node().redacted?5:-1),B(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 Ew(e,t){e&1&&(q(0,`p`,0),Z(1,`Checking…`),J())}function Dw(e,t){e&1&&(q(0,`p`,0),Z(1,`No problems found. For generic accessibility, run axe on the page.`),J())}function Ow(e,t){if(e&1&&(q(0,`span`,0),Z(1),J()),e&2){let e=X().$implicit;B(),$(`at `,e.path)}}function kw(e,t){if(e&1&&(q(0,`li`)(1,`span`,2),Z(2),J(),q(3,`code`),Z(4),J(),V(5,Ow,2,1,`span`,0),q(6,`div`),Z(7),J(),q(8,`div`,0),Z(9),J()()),e&2){let e=t.$implicit;B(),ph(`data-tone`,e.severity===`info`?``:e.severity===`error`?`bad`:`warn`),B(),Q(e.severity),B(2),Q(e.rule),B(),H(e.path?5:-1),B(2),Q(e.message),B(2),$(`Fix: `,e.fix)}}function Aw(e,t){if(e&1&&(q(0,`ul`,1),U(1,kw,10,6,`li`,null,Ch),J()),e&2){let e=X();B(),W(e.findings())}}var jw=class e{formId=Zg.required();version=Zg(0);rpc=Zg(null);submit=L(``);payload=L(``);message=L(``);constructor(){Ks(()=>{let e=this.formId();this.version();let t=this.rpc();Kg(async()=>{let[n,r]=await Promise.all([bw(t,`forms-explain`,{kind:`submit`,form:e}),bw(t,`forms-explain`,{kind:`payload`,form:e})]);this.formId()===e&&(this.submit.set(Cw(n)),this.payload.set(Cw(r)))})})}async copyFixture(){let e=(await bw(this.rpc(),`forms-explain`,{kind:`fixture`,form:this.formId()})??``).match(/```ts\n([\s\S]*?)```/)?.[1]??``;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=qp({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&&(B(3),Q(t.submit()||`Loading…`),B(4),Q(t.payload()||`Loading…`),B(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; + }`]})},Mw=class e{formId=Zg.required();version=Zg(0);rpc=Zg(null);findings=L(null);constructor(){Ks(()=>{let e=this.formId();this.version();let t=this.rpc();Kg(async()=>{let n=await bw(t,`forms-lint`,{form:e});this.formId()===e&&this.findings.set(n??[])})})}static ɵfac=function(t){return new(t||e)};static ɵcmp=qp({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,Ew,2,0,`p`,0)(1,Dw,2,0,`p`,0)(2,Aw,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; + }`]})},Nw=(e,t)=>t.formId+`#`+t.seq;function Pw(e,t){if(e&1){let e=Wh();q(0,`label`)(1,`input`,4),Y(`change`,function(){let t=ho(e).$implicit;return go(X().filter.set(t))}),J(),Z(2),J()}if(e&2){let e=t.$implicit,n=X();B(),Gh(`value`,e)(`checked`,e===n.filter()),B(),$(` `,e,` `)}}function Fw(e,t){if(e&1&&(q(0,`span`,6),Z(1),J()),e&2){let e=X().$implicit;ph(`data-tone`,e.outcome===`ran`?``:`bad`),B(),Q(e.outcome)}}function Iw(e,t){if(e&1&&(q(0,`span`,3),Z(1),J(),Z(2,` → `)),e&2){let e=X().$implicit;B(),Q(e.prev)}}function Lw(e,t){if(e&1&&(q(0,`span`,6),Z(1),J()),e&2){let e=X().$implicit;B(),$(`×`,e.count)}}function Rw(e,t){if(e&1&&(q(0,`span`,6),Z(1),J()),e&2){let e=X().$implicit;B(),Q(e.origin)}}function zw(e,t){if(e&1&&(q(0,`li`)(1,`time`),Z(2),J(),q(3,`code`),Z(4),J(),q(5,`span`,5),Z(6),J(),V(7,Fw,2,2,`span`,6),q(8,`span`,7),V(9,Iw,3,1),Z(10),J(),V(11,Lw,2,1,`span`,6),V(12,Rw,2,1,`span`,6),J()),e&2){let e=t.$implicit,n=X(2);ph(`data-type`,e.type),B(2),Q(n.time(e.timestamp)),B(2),Q(e.path||`(form)`),B(2),Q(e.type),B(),H(e.outcome?7:-1),B(2),H(e.prev===void 0?-1:9),B(),$(` `,e.detail,` `),B(),H(e.count&&e.count>1?11:-1),B(),H(e.origin?12:-1)}}function Bw(e,t){if(e&1&&(q(0,`ol`,2),U(1,zw,13,9,`li`,null,Nw),J()),e&2){let e=X();B(),W(e.shown())}}function Vw(e,t){e&1&&(q(0,`p`,3),Z(1,`No changes yet. Type into the form to see them here.`),J())}var Hw=[`all`,`user`,`code`,`devtools`],Uw=class e{events=Zg.required();origins=Hw;filter=L(`all`);shown=Gg(()=>{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=qp({type:e,selectors:[[`app-forms-timeline`]],inputs:{events:[1,`events`]},decls:7,vars:1,consts:[[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`]],template:function(e,t){e&1&&(q(0,`fieldset`,0)(1,`legend`,1),Z(2,`Show changes from`),J(),U(3,Pw,3,3,`label`,null,wh),J(),V(5,Bw,3,0,`ol`,2)(6,Vw,2,0,`p`,3)),e&2&&(B(3),W(t.origins),B(2),H(t.shown().length?5:6))},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; + }`]})},Ww=()=>[],Gw=(e,t)=>t.id,Kw=(e,t)=>t.node.path;function qw(e,t){e&1&&(G(0,`p`,0),Z(1,`Connecting…`),K())}function Jw(e,t){e&1&&(G(0,`p`,0),Z(1,`Could not load forms from the devtools server. Reload to try again.`),K())}function Yw(e,t){e&1&&(G(0,`p`,0),Z(1,`Loading forms…`),K())}function Xw(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 Zw(e,t){e&1&&(G(0,`span`,10),Z(1),G(2,`span`,9),Z(3,` errors`),K()()),e&2&&(B(),Q(t))}function Qw(e,t){if(e&1){let e=Wh();G(0,`li`)(1,`button`,5),Jh(`click`,function(){let t=ho(e).$implicit;return go(X(2).selectForm(t.id))}),Ih(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,Zw,4,1,`span`,10),K()()}if(e&2){let e,n=t.$implicit,r=X(2);B(),ug(`active`,n.id===r.selected()?.id),ph(`aria-current`,n.id===r.selected()?.id?`true`:null),B(),ph(`data-status`,n.root.status),B(2),Q(n.label),B(2),kg(``,r.kindLabel(n.kind),` · `,n.id,` `),B(2),$(`, `,n.root.status),B(),H((e=r.counts().get(n.id)?.errors)?9:-1,e)}}function $w(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X();B(),Q(e.submitted?`submitted`:`not submitted`)}}function eT(e,t){e&1&&(G(0,`span`),Z(1,`submitting`),K())}function tT(e,t){if(e&1){let e=Wh();G(0,`button`,14),Jh(`click`,function(){return ho(e),go(X(3).confirmAct(`restore`))}),Z(1),K()}if(e&2){let e=X(3);B(),$(` `,e.armed()===`restore`?`Confirm restore`:`Restore `+e.snapshot(),` `)}}function nT(e,t){if(e&1){let e=Wh();G(0,`button`,22),Jh(`click`,function(){let t=ho(e).$implicit;return go(X(3).tab_.set(t.id))}),Z(1),K()}if(e&2){let e=t.$implicit,n=X(3);Nh(`id`,`forms-tab-`+e.id),ph(`aria-selected`,e.id===n.tab_())(`aria-controls`,`forms-panel-`+e.id)(`tabindex`,e.id===n.tab_()?0:-1),B(),$(` `,e.label,` `)}}function rT(e,t){if(e&1){let e=Wh();G(0,`label`)(1,`input`,29),Jh(`change`,function(){let t=ho(e).$implicit;return go(X(4).toggleChip(t.id))}),K(),Z(2),K()}if(e&2){let e=t.$implicit,n=X(4);B(),Nh(`checked`,n.active().has(e.id)),B(),$(` `,e.label,` `)}}function iT(e,t){if(e&1&&(G(0,`div`,2),Z(1,` typed `),G(2,`code`),Z(3),Fg(4,`json`),K(),Z(5,`, not in the model yet `),K()),e&2){let e=X(2).$implicit;B(3),Q(Lg(4,1,e.node.uncommitted))}}function aT(e,t){if(e&1&&(G(0,`div`,2),Z(1,` resets to `),G(2,`code`),Z(3),Fg(4,`json`),K()()),e&2){let e=X(2).$implicit;B(3),Q(Lg(4,1,e.node.defaultValue))}}function oT(e,t){if(e&1&&(G(0,`code`),Z(1),Fg(2,`json`),K(),V(3,iT,6,3,`div`,2),V(4,aT,5,3,`div`,2)),e&2){let e=X().$implicit;B(),Q(Lg(2,3,e.node.value)),B(2),H(e.node.uncommitted===void 0?-1:3),B(),H(e.node.defaultValue===void 0?-1:4)}}function sT(e,t){e&1&&(G(0,`span`,2),Z(1,`not created yet`),K())}function cT(e,t){if(e&1&&(G(0,`span`,12),Z(1),K()),e&2){let e=X().$implicit;ph(`data-status`,e.node.status),B(),Q(e.node.status)}}function lT(e,t){e&1&&(G(0,`span`),Z(1,`touched`),K())}function uT(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;B(),Q(e.node.changed===!1?`dirty, unchanged`:`dirty`)}}function dT(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;B(),$(`not validated (`,e.node.skipped,`)`)}}function fT(e,t){if(e&1&&(G(0,`span`,36),Z(1),K()),e&2){let e=X().$implicit;B(),$(`stale: `,e.node.stale.join(`, `))}}function pT(e,t){e&1&&(G(0,`span`,36),Z(1,`view out of sync`),K())}function mT(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;B(),$(`redacted (`,e.node.redacted,`)`)}}function hT(e,t){e&1&&(G(0,`span`),Z(1,`required`),K())}function gT(e,t){e&1&&(G(0,`span`),Z(1,`readonly`),K())}function _T(e,t){e&1&&(G(0,`span`),Z(1,`hidden`),K())}function vT(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;B(),$(`updates on `,e.node.updateOn)}}function yT(e,t){e&1&&(G(0,`span`),Z(1,`debouncing`),K())}function bT(e,t){e&1&&(G(0,`span`),Z(1,`validators`),K())}function xT(e,t){e&1&&(G(0,`span`),Z(1,`async validator`),K())}function ST(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=t.$implicit;B(),Q(e)}}function CT(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=X().$implicit;B(),Q(e.node.accessor)}}function wT(e,t){if(e&1&&(G(0,`span`),Z(1),K()),e&2){let e=t.$implicit;B(),$(`disabled: `,e)}}function TT(e,t){if(e&1&&(G(0,`span`,40),Z(1),K()),e&2){let e=X().$implicit,t=X(5);B(),Q(t.sourceText(e))}}function ET(e,t){if(e&1&&(G(0,`div`),Z(1),G(2,`code`,39),Z(3),K(),V(4,TT,2,1,`span`,40),K()),e&2){let e=t.$implicit,n=X().$implicit,r=X(4);B(),$(` `,r.errorText(n.node,e),` `),B(2),Q(e.kind),B(),H(e.source?4:-1)}}function DT(e,t){e&1&&(G(0,`div`,38),Z(1,`not shown to the user`),K())}function OT(e,t){if(e&1&&(G(0,`tr`)(1,`td`,41),Z(2),K()()),e&2){let e=X().$implicit;B(),lg(`padding-left`,24+e.depth*16,`px`),B(),kg(` `,e.node.truncated,` more fields under `,e.node.path||`the form`,` not shown `)}}function kT(e,t){if(e&1){let e=Wh();G(0,`tr`,30),Jh(`mouseenter`,function(){let t=ho(e).$implicit,n=X(2);return go(X(2).highlight(n.id,t.node.path))})(`mouseleave`,function(){return ho(e),go(X(4).highlight(null,``))}),G(1,`th`,31)(2,`button`,32),Jh(`focus`,function(){let t=ho(e).$implicit,n=X(2);return go(X(2).highlight(n.id,t.node.path))})(`blur`,function(){return ho(e),go(X(4).highlight(null,``))})(`click`,function(){let t=ho(e).$implicit;return go(X(4).fieldPath.set(t.node.path))}),Z(3),K(),G(4,`span`,33),Z(5),K()(),G(6,`td`,34),V(7,oT,5,5),K(),G(8,`td`),V(9,sT,2,0,`span`,2)(10,cT,2,2,`span`,12),K(),G(11,`td`,35),V(12,lT,2,0,`span`),V(13,uT,2,1,`span`),V(14,dT,2,1,`span`),V(15,fT,2,1,`span`,36),V(16,pT,2,0,`span`,36),V(17,mT,2,1,`span`),V(18,hT,2,0,`span`),V(19,gT,2,0,`span`),V(20,_T,2,0,`span`),V(21,vT,2,1,`span`),V(22,yT,2,0,`span`),V(23,bT,2,0,`span`),V(24,xT,2,0,`span`),U(25,ST,2,1,`span`,null,wh),V(27,CT,2,1,`span`),U(28,wT,2,1,`span`,null,Ch),K(),G(30,`td`,37),U(31,ET,5,3,`div`,null,Ch),V(33,DT,2,0,`div`,38),K()(),V(34,OT,3,4,`tr`)}if(e&2){let e=t.$implicit,n=X(4);ug(`invalid`,e.node.errors.length),B(),lg(`padding-left`,8+e.depth*16,`px`),B(),ph(`aria-label`,`Highlight `+(e.node.path||`the form`)+` on the page`)(`aria-pressed`,e.node.path===n.fieldPath()),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.skipped?14:-1),B(),H(e.node.stale?.length?15:-1),B(),H(e.node.dom?.drift===void 0?-1:16),B(),H(e.node.redacted?17:-1),B(),H(e.node.required?18:-1),B(),H(e.node.readonly?19:-1),B(),H(e.node.hidden?20:-1),B(),H(e.node.updateOn?21:-1),B(),H(e.node.debouncing?22:-1),B(),H(e.node.validators?.sync?23:-1),B(),H(e.node.validators?.async?24:-1),B(),W(n.constraintList(e.node)),B(2),H(e.node.accessor?27:-1),B(),W(e.node.disabledReasons??Mg(26,Ww)),B(3),W(e.node.errors),B(2),H(e.node.errors.length&&e.node.dom?.errorShown===!1?33:-1),B(),H(e.node.truncated?34:-1)}}function AT(e,t){if(e&1&&(G(0,`tr`)(1,`td`,41),Z(2),K()()),e&2){let e=X(4);B(2),$(` No field path matches "`,e.filter(),`". `)}}function jT(e,t){if(e&1&&Ih(0,`app-forms-field-detail`,28),e&2){let e=X(2),n=X(2);Nh(`form`,e)(`node`,t)(`version`,n.version())(`rpc`,n.rpc())}}function MT(e,t){if(e&1){let e=Wh();G(0,`fieldset`,23)(1,`legend`,9),Z(2,`Show only fields that are`),K(),U(3,rT,3,2,`label`,null,Gw),K(),G(5,`input`,24),Jh(`input`,function(t){return ho(e),go(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,kT,35,27,null,null,Kw,!1,AT,3,1,`tr`),K()()(),V(24,jT,1,4,`app-forms-field-detail`,28)}if(e&2){let e,t=X(3);B(3),W(t.chips),B(2),Nh(`value`,t.filter()),B(16),W(t.rows()),B(3),H((e=t.selectedNode())?24:-1,e)}}function NT(e,t){e&1&&Ih(0,`app-forms-timeline`,20),e&2&&Nh(`events`,X(3).selectedEvents())}function PT(e,t){if(e&1&&Ih(0,`app-forms-submit`,21),e&2){let e=X(),t=X(2);Nh(`formId`,e.id)(`version`,t.version())(`rpc`,t.rpc())}}function FT(e,t){if(e&1&&Ih(0,`app-forms-lint`,21),e&2){let e=X(),t=X(2);Nh(`formId`,e.id)(`version`,t.version())(`rpc`,t.rpc())}}function IT(e,t){if(e&1){let e=Wh();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,$w,2,1,`span`),V(9,eT,2,0,`span`),G(10,`span`,2),Z(11),K()(),G(12,`div`,13)(13,`button`,14),Jh(`click`,function(){return ho(e),go(X(2).act(`touch-all`))}),Z(14,`Touch all`),K(),G(15,`button`,14),Jh(`click`,function(){return ho(e),go(X(2).act(`revalidate`))}),Z(16,`Revalidate`),K(),G(17,`button`,14),Jh(`click`,function(){return ho(e),go(X(2).act(`focus-first-invalid`))}),Z(18,` Focus first invalid `),K(),G(19,`button`,14),Jh(`click`,function(){return ho(e),go(X(2).act(`snapshot`))}),Z(20,`Snapshot`),K(),V(21,tT,2,1,`button`,15),G(22,`button`,14),Jh(`click`,function(){return ho(e),go(X(2).confirmAct(`reset`))}),Z(23),K(),G(24,`button`,14),Jh(`click`,function(){return ho(e),go(X(2).confirmAct(`submit`))}),Z(25),K()(),G(26,`p`,16),Z(27),K(),G(28,`div`,17),Jh(`keydown`,function(t){return ho(e),go(X(2).onKey(t))}),U(29,nT,2,5,`button`,18,Gw),K(),G(31,`div`,19),V(32,MT,25,3)(33,NT,1,1,`app-forms-timeline`,20)(34,PT,1,3,`app-forms-submit`,21)(35,FT,1,3,`app-forms-lint`,21),K()()}if(e&2){let e,n=t,r=X(2);ph(`aria-label`,n.label),B(2),ph(`data-status`,n.root.status),B(),Q(n.root.status),B(2),Q(n.root.dirty?`dirty`:`pristine`),B(2),Q(n.root.touched?`touched`:`untouched`),B(),H(n.submitted===void 0?-1:8),B(),H(n.root.submitting?9:-1),B(2),kg(``,r.counts().get(n.id)?.fields,` fields, `,r.counts().get(n.id)?.errors,` errors`),B(10),H(r.snapshot()?21:-1),B(2),$(` `,r.armed()===`reset`?`Confirm reset`:`Reset`,` `),B(2),$(` `,r.armed()===`submit`?`Confirm submit`:`Submit`,` `),B(2),Q(r.message()),B(2),W(r.tabs),B(2),Nh(`id`,`forms-panel-`+r.tab_()),ph(`aria-labelledby`,`forms-tab-`+r.tab_()),B(),H((e=r.tab_())===`fields`?32:e===`timeline`?33:e===`submit`?34:e===`lint`?35:-1)}}function LT(e,t){if(e&1&&(G(0,`div`,1)(1,`ul`,3),U(2,Qw,10,9,`li`,null,Gw),K(),V(4,IT,36,16,`section`,4),K()),e&2){let e,t=X();B(2),W(t.forms()),B(2),H((e=t.selected())?4:-1,e)}}var RT=[{id:`fields`,label:`Fields`},{id:`timeline`,label:`Timeline`},{id:`submit`,label:`Submit`},{id:`lint`,label:`Lint`}],zT=[{id:`invalid`,label:`Invalid`},{id:`dirty`,label:`Dirty`},{id:`touched`,label:`Touched`},{id:`disabled`,label:`Disabled`},{id:`hidden-error`,label:`Error not shown`}];function BT(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 VT(e){return e.errors.length+(e.children??[]).reduce((e,t)=>e+VT(t),0)}function HT(e){return 1+(e.children??[]).reduce((e,t)=>e+HT(t),0)}var UT=class e{rpc=Zg(null);forms=L([]);events=L([]);loading=L(!0);failed=L(!1);selectedId=L(null);filter=L(``);tabs=RT;chips=zT;tab_=L(`fields`);active=L(new Set);fieldPath=L(null);version=L(0);message=L(``);armed=L(null);snapshot=L(null);unsubscribe=null;destroyRef=P(as);counts=Gg(()=>new Map(this.forms().map(e=>[e.id,{fields:HT(e.root),errors:VT(e.root)}])));selected=Gg(()=>{let e=this.forms();return e.find(e=>e.id===this.selectedId())??e[0]??null});rows=Gg(()=>{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=>BT(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=Gg(()=>{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=Gg(()=>{let e=this.selected()?.id;return this.events().filter(t=>t.formId===e).slice(-200)});constructor(){Ks(()=>{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??[]),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)}}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 xw(this.rpc(),{action:e,formId:n.id,...t});r.snapshot&&this.snapshot.set(r.snapshot),this.message.set(Sw(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=yw[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 vw[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=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`],[`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`],[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`]],template:function(e,t){e&1&&V(0,qw,2,0,`p`,0)(1,Jw,2,0,`p`,0)(2,Yw,2,0,`p`,0)(3,Xw,5,0,`div`,0)(4,LT,5,1,`div`,1),e&2&&H(t.rpc()?t.failed()?1:t.loading()?2:t.forms().length?4:3:0)},dependencies:[Tw,Uw,jw,Mw,p_],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; + }`]})},WT=(e,t)=>t.id;function GT(e,t){if(e&1){let e=Wh();G(0,`button`,13),Jh(`click`,function(){let t=ho(e).$implicit;return go(X().switchTab(t.id))}),Z(1),K()}if(e&2){let e=t.$implicit;ug(`active`,X().tab()===e.id),B(),Q(e.label)}}function KT(e,t){if(e&1){let e=Wh();G(0,`app-dashboard`,14),Jh(`navigate`,function(t){return ho(e),go(X().switchTab(t))}),K()}e&2&&Nh(`rpc`,X().rpc())}function qT(e,t){e&1&&Ih(0,`app-component-tree`,12),e&2&&Nh(`rpc`,X().rpc())}function JT(e,t){e&1&&Ih(0,`app-route-inspector`,12),e&2&&Nh(`rpc`,X().rpc())}function YT(e,t){e&1&&Ih(0,`app-signal-inspector`,12),e&2&&Nh(`rpc`,X().rpc())}function XT(e,t){e&1&&Ih(0,`app-di-inspector`,12),e&2&&Nh(`rpc`,X().rpc())}function ZT(e,t){e&1&&Ih(0,`app-store-inspector`,12),e&2&&Nh(`rpc`,X().rpc())}function QT(e,t){e&1&&Ih(0,`app-forms-inspector`,12),e&2&&Nh(`rpc`,X().rpc())}var $T=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=tE();LS(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),Jo(),G(2,`svg`,1)(3,`defs`)(4,`linearGradient`,2),Ih(5,`stop`,3)(6,`stop`,4)(7,`stop`,5)(8,`stop`,6)(9,`stop`,7)(10,`stop`,8),K()(),Ih(11,`path`,9),K(),Yo(),G(12,`span`),Z(13,`Angular DevTools`),K()(),G(14,`nav`),U(15,GT,2,3,`button`,10,WT),K(),G(17,`span`,11),Z(18),K()(),G(19,`main`),V(20,KT,1,1,`app-dashboard`,12)(21,qT,1,1,`app-component-tree`,12)(22,JT,1,1,`app-route-inspector`,12)(23,YT,1,1,`app-signal-inspector`,12)(24,XT,1,1,`app-di-inspector`,12)(25,ZT,1,1,`app-store-inspector`,12)(26,QT,1,1,`app-forms-inspector`,12),K()),e&2){let e;B(15),W(t.tabs),B(2),ug(`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:[RS,eC,sC,kC,QC,_w,UT],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 eE(e){try{return new URL(e,location.href).origin===location.origin}catch{return!1}}function tE(){let e=new URLSearchParams(location.search).get(`baseURL`);if(e&&eE(e))return e;if(!location.pathname.includes(`__ng-devtools`))return`/__ng-devtools/`}Z_($T).catch(console.error);export{ey as t}; \ No newline at end of file diff --git a/extension/ui/assets/index-ruy7p20M.js b/extension/ui/assets/index-ruy7p20M.js deleted file mode 100644 index 6c926b6..0000000 --- a/extension/ui/assets/index-ruy7p20M.js +++ /dev/null @@ -1,1170 +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 E.zone}static get currentTask(){return se}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){E={parent:E,zone:this};try{return this._zoneDelegate.invoke(this,e,t,n,r)}finally{E=E.parent}}runGuarded(e,t=null,n,r){E={parent:E,zone:this};try{try{return this._zoneDelegate.invoke(this,e,t,n,r)}catch(e){if(this._zoneDelegate.handleError(this,e))throw e}}finally{E=E.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=se;se=r,E={parent:E,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)}}E=E.parent,se=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,ce++;try{return e.runCount++,e.zone.runTask(e,t,n)}finally{try{ce===1&&!s[m]&&b()}finally{ce--}}}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&&ce===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:()=>E,onUnhandledError:le,microtaskDrainDone:le,scheduleMicroTask:y,showUncaughtError:()=>!i[c(`ignoreConsoleErrorUncaughtError`)],patchEventTarget:()=>[],patchOnProperties:le,patchMethod:()=>le,bindArguments:()=>[],patchThen:()=>le,patchMacroTask:()=>le,patchEventPrototype:()=>le,getGlobalObjects:()=>void 0,ObjectDefineProperty:()=>le,ObjectGetOwnPropertyDescriptor:()=>void 0,ObjectCreate:()=>void 0,ArraySlice:()=>[],patchClass:()=>le,wrapWithCurrentZone:()=>le,filterProperties:()=>[],attachOriginToPatched:()=>le,_redefineProperty:()=>le,patchCallbacks:()=>le,nativeScheduleMicroTask:v},E={parent:null,zone:new i(null,null)},se=null,ce=0;function le(){}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 ye(t,e),t})(a)}}}function oe(e){return e?e.writable===!1?!1:typeof e.get!=`function`||e.set!==void 0:!0}var E=typeof WorkerGlobalScope<`u`&&self instanceof WorkerGlobalScope,se=!(`nw`in w)&&w.process!==void 0&&w.process.toString()===`[object process]`,ce=!se&&!E&&!!(C&&re.HTMLElement),le=w.process!==void 0&&w.process.toString()===`[object process]`&&!E&&!!(C&&re.HTMLElement),ue=Object.create(null),de=S(`enable_beforeunload`),fe=function(e){if(e||=w.event,!e)return;let t=ue[e.type];t||=ue[e.type]=S(`ON_PROPERTY`+e.type);let n=this||e.target||w,r=n[t],i;if(ce&&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[de]&&typeof i==`string`?e.returnValue=i:i!=null&&!i&&e.preventDefault();return i};function pe(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=ue[s];c||=ue[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,fe),o?.call(n,null),n[c]=t,typeof t==`function`&&n.addEventListener(s,fe,!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 me(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 ye(e,t){e[S(`OriginalDelegate`)]=t}function be(e){return typeof e==`function`}function xe(e){return typeof e==`number`}var Se={useG:!0},Ce=Object.create(null),we={},Te=RegExp(`^`+te+`(\\w+)(true|false)$`),Ee=S(`propagationStopped`),De=[`capture`,`once`,`passive`,`signal`];function Oe(e,t){let n=(t?t(e):e)+ee,r=(t?t(e):e)+b,i=te+n,a=te+r;Ce[e]={[ee]:i,[b]:a}}function ke(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[Ce[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=Ce[e.eventName],n;t&&(n=t[e.capture?b:ee]);let r=n&&e.target[n];if(r){for(let t=0;tce.zone.cancelTask(ce);t.call(_,`abort`,e,{once:!0}),ce.removeAbortListener=()=>_.removeEventListener(`abort`,e)}if(y.target=null,E&&(E.taskData=null),ne&&(y.options.once=!0),typeof ce.options!=`boolean`&&(ce.options=g),ce.target=l,ce.capture=te,ce.eventName=u,m&&(ce.originalDelegate=p),c?re.unshift(ce):re.push(ce),s)return l}};return _[i]=he(ne,u,le,ue,g),w&&(_.prependListener=he(w,`.prependListener:`,E,ue,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=Ce[r],c;s&&(c=s[a?b:ee]);let l=c&&t[c];if(l)for(let e=0;efunction(t,n){t[Ee]=!0,e&&e.apply(t,n)})}function Me(e,t){t.patchMethod(e,`queueMicrotask`,e=>function(e,t){Zone.current.scheduleMicroTask(`queueMicrotask`,t[0])})}var Ne=S(`zoneTask`);function Pe(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 xe(r)?n.handleId=r:(n.handle=r,n.isRefreshable=be(r?.refresh)),t}function c(t){let{handle:n,handleId:r}=t.data;return a.call(e,n??r)}i=_e(e,t,n=>function(i,a){if(be(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[Ne]=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[Ne]=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=_e(e,n,t=>function(n,r){let i=r[0],a;xe(i)?(a=o[i],delete o[i]):(a=i?.[Ne],a?i[Ne]=null:a=i),a?.type?a.cancelFn&&a.zone.cancelTask(a):t.apply(e,r)})}function Fe(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 Ie(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 ze(e,t,n,r){e&&me(e,Re(e,t,n),r)}function Be(e){return Object.getOwnPropertyNames(e).filter(e=>e.startsWith(`on`)&&e.length>2).map(e=>e.substring(2))}function Ve(e,t){if(se&&!le||Zone[e.symbol(`patchEvents`)])return;let n=t.__Zone_ignore_on_properties,r=[];if(ce){let e=window;r=r.concat([`Document`,`SVGElement`,`Element`,`HTMLElement`,`HTMLBodyElement`,`HTMLMediaElement`,`HTMLFrameSetElement`,`HTMLFrameElement`,`HTMLIFrameElement`,`HTMLMarqueeElement`,`Worker`]),ze(e,Be(e),n,p(e))}r=r.concat([`XMLHttpRequest`,`XMLHttpRequestEventTarget`,`IDBIndex`,`IDBRequest`,`IDBOpenDBRequest`,`IDBDatabase`,`IDBTransaction`,`IDBCursor`,`WebSocket`]);for(let e=0;e{let t=`clear`;Pe(e,`set`,t,`Timeout`),Pe(e,`set`,t,`Interval`),Pe(e,`set`,t,`Immediate`)}),e.__load_patch(`requestAnimationFrame`,e=>{Pe(e,`request`,`cancel`,`AnimationFrame`),Pe(e,`mozRequest`,`mozCancel`,`AnimationFrame`),Pe(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)=>{Le(e,n),Ie(e,n);let r=e.XMLHttpRequestEventTarget;r&&r.prototype&&n.patchEventTarget(e,n,[r.prototype])}),e.__load_patch(`MutationObserver`,(e,t,n)=>{ge(`MutationObserver`),ge(`WebKitMutationObserver`)}),e.__load_patch(`IntersectionObserver`,(e,t,n)=>{ge(`IntersectionObserver`)}),e.__load_patch(`FileReader`,(e,t,n)=>{ge(`FileReader`)}),e.__load_patch(`on_property`,(e,t,n)=>{Ve(n,e)}),e.__load_patch(`customElements`,(e,t,n)=>{Fe(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=_e(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=_e(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){Ae(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)=>{Me(e,n)})}function Ue(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 E(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=E;function se(e){return function(t,n){let r=e.apply(t,n);if(r instanceof T)return r;let i=r.constructor;return i[oe]||E(i),r}}if(ae){E(ae);let t=ae.try;t&&typeof t==`function`&&(T.try=t),_e(e,`fetch`,e=>se(e))}return Promise[t.__symbol__(`uncaughtPromiseErrors`)]=s,T})}function We(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 Ge(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 Ke(e){e.__load_patch(`util`,(e,t,n)=>{let r=Be(e);n.patchOnProperties=me,n.patchMethod=_e,n.bindArguments=T,n.patchMacroTask=ve;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=je,n.patchEventTarget=ke,n.ObjectDefineProperty=f,n.ObjectGetOwnPropertyDescriptor=d,n.ObjectCreate=m,n.ArraySlice=h,n.patchClass=ge,n.wrapWithCurrentZone=ne,n.filterProperties=Re,n.attachOriginToPatched=ye,n._redefineProperty=Object.defineProperty,n.patchCallbacks=Ge,n.getGlobalObjects=()=>({globalSources:we,zoneSymbolEventNames:Ce,eventNames:r,isBrowser:ce,isMix:le,isNode:se,TRUE_STR:b,FALSE_STR:ee,ZONE_SYMBOL_PREFIX:te,ADD_EVENT_LISTENER_STR:g,REMOVE_EVENT_LISTENER_STR:_})})}function qe(e){Ue(e),We(e),Ke(e)}var Je=u();qe(Je),He(Je);var Ye=(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})(Ye||{}),Xe=(function(e){return e[e.None=0]=`None`,e[e.Const=1]=`Const`,e})(Xe||{}),Ze=class{modifiers;constructor(e=Xe.None){this.modifiers=e}hasModifier(e){return(this.modifiers&e)!==0}},Qe=(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})(Qe||{}),$e=class extends Ze{name;constructor(e,t){super(t),this.name=e}visitType(e,t){return e.visitBuiltinType(this,t)}};Qe.Dynamic;var et=new $e(Qe.Inferred);Qe.Bool,Qe.Int,Qe.Number,Qe.String,Qe.Function,Qe.None;var D=(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})(D||{});function tt(e,t){return e==null||t==null?e==t:e.isEquivalent(t)}function nt(e,t,n){let r=e.length;if(r!==t.length)return!1;for(let i=0;ie.isEquivalent(t))}var it=class{leadingComments;type;sourceSpan;constructor(e,t,n){this.leadingComments=n,this.type=e||null,this.sourceSpan=t||null}prop(e,t){return new mt(this,e,null,t)}key(e,t,n){return new ht(this,e,t,n)}callFn(e,t,n,r){return new st(this,e,null,t,n,r)}instantiate(e,t,n,r){return new ct(this,e,t,n)}conditional(e,t=null,n,r){return new ft(this,e,t,null,n)}equals(e,t){return new pt(D.Equals,this,e,null,t)}notEquals(e,t){return new pt(D.NotEquals,this,e,null,t)}identical(e,t){return new pt(D.Identical,this,e,null,t)}notIdentical(e,t){return new pt(D.NotIdentical,this,e,null,t)}minus(e,t){return new pt(D.Minus,this,e,null,t)}plus(e,t){return new pt(D.Plus,this,e,null,t)}divide(e,t){return new pt(D.Divide,this,e,null,t)}multiply(e,t){return new pt(D.Multiply,this,e,null,t)}modulo(e,t){return new pt(D.Modulo,this,e,null,t)}power(e,t){return new pt(D.Exponentiation,this,e,null,t)}and(e,t){return new pt(D.And,this,e,null,t)}bitwiseOr(e,t){return new pt(D.BitwiseOr,this,e,null,t)}bitwiseAnd(e,t){return new pt(D.BitwiseAnd,this,e,null,t)}or(e,t){return new pt(D.Or,this,e,null,t)}lower(e,t){return new pt(D.Lower,this,e,null,t)}lowerEquals(e,t){return new pt(D.LowerEquals,this,e,null,t)}bigger(e,t){return new pt(D.Bigger,this,e,null,t)}biggerEquals(e,t){return new pt(D.BiggerEquals,this,e,null,t)}isBlank(e){return this.equals(bt,e)}nullishCoalesce(e,t){return new pt(D.NullishCoalesce,this,e,null,t)}toStmt(e){return new Ct(this,null,e)}},at=class e extends it{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 pt(D.Assign,this,e,null,this.sourceSpan)}},ot=class e extends it{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())}},st=class e extends it{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)&&rt(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)}},ct=class e extends it{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)&&rt(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)}},lt=class e extends it{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)}},ut=class e extends it{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)}},dt=class e extends it{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)}},ft=class e extends it{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)&&tt(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)}},pt=class e extends it{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===D.Assign||e===D.AdditionAssignment||e===D.SubtractionAssignment||e===D.MultiplicationAssignment||e===D.DivisionAssignment||e===D.RemainderAssignment||e===D.ExponentiationAssignment||e===D.AndAssignment||e===D.OrAssignment||e===D.NullishCoalesceAssignment}},mt=class e extends it{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 pt(D.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)}},ht=class e extends it{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 pt(D.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)}},gt=class e extends it{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&&rt(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)}},_t=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()}},vt=class e extends it{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&&rt(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)}},yt=class e extends it{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)}},bt=new ut(null,et,null),xt=(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})(xt||{}),St=class{modifiers;sourceSpan;leadingComments;constructor(e=xt.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)}},Ct=class e extends St{expr;constructor(e,t,n){super(xt.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 ut&&typeof e.value==`string`)return`"${e.value}"`;if(e instanceof ut)return String(e.value);if(e instanceof lt)return`/${e.body}/${e.flags??``}`;if(e instanceof gt){let t=[];for(let n of e.entries)t.push(this.keyOf(n));return`[${t.join(`,`)}]`}if(e instanceof vt){let t=[];for(let n of e.entries)if(n instanceof _t)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 dt)return`import("${e.value.moduleName}", ${e.value.name})`;if(e instanceof at)return`read(${e.name})`;if(e instanceof ot)return`typeof(${this.keyOf(e.expr)})`;if(e instanceof yt)return`...${this.keyOf(e.expression)}`;throw Error(`${this.constructor.name} does not handle expressions of type ${e.constructor.name}`)}});var O=`@angular/core`,k=(()=>{class e{static core={name:null,moduleName:O};static namespaceHTML={name:`ɵɵnamespaceHTML`,moduleName:O};static namespaceMathML={name:`ɵɵnamespaceMathML`,moduleName:O};static namespaceSVG={name:`ɵɵnamespaceSVG`,moduleName:O};static element={name:`ɵɵelement`,moduleName:O};static elementStart={name:`ɵɵelementStart`,moduleName:O};static elementEnd={name:`ɵɵelementEnd`,moduleName:O};static foreignComponent={name:`ɵɵforeignComponent`,moduleName:O};static foreignContent={name:`ɵɵforeignContent`,moduleName:O};static foreignContentFn={name:`ɵɵforeignContentFn`,moduleName:O};static domElement={name:`ɵɵdomElement`,moduleName:O};static domElementStart={name:`ɵɵdomElementStart`,moduleName:O};static domElementEnd={name:`ɵɵdomElementEnd`,moduleName:O};static domElementContainer={name:`ɵɵdomElementContainer`,moduleName:O};static domElementContainerStart={name:`ɵɵdomElementContainerStart`,moduleName:O};static domElementContainerEnd={name:`ɵɵdomElementContainerEnd`,moduleName:O};static domTemplate={name:`ɵɵdomTemplate`,moduleName:O};static domListener={name:`ɵɵdomListener`,moduleName:O};static advance={name:`ɵɵadvance`,moduleName:O};static syntheticHostProperty={name:`ɵɵsyntheticHostProperty`,moduleName:O};static syntheticHostListener={name:`ɵɵsyntheticHostListener`,moduleName:O};static attribute={name:`ɵɵattribute`,moduleName:O};static classProp={name:`ɵɵclassProp`,moduleName:O};static elementContainerStart={name:`ɵɵelementContainerStart`,moduleName:O};static elementContainerEnd={name:`ɵɵelementContainerEnd`,moduleName:O};static elementContainer={name:`ɵɵelementContainer`,moduleName:O};static styleMap={name:`ɵɵstyleMap`,moduleName:O};static classMap={name:`ɵɵclassMap`,moduleName:O};static styleProp={name:`ɵɵstyleProp`,moduleName:O};static interpolate={name:`ɵɵinterpolate`,moduleName:O};static interpolate1={name:`ɵɵinterpolate1`,moduleName:O};static interpolate2={name:`ɵɵinterpolate2`,moduleName:O};static interpolate3={name:`ɵɵinterpolate3`,moduleName:O};static interpolate4={name:`ɵɵinterpolate4`,moduleName:O};static interpolate5={name:`ɵɵinterpolate5`,moduleName:O};static interpolate6={name:`ɵɵinterpolate6`,moduleName:O};static interpolate7={name:`ɵɵinterpolate7`,moduleName:O};static interpolate8={name:`ɵɵinterpolate8`,moduleName:O};static interpolateV={name:`ɵɵinterpolateV`,moduleName:O};static nextContext={name:`ɵɵnextContext`,moduleName:O};static resetView={name:`ɵɵresetView`,moduleName:O};static templateCreate={name:`ɵɵtemplate`,moduleName:O};static defer={name:`ɵɵdefer`,moduleName:O};static deferWhen={name:`ɵɵdeferWhen`,moduleName:O};static deferOnIdle={name:`ɵɵdeferOnIdle`,moduleName:O};static deferOnImmediate={name:`ɵɵdeferOnImmediate`,moduleName:O};static deferOnTimer={name:`ɵɵdeferOnTimer`,moduleName:O};static deferOnHover={name:`ɵɵdeferOnHover`,moduleName:O};static deferOnInteraction={name:`ɵɵdeferOnInteraction`,moduleName:O};static deferOnViewport={name:`ɵɵdeferOnViewport`,moduleName:O};static deferPrefetchWhen={name:`ɵɵdeferPrefetchWhen`,moduleName:O};static deferPrefetchOnIdle={name:`ɵɵdeferPrefetchOnIdle`,moduleName:O};static deferPrefetchOnImmediate={name:`ɵɵdeferPrefetchOnImmediate`,moduleName:O};static deferPrefetchOnTimer={name:`ɵɵdeferPrefetchOnTimer`,moduleName:O};static deferPrefetchOnHover={name:`ɵɵdeferPrefetchOnHover`,moduleName:O};static deferPrefetchOnInteraction={name:`ɵɵdeferPrefetchOnInteraction`,moduleName:O};static deferPrefetchOnViewport={name:`ɵɵdeferPrefetchOnViewport`,moduleName:O};static deferHydrateWhen={name:`ɵɵdeferHydrateWhen`,moduleName:O};static deferHydrateNever={name:`ɵɵdeferHydrateNever`,moduleName:O};static deferHydrateOnIdle={name:`ɵɵdeferHydrateOnIdle`,moduleName:O};static deferHydrateOnImmediate={name:`ɵɵdeferHydrateOnImmediate`,moduleName:O};static deferHydrateOnTimer={name:`ɵɵdeferHydrateOnTimer`,moduleName:O};static deferHydrateOnHover={name:`ɵɵdeferHydrateOnHover`,moduleName:O};static deferHydrateOnInteraction={name:`ɵɵdeferHydrateOnInteraction`,moduleName:O};static deferHydrateOnViewport={name:`ɵɵdeferHydrateOnViewport`,moduleName:O};static deferEnableTimerScheduling={name:`ɵɵdeferEnableTimerScheduling`,moduleName:O};static enableIncrementalHydrationRuntime={name:`ɵɵenableIncrementalHydrationRuntime`,moduleName:O};static conditionalCreate={name:`ɵɵconditionalCreate`,moduleName:O};static conditionalBranchCreate={name:`ɵɵconditionalBranchCreate`,moduleName:O};static conditional={name:`ɵɵconditional`,moduleName:O};static repeater={name:`ɵɵrepeater`,moduleName:O};static repeaterCreate={name:`ɵɵrepeaterCreate`,moduleName:O};static repeaterTrackByIndex={name:`ɵɵrepeaterTrackByIndex`,moduleName:O};static repeaterTrackByIdentity={name:`ɵɵrepeaterTrackByIdentity`,moduleName:O};static componentInstance={name:`ɵɵcomponentInstance`,moduleName:O};static text={name:`ɵɵtext`,moduleName:O};static enableBindings={name:`ɵɵenableBindings`,moduleName:O};static disableBindings={name:`ɵɵdisableBindings`,moduleName:O};static getCurrentView={name:`ɵɵgetCurrentView`,moduleName:O};static textInterpolate={name:`ɵɵtextInterpolate`,moduleName:O};static textInterpolate1={name:`ɵɵtextInterpolate1`,moduleName:O};static textInterpolate2={name:`ɵɵtextInterpolate2`,moduleName:O};static textInterpolate3={name:`ɵɵtextInterpolate3`,moduleName:O};static textInterpolate4={name:`ɵɵtextInterpolate4`,moduleName:O};static textInterpolate5={name:`ɵɵtextInterpolate5`,moduleName:O};static textInterpolate6={name:`ɵɵtextInterpolate6`,moduleName:O};static textInterpolate7={name:`ɵɵtextInterpolate7`,moduleName:O};static textInterpolate8={name:`ɵɵtextInterpolate8`,moduleName:O};static textInterpolateV={name:`ɵɵtextInterpolateV`,moduleName:O};static restoreView={name:`ɵɵrestoreView`,moduleName:O};static pureFunction0={name:`ɵɵpureFunction0`,moduleName:O};static pureFunction1={name:`ɵɵpureFunction1`,moduleName:O};static pureFunction2={name:`ɵɵpureFunction2`,moduleName:O};static pureFunction3={name:`ɵɵpureFunction3`,moduleName:O};static pureFunction4={name:`ɵɵpureFunction4`,moduleName:O};static pureFunction5={name:`ɵɵpureFunction5`,moduleName:O};static pureFunction6={name:`ɵɵpureFunction6`,moduleName:O};static pureFunction7={name:`ɵɵpureFunction7`,moduleName:O};static pureFunction8={name:`ɵɵpureFunction8`,moduleName:O};static pureFunctionV={name:`ɵɵpureFunctionV`,moduleName:O};static pipeBind1={name:`ɵɵpipeBind1`,moduleName:O};static pipeBind2={name:`ɵɵpipeBind2`,moduleName:O};static pipeBind3={name:`ɵɵpipeBind3`,moduleName:O};static pipeBind4={name:`ɵɵpipeBind4`,moduleName:O};static pipeBindV={name:`ɵɵpipeBindV`,moduleName:O};static domProperty={name:`ɵɵdomProperty`,moduleName:O};static ariaProperty={name:`ɵɵariaProperty`,moduleName:O};static property={name:`ɵɵproperty`,moduleName:O};static control={name:`ɵɵcontrol`,moduleName:O};static controlCreate={name:`ɵɵcontrolCreate`,moduleName:O};static animationEnterListener={name:`ɵɵanimateEnterListener`,moduleName:O};static animationLeaveListener={name:`ɵɵanimateLeaveListener`,moduleName:O};static animationEnter={name:`ɵɵanimateEnter`,moduleName:O};static animationLeave={name:`ɵɵanimateLeave`,moduleName:O};static i18n={name:`ɵɵi18n`,moduleName:O};static i18nAttributes={name:`ɵɵi18nAttributes`,moduleName:O};static i18nExp={name:`ɵɵi18nExp`,moduleName:O};static i18nStart={name:`ɵɵi18nStart`,moduleName:O};static i18nEnd={name:`ɵɵi18nEnd`,moduleName:O};static i18nApply={name:`ɵɵi18nApply`,moduleName:O};static i18nPostprocess={name:`ɵɵi18nPostprocess`,moduleName:O};static pipe={name:`ɵɵpipe`,moduleName:O};static projection={name:`ɵɵprojection`,moduleName:O};static projectionDef={name:`ɵɵprojectionDef`,moduleName:O};static reference={name:`ɵɵreference`,moduleName:O};static inject={name:`ɵɵinject`,moduleName:O};static injectAttribute={name:`ɵɵinjectAttribute`,moduleName:O};static directiveInject={name:`ɵɵdirectiveInject`,moduleName:O};static invalidFactory={name:`ɵɵinvalidFactory`,moduleName:O};static invalidFactoryDep={name:`ɵɵinvalidFactoryDep`,moduleName:O};static templateRefExtractor={name:`ɵɵtemplateRefExtractor`,moduleName:O};static forwardRef={name:`forwardRef`,moduleName:O};static resolveForwardRef={name:`resolveForwardRef`,moduleName:O};static replaceMetadata={name:`ɵɵreplaceMetadata`,moduleName:O};static getReplaceMetadataURL={name:`ɵɵgetReplaceMetadataURL`,moduleName:O};static ɵɵdefineInjectable={name:`ɵɵdefineInjectable`,moduleName:O};static declareInjectable={name:`ɵɵngDeclareInjectable`,moduleName:O};static InjectableDeclaration={name:`ɵɵInjectableDeclaration`,moduleName:O};static defineService={name:`ɵɵdefineService`,moduleName:O};static declareService={name:`ɵɵngDeclareService`,moduleName:O};static resolveWindow={name:`ɵɵresolveWindow`,moduleName:O};static resolveDocument={name:`ɵɵresolveDocument`,moduleName:O};static resolveBody={name:`ɵɵresolveBody`,moduleName:O};static getComponentDepsFactory={name:`ɵɵgetComponentDepsFactory`,moduleName:O};static defineComponent={name:`ɵɵdefineComponent`,moduleName:O};static declareComponent={name:`ɵɵngDeclareComponent`,moduleName:O};static setComponentScope={name:`ɵɵsetComponentScope`,moduleName:O};static ChangeDetectionStrategy={name:`ChangeDetectionStrategy`,moduleName:O};static ViewEncapsulation={name:`ViewEncapsulation`,moduleName:O};static ComponentDeclaration={name:`ɵɵComponentDeclaration`,moduleName:O};static FactoryDeclaration={name:`ɵɵFactoryDeclaration`,moduleName:O};static declareFactory={name:`ɵɵngDeclareFactory`,moduleName:O};static FactoryTarget={name:`ɵɵFactoryTarget`,moduleName:O};static defineDirective={name:`ɵɵdefineDirective`,moduleName:O};static declareDirective={name:`ɵɵngDeclareDirective`,moduleName:O};static DirectiveDeclaration={name:`ɵɵDirectiveDeclaration`,moduleName:O};static InjectorDef={name:`ɵɵInjectorDef`,moduleName:O};static InjectorDeclaration={name:`ɵɵInjectorDeclaration`,moduleName:O};static defineInjector={name:`ɵɵdefineInjector`,moduleName:O};static declareInjector={name:`ɵɵngDeclareInjector`,moduleName:O};static NgModuleDeclaration={name:`ɵɵNgModuleDeclaration`,moduleName:O};static ModuleWithProviders={name:`ModuleWithProviders`,moduleName:O};static defineNgModule={name:`ɵɵdefineNgModule`,moduleName:O};static declareNgModule={name:`ɵɵngDeclareNgModule`,moduleName:O};static setNgModuleScope={name:`ɵɵsetNgModuleScope`,moduleName:O};static registerNgModuleType={name:`ɵɵregisterNgModuleType`,moduleName:O};static PipeDeclaration={name:`ɵɵPipeDeclaration`,moduleName:O};static definePipe={name:`ɵɵdefinePipe`,moduleName:O};static declarePipe={name:`ɵɵngDeclarePipe`,moduleName:O};static declareClassMetadata={name:`ɵɵngDeclareClassMetadata`,moduleName:O};static declareClassMetadataAsync={name:`ɵɵngDeclareClassMetadataAsync`,moduleName:O};static setClassMetadata={name:`ɵsetClassMetadata`,moduleName:O};static setClassMetadataAsync={name:`ɵsetClassMetadataAsync`,moduleName:O};static setClassDebugInfo={name:`ɵsetClassDebugInfo`,moduleName:O};static queryRefresh={name:`ɵɵqueryRefresh`,moduleName:O};static viewQuery={name:`ɵɵviewQuery`,moduleName:O};static loadQuery={name:`ɵɵloadQuery`,moduleName:O};static contentQuery={name:`ɵɵcontentQuery`,moduleName:O};static viewQuerySignal={name:`ɵɵviewQuerySignal`,moduleName:O};static contentQuerySignal={name:`ɵɵcontentQuerySignal`,moduleName:O};static queryAdvance={name:`ɵɵqueryAdvance`,moduleName:O};static twoWayProperty={name:`ɵɵtwoWayProperty`,moduleName:O};static twoWayBindingSet={name:`ɵɵtwoWayBindingSet`,moduleName:O};static twoWayListener={name:`ɵɵtwoWayListener`,moduleName:O};static declareLet={name:`ɵɵdeclareLet`,moduleName:O};static storeLet={name:`ɵɵstoreLet`,moduleName:O};static readContextLet={name:`ɵɵreadContextLet`,moduleName:O};static arrowFunction={name:`ɵɵarrowFunction`,moduleName:O};static attachSourceLocations={name:`ɵɵattachSourceLocations`,moduleName:O};static NgOnChangesFeature={name:`ɵɵNgOnChangesFeature`,moduleName:O};static ControlFeature={name:`ɵɵControlFeature`,moduleName:O};static InheritDefinitionFeature={name:`ɵɵInheritDefinitionFeature`,moduleName:O};static ProvidersFeature={name:`ɵɵProvidersFeature`,moduleName:O};static HostDirectivesFeature={name:`ɵɵHostDirectivesFeature`,moduleName:O};static ExternalStylesFeature={name:`ɵɵExternalStylesFeature`,moduleName:O};static listener={name:`ɵɵlistener`,moduleName:O};static getInheritedFactory={name:`ɵɵgetInheritedFactory`,moduleName:O};static sanitizeHtml={name:`ɵɵsanitizeHtml`,moduleName:O};static sanitizeStyle={name:`ɵɵsanitizeStyle`,moduleName:O};static validateAttribute={name:`ɵɵvalidateAttribute`,moduleName:O};static sanitizeResourceUrl={name:`ɵɵsanitizeResourceUrl`,moduleName:O};static sanitizeScript={name:`ɵɵsanitizeScript`,moduleName:O};static sanitizeUrl={name:`ɵɵsanitizeUrl`,moduleName:O};static sanitizeUrlOrResourceUrl={name:`ɵɵsanitizeUrlOrResourceUrl`,moduleName:O};static trustConstantHtml={name:`ɵɵtrustConstantHtml`,moduleName:O};static trustConstantResourceUrl={name:`ɵɵtrustConstantResourceUrl`,moduleName:O};static inputDecorator={name:`Input`,moduleName:O};static outputDecorator={name:`Output`,moduleName:O};static viewChildDecorator={name:`ViewChild`,moduleName:O};static viewChildrenDecorator={name:`ViewChildren`,moduleName:O};static contentChildDecorator={name:`ContentChild`,moduleName:O};static contentChildrenDecorator={name:`ContentChildren`,moduleName:O};static InputSignalBrandWriteType={name:`ɵINPUT_SIGNAL_BRAND_WRITE_TYPE`,moduleName:O};static UnwrapDirectiveSignalInputs={name:`ɵUnwrapDirectiveSignalInputs`,moduleName:O};static unwrapWritableSignal={name:`ɵunwrapWritableSignal`,moduleName:O};static assertType={name:`ɵassertType`,moduleName:O}}return e})();D.And,D.Bigger,D.BiggerEquals,D.BitwiseOr,D.BitwiseAnd,D.Divide,D.Assign,D.Equals,D.Identical,D.Lower,D.LowerEquals,D.Minus,D.Modulo,D.Exponentiation,D.Multiply,D.NotEquals,D.NotIdentical,D.NullishCoalesce,D.Or,D.Plus,D.In,D.InstanceOf,D.AdditionAssignment,D.SubtractionAssignment,D.MultiplicationAssignment,D.DivisionAssignment,D.RemainderAssignment,D.ExponentiationAssignment,D.AndAssignment,D.OrAssignment,D.NullishCoalesceAssignment;var wt=class{span;sourceSpan;constructor(e,t){this.span=e,this.sourceSpan=t}toString(){return`AST`}},Tt=class extends wt{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)}},Et=(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})(Et||{}),Dt=`(:(where|is)\\()?`,Ot=`-shadowcsshost`,kt=`-shadowcsscontext`,At=`[^)(]*`,jt=String.raw`(?:\(${At}\)|${At})+?`,Mt=String.raw`(?:\(${jt}\)|${At})+?`,Nt=String.raw`(?:\((${Mt})\))`;String.raw`(:nth-[-\w]+)`+Nt,Ot+Nt+``,`${Dt}`,kt+Nt+``;var A=(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})(A||{}),Pt=(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})(Pt||{}),Ft=(function(e){return e[e.None=0]=`None`,e[e.AlwaysInline=1]=`AlwaysInline`,e})(Ft||{}),It=(function(e){return e[e.Context=0]=`Context`,e[e.Identifier=1]=`Identifier`,e[e.SavedView=2]=`SavedView`,e[e.Alias=3]=`Alias`,e})(It||{}),Lt=(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})(Lt||{}),Rt=(function(e){return e[e.Creation=0]=`Creation`,e[e.Postproccessing=1]=`Postproccessing`,e})(Rt||{}),zt=(function(e){return e[e.I18nText=0]=`I18nText`,e[e.I18nAttribute=1]=`I18nAttribute`,e})(zt||{}),Bt=(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})(Bt||{}),Vt=(function(e){return e[e.HTML=0]=`HTML`,e[e.SVG=1]=`SVG`,e[e.Math=2]=`Math`,e})(Vt||{}),Ht=(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})(Ht||{}),Ut=(function(e){return e[e.RootI18n=0]=`RootI18n`,e[e.Icu=1]=`Icu`,e[e.Attr=2]=`Attr`,e})(Ut||{}),Wt=(function(e){return e[e.NgTemplate=0]=`NgTemplate`,e[e.Structural=1]=`Structural`,e[e.Block=2]=`Block`,e})(Wt||{}),Gt=(function(e){return e[e.None=0]=`None`,e[e.InChildOperation=1]=`InChildOperation`,e[e.InArrowFunctionOperation=2]=`InArrowFunctionOperation`,e[e.InSafeNavigationMigration=4]=`InSafeNavigationMigration`,e})(Gt||{});A.Element,A.ElementStart,A.Container,A.ContainerStart,A.Template,A.RepeaterCreate,A.ConditionalCreate,A.ConditionalBranchCreate;var j=(function(e){return e[e.Tmpl=0]=`Tmpl`,e[e.Host=1]=`Host`,e[e.Both=2]=`Both`,e})(j||{}),Kt=(function(e){return e[e.Full=0]=`Full`,e[e.DomOnly=1]=`DomOnly`,e})(Kt||{});k.ariaProperty,k.ariaProperty,k.attribute,k.attribute,k.classProp,k.classProp,k.element,k.element,k.elementContainer,k.elementContainer,k.elementContainerEnd,k.elementContainerEnd,k.elementContainerStart,k.elementContainerStart,k.elementEnd,k.elementEnd,k.elementStart,k.elementStart,k.domProperty,k.domProperty,k.i18nExp,k.i18nExp,k.listener,k.listener,k.listener,k.listener,k.property,k.property,k.styleProp,k.styleProp,k.syntheticHostListener,k.syntheticHostListener,k.syntheticHostProperty,k.syntheticHostProperty,k.templateCreate,k.templateCreate,k.twoWayProperty,k.twoWayProperty,k.twoWayListener,k.twoWayListener,k.declareLet,k.declareLet,k.conditionalCreate,k.conditionalBranchCreate,k.conditionalBranchCreate,k.conditionalBranchCreate,k.domElement,k.domElement,k.domElementStart,k.domElementStart,k.domElementEnd,k.domElementEnd,k.domElementContainer,k.domElementContainer,k.domElementContainerStart,k.domElementContainerStart,k.domElementContainerEnd,k.domElementContainerEnd,k.domListener,k.domListener,k.domTemplate,k.domTemplate,k.animationEnter,k.animationEnter,k.animationLeave,k.animationLeave,k.animationEnterListener,k.animationEnterListener,k.animationLeaveListener,k.animationLeaveListener,D.And,D.Bigger,D.BiggerEquals,D.BitwiseOr,D.BitwiseAnd,D.Divide,D.Assign,D.Equals,D.Identical,D.Lower,D.LowerEquals,D.Minus,D.Modulo,D.Exponentiation,D.Multiply,D.NotEquals,D.NotIdentical,D.NullishCoalesce,D.Or,D.Plus,D.In,D.InstanceOf,D.AdditionAssignment,D.SubtractionAssignment,D.MultiplicationAssignment,D.DivisionAssignment,D.RemainderAssignment,D.ExponentiationAssignment,D.AndAssignment,D.OrAssignment,D.NullishCoalesceAssignment,A.Property,A.Property,A.Property,A.Attribute,A.Attribute,A.Property,A.TwoWayProperty,A.Container,A.ContainerStart,A.ContainerEnd,A.Element,A.ElementStart,A.ElementEnd,A.Template,A.ElementEnd,A.ElementStart,A.Element,A.ContainerEnd,A.ContainerStart,A.Container,A.I18nEnd,A.I18nStart,A.I18n,A.Pipe;var qt=` \f -\r \v ᠎ - \u2028\u2029   `;`${qt}`,`${qt}`;var Jt=(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})(Jt||{}),Yt=(function(e){return e[e.Plain=0]=`Plain`,e[e.TemplateLiteralPart=1]=`TemplateLiteralPart`,e[e.TemplateLiteralEnd=2]=`TemplateLiteralEnd`,e})(Yt||{});Jt.Character,A.StyleMap,A.ClassMap,A.StyleProp,A.ClassProp,A.Attribute,A.Property,A.Attribute,A.Control,A.DomProperty,A.DomProperty,A.Attribute,A.StyleMap,A.ClassMap,A.StyleProp,A.ClassProp,A.Listener,A.TwoWayListener,A.AnimationListener,A.StyleMap,A.ClassMap,A.StyleProp,A.ClassProp,A.Property,A.TwoWayProperty,A.DomProperty,A.Attribute,A.Animation,A.Control,Ht.Idle,k.deferOnIdle,k.deferPrefetchOnIdle,k.deferHydrateOnIdle,Ht.Immediate,k.deferOnImmediate,k.deferPrefetchOnImmediate,k.deferHydrateOnImmediate,Ht.Timer,k.deferOnTimer,k.deferPrefetchOnTimer,k.deferHydrateOnTimer,Ht.Hover,k.deferOnHover,k.deferPrefetchOnHover,k.deferHydrateOnHover,Ht.Interaction,k.deferOnInteraction,k.deferPrefetchOnInteraction,k.deferHydrateOnInteraction,Ht.Viewport,k.deferOnViewport,k.deferPrefetchOnViewport,k.deferHydrateOnViewport,Ht.Never,k.deferHydrateNever,k.deferHydrateNever,k.deferHydrateNever,k.pipeBind1,k.pipeBind2,k.pipeBind3,k.pipeBind4,k.textInterpolate,k.textInterpolate1,k.textInterpolate2,k.textInterpolate3,k.textInterpolate4,k.textInterpolate5,k.textInterpolate6,k.textInterpolate7,k.textInterpolate8,k.textInterpolateV,k.interpolate,k.interpolate1,k.interpolate2,k.interpolate3,k.interpolate4,k.interpolate5,k.interpolate6,k.interpolate7,k.interpolate8,k.interpolateV,k.pureFunction0,k.pureFunction1,k.pureFunction2,k.pureFunction3,k.pureFunction4,k.pureFunction5,k.pureFunction6,k.pureFunction7,k.pureFunction8,k.pureFunctionV,k.resolveWindow,k.resolveDocument,k.resolveBody,Ye.HTML,k.sanitizeHtml,Ye.RESOURCE_URL,k.sanitizeResourceUrl,Ye.SCRIPT,k.sanitizeScript,Ye.STYLE,k.sanitizeStyle,Ye.URL,k.sanitizeUrl,Ye.ATTRIBUTE_NO_BINDING,k.validateAttribute,Ye.HTML,k.trustConstantHtml,Ye.RESOURCE_URL,k.trustConstantResourceUrl;var Xt=(function(e){return e[e.None=0]=`None`,e[e.ViewContextRead=1]=`ViewContextRead`,e[e.ViewContextWrite=2]=`ViewContextWrite`,e[e.SideEffectful=4]=`SideEffectful`,e})(Xt||{});j.Tmpl,j.Tmpl,j.Both,j.Host,j.Tmpl,j.Tmpl,j.Tmpl,j.Both,j.Both,j.Both,j.Tmpl,j.Both,j.Both,j.Tmpl,j.Both,j.Tmpl,j.Both,j.Both,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Both,j.Both,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Both,j.Both,j.Both,j.Tmpl,j.Tmpl,j.Both,j.Tmpl,j.Tmpl,j.Tmpl,j.Both,j.Both,j.Tmpl,j.Both,j.Both,j.Both,j.Both,j.Both,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Both,j.Tmpl,j.Both,j.Tmpl,j.Both,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Tmpl,j.Both,j.Both,j.Both,Et.Property,Lt.Property,Et.TwoWay,Lt.TwoWayProperty,Et.Attribute,Lt.Attribute,Et.Class,Lt.ClassName,Et.Style,Lt.StyleProperty,Et.LegacyAnimation,Lt.LegacyAnimation,Et.Animation,Lt.Animation;var Zt=`%COMP%`;`${Zt}`,`${Zt}`,class e{static SINGLETON=new e;static veWillInferAnyFor(t){let n=e.SINGLETON;return t instanceof Tt?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 Qt=null,$t=!1,en=1,tn=null,nn=Symbol(`SIGNAL`);function M(e){let t=Qt;return Qt=e,t}function rn(){return Qt}var an={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 on(e){if($t)throw Error(``);if(Qt===null)return;Qt.consumerOnSignalRead(e);let t=Qt.producersTail;if(t!==void 0&&t.producer===e)return;let n,r=Qt.recomputing;if(r&&(n=t===void 0?Qt.producers:t.nextProducer,n!==void 0&&n.producer===e)){Qt.producersTail=n,n.lastReadVersion=e.version,n.knownValidAtEpoch=en;return}let i=e.consumersTail;if(i!==void 0&&i.consumer===Qt&&(!r||i.knownValidAtEpoch===en))return;let a=xn(Qt),o={producer:e,consumer:Qt,nextProducer:n,prevConsumer:void 0,knownValidAtEpoch:en,lastReadVersion:e.version,nextConsumer:void 0};Qt.producersTail=o,t===void 0?Qt.producers=o:t.nextProducer=o,a&&yn(e,o)}function sn(){en++}function cn(e){if((!xn(e)||e.dirty)&&(e.dirty||e.lastCleanEpoch!==en)){if(!e.producerMustRecompute(e)&&!_n(e)){fn(e);return}e.producerRecomputeValue(e),fn(e)}}function ln(e){if(e.consumers===void 0)return;let t=$t;$t=!0;try{for(let t=e.consumers;t!==void 0;t=t.nextConsumer){let e=t.consumer;e.dirty||dn(e)}}finally{$t=t}}function un(){return Qt?.consumerAllowSignalWrites!==!1}function dn(e){e.dirty=!0,ln(e),e.consumerMarkedDirty?.(e)}function fn(e){e.dirty=!1,e.lastCleanEpoch=en}function pn(e){return e&&mn(e),M(e)}function mn(e){if(e.producersTail?.knownValidAtEpoch===en){let t=e.producers;for(;t!==void 0;)t.knownValidAtEpoch=null,t=t.nextProducer}e.producersTail=void 0,e.recomputing=!0}function hn(e,t){M(t),e&&gn(e)}function gn(e){e.recomputing=!1;let t=e.producersTail,n=t===void 0?e.producers:t.nextProducer;if(n!==void 0){if(xn(e))do n=bn(n);while(n!==void 0);t===void 0?e.producers=void 0:t.nextProducer=void 0}}function _n(e){for(let t=e.producers;t!==void 0;t=t.nextProducer){let e=t.producer,n=t.lastReadVersion;if(n!==e.version||(cn(e),n!==e.version))return!0}return!1}function vn(e){if(xn(e)){let t=e.producers;for(;t!==void 0;)t=bn(t)}e.producers=void 0,e.producersTail=void 0,e.consumers=void 0,e.consumersTail=void 0}function yn(e,t){let n=e.consumersTail,r=xn(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)yn(t.producer,t)}function bn(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,!xn(t)){let e=t.producers;for(;e!==void 0;)e=bn(e)}return n}function xn(e){return e.consumerIsAlwaysLive||e.consumers!==void 0}function Sn(e){tn?.(e)}function Cn(e,t){return Object.is(e,t)}function wn(e,t){let n=Object.create(On);n.computation=e,t!==void 0&&(n.equal=t);let r=()=>{if(cn(n),on(n),n.value===Dn)throw n.error;return n.value};return r[nn]=n,Sn(n),r}var Tn=Symbol(`UNSET`),En=Symbol(`COMPUTING`),Dn=Symbol(`ERRORED`),On={...an,value:Tn,dirty:!0,error:null,equal:Cn,kind:`computed`,producerMustRecompute(e){return e.value===Tn||e.value===En},producerRecomputeValue(e){if(e.value===En)throw Error(``);let t=e.value;e.value=En;let n=pn(e),r,i=!1;try{r=e.computation(),M(null),i=t!==Tn&&t!==Dn&&r!==Dn&&e.equal(t,r)}catch(t){r=Dn,e.error=t}finally{hn(e,n)}if(i){e.value=t;return}e.value=r,e.version++}};function kn(){throw Error()}var An=kn;function jn(e){An(e)}function Mn(e){An=e}var Nn=null;function Pn(e,t){let n=Object.create(Rn);n.value=e,t!==void 0&&(n.equal=t);let r=()=>Fn(n);return r[nn]=n,Sn(n),[r,e=>In(n,e),e=>Ln(n,e)]}function Fn(e){return on(e),e.value}function In(e,t){un()||jn(e),e.equal(e.value,t)||(e.value=t,zn(e))}function Ln(e,t){un()||jn(e),In(e,t(e.value))}var Rn={...an,equal:Cn,value:void 0,kind:`signal`};function zn(e){e.version++,sn(),ln(e),Nn?.(e)}var Bn={...an,consumerIsAlwaysLive:!0,consumerAllowSignalWrites:!0,dirty:!0,kind:`effect`};function Vn(e){if(e.dirty=!1,e.version>0&&!_n(e))return;e.version++;let t=pn(e);try{e.cleanup(),e.fn()}finally{hn(e,t)}}var Hn=void 0;function Un(){return Hn}function Wn(e){let t=Hn;return Hn=e,t}var Gn=Symbol(`NotFound`);function Kn(e){return e===Gn||e?.name===`ɵNotFound`}var qn=function(e,t){return qn=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])},qn(e,t)};function Jn(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);qn(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}function Yn(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 Xn(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 Zn(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?rr:(this.currentObservers=null,a.push(e),new nr(function(){t.currentObservers=null,tr(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 kr;return e.source=this,e},t.create=function(e,t){return new zr(e,t)},t}(kr),zr=function(e){Jn(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)??rr},t}(Rr),Br=function(e){Jn(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}(Rr);function Vr(e,t){return Pr(function(n,r){var i=0;n.subscribe(Fr(r,function(n){r.next(e.call(t,n,i++))}))})}var Hr=`https://angular.dev/best-practices/security#preventing-cross-site-scripting-xss`,N=class extends Error{code;constructor(e,t){super(Wr(e,t)),this.code=e}};function Ur(e){return`NG0${Math.abs(e)}`}function Wr(e,t){return`${Ur(e)}${t?`: `+t:``}`}function P(e){for(let t in e)if(e[t]===P)return t;throw Error(``)}function Gr(e){if(typeof e==`string`)return e;if(Array.isArray(e))return`[${e.map(Gr).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 Kr(e,t){return e?t?`${e} ${t}`:e:t||``}var qr=P({__forward_ref__:P});function Jr(e){return e.__forward_ref__=Jr,e}function Yr(e){return Xr(e)?e():e}function Xr(e){return typeof e==`function`&&Object.hasOwn(e,qr)&&e.__forward_ref__===Jr}function Zr(e){return{token:e.token,providedIn:e.providedIn||null,factory:e.factory,value:void 0}}function Qr(e){return $r(e,ni)}function $r(e,t){return Object.hasOwn(e,t)&&e[t]||null}function ei(e){return(e?.[ni]??null)||null}function ti(e){return e&&Object.hasOwn(e,ri)?e[ri]:null}var ni=P({ɵprov:P}),ri=P({ɵinj:P}),F=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=Zr({token:this,providedIn:t.providedIn||`root`,factory:t.factory}))}get multi(){return this}toString(){return`InjectionToken ${this._desc}`}};function ii(e){return e&&!!e.ɵproviders}var ai=P({ɵcmp:P}),oi=P({ɵdir:P}),si=P({ɵpipe:P}),ci=P({ɵfac:P}),li=P({__NG_ELEMENT_ID__:P}),ui=P({__NG_ENV_ID__:P});function di(e){return mi(e,`@Component`),e[ai]||null}function fi(e){return mi(e,`@Directive`),e[oi]||null}function pi(e){return mi(e,`@Pipe`),e[si]||null}function mi(e,t){if(e==null)throw new N(-919,!1)}function hi(e){return typeof e==`string`?e:e==null?``:String(e)}var gi=P({ngErrorCode:P}),_i=P({ngErrorMessage:P}),vi=P({ngTokenPath:P});function yi(e,t){return xi(``,-200,t)}function bi(e,t){throw new N(-201,!1)}function xi(e,t,n){let r=new N(t,e);return r[gi]=t,r[_i]=e,n&&(r[vi]=n),r}function Si(e){return e[gi]}var Ci;function wi(){return Ci}function Ti(e){let t=Ci;return Ci=e,t}function Ei(e,t,n){let r=Qr(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;bi(e,``)}var Di={},Oi=`__NG_DI_FLAG__`,ki=class{injector;constructor(e){this.injector=e}retrieve(e,t){let n=ji(t)||0;try{return this.injector.get(e,n&8?null:Di,n)}catch(e){if(Kn(e))return e;throw e}}};function Ai(e,t=0){let n=Un();if(n===void 0)throw new N(-203,!1);if(n===null)return Ei(e,void 0,t);{let r=Mi(t),i=n.retrieve(e,r);if(Kn(i)){if(r.optional)return null;throw i}return i}}function I(e,t=0){return(wi()||Ai)(Yr(e),t)}function L(e,t){return I(e,ji(t))}function ji(e){return e===void 0||typeof e==`number`?e:0|(e.optional&&8)|(e.host&&1)|(e.self&&2)|(e.skipSelf&&4)}function Mi(e){return{optional:!!(e&8),host:!!(e&1),self:!!(e&2),skipSelf:!!(e&4)}}function Ni(e){let t=[];for(let n=0;nArray.isArray(e)?Ii(e,t):t(e))}function Li(e,t,n){t>=e.length?e.push(n):e.splice(t,0,n)}function Ri(e,t){return t>=e.length-1?e.pop():e.splice(t,1)[0]}function zi(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 Bi(e,t,n){let r=Hi(e,t);return r>=0?e[r|1]=n:(r=~r,zi(e,r,t,n)),r}function Vi(e,t){let n=Hi(e,t);if(n>=0)return e[n|1]}function Hi(e,t){return Ui(e,t,1)}function Ui(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 Ii(t,e=>{let t=e;$i(t,a,[],r)&&(i||=[],i.push(t))}),i!==void 0&&Qi(i,a),n}function Qi(e,t){for(let n=0;n{t(e,r)})}}function $i(e,t,n,r){if(e=Yr(e),!e)return!1;let i=null,a=ti(e),o=!a&&di(e);if(!a&&!o){let t=e.ngModule;if(a=ti(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)$i(i,t,n,r)}}else if(a){if(a.imports!=null&&!s){r.add(i);let e;try{Ii(a.imports,i=>{$i(i,t,n,r)&&(e||=[],e.push(i))})}finally{}e!==void 0&&Qi(e,t)}if(!s){let e=Fi(i)||(()=>new i);t({provide:i,useFactory:e,deps:Gi},i),t({provide:Ji,useValue:i,multi:!0},i),t({provide:Ki,useValue:()=>I(i),multi:!0},i)}let o=a.providers;if(o!=null&&!s){let n=e;ea(o,e=>{t(e,n)})}}else return!1;return i!==e&&e.providers!==void 0}function ea(e,t){for(let n of e)ii(n)&&(n=n.ɵproviders),Array.isArray(n)?ea(n,t):t(n)}var ta=P({provide:String,useValue:P});function na(e){return typeof e==`object`&&!!e&&ta in e}function ra(e){return!!(e&&e.useExisting)}function ia(e){return!!(e&&e.useFactory)}function aa(e){return typeof e==`function`}var oa=new F(``),sa={},ca={},la=void 0;function ua(){return la===void 0&&(la=new Yi),la}var da=class{},fa=class extends da{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,Sa(e,e=>this.processProvider(e)),this.records.set(qi,va(void 0,this)),r.has(`environment`)&&this.records.set(da,va(void 0,this));let i=this.records.get(oa);i!=null&&typeof i.value==`string`&&this.scopes.add(i.value),this.injectorDefTypes=new Set(this.get(Ji,Gi,{self:!0}))}retrieve(e,t){let n=ji(t)||0;try{return this.get(e,Di,n)}catch(e){if(Kn(e))return e;throw e}}destroy(){_a(this),this._destroyed=!0;let e=M(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(),M(e)}}onDestroy(e){return _a(this),this._onDestroyHooks.push(e),()=>this.removeOnDestroy(e)}runInContext(e){_a(this);let t=Wn(this),n=Ti(void 0);try{return e()}finally{Wn(t),Ti(n)}}get(e,t=Di,n){if(_a(this),Object.hasOwn(e,ui))return e[ui](this);let r=ji(n),i=Wn(this),a=Ti(void 0);try{if(!(r&4)){let t=this.records.get(e);if(t===void 0){let n=xa(e)&&Qr(e);t=n&&this.injectableDefInScope(n)?va(pa(e),sa):null,this.records.set(e,t)}if(t!=null)return this.hydrate(e,t,r)}let n=r&2?ua():this.parent;return t=r&8&&t===Di?null:t,n.get(e,t)}catch(e){let t=Si(e);throw t===-200||t===-201?new N(t,null):e}finally{Ti(a),Wn(i)}}resolveInjectorInitializers(){let e=M(null),t=Wn(this),n=Ti(void 0);try{let e=this.get(Ki,Gi,{self:!0});for(let t of e)t()}finally{Wn(t),Ti(n),M(e)}}toString(){return`R3Injector[...]`}processProvider(e){e=Yr(e);let t=aa(e)?e:Yr(e&&e.provide),n=ha(e);if(!aa(e)&&e.multi===!0){let n=this.records.get(t);n||(n=va(void 0,sa,!0),n.factory=()=>Ni(n.multi),this.records.set(t,n)),t=e,n.multi.push(e)}this.records.set(t,n)}hydrate(e,t,n){let r=M(null);try{if(t.value===ca)throw yi(``);return t.value===sa&&(t.value=ca,t.value=t.factory(void 0,n)),typeof t.value==`object`&&t.value&&ba(t.value)&&this._ngOnDestroyHooks.add(t.value),t.value}finally{M(r)}}injectableDefInScope(e){if(!e.providedIn)return!1;let t=Yr(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 pa(e){let t=Qr(e),n=t===null?Fi(e):t.factory;if(n!==null)return n;if(e instanceof F)throw new N(-204,!1);if(e instanceof Function)return ma(e);throw new N(-204,!1)}function ma(e){if(e.length>0)throw new N(-204,!1);let t=ei(e);return t===null?()=>new e:()=>t.factory(e)}function ha(e){return na(e)?va(void 0,e.useValue):va(ga(e),sa)}function ga(e,t,n){let r;if(aa(e)){let t=Yr(e);return Fi(t)||pa(t)}if(na(e))r=()=>Yr(e.useValue);else if(ia(e))r=()=>e.useFactory(...Ni(e.deps||[]));else if(ra(e))r=(t,n)=>I(Yr(e.useExisting),n!==void 0&&n&8?8:void 0);else{let t=Yr(e&&(e.useClass||e.provide));if(ya(e))r=()=>new t(...Ni(e.deps));else return Fi(t)||pa(t)}return r}function _a(e){if(e.destroyed)throw new N(-205,!1)}function va(e,t,n=!1){return{factory:e,value:t,multi:n?[]:void 0}}function ya(e){return!!e.deps}function ba(e){return typeof e==`object`&&!!e&&typeof e.ngOnDestroy==`function`}function xa(e){return typeof e==`function`||typeof e==`object`&&e.ngMetadataName===`InjectionToken`}function Sa(e,t){for(let n of e)Array.isArray(n)?Sa(n,t):n&&ii(n)?Sa(n.ɵproviders,t):t(n)}function Ca(e,t){let n;e instanceof fa?(_a(e),n=e):n=new ki(e);let r=Wn(n),i=Ti(void 0);try{return t()}finally{Wn(r),Ti(i)}}function wa(){return wi()!==void 0||Un()!=null}var Ta=1;function Ea(e){return Array.isArray(e)&&typeof e[Ta]==`object`}function Da(e){return Array.isArray(e)&&e[Ta]===!0}function Oa(e){return!!(e.flags&4)}function ka(e){return e.componentOffset>-1}function Aa(e){return(e.flags&1)==1}function ja(e){return!!e.template}function Ma(e){return!!(e[2]&512)}function Na(e){return(e[2]&256)==256}var Pa=`math`;function Fa(e){for(;Array.isArray(e);)e=e[0];return e}function Ia(e,t){return Fa(t[e])}function La(e,t){return Fa(t[e.index])}function Ra(e,t){return e.data[t]}function za(e,t){return e[t]}function Ba(e,t,n,r){n>=e.data.length&&(e.data[n]=null,e.blueprint[n]=null),t[n]=r}function Va(e,t){let n=t[e];return Ea(n)?n:n[0]}function Ha(e){return(e[2]&128)==128}function Ua(e,t){return t==null?null:e[t]}function Wa(e){e[17]=0}function Ga(e){e[2]&1024||(e[2]|=1024,Ha(e)&&Ya(e))}function Ka(e,t){for(;e>0;)t=t[14],e--;return t}function qa(e){return!!(e[2]&9216||e[24]?.dirty)}function Ja(e){e[10].changeDetectionScheduler?.notify(8),e[2]&64&&(e[2]|=1024),qa(e)&&Ya(e)}function Ya(e){e[10].changeDetectionScheduler?.notify(0);let t=Qa(e);for(;t!==null&&!(t[2]&8192||(t[2]|=8192,!Ha(t)));)t=Qa(t)}function Xa(e,t){if(Na(e))throw new N(911,!1);e[21]===null&&(e[21]=[]),e[21].push(t)}function Za(e,t){if(e[21]===null)return;let n=e[21].indexOf(t);n!==-1&&e[21].splice(n,1)}function Qa(e){let t=e[3];return Da(t)?t[3]:t}function $a(e){return e[7]??=[]}function eo(e){return e.cleanup??=[]}var R={lFrame:Io(null),bindingsEnabled:!0,skipHydrationRootTNode:null},to=!1;function no(){return R.lFrame.elementDepthCount}function ro(){R.lFrame.elementDepthCount++}function io(){R.lFrame.elementDepthCount--}function ao(){return R.bindingsEnabled}function oo(){return R.skipHydrationRootTNode!==null}function so(e){return R.skipHydrationRootTNode===e}function co(){R.skipHydrationRootTNode=null}function z(){return R.lFrame.lView}function lo(){return R.lFrame.tView}function uo(e){return R.lFrame.contextLView=e,e[8]}function fo(e){return R.lFrame.contextLView=null,e}function po(){let e=mo();for(;e!==null&&e.type===64;)e=e.parent;return e}function mo(){return R.lFrame.currentTNode}function ho(){let e=R.lFrame,t=e.currentTNode;return e.isParent?t:t.parent}function go(e,t){let n=R.lFrame;n.currentTNode=e,n.isParent=t}function _o(){return R.lFrame.isParent}function vo(){R.lFrame.isParent=!1}function yo(){return to}function bo(e){let t=to;return to=e,t}function xo(){let e=R.lFrame,t=e.bindingRootIndex;return t===-1&&(t=e.bindingRootIndex=e.tView.bindingStartIndex),t}function So(){return R.lFrame.bindingIndex}function Co(e){return R.lFrame.bindingIndex=e}function wo(){return R.lFrame.bindingIndex++}function To(e){let t=R.lFrame,n=t.bindingIndex;return t.bindingIndex+=e,n}function Eo(){return R.lFrame.inI18n}function Do(e,t){let n=R.lFrame;n.bindingIndex=n.bindingRootIndex=e,ko(t)}function Oo(){return R.lFrame.currentDirectiveIndex}function ko(e){R.lFrame.currentDirectiveIndex=e}function Ao(e){let t=R.lFrame.currentDirectiveIndex;return t===-1?null:e[t]}function jo(e){R.lFrame.currentQueryIndex=e}function Mo(e){let t=e[1];return t.type===2?t.declTNode:t.type===1?e[5]:null}function No(e,t,n){if(n&4){let r=t,i=e;for(;r=r.parent,r===null&&!(n&1)&&(r=Mo(i),!(r===null||(i=i[14],r.type&10))););if(r===null)return!1;t=r,e=i}let r=R.lFrame=Fo();return r.currentTNode=t,r.lView=e,!0}function Po(e){let t=Fo(),n=e[1];R.lFrame=t,t.currentTNode=n.firstChild,t.lView=e,t.tView=n,t.contextLView=e,t.bindingIndex=n.bindingStartIndex,t.inI18n=!1}function Fo(){let e=R.lFrame,t=e===null?null:e.child;return t===null?Io(e):t}function Io(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 Lo(){let e=R.lFrame;return R.lFrame=e.parent,e.currentTNode=null,e.lView=null,e}var Ro=Lo;function zo(){let e=Lo();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 Bo(e){return(R.lFrame.contextLView=Ka(e,R.lFrame.contextLView))[8]}function Vo(){return R.lFrame.selectedIndex}function Ho(e){R.lFrame.selectedIndex=e}function Uo(){let e=R.lFrame;return Ra(e.tView,e.selectedIndex)}function Wo(){R.lFrame.currentNamespace=`svg`}function Go(){Ko()}function Ko(){R.lFrame.currentNamespace=null}function qo(){return R.lFrame.currentNamespace}var Jo=!0;function Yo(){return Jo}function Xo(e){Jo=e}function Zo(e,t=null,n=null,r){let i=Qo(e,t,n,r);return i.resolveInjectorInitializers(),i}function Qo(e,t=null,n=null,r,i=new Set){return new fa([n||Gi,Xi(e)],t||ua(),null,i)}var $o=class e{static THROW_IF_NOT_FOUND=Di;static NULL=new Yi;static create(e,t){if(Array.isArray(e))return Zo({name:``},t,e,``);{let t=e.name??``;return Zo({name:t},e.parent,e.providers,t)}}static ɵprov=Zr({token:e,providedIn:`any`,factory:()=>I(qi)});static __NG_ELEMENT_ID__=-1},es=new F(``),ts=class{static __NG_ELEMENT_ID__=rs;static __NG_ENV_ID__=e=>e},ns=class extends ts{_lView;constructor(e){super(),this._lView=e}get destroyed(){return Na(this._lView)}onDestroy(e){let t=this._lView;return Xa(t,e),()=>Za(t,e)}};function rs(){return new ns(z())}var is=new F(``),as=(()=>{class e{taskId=0;pendingTasks=new Set;destroyed=!1;pendingTask=new Br(!1);debugTaskTracker=L(is,{optional:!0});get hasPendingTasks(){return!this.destroyed&&this.pendingTask.value}get hasPendingTasksObservable(){return this.destroyed?new kr(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=Zr({token:e,providedIn:`root`,factory:()=>new e})}return e})(),os=class extends Rr{__isAsync;destroyRef=void 0;pendingTasks=void 0;constructor(e=!1){super(),this.__isAsync=e,wa()&&(this.destroyRef=L(ts,{optional:!0})??void 0,this.pendingTasks=L(as,{optional:!0})??void 0)}emit(e){let t=M(null);try{super.next(e)}finally{M(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 nr&&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 ss(...e){}function cs(e){let t,n;function r(){e=ss;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 ls(e){return queueMicrotask(()=>e()),()=>{e=ss}}var us=`isAngularZone`,ds=`isAngularZone_ID`,fs=0,ps=class e{hasPendingMacrotasks=!1;hasPendingMicrotasks=!1;isStable=!0;onUnstable=new os(!1);onMicrotaskEmpty=new os(!1);onStable=new os(!1);onError=new os(!1);constructor(e){let{enableLongStackTrace:t=!1,shouldCoalesceEventChangeDetection:n=!1,shouldCoalesceRunChangeDetection:r=!1,scheduleInRootZone:i=!1}=e;if(typeof Zone>`u`)throw new N(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,_s(a)}static isInAngularZone(){return typeof Zone<`u`&&Zone.current.get(us)===!0}static assertInAngularZone(){if(!e.isInAngularZone())throw new N(909,!1)}static assertNotInAngularZone(){if(e.isInAngularZone())throw new N(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,ms,ss,ss);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)}},ms={};function hs(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 gs(e){if(e.isCheckStableRunning||e.callbackScheduled)return;e.callbackScheduled=!0;function t(){cs(()=>{e.callbackScheduled=!1,vs(e),e.isCheckStableRunning=!0,hs(e),e.isCheckStableRunning=!1})}e.scheduleInRootZone?Zone.root.run(()=>{t()}):e._outer.run(()=>{t()}),vs(e)}function _s(e){let t=()=>{gs(e)},n=fs++;e._inner=e._inner.fork({name:`angular`,properties:{[us]:!0,[ds]:n,[ds+n]:!0},onInvokeTask:(n,r,i,a,o,s)=>{if(Ss(s))return n.invokeTask(i,a,o,s);try{return ys(e),n.invokeTask(i,a,o,s)}finally{(e.shouldCoalesceEventChangeDetection&&a.type===`eventTask`||e.shouldCoalesceRunChangeDetection)&&t(),bs(e)}},onInvoke:(n,r,i,a,o,s,c)=>{try{return ys(e),n.invoke(i,a,o,s,c)}finally{e.shouldCoalesceRunChangeDetection&&!e.callbackScheduled&&!Cs(s)&&t(),bs(e)}},onHasTask:(t,n,r,i)=>{t.hasTask(r,i),n===r&&(i.change==`microTask`?(e._hasPendingMicrotasks=i.microTask,vs(e),hs(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 vs(e){e.hasPendingMicrotasks=!!(e._hasPendingMicrotasks||(e.shouldCoalesceEventChangeDetection||e.shouldCoalesceRunChangeDetection)&&e.callbackScheduled===!0)}function ys(e){e._nesting++,e.isStable&&(e.isStable=!1,e.onUnstable.emit(null))}function bs(e){e._nesting--,hs(e)}var xs=class{hasPendingMicrotasks=!1;hasPendingMacrotasks=!1;isStable=!0;onUnstable=new os;onMicrotaskEmpty=new os;onStable=new os;onError=new os;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 Ss(e){return ws(e,`__ignore_ng_zone__`)}function Cs(e){return ws(e,`__scheduler_tick__`)}function ws(e,t){return!Array.isArray(e)||e.length!==1?!1:e[0]?.data?.[t]===!0}var Ts=class{_console=console;handleError(e){this._console.error(`ERROR`,e)}},Es=new F(``,{factory:()=>{let e=L(ps),t=L(da),n;return r=>{e.runOutsideAngular(()=>{t.destroyed&&!n?setTimeout(()=>{throw r}):(n??=t.get(Ts),n.handleError(r))})}}}),Ds={provide:Ki,useValue:()=>{L(Ts,{optional:!0})},multi:!0};function B(e,t){let[n,r,i]=Pn(e,t?.equal),a=n;return a[nn],a.set=r,a.update=i,a.asReadonly=Os.bind(a),a}function Os(){let e=this[nn];if(e.readonlyFn===void 0){let t=()=>this();t[nn]=e,e.readonlyFn=t}return e.readonlyFn}var ks=new F(``,{factory:()=>As}),As=`ng`,js=new F(``),Ms=new F(``,{providedIn:`platform`,factory:()=>`unknown`}),Ns=new F(``,{factory:()=>L(es).body?.querySelector(`[ngCspNonce]`)?.getAttribute(`ngCspNonce`)||null}),Ps=(()=>{class e{view;node;constructor(e,t){this.view=e,this.node=t}static __NG_ELEMENT_ID__=Fs}return e})();function Fs(){return new Ps(z(),po())}var Is=class{},Ls=new F(``,{factory:()=>!0}),Rs=new F(``),zs=(()=>{class e{static ɵprov=Zr({token:e,providedIn:`root`,factory:()=>new Bs})}return e})(),Bs=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}},Vs=class{[nn];constructor(e){this[nn]=e}destroy(){this[nn].destroy()}};function Hs(e,t){let n=t?.injector??L($o),r=t?.manualCleanup===!0?null:n.get(ts),i,a=n.get(Ps,null,{optional:!0}),o=n.get(Is);return a===null?i=qs(e,n.get(zs),o):(i=Ks(a.view,o,e),r instanceof ns&&r._lView===a.view&&(r=null)),i.injector=n,r!==null&&(i.onDestroyFns=[r.onDestroy(()=>i.destroy())]),new Vs(i)}var Us={...Bn,cleanupFns:void 0,zone:null,onDestroyFns:null,run(){let e=bo(!1);try{Vn(this)}finally{bo(e)}},cleanup(){if(!this.cleanupFns?.length)return;let e=M(null);try{for(;this.cleanupFns.length;)this.cleanupFns.pop()()}finally{this.cleanupFns=[],M(e)}}},Ws={...Us,consumerMarkedDirty(){this.scheduler.schedule(this),this.notifier.notify(12)},destroy(){if(vn(this),this.onDestroyFns!==null)for(let e of this.onDestroyFns)e();this.cleanup(),this.scheduler.remove(this)}},Gs={...Us,consumerMarkedDirty(){this.view[2]|=8192,Ya(this.view),this.notifier.notify(13)},destroy(){if(vn(this),this.onDestroyFns!==null)for(let e of this.onDestroyFns)e();this.cleanup(),this.view[23]?.delete(this)}};function Ks(e,t,n){let r=Object.create(Gs);return r.view=e,r.zone=typeof Zone<`u`?Zone.current:null,r.notifier=t,r.fn=Js(r,n),e[23]??=new Set,e[23].add(r),r.consumerMarkedDirty(r),r}function qs(e,t,n){let r=Object.create(Ws);return r.fn=Js(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 Js(e,t){return()=>{t(t=>(e.cleanupFns??=[]).push(t))}}var Ys=(()=>{class e{internalPendingTasks=L(as);scheduler=L(Is);errorHandler=L(Es);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=Zr({token:e,providedIn:`root`,factory:()=>new e})}return e})(),Xs=Symbol(`InputSignalNode#UNSET`),Zs={...Rn,transformFn:void 0,applyValueToInputSignal(e,t){In(e,t)}};function Qs(e){return{toString:e}.toString()}var V=(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})(V||{});function $s(e,t,n,r){t===null?e[n]=r:t.applyValueToInputSignal(t,r)}var ec=null;function tc(){return ec}var nc=[],H=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,lc(o,a)):lc(o,a)}var dc=-1,fc=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 pc(e){return!!(e.flags&8)}function mc(e){return!!(e.flags&16)}function hc(e,t,n){let r=0;for(;rt){o=a-1;break}}}for(;a>16}function Cc(e,t){let n=Sc(e),r=t;for(;n>0;)r=r[14],n--;return r}var wc=!0;function Tc(e){let t=wc;return wc=e,t}var Ec=255,Dc=5,Oc=0,kc={};function Ac(e,t,n){let r;typeof n==`string`?r=n.charCodeAt(0)||0:Object.hasOwn(n,li)&&(r=n[li]),r??=n[li]=Oc++;let i=r&Ec,a=1<>Dc)]|=a}function jc(e,t){let n=Nc(e,t);if(n!==-1)return n;let r=t[1];r.firstCreatePass&&(e.injectorIndex=t.length,Mc(r.data,e),Mc(t,null),Mc(r.blueprint,null));let i=Pc(e,t),a=e.injectorIndex;if(bc(i)){let e=xc(i),n=Cc(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 Mc(e,t){e.push(0,0,0,0,0,0,0,0,t)}function Nc(e,t){return e.injectorIndex===-1||e.parent&&e.parent.injectorIndex===e.injectorIndex||t[e.injectorIndex+8]===null?-1:e.injectorIndex}function Pc(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=Yc(i),r===null)return dc;if(n++,i=i[14],r.injectorIndex!==-1)return r.injectorIndex|n<<16}return dc}function Fc(e,t,n){Ac(e,t,n)}function Ic(e,t,n){if(n&8||e!==void 0)return e;bi(t,`NodeInjector`)}function Lc(e,t,n,r){if(n&8&&r===void 0&&(r=null),!(n&3)){let i=e[9],a=Ti(void 0);try{return i?i.get(t,r,n&8):Ei(t,r,n&8)}finally{Ti(a)}}return Ic(r,t,n)}function Rc(e,t,n,r=0,i){if(e!==null){if(t[2]&2048&&!(r&2)){let i=Jc(e,t,n,r,kc);if(i!==kc)return i}let i=zc(e,t,n,r,kc);if(i!==kc)return i}return Lc(t,n,r,i)}function zc(e,t,n,r,i){let a=Uc(n);if(typeof a==`function`){if(!No(t,e,r))return r&1?Ic(i,n,r):Lc(t,n,r,i);try{let e;if(e=a(r),e==null&&!(r&8))bi(n);else return e}finally{Ro()}}else if(typeof a==`number`){let i=null,o=Nc(e,t),s=dc,c=r&1?t[15][5]:null;for((o===-1||r&4)&&(s=o===-1?Pc(e,t):t[o+8],s===dc||!Gc(r,!1)?o=-1:(i=t[1],o=xc(s),t=Cc(s,t)));o!==-1;){let e=t[1];if(Wc(a,o,e.data)){let e=Bc(o,t,n,i,r,c);if(e!==kc)return e}s=t[o+8],s!==dc&&Gc(r,t[1].data[o+8]===c)&&Wc(a,o,t)?(i=e,o=xc(s),t=Cc(s,t)):o=-1}}return i}function Bc(e,t,n,r,i,a){let o=t[1],s=o.data[e+8],c=Vc(s,o,n,r==null?ka(s)&&wc:r!=o&&!!(s.type&3),i&1&&a===s);return c===null?kc:Hc(t,o,c,s,i)}function Vc(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&&ja(e)&&e.type===n)return c}return null}function Hc(e,t,n,r,i){let a=e[n],o=t.data;if(a instanceof fc){let s=a;if(s.resolving)throw yi(``);let c=Tc(s.canSeeViewProviders);s.resolving=!0,o[n].type||o[n];let l=s.injectImpl?Ti(s.injectImpl):null;No(e,r,0);try{a=e[n]=s.factory(void 0,i,o,e,r),t.firstCreatePass&&n>=r.directiveStart&&rc(n,o[n],t)}finally{l!==null&&Ti(l),Tc(c),s.resolving=!1,Ro()}}return a}function Uc(e){if(typeof e==`string`)return e.charCodeAt(0)||0;let t=Object.hasOwn(e,li)?e[li]:void 0;return typeof t==`number`?t>=0?t&Ec:qc:t}function Wc(e,t,n){let r=1<>Dc)]&r)}function Gc(e,t){return!(e&2)&&!(e&1&&t)}var Kc=class{_tNode;_lView;constructor(e,t){this._tNode=e,this._lView=t}get(e,t,n){return Rc(this._tNode,this._lView,e,ji(n),t)}};function qc(){return new Kc(po(),z())}function Jc(e,t,n,r,i){let a=e,o=t;for(;a!==null&&o!==null&&o[2]&2048&&!Ma(o);){let e=zc(a,o,n,r|2,kc);if(e!==kc)return e;r&=-5;let t=a.parent;if(!t){let e=o[20];if(e){let t=e.get(n,kc,r);if(t!==kc)return t}t=Yc(o),o=o[14]}a=t}return i}function Yc(e){let t=e[1],n=t.type;return n===2?t.declTNode:n===1?e[5]:null}var Xc=()=>(typeof requestIdleCallback<`u`?requestIdleCallback:e=>setTimeout(e)).bind(globalThis),Zc=()=>(typeof requestIdleCallback<`u`?cancelIdleCallback:clearTimeout).bind(globalThis),Qc=new F(``,{factory:()=>new $c}),$c=class{requestIdleCallback=Xc();cancelIdleCallback=Zc();requestOnIdle(e,t){return this.requestIdleCallback(e,t)}cancelOnIdle(e){return this.cancelIdleCallback(e)}};function el(e){return{token:e.token,providedIn:e.autoProvided===!1?null:`root`,factory:e.factory,value:void 0}}function tl(){return nl(po(),z())}function nl(e,t){return new rl(La(e,t))}var rl=(()=>{class e{nativeElement;constructor(e){this.nativeElement=e}static __NG_ELEMENT_ID__=tl}return e})();function il(e){return(e.flags&128)==128}var al=(function(e){return e[e.OnPush=0]=`OnPush`,e[e.Eager=1]=`Eager`,e[e.Default=1]=`Default`,e})(al||{}),ol=new Map,sl=0;function cl(){return sl++}function ll(e){ol.set(e[19],e)}function ul(e){ol.delete(e[19])}var dl=`__ngContext__`;function fl(e,t){Ea(t)?(e[dl]=t[19],ll(t)):e[dl]=t}function pl(e){return hl(e[12])}function ml(e){return hl(e[4])}function hl(e){for(;e!==null&&!Da(e);)e=e[4];return e}var gl=void 0;function _l(e){gl=e}function vl(){if(gl!==void 0)return gl;if(typeof document<`u`)return document;throw new N(210,!1)}var yl=!1,bl=new F(``,{factory:()=>yl}),xl=new F(``),Sl=new WeakMap;function Cl(e,t){if(typeof e!=`object`||!e)return;let n=Sl.get(e);n||(n=new WeakSet,Sl.set(e,n)),n.add(t)}var wl=new F(``);function Tl(e){return(e.flags&32)==32}var El=()=>null;function Dl(e,t,n=!1){return El(e,t,n)}function Ol(e){return e.get(xl,!1,{optional:!0})}function kl(e,t){let n=e.contentQueries;if(n!==null){let r=M(null);try{for(let r=0;r|^->||--!>|)/g,Ll=`​$1​`;function Rl(e){return e.replace(Fl,e=>e.replace(Il,Ll))}function zl(e,t){return e.createText(t)}function Bl(e,t,n){e.setValue(t,n)}function Vl(e,t){return e.createComment(Rl(t))}function Hl(e,t,n){return e.createElement(t,n)}function Ul(e,t,n,r,i){e.insertBefore(t,n,r,i)}function Wl(e,t,n){e.appendChild(t,n)}function Gl(e,t,n,r,i){r===null?Wl(e,t,n):Ul(e,t,n,r,i)}function Kl(e,t,n,r){e.removeChild(null,t,n,r)}function ql(e,t,n){e.setAttribute(t,`style`,n)}function Jl(e,t,n){n===``?e.removeAttribute(t,`class`):e.setAttribute(t,`class`,n)}function Yl(e,t,n){let{mergedAttrs:r,classes:i,styles:a}=n;r!==null&&hc(e,t,r),i!==null&&Jl(e,t,i),a!==null&&ql(e,t,a)}function Xl(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 Zl=`ng-template`;function Ql(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(nu(r))return!1;o=!0}}}}}return nu(r)||o}function nu(e){return!(e&1)}function ru(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!==``&&!nu(o)&&(t+=su(a,i),i=``),r=o,a||=!nu(r);n++}return i!==``&&(t+=su(a,i)),t}function lu(e){return e.map(cu).join(`,`)}function uu(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),vu.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 bu(e,t,n){let r=_u(n),i=gu.get(e);i?i.some(e=>e.el===t)||i.push({el:t,declarationView:r}):gu.set(e,[{el:t,declarationView:r}])}var xu=(function(e){return e[e.CHANGE_DETECTION=0]=`CHANGE_DETECTION`,e[e.AFTER_NEXT_RENDER=1]=`AFTER_NEXT_RENDER`,e})(xu||{}),Su=new F(``),Cu=new Set;function wu(e){Cu.has(e)||(Cu.add(e),performance?.mark?.(`mark_feature_usage`,{detail:{feature:e}}))}var Tu=(()=>{class e{impl=null;execute(){this.impl?.execute()}static ɵprov=Zr({token:e,providedIn:`root`,factory:()=>new e})}return e})(),Eu=new F(``,{factory:()=>{let e=L(da),t=new Set;return e.onDestroy(()=>t.clear()),{queue:t,isScheduled:!1,scheduler:null,injector:e}}});function Du(e,t,n){let r=e.get(Eu);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 Ou(e,t){let n=e.get(Eu);if(Array.isArray(t))for(let e of t)n.queue.delete(e);else n.queue.delete(t)}function ku(e,t){let n=e.get(Eu);if(t.detachedLeaveAnimationFns){for(let e of t.detachedLeaveAnimationFns)n.queue.delete(e);t.detachedLeaveAnimationFns=void 0}}function Au(e,t){for(let[n,r]of t)Du(e,r.animateFns)}function ju(e,t,n,r){let i=e?.[26]?.enter;t!==null&&i&&i.has(n.index)&&Au(r,i)}function Mu(e,t,n,r){try{n.get(qi)}catch{return r(!1)}let i=e?.[26];i?.enter?.has(t.index)&&Ou(n,i.enter.get(t.index).animateFns);let a=Nu(e,t,i);if(a.size===0){let n=!1;if(e){let r=[];Fu(e,t,r),n=r.length>0}if(!n)return r(!1)}e&&hu.add(e[19]),Du(n,()=>Pu(e,t,i||void 0,a,r),i||void 0)}function Nu(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 Pu(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&&Fu(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),Lu(e,t.running,i)}else Promise.allSettled(a).then(()=>{e&&hu.delete(e[19]),i(!0)})}else e&&hu.delete(e[19]),i(!1)}function Fu(e,t,n){if(t.type&12){let r=e[t.index];if(Da(r))for(let e=10;e{e[26]?.running===t&&(e[26].running=void 0,hu.delete(e[19])),n(!0)})}function Ru(e,t,n,r,i,a,o,s){if(i!=null){let c,l=!1;Da(i)?c=i:Ea(i)&&(l=!0,i=i[0]);let u=Fa(i);e===0&&r!==null?(ju(s,r,a,n),o==null?Wl(t,r,u):Ul(t,r,u,o||null,!0)):e===1&&r!==null?(ju(s,r,a,n),Ul(t,r,u,o||null,!0),yu(a,u,s)):e===2?(s?.[26]?.leave?.has(a.index)&&bu(a,u,s),vu.delete(u),Mu(s,a,n,e=>{if(vu.has(u)){vu.delete(u);return}Kl(t,u,l,e)})):e===3&&(vu.delete(u),Mu(s,a,n,()=>{t.destroyNode(u)})),c!=null&&sd(t,e,n,c,a,r,o)}}function zu(e,t){Vu(e,t),t[0]=null,t[5]=null}function Bu(e,t,n,r,i,a){r[0]=i,r[5]=t,id(e,r,n,1,i,a)}function Vu(e,t){t[10].changeDetectionScheduler?.notify(9),id(e,t,t[11],2,null,null)}function Hu(e){let t=e[12];if(!t)return Gu(e[1],e);for(;t;){let n=null;if(Ea(t))n=t[12];else{let e=t[10];e&&(n=e)}if(!n){for(;t&&!t[4]&&t!==e;)Ea(t)&&Gu(t[1],t),t=t[3];t===null&&(t=e),Ea(t)&&Gu(t[1],t),n=t&&t[4]}t=n}}function Uu(e,t){let n=e[9],r=n.indexOf(t);n.splice(r,1)}function Wu(e,t){if(Na(t))return;let n=t[11];n.destroyNode&&id(e,t,n,3,null,null),Hu(t)}function Gu(e,t){if(Na(t))return;let n=M(null);try{t[2]&=-129,t[2]|=256,t[24]&&vn(t[24]),qu(e,t),Ku(e,t),t[1].type===1&&t[11].destroy();let n=t[16];if(n!==null&&Da(t[3])){n!==t[3]&&Uu(n,t);let r=t[18];r!==null&&r.detachView(e)}ul(t)}finally{M(n)}}function Ku(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&&_d(e,t,27,!1),H(o?V.TemplateUpdateStart:V.TemplateCreateStart,i,n),n(r,i)}finally{Ho(a),H(o?V.TemplateUpdateEnd:V.TemplateCreateEnd,i,n)}}function xd(e,t,n){Od(e,t,n),(n.flags&64)==64&&kd(e,t,n)}function Sd(e,t,n=La){let r=t.localNames;if(r!==null){let i=t.index+1;for(let a=0;a{Ya(e.lView)},consumerOnSignalRead(){this.lView[24]=this}};function $d(e){let t=e[24]??Object.create(ef);return t.lView=e,t}var ef={...an,consumerIsAlwaysLive:!0,kind:`template`,consumerMarkedDirty:e=>{let t=Qa(e.lView);for(;t&&!tf(t[1]);)t=Qa(t);t&&Ga(t)},consumerOnSignalRead(){this.lView[24]=this}};function tf(e){return e.type!==2}function nf(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 rf=100;function af(e,t=0){let n=e[10].rendererFactory;n.begin?.();try{of(e,t)}finally{n.end?.()}}function of(e,t){let n=yo();try{bo(!0),ff(e,t);let n=0;for(;qa(e);){if(n===rf)throw new N(103,!1);n++,ff(e,1)}}finally{bo(n)}}function sf(e,t,n,r){if(Na(t))return;let i=t[2];Po(t);let a=!0,o=null,s=null;tf(e)?(s=Yd(t),o=pn(s)):rn()===null?(a=!1,s=$d(t),o=pn(s)):t[24]&&=(vn(t[24]),null);try{Wa(t),Co(e.bindingStartIndex),n!==null&&bd(e,t,n,2,r);let a=(i&3)==3;if(a){let n=e.preOrderCheckHooks;n!==null&&ac(t,n,null)}else{let n=e.preOrderHooks;n!==null&&oc(t,n,0,null),sc(t,0)}if(lf(t),nf(t),cf(t,0),e.contentQueries!==null&&kl(e,t),a){let n=e.contentCheckHooks;n!==null&&ac(t,n)}else{let n=e.contentHooks;n!==null&&oc(t,n,1),sc(t,1)}mf(e,t);let o=e.components;o!==null&&pf(t,o,0);let s=e.viewQuery;if(s!==null&&Al(2,s,r),a){let n=e.viewCheckHooks;n!==null&&ac(t,n)}else{let n=e.viewHooks;n!==null&&oc(t,n,2),sc(t,2)}if(e.firstUpdatePass===!0&&(e.firstUpdatePass=!1),t[22]){for(let e of t[22])e();t[22]=null}qd(t),t[2]&=-73}catch(e){throw Ya(t),e}finally{s!==null&&(hn(s,o),a&&Zd(s)),zo()}}function cf(e,t){for(let n=pl(e);n!==null;n=ml(n))for(let e=10;e0&&(e[n-1][4]=r[4]);let a=Ri(e,10+t);zu(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 xf(e,t,n,r){let i=10+r,a=n.length;r>0&&(n[i-1][4]=t),r-1&&(bf(e,n),Ri(t,n))}this._attachedToViewContainer=!1}Wu(this._lView[1],this._lView)}onDestroy(e){Xa(this._lView,e)}markForCheck(){hf(this._cdRefInjectingView||this._lView,4)}detach(){this._lView[2]&=-129}reattach(){Ja(this._lView),this._lView[2]|=128}detectChanges(){this._lView[2]|=1024,af(this._lView)}checkNoChanges(){}attachToViewContainerRef(){if(this._appRef)throw new N(902,!1);this._attachedToViewContainer=!0}detachFromAppRef(){this._appRef=null;let e=Ma(this._lView),t=this._lView[16];t!==null&&!e&&Uu(t,this._lView),Vu(this._lView[1],this._lView)}attachToAppRef(e){if(this._attachedToViewContainer)throw new N(902,!1);this._appRef=e;let t=Ma(this._lView),n=this._lView[16];n!==null&&!t&&Sf(n,this._lView),Ja(this._lView)}};function wf(e,t,n,r,i){let a=e.data[t];if(a===null)a=Tf(e,t,n,r,i),Eo()&&(a.flags|=32);else if(a.type&64){a.type=n,a.value=r,a.attrs=i;let e=ho();a.injectorIndex=e===null?-1:e.injectorIndex}return go(a,!0),a}function Tf(e,t,n,r,i){let a=mo(),o=_o(),s=o?a:a&&a.parent,c=e.data[t]=Df(e,s,n,t,r,i);return Ef(e,c,a,o),c}function Ef(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 Df(e,t,n,r,i,a){let o=t?t.injectorIndex:-1,s=0;return oo()&&(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:qo(),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 Of(e){let t=e[6]??[],n=e[3][11],r=[];for(let e of t)e.data.di===void 0?kf(e,n):r.push(e);e[6]=r}function kf(e,t){let n=0,r=e.firstChild;if(r){let i=e.data.r;for(;nnull,jf=()=>null;function Mf(e,t){return Af(e,t)}function Nf(e,t,n){return jf(e,t,n)}var Pf=class{},Ff=class{},If=(()=>{class e{static ɵprov=Zr({token:e,providedIn:`root`,factory:()=>null})}return e})();function Lf(e){return e.debugInfo?.className||e.type.name||null}var Rf={},zf=class{injector;parentInjector;constructor(e,t){this.injector=e,this.parentInjector=t}get(e,t,n){let r=this.injector.get(e,Rf,n);return r!==Rf||t===Rf?r:this.parentInjector.get(e,t,n)}};function Bf(e,t,n){return e[t]=n}function Vf(e,t){return e[t]}function Hf(e,t,n){if(n===du)return!1;let r=e[t];return!Object.is(r,n)&&(e[t]=n,!0)}function Uf(e,t,n,r){let i=Hf(e,t,n);return Hf(e,t+1,r)||i}function Wf(e,t,n,r,i){let a=Uf(e,t,n,r);return Hf(e,t+2,i)||a}function Gf(e,t,n){return function r(i){let a=r.__ngNativeEl__;a!==void 0&&Cl(i,a),hf(ka(e)?Va(e.index,t):t,5);let o=t[8],s=Kf(t,o,n,i),c=r.__ngNextListenerFn__;for(;c;)s=Kf(t,o,c,i)&&s,c=c.__ngNextListenerFn__;return s}}function Kf(e,t,n,r){let i=M(null);try{return H(V.OutputStart,t,n),n(r)!==!1}catch(t){return Ld(e,t),!1}finally{H(V.OutputEnd,t,n),M(i)}}function qf(e,t,n,r,i,a,o,s){let c=Aa(e),l=!1,u=null;if(!r&&c&&(u=Yf(t,n,a,e.index)),u!==null){let e=u.__ngLastListenerFn__||u;e.__ngNextListenerFn__=o,u.__ngLastListenerFn__=o,l=!0}else{let o=La(e,n),c=r?r(o):o;r||(s.__ngNativeEl__=o);let l=i.listen(c,a,s);Jf(a)||Xf(r?t=>r(Fa(t[e.index])):e.index,t,n,a,s,l,!1)}return l}function Jf(e){return e.startsWith(`animation`)||e.startsWith(`transition`)}function Yf(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 Xf(e,t,n,r,i,a,o){let s=t.firstCreatePass?eo(t):null,c=$a(n),l=c.length;c.push(i,a),s&&s.push(r,e,l,(l+1)*(o?-1:1))}function Zf(e,t,n,r,i,a){let o=t[n],s=t[1],c=o[s.data[n].outputs[r]].subscribe(a);Xf(e.index,s,t,i,a,c,!0)}var Qf=Symbol(`BINDING`),$f=new F(``);function ep(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 mp(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&vd.SignalBased)!==0};return i&&(a.transform=i),a})}function Sp(e){return Object.keys(e).map(t=>({propName:e[t],templateName:t}))}function Cp(e,t,n){let r=t instanceof da?t:t?.injector;return r&&e.getStandaloneInjector!==null&&(r=e.getStandaloneInjector(r)||r),r?new zf(n,r):n}function wp(e){let t=e.get(Ff,null);if(t===null)throw new N(407,!1);return{rendererFactory:t,sanitizer:e.get(If,null),changeDetectionScheduler:e.get(Is,null),ngReflect:!1,tracingService:e.get(Su,null,{optional:!0})}}function Tp(e,t,n){let r=Dp(e);return Hl(t,r,r===`svg`?`svg`:r===`math`?Pa:n)}function Ep(e){if((e&&`localName`in e&&typeof e.localName==`string`?e.localName:e?.tagName)?.toLowerCase()===`script`)throw new N(905,!1)}function Dp(e){return(e.selectors[0][0]||`div`).toLowerCase()}var Op=class{componentDef;ngModule;selector;componentType;ngContentSelectors;isBoundToModule;cachedInputs=null;cachedOutputs=null;get inputs(){return this.cachedInputs??=xp(this.componentDef.inputs),this.cachedInputs}get outputs(){return this.cachedOutputs??=Sp(this.componentDef.outputs),this.cachedOutputs}constructor(e,t){this.componentDef=e,this.ngModule=t,this.componentType=e.type,this.selector=lu(e.selectors),this.ngContentSelectors=e.ngContentSelectors??[],this.isBoundToModule=!!t}create(e,t,n,r,i,a,o){H(V.DynamicComponentStart);let s=M(null);try{let s=this.componentDef,c=Cp(s,r||this.ngModule,e),l=wp(c),u=l.tracingService;return u&&u.componentCreate?u.componentCreate(Lf(s),()=>this.createComponentRef(l,c,t,n,i,a,o)):this.createComponentRef(l,c,t,n,i,a,o)}finally{M(s)}}createComponentRef(e,t,n,r,i,a,o){let s=this.componentDef,c=kp(r,s,a,i),l=e.rendererFactory.createRenderer(null,s),u=r?Cd(l,r,s.encapsulation,t):Tp(s,l,o??null);Ep(u);let d=t.get($f,null),f=Ap(u,()=>t.get(es,null)??vl());d&&d.addHost(f);let p=a?.some(Mp)||i?.some(e=>typeof e!=`function`&&e.bindings.some(Mp)),m=fd(null,c,null,512|md(s),null,null,e,l,t,null,Dl(u,t,!0));d&&yp&&f instanceof ShadowRoot&&Xa(m,()=>{d.removeHost(f)}),m[27]=u,Po(m);let h=null;try{let e=gp(27,m,2,`#host`,()=>c.directiveRegistry,!0,0);Yl(l,u,e),fl(u,m),xd(c,m,e),jl(c,e,m),_p(c,e),n!==void 0&&Pp(e,this.ngContentSelectors,n),h=Va(e.index,m),m[8]=h[8],Vd(c,m,null)}catch(e){throw h!==null&&ul(h),ul(m),e}finally{H(V.DynamicComponentEnd),zo()}return new Np(this.componentType,m,!!p)}};function kp(e,t,n,r){let i=e?[`ng-version`,`22.1.7`]:uu(t.selectors[0]),a=null,o=null,s=0;if(n)for(let e of n)s+=e[Qf].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 Mp(e){let t=e[Qf].kind;return t===`input`||t===`twoWay`}var Np=class extends Pf{_rootLView;_hasInputBindings;instance;hostView;changeDetectorRef;componentType;location;previousInputValues=null;_tNode;constructor(e,t,n){super(),this._rootLView=t,this._hasInputBindings=n,this._tNode=Ra(t[1],27),this.location=nl(this._tNode,t),this.instance=Va(this._tNode.index,t)[8],this.hostView=this.changeDetectorRef=new Cf(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;Rd(n,r[1],r,e,t),this.previousInputValues.set(e,t),hf(Va(n.index,r),1)}get injector(){return new Kc(this._tNode,this._rootLView)}destroy(){this.hostView.destroy()}onDestroy(e){this.hostView.onDestroy(e)}};function Pp(e,t,n){let r=e.projection=[];for(let e=0;e!1;function Ip(e,t,n){return Fp(e,t,n)}function Lp(e){return!!e&&typeof e.then==`function`}function Rp(e){return!!e&&typeof e.subscribe==`function`}var zp=class{},Bp=class extends zp{injector;instance=null;constructor(e){super();let t=new fa([...e.providers,{provide:zp,useValue:this}],e.parent||ua(),e.debugName,new Set([`environment`]));this.injector=t,e.runEnvironmentInitializers&&t.resolveInjectorInitializers()}destroy(){this.injector.destroy()}onDestroy(e){this.injector.onDestroy(e)}};function Vp(e,t,n=null){return new Bp({providers:e,parent:t,debugName:n,runEnvironmentInitializers:!0}).injector}var Hp=(()=>{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=Zi(!1,e.type),n=t.length>0?Vp([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=Zr({token:e,providedIn:`environment`,factory:()=>new e(I(da))})}return e})();function Up(e){return Qs(()=>{let t=Jp(e),n={...t,decls:e.decls,vars:e.vars,template:e.template,consts:e.consts||null,ngContentSelectors:e.ngContentSelectors,onPush:e.changeDetection!==al.Eager,directiveDefs:null,pipeDefs:null,dependencies:t.standalone&&e.dependencies||null,getStandaloneInjector:t.standalone?e=>e.get(Hp).getOrCreateStandaloneInjector(n):null,getExternalStyles:null,signals:e.signals??!1,data:e.data||{},encapsulation:e.encapsulation||Ml.Emulated,styles:e.styles||Gi,_:null,schemas:e.schemas||null,tView:null,id:``};t.standalone&&wu(`NgStandalone`),Yp(n);let r=e.dependencies;return n.directiveDefs=Xp(r,Wp),n.pipeDefs=Xp(r,pi),n.id=Zp(n),n})}function Wp(e){return di(e)||fi(e)}function Gp(e,t){if(e==null)return Wi;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=vd.None,c=null),n[a]=[r,s,c],t[a]=o}return n}function Kp(e){if(e==null)return Wi;let t={};for(let n in e)Object.hasOwn(e,n)&&(t[e[n]]=n);return t}function qp(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 Jp(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||Wi,exportAs:e.exportAs||null,standalone:e.standalone??!0,signals:e.signals===!0,selectors:e.selectors||Gi,viewQuery:e.viewQuery||null,features:e.features||null,setInput:null,resolveHostDirectives:null,hostDirectives:null,controlDef:null,signalFormsInputPresence:null,inputs:Gp(e.inputs,t),outputs:Kp(e.outputs),debugInfo:null}}function Yp(e){e.features?.forEach(t=>t(e))}function Xp(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 Zp(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 Qp=new F(``),$p=(()=>{class e{resolve;reject;initialized=!1;done=!1;donePromise=new Promise((e,t)=>{this.resolve=e,this.reject=t});appInits=L(Qp,{optional:!0})??[];injector=L($o);constructor(){}runInitializers(){if(this.initialized)return;let e=[];for(let t of this.appInits){let n=Ca(this.injector,t);if(Lp(n))e.push(n);else if(Rp(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=el({token:e,factory:e.ɵfac})}return e})();function em(e,t,n,r,i,a,o,s){if(n.firstCreatePass){e.mergedAttrs=vc(e.mergedAttrs,e.attrs);let t=e.tView=ld(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),go(e,!1);let c=rm(n,t,e,r);Yo()&&$u(n,t,c,e),fl(c,t);let l=gf(c,t,c,e);t[r+27]=l,gd(t,l),Ip(l,e,t)}function tm(e,t,n,r,i,a,o,s,c,l,u){let d=n+27,f;if(t.firstCreatePass){if(f=wf(t,d,4,o||null,s||null),l!=null){let e=Ua(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?Vp(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=Zr({token:e,providedIn:`environment`,factory:()=>new e})}return e})(),Nm=new F(``);function Pm(e,t,n){return e.get(Mm).getOrCreateInjector(t,e,n,``)}function Fm(e,t,n){if(e instanceof zf){let r=e.injector,i=e.parentInjector;return new zf(r,Pm(i,t,n))}let r=e.get(da);return r===e?Pm(e,t,n):new zf(e,Pm(r,t,n))}function Im(e,t,n,r=!1){let i=n[3],a=i[1];if(Na(i))return;let o=Cm(i,t),s=o[1],c=o[mm];if(!(c!==null&&ee.data.s===t[1])??-1;return{dehydratedView:n>-1?e[6][n]:null,dehydratedViewIx:n}}function Rm(e,t,n,r,i){H(V.DeferBlockStateStart);let a=Dm(e,i,r);if(a!==null){t[1]=e;let o=i[1],s=Ra(o,a+27);yf(n,0);let c;if(e===cm.Complete){let e=Tm(o,r),t=e.providers;t&&t.length>0&&(c=Fm(i[9],e,t))}let{dehydratedView:l,dehydratedViewIx:u}=Lm(n,t),d=Ud(i,s,null,{injector:c,dehydratedView:l});if(vf(n,d,0,Wd(s,l)),Ga(d),u>-1&&n[6]?.splice(u,1),(e===cm.Complete||e===cm.Error)&&Array.isArray(t[hm])){for(let e of t[hm])e();t[hm]=null}}H(V.DeferBlockStateEnd)}function zm(e,t){return e{e.loadingState===am.COMPLETE?Im(cm.Complete,t,n):e.loadingState===am.FAILED&&Im(cm.Error,t,n)})}var Hm=null;function Um(e,t){return t[9].get(Nm,null,{optional:!0})?.behavior!==_m.Manual}var Wm=new F(``),Gm=new F(``);function Km(){Mn(()=>{throw new N(600,``)})}var qm=10,Jm=(()=>{class e{_runningTick=!1;_destroyed=!1;_destroyListeners=[];_views=[];internalErrorHandler=L(Es);afterRenderManager=L(Tu);zonelessEnabled=L(Ls);rootEffectScheduler=L(zs);dirtyFlags=0;tracingSnapshot=null;allTestViews=new Set;autoDetectTestViews=new Set;includeAllTestViews=!1;afterTick=new Rr;get allViews(){return[...(this.includeAllTestViews?this.allTestViews:this.autoDetectTestViews).keys(),...this._views]}get destroyed(){return this._destroyed}componentTypes=[];components=[];internalPendingTask=L(as);get isStable(){return this.internalPendingTask.hasPendingTasksObservable.pipe(Vr(e=>!e))}constructor(){L(Su,{optional:!0})}whenStable(){let e;return new Promise(t=>{e=this.isStable.subscribe({next:e=>{e&&t()}})}).finally(()=>{e.unsubscribe()})}_injector=L(da);_rendererFactory=null;get injector(){return this._injector}bootstrap(e,t){return this.bootstrapImpl(e,t)}bootstrapImpl(e,t,n=$o.NULL){return this._injector.get(ps).run(()=>{if(H(V.BootstrapComponentStart),!this._injector.get($p).done)throw new N(405,``);let r=di(e),i=this._injector.get(zp),a=new Op(r,i);this.componentTypes.push(e);let{hostElement:o,directives:s,bindings:c}=Ym(t),l=o||a.selector,u=a.create(n,[],l,i.injector,s,c),d=u.location.nativeElement,f=u.injector.get(Wm,null);return f?.registerApplication(d),u.onDestroy(()=>{this.detachView(u.hostView),Xm(this.components,u),f?.unregisterApplication(d)}),this._loadComponent(u),H(V.BootstrapComponentEnd,u),u})}tick(){this.zonelessEnabled||(this.dirtyFlags|=1),this._tick()}_tick(){H(V.ChangeDetectionStart),this.tracingSnapshot===null?this.tickImpl():this.tracingSnapshot.run(xu.CHANGE_DETECTION,this.tickImpl)}tickImpl=()=>{if(this._runningTick)throw H(V.ChangeDetectionEnd),new N(101,!1);let e=M(null);try{this._runningTick=!0,this.synchronize()}finally{this._runningTick=!1,this.tracingSnapshot?.dispose(),this.tracingSnapshot=null,M(e),this.afterTick.next(),H(V.ChangeDetectionEnd)}};synchronize(){this._rendererFactory===null&&!this._injector.destroyed&&(this._rendererFactory=this._injector.get(Ff,null,{optional:!0}));let e=0;for(;this.dirtyFlags!==0&&e++qa(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;Xm(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(Gm,[]).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),()=>Xm(this._destroyListeners,e)}destroy(){if(this._destroyed)throw new N(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=el({token:e,factory:e.ɵfac})}return e})();function Ym(e){return e===void 0||typeof e==`string`||e instanceof Element?{hostElement:e}:e}function Xm(e,t){let n=e.indexOf(t);n>-1&&e.splice(n,1)}function Zm(e,t,n){let r=t.get($m);return r.add(e,n),()=>r.remove(e)}function Qm(e){return(t,n)=>Zm(t,n,e)}var $m=(()=>{class e{buckets=new Map;callbackBucket=new Map;applicationRef=L(Jm);ngZone=L(ps);idleService=L(Qc);add(e,t){let n=eh(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=eh(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=Zr({token:e,providedIn:`root`,factory:()=>new e})}return e})();function eh(e){return!e||e.timeout==null?``:`${e.timeout}`}function th(e){let t=z(),n=po();if(Bm(t,n),!Um(0,t))return;let r=t[9];vm(0,Cm(t,n),e(()=>rh(0,t,n),r))}function nh(e,t,n){let r=t[9],i=t[1];if(e.loadingState!==am.NOT_STARTED)return e.loadingPromise??Promise.resolve();let a=Cm(t,n),o=jm(i,e);e.loadingState=am.IN_PROGRESS,ym(1,a);let s=e.dependencyResolverFn,c=r.get(Ys).add();return s?(e.loadingPromise=Promise.allSettled(s()).then(n=>{let r=!1,i=[],a=[];for(let e=0;e0&&(t.directiveRegistry=Am(t.directiveRegistry,i),e.providers=Zi(!1,...i.map(e=>e.type))),a.length>0&&(t.pipeRegistry=Am(t.pipeRegistry,a))}}),e.loadingPromise.finally(()=>{e.loadingPromise=null,c()})):(e.loadingPromise=Promise.resolve().then(()=>{e.loadingPromise=null,e.loadingState=am.COMPLETE,c()}),e.loadingPromise)}function rh(e,t,n){let r=t[1],i=t[n.index];if(!Um(e,t))return;let a=Cm(t,n),o=Tm(r,n);switch(bm(a),o.loadingState){case am.NOT_STARTED:Im(cm.Loading,n,i),nh(o,t,n),o.loadingState===am.IN_PROGRESS&&Vm(o,n,i);break;case am.IN_PROGRESS:Im(cm.Loading,n,i),Vm(o,n,i);break;case am.COMPLETE:Im(cm.Complete,n,i);break;case am.FAILED:Im(cm.Error,n,i)}}function ih(e,t,n){return e===0?oh(t,n):e!==2||!oh(t,n)}function ah(e){return e!=null&&(e&1)==1}function oh(e,t){let n=e[9],r=Tm(e[1],t),i=Ol(n),a=ah(r.flags),o=Cm(e,t)[pm]!==null;return!(a&&o&&i)}function sh(e,t,n,r,i,a,o,s,c,l){let u=z(),d=lo(),f=e+27,p=tm(u,d,e,null,0,0),m=u[9],h=Ol(m);if(d.firstCreatePass){wu(`NgDefer`);let e={primaryTmplIndex:t,loadingTmplIndex:r??null,placeholderTmplIndex:i??null,errorTmplIndex:a??null,placeholderBlockConfig:null,loadingBlockConfig:null,dependencyResolverFn:n??null,loadingState:am.NOT_STARTED,loadingPromise:null,providers:null,hydrateTriggers:null,debug:null,flags:l??0};c?.(d,e,s,o),Em(d,f,e)}let g=u[f];Ip(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,lm.Initial,null,null,null,null,v,_,null,null];wm(u,f,y);let b=null;v!==null&&h&&(b=m.get(wl),b.add(v,{lView:u,tNode:p,lContainer:g}));let ee=()=>{bm(y),v!==null&&b?.cleanup([v])};vm(0,y,()=>Za(u,ee)),Xa(u,ee)}function ch(e){ih(0,z(),po())&&th(Qm({timeout:e}))}function lh(e,t,n,r){let i=z();return Hf(i,wo(),t)&&(lo(),Md(Uo(),i,e,t,n,r)),lh}var uh=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 dh(e,t,n,r,i){return e===n&&Object.is(t,r)?1:Object.is(i(e,t),i(n,r))?-1:0}function fh(e,t,n,r){let i,a,o=0,s=e.length-1;if(Array.isArray(t)){M(r);let c=t.length-1;for(M(null);o<=s&&o<=c;){let r=e.at(o),l=t[o],u=dh(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=dh(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 gh,a??=hh(e,o,s,n),ph(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;)mh(e,i,n,o,t[o]),o++}else if(t!=null){M(r);let c=t[Symbol.iterator]();M(null);let l=c.next();for(;!l.done&&o<=s;){let t=e.at(o),r=l.value,u=dh(o,t,o,r,n);if(u!==0)u<0&&e.updateValue(o,r),o++,l=c.next();else{i??=new gh,a??=hh(e,o,s,n);let u=n(o,r);if(ph(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;)mh(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 ph(e,t,n,r){return t!==void 0&&t.has(r)?(e.attach(n,t.get(r)),t.delete(r),!0):!1}function mh(e,t,n,r,i){if(ph(e,t,r,n(r,i)))e.updateValue(r,i);else{let t=e.create(r,i);e.attach(r,t)}}function hh(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 gh=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 W(e,t,n,r,i,a,o,s){wu(`NgControlFlow`);let c=z(),l=lo();return tm(c,l,e,t,n,r,i,Ua(l.consts,a),256,o,s),_h}function _h(e,t,n,r,i,a,o,s){wu(`NgControlFlow`);let c=z(),l=lo();return tm(c,l,e,t,n,r,i,Ua(l.consts,a),512,o,s),_h}function G(e,t){wu(`NgControlFlow`);let n=z(),r=wo(),i=n[r]===du?-1:n[r],a=i===-1?void 0:Ch(n,27+i);if(Hf(n,r,e)){let r=M(null);try{if(a!==void 0&&yf(a,0),e!==-1){let r=27+e,i=Ch(n,r),a=Oh(n[1],r),o=Nf(i,a,n);vf(i,Ud(n,a,t,{dehydratedView:o}),0,Wd(a,o))}}finally{M(r)}}else if(a!==void 0){let e=_f(a,0);e!==void 0&&(e[8]=t)}}var vh=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 yh(e){return e}function bh(e,t){return t}var xh=class{hasEmptyBlock;trackByFn;liveCollection;constructor(e,t,n){this.hasEmptyBlock=e,this.trackByFn=t,this.liveCollection=n}};function K(e,t,n,r,i,a,o,s,c,l,u,d,f){wu(`NgControlFlow`);let p=z(),m=lo(),h=c!==void 0,g=z(),_=new xh(h,s?o.bind(g[15][8]):o);g[27+e]=_,tm(p,m,e+1,t,n,r,i,Ua(m.consts,a),256),h&&tm(p,m,e+2,c,l,u,d,Ua(m.consts,f),512)}var Sh=class extends uh{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,vf(this.lContainer,t,e,Wd(this.templateTNode,n)),wh(this.lContainer,e)}detach(e){return this.needsIndexUpdate||=e!==this.length-1,Th(this.lContainer,e),Eh(this.lContainer,e)}create(e,t){let n=Mf(this.lContainer,this.templateTNode.tView.ssrId);return Ud(this.hostLView,this.templateTNode,new vh(this.lContainer,t,e),{dehydratedView:n})}destroy(e){Wu(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];ku(e,r),hu.delete(n[19]),r.detachedLeaveAnimationFns=void 0}}function Th(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 Eh(e,t){return bf(e,t)}function Dh(e,t){return _f(e,t)}function Oh(e,t){return Ra(e,t)}function kh(e,t,n){let r=z();return Hf(r,wo(),t)&&(lo(),Td(Uo(),r,e,t,r[11],n)),kh}function Ah(e,t,n,r,i){Rd(t,e,n,i?`class`:`style`,r)}function jh(e,t,n,r){let i=z(),a=i[1],o=e+27,s=a.firstCreatePass?gp(o,i,2,t,jd,ao(),n,r):a.data[o];if(ka(s)){let n=i[10].tracingService;if(n&&n.componentCreate){let o=a.data[s.directiveStart+s.componentOffset];return n.componentCreate(Lf(o),()=>(Mh(e,t,i,s,r),jh))}}return Mh(e,t,i,s,r),jh}function Mh(e,t,n,r,i){if(Fd(r,n,e,t,Ih),Aa(r)){let e=n[1];xd(e,n,r),jl(e,r,n)}i!=null&&Sd(n,r)}function Nh(){let e=lo(),t=Id(po());return e.firstCreatePass&&_p(e,t),so(t)&&co(),io(),t.classesWithoutHost!=null&&pc(t)&&Ah(e,t,z(),t.classesWithoutHost,!0),t.stylesWithoutHost!=null&&mc(t)&&Ah(e,t,z(),t.stylesWithoutHost,!1),Nh}function Ph(e,t,n,r){return jh(e,t,n,r),Nh(),Ph}function J(e,t,n,r){let i=z(),a=i[1],o=e+27,s=a.firstCreatePass?vp(o,a,2,t,n,r):a.data[o];return Fd(s,i,e,t,Ih),r!=null&&Sd(i,s),J}function Y(){return so(Id(po()))&&co(),io(),Y}function Fh(e,t,n,r){return J(e,t,n,r),Y(),Fh}var Ih=(e,t,n,r,i)=>(Xo(!0),Hl(t[11],r,qo()));function Lh(){let e=lo(),t=Id(po());return e.firstCreatePass&&_p(e,t),Lh}function Rh(e,t,n){let r=z(),i=r[1],a=e+27,o=i.firstCreatePass?vp(a,i,8,`ng-container`,t,n):i.data[a];return Fd(o,r,e,`ng-container`,Vh),n!=null&&Sd(r,o),Rh}function zh(){return Id(po()),Lh}function Bh(e,t,n){return Rh(e,t,n),zh(),Bh}var Vh=(e,t,n,r,i)=>(Xo(!0),Vl(t[11],``));function Hh(){return z()}function Uh(e,t,n){let r=z();return Hf(r,wo(),t)&&(lo(),Ed(Uo(),r,e,t,r[11],n)),Uh}var Wh=`en-US`;function Gh(e){typeof e==`string`&&e.toLowerCase().replace(/_/g,`-`)}function Kh(e,t,n){let r=z(),i=lo(),a=po();return Jh(i,r,r[11],a,e,t,n),Kh}function qh(e,t,n){let r=z(),i=lo(),a=po();return(a.type&3||n)&&qf(a,i,r,n,r[11],e,t,Gf(a,r,t)),qh}function Jh(e,t,n,r,i,a,o){let s=!0,c=null;if((r.type&3||o)&&(c??=Gf(r,t,a),qf(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 Zh(e){return(e&2)==2}function Qh(e,t){return e&131071|t<<17}function $h(e){return e|2}function eg(e){return(e&131068)>>2}function tg(e,t){return e&-131069|t<<2}function ng(e){return(e&1)==1}function rg(e){return e|1}function ig(e,t,n,r,i,a){let o=a?t.classBindings:t.styleBindings,s=Xh(o),c=eg(o);e[r]=n;let l=!1,u;if(Array.isArray(n)){let e=n;u=e[1],(u===null||Hi(e,u)>0)&&(l=!0)}else u=n;if(i){if(c!==0){let t=Xh(e[s+1]);e[r+1]=Yh(t,s),t!==0&&(e[t+1]=tg(e[t+1],r)),e[s+1]=Qh(e[s+1],r)}else e[r+1]=Yh(s,0),s!==0&&(e[s+1]=tg(e[s+1],r)),s=r}else e[r+1]=Yh(c,0),s===0?s=r:e[c+1]=tg(e[c+1],r),c=r;l&&(e[r+1]=$h(e[r+1])),og(e,u,r,!0),og(e,u,r,!1),ag(t,u,e,r,a),o=Yh(s,c),a?t.classBindings=o:t.styleBindings=o}function ag(e,t,n,r,i){let a=i?e.residualClasses:e.residualStyles;a!=null&&typeof t==`string`&&Hi(a,t)>=0&&(n[r+1]=rg(n[r+1]))}function og(e,t,n,r){let i=e[n+1],a=t===null,o=r?Xh(i):eg(i),s=!1;for(;o!==0&&(s===!1||a);){let n=e[o],i=e[o+1];sg(n,t)&&(s=!0,e[o+1]=r?rg(i):$h(i)),o=r?Xh(i):eg(i)}s&&(e[n+1]=r?$h(i):rg(i))}function sg(e,t){return e===null||t==null||(Array.isArray(e)?e[1]:e)===t?!0:Array.isArray(e)&&typeof t==`string`?Hi(e,t)>=0:!1}function cg(e,t,n){return ug(e,t,n,!1),cg}function lg(e,t){return ug(e,t,null,!0),lg}function ug(e,t,n,r){let i=z(),a=lo(),o=To(2);if(a.firstUpdatePass&&fg(a,e,o,r),t!==du&&Hf(i,o,t)){let s=a.data[Vo()];yg(a,s,i,i[11],e,i[o+1]=Sg(t,n),r,o)}}function dg(e,t){return t>=e.expandoStartIndex}function fg(e,t,n,r){let i=e.data;if(i[n+1]===null){let a=i[Vo()],o=dg(e,n);Cg(a,r)&&t===null&&!o&&(t=!1),t=pg(i,a,t,r),ig(i,a,t,n,o,r)}}function pg(e,t,n,r){let i=Ao(e),a=r?t.residualClasses:t.residualStyles;if(i===null)(r?t.classBindings:t.styleBindings)===0&&(n=_g(null,e,t,n,r),n=vg(n,t.attrs,r),a=null);else{let o=t.directiveStylingLast;if(o===-1||e[o]!==i){if(n=_g(i,e,t,n,r),a===null){let n=mg(e,t,r);n!==void 0&&Array.isArray(n)&&(n=_g(null,e,t,n[1],r),n=vg(n,t.attrs,r),hg(e,t,r,n))}else a=gg(e,t,r)}}return a!==void 0&&(r?t.residualClasses=a:t.residualStyles=a),n}function mg(e,t,n){let r=n?t.classBindings:t.styleBindings;if(eg(r)!==0)return e[Xh(r)]}function hg(e,t,n,r){let i=n?t.classBindings:t.styleBindings;e[Xh(i)]=r}function gg(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===du&&(u=l?Gi:void 0);let d=l?Vi(u,r):c===r?u:void 0;if(a&&!xg(d)&&(d=Vi(t,r)),xg(d)&&(s=d,o))return s;let f=e[i+1];i=o?Xh(f):eg(f)}if(t!==null){let e=a?t.residualClasses:t.residualStyles;e!=null&&(s=Vi(e,r))}return s}function xg(e){return e!==void 0}function Sg(e,t){return e==null||e===``||(typeof t==`string`?e=Pl(e)+t:typeof e==`object`&&(e=Gr(Pl(e)))),e}function Cg(e,t){return!!(e.flags&(t?8:16))}function Z(e,t=``){let n=z(),r=lo(),i=e+27,a=r.firstCreatePass?wf(r,i,1,t,null):r.data[i],o=wg(r,n,a,t);n[i]=o,Yo()&&$u(r,n,o,a),go(a,!1)}var wg=(e,t,n,r)=>(Xo(!0),zl(t[11],r));function Tg(e,t,n,r=``){return Hf(e,wo(),n)?t+hi(n)+r:du}function Eg(e,t,n,r,i,a=``){let o=Uf(e,So(),n,i);return To(2),o?t+hi(n)+r+hi(i)+a:du}function Dg(e,t,n,r,i,a,o,s=``){let c=Wf(e,So(),n,i,o);return To(3),c?t+hi(n)+r+hi(i)+a+hi(o)+s:du}function Q(e){return $(``,e),Q}function $(e,t,n){let r=z(),i=Tg(r,e,t,n);return i!==du&&Ag(r,Vo(),i),$}function Og(e,t,n,r,i){let a=z(),o=Eg(a,e,t,n,r,i);return o!==du&&Ag(a,Vo(),o),Og}function kg(e,t,n,r,i,a,o){let s=z(),c=Dg(s,e,t,n,r,i,a,o);return c!==du&&Ag(s,Vo(),c),kg}function Ag(e,t,n){let r=Ia(t,e);Bl(e[11],r,n)}function jg(e,t){let n=xo()+e,r=z();return r[n]===du?Bf(r,n,t()):Vf(r,n)}function Mg(e,t){let n=e[t];return n===du?void 0:n}function Ng(e,t,n,r,i,a){let o=t+n;return Hf(e,o,i)?Bf(e,o+1,a?r.call(a,i):r(i)):Mg(e,o+1)}function Pg(e,t){let n=lo(),r,i=e+27;n.firstCreatePass?(r=Fg(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=Fi(r.type,!0)),o=Ti(tp);try{let e=Tc(!1),t=a();return Tc(e),Ba(n,z(),i,t),t}finally{Ti(o)}}function Fg(e,t){if(t)for(let n=t.length-1;n>=0;n--){let r=t[n];if(e===r.name)return r}}function Ig(e,t,n){let r=e+27,i=z(),a=za(i,r);return Lg(i,r)?Ng(i,xo(),t,a.transform,n,a):a.transform(n)}function Lg(e,t){return e[1].data[t].pure}var Rg=(()=>{class e{applicationErrorHandler=L(Es);appRef=L(Jm);taskService=L(as);ngZone=L(ps);zonelessEnabled=L(Ls);tracing=L(Su,{optional:!0});zoneIsDefined=typeof Zone<`u`&&!!Zone.root.run;schedulerTickApplyArgs=[{data:{__scheduler_tick__:!0}}];subscriptions=new nr;angularZoneId=this.zoneIsDefined?this.ngZone._inner?.get(ds):null;scheduleInRootZone=!this.zonelessEnabled&&this.zoneIsDefined&&(L(Rs,{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?ls:cs;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=el({token:e,factory:e.ɵfac})}return e})();function zg(){return[{provide:Is,useExisting:Rg},{provide:ps,useClass:xs},{provide:Ls,useValue:!0}]}function Bg(){return typeof $localize<`u`&&$localize.locale||`en-US`}var Vg=new F(``,{factory:()=>L(Vg,{optional:!0,skipSelf:!0})||Bg()}),Hg=class{destroyed=!1;listeners=null;errorHandler=L(Ts,{optional:!0});isEmitting=!1;hasNullListeners=!1;destroyRef=L(ts);constructor(){this.destroyRef.onDestroy(()=>{this.destroyed=!0,this.listeners=null})}subscribe(e){if(this.destroyed)throw new N(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(Wr(953,!1));return}if(this.listeners===null)return;this.isEmitting=!0;let t=M(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&&Ug(this.listeners)),M(t),this.isEmitting=!1}}};function Ug(e){let t=e.length-1;for(;t>-1;)e[t]===null&&e.splice(t,1),t--}function Wg(e,t){return wn(e,t?.equal)}(class e extends Error{_brand;constructor(e){super(e)}static IDLE=new e(`IDLE`);static LOADING=new e(`LOADING`)});function Gg(e,t){let n=Object.create(Zs);n.value=e,n.transformFn=t?.transform;function r(){if(on(n),n.value===Xs)throw new N(-950,null);return n.value}return r[nn]=n,r}function Kg(e){return new Hg}function qg(e,t){return Gg(e,t)}function Jg(e){return Gg(Xs,e)}var Yg=(qg.required=Jg,qg),Xg=new F(``),Zg=new F(``);function Qg(e){return!e.moduleRef}function $g(e){let t=Qg(e)?e.r3Injector:e.moduleRef.injector,n=t.get(ps);return n.run(()=>{Qg(e)?e.r3Injector.resolveInjectorInitializers():e.moduleRef.resolveInjectorInitializers();let r=t.get(Es),i;if(n.runOutsideAngular(()=>{i=n.onError.subscribe({next:r})}),Qg(e)){let n=()=>t.destroy(),r=e.platformInjector.get(Xg);r.add(n),t.onDestroy(()=>{i.unsubscribe(),r.delete(n)})}else{let t=()=>e.moduleRef.destroy(),n=e.platformInjector.get(Xg);n.add(t),e.moduleRef.onDestroy(()=>{Xm(e.allPlatformModules,e.moduleRef),i.unsubscribe(),n.delete(t)})}return t_(r,n,()=>{let n=t.get(as),r=n.add(),i=t.get($p);return i.runInitializers(),i.donePromise.then(()=>{if(Gh(t.get(Vg,Wh)||`en-US`),!t.get(Zg,!0))return Qg(e)?t.get(Jm):(e.allPlatformModules.push(e.moduleRef),e.moduleRef);if(Qg(e)){let n=t.get(Jm);return e.rootComponent!==void 0&&n.bootstrap(e.rootComponent),n}return e_?.(e.moduleRef,e.allPlatformModules),e.moduleRef}).finally(()=>void n.remove(r))})})}var e_;function t_(e,t,n){try{let r=n();return Lp(r)?r.catch(n=>{throw t.runOutsideAngular(()=>e(n)),n}):r}catch(n){throw t.runOutsideAngular(()=>e(n)),n}}var n_=null;function r_(e=[],t){return $o.create({name:t,providers:[{provide:oa,useValue:`platform`},{provide:Xg,useValue:new Set([()=>n_=null])},...e]})}function i_(e=[]){if(n_)return n_;let t=r_(e);return n_=t,Km(),a_(t),t}function a_(e){let t=e.get(js,null);Ca(e,()=>{t?.forEach(e=>e())})}function o_(e){let{rootComponent:t,appProviders:n,platformProviders:r,platformRef:i}=e;H(V.BootstrapApplicationStart);try{let e=i?.injector??i_(r);return $g({r3Injector:new Bp({providers:[zg(),Ds,...n||[]],parent:e,debugName:``,runEnvironmentInitializers:!1}).injector,platformInjector:e,rootComponent:t})}catch(e){return Promise.reject(e)}finally{H(V.BootstrapApplicationEnd)}}var s_=null;function c_(){return s_}function l_(e){s_??=e}var u_=class{},d_=(()=>{class e{transform(e){return JSON.stringify(e,null,2)}static ɵfac=function(t){return new(t||e)};static ɵpipe=qp({name:`json`,type:e,pure:!1})}return e})();function f_(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 p_=`browser`,m_=class{_doc;constructor(e){this._doc=e}manager},h_=(()=>{class e extends m_{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)(I(es))};static ɵprov=Zr({token:e,factory:e.ɵfac})}return e})(),g_=new F(``),__=(()=>{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 h_));this._plugins=n.slice().reverse();let r=e.find(e=>e instanceof h_);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 N(-5101,!1);return this._eventNameToPlugin.set(e,t),t}static ɵfac=function(t){return new(t||e)(I(g_),I(ps))};static ɵprov=Zr({token:e,factory:e.ɵfac})}return e})(),v_=`ng-app-id`;function y_(e){for(let t of e)t.remove()}function b_(e,t){let n=t.createElement(`style`);return n.textContent=e,n}function x_(e,t,n,r){let i=e.head?.querySelectorAll(`style[${v_}="${t}"],link[${v_}="${t}"]`);if(!i||i.length===0)return!1;for(let e of i)e.removeAttribute(v_),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 S_(e,t){let n=t.createElement(`link`);return n.setAttribute(`rel`,`stylesheet`),n.setAttribute(`href`,e),n}var C_=(()=>{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,x_(e,t,this.inline,this.external)&&this.hosts.add(e.head)}addStyles(e,t){for(let t of e)this.addUsage(t,this.inline,b_);t?.forEach(e=>this.addUsage(e,this.external,S_))}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&&(y_(n.elements),t.delete(e)))}ngOnDestroy(){for(let[,{elements:e}]of[...this.inline,...this.external])y_(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,b_(t,this.doc)));for(let[t,{elements:n}]of this.external)n.push(this.addElement(e,S_(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)(I(es),I(ks),I(Ns,8),I(Ms))};static ɵprov=Zr({token:e,factory:e.ɵfac})}return e})(),w_={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`},T_=/%COMP%/g,E_=`%COMP%`,D_=`_nghost-${E_}`,O_=`_ngcontent-${E_}`,k_=!0,A_=new F(``,{factory:()=>k_}),j_=new F(``);function M_(e){return O_.replace(T_,e)}function N_(e){return D_.replace(T_,e)}function P_(e,t){return t.map(t=>t.replace(T_,e))}var F_=(()=>{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 I_(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 B_?n.applyToHost(e):n instanceof z_&&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 Ml.Emulated:r=new B_(o,s,t,this.appId,c,i,a,l,this.cssVarNamespace);break;case Ml.ShadowDom:return new R_(o,e,t,i,a,this.nonce,l,this.cssVarNamespace,s);case Ml.ExperimentalIsolatedShadowDom:return new R_(o,e,t,i,a,this.nonce,l,this.cssVarNamespace);default:r=new z_(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)(I(__),I($f),I(ks),I(A_),I(es),I(ps),I(Ns),I(Su,8),I(j_,8))};static ɵprov=Zr({token:e,factory:e.ɵfac})}return e})(),I_=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(w_[t]||t,e):this.doc.createElement(e)}createComment(e){return this.doc.createComment(e)}createText(e){return this.doc.createTextNode(e)}appendChild(e,t){(L_(e)?e.content:e).appendChild(t)}insertBefore(e,t,n){if(e){let r=L_(e)?e.content:e;if(n!=null&&n.parentNode!==r)throw new N(-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 N(-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=w_[r];i?e.setAttributeNS(i,t,n):e.setAttribute(t,n)}else e.setAttribute(t,n)}removeAttribute(e,t,n){if(n){let r=w_[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&(fu.DashCase|fu.Important)?e.style.setProperty(t,n,r&fu.Important?`important`:``):e.style[t]=n}removeStyle(e,t,n){let r=t.startsWith(`--`);r&&(t=t.replace(`%NS%`,this.cssVarNamespace)),r||n&fu.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=c_().getGlobalEventTarget(this.doc,e),!e))throw new N(-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 L_(e){return e.tagName===`TEMPLATE`&&e.content!==void 0}var R_=class extends I_{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=P_(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=S_(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)}},z_=class extends I_{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?P_(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&&hu.size===0&&this.sharedStylesHost.removeStyles(this.styles,this.styleUrls)}},B_=class extends z_{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=M_(l),this.hostAttr=N_(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}},V_=class e extends u_{supportsDOMEvents=!0;static makeCurrent(){l_(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=U_();return t==null?null:W_(t)}resetBaseElement(){H_=null}getUserAgent(){return window.navigator.userAgent}getCookie(e){return f_(document.cookie,e)}},H_=null;function U_(){return H_||=document.head.querySelector(`base`),H_?H_.getAttribute(`href`):null}function W_(e){return new URL(e,document.baseURI).pathname}var G_=[`alt`,`control`,`meta`,`shift`],K_={"\b":`Backspace`," ":`Tab`,"":`Delete`,"\x1B":`Escape`,Del:`Delete`,Esc:`Escape`,Left:`ArrowLeft`,Right:`ArrowRight`,Up:`ArrowUp`,Down:`ArrowDown`,Menu:`ContextMenu`,Scroll:`ScrollLock`,Win:`OS`},q_={alt:e=>e.altKey,control:e=>e.ctrlKey,meta:e=>e.metaKey,shift:e=>e.shiftKey},J_=(()=>{class e extends m_{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(()=>c_().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.`),G_.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=K_[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`),G_.forEach(t=>{if(t!==n){let n=q_[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)(I(es))};static ɵprov=Zr({token:e,factory:e.ɵfac})}return e})();async function Y_(e,t,n){return o_({rootComponent:e,...X_(t,n)})}function X_(e,t){return{platformRef:t?.platformRef,appProviders:[...tv,...e?.providers??[]],platformProviders:ev}}function Z_(){V_.makeCurrent()}function Q_(){return new Ts}function $_(){return _l(document),document}var ev=[{provide:Ms,useValue:p_},{provide:js,useValue:Z_,multi:!0},{provide:es,useFactory:$_}],tv=[{provide:oa,useValue:`root`},{provide:Ts,useFactory:Q_},{provide:g_,useClass:h_,multi:!0},{provide:g_,useClass:J_,multi:!0},F_,{provide:$f,useClass:C_},{provide:C_,useExisting:$f},__,{provide:Ff,useExisting:F_},[]];function nv(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 ov({code:i,why:iv(a.why,e),fix:iv(a.fix,e),docs:o,cause:e.cause,sources:e.sources,data:iv(a.data,e)},s);for(let e of t)e(r,n);return r};n[i]=s}return n}function lv(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 hv=Math.random.bind(Math),gv=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`;function _v(e=21){let t=``,n=e;for(;n--;)t+=gv[hv()*64|0];return t}var vv=6e4,yv=e=>e,bv=yv,{clearTimeout:xv,setTimeout:Sv}=globalThis;function Cv(e,t){let{post:n,on:r,off:i=()=>{},eventNames:a=[],serialize:o=yv,deserialize:s=bv,resolver:c,bind:l=`rpc`,timeout:u=vv,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}=mv(),_=_v();s.i=_;let v;async function y(n=s){return u>=0&&(v=Sv(()=>{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{xv(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&&(xv(r.timeoutId),n?r.reject(n):r.resolve(t)),p.delete(e)}}return m=r(b),h}function wv(e,t){return t.safety?t.safety:e===`static`||e===`query`||e==null?`read`:`action`}var Tv=Object.freeze({type:`object`,additionalProperties:!0});function Ev(e){let t=e[`~standard`];if(t.jsonSchema)try{return t.jsonSchema.input({target:`draft-2020-12`})}catch{return Tv}return Tv}function Dv(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 kv(e,t){return Ov(e,t)??[e]}function Av(e){return typeof e==`string`?`'${e}'`:new Pv().serialize(e)}var jv=` _-,;:!?.'"()[]{}@*/\\&#%\`^+<=>|~$0123456789abcdefghijklmnopqrstuvwxyz`,Mv=(function(){let e=new Uint8Array(128);for(let t=0;t<69;t++)e[jv.charCodeAt(t)]=t+1;for(let t=65;t<=90;t++)e[t]=e[t+32];return e})();function Nv(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})(),Fv=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225],Iv=[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],Lv=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_`,Rv=[],zv=class{_data=new Bv;_hash=new Bv([...Fv]);_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)Rv[n]=e[t+n]|0;else{let e=Rv[n-15],t=(e<<25|e>>>7)^(e<<14|e>>>18)^e>>>3,r=Rv[n-2],i=(r<<15|r>>>17)^(r<<13|r>>>19)^r>>>10;Rv[n]=t+Rv[n-7]+i+Rv[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+Iv[n]+Rv[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=Bv.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 Vv(e){return new zv().finalize(e).toBase64()}function Hv(e){return Vv(Av(e))}function Uv(e){return Hv(e)}function Wv(){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 Gv=/^[\w+.-]{2,}:\/\//;function Kv(e){return e.endsWith(`/`)?e:`${e}/`}function qv(e){return(e.endsWith(`/`)?e.slice(0,-1):e)||`/`}function Jv(e,...t){let n=e;for(let e of t)e&&e!==`/`&&(n=n?Kv(n)+e.replace(/^\.?\//,``):e);return n}function Yv(e,t){if(!t||t===`/`||Gv.test(e))return e;let n=qv(t);return e.startsWith(n)?e:Jv(n,e)}function Xv(e,t){let n=e.match(Gv);return t+(n?e.slice(n[0].length):e)}var Zv=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`;function Qv(e=21){let t=``,n=e;for(;n--;)t+=Zv[Math.random()*64|0];return t}var $v=Symbol.for(`immer-nothing`),ey=Symbol.for(`immer-draftable`),ty=Symbol.for(`immer-state`),ny=[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 ry(e,...t){{let n=ny[e],r=Dy(n)?n.apply(null,t):n;throw Error(`[Immer] ${r}`)}}var iy=Object,ay=iy.getPrototypeOf,oy=`constructor`,sy=`prototype`,cy=`configurable`,ly=`enumerable`,uy=`writable`,dy=`value`,fy=e=>!!e&&!!e[ty];function py(e){return e?gy(e)||Cy(e)||!!e[ey]||!!e[oy]?.[ey]||wy(e)||Ty(e):!1}var my=iy[sy][oy].toString(),hy=new WeakMap;function gy(e){if(!e||!Ey(e))return!1;let t=ay(e);if(t===null||t===iy[sy])return!0;let n=iy.hasOwnProperty.call(t,oy)&&t[oy];if(n===Object)return!0;if(!Dy(n))return!1;let r=hy.get(n);return r===void 0&&(r=Function.toString.call(n),hy.set(n,r)),r===my}function _y(e,t,n=!0){vy(e)===0?(n?Reflect.ownKeys(e):iy.keys(e)).forEach(n=>{t(n,e[n],e)}):e.forEach((n,r)=>t(r,n,e))}function vy(e){let t=e[ty];return t?t.type_:Cy(e)?1:wy(e)?2:Ty(e)?3:0}var yy=(e,t,n=vy(e))=>n===2?e.has(t):iy[sy].hasOwnProperty.call(e,t),by=(e,t,n=vy(e))=>n===2?e.get(t):e[t],xy=(e,t,n,r=vy(e))=>{r===2?e.set(t,n):r===3?e.add(n):e[t]=n};function Sy(e,t){return e===t?e!==0||1/e==1/t:e!==e&&t!==t}var Cy=Array.isArray,wy=e=>e instanceof Map,Ty=e=>e instanceof Set,Ey=e=>typeof e==`object`,Dy=e=>typeof e==`function`,Oy=e=>typeof e==`boolean`;function ky(e){let t=+e;return Number.isInteger(t)&&String(t)===e}var Ay=e=>Ey(e)?e?.[ty]:null,jy=e=>e.copy_||e.base_,My=e=>e.modified_?e.copy_:e.base_;function Ny(e,t){if(wy(e))return new Map(e);if(Ty(e))return new Set(e);if(Cy(e))return Array[sy].slice.call(e);let n=gy(e);if(t===!0||t===`class_only`&&!n){let t=iy.getOwnPropertyDescriptors(e);delete t[ty];let n=Reflect.ownKeys(t);for(let r=0;r1&&iy.defineProperties(e,{set:Iy,add:Iy,clear:Iy,delete:Iy}),iy.freeze(e),t&&_y(e,(e,t)=>{Py(t,!0)},!1),e)}function Fy(){ry(2)}var Iy={[dy]:Fy};function Ly(e){return e===null||!Ey(e)||iy.isFrozen(e)}var Ry=`MapSet`,zy=`Patches`,By=`ArrayMethods`,Vy={};function Hy(e){let t=Vy[e];return t||ry(0,e),t}var Uy=e=>!!Vy[e];function Wy(e,t){Vy[e]||(Vy[e]=t)}var Gy,Ky=()=>Gy,qy=(e,t)=>({drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0,handledSet_:new Set,processedForPatches_:new Set,mapSetPlugin_:Uy(Ry)?Hy(Ry):void 0,arrayMethodsPlugin_:Uy(By)?Hy(By):void 0});function Jy(e,t){t&&(e.patchPlugin_=Hy(zy),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function Yy(e){Xy(e),e.drafts_.forEach(Qy),e.drafts_=null}function Xy(e){e===Gy&&(Gy=e.parent_)}var Zy=e=>Gy=qy(Gy,e);function Qy(e){let t=e[ty];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function $y(e,t){t.unfinalizedDrafts_=t.drafts_.length;let n=t.drafts_[0];if(e!==void 0&&e!==n){n[ty].modified_&&(Yy(t),ry(4)),py(e)&&(e=eb(t,e));let{patchPlugin_:r}=t;r&&r.generateReplacementPatches_(n[ty].base_,e,t)}else e=eb(t,n);return tb(t,e,!0),Yy(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e===$v?void 0:e}function eb(e,t){if(Ly(t))return t;let n=t[ty];if(!n)return lb(t,e.handledSet_,e);if(!rb(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);sb(n,e)}return n.copy_}function tb(e,t,n=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&Py(t,n)}function nb(e){e.finalized_=!0,e.scope_.unfinalizedDrafts_--}var rb=(e,t)=>e.scope_===t,ib=[];function ab(e,t,n,r){let i=jy(e),a=e.type_;if(r!==void 0&&by(i,r,a)===t){xy(i,r,n,a);return}if(!e.draftLocations_){let t=e.draftLocations_=new Map;_y(i,(e,n)=>{if(fy(n)){let r=t.get(n)||[];r.push(e),t.set(n,r)}})}let o=e.draftLocations_.get(t)??ib;for(let e of o)xy(i,e,n,a)}function ob(e,t,n){e.callbacks_.push(function(r){let i=t;if(!i||!rb(i,r))return;r.mapSetPlugin_?.fixSetContents(i);let a=My(i);ab(e,i.draft_??i,a,n),sb(i,r)})}function sb(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)}nb(e)}}function cb(e,t,n){let{scope_:r}=e;if(fy(n)){let i=n[ty];rb(i,r)&&i.callbacks_.push(function(){vb(e),ab(e,n,My(i),t)})}else py(n)&&e.callbacks_.push(function(){let i=jy(e);e.type_===3?i.has(n)&&lb(n,r.handledSet_,r):by(i,t,e.type_)===n&&r.drafts_.length>1&&(e.assigned_.get(t)??!1)===!0&&e.copy_&&lb(by(e.copy_,t,e.type_),r.handledSet_,r)})}function lb(e,t,n){return!n.immer_.autoFreeze_&&n.unfinalizedDrafts_<1||fy(e)||t.has(e)||!py(e)||Ly(e)?e:(t.add(e),_y(e,(r,i)=>{if(fy(i)){let t=i[ty];rb(t,n)&&(xy(e,r,My(t),e.type_),nb(t))}else py(i)&&lb(i,t,n)}),e)}function ub(e,t){let n=Cy(e),r={type_:+!!n,scope_:t?t.scope_:Ky(),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=db;n&&(i=[r],a=fb);let{revoke:o,proxy:s}=Proxy.revocable(i,a);return r.draft_=s,r.revoke_=o,[s,r]}var db={get(e,t){if(t===ty)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=jy(e);if(!yy(i,t,e.type_))return hb(e,i,t);let a=i[t];if(e.finalized_||!py(a)||r&&e.operationMethod&&n?.isMutatingArrayMethod(e.operationMethod)&&ky(t))return a;if(a===pb(e.base_,t)||mb(e,t,a)){vb(e);let n=e.type_===1?+t:t,r=bb(e.scope_,a,e,n);return e.copy_[n]=r}return a},has(e,t){return t in jy(e)},ownKeys(e){return Reflect.ownKeys(jy(e))},set(e,t,n){let r=gb(jy(e),t);if(r?.set)return r.set.call(e.draft_,n),!0;if(!e.modified_){let r=pb(jy(e),t),i=r?.[ty];if(i&&i.base_===n)return e.copy_[t]=n,e.assigned_.set(t,!1),!0;if(Sy(n,r)&&(n!==void 0||yy(e.base_,t,e.type_)))return!0;vb(e),_b(e)}return e.copy_[t]===n&&(n!==void 0||yy(e.copy_,t,e.type_))||Number.isNaN(n)&&Number.isNaN(e.copy_[t])?!0:(e.copy_[t]=n,e.assigned_.set(t,!0),cb(e,t,n),!0)},deleteProperty(e,t){return vb(e),pb(e.base_,t)!==void 0||t in e.base_?(e.assigned_.set(t,!1),_b(e)):e.assigned_.delete(t),e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){let n=jy(e),r=Reflect.getOwnPropertyDescriptor(n,t);return r&&{[uy]:!0,[cy]:e.type_!==1||t!==`length`,[ly]:r[ly],[dy]:n[t]}},defineProperty(){ry(11)},getPrototypeOf(e){return ay(e.base_)},setPrototypeOf(){ry(12)}},fb={};for(let e in db){let t=db[e];fb[e]=function(){let e=arguments;return e[0]=e[0][0],t.apply(this,e)}}fb.deleteProperty=function(e,t){return isNaN(parseInt(t))&&ry(13),fb.set.call(this,e,t,void 0)},fb.set=function(e,t,n){return t!==`length`&&isNaN(parseInt(t))&&ry(14),db.set.call(this,e[0],t,n,e[0])};function pb(e,t){let n=e[ty];return(n?jy(n):e)[t]}function mb(e,t,n){return e.type_!==1||!e.allIndicesReassigned_||e.assigned_?.get(t)||!py(n)||n[ty]?!1:e.baseRefs_.has(n)}function hb(e,t,n){let r=gb(t,n);return r?dy in r?r[dy]:r.get?.call(e.draft_):void 0}function gb(e,t){if(!(t in e))return;let n=ay(e);for(;n;){let e=Object.getOwnPropertyDescriptor(n,t);if(e)return e;n=ay(n)}}function _b(e){e.modified_||(e.modified_=!0,e.parent_&&_b(e.parent_))}function vb(e){e.copy_||=(e.assigned_=new Map,Ny(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var yb=class{constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!1,this.produce=(e,t,n)=>{if(Dy(e)&&!Dy(t)){let n=t;t=e;let r=this;return function(e=n,...i){return r.produce(e,e=>t.call(this,e,...i))}}Dy(t)||ry(6),n!==void 0&&!Dy(n)&&ry(7);let r;if(py(e)){let i=Zy(this),a=bb(i,e,void 0),o=!0;try{r=t(a),o=!1}finally{o?Yy(i):Xy(i)}return Jy(i,n),$y(r,i)}if(!e||!Ey(e)){if(r=t(e),r===void 0&&(r=e),r===$v&&(r=void 0),this.autoFreeze_&&Py(r,!0),n){let t=[],i=[];Hy(zy).generateReplacementPatches_(e,r,{patches_:t,inversePatches_:i}),n(t,i)}return r}ry(1,e)},this.produceWithPatches=(e,t)=>{if(Dy(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]},Oy(e?.autoFreeze)&&this.setAutoFreeze(e.autoFreeze),Oy(e?.useStrictShallowCopy)&&this.setUseStrictShallowCopy(e.useStrictShallowCopy),Oy(e?.useStrictIteration)&&this.setUseStrictIteration(e.useStrictIteration)}createDraft(e){py(e)||ry(8),fy(e)&&(e=xb(e));let t=Zy(this),n=bb(t,e,void 0);return n[ty].isManual_=!0,Xy(t),n}finishDraft(e,t){let n=e&&e[ty];(!n||!n.isManual_)&&ry(9);let{scope_:r}=n;return Jy(r,t),$y(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=Hy(zy).applyPatches_;return fy(e)?r(e,t):this.produce(e,e=>r(e,t))}};function bb(e,t,n,r){let[i,a]=wy(t)?Hy(Ry).proxyMap_(t,n):Ty(t)?Hy(Ry).proxySet_(t,n):ub(t,n);return(n?.scope_??Ky()).drafts_.push(i),a.callbacks_=n?.callbacks_??[],a.key_=r,n&&r!==void 0?ob(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 xb(e){return fy(e)||ry(10,e),Sb(e)}function Sb(e){if(!py(e)||Ly(e))return e;let t=e[ty],n,r=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,n=Ny(e,t.scope_.immer_.useStrictShallowCopy_),r=t.scope_.immer_.shouldUseStrictIteration()}else n=Ny(e,!0);return _y(n,(e,t)=>{xy(n,e,Sb(t))},r),t&&(t.finalized_=!1),n}function Cb(){ny.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=Ay(by(e,n.key_)),i=by(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||yy(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=by(o,e,c),f=by(s,e,c),p=l?yy(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===$v?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(Ty(e))return new Set(Array.from(e).map(u));let t=Object.create(ay(e));for(let n in e)t[n]=u(e[n]);return yy(e,ey)&&(t[ey]=e[ey]),t}function d(e){return fy(e)?u(e):e}Wy(zy,{applyPatches_:l,generatePatches_:i,generateReplacementPatches_:c,getPath:e})}globalThis.Iterator?.from;var wb=new yb,Tb=wb.produce,Eb=wb.produceWithPatches.bind(wb),Db=wb.applyPatches.bind(wb),Ob=1e3;function kb(e,t){if(e.add(t),e.size>Ob){let t=e.values().next().value;t!==void 0&&e.delete(t)}}function Ab(e){let{enablePatches:t=!1}=e;t&&Cb();let n=Wv(),r=e.initialValue,i=new Set;return{on:n.on,value:()=>r,patch:(e,t=Qv())=>{i.has(t)||(Cb(),r=Db(r,e),kb(i,t),n.emit(`updated`,r,void 0,t))},mutate:(e,a=Qv())=>{if(!i.has(a)){if(kb(i,a),t){let[t,i]=Eb(r,e);if(t===r)return;r=t,n.emit(`updated`,r,i,a)}else{let t=Tb(r,e);if(t===r)return;r=t,n.emit(`updated`,r,void 0,a)}}},syncIds:i}}var jb=typeof self==`object`?self:globalThis,Mb=new Set([`Error`,`EvalError`,`RangeError`,`ReferenceError`,`SyntaxError`,`TypeError`,`URIError`,`AggregateError`]),Nb=new Set([`Boolean`,`Number`,`String`,`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float16Array`,`Float32Array`,`Float64Array`,`BigInt64Array`,`BigUint64Array`]);function Pb(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=Mb.has(e)?jb[e]:void 0;return n(new(r??jb.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`&&Nb.has(a))return n(new jb[a](o),i);throw TypeError(`unable to deserialize unsafe or unknown type: ${String(a)}`)};return r}function Fb(e){return Pb(new Map,e)(0)}var Ib=``,{toString:Lb}={},{keys:Rb}=Object;function zb(e){let t=typeof e;if(t!==`object`||!e)return[0,t];let n=Lb.call(e).slice(8,-1);switch(n){case`Array`:return[1,Ib];case`Object`:return[2,Ib];case`Date`:return[3,Ib];case`RegExp`:return[4,Ib];case`Map`:return[5,Ib];case`Set`:return[6,Ib];case`DataView`:return[1,n]}return n.includes(`Array`)?[1,n]:n.includes(`Error`)?[7,n]:[2,n]}function Bb([e,t]){return e===0&&(t===`function`||t===`symbol`)}function Vb(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]=zb(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 Rb(r))(e||!Bb(zb(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||!(Bb(zb(n))||Bb(zb(i))))&&t.push([a(n),a(i)]);return n}case 6:{let t=[],n=i([o,t],r);for(let n of r)(e||!Bb(zb(n)))&&t.push(a(n));return n}}let{message:c}=r;return i([o,{name:s,message:c}],r)};return a}function Hb(e,t={}){let n=[];return Vb(!(t.json||t.lossy),!!t.json,new Map,n)(e),n}var{parse:Ub,stringify:Wb}=JSON,Gb={json:!0,lossy:!0};function Kb(e){return Fb(Ub(e))}function qb(e){return Wb(Hb(e,Gb))}function Jb(e){return Fb(e)}function Yb(e){return qb(e)}function Xb(e){return Kb(e)}var Zb=256,Qb=class extends Error{name=`StreamClosedError`};function $b(e={}){let t=e.id??Qv(),n=Math.max(0,e.replayWindow??0),r=Wv(),i=new AbortController,a=[],o=!1,s=0;function c(e){if(o)throw new Qb(`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=tx(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 ex(e={}){let t=e.id??Qv(),n=Math.max(1,e.highWaterMark??Zb),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 tx(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 nx=128;function rx(e){return e.replace(/[^\w-]+/g,`_`).slice(0,nx)}var ix=`modulepreload`,ax=function(e,t){return new URL(e,t).href},ox={},sx=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=ax(t,n),t=s(t),t in ox)return;ox[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`:ix,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)})},cx=`__connection.json`,lx=`__DEVFRAME_CONNECTION__`,ux=`x-birpc-session`,dx=`__rpc-dump/index.json`,fx=`devframe:services`,px=`devframe_otp`,mx=`devframe_auth_token`;uv.postMessage.remoteAssetsError;var hx=class{cacheMap=new Map;options;keySerializer;constructor(e){this.options=e,this.keySerializer=e.keySerializer||(e=>Uv(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()}},gx=pv({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 _x(e){if(e.agent&&e.jsonSerializable===!1)throw gx.DF0019({name:e.name});e.agent&&!e.jsonSerializable&&(e.jsonSerializable=!0)}async function vx(e,t){let n=e[`~standard`].validate(t);return n instanceof Promise?await n:n}function yx(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 bx(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 Cx(e,t){let n=e.handler;if(!n){let r=await Sx(e,t);if(!r.handler)throw gx.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 bx(e.name,r,t),o=await a(...n);return await xx(e.name,i,o)}}var wx=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 Cx(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 gx.DF0021({name:e.name});_x(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 gx.DF0022({name:e.name});_x(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 Cx(this.definitions.get(e),this.context)}getSchema(e){let t=this.definitions.get(e);if(!t)throw gx.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 Tx(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 Dx(t,`undefined`,r,e);return n}return i!==null&&Ex(i,r,e,t),n})}function Ex(e,t,n,r){if(typeof e==`bigint`)throw Dx(r,`BigInt`,t,n);if(typeof e!=`object`)return;if(e instanceof Map)throw Dx(r,`Map`,t,n);if(e instanceof Set)throw Dx(r,`Set`,t,n);if(e instanceof Date)throw Dx(r,`Date`,t,n);if(Array.isArray(e))return;let i=Object.getPrototypeOf(e);if(i!==null&&i!==Object.prototype)throw Dx(r,e.constructor?.name??`class instance`,t,n)}function Dx(e,t,n,r){let i=Ox(n,r);return gx.DF0020({name:e||``,type:t,path:i})}function Ox(e,t){return Array.isArray(e)?`[${t}]`:t===``?``:t}var kx=`__DEVFRAME_CONNECTION_META__`,Ax=`__DEVFRAME_CONNECTION_AUTH_TOKEN__`;function jx(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 Mx(){return jx(lx)}function Nx(){return jx(kx)}function Px(e){if(e)return e;try{let e=localStorage.getItem(Ax);if(e)return e}catch{}return jx(Ax)}function Fx(e){globalThis[lx]=e,globalThis[kx]={...e.connectionMeta,baseUrl:e.metaBaseUrl},e.authToken&&Ix(e.authToken)}function Ix(e){try{localStorage.setItem(Ax,e)}catch{}globalThis[Ax]=e;let t=Mx();t&&(globalThis[lx]={...t,authToken:e})}function Lx(e){let t=Yv(cx,e);try{return new URL(t,globalThis.location?.href).href}catch{return t}}function Rx(e,t){return t&&t!==e.authToken?{...e,authToken:t}:e}function zx(){let e=Mx();if(e)return Rx(e,Px()??e.authToken??e.connectionMeta.authToken);let t=Nx();if(t)return{connectionMeta:t,metaBaseUrl:t.baseUrl??Lx(`./`),authToken:Px(t.authToken)}}async function Bx(e={}){if(e.connection){let t=Rx(e.connection,Px(e.authToken??e.connection.authToken??e.connection.connectionMeta.authToken));return Fx(t),t}let t=Array.isArray(e.baseURL)?e.baseURL:[e.baseURL??`./`];if(e.connectionMeta){let n={connectionMeta:e.connectionMeta,metaBaseUrl:Lx(t[0]??`./`),authToken:Px(e.authToken??e.connectionMeta.authToken)};return Fx(n),n}let n=zx();if(n){let t=Rx(n,Px(e.authToken??n.authToken??n.connectionMeta.authToken));return Fx(t),t}let r=[];for(let n of t){let t=Yv(cx,n),i=Lx(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:Px(e.authToken??r.authToken)};return Fx(o),o}catch(e){r.push(e)}}throw Error(`Failed to get connection meta from ${t.join(`, `)}`,{cause:r})}var Vx=class extends Error{name=`DevframeConnectionError`;kind;constructor(e,t,n){super(t,n),this.kind=e}};function Hx(e=px){try{let t=globalThis.location?.hash?.replace(/^#/,``)??``;return new URLSearchParams(t).get(e)||void 0}catch{return}}function Ux(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 Wx(e=px){let t=Hx(e);return t&&Ux(e),t}async function Gx(e,t={}){let n=Wx(t.param??`devframe_otp`);return n?e.isTrusted?!0:e.requestTrustWithCode(n):!1}function Kx(e){let t={},n=new WeakMap,r,i=()=>(r??=e.sharedState.get(fx,{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 qx(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:uv.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:uv.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=Ab({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(uv.client.isTrustedUpdated,e=>{e&&!n&&(n=!0,d())})}})}}}var Jx=new Map;function Yx(e=Jx){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?Tx(n,r??``):`s:${Yb(n)}`},deserialize:e=>{let n=e.startsWith(`s:`)?Xb(e.slice(2)):JSON.parse(e);return n.t===`q`&&n.i&&n.m&&t.set(n.i,n.m),n}}}function Xx(){}function Zx(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 Qx(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 $x(e){let{onConnected:t=Xx,onError:n=Xx,onDisconnected:r=Xx,definitions:i,fetch:a=globalThis.fetch.bind(globalThis)}=e,o=e.url;e.authToken&&(o=`${o}${o.includes(`?`)?`&`:`?`}${mx}=${encodeURIComponent(e.authToken)}`);let s=Yx(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=Zx(r);if(!e)break;r=e.rest;let{event:t,data:n}=Qx(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`,[ux]: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 eS(e,t){let{channel:n,rpcOptions:r={}}=t;return Cv(e,{...n,timeout:-1,...r,proxify:!1})}function tS(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(uv.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 Vx(`connection`,`[devframe] Not connected to the devframe server`,{cause:u??void 0}):l===`unauthorized`?new Vx(`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(uv.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 Vx(`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(uv.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(uv.client.connectionError,e),m(new Vx(`connection`,`[devframe] Connection to the devframe server failed`,{cause:e}))},onDisconnected(){l!==`error`&&f(`disconnected`),m(new Vx(`connection`,`[devframe] Disconnected from the devframe server`,{cause:u??void 0}))}}),y=eS(a.functions,{channel:v,rpcOptions:o});a.register({name:uv.broadcast.authRevoked,type:`event`,handler:()=>{c=!1;let e=new Vx(`auth`,`[devframe] The devframe server revoked this client's trust`);f(`unauthorized`,e),i.emit(uv.client.connectionError,e),m(e),i.emit(uv.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 Vx(`auth`,`[devframe] The devframe server refused this client's credentials`);f(`unauthorized`,e),i.emit(uv.client.connectionError,e)}return i.emit(uv.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(uv.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(uv.client.error,n,t),Promise.reject(n)):g(y.$call(...e),t)},callEvent:(...e)=>{let t=h();if(t){i.emit(uv.client.error,t,String(e[0]));return}return y.$callEvent(...e)},callOptional:(...e)=>{let t=String(e[0]),n=h();return n?(i.emit(uv.client.error,n,t),Promise.reject(n)):g(y.$callOptional(...e),t)},close:()=>{v.close()}}}function nS(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 rS(e){let{authToken:t,connectionMeta:n,metaBaseUrl:r,events:i,clientRpc:a,rpcOptions:o={},sseOptions:s={},callTimeout:c=0}=e,l=nS(n.sse,r??`./`,location);return tS({transport:`sse`,authToken:t,connectionMeta:n,events:i,clientRpc:a,rpcOptions:o,callTimeout:c,createChannel:e=>$x({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 iS(e){let{name:t,message:n,cause:r,...i}=e,a=r instanceof Error?r:aS(r)?iS(r):r,o=a===void 0?Error(n):Error(n,{cause:a});return o.name=t,Object.assign(o,i),o}function aS(e){return typeof e==`object`&&!!e&&typeof e.message==`string`&&typeof e.name==`string`}function oS(e){return typeof e==`object`&&!!e&&e.type===`static`&&typeof e.path==`string`}function sS(e){return typeof e==`object`&&!!e&&e.type===`query`&&typeof e.records==`object`&&e.records!==null}function cS(e){return typeof e==`object`&&!!e&&(`output`in e||`error`in e)}function lS(e){if(e.error)throw iS(e.error);return e.output}function uS(e){return e.some(e=>e!=null)}function dS(e){return typeof e==`object`&&e&&`serialization`in e&&`data`in e?e.data:e}function fS(e,t){let n=new Map,r=new Map;function i(e,t){return t===`structured-clone`&&Array.isArray(e)?Jb(e):e}function a(e,t){return i(dS(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 cS(r)?lS(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(oS(r)){if(uS(n))throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`);return await o(r)}if(sS(r)){let e=Uv(n),i=r.records[e];if(i)return lS(await s(i,r.serialization));if(r.fallback)return lS(await s(r.fallback,r.serialization));throw Error(`[devframe-rpc] No dump match for "${t}" with args: ${JSON.stringify(n)}`)}if(!uS(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 pS(e){let t=fS(await e.fetchJsonFromBases(dx),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 mS=``;function hS(e,t){return`${e}${mS}${t}`}function gS(e){let t=new Map,n=new Map;e.client.register({name:uv.broadcast.streamingChunk,type:`event`,handler(e,n,r,i){t.get(hS(e,n))?._push(r,i)}}),e.client.register({name:uv.broadcast.streamingEnd,type:`event`,handler(e,n,r){let i=hS(e,n),a=t.get(i);a&&(a._end(r),t.delete(i))}}),e.client.register({name:uv.broadcast.streamingUploadCancel,type:`event`,handler(e,t){let r=hS(e,t),i=n.get(r);i&&(i.abort(`server cancelled upload`),n.delete(r))}}),e.events.on(uv.client.isTrustedUpdated,n=>{if(n)for(let[n,r]of t){if(r.cancelled||r.done)continue;let t=n.indexOf(mS);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=hS(n,r),o=t.get(a);if(o)return o;let s=ex({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(uv.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=hS(t,r),a=n.get(i);if(a)return a;let o=$b({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 _S(){}var vS=new Map;function yS(e){let t=e.url;e.authToken&&(t=`${t}?${mx}=${encodeURIComponent(e.authToken)}`);let n=new WebSocket(t),{onConnected:r=_S,onError:i=_S,onDisconnected:a=_S,definitions:o=vS}=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=Yx(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 bS(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 Xv(a,/^https/i.test(a)?`wss://`:`ws://`);let o=new URL(a,r);return o.protocol=i,o.href}function xS(e){let{authToken:t,connectionMeta:n,metaBaseUrl:r,events:i,clientRpc:a,rpcOptions:o={},wsOptions:s={},callTimeout:c=0}=e,l=bS(n.websocket,r??`./`,location);return tS({transport:`websocket`,authToken:t,connectionMeta:n,events:i,clientRpc:a,rpcOptions:o,callTimeout:c,createChannel:e=>yS({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 SS(e){return e.includes(`:`)}function CS(e,t){return SS(t)?t:`${e}:${t}`}function wS(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 TS(e,t,n){let r=`devframe:settings:${n}:${t}`,i;function a(){return i||=e.sharedState.get(r,{initialValue:{}}),i}return wS(a)}function ES(e,t){return{global:TS(e,t,`global`),project:TS(e,t,`project`)}}function DS(e,t){return{namespace:t,base:e,rpc:{namespace:t,register(n){if(SS(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(CS(t,n),...r)),callEvent:((n,...r)=>e.callEvent(CS(t,n),...r)),callOptional:((n,...r)=>e.callOptional(CS(t,n),...r)),sharedState:((n,r)=>e.sharedState.get(CS(t,n),r)),streaming:{subscribe:(n,r,i)=>e.streaming.subscribe(CS(t,n),r,i),upload:(n,r)=>e.streaming.upload(CS(t,n),r)}},settings:ES(e,t),scope:e.scope}}function OS(){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 kS(e,t={}){let n=t.modelContext??OS();if(!n)return()=>{};let r=n,i=new Map,a=new Map;function o(t,n){let o=rx(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=wv(t.type,n),u=r.registerTool({name:o,description:n.description,inputSchema:Dv(t.args),annotations:{title:n.title??t.name,readOnlyHint:l===`read`,destructiveHint:l===`destructive`},execute:n=>AS(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 AS(e,t,n){try{let r=kv(n,e.args?.length);return{content:[{type:`text`,text:jS(await(await Cx(e,t))(...r))}]}}catch(e){return{isError:!0,content:[{type:`text`,text:MS(e)}]}}}function jS(e){return e===void 0?`undefined`:typeof e==`string`?e:JSON.stringify(e,null,2)}function MS(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 NS(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 PS(e={}){let{baseURL:t=`./`,rpcOptions:n={},cacheOptions:r=!1}=e,i=Wv(),a=Array.isArray(t)?t:[t],o=await Bx(e),{connectionMeta:s,metaBaseUrl:c,authToken:l}=o,u=a[0]??`./`;try{u=new URL(`.`,c).href}catch{}let d=new hx({functions:[],...typeof e.cacheOptions==`object`?e.cacheOptions:{}}),f={rpc:void 0},p=new wx(f),m=e.webmcp===!1?void 0:kS(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(Yv(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=NS(e.transport??`auto`,s),b=y===`static`?await pS({fetchJsonFromBases:_}):y===`sse`?rS({...v,sseOptions:e.sseOptions}):xS({...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=>(Ix(e),o={...o,authToken:e},b.requestTrustWithToken(e)),requestTrustWithCode:async e=>{let t=await b.requestTrustWithCode(e);if(!t)return!1;Ix(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=qx(C),C.streaming=gS(C),C.services=Kx(C);let re=new Map;C.scope=(e=>{if(!e)return C;let t=re.get(e);return t||(t=DS(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 Gx(C,{param:n}):!1;t||r||C.isTrusted||await ie()}return te=T().then(()=>{ne=!0},()=>{ne=!0}),s.mcp&&sx(async()=>{let{setupBrowserAgentRpcBridge:e}=await import(`./browser-agent-rpc-BXhoSh1z-Drr9EpwB.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 FS=PS,IS=class e{rpc=Yg(null);navigate=Kg();meta=B(null);componentCount=B(0);routeCount=B(0);signalCount=B(0);providerCount=B(0);storeCount=B(0);constructor(){Hs(()=>{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=Up({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&&(J(0,`div`,0)(1,`div`,1)(2,`h2`),Z(3,`Project`),Y(),J(4,`dl`)(5,`dt`),Z(6,`Name`),Y(),J(7,`dd`),Z(8),Y(),J(9,`dt`),Z(10,`Angular`),Y(),J(11,`dd`),Z(12),Y(),J(13,`dt`),Z(14,`TypeScript`),Y(),J(15,`dd`),Z(16),Y(),J(17,`dt`),Z(18,`SSR`),Y(),J(19,`dd`),Z(20),Y()()(),J(21,`div`,2),qh(`click`,function(){return t.navigate.emit(`components`)}),J(22,`h2`),Z(23,`Components`),Y(),J(24,`p`,3),Z(25),Y(),J(26,`p`,4),Z(27,`discovered in source`),Y()(),J(28,`div`,2),qh(`click`,function(){return t.navigate.emit(`routes`)}),J(29,`h2`),Z(30,`Routes`),Y(),J(31,`p`,3),Z(32),Y(),J(33,`p`,4),Z(34,`registered paths`),Y()(),J(35,`div`,2),qh(`click`,function(){return t.navigate.emit(`signals`)}),J(36,`h2`),Z(37,`Signals`),Y(),J(38,`p`,3),Z(39),Y(),J(40,`p`,4),Z(41,`reactive primitives`),Y()(),J(42,`div`,2),qh(`click`,function(){return t.navigate.emit(`injectors`)}),J(43,`h2`),Z(44,`Injectors`),Y(),J(45,`p`,3),Z(46),Y(),J(47,`p`,4),Z(48,`DI providers`),Y()(),J(49,`div`,2),qh(`click`,function(){return t.navigate.emit(`store`)}),J(50,`h2`),Z(51,`NgRx Store`),Y(),J(52,`p`,3),Z(53),Y(),J(54,`p`,4),Z(55,`store entries`),Y()()()),e&2&&(U(8),Q(t.meta()?.projectName??`…`),U(4),Q(t.meta()?.angularVersion??`…`),U(4),Q(t.meta()?.typescript??`…`),U(4),Q(t.meta()?.ssr?`Yes`:`No`),U(5),Q(t.componentCount()),U(7),Q(t.routeCount()),U(7),Q(t.signalCount()),U(7),Q(t.providerCount()),U(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; - }`]})},LS=(e,t)=>t.selector,RS=(e,t)=>t.token+t.line;function zS(e,t){e&1&&(J(0,`p`,3),Z(1,`Scanning components…`),Y())}function BS(e,t){e&1&&(J(0,`p`,3),Z(1,`No components found.`),Y())}function VS(e,t){if(e&1&&(J(0,`li`,13),Z(1),Y()),e&2){let e=t.$implicit;U(),Q(e)}}function HS(e,t){if(e&1&&(J(0,`h4`),Z(1,`Inputs`),Y(),J(2,`ul`,12),K(3,VS,2,1,`li`,13,bh),Y()),e&2){let e=X(2).$implicit;U(3),q(e.inputs)}}function US(e,t){if(e&1&&(J(0,`li`,14),Z(1),Y()),e&2){let e=t.$implicit;U(),Q(e)}}function WS(e,t){if(e&1&&(J(0,`h4`),Z(1,`Outputs`),Y(),J(2,`ul`,12),K(3,US,2,1,`li`,14,bh),Y()),e&2){let e=X(2).$implicit;U(3),q(e.outputs)}}function GS(e,t){if(e&1&&(J(0,`span`,19),Z(1),Y()),e&2){let e=X().$implicit;U(),$(`→ `,e.source)}}function KS(e,t){if(e&1&&(J(0,`li`,16)(1,`span`,17),Z(2),Y(),J(3,`span`,18),Z(4),Y(),W(5,GS,2,1,`span`,19),Y()),e&2){let e=t.$implicit;U(2),Q(e.token),U(2),Q(e.type),U(),G(e.source&&e.source!==`class`&&e.source!==`providers array`?5:-1)}}function qS(e,t){if(e&1&&(J(0,`h4`),Z(1,`Injected Providers`),Y(),J(2,`ul`,15),K(3,KS,6,3,`li`,16,RS),Y()),e&2){let e=X(4);U(3),q(e.selectedProviders())}}function JS(e,t){e&1&&(J(0,`p`,11),Z(1,`No injected providers detected.`),Y())}function YS(e,t){if(e&1&&(J(0,`div`,10)(1,`dl`)(2,`dt`),Z(3,`File`),Y(),J(4,`dd`),Z(5),Y(),J(6,`dt`),Z(7,`Standalone`),Y(),J(8,`dd`),Z(9),Y()(),W(10,HS,5,0),W(11,WS,5,0),W(12,qS,5,0)(13,JS,2,0,`p`,11),Y()),e&2){let e=X().$implicit,t=X(2);U(5),Q(e.file),U(4),Q(e.isStandalone?`Yes`:`No`),U(),G(e.inputs.length?10:-1),U(),G(e.outputs.length?11:-1),U(),G(t.selectedProviders().length?12:13)}}function XS(e,t){if(e&1){let e=Hh();J(0,`li`,6)(1,`button`,7),qh(`click`,function(){let t=uo(e).$implicit;return fo(X(2).select(t))}),J(2,`div`,8),Z(3),Y(),J(4,`div`,9),Z(5),Y()(),W(6,YS,14,5,`div`,10),Y()}if(e&2){let e=t.$implicit,n=X(2);lg(`expanded`,n.isSelected(e)),U(),lh(`aria-expanded`,n.isSelected(e)),U(2),$(`<`,e.selector,`>`),U(2),Q(e.file),U(),G(n.isSelected(e)?6:-1)}}function ZS(e,t){if(e&1&&(J(0,`ul`,4),K(1,XS,7,6,`li`,5,LS),Y()),e&2){let e=X();U(),q(e.filtered())}}var QS=class e{rpc=Yg(null);components=B([]);allProviders=B([]);filter=B(``);loading=B(!1);selected=B(null);selectedProviders=B([]);filtered=B([]);constructor(){Hs(()=>{let e=this.filter().toLowerCase(),t=this.components();this.filtered.set(e?t.filter(t=>t.selector.includes(e)||t.file.includes(e)):t)}),Hs(()=>{this.rpc()&&this.refresh()})}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=Up({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,`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&&(J(0,`div`,0)(1,`input`,1),qh(`input`,function(e){return t.filter.set(e.target.value)}),Y(),J(2,`button`,2),qh(`click`,function(){return t.refresh()}),Z(3,`Refresh`),Y()(),W(4,zS,2,0,`p`,3)(5,BS,2,0,`p`,3)(6,ZS,3,0,`ul`,4)),e&2&&(U(),Uh(`value`,t.filter()),U(3),G(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; - } - .provider-source[_ngcontent-%COMP%] { - font-size: 12px; - color: #71717a; - } - .no-providers[_ngcontent-%COMP%] { - font-size: 13px; - color: #52525b; - }`]})};function $S(e,t){e&1&&(J(0,`p`,3),Z(1,`Scanning routes…`),Y())}function eC(e,t){e&1&&(J(0,`p`,3),Z(1,`No routes found.`),Y())}function tC(e,t){if(e&1&&(J(0,`span`,7),Z(1),Y()),e&2){let e=X().$implicit;U(),$(`➜ `,e.redirectTo)}}function nC(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` `,e.component??`—`,` `)}}function rC(e,t){if(e&1&&(J(0,`tr`)(1,`td`,6),Z(2),Y(),J(3,`td`),W(4,tC,2,1,`span`,7)(5,nC,1,1),Y(),J(6,`td`),Z(7),Y(),J(8,`td`,8),Z(9),Y(),J(10,`td`),Z(11),Y()()),e&2){let e=t.$implicit;U(2),$(`/`,e.path),U(2),G(e.redirectTo===void 0?5:4),U(3),Q(e.title??`—`),U(2),Q(e.file),U(2),Q(e.hasChildren?`Yes`:`—`)}}function iC(e,t){if(e&1&&(J(0,`table`,4)(1,`thead`)(2,`tr`)(3,`th`,5),Z(4,`Path`),Y(),J(5,`th`,5),Z(6,`Component / Target`),Y(),J(7,`th`,5),Z(8,`Title`),Y(),J(9,`th`,5),Z(10,`File`),Y(),J(11,`th`,5),Z(12,`Children`),Y()()(),J(13,`tbody`),K(14,rC,12,5,`tr`,null,yh),Y()()),e&2){let e=X();U(14),q(e.filtered())}}var aC=class e{rpc=Yg(null);routes=B([]);filter=B(``);loading=B(!1);filtered=Wg(()=>{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(){Hs(()=>{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=Up({type:e,selectors:[[`app-route-inspector`]],inputs:{rpc:[1,`rpc`]},decls:7,vars:2,consts:[[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&&(J(0,`div`,0)(1,`input`,1),qh(`input`,function(e){return t.onFilterInput(e)}),Y(),J(2,`button`,2),qh(`click`,function(){return t.refresh()}),Z(3,`Refresh`),Y()(),W(4,$S,2,0,`p`,3)(5,eC,2,0,`p`,3)(6,iC,16,0,`table`,4)),e&2&&(U(),Uh(`value`,t.filter()),U(3),G(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; - } - 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: #71717a; - 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: #71717a; - }`]})},oC=(e,t)=>t.name+t.file+t.line,sC=(e,t)=>t.kind,cC=(e,t)=>t.id;function lC(e,t){e&1&&(J(0,`div`,3)(1,`p`,4),Z(2,`No signals found.`),Y(),J(3,`p`,5),Z(4,` No signal(), computed(), effect() calls found in source. Runtime graph requires Angular 19+ with the overlay connected. `),Y()())}function uC(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · in <`,e.component,`> `)}}function dC(e,t){if(e&1&&(J(0,`div`,8)(1,`div`,9)(2,`span`,10),Z(3),Y(),J(4,`span`,11),Z(5),Y()(),J(6,`div`,12),Z(7),W(8,uC,1,1),Y()()),e&2){let e=t.$implicit,n=X(2);U(2),cg(`background`,n.kindColor(e.kind)),U(),Q(e.kind),U(2),Q(e.name),U(2),Og(` `,e.file,`:`,e.line,` `),U(),G(e.component?8:-1)}}function fC(e,t){if(e&1&&(J(0,`p`,6),Z(1,`Signals from source scan (static analysis):`),Y(),J(2,`div`,7),K(3,dC,9,7,`div`,8,oC),Y()),e&2){let e=X();U(3),q(e.filteredSourceSignals())}}function pC(e,t){if(e&1&&(J(0,`span`,14),Fh(1,`span`,17),Z(2),Y()),e&2){let e=t.$implicit;U(),cg(`background`,e.color),U(),$(` `,e.kind,` `)}}function mC(e,t){e&1&&(J(0,`span`,19),Z(1,`watching`),Y())}function hC(e,t){if(e&1&&(J(0,`div`,20),Z(1),Pg(2,`json`),Y()),e&2){let e=X().$implicit;U(),Q(Ig(2,1,e.value))}}function gC(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · Deps: `,X(2).getDependencies(e).length,` `)}}function _C(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · Consumers: `,X(2).getConsumers(e).length,` `)}}function vC(e,t){if(e&1){let e=Hh();J(0,`div`,18),qh(`click`,function(){let t=uo(e).$implicit;return fo(X(2).selectNode(t))}),J(1,`div`,9)(2,`span`,10),Z(3),Y(),J(4,`span`,11),Z(5),Y(),W(6,mC,2,0,`span`,19),Y(),W(7,hC,3,3,`div`,20),J(8,`div`,12),Z(9),W(10,gC,1,1),W(11,_C,1,1),Y()()}if(e&2){let e=t.$implicit,n=X(2);lg(`selected`,n.selectedNode()?.id===e.id),U(2),cg(`background`,n.kindColor(e.kind)),U(),Q(e.kind),U(2),Q(e.label??`(unnamed)`),U(),G(e.watched?6:-1),U(),G(e.value===void 0?-1:7),U(2),$(` Epoch: `,e.epoch,` `),U(),G(n.getDependencies(e).length?10:-1),U(),G(n.getConsumers(e).length?11:-1)}}function yC(e,t){if(e&1&&(J(0,`dt`),Z(1,`Value`),Y(),J(2,`dd`)(3,`pre`),Z(4),Pg(5,`json`),Y()()),e&2){let e=X(3);U(4),Q(Ig(5,1,e.selectedNode().value))}}function bC(e,t){if(e&1&&(J(0,`li`)(1,`span`,21),Z(2),Y(),Z(3),Y()),e&2){let e=t.$implicit,n=X(4);U(),cg(`background`,n.kindColor(e.kind)),U(),Q(e.kind),U(),$(` `,e.label??e.id,` `)}}function xC(e,t){if(e&1&&(J(0,`h4`),Z(1,`Dependencies (producers)`),Y(),J(2,`ul`),K(3,bC,4,4,`li`,null,cC),Y()),e&2){let e=X(3);U(3),q(e.getDependencies(e.selectedNode()))}}function SC(e,t){if(e&1&&(J(0,`li`)(1,`span`,21),Z(2),Y(),Z(3),Y()),e&2){let e=t.$implicit,n=X(4);U(),cg(`background`,n.kindColor(e.kind)),U(),Q(e.kind),U(),$(` `,e.label??e.id,` `)}}function CC(e,t){if(e&1&&(J(0,`h4`),Z(1,`Consumers`),Y(),J(2,`ul`),K(3,SC,4,4,`li`,null,cC),Y()),e&2){let e=X(3);U(3),q(e.getConsumers(e.selectedNode()))}}function wC(e,t){if(e&1&&(J(0,`aside`,16)(1,`h3`),Z(2),Y(),J(3,`dl`)(4,`dt`),Z(5,`Kind`),Y(),J(6,`dd`),Z(7),Y(),J(8,`dt`),Z(9,`Epoch`),Y(),J(10,`dd`),Z(11),Y(),W(12,yC,6,3),Y(),W(13,xC,5,0),W(14,CC,5,0),Y()),e&2){let e=X(2);U(2),Q(e.selectedNode().label??e.selectedNode().id),U(5),Q(e.selectedNode().kind),U(4),Q(e.selectedNode().epoch),U(),G(e.selectedNode().value===void 0?-1:12),U(),G(e.getDependencies(e.selectedNode()).length?13:-1),U(),G(e.getConsumers(e.selectedNode()).length?14:-1)}}function TC(e,t){if(e&1&&(J(0,`div`,13),K(1,pC,3,3,`span`,14,sC),Y(),J(3,`div`,7),K(4,vC,12,11,`div`,15,cC),Y(),W(6,wC,15,6,`aside`,16)),e&2){let e=X();U(),q(e.kindLegend),U(3),q(e.filteredNodes()),U(2),G(e.selectedNode()?6:-1)}}var EC={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`},DC=class e{rpc=Yg(null);graph=B(null);sourceSignals=B([]);filter=B(``);selectedNode=B(null);kindLegend=Object.entries(EC).map(([e,t])=>({kind:e,color:t}));filteredNodes=Wg(()=>{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});filteredSourceSignals=Wg(()=>{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(){Hs(()=>{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=t.value();n?.graph&&this.graph.set(n.graph),t.on(`updated`,e=>{e?.graph&&this.graph.set(e.graph)})}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.selectedNode.set(this.selectedNode()?.id===e.id?null:e)}kindColor(e){return EC[e]??EC.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=Up({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`],[1,`node-card`,3,`selected`],[1,`detail-panel`],[1,`dot`],[1,`node-card`,3,`click`],[1,`watched-badge`],[1,`node-value`],[1,`kind-badge`,`sm`]],template:function(e,t){e&1&&(J(0,`div`,0)(1,`input`,1),qh(`input`,function(e){return t.filter.set(e.target.value)}),Y(),J(2,`span`,2),Z(3),Y()(),W(4,lC,5,0,`div`,3),W(5,fC,5,0),W(6,TC,7,1)),e&2&&(U(),Uh(`value`,t.filter()),U(2),$(`Component: `,t.graph()?.componentSelector??`—`),U(),G(!t.graph()&&t.sourceSignals().length===0?4:-1),U(),G(!t.graph()&&t.sourceSignals().length>0?5:-1),U(),G(t.graph()?6:-1))},dependencies:[d_],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; - } - .node-card[_ngcontent-%COMP%] { - 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.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; - }`]})},OC=(e,t)=>t.type,kC=(e,t)=>t.token+t.file+t.line,AC=(e,t)=>t.injector.id,jC=(e,t)=>t.node.injector.id,MC=(e,t)=>t.token;function NC(e,t){e&1&&(J(0,`div`,4)(1,`p`,5),Z(2,`No DI data found.`),Y(),J(3,`p`,6),Z(4,` No providers, injectables, or inject() calls found. Runtime tree requires Angular 17+ with the overlay connected. `),Y()())}function PC(e,t){if(e&1&&(J(0,`span`,14),Z(1),Y()),e&2){let e=X().$implicit;U(),$(`providedIn: `,e.providedIn)}}function FC(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · as `,e.source,` `)}}function IC(e,t){if(e&1&&(J(0,`div`,11)(1,`div`,12)(2,`span`,13),Z(3),Y(),W(4,PC,2,1,`span`,14),Y(),J(5,`div`,15),Z(6),W(7,FC,1,1),Y()()),e&2){let e=t.$implicit;U(3),Q(e.token),U(),G(e.providedIn?4:-1),U(2),Og(` `,e.file,`:`,e.line,` `),U(),G(e.source!==`class`&&e.source!==`providers array`?7:-1)}}function LC(e,t){if(e&1&&(J(0,`div`,9)(1,`h3`),Z(2),Y(),J(3,`div`,10),K(4,IC,8,5,`div`,11,kC),Y()()),e&2){let e=t.$implicit;U(2),Og(``,e.label,` (`,e.items.length,`)`),U(2),q(e.items)}}function RC(e,t){if(e&1&&(J(0,`p`,7),Z(1,`DI from source scan (static analysis):`),Y(),J(2,`div`,8),K(3,LC,6,2,`div`,9,OC),Y()),e&2){let e=X();U(3),q(e.groupedProviders())}}function zC(e,t){e&1&&Bh(0)}function BC(e,t){if(e&1&&(J(0,`span`,24),Z(1),Y()),e&2){let e=X().$implicit;U(),$(``,e.node.injector.providerCount,` providers`)}}function VC(e,t){if(e&1){let e=Hh();J(0,`div`,21),qh(`click`,function(){let t=uo(e).$implicit;return fo(X(4).select(t.node))}),J(1,`span`,22),Z(2),Y(),J(3,`span`,23),Z(4),Y(),W(5,BC,2,1,`span`,24),Y()}if(e&2){let e=t.$implicit,n=X(4);cg(`padding-left`,e.depth*24+12,`px`),lg(`selected`,n.selectedId()===e.node.injector.id),U(),cg(`background`,n.typeColor(e.node.injector.type)),U(),$(` `,e.node.injector.type,` `),U(2),Q(e.node.injector.name),U(),G(e.node.injector.providerCount>0?5:-1)}}function HC(e,t){if(e&1&&(J(0,`div`,19),K(1,VC,6,9,`div`,20,jC),Y()),e&2){let e=X().$implicit,t=X(2);U(),q(t.flattenTree(e))}}function UC(e,t){e&1&&(nm(0,zC,1,0,`ng-container`,18)(1,HC,3,0),sh(2,1),ch()),e&2&&Uh(`ngTemplateOutlet`,void 0)}function WC(e,t){e&1&&(J(0,`p`,5),Z(1,`No providers configured on this injector.`),Y())}function GC(e,t){if(e&1&&(J(0,`tr`)(1,`td`,13),Z(2),Y(),J(3,`td`),Z(4),Y(),J(5,`td`),Z(6),Y()()),e&2){let e=t.$implicit;U(2),Q(e.token),U(2),Q(e.type),U(2),Q(e.isViewProvider?`Yes`:`—`)}}function KC(e,t){if(e&1&&(J(0,`table`,26)(1,`thead`)(2,`tr`)(3,`th`),Z(4,`Token`),Y(),J(5,`th`),Z(6,`Type`),Y(),J(7,`th`),Z(8,`View`),Y()()(),J(9,`tbody`),K(10,GC,7,3,`tr`,null,MC),Y()()),e&2){let e=X(3);U(10),q(e.selectedInjector().providers)}}function qC(e,t){if(e&1&&(J(0,`aside`,17)(1,`div`,25)(2,`span`,22),Z(3),Y(),J(4,`h3`),Z(5),Y()(),W(6,WC,2,0,`p`,5)(7,KC,12,0,`table`,26),Y()),e&2){let e=X(2);U(2),cg(`background`,e.typeColor(e.selectedInjector().injector.type)),U(),$(` `,e.selectedInjector().injector.type,` `),U(2),Q(e.selectedInjector().injector.name),U(),G(e.selectedInjector().providers.length===0?6:7)}}function JC(e,t){if(e&1&&(J(0,`div`,16),K(1,UC,4,1,null,null,AC),Y(),W(3,qC,8,5,`aside`,17)),e&2){let e=X();U(),q(e.filteredRoots()),U(2),G(e.selectedInjector()?3:-1)}}var YC={element:`#60a5fa`,environment:`#34d399`,null:`#71717a`},XC=class e{rpc=Yg(null);roots=B([]);sourceProviders=B([]);filter=B(``);hideEmpty=B(!1);selectedId=B(null);selectedInjector=Wg(()=>{let e=this.selectedId();return e?this.findNode(this.roots(),e):null});filteredRoots=Wg(()=>{let e=this.roots();this.hideEmpty()&&(e=this.filterEmpty(e));let t=this.filter().toLowerCase();return t&&(e=this.filterByQuery(e,t)),e});groupedProviders=Wg(()=>{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(){Hs(()=>{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 YC[e]??YC.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=Up({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&&(J(0,`div`,0)(1,`input`,1),qh(`input`,function(e){return t.filter.set(e.target.value)}),Y(),J(2,`label`,2)(3,`input`,3),qh(`change`,function(){return t.hideEmpty.set(!t.hideEmpty())}),Y(),Z(4,` Hide empty injectors `),Y()(),W(5,NC,5,0,`div`,4),W(6,RC,5,0),W(7,JC,4,1)),e&2&&(U(),Uh(`value`,t.filter()),U(2),Uh(`checked`,t.hideEmpty()),U(2),G(t.roots().length===0&&t.sourceProviders().length===0?5:-1),U(),G(t.roots().length===0&&t.sourceProviders().length>0?6:-1),U(),G(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; - }`]})},ZC=(e,t)=>t.kind,QC=(e,t)=>t.name+t.file+t.line;function $C(e,t){e&1&&Fh(0,`span`,4)}function ew(e,t){e&1&&(J(0,`div`,5)(1,`p`,6),Z(2,`No NgRx store patterns found.`),Y(),J(3,`p`,7),Z(4,` No createAction, createReducer, createEffect, createSelector, or createFeature calls found in source. Make sure your app uses @ngrx/store. `),Y()())}function tw(e,t){if(e&1&&(J(0,`span`,9),Fh(1,`span`,14),Z(2),Y()),e&2){let e=t.$implicit;U(),cg(`background`,e.color),U(),$(` `,e.kind,` `)}}function nw(e,t){if(e&1&&(J(0,`span`,15),Z(1),Y()),e&2){let e=t.$implicit;cg(`border-color`,X(3).kindColor(e.kind)),U(),kg(` `,e.count,` `,e.kind,``,e.count===1?``:`s`,` `)}}function rw(e,t){if(e&1&&Z(0),e&2){let e=X().$implicit;$(` · `,e.detail,` `)}}function iw(e,t){if(e&1&&(J(0,`div`,13)(1,`div`,16)(2,`span`,17),Z(3),Y(),J(4,`span`,18),Z(5),Y()(),J(6,`div`,19),Z(7),W(8,rw,1,1),Y()()),e&2){let e=t.$implicit,n=X(3);U(2),cg(`background`,n.kindColor(e.kind)),U(),$(` `,e.kind,` `),U(2),Q(e.name),U(2),Og(` `,e.file,`:`,e.line,` `),U(),G(e.detail?8:-1)}}function aw(e,t){if(e&1&&(J(0,`div`,8),K(1,tw,3,3,`span`,9,ZC),Y(),J(3,`div`,10),K(4,nw,2,5,`span`,11,ZC),Y(),J(6,`div`,12),K(7,iw,9,7,`div`,13,QC),Y()),e&2){let e=X(2);U(),q(e.kindLegend),U(3),q(e.groupedEntries()),U(3),q(e.filteredEntries())}}function ow(e,t){e&1&&W(0,ew,5,0,`div`,5)(1,aw,9,0),e&2&&G(X().sourceEntries().length===0?0:1)}function sw(e,t){e&1&&(J(0,`div`,5)(1,`p`,6),Z(2,`No NgRx store connection detected.`),Y(),J(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. `),Y()())}function cw(e,t){if(e&1){let e=Hh();J(0,`div`,28),qh(`click`,function(){let t=uo(e).$implicit;return fo(X(3).selectedAction.set(t))}),J(1,`div`,29),Z(2),Y(),J(3,`div`,30),Z(4),Y()()}if(e&2){let e=t.$implicit,n=X(3);lg(`selected`,n.selectedAction()===e),U(2),Q(e.type),U(2),Q(n.formatTime(e.timestamp))}}function lw(e,t){e&1&&(J(0,`p`,6),Z(1,`No actions dispatched yet.`),Y())}function uw(e,t){if(e&1&&(J(0,`dt`),Z(1,`Payload`),Y(),J(2,`dd`)(3,`pre`),Z(4),Pg(5,`json`),Y()()),e&2){let e=X(4);U(4),Q(Ig(5,1,e.selectedAction().payload))}}function dw(e,t){if(e&1&&(J(0,`aside`,27)(1,`h3`),Z(2),Y(),J(3,`dl`)(4,`dt`),Z(5,`Type`),Y(),J(6,`dd`),Z(7),Y(),J(8,`dt`),Z(9,`Time`),Y(),J(10,`dd`),Z(11),Y(),W(12,uw,6,3),Y()()),e&2){let e=X(3);U(2),Q(e.selectedAction().type),U(5),Q(e.selectedAction().type),U(4),Q(e.formatTime(e.selectedAction().timestamp)),U(),G(e.selectedAction().payload===void 0?-1:12)}}function fw(e,t){if(e&1&&(J(0,`div`,20)(1,`section`,21)(2,`h3`),Z(3,`Current State`),Y(),J(4,`pre`,22),Z(5),Pg(6,`json`),Y()(),J(7,`section`,23)(8,`h3`),Z(9,` Recent Actions `),J(10,`span`,24),Z(11),Y()(),J(12,`div`,25),K(13,cw,5,4,`div`,26,yh,!1,lw,2,0,`p`,6),Y()()(),W(16,dw,13,4,`aside`,27)),e&2){let e=X(2);U(5),Q(Ig(6,4,e.runtimeState()?.state)),U(6),Q(e.filteredActions().length),U(2),q(e.filteredActions()),U(3),G(e.selectedAction()?16:-1)}}function pw(e,t){e&1&&W(0,sw,5,0,`div`,5)(1,fw,17,6),e&2&&G(+!!X().runtimeState()?.connected)}var mw={action:`#f59e0b`,reducer:`#a78bfa`,effect:`#fb923c`,selector:`#60a5fa`,feature:`#34d399`,"store-setup":`#94a3b8`,"signal-store":`#e879f9`,"signal-state":`#22d3ee`,"signal-method":`#fb7185`},hw=class e{rpc=Yg(null);filter=B(``);mode=B(`source`);sourceEntries=B([]);runtimeState=B(null);selectedAction=B(null);kindLegend=Object.entries(mw).map(([e,t])=>({kind:e,color:t}));filteredEntries=Wg(()=>{let e=this.filter().toLowerCase();return this.sourceEntries().filter(t=>t.name.toLowerCase().includes(e)||t.kind.toLowerCase().includes(e))});groupedEntries=Wg(()=>{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=Wg(()=>{let e=this.filter().toLowerCase(),t=[...this.runtimeState()?.actions??[]].reverse();return e?t.filter(t=>t.type.toLowerCase().includes(e)):t});constructor(){Hs(()=>{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 mw[e]??`#71717a`}formatTime(e){return new Date(e).toLocaleTimeString()}static ɵfac=function(t){return new(t||e)};static ɵcmp=Up({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&&(J(0,`div`,0)(1,`input`,1),qh(`input`,function(e){return t.filter.set(e.target.value)}),Y(),J(2,`div`,2)(3,`button`,3),qh(`click`,function(){return t.mode.set(`source`)}),Z(4,`Source`),Y(),J(5,`button`,3),qh(`click`,function(){return t.mode.set(`runtime`)}),Z(6,` Runtime `),W(7,$C,1,0,`span`,4),Y()()(),W(8,ow,2,1),W(9,pw,2,1)),e&2&&(U(),Uh(`value`,t.filter()),U(2),lg(`active`,t.mode()===`source`),U(2),lg(`active`,t.mode()===`runtime`),U(2),G(t.runtimeState()?.connected?7:-1),U(),G(t.mode()===`source`?8:-1),U(),G(t.mode()===`runtime`?9:-1))},dependencies:[d_],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; - }`]})},gw=()=>[],_w=(e,t)=>t.id,vw=(e,t)=>t.node.path,yw=(e,t)=>t.formId+`#`+t.seq;function bw(e,t){e&1&&(J(0,`p`,0),Z(1,`Connecting…`),Y())}function xw(e,t){e&1&&(J(0,`p`,0),Z(1,`Could not load forms from the devtools server. Reload to try again.`),Y())}function Sw(e,t){e&1&&(J(0,`p`,0),Z(1,`Loading forms…`),Y())}function Cw(e,t){e&1&&(J(0,`div`,0)(1,`p`),Z(2,`No forms on the page yet.`),Y(),J(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. `),Y()())}function ww(e,t){e&1&&(J(0,`span`,10),Z(1),J(2,`span`,9),Z(3,` errors`),Y()()),e&2&&(U(),Q(t))}function Tw(e,t){if(e&1){let e=Hh();J(0,`li`)(1,`button`,5),qh(`click`,function(){let t=uo(e).$implicit;return fo(X(2).selectForm(t.id))}),Fh(2,`span`,6),J(3,`span`,7),Z(4),Y(),J(5,`span`,8),Z(6),J(7,`span`,9),Z(8),Y()(),W(9,ww,4,1,`span`,10),Y()()}if(e&2){let e,n=t.$implicit,r=X(2);U(),lg(`active`,n.id===r.selected()?.id),lh(`aria-current`,n.id===r.selected()?.id?`true`:null),U(),lh(`data-status`,n.root.status),U(2),Q(n.label),U(2),Og(``,r.kindLabel(n.kind),` · `,n.id,` `),U(2),$(`, `,n.root.status),U(),G((e=r.counts().get(n.id)?.errors)?9:-1,e)}}function Ew(e,t){if(e&1&&(J(0,`span`),Z(1),Y()),e&2){let e=X();U(),Q(e.submitted?`submitted`:`not submitted`)}}function Dw(e,t){e&1&&(J(0,`span`),Z(1,`submitting`),Y())}function Ow(e,t){if(e&1&&(J(0,`div`,2),Z(1,` resets to `),J(2,`code`),Z(3),Pg(4,`json`),Y()()),e&2){let e=X(2).$implicit;U(3),Q(Ig(4,1,e.node.defaultValue))}}function kw(e,t){if(e&1&&(J(0,`code`),Z(1),Pg(2,`json`),Y(),W(3,Ow,5,3,`div`,2)),e&2){let e=X().$implicit;U(),Q(Ig(2,2,e.node.value)),U(2),G(e.node.defaultValue===void 0?-1:3)}}function Aw(e,t){e&1&&(J(0,`span`,2),Z(1,`not created yet`),Y())}function jw(e,t){if(e&1&&(J(0,`span`,12),Z(1),Y()),e&2){let e=X().$implicit;lh(`data-status`,e.node.status),U(),Q(e.node.status)}}function Mw(e,t){e&1&&(J(0,`span`),Z(1,`touched`),Y())}function Nw(e,t){e&1&&(J(0,`span`),Z(1,`dirty`),Y())}function Pw(e,t){e&1&&(J(0,`span`),Z(1,`required`),Y())}function Fw(e,t){e&1&&(J(0,`span`),Z(1,`readonly`),Y())}function Iw(e,t){e&1&&(J(0,`span`),Z(1,`hidden`),Y())}function Lw(e,t){if(e&1&&(J(0,`span`),Z(1),Y()),e&2){let e=X().$implicit;U(),$(`updates on `,e.node.updateOn)}}function Rw(e,t){e&1&&(J(0,`span`),Z(1,`debouncing`),Y())}function zw(e,t){e&1&&(J(0,`span`),Z(1,`validators`),Y())}function Bw(e,t){e&1&&(J(0,`span`),Z(1,`async validator`),Y())}function Vw(e,t){if(e&1&&(J(0,`span`),Z(1),Y()),e&2){let e=t.$implicit;U(),Q(e)}}function Hw(e,t){if(e&1&&(J(0,`span`),Z(1),Y()),e&2){let e=X().$implicit;U(),Q(e.node.accessor)}}function Uw(e,t){if(e&1&&(J(0,`span`),Z(1),Y()),e&2){let e=t.$implicit;U(),$(`disabled: `,e)}}function Ww(e,t){if(e&1&&(J(0,`div`),Z(1),J(2,`code`,25),Z(3),Y()()),e&2){let e=t.$implicit,n=X().$implicit,r=X(3);U(),$(` `,r.errorText(n.node,e),` `),U(2),Q(e.kind)}}function Gw(e,t){if(e&1&&(J(0,`tr`)(1,`td`,26),Z(2),Y()()),e&2){let e=X().$implicit;U(),cg(`padding-left`,24+e.depth*16,`px`),U(),Og(` `,e.node.truncated,` more fields under `,e.node.path||`the form`,` not shown `)}}function Kw(e,t){if(e&1){let e=Hh();J(0,`tr`,18),qh(`mouseenter`,function(){let t=uo(e).$implicit,n=X();return fo(X(2).highlight(n.id,t.node.path))})(`mouseleave`,function(){return uo(e),fo(X(3).highlight(null,``))}),J(1,`th`,19)(2,`button`,20),qh(`focus`,function(){let t=uo(e).$implicit,n=X();return fo(X(2).highlight(n.id,t.node.path))})(`blur`,function(){return uo(e),fo(X(3).highlight(null,``))}),Z(3),Y(),J(4,`span`,21),Z(5),Y()(),J(6,`td`,22),W(7,kw,4,4),Y(),J(8,`td`),W(9,Aw,2,0,`span`,2)(10,jw,2,2,`span`,12),Y(),J(11,`td`,23),W(12,Mw,2,0,`span`),W(13,Nw,2,0,`span`),W(14,Pw,2,0,`span`),W(15,Fw,2,0,`span`),W(16,Iw,2,0,`span`),W(17,Lw,2,1,`span`),W(18,Rw,2,0,`span`),W(19,zw,2,0,`span`),W(20,Bw,2,0,`span`),K(21,Vw,2,1,`span`,null,bh),W(23,Hw,2,1,`span`),K(24,Uw,2,1,`span`,null,yh),Y(),J(26,`td`,24),K(27,Ww,4,2,`div`,null,yh),Y()(),W(29,Gw,3,4,`tr`)}if(e&2){let e=t.$implicit,n=X(3);lg(`invalid`,e.node.errors.length),U(),cg(`padding-left`,8+e.depth*16,`px`),U(),lh(`aria-label`,`Highlight `+(e.node.path||`the form`)+` on the page`),U(),$(` `,e.node.key||`(form)`,` `),U(2),Q(e.node.type),U(2),G(e.node.type===`control`?7:-1),U(2),G(e.node.materialized===!1?9:10),U(3),G(e.node.touched?12:-1),U(),G(e.node.dirty?13:-1),U(),G(e.node.required?14:-1),U(),G(e.node.readonly?15:-1),U(),G(e.node.hidden?16:-1),U(),G(e.node.updateOn?17:-1),U(),G(e.node.debouncing?18:-1),U(),G(e.node.validators?.sync?19:-1),U(),G(e.node.validators?.async?20:-1),U(),q(n.constraintList(e.node)),U(2),G(e.node.accessor?23:-1),U(),q(e.node.disabledReasons??jg(20,gw)),U(3),q(e.node.errors),U(2),G(e.node.truncated?29:-1)}}function qw(e,t){if(e&1&&(J(0,`tr`)(1,`td`,26),Z(2),Y()()),e&2){let e=X(3);U(2),$(`No field path matches "`,e.filter(),`".`)}}function Jw(e,t){if(e&1&&(J(0,`span`,2),Z(1),Y()),e&2){let e=X().$implicit;U(),Q(e.detail)}}function Yw(e,t){if(e&1&&(J(0,`li`)(1,`time`),Z(2),Y(),J(3,`code`),Z(4),Y(),J(5,`span`,27),Z(6),Y(),W(7,Jw,2,1,`span`,2),Y()),e&2){let e=t.$implicit,n=X(4);U(2),Q(n.time(e.timestamp)),U(2),Q(e.path||`(form)`),U(2),Q(e.type),U(),G(e.detail?7:-1)}}function Xw(e,t){if(e&1&&(J(0,`ol`,17),K(1,Yw,8,4,`li`,null,yw),Y()),e&2){let e=X(3);U(),q(e.selectedEvents())}}function Zw(e,t){e&1&&(J(0,`p`,2),Z(1,`No changes yet. Type into the form to see them here.`),Y())}function Qw(e,t){if(e&1){let e=Hh();J(0,`section`,4)(1,`div`,11)(2,`span`,12),Z(3),Y(),J(4,`span`),Z(5),Y(),J(6,`span`),Z(7),Y(),W(8,Ew,2,1,`span`),W(9,Dw,2,0,`span`),J(10,`span`,2),Z(11),Y()(),J(12,`input`,13),qh(`input`,function(t){return uo(e),fo(X(2).onFilter(t))}),Y(),J(13,`div`,14)(14,`table`,15)(15,`thead`)(16,`tr`)(17,`th`,16),Z(18,`Field`),Y(),J(19,`th`,16),Z(20,`Value`),Y(),J(21,`th`,16),Z(22,`Status`),Y(),J(23,`th`,16),Z(24,`State`),Y(),J(25,`th`,16),Z(26,`Errors`),Y()()(),J(27,`tbody`),K(28,Kw,30,21,null,null,vw,!1,qw,3,1,`tr`),Y()()(),J(31,`h2`),Z(32,`Recent changes`),Y(),W(33,Xw,3,0,`ol`,17)(34,Zw,2,0,`p`,2),Y()}if(e&2){let e=t,n=X(2);lh(`aria-label`,e.label),U(2),lh(`data-status`,e.root.status),U(),Q(e.root.status),U(2),Q(e.root.dirty?`dirty`:`pristine`),U(2),Q(e.root.touched?`touched`:`untouched`),U(),G(e.submitted===void 0?-1:8),U(),G(e.root.submitting?9:-1),U(2),Og(``,n.counts().get(e.id)?.fields,` fields, `,n.counts().get(e.id)?.errors,` errors`),U(),Uh(`value`,n.filter()),U(16),q(n.rows()),U(5),G(n.selectedEvents().length?33:34)}}function $w(e,t){if(e&1&&(J(0,`div`,1)(1,`ul`,3),K(2,Tw,10,9,`li`,null,_w),Y(),W(4,Qw,35,12,`section`,4),Y()),e&2){let e,t=X();U(2),q(t.forms()),U(2),G((e=t.selected())?4:-1,e)}}var eT={signal:`Signal Forms`,reactive:`Reactive`,template:`Template-driven`};function tT(e){return e.errors.length+(e.children??[]).reduce((e,t)=>e+tT(t),0)}function nT(e){return 1+(e.children??[]).reduce((e,t)=>e+nT(t),0)}var rT=class e{rpc=Yg(null);forms=B([]);events=B([]);loading=B(!0);failed=B(!1);selectedId=B(null);filter=B(``);unsubscribe=null;destroyRef=L(ts);counts=Wg(()=>new Map(this.forms().map(e=>[e.id,{fields:nT(e.root),errors:tT(e.root)}])));selected=Wg(()=>{let e=this.forms();return e.find(e=>e.id===this.selectedId())??e[0]??null});rows=Wg(()=>{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=Wg(()=>{let e=this.selected()?.id;return this.events().filter(t=>t.formId===e).slice(-50).reverse()});constructor(){Hs(()=>{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 eT[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=Up({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&&W(0,bw,2,0,`p`,0)(1,xw,2,0,`p`,0)(2,Sw,2,0,`p`,0)(3,Cw,5,0,`div`,0)(4,$w,5,1,`div`,1),e&2&&G(t.rpc()?t.failed()?1:t.loading()?2:t.forms().length?4:3:0)},dependencies:[d_],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; - }`]})},iT=(e,t)=>t.id;function aT(e,t){if(e&1){let e=Hh();jh(0,`button`,13),Kh(`click`,function(){let t=uo(e).$implicit;return fo(X().switchTab(t.id))}),Z(1),Nh()}if(e&2){let e=t.$implicit;lg(`active`,X().tab()===e.id),U(),Q(e.label)}}function oT(e,t){if(e&1){let e=Hh();jh(0,`app-dashboard`,14),Kh(`navigate`,function(t){return uo(e),fo(X().switchTab(t))}),Nh()}e&2&&kh(`rpc`,X().rpc())}function sT(e,t){e&1&&Ph(0,`app-component-tree`,12),e&2&&kh(`rpc`,X().rpc())}function cT(e,t){e&1&&Ph(0,`app-route-inspector`,12),e&2&&kh(`rpc`,X().rpc())}function lT(e,t){e&1&&Ph(0,`app-signal-inspector`,12),e&2&&kh(`rpc`,X().rpc())}function uT(e,t){e&1&&Ph(0,`app-di-inspector`,12),e&2&&kh(`rpc`,X().rpc())}function dT(e,t){e&1&&Ph(0,`app-store-inspector`,12),e&2&&kh(`rpc`,X().rpc())}function fT(e,t){e&1&&Ph(0,`app-forms-inspector`,12),e&2&&kh(`rpc`,X().rpc())}var pT=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=B(`dashboard`);rpc=B(null);connected=B(!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=hT();FS(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=Up({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&&(jh(0,`header`)(1,`h1`,0),Wo(),jh(2,`svg`,1)(3,`defs`)(4,`linearGradient`,2),Ph(5,`stop`,3)(6,`stop`,4)(7,`stop`,5)(8,`stop`,6)(9,`stop`,7)(10,`stop`,8),Nh()(),Ph(11,`path`,9),Nh(),Go(),jh(12,`span`),Z(13,`Angular DevTools`),Nh()(),jh(14,`nav`),K(15,aT,2,3,`button`,10,iT),Nh(),jh(17,`span`,11),Z(18),Nh()(),jh(19,`main`),W(20,oT,1,1,`app-dashboard`,12)(21,sT,1,1,`app-component-tree`,12)(22,cT,1,1,`app-route-inspector`,12)(23,lT,1,1,`app-signal-inspector`,12)(24,uT,1,1,`app-di-inspector`,12)(25,dT,1,1,`app-store-inspector`,12)(26,fT,1,1,`app-forms-inspector`,12),Nh()),e&2){let e;U(15),q(t.tabs),U(2),lg(`connected`,t.connected()),U(),$(` `,t.connected()?`Connected`:`Connecting…`,` `),U(2),G((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:[IS,QS,aC,DC,XC,hw,rT],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 mT(e){try{return new URL(e,location.href).origin===location.origin}catch{return!1}}function hT(){let e=new URLSearchParams(location.search).get(`baseURL`);if(e&&mT(e))return e;if(!location.pathname.includes(`__ng-devtools`))return`/__ng-devtools/`}Y_(pT).catch(console.error);export{Qv as t}; \ No newline at end of file diff --git a/extension/ui/index.html b/extension/ui/index.html index 936a8e0..35c5940 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..52c23f4 --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-actions.test.ts @@ -0,0 +1,270 @@ +// @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, runFormAction, 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('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..17c36e0 --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-collector.test.ts @@ -0,0 +1,190 @@ +// @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('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-lint.test.ts b/packages/ng-devtools/src/__tests__/forms-lint.test.ts new file mode 100644 index 0000000..0728e24 --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-lint.test.ts @@ -0,0 +1,109 @@ +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'); + }); +}); 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..927c39f --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-mcp.test.ts @@ -0,0 +1,416 @@ +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'"], + }); + 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('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'); + }); + + 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('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..ec6e80a --- /dev/null +++ b/packages/ng-devtools/src/__tests__/forms-read.test.ts @@ -0,0 +1,299 @@ +// @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, + 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'); + }); + + 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(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..89388c0 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,7 @@ 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: [] }); }); }); 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 d23302b..50fb1b2 100644 --- a/packages/ng-devtools/src/devframe.ts +++ b/packages/ng-devtools/src/devframe.ts @@ -19,6 +19,22 @@ import { type FormsState, type InspectFormsArgs, } from './rpc/forms-tools.ts'; +import { + explainCustomControlText, + explainFieldText, + explainSubmitText, + fieldOwner, + exportFormText, + formDiffText, + formHistoryText, + formPayloadText, + latestMarker, + lintFormsFor, + lintFormsText, + waitSatisfied, + type WaitUntil, +} from './rpc/forms-explain.ts'; +import { findFormSource, sourceText } from './rpc/forms-source.ts'; import pkg from '../package.json' with { type: 'json' }; @@ -88,7 +104,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) => @@ -96,6 +112,7 @@ const ngDevtools = defineDevframe({ draft.forms = next.forms; draft.events = next.events; draft.reportedAt = next.reportedAt; + draft.setupErrors = next.setupErrors ?? []; }); my.rpc.register({ @@ -138,6 +155,94 @@ 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-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', @@ -352,6 +457,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: @@ -382,14 +491,333 @@ 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 pageProperty = { + 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: pageProperty, + }, + }, + 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: pageProperty } }, + 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: pageProperty } }, + 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'], + }, + 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: pageProperty, + }, + }, + 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: pageProperty, + }, + }, + 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: pageProperty } }, + 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: pageProperty }, + }, + 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: pageProperty, + }, + }, + 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: pageProperty, + }, + }, + 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. 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', + ], + }, + 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 form = str(args?.['form']); + const match = state.forms.find((f) => f.id === form || f.id.split('@')[0] === form); + if (!match) + return { + markdown: `No form ${form ?? ''}. Forms: ${state.forms.map((f) => f.id).join(', ')}.`, + }; + 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 form = str(args?.['form']); + const match = state.forms.find((f) => f.id === form || f.id.split('@')[0] === form); + if (!match) + return { + markdown: `No form ${form ?? ''}. Forms: ${state.forms.map((f) => f.id).join(', ')}.`, + }; + 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..5904d59 --- /dev/null +++ b/packages/ng-devtools/src/forms-actions.ts @@ -0,0 +1,612 @@ +import { + directivesOf, + findFieldElement, + isAbstractControl, + nodeAt, + serializeFormValue, + type FormsDebugApi, + type FoundForm, +} from './forms.ts'; +import { 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', +] 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(); +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 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); + 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}.`); + 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) { + return { ok: true, message: 'Found', formId, path: controlPath(found.root, control) }; + } + } + } + return fail(`${selector} is not bound to a form field.`); +} + +function controlPath(root: AnyRecord, target: AnyRecord): string { + const keys: string[] = []; + let current: AnyRecord | null = target; + for (let guard = 0; current && current !== root && guard < 64; guard++) { + const parent: AnyRecord | null = read(() => current!['parent'], null); + if (!parent) break; + const controls = read(() => parent['controls'], {}); + const key = Array.isArray(controls) + ? String(controls.indexOf(current)) + : Object.keys(controls).find((k) => controls[k] === current); + keys.unshift(key ?? '?'); + current = parent; + } + return keys.join('.'); +} + +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, { + 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 (shapeOf(rawValue(found, found.root)) !== saved.shape) { + return fail( + 'The form structure changed since the snapshot (arrays or groups differ), so it cannot be restored.', + ); + } + if (signal) found.root['value'].set(structuredCloneSafe(saved.value)); + else found.root['patchValue'](saved.value); + 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..7274e10 --- /dev/null +++ b/packages/ng-devtools/src/forms-collector.ts @@ -0,0 +1,444 @@ +import { + collectForms, + detailOf, + diffForms, + findFieldElement, + findForms, + formIdFor, + propertyHolding, + serializeControl, + watchControlEvents, + type CollectedForm, + type EventOrigin, + type FormEvent, + type FormFieldNode, + type FoundForm, +} from './forms.ts'; +import { isDevtoolsAction, isFormAction, runFormAction } from './forms-actions.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 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; + + 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 (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 origin: EventOrigin | undefined = devtoolsSincePush + ? 'devtools' + : userSincePush + ? 'user' + : undefined; + recordFormEvent(origin ? { ...event, origin } : event, false); + } + } + lastForms = forms; + userSincePush = false; + devtoolsSincePush = false; + const report = { pageId, forms, events: formEvents, setupErrors }; + 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); + } + + const onUserEvent = (event: Event) => { + if (!isDevtoolsAction()) userSincePush = true; + 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: redactMessage(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; + } + devtoolsSincePush = true; + runFormAction( + { + ng, + forms: foundById, + elements: fieldElements, + all: () => document.querySelectorAll('*'), + }, + 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(); + }, + }; +} 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-privacy.ts b/packages/ng-devtools/src/forms-privacy.ts new file mode 100644 index 0000000..33c9cfa --- /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) return null; + if (element.getAttribute('type') === 'password') return 'input-type'; + if (SECRET_AUTOCOMPLETE.test(element.getAttribute('autocomplete') ?? '')) return 'autocomplete'; + if (!unmasked && safeClosest(element, MASK_MARKERS)) return 'marker'; + if (!unmasked && 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..d652c60 100644 --- a/packages/ng-devtools/src/forms.ts +++ b/packages/ng-devtools/src/forms.ts @@ -1,3 +1,29 @@ +import { domFacts, submitDom, type DomFacts, type SubmitDom } from './forms-dom.ts'; +import { + REDACTED, + SecretSet, + 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 +31,8 @@ export interface FormFieldError { kind: string; message: string; params?: Record; + source?: ErrorSource; + from?: string; } export interface FormFieldNode { @@ -31,6 +59,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,6 +85,8 @@ export interface CollectedForm { property?: string; label: string; submitted?: boolean; + submit?: SubmitSetup; + submitDom?: SubmitDom; root: FormFieldNode; } @@ -50,8 +97,15 @@ export interface FormEvent { detail?: string; timestamp: number; seq?: number; + origin?: EventOrigin; + caller?: string; + prev?: string; + count?: number; + outcome?: 'ran' | 'blocked' | 'threw' | 'busy'; } +export type EventOrigin = 'user' | 'code' | 'devtools' | 'binding'; + export interface FormsDebugApi { getComponent(el: Element): unknown; getDirectives(el: Element): unknown[]; @@ -65,6 +119,7 @@ export interface FoundForm { property?: string; directive?: AnyRecord; element?: Element; + formElement?: Element; } export interface FoundForms { @@ -72,20 +127,53 @@ 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; + +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) { + if (!secrets) return; + if (value && typeof value === 'object') { + for (const item of Object.values(value as object).slice(0, 50)) remember(item); + } 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 +244,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 +276,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 +413,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 +511,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 +542,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 +584,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 +614,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 +722,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 +743,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 +752,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 +765,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, }); }); } @@ -667,7 +813,18 @@ export function collectForms( const count = (seen.get(label) ?? 0) + 1; seen.set(label, count); if (count > 1) label = `${label} #${count}`; - return { + secrets = new SecretSet(); + 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: idOf(found.root), kind: found.kind, owner, @@ -677,14 +834,23 @@ 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; }); } +function redactTree(node: FormFieldNode, set: SecretSet) { + node.errors = node.errors.map((error) => ({ ...error, message: set.redact(error.message) })); + if (node.disabledReasons) node.disabledReasons = node.disabledReasons.map((r) => set.redact(r)); + if (typeof node.value === 'string') node.value = set.redact(node.value); + if (node.dom?.drift && typeof node.dom.drift === 'string') + node.dom.drift = set.redact(node.dom.drift); + for (const child of node.children ?? []) redactTree(child, set); +} + function flatten(node: FormFieldNode, out = new Map()) { out.set(node.path, node); for (const child of node.children ?? []) flatten(child, out); @@ -755,8 +921,11 @@ function pathTo(root: AnyRecord, target: AnyRecord): string { 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); @@ -785,7 +954,7 @@ export function controlEventOf( 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 +985,7 @@ export function watchControlEvents( const subscription = read( () => events['subscribe']((event: AnyRecord) => { + if (isProbing()) return; const emit = () => { const mapped = read( () => @@ -848,6 +1018,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 143146d..b721ad5 100644 --- a/packages/ng-devtools/src/overlay.ts +++ b/packages/ng-devtools/src/overlay.ts @@ -1,33 +1,9 @@ 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'; 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'; function storedPageId(): string | null { @@ -73,16 +49,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. @@ -110,113 +76,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; pushTree(); pushSignalGraph(); @@ -249,40 +110,14 @@ 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(() => {}); addEventListener('pagehide', leave); return () => { clearInterval(interval); removeEventListener('pagehide', leave); - for (const { stop } of watched.values()) stop(); + forms.stop(); 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..1557060 --- /dev/null +++ b/packages/ng-devtools/src/rpc/forms-explain.ts @@ -0,0 +1,550 @@ +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 && args.form) { + const exact = forms.find((f) => f.id === args.form || f.id.split('@')[0] === args.form); + if (exact) return exact; + } + if (forms.length > 1 && !args.form) { + return `${forms.length} forms match; pass \`form\`: ${forms.map((f) => `${f.id} ${code(f.label)}`).join(', ')}.`; + } + return forms[0]; +} + +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 ?? '', + ] + .filter(Boolean) + .join(', '); + return `- #${event.seq ?? '?'} ${time} ${code(event.path || '(form)')} ${event.type} ${change}${extra ? ` (${extra})` : ''}`; +} + +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 setup = (state.setupErrors ?? []) + .map((e) => e.message) + .filter((m) => !node.key || m.includes(node.key)); + 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..60b7673 --- /dev/null +++ b/packages/ng-devtools/src/rpc/forms-lint.ts @@ -0,0 +1,228 @@ +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