@mk-kit/ui 0.36.0 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -6
- package/fesm2022/mk-kit-ui-chat.mjs +490 -0
- package/fesm2022/mk-kit-ui-chat.mjs.map +1 -0
- package/fesm2022/mk-kit-ui-core.mjs +310 -1
- package/fesm2022/mk-kit-ui-core.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-dynamic-form.mjs +578 -0
- package/fesm2022/mk-kit-ui-dynamic-form.mjs.map +1 -0
- package/fesm2022/mk-kit-ui-feedback.mjs +400 -8
- package/fesm2022/mk-kit-ui-feedback.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-forms.mjs +816 -6
- package/fesm2022/mk-kit-ui-forms.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-query-builder.mjs +276 -0
- package/fesm2022/mk-kit-ui-query-builder.mjs.map +1 -0
- package/fesm2022/mk-kit-ui-table.mjs +20 -1
- package/fesm2022/mk-kit-ui-table.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-testing.mjs +834 -0
- package/fesm2022/mk-kit-ui-testing.mjs.map +1 -0
- package/fesm2022/mk-kit-ui.mjs +3 -0
- package/fesm2022/mk-kit-ui.mjs.map +1 -1
- package/package.json +17 -1
- package/types/mk-kit-ui-chat.d.ts +288 -0
- package/types/mk-kit-ui-core.d.ts +167 -2
- package/types/mk-kit-ui-dynamic-form.d.ts +305 -0
- package/types/mk-kit-ui-feedback.d.ts +111 -2
- package/types/mk-kit-ui-forms.d.ts +264 -3
- package/types/mk-kit-ui-query-builder.d.ts +98 -0
- package/types/mk-kit-ui-table.d.ts +12 -0
- package/types/mk-kit-ui-testing.d.ts +344 -0
- package/types/mk-kit-ui.d.ts +3 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mk-kit-ui-testing.mjs","sources":["../../../projects/mk-kit/testing/harness.ts","../../../projects/mk-kit/testing/harnesses/form-controls.harness.ts","../../../projects/mk-kit/testing/harnesses/navigation.harness.ts","../../../projects/mk-kit/testing/harnesses/table.harness.ts","../../../projects/mk-kit/testing/harnesses/overlays.harness.ts","../../../projects/mk-kit/testing/index.ts","../../../projects/mk-kit/testing/mk-kit-ui-testing.ts"],"sourcesContent":["import type { ComponentFixture } from '@angular/core/testing';\n\n/**\n * Filters every harness lookup accepts. `selector` narrows the host elements\n * considered (e.g. a class or attribute your template sets); `text` matches\n * the host's trimmed text content — a string must match exactly, a RegExp\n * is tested.\n */\nexport interface MkHarnessFilters {\n selector?: string;\n text?: string | RegExp;\n}\n\n/** Constructor shape of every harness class: a static `hostSelector`. */\nexport interface MkHarnessType<T extends MkHarness> {\n new (host: MkTestElement, loader: MkHarnessLoader): T;\n readonly hostSelector: string;\n}\n\n/** Keys accepted by `MkTestElement.sendKeys` besides printable characters. */\nexport type MkTestKey =\n | 'Enter'\n | 'Escape'\n | 'Tab'\n | 'Backspace'\n | 'Delete'\n | ' '\n | 'ArrowUp'\n | 'ArrowDown'\n | 'ArrowLeft'\n | 'ArrowRight'\n | 'Home'\n | 'End'\n | 'PageUp'\n | 'PageDown';\n\nconst NO_OP = async (): Promise<void> => {};\n\n/**\n * A DOM element wrapped for tests: reads are synchronous, every interaction\n * dispatches the same events a user would and then settles change detection\n * (`fixture.detectChanges()` + `whenStable()`), so the next read sees the\n * updated view.\n */\nexport class MkTestElement {\n constructor(\n /** The underlying element — reach for it when a harness has no getter. */\n readonly native: HTMLElement,\n /** Flush change detection after an interaction. */\n readonly settle: () => Promise<void> = NO_OP,\n ) {}\n\n /** Trimmed text content with whitespace collapsed. */\n text(): string {\n return (this.native.textContent ?? '').replace(/\\s+/g, ' ').trim();\n }\n\n attr(name: string): string | null {\n return this.native.getAttribute(name);\n }\n\n hasClass(name: string): boolean {\n return this.native.classList.contains(name);\n }\n\n /** Read a DOM property (`value`, `checked`, `open`, …). */\n prop<T = unknown>(name: string): T {\n return (this.native as unknown as Record<string, T>)[name];\n }\n\n matches(selector: string): boolean {\n return this.native.matches(selector);\n }\n\n isFocused(): boolean {\n return this.native.ownerDocument.activeElement === this.native;\n }\n\n /** Native `disabled`, `aria-disabled=\"true\"` or a `--disabled` host class. */\n isDisabled(): boolean {\n const el = this.native as HTMLElement & { disabled?: boolean };\n return (\n el.disabled === true ||\n el.getAttribute('aria-disabled') === 'true' ||\n Array.from(el.classList).some((c) => c.endsWith('--disabled'))\n );\n }\n\n query(selector: string): MkTestElement | null {\n const el = this.native.querySelector<HTMLElement>(selector);\n return el ? new MkTestElement(el, this.settle) : null;\n }\n\n queryAll(selector: string): MkTestElement[] {\n return Array.from(this.native.querySelectorAll<HTMLElement>(selector)).map(\n (el) => new MkTestElement(el, this.settle),\n );\n }\n\n /** Like `query`, but throws a readable error when nothing matches. */\n child(selector: string): MkTestElement {\n const el = this.query(selector);\n if (!el) throw new Error(`Expected \"${selector}\" inside <${this.describe()}>.`);\n return el;\n }\n\n /** pointerdown → mousedown → focus → pointerup → mouseup → click, like a user. */\n async click(): Promise<void> {\n const el = this.native;\n el.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, cancelable: true }));\n el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));\n el.focus();\n el.dispatchEvent(new PointerEvent('pointerup', { bubbles: true, cancelable: true }));\n el.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true }));\n el.click();\n await this.settle();\n }\n\n async hover(): Promise<void> {\n for (const type of ['pointerenter', 'mouseenter', 'pointerover', 'mouseover']) {\n this.native.dispatchEvent(new MouseEvent(type, { bubbles: type.endsWith('over') }));\n }\n this.native.dispatchEvent(new MouseEvent('mousemove', { bubbles: true }));\n await this.settle();\n }\n\n async leave(): Promise<void> {\n for (const type of ['pointerleave', 'mouseleave', 'pointerout', 'mouseout']) {\n this.native.dispatchEvent(new MouseEvent(type, { bubbles: type.endsWith('out') }));\n }\n await this.settle();\n }\n\n async focus(): Promise<void> {\n this.native.focus();\n if (!this.isFocused()) this.native.dispatchEvent(new FocusEvent('focus'));\n await this.settle();\n }\n\n async blur(): Promise<void> {\n this.native.blur();\n this.native.dispatchEvent(new FocusEvent('blur'));\n this.native.dispatchEvent(new FocusEvent('focusout', { bubbles: true }));\n await this.settle();\n }\n\n /**\n * Type into an input/textarea/contenteditable character by character —\n * keydown, `value` append, `input`, keyup — then settle. Use `setValue`\n * to replace the value in one go.\n */\n async type(text: string): Promise<void> {\n const el = this.native as HTMLInputElement;\n el.focus();\n for (const ch of text) {\n const down = new KeyboardEvent('keydown', { key: ch, bubbles: true, cancelable: true });\n el.dispatchEvent(down);\n if (!down.defaultPrevented) {\n if (el.isContentEditable) el.textContent = (el.textContent ?? '') + ch;\n else el.value = (el.value ?? '') + ch;\n el.dispatchEvent(new InputEvent('input', { bubbles: true, data: ch, inputType: 'insertText' }));\n }\n el.dispatchEvent(new KeyboardEvent('keyup', { key: ch, bubbles: true }));\n }\n await this.settle();\n }\n\n /** Set the value of an input/textarea/select and fire `input` + `change`. */\n async setValue(value: string): Promise<void> {\n const el = this.native as HTMLInputElement;\n el.focus();\n el.value = value;\n el.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertReplacementText' }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n await this.settle();\n }\n\n async clear(): Promise<void> {\n const el = this.native as HTMLInputElement;\n el.focus();\n el.value = '';\n el.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'deleteContentBackward' }));\n await this.settle();\n }\n\n /** Dispatch keydown/keyup for each key. Printable single characters are also typed. */\n async sendKeys(...keys: Array<MkTestKey | (string & {})>): Promise<void> {\n for (const key of keys) {\n const mods = parseKey(key);\n const down = new KeyboardEvent('keydown', { ...mods, bubbles: true, cancelable: true });\n this.native.dispatchEvent(down);\n if (!down.defaultPrevented && mods.key.length === 1 && !mods.ctrlKey && !mods.metaKey) {\n const el = this.native as HTMLInputElement;\n if ('value' in el && typeof el.value === 'string' && !el.isContentEditable && isTextField(el)) {\n el.value += mods.key;\n el.dispatchEvent(new InputEvent('input', { bubbles: true, data: mods.key, inputType: 'insertText' }));\n }\n }\n this.native.dispatchEvent(new KeyboardEvent('keyup', { ...mods, bubbles: true }));\n }\n await this.settle();\n }\n\n /** Dispatch any event on the element and settle. */\n async dispatch(event: Event): Promise<void> {\n this.native.dispatchEvent(event);\n await this.settle();\n }\n\n private describe(): string {\n const el = this.native;\n const id = el.id ? `#${el.id}` : '';\n const cls = el.classList.length ? `.${Array.from(el.classList).slice(0, 2).join('.')}` : '';\n return `${el.tagName.toLowerCase()}${id}${cls}`;\n }\n}\n\n/** `Control+a`, `Shift+Tab`, `Enter`, `a` → KeyboardEventInit. */\nfunction parseKey(key: string): KeyboardEventInit & { key: string } {\n const parts = key.split('+');\n const k = parts.pop() ?? key;\n const has = (m: string) => parts.some((p) => p.toLowerCase() === m);\n return {\n key: k,\n ctrlKey: has('control') || has('ctrl'),\n metaKey: has('meta') || has('cmd'),\n shiftKey: has('shift'),\n altKey: has('alt'),\n };\n}\n\nfunction isTextField(el: HTMLElement): boolean {\n if (el instanceof HTMLTextAreaElement) return true;\n if (!(el instanceof HTMLInputElement)) return false;\n return !['checkbox', 'radio', 'button', 'submit', 'reset', 'file', 'range', 'color'].includes(el.type);\n}\n\n/**\n * Finds harnesses under a root element. Create one with\n * `MkHarnessLoader.fromFixture(fixture)`; use `.document()` for content that\n * mk-kit teleports into `document.body` (dialogs, toasts, menus, select\n * panels) and `.within(el)` to scope lookups.\n */\nexport class MkHarnessLoader {\n constructor(\n readonly root: Element,\n readonly settle: () => Promise<void>,\n ) {}\n\n /**\n * Loader rooted at the fixture's host element. Every interaction runs\n * `fixture.detectChanges()` and awaits `fixture.whenStable()` afterwards,\n * so it works in zoneless and zone-based TestBeds alike.\n */\n static fromFixture(fixture: ComponentFixture<unknown>): MkHarnessLoader {\n const settle = async () => {\n fixture.detectChanges();\n await fixture.whenStable();\n fixture.detectChanges();\n };\n return new MkHarnessLoader(fixture.nativeElement as Element, settle);\n }\n\n /** Same settle function, rooted at `document.body` — for overlays. */\n document(): MkHarnessLoader {\n return new MkHarnessLoader(this.root.ownerDocument.body, this.settle);\n }\n\n within(root: Element | MkTestElement): MkHarnessLoader {\n return new MkHarnessLoader(root instanceof MkTestElement ? root.native : root, this.settle);\n }\n\n /** Wrap the root element itself. */\n rootElement(): MkTestElement {\n return new MkTestElement(this.root as HTMLElement, this.settle);\n }\n\n element(selector: string): MkTestElement {\n const el = this.root.querySelector<HTMLElement>(selector) ?? (this.root.matches(selector) ? (this.root as HTMLElement) : null);\n if (!el) throw new Error(`No element matches \"${selector}\" under <${this.root.tagName.toLowerCase()}>.`);\n return new MkTestElement(el, this.settle);\n }\n\n elements(selector: string): MkTestElement[] {\n return Array.from(this.root.querySelectorAll<HTMLElement>(selector)).map((el) => new MkTestElement(el, this.settle));\n }\n\n /** First matching harness; throws when there is none. */\n async get<T extends MkHarness>(type: MkHarnessType<T>, filters: MkHarnessFilters = {}): Promise<T> {\n const [first] = await this.getAll(type, filters);\n if (!first) {\n throw new Error(\n `No ${type.name} found (host \"${type.hostSelector}\"${filters.selector ? `, selector \"${filters.selector}\"` : ''}${\n filters.text ? `, text ${String(filters.text)}` : ''\n }) under <${this.root.tagName.toLowerCase()}>.`,\n );\n }\n return first;\n }\n\n async getOrNull<T extends MkHarness>(type: MkHarnessType<T>, filters: MkHarnessFilters = {}): Promise<T | null> {\n const [first] = await this.getAll(type, filters);\n return first ?? null;\n }\n\n async has<T extends MkHarness>(type: MkHarnessType<T>, filters: MkHarnessFilters = {}): Promise<boolean> {\n return (await this.getAll(type, filters)).length > 0;\n }\n\n async getAll<T extends MkHarness>(type: MkHarnessType<T>, filters: MkHarnessFilters = {}): Promise<T[]> {\n await this.settle();\n const hosts = new Set<HTMLElement>();\n for (const part of type.hostSelector.split(',')) {\n const sel = part.trim();\n if (this.root.matches(sel)) hosts.add(this.root as HTMLElement);\n for (const el of Array.from(this.root.querySelectorAll<HTMLElement>(sel))) hosts.add(el);\n }\n const out: T[] = [];\n for (const host of hosts) {\n if (filters.selector && !host.matches(filters.selector)) continue;\n const el = new MkTestElement(host, this.settle);\n if (filters.text !== undefined && !matchText(el.text(), filters.text)) continue;\n out.push(new type(el, this));\n }\n // Document order.\n out.sort((a, b) => (a.host.native.compareDocumentPosition(b.host.native) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1));\n return out;\n }\n}\n\nexport function matchText(actual: string, expected: string | RegExp): boolean {\n return typeof expected === 'string' ? actual === expected : expected.test(actual);\n}\n\n/**\n * Base class of every mk-kit harness. Subclasses declare `hostSelector`\n * and expose user-level actions (`click()`, `selectOption()`, …) and reads\n * (`isChecked()`, `text()`), so specs never depend on the component's DOM.\n */\nexport abstract class MkHarness {\n static readonly hostSelector: string = '';\n\n constructor(\n /** The component's host element. */\n readonly host: MkTestElement,\n protected readonly loader: MkHarnessLoader,\n ) {}\n\n protected settle(): Promise<void> {\n return this.loader.settle();\n }\n\n /** Query inside the host. */\n protected q(selector: string): MkTestElement | null {\n return this.host.query(selector);\n }\n\n protected qAll(selector: string): MkTestElement[] {\n return this.host.queryAll(selector);\n }\n\n /** Query the whole document — for panels teleported to `document.body`. */\n protected qDocument(selector: string): MkTestElement | null {\n const el = this.host.native.ownerDocument.querySelector<HTMLElement>(selector);\n return el ? new MkTestElement(el, this.host.settle) : null;\n }\n\n /** Element referenced by an `aria-controls` / `aria-owns` id on `from`. */\n protected controlled(from: MkTestElement, attribute = 'aria-controls'): MkTestElement | null {\n const id = from.attr(attribute);\n if (!id) return null;\n const el = this.host.native.ownerDocument.getElementById(id);\n return el ? new MkTestElement(el, this.host.settle) : null;\n }\n}\n\n/** Resolve \"by index or by label\" arguments shared by option-style harnesses. */\nexport function pickBy<T>(items: T[], which: number | string | RegExp, label: (item: T) => string, what: string): T {\n const item =\n typeof which === 'number'\n ? items[which]\n : items.find((i) => matchText(label(i), which));\n if (!item) {\n throw new Error(\n `No ${what} ${typeof which === 'number' ? `at index ${which}` : `matching ${String(which)}`}. Available: ${items\n .map((i) => JSON.stringify(label(i)))\n .join(', ') || '(none)'}.`,\n );\n }\n return item;\n}\n","import { MkHarness, MkTestElement, pickBy } from '../harness';\n\n/** `button[mkButton]` / `a[mkButton]`. */\nexport class MkButtonHarness extends MkHarness {\n static override readonly hostSelector = 'button[mkButton], a[mkButton], .mk-button';\n\n text(): string {\n return this.host.text();\n }\n\n async click(): Promise<void> {\n await this.host.click();\n }\n\n async focus(): Promise<void> {\n await this.host.focus();\n }\n\n isDisabled(): boolean {\n return this.host.isDisabled();\n }\n\n isLoading(): boolean {\n return this.host.hasClass('mk-button--loading');\n }\n\n tone(): string | null {\n return this.host.attr('data-tone');\n }\n\n /** `solid` | `soft` | `outline` | `ghost` | `link`. */\n variant(): string | null {\n const m = Array.from(this.host.native.classList).find((c) =>\n /^mk-button--(solid|soft|outline|ghost|link)$/.test(c),\n );\n return m ? m.replace('mk-button--', '') : null;\n }\n\n size(): string | null {\n const m = Array.from(this.host.native.classList).find((c) => /^mk-button--(sm|md|lg)$/.test(c));\n return m ? m.replace('mk-button--', '') : null;\n }\n}\n\n/** Native `input[mkInput]` / `textarea[mkInput]`. */\nexport class MkInputHarness extends MkHarness {\n static override readonly hostSelector = '[mkInput], .mk-input';\n\n value(): string {\n return this.host.prop<string>('value') ?? '';\n }\n\n /** Replace the value (fires `input` + `change`). */\n async setValue(value: string): Promise<void> {\n await this.host.setValue(value);\n }\n\n /** Append text one character at a time (keydown / input / keyup). */\n async type(text: string): Promise<void> {\n await this.host.type(text);\n }\n\n async clear(): Promise<void> {\n await this.host.clear();\n }\n\n async focus(): Promise<void> {\n await this.host.focus();\n }\n\n async blur(): Promise<void> {\n await this.host.blur();\n }\n\n placeholder(): string {\n return this.host.attr('placeholder') ?? '';\n }\n\n type_(): string {\n return this.host.attr('type') ?? (this.host.native.tagName === 'TEXTAREA' ? 'textarea' : 'text');\n }\n\n isDisabled(): boolean {\n return this.host.isDisabled();\n }\n\n isInvalid(): boolean {\n return this.host.hasClass('mk-input--invalid') || this.host.attr('aria-invalid') === 'true';\n }\n\n isRequired(): boolean {\n return this.host.prop<boolean>('required') === true || this.host.attr('aria-required') === 'true';\n }\n\n isFocused(): boolean {\n return this.host.isFocused();\n }\n}\n\n/** `mk-checkbox`. */\nexport class MkCheckboxHarness extends MkHarness {\n static override readonly hostSelector = 'mk-checkbox';\n\n private get input(): MkTestElement {\n return this.host.child('input[type=\"checkbox\"]');\n }\n\n label(): string {\n return this.q('.mk-checkbox__text')?.text() ?? '';\n }\n\n isChecked(): boolean {\n return this.input.prop<boolean>('checked') === true;\n }\n\n isIndeterminate(): boolean {\n return this.input.prop<boolean>('indeterminate') === true;\n }\n\n isDisabled(): boolean {\n return this.input.isDisabled();\n }\n\n isRequired(): boolean {\n return this.input.prop<boolean>('required') === true;\n }\n\n async toggle(): Promise<void> {\n await this.input.click();\n }\n\n async check(): Promise<void> {\n if (!this.isChecked()) await this.toggle();\n }\n\n async uncheck(): Promise<void> {\n if (this.isChecked()) await this.toggle();\n }\n\n async focus(): Promise<void> {\n await this.input.focus();\n }\n\n async blur(): Promise<void> {\n await this.input.blur();\n }\n}\n\n/** `mk-switch`. */\nexport class MkSwitchHarness extends MkHarness {\n static override readonly hostSelector = 'mk-switch';\n\n private get control(): MkTestElement {\n return this.host.child('[role=\"switch\"]');\n }\n\n label(): string {\n return this.q('.mk-switch__label')?.text() ?? '';\n }\n\n isChecked(): boolean {\n return this.control.attr('aria-checked') === 'true';\n }\n\n isDisabled(): boolean {\n return this.control.isDisabled();\n }\n\n async toggle(): Promise<void> {\n await this.control.click();\n }\n\n async check(): Promise<void> {\n if (!this.isChecked()) await this.toggle();\n }\n\n async uncheck(): Promise<void> {\n if (this.isChecked()) await this.toggle();\n }\n\n async focus(): Promise<void> {\n await this.control.focus();\n }\n}\n\n/** One `mk-radio` inside a group. */\nexport class MkRadioHarness extends MkHarness {\n static override readonly hostSelector = 'mk-radio';\n\n label(): string {\n return this.q('.mk-radio__label')?.text() ?? this.host.text();\n }\n\n isChecked(): boolean {\n return this.host.attr('aria-checked') === 'true';\n }\n\n isDisabled(): boolean {\n return this.host.isDisabled();\n }\n\n async select(): Promise<void> {\n await this.host.click();\n }\n\n async focus(): Promise<void> {\n await this.host.focus();\n }\n}\n\n/** `mk-radio-group`. */\nexport class MkRadioGroupHarness extends MkHarness {\n static override readonly hostSelector = 'mk-radio-group';\n\n radios(): Promise<MkRadioHarness[]> {\n return this.loader.within(this.host).getAll(MkRadioHarness);\n }\n\n async labels(): Promise<string[]> {\n return (await this.radios()).map((r) => r.label());\n }\n\n /** Label of the checked radio, or `null`. */\n async checkedLabel(): Promise<string | null> {\n return (await this.radios()).find((r) => r.isChecked())?.label() ?? null;\n }\n\n async checkedIndex(): Promise<number> {\n return (await this.radios()).findIndex((r) => r.isChecked());\n }\n\n /** Select by index, exact label or RegExp. */\n async select(which: number | string | RegExp): Promise<void> {\n const radios = await this.radios();\n await pickBy(radios, which, (r) => r.label(), 'radio').select();\n }\n\n isDisabled(): boolean {\n return this.host.hasClass('mk-radio-group--disabled');\n }\n}\n\nexport interface MkSelectOptionState {\n label: string;\n selected: boolean;\n disabled: boolean;\n}\n\n/** `mk-select` — opens the teleported listbox and picks options like a user. */\nexport class MkSelectHarness extends MkHarness {\n static override readonly hostSelector = 'mk-select';\n\n private get trigger(): MkTestElement {\n return this.host.child('[role=\"combobox\"]');\n }\n\n /** Label of the selected option, or `''` when only the placeholder shows. */\n valueText(): string {\n const v = this.q('.mk-select__value');\n return v && !v.hasClass('mk-select__value--placeholder') ? v.text() : '';\n }\n\n placeholder(): string {\n return this.q('.mk-select__value--placeholder')?.text() ?? '';\n }\n\n isOpen(): boolean {\n return this.trigger.attr('aria-expanded') === 'true';\n }\n\n isDisabled(): boolean {\n return this.trigger.isDisabled();\n }\n\n isInvalid(): boolean {\n return this.trigger.attr('aria-invalid') === 'true';\n }\n\n async open(): Promise<void> {\n if (!this.isOpen()) await this.trigger.click();\n }\n\n async close(): Promise<void> {\n if (this.isOpen()) await this.trigger.sendKeys('Escape');\n if (this.isOpen()) await this.trigger.click();\n }\n\n async focus(): Promise<void> {\n await this.trigger.focus();\n }\n\n /** Options of the (opened) listbox. Opens it if needed. */\n async options(): Promise<MkSelectOptionState[]> {\n const els = await this.optionElements();\n return els.map((el) => ({\n label: el.text(),\n selected: el.attr('aria-selected') === 'true',\n disabled: el.attr('aria-disabled') === 'true',\n }));\n }\n\n /** Pick an option by index, exact label or RegExp (opens the list first). */\n async selectOption(which: number | string | RegExp): Promise<void> {\n const els = await this.optionElements();\n await pickBy(els, which, (el) => el.text(), 'option').click();\n }\n\n private async optionElements(): Promise<MkTestElement[]> {\n await this.open();\n const list = this.controlled(this.trigger);\n if (!list) throw new Error('mk-select listbox did not open.');\n return list.queryAll('[role=\"option\"]');\n }\n}\n\n/** `mk-form-field` — label / hint / error around any control. */\nexport class MkFormFieldHarness extends MkHarness {\n static override readonly hostSelector = 'mk-form-field';\n\n label(): string {\n return this.q('.mk-form-field__label-text')?.text() ?? '';\n }\n\n hint(): string | null {\n return this.q('.mk-form-field__hint')?.text() ?? null;\n }\n\n /** The visible validation message, or `null` when the field is valid/untouched. */\n error(): string | null {\n return this.q('.mk-form-field__error')?.text() ?? null;\n }\n\n hasError(): boolean {\n return this.error() !== null;\n }\n\n isRequired(): boolean {\n return !!this.q('.mk-form-field__required');\n }\n\n /** The control inside the field, as a harness of the given type. */\n control<T extends MkHarness>(type: Parameters<typeof this.loader.get<T>>[0]): Promise<T> {\n return this.loader.within(this.host).get(type);\n }\n}\n","import { MkHarness, MkTestElement, pickBy } from '../harness';\n\n/** `mk-tabs`. */\nexport class MkTabsHarness extends MkHarness {\n static override readonly hostSelector = 'mk-tabs';\n\n private tabButtons(): MkTestElement[] {\n return this.qAll('[role=\"tab\"]');\n }\n\n labels(): string[] {\n return this.tabButtons().map((t) => t.text());\n }\n\n selectedIndex(): number {\n return this.tabButtons().findIndex((t) => t.attr('aria-selected') === 'true');\n }\n\n selectedLabel(): string | null {\n const i = this.selectedIndex();\n return i >= 0 ? this.labels()[i] : null;\n }\n\n /** Select by index, exact label or RegExp. */\n async select(which: number | string | RegExp): Promise<void> {\n await pickBy(this.tabButtons(), which, (t) => t.text(), 'tab').click();\n }\n\n isDisabled(which: number | string | RegExp): boolean {\n return pickBy(this.tabButtons(), which, (t) => t.text(), 'tab').isDisabled();\n }\n\n /** The visible tab panel (`mk-tab` host). */\n selectedPanel(): MkTestElement | null {\n const tab = this.tabButtons()[this.selectedIndex()];\n return tab ? this.controlled(tab) : null;\n }\n\n /** Text of the visible panel. */\n selectedPanelText(): string {\n return this.selectedPanel()?.text() ?? '';\n }\n}\n\n/**\n * A `[mkMenuTriggerFor]` trigger and the `mk-menu` panel it opens. The host\n * is matched by the trigger's `aria-haspopup=\"menu\"` (the directive's\n * attribute is an input binding, so it is not in the DOM).\n */\nexport class MkMenuHarness extends MkHarness {\n static override readonly hostSelector = '[aria-haspopup=\"menu\"]';\n\n isOpen(): boolean {\n return this.host.attr('aria-expanded') === 'true';\n }\n\n async open(): Promise<void> {\n if (!this.isOpen()) await this.host.click();\n }\n\n async close(): Promise<void> {\n if (this.isOpen()) await this.panel()?.sendKeys('Escape');\n if (this.isOpen()) await this.host.click();\n }\n\n /** The teleported panel (`[role=\"menu\"]`), or `null` while closed. */\n panel(): MkTestElement | null {\n return this.controlled(this.host);\n }\n\n /** Item texts of the open menu (opens it if needed). Submenu panels excluded. */\n async items(): Promise<string[]> {\n return (await this.itemElements()).map((i) => i.text());\n }\n\n /** Click an item by index, exact text or RegExp (opens the menu first). */\n async clickItem(which: number | string | RegExp): Promise<void> {\n await pickBy(await this.itemElements(), which, (i) => i.text(), 'menu item').click();\n }\n\n async isItemDisabled(which: number | string | RegExp): Promise<boolean> {\n return pickBy(await this.itemElements(), which, (i) => i.text(), 'menu item').isDisabled();\n }\n\n private async itemElements(): Promise<MkTestElement[]> {\n await this.open();\n const panel = this.panel();\n if (!panel) throw new Error('mk-menu panel did not open.');\n return panel.queryAll('[role=\"menuitem\"]');\n }\n}\n","import { MkHarness, MkTestElement, pickBy } from '../harness';\nimport { MkCheckboxHarness } from './form-controls.harness';\n\n/** One data row of `mk-table`. */\nexport class MkTableRowHarness extends MkHarness {\n static override readonly hostSelector = 'tr.mk-table__row';\n\n /** Cell texts of the data columns (expand / select cells excluded). */\n cells(): string[] {\n return this.dataCells().map((c) => c.text());\n }\n\n cell(index: number): string {\n return this.cells()[index] ?? '';\n }\n\n isSelected(): boolean {\n return this.host.hasClass('mk-table__row--selected');\n }\n\n isExpanded(): boolean {\n return this.host.hasClass('mk-table__row--expanded') || this.host.attr('aria-expanded') === 'true';\n }\n\n async click(): Promise<void> {\n await this.host.click();\n }\n\n /** Toggle the selection checkbox (throws when the table is not `selectable`). */\n async toggleSelected(): Promise<void> {\n const cb = await this.loader.within(this.host.child('.mk-table__td--select')).get(MkCheckboxHarness);\n await cb.toggle();\n }\n\n /** Toggle the expand / tree control of the row. */\n async toggleExpanded(): Promise<void> {\n const btn = this.q('.mk-table__td--expand button') ?? this.q('.mk-table__tree-toggle') ?? this.q('button[aria-expanded]');\n if (!btn) throw new Error('Row has no expand toggle (table is not expandable / has no children).');\n await btn.click();\n }\n\n private dataCells(): MkTestElement[] {\n return this.qAll('td.mk-table__td').filter(\n (c) => !c.hasClass('mk-table__td--expand') && !c.hasClass('mk-table__td--select'),\n );\n }\n}\n\n/** `mk-table`. */\nexport class MkTableHarness extends MkHarness {\n static override readonly hostSelector = 'mk-table';\n\n /** Header labels of the data columns, in display order. */\n headers(): string[] {\n return this.headerCells().map((th) => th.child('.mk-table__th-label').text());\n }\n\n rows(): Promise<MkTableRowHarness[]> {\n return this.loader.within(this.host).getAll(MkTableRowHarness);\n }\n\n async rowCount(): Promise<number> {\n return (await this.rows()).length;\n }\n\n /** Every data cell as text: `rows()[r].cells()`. */\n async cellTexts(): Promise<string[][]> {\n return (await this.rows()).map((r) => r.cells());\n }\n\n /** Click a sortable header (by index, exact label or RegExp). */\n async sortBy(which: number | string | RegExp): Promise<void> {\n const th = pickBy(this.headerCells(), which, (h) => h.child('.mk-table__th-label').text(), 'column');\n const btn = th.query('.mk-table__th-button');\n if (!btn) throw new Error(`Column \"${th.text()}\" is not sortable.`);\n await btn.click();\n }\n\n /** `'ascending' | 'descending' | 'none' | null` (null = not sortable). */\n sortDirection(which: number | string | RegExp): string | null {\n return pickBy(this.headerCells(), which, (h) => h.child('.mk-table__th-label').text(), 'column').attr('aria-sort');\n }\n\n async selectedRowCount(): Promise<number> {\n return (await this.rows()).filter((r) => r.isSelected()).length;\n }\n\n /** Toggle the header \"select all\" checkbox. */\n async toggleAll(): Promise<void> {\n const th = this.q('.mk-table__th--select');\n if (!th) throw new Error('Table is not selectable.');\n await (await this.loader.within(th).get(MkCheckboxHarness)).toggle();\n }\n\n isEmpty(): boolean {\n return !this.q('tr.mk-table__row');\n }\n\n private headerCells(): MkTestElement[] {\n return this.qAll('th.mk-table__th').filter(\n (th) => !th.hasClass('mk-table__th--expand') && !th.hasClass('mk-table__th--select'),\n );\n }\n}\n","import { MkHarness, MkTestElement, pickBy } from '../harness';\n\n/**\n * A dialog opened by `MkDialogService` (`open()`, `confirm()`, `alert()`,\n * `prompt()`). Dialogs live in `document.body`, so look them up through\n * `loader.document()`.\n */\nexport class MkDialogHarness extends MkHarness {\n static override readonly hostSelector = '.mk-overlay-panel[role=\"dialog\"], .mk-overlay-panel[role=\"alertdialog\"]';\n\n title(): string {\n return this.q('.mk-dialog__title')?.text() ?? this.host.attr('aria-label') ?? '';\n }\n\n bodyText(): string {\n return this.q('.mk-dialog__body')?.text() ?? this.host.text();\n }\n\n /** Texts of every button in the dialog (header close excluded). */\n buttons(): string[] {\n return this.buttonElements().map((b) => b.text());\n }\n\n /** Click a button by index, exact text or RegExp. */\n async clickButton(which: number | string | RegExp): Promise<void> {\n await pickBy(this.buttonElements(), which, (b) => b.text(), 'dialog button').click();\n }\n\n /** The header × button. */\n async close(): Promise<void> {\n const btn = this.q('.mk-dialog__close');\n if (!btn) throw new Error('Dialog has no close button (hideClose).');\n await btn.click();\n }\n\n async pressEscape(): Promise<void> {\n await this.host.sendKeys('Escape');\n }\n\n /** The prompt dialog's text field, if any. */\n input(): MkTestElement | null {\n return this.q('.mk-dialog__body input, .mk-dialog__body textarea');\n }\n\n private buttonElements(): MkTestElement[] {\n return this.qAll('button').filter(\n (b) => !b.hasClass('mk-dialog__close') && !b.hasClass('mk-dialog__grip') && !b.hasClass('mk-dialog__resizer'),\n );\n }\n}\n\n/** One toast shown by `MkToastService` (lives in `document.body` — use `loader.document()`). */\nexport class MkToastHarness extends MkHarness {\n static override readonly hostSelector = 'mk-toast';\n\n title(): string | null {\n return this.q('.mk-toast__title')?.text() ?? null;\n }\n\n message(): string {\n return this.q('.mk-toast__message')?.text() ?? '';\n }\n\n tone(): string | null {\n return this.host.attr('data-tone');\n }\n\n actionLabel(): string | null {\n return this.q('.mk-toast__actions button')?.text() ?? null;\n }\n\n async clickAction(): Promise<void> {\n const btn = this.q('.mk-toast__actions button');\n if (!btn) throw new Error('Toast has no action.');\n await btn.click();\n }\n\n async dismiss(): Promise<void> {\n const btn = this.q('.mk-toast__close');\n if (!btn) throw new Error('Toast is not dismissible.');\n await btn.click();\n }\n}\n","/**\n * `@mk-kit/ui/testing` — component test harnesses.\n *\n * Harnesses drive mk-kit components the way a user does (click the trigger,\n * pick the option, read the label) so specs stay stable when a component's\n * DOM changes. Zero dependencies beyond `@angular/core/testing`; works with\n * zoneless and zone-based TestBeds. Not re-exported from the root\n * `@mk-kit/ui` entry on purpose — it never belongs in an app bundle.\n */\nexport * from './harness';\nexport * from './harnesses/form-controls.harness';\nexport * from './harnesses/navigation.harness';\nexport * from './harnesses/table.harness';\nexport * from './harnesses/overlays.harness';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AAoCA,MAAM,KAAK,GAAG,YAA0B,EAAE,CAAC;AAE3C;;;;;AAKG;MACU,aAAa,CAAA;AAGb,IAAA,MAAA;AAEA,IAAA,MAAA;AAJX,IAAA,WAAA;;IAEW,MAAmB;;AAEnB,IAAA,MAAA,GAA8B,KAAK,EAAA;QAFnC,IAAA,CAAA,MAAM,GAAN,MAAM;QAEN,IAAA,CAAA,MAAM,GAAN,MAAM;IACd;;IAGH,IAAI,GAAA;AACF,QAAA,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE;IACpE;AAEA,IAAA,IAAI,CAAC,IAAY,EAAA;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC;IACvC;AAEA,IAAA,QAAQ,CAAC,IAAY,EAAA;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC7C;;AAGA,IAAA,IAAI,CAAc,IAAY,EAAA;AAC5B,QAAA,OAAQ,IAAI,CAAC,MAAuC,CAAC,IAAI,CAAC;IAC5D;AAEA,IAAA,OAAO,CAAC,QAAgB,EAAA;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;IACtC;IAEA,SAAS,GAAA;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,KAAK,IAAI,CAAC,MAAM;IAChE;;IAGA,UAAU,GAAA;AACR,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAA8C;AAC9D,QAAA,QACE,EAAE,CAAC,QAAQ,KAAK,IAAI;AACpB,YAAA,EAAE,CAAC,YAAY,CAAC,eAAe,CAAC,KAAK,MAAM;YAC3C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAElE;AAEA,IAAA,KAAK,CAAC,QAAgB,EAAA;QACpB,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAc,QAAQ,CAAC;AAC3D,QAAA,OAAO,EAAE,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI;IACvD;AAEA,IAAA,QAAQ,CAAC,QAAgB,EAAA;AACvB,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAc,QAAQ,CAAC,CAAC,CAAC,GAAG,CACxE,CAAC,EAAE,KAAK,IAAI,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAC3C;IACH;;AAGA,IAAA,KAAK,CAAC,QAAgB,EAAA;QACpB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;AAC/B,QAAA,IAAI,CAAC,EAAE;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,CAAA,UAAA,EAAa,QAAQ,CAAA,UAAA,EAAa,IAAI,CAAC,QAAQ,EAAE,CAAA,EAAA,CAAI,CAAC;AAC/E,QAAA,OAAO,EAAE;IACX;;AAGA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM;AACtB,QAAA,EAAE,CAAC,aAAa,CAAC,IAAI,YAAY,CAAC,aAAa,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;AACtF,QAAA,EAAE,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAClF,EAAE,CAAC,KAAK,EAAE;AACV,QAAA,EAAE,CAAC,aAAa,CAAC,IAAI,YAAY,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;AACpF,QAAA,EAAE,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAChF,EAAE,CAAC,KAAK,EAAE;AACV,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,KAAK,MAAM,IAAI,IAAI,CAAC,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE;YAC7E,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrF;AACA,QAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AACzE,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,KAAK,MAAM,IAAI,IAAI,CAAC,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE;YAC3E,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACpF;AACA,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AACzE,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;AAEA,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;QAClB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AACjD,QAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AACxE,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;AAEA;;;;AAIG;IACH,MAAM,IAAI,CAAC,IAAY,EAAA;AACrB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAA0B;QAC1C,EAAE,CAAC,KAAK,EAAE;AACV,QAAA,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE;YACrB,MAAM,IAAI,GAAG,IAAI,aAAa,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AACvF,YAAA,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC;AACtB,YAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC1B,IAAI,EAAE,CAAC,iBAAiB;AAAE,oBAAA,EAAE,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC,WAAW,IAAI,EAAE,IAAI,EAAE;;AACjE,oBAAA,EAAE,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,IAAI,EAAE;gBACrC,EAAE,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;YACjG;AACA,YAAA,EAAE,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E;AACA,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;;IAGA,MAAM,QAAQ,CAAC,KAAa,EAAA;AAC1B,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAA0B;QAC1C,EAAE,CAAC,KAAK,EAAE;AACV,QAAA,EAAE,CAAC,KAAK,GAAG,KAAK;AAChB,QAAA,EAAE,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAChG,QAAA,EAAE,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AACxD,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAA0B;QAC1C,EAAE,CAAC,KAAK,EAAE;AACV,QAAA,EAAE,CAAC,KAAK,GAAG,EAAE;AACb,QAAA,EAAE,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAChG,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;;AAGA,IAAA,MAAM,QAAQ,CAAC,GAAG,IAAsC,EAAA;AACtD,QAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACtB,YAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC;YAC1B,MAAM,IAAI,GAAG,IAAI,aAAa,CAAC,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AACvF,YAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACrF,gBAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAA0B;gBAC1C,IAAI,OAAO,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,EAAE,CAAC,iBAAiB,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE;AAC7F,oBAAA,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG;oBACpB,EAAE,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;gBACvG;YACF;YACA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACnF;AACA,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;;IAGA,MAAM,QAAQ,CAAC,KAAY,EAAA;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;AAChC,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IACrB;IAEQ,QAAQ,GAAA;AACd,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM;AACtB,QAAA,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAA,CAAA,EAAI,EAAE,CAAC,EAAE,CAAA,CAAE,GAAG,EAAE;AACnC,QAAA,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,CAAE,GAAG,EAAE;AAC3F,QAAA,OAAO,CAAA,EAAG,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA,EAAG,EAAE,CAAA,EAAG,GAAG,CAAA,CAAE;IACjD;AACD;AAED;AACA,SAAS,QAAQ,CAAC,GAAW,EAAA;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;IAC5B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,GAAG;IAC5B,MAAM,GAAG,GAAG,CAAC,CAAS,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACnE,OAAO;AACL,QAAA,GAAG,EAAE,CAAC;QACN,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC;QACtC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;AAClC,QAAA,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;AACtB,QAAA,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC;KACnB;AACH;AAEA,SAAS,WAAW,CAAC,EAAe,EAAA;IAClC,IAAI,EAAE,YAAY,mBAAmB;AAAE,QAAA,OAAO,IAAI;AAClD,IAAA,IAAI,EAAE,EAAE,YAAY,gBAAgB,CAAC;AAAE,QAAA,OAAO,KAAK;IACnD,OAAO,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;AACxG;AAEA;;;;;AAKG;MACU,eAAe,CAAA;AAEf,IAAA,IAAA;AACA,IAAA,MAAA;IAFX,WAAA,CACW,IAAa,EACb,MAA2B,EAAA;QAD3B,IAAA,CAAA,IAAI,GAAJ,IAAI;QACJ,IAAA,CAAA,MAAM,GAAN,MAAM;IACd;AAEH;;;;AAIG;IACH,OAAO,WAAW,CAAC,OAAkC,EAAA;AACnD,QAAA,MAAM,MAAM,GAAG,YAAW;YACxB,OAAO,CAAC,aAAa,EAAE;AACvB,YAAA,MAAM,OAAO,CAAC,UAAU,EAAE;YAC1B,OAAO,CAAC,aAAa,EAAE;AACzB,QAAA,CAAC;QACD,OAAO,IAAI,eAAe,CAAC,OAAO,CAAC,aAAwB,EAAE,MAAM,CAAC;IACtE;;IAGA,QAAQ,GAAA;AACN,QAAA,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IACvE;AAEA,IAAA,MAAM,CAAC,IAA6B,EAAA;QAClC,OAAO,IAAI,eAAe,CAAC,IAAI,YAAY,aAAa,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IAC7F;;IAGA,WAAW,GAAA;QACT,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,IAAmB,EAAE,IAAI,CAAC,MAAM,CAAC;IACjE;AAEA,IAAA,OAAO,CAAC,QAAgB,EAAA;AACtB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAc,QAAQ,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAI,IAAI,CAAC,IAAoB,GAAG,IAAI,CAAC;AAC9H,QAAA,IAAI,CAAC,EAAE;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,CAAA,oBAAA,EAAuB,QAAQ,YAAY,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA,EAAA,CAAI,CAAC;QACxG,OAAO,IAAI,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC;IAC3C;AAEA,IAAA,QAAQ,CAAC,QAAgB,EAAA;AACvB,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAc,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACtH;;AAGA,IAAA,MAAM,GAAG,CAAsB,IAAsB,EAAE,UAA4B,EAAE,EAAA;AACnF,QAAA,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;QAChD,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CACb,CAAA,GAAA,EAAM,IAAI,CAAC,IAAI,CAAA,cAAA,EAAiB,IAAI,CAAC,YAAY,CAAA,CAAA,EAAI,OAAO,CAAC,QAAQ,GAAG,CAAA,YAAA,EAAe,OAAO,CAAC,QAAQ,CAAA,CAAA,CAAG,GAAG,EAAE,CAAA,EAC7G,OAAO,CAAC,IAAI,GAAG,CAAA,OAAA,EAAU,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA,CAAE,GAAG,EACpD,CAAA,SAAA,EAAY,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA,EAAA,CAAI,CAChD;QACH;AACA,QAAA,OAAO,KAAK;IACd;AAEA,IAAA,MAAM,SAAS,CAAsB,IAAsB,EAAE,UAA4B,EAAE,EAAA;AACzF,QAAA,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;QAChD,OAAO,KAAK,IAAI,IAAI;IACtB;AAEA,IAAA,MAAM,GAAG,CAAsB,IAAsB,EAAE,UAA4B,EAAE,EAAA;AACnF,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC;IACtD;AAEA,IAAA,MAAM,MAAM,CAAsB,IAAsB,EAAE,UAA4B,EAAE,EAAA;AACtF,QAAA,MAAM,IAAI,CAAC,MAAM,EAAE;AACnB,QAAA,MAAM,KAAK,GAAG,IAAI,GAAG,EAAe;AACpC,QAAA,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;AAC/C,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE;AACvB,YAAA,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;AAAE,gBAAA,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAmB,CAAC;AAC/D,YAAA,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAc,GAAG,CAAC,CAAC;AAAE,gBAAA,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1F;QACA,MAAM,GAAG,GAAQ,EAAE;AACnB,QAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACxB,YAAA,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAAE;YACzD,MAAM,EAAE,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;AAC/C,YAAA,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC;gBAAE;YACvE,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC9B;;AAEA,QAAA,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,2BAA2B,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACtH,QAAA,OAAO,GAAG;IACZ;AACD;AAEK,SAAU,SAAS,CAAC,MAAc,EAAE,QAAyB,EAAA;AACjE,IAAA,OAAO,OAAO,QAAQ,KAAK,QAAQ,GAAG,MAAM,KAAK,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;AACnF;AAEA;;;;AAIG;MACmB,SAAS,CAAA;AAKlB,IAAA,IAAA;AACU,IAAA,MAAA;AALrB,IAAA,OAAgB,YAAY,GAAW,EAAE;AAEzC,IAAA,WAAA;;AAEW,IAAA,IAAmB,EACT,MAAuB,EAAA;QADjC,IAAA,CAAA,IAAI,GAAJ,IAAI;QACM,IAAA,CAAA,MAAM,GAAN,MAAM;IACxB;IAEO,MAAM,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;IAC7B;;AAGU,IAAA,CAAC,CAAC,QAAgB,EAAA;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAClC;AAEU,IAAA,IAAI,CAAC,QAAgB,EAAA;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACrC;;AAGU,IAAA,SAAS,CAAC,QAAgB,EAAA;AAClC,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAc,QAAQ,CAAC;AAC9E,QAAA,OAAO,EAAE,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI;IAC5D;;AAGU,IAAA,UAAU,CAAC,IAAmB,EAAE,SAAS,GAAG,eAAe,EAAA;QACnE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;AAC/B,QAAA,IAAI,CAAC,EAAE;AAAE,YAAA,OAAO,IAAI;AACpB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;AAC5D,QAAA,OAAO,EAAE,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI;IAC5D;;AAGF;AACM,SAAU,MAAM,CAAI,KAAU,EAAE,KAA+B,EAAE,KAA0B,EAAE,IAAY,EAAA;AAC7G,IAAA,MAAM,IAAI,GACR,OAAO,KAAK,KAAK;AACf,UAAE,KAAK,CAAC,KAAK;UACX,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACnD,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,IAAI,KAAK,CACb,CAAA,GAAA,EAAM,IAAI,CAAA,CAAA,EAAI,OAAO,KAAK,KAAK,QAAQ,GAAG,YAAY,KAAK,CAAA,CAAE,GAAG,CAAA,SAAA,EAAY,MAAM,CAAC,KAAK,CAAC,CAAA,CAAE,CAAA,aAAA,EAAgB;AACxG,aAAA,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,aAAA,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAA,CAAA,CAAG,CAC7B;IACH;AACA,IAAA,OAAO,IAAI;AACb;;ACpYA;AACM,MAAO,eAAgB,SAAQ,SAAS,CAAA;AAC5C,IAAA,OAAyB,YAAY,GAAG,2CAA2C;IAEnF,IAAI,GAAA;AACF,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;IACzB;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;IACzB;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;IACzB;IAEA,UAAU,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;IAC/B;IAEA,SAAS,GAAA;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IACjD;IAEA,IAAI,GAAA;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;IACpC;;IAGA,OAAO,GAAA;AACL,QAAA,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KACtD,8CAA8C,CAAC,IAAI,CAAC,CAAC,CAAC,CACvD;AACD,QAAA,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,GAAG,IAAI;IAChD;IAEA,IAAI,GAAA;AACF,QAAA,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/F,QAAA,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,GAAG,IAAI;IAChD;;AAGF;AACM,MAAO,cAAe,SAAQ,SAAS,CAAA;AAC3C,IAAA,OAAyB,YAAY,GAAG,sBAAsB;IAE9D,KAAK,GAAA;QACH,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAS,OAAO,CAAC,IAAI,EAAE;IAC9C;;IAGA,MAAM,QAAQ,CAAC,KAAa,EAAA;QAC1B,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IACjC;;IAGA,MAAM,IAAI,CAAC,IAAY,EAAA;QACrB,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5B;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;IACzB;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;IACzB;AAEA,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;IACxB;IAEA,WAAW,GAAA;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE;IAC5C;IAEA,KAAK,GAAA;AACH,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IAClG;IAEA,UAAU,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;IAC/B;IAEA,SAAS,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,MAAM;IAC7F;IAEA,UAAU,GAAA;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAU,UAAU,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,MAAM;IACnG;IAEA,SAAS,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;IAC9B;;AAGF;AACM,MAAO,iBAAkB,SAAQ,SAAS,CAAA;AAC9C,IAAA,OAAyB,YAAY,GAAG,aAAa;AAErD,IAAA,IAAY,KAAK,GAAA;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC;IAClD;IAEA,KAAK,GAAA;QACH,OAAO,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;IACnD;IAEA,SAAS,GAAA;QACP,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAU,SAAS,CAAC,KAAK,IAAI;IACrD;IAEA,eAAe,GAAA;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAU,eAAe,CAAC,KAAK,IAAI;IAC3D;IAEA,UAAU,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;IAChC;IAEA,UAAU,GAAA;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAU,UAAU,CAAC,KAAK,IAAI;IACtD;AAEA,IAAA,MAAM,MAAM,GAAA;AACV,QAAA,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;IAC1B;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;AAAE,YAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IAC5C;AAEA,IAAA,MAAM,OAAO,GAAA;QACX,IAAI,IAAI,CAAC,SAAS,EAAE;AAAE,YAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IAC3C;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;IAC1B;AAEA,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;IACzB;;AAGF;AACM,MAAO,eAAgB,SAAQ,SAAS,CAAA;AAC5C,IAAA,OAAyB,YAAY,GAAG,WAAW;AAEnD,IAAA,IAAY,OAAO,GAAA;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAC3C;IAEA,KAAK,GAAA;QACH,OAAO,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;IAClD;IAEA,SAAS,GAAA;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,MAAM;IACrD;IAEA,UAAU,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;IAClC;AAEA,IAAA,MAAM,MAAM,GAAA;AACV,QAAA,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;IAC5B;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;AAAE,YAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IAC5C;AAEA,IAAA,MAAM,OAAO,GAAA;QACX,IAAI,IAAI,CAAC,SAAS,EAAE;AAAE,YAAA,MAAM,IAAI,CAAC,MAAM,EAAE;IAC3C;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;IAC5B;;AAGF;AACM,MAAO,cAAe,SAAQ,SAAS,CAAA;AAC3C,IAAA,OAAyB,YAAY,GAAG,UAAU;IAElD,KAAK,GAAA;AACH,QAAA,OAAO,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;IAC/D;IAEA,SAAS,GAAA;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,MAAM;IAClD;IAEA,UAAU,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;IAC/B;AAEA,IAAA,MAAM,MAAM,GAAA;AACV,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;IACzB;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;IACzB;;AAGF;AACM,MAAO,mBAAoB,SAAQ,SAAS,CAAA;AAChD,IAAA,OAAyB,YAAY,GAAG,gBAAgB;IAExD,MAAM,GAAA;AACJ,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC;IAC7D;AAEA,IAAA,MAAM,MAAM,GAAA;QACV,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IACpD;;AAGA,IAAA,MAAM,YAAY,GAAA;QAChB,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,IAAI;IAC1E;AAEA,IAAA,MAAM,YAAY,GAAA;QAChB,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;IAC9D;;IAGA,MAAM,MAAM,CAAC,KAA+B,EAAA;AAC1C,QAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;QAClC,MAAM,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC,MAAM,EAAE;IACjE;IAEA,UAAU,GAAA;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IACvD;;AASF;AACM,MAAO,eAAgB,SAAQ,SAAS,CAAA;AAC5C,IAAA,OAAyB,YAAY,GAAG,WAAW;AAEnD,IAAA,IAAY,OAAO,GAAA;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC;IAC7C;;IAGA,SAAS,GAAA;QACP,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE;IAC1E;IAEA,WAAW,GAAA;QACT,OAAO,IAAI,CAAC,CAAC,CAAC,gCAAgC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;IAC/D;IAEA,MAAM,GAAA;QACJ,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,MAAM;IACtD;IAEA,UAAU,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;IAClC;IAEA,SAAS,GAAA;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,MAAM;IACrD;AAEA,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AAAE,YAAA,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;IAChD;AAEA,IAAA,MAAM,KAAK,GAAA;QACT,IAAI,IAAI,CAAC,MAAM,EAAE;YAAE,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACxD,IAAI,IAAI,CAAC,MAAM,EAAE;AAAE,YAAA,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;IAC/C;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;IAC5B;;AAGA,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE;QACvC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM;AACtB,YAAA,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE;YAChB,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,MAAM;YAC7C,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,MAAM;AAC9C,SAAA,CAAC,CAAC;IACL;;IAGA,MAAM,YAAY,CAAC,KAA+B,EAAA;AAChD,QAAA,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE;QACvC,MAAM,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC,KAAK,EAAE;IAC/D;AAEQ,IAAA,MAAM,cAAc,GAAA;AAC1B,QAAA,MAAM,IAAI,CAAC,IAAI,EAAE;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;AAC1C,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC;AAC7D,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACzC;;AAGF;AACM,MAAO,kBAAmB,SAAQ,SAAS,CAAA;AAC/C,IAAA,OAAyB,YAAY,GAAG,eAAe;IAEvD,KAAK,GAAA;QACH,OAAO,IAAI,CAAC,CAAC,CAAC,4BAA4B,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;IAC3D;IAEA,IAAI,GAAA;QACF,OAAO,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI;IACvD;;IAGA,KAAK,GAAA;QACH,OAAO,IAAI,CAAC,CAAC,CAAC,uBAAuB,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI;IACxD;IAEA,QAAQ,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI;IAC9B;IAEA,UAAU,GAAA;QACR,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC;IAC7C;;AAGA,IAAA,OAAO,CAAsB,IAA8C,EAAA;AACzE,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAChD;;;ACrVF;AACM,MAAO,aAAc,SAAQ,SAAS,CAAA;AAC1C,IAAA,OAAyB,YAAY,GAAG,SAAS;IAEzC,UAAU,GAAA;AAChB,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;IAClC;IAEA,MAAM,GAAA;AACJ,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C;IAEA,aAAa,GAAA;QACX,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,MAAM,CAAC;IAC/E;IAEA,aAAa,GAAA;AACX,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE;AAC9B,QAAA,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI;IACzC;;IAGA,MAAM,MAAM,CAAC,KAA+B,EAAA;QAC1C,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE;IACxE;AAEA,IAAA,UAAU,CAAC,KAA+B,EAAA;QACxC,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,UAAU,EAAE;IAC9E;;IAGA,aAAa,GAAA;AACX,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;AACnD,QAAA,OAAO,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,IAAI;IAC1C;;IAGA,iBAAiB,GAAA;QACf,OAAO,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAC3C;;AAGF;;;;AAIG;AACG,MAAO,aAAc,SAAQ,SAAS,CAAA;AAC1C,IAAA,OAAyB,YAAY,GAAG,wBAAwB;IAEhE,MAAM,GAAA;QACJ,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,MAAM;IACnD;AAEA,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AAAE,YAAA,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;IAC7C;AAEA,IAAA,MAAM,KAAK,GAAA;QACT,IAAI,IAAI,CAAC,MAAM,EAAE;YAAE,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;QACzD,IAAI,IAAI,CAAC,MAAM,EAAE;AAAE,YAAA,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;IAC5C;;IAGA,KAAK,GAAA;QACH,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;IACnC;;AAGA,IAAA,MAAM,KAAK,GAAA;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACzD;;IAGA,MAAM,SAAS,CAAC,KAA+B,EAAA;QAC7C,MAAM,MAAM,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC,KAAK,EAAE;IACtF;IAEA,MAAM,cAAc,CAAC,KAA+B,EAAA;QAClD,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC,UAAU,EAAE;IAC5F;AAEQ,IAAA,MAAM,YAAY,GAAA;AACxB,QAAA,MAAM,IAAI,CAAC,IAAI,EAAE;AACjB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;AAC1B,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC;AAC1D,QAAA,OAAO,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC;IAC5C;;;ACtFF;AACM,MAAO,iBAAkB,SAAQ,SAAS,CAAA;AAC9C,IAAA,OAAyB,YAAY,GAAG,kBAAkB;;IAG1D,KAAK,GAAA;AACH,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C;AAEA,IAAA,IAAI,CAAC,KAAa,EAAA;QAChB,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE;IAClC;IAEA,UAAU,GAAA;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IACtD;IAEA,UAAU,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,MAAM;IACpG;AAEA,IAAA,MAAM,KAAK,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;IACzB;;AAGA,IAAA,MAAM,cAAc,GAAA;QAClB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC;AACpG,QAAA,MAAM,EAAE,CAAC,MAAM,EAAE;IACnB;;AAGA,IAAA,MAAM,cAAc,GAAA;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,8BAA8B,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,uBAAuB,CAAC;AACzH,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC;AAClG,QAAA,MAAM,GAAG,CAAC,KAAK,EAAE;IACnB;IAEQ,SAAS,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,CACxC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAClF;IACH;;AAGF;AACM,MAAO,cAAe,SAAQ,SAAS,CAAA;AAC3C,IAAA,OAAyB,YAAY,GAAG,UAAU;;IAGlD,OAAO,GAAA;QACL,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/E;IAEA,IAAI,GAAA;AACF,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAChE;AAEA,IAAA,MAAM,QAAQ,GAAA;QACZ,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM;IACnC;;AAGA,IAAA,MAAM,SAAS,GAAA;QACb,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAClD;;IAGA,MAAM,MAAM,CAAC,KAA+B,EAAA;AAC1C,QAAA,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC;QACpG,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,sBAAsB,CAAC;AAC5C,QAAA,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,CAAA,QAAA,EAAW,EAAE,CAAC,IAAI,EAAE,CAAA,kBAAA,CAAoB,CAAC;AACnE,QAAA,MAAM,GAAG,CAAC,KAAK,EAAE;IACnB;;AAGA,IAAA,aAAa,CAAC,KAA+B,EAAA;AAC3C,QAAA,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;IACpH;AAEA,IAAA,MAAM,gBAAgB,GAAA;QACpB,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM;IACjE;;AAGA,IAAA,MAAM,SAAS,GAAA;QACb,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,uBAAuB,CAAC;AAC1C,QAAA,IAAI,CAAC,EAAE;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC;AACpD,QAAA,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE;IACtE;IAEA,OAAO,GAAA;AACL,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACpC;IAEQ,WAAW,GAAA;AACjB,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,CACxC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CACrF;IACH;;;ACpGF;;;;AAIG;AACG,MAAO,eAAgB,SAAQ,SAAS,CAAA;AAC5C,IAAA,OAAyB,YAAY,GAAG,yEAAyE;IAEjH,KAAK,GAAA;QACH,OAAO,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;IAClF;IAEA,QAAQ,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;IAC/D;;IAGA,OAAO,GAAA;AACL,QAAA,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD;;IAGA,MAAM,WAAW,CAAC,KAA+B,EAAA;QAC/C,MAAM,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC,KAAK,EAAE;IACtF;;AAGA,IAAA,MAAM,KAAK,GAAA;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC;AACvC,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC;AACpE,QAAA,MAAM,GAAG,CAAC,KAAK,EAAE;IACnB;AAEA,IAAA,MAAM,WAAW,GAAA;QACf,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACpC;;IAGA,KAAK,GAAA;AACH,QAAA,OAAO,IAAI,CAAC,CAAC,CAAC,mDAAmD,CAAC;IACpE;IAEQ,cAAc,GAAA;AACpB,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAC/B,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAC9G;IACH;;AAGF;AACM,MAAO,cAAe,SAAQ,SAAS,CAAA;AAC3C,IAAA,OAAyB,YAAY,GAAG,UAAU;IAElD,KAAK,GAAA;QACH,OAAO,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI;IACnD;IAEA,OAAO,GAAA;QACL,OAAO,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;IACnD;IAEA,IAAI,GAAA;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;IACpC;IAEA,WAAW,GAAA;QACT,OAAO,IAAI,CAAC,CAAC,CAAC,2BAA2B,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI;IAC5D;AAEA,IAAA,MAAM,WAAW,GAAA;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,2BAA2B,CAAC;AAC/C,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC;AACjD,QAAA,MAAM,GAAG,CAAC,KAAK,EAAE;IACnB;AAEA,IAAA,MAAM,OAAO,GAAA;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;AACtC,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC;AACtD,QAAA,MAAM,GAAG,CAAC,KAAK,EAAE;IACnB;;;ACjFF;;;;;;;;AAQG;;ACRH;;AAEG;;;;"}
|
package/fesm2022/mk-kit-ui.mjs
CHANGED
|
@@ -15,6 +15,9 @@ export * from '@mk-kit/ui/rich-text';
|
|
|
15
15
|
export * from '@mk-kit/ui/block-editor';
|
|
16
16
|
export * from '@mk-kit/ui/context-menu';
|
|
17
17
|
export * from '@mk-kit/ui/layout';
|
|
18
|
+
export * from '@mk-kit/ui/chat';
|
|
19
|
+
export * from '@mk-kit/ui/query-builder';
|
|
20
|
+
export * from '@mk-kit/ui/dynamic-form';
|
|
18
21
|
export * from '@mk-kit/ui/media';
|
|
19
22
|
|
|
20
23
|
/*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mk-kit-ui.mjs","sources":["../../../projects/mk-kit/src/public-api.ts","../../../projects/mk-kit/src/mk-kit-ui.ts"],"sourcesContent":["/*\n * Public API Surface of @mk-kit/ui.\n *\n * The library ships Material-style secondary entry points — import from the\n * group entries (`@mk-kit/ui/forms`, `@mk-kit/ui/table`, …) so a code-split\n * app only carries the groups each chunk uses. This root entry re-exports\n * everything for convenience; importing it eagerly pulls all groups into the\n * importing chunk.\n */\nexport * from '@mk-kit/ui/core';\nexport * from '@mk-kit/ui/icon';\nexport * from '@mk-kit/ui/chip';\nexport * from '@mk-kit/ui/checkbox';\nexport * from '@mk-kit/ui/button';\nexport * from '@mk-kit/ui/directives';\nexport * from '@mk-kit/ui/dnd';\nexport * from '@mk-kit/ui/navigation';\nexport * from '@mk-kit/ui/forms';\nexport * from '@mk-kit/ui/datetime';\nexport * from '@mk-kit/ui/table';\nexport * from '@mk-kit/ui/data';\nexport * from '@mk-kit/ui/feedback';\nexport * from '@mk-kit/ui/rich-text';\nexport * from '@mk-kit/ui/block-editor';\nexport * from '@mk-kit/ui/context-menu';\nexport * from '@mk-kit/ui/layout';\nexport * from '@mk-kit/ui/media';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mk-kit-ui.mjs","sources":["../../../projects/mk-kit/src/public-api.ts","../../../projects/mk-kit/src/mk-kit-ui.ts"],"sourcesContent":["/*\n * Public API Surface of @mk-kit/ui.\n *\n * The library ships Material-style secondary entry points — import from the\n * group entries (`@mk-kit/ui/forms`, `@mk-kit/ui/table`, …) so a code-split\n * app only carries the groups each chunk uses. This root entry re-exports\n * everything for convenience; importing it eagerly pulls all groups into the\n * importing chunk.\n */\nexport * from '@mk-kit/ui/core';\nexport * from '@mk-kit/ui/icon';\nexport * from '@mk-kit/ui/chip';\nexport * from '@mk-kit/ui/checkbox';\nexport * from '@mk-kit/ui/button';\nexport * from '@mk-kit/ui/directives';\nexport * from '@mk-kit/ui/dnd';\nexport * from '@mk-kit/ui/navigation';\nexport * from '@mk-kit/ui/forms';\nexport * from '@mk-kit/ui/datetime';\nexport * from '@mk-kit/ui/table';\nexport * from '@mk-kit/ui/data';\nexport * from '@mk-kit/ui/feedback';\nexport * from '@mk-kit/ui/rich-text';\nexport * from '@mk-kit/ui/block-editor';\nexport * from '@mk-kit/ui/context-menu';\nexport * from '@mk-kit/ui/layout';\nexport * from '@mk-kit/ui/chat';\nexport * from '@mk-kit/ui/query-builder';\nexport * from '@mk-kit/ui/dynamic-form';\nexport * from '@mk-kit/ui/media';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;AAQG;;ACRH;;AAEG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mk-kit/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -63,6 +63,10 @@
|
|
|
63
63
|
"types": "./types/mk-kit-ui-button.d.ts",
|
|
64
64
|
"default": "./fesm2022/mk-kit-ui-button.mjs"
|
|
65
65
|
},
|
|
66
|
+
"./chat": {
|
|
67
|
+
"types": "./types/mk-kit-ui-chat.d.ts",
|
|
68
|
+
"default": "./fesm2022/mk-kit-ui-chat.mjs"
|
|
69
|
+
},
|
|
66
70
|
"./checkbox": {
|
|
67
71
|
"types": "./types/mk-kit-ui-checkbox.d.ts",
|
|
68
72
|
"default": "./fesm2022/mk-kit-ui-checkbox.mjs"
|
|
@@ -95,6 +99,10 @@
|
|
|
95
99
|
"types": "./types/mk-kit-ui-dnd.d.ts",
|
|
96
100
|
"default": "./fesm2022/mk-kit-ui-dnd.mjs"
|
|
97
101
|
},
|
|
102
|
+
"./dynamic-form": {
|
|
103
|
+
"types": "./types/mk-kit-ui-dynamic-form.d.ts",
|
|
104
|
+
"default": "./fesm2022/mk-kit-ui-dynamic-form.mjs"
|
|
105
|
+
},
|
|
98
106
|
"./feedback": {
|
|
99
107
|
"types": "./types/mk-kit-ui-feedback.d.ts",
|
|
100
108
|
"default": "./fesm2022/mk-kit-ui-feedback.mjs"
|
|
@@ -119,6 +127,10 @@
|
|
|
119
127
|
"types": "./types/mk-kit-ui-navigation.d.ts",
|
|
120
128
|
"default": "./fesm2022/mk-kit-ui-navigation.mjs"
|
|
121
129
|
},
|
|
130
|
+
"./query-builder": {
|
|
131
|
+
"types": "./types/mk-kit-ui-query-builder.d.ts",
|
|
132
|
+
"default": "./fesm2022/mk-kit-ui-query-builder.mjs"
|
|
133
|
+
},
|
|
122
134
|
"./rich-text": {
|
|
123
135
|
"types": "./types/mk-kit-ui-rich-text.d.ts",
|
|
124
136
|
"default": "./fesm2022/mk-kit-ui-rich-text.mjs"
|
|
@@ -126,6 +138,10 @@
|
|
|
126
138
|
"./table": {
|
|
127
139
|
"types": "./types/mk-kit-ui-table.d.ts",
|
|
128
140
|
"default": "./fesm2022/mk-kit-ui-table.mjs"
|
|
141
|
+
},
|
|
142
|
+
"./testing": {
|
|
143
|
+
"types": "./types/mk-kit-ui-testing.d.ts",
|
|
144
|
+
"default": "./fesm2022/mk-kit-ui-testing.mjs"
|
|
129
145
|
}
|
|
130
146
|
},
|
|
131
147
|
"module": "fesm2022/mk-kit-ui.mjs",
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TemplateRef } from '@angular/core';
|
|
3
|
+
import * as _mk_kit_ui_core from '@mk-kit/ui/core';
|
|
4
|
+
|
|
5
|
+
/** Who a message comes from. `system` renders as a centred note. */
|
|
6
|
+
type MkChatRole = 'user' | 'assistant' | 'system';
|
|
7
|
+
/** Display identity of a message author. */
|
|
8
|
+
interface MkChatAuthor {
|
|
9
|
+
/** Shown beside the message and used for avatar initials. */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Avatar image URL; initials from `name` when omitted. */
|
|
12
|
+
avatar?: string;
|
|
13
|
+
}
|
|
14
|
+
/** A file shown with a message (an image when `type` is `image/*` and `url` is set). */
|
|
15
|
+
interface MkChatAttachment {
|
|
16
|
+
name: string;
|
|
17
|
+
/** MIME type, e.g. `image/png`. */
|
|
18
|
+
type?: string;
|
|
19
|
+
/** Size in bytes, shown formatted. */
|
|
20
|
+
size?: number;
|
|
21
|
+
/** Link / image source. */
|
|
22
|
+
url?: string;
|
|
23
|
+
}
|
|
24
|
+
/** Lifecycle of a tool / function call an assistant made while answering. */
|
|
25
|
+
type MkChatToolStatus = 'running' | 'done' | 'error';
|
|
26
|
+
/** A tool call card rendered above the message text. */
|
|
27
|
+
interface MkChatToolCall {
|
|
28
|
+
id?: string;
|
|
29
|
+
/** Tool name, e.g. `search_orders`. */
|
|
30
|
+
name: string;
|
|
31
|
+
status: MkChatToolStatus;
|
|
32
|
+
/** One-line human summary, e.g. `3 orders found`. */
|
|
33
|
+
summary?: string;
|
|
34
|
+
/** Raw input, shown under the disclosure. */
|
|
35
|
+
input?: string;
|
|
36
|
+
/** Raw output, shown under the disclosure. */
|
|
37
|
+
output?: string;
|
|
38
|
+
}
|
|
39
|
+
/** One message in the conversation. Replace the object (new reference) to update it. */
|
|
40
|
+
interface MkChatMessage {
|
|
41
|
+
id: string;
|
|
42
|
+
role: MkChatRole;
|
|
43
|
+
/** Message body — Markdown for assistants (when `markdown` is on), plain text otherwise. */
|
|
44
|
+
text: string;
|
|
45
|
+
author?: MkChatAuthor;
|
|
46
|
+
/** When it was sent; a `Date`, ISO string or epoch ms. */
|
|
47
|
+
timestamp?: Date | string | number;
|
|
48
|
+
/** Still receiving text: shows a cursor and keeps the log pinned to the bottom. */
|
|
49
|
+
streaming?: boolean;
|
|
50
|
+
/** Delivery / generation failed; shown under the bubble with a retry button. */
|
|
51
|
+
error?: string;
|
|
52
|
+
attachments?: MkChatAttachment[];
|
|
53
|
+
tools?: MkChatToolCall[];
|
|
54
|
+
}
|
|
55
|
+
/** Payload of the `send` output. */
|
|
56
|
+
interface MkChatSend {
|
|
57
|
+
text: string;
|
|
58
|
+
files: File[];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* PromptBox — the composer of a chat: an auto-growing textarea, attachments
|
|
63
|
+
* (button, drop, paste), quick-reply suggestions and a send button that turns
|
|
64
|
+
* into *stop* while a reply is being generated.
|
|
65
|
+
*
|
|
66
|
+
* Enter sends, Shift+Enter breaks the line (`sendOnEnter="false"` to swap).
|
|
67
|
+
*
|
|
68
|
+
* ```html
|
|
69
|
+
* <mk-prompt-box
|
|
70
|
+
* [(value)]="draft"
|
|
71
|
+
* [busy]="generating()"
|
|
72
|
+
* attachments
|
|
73
|
+
* [suggestions]="['Summarise this page', 'Draft a reply']"
|
|
74
|
+
* (send)="ask($event)"
|
|
75
|
+
* (stop)="abort()"
|
|
76
|
+
* />
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
declare class MkPromptBox {
|
|
80
|
+
protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
|
|
81
|
+
protected readonly id: string;
|
|
82
|
+
/** The draft text (two-way). */
|
|
83
|
+
readonly value: _angular_core.ModelSignal<string>;
|
|
84
|
+
/** Placeholder of the textarea. */
|
|
85
|
+
readonly placeholder: _angular_core.InputSignal<string>;
|
|
86
|
+
/** Disable everything (e.g. while offline). */
|
|
87
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
88
|
+
/** A reply is being generated: the send button becomes *stop*, sending is paused. */
|
|
89
|
+
readonly busy: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
90
|
+
/** Allow attaching files (button, drag & drop, paste). */
|
|
91
|
+
readonly attachments: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
92
|
+
/** Accepted file types for the picker (`accept` attribute syntax). */
|
|
93
|
+
readonly accept: _angular_core.InputSignal<string>;
|
|
94
|
+
/** Maximum number of attached files (0 = unlimited). */
|
|
95
|
+
readonly maxFiles: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
96
|
+
/** Maximum draft length; shows a counter when set. */
|
|
97
|
+
readonly maxLength: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
98
|
+
/** Minimum visible rows. */
|
|
99
|
+
readonly rows: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
100
|
+
/** Rows the textarea grows to before scrolling. */
|
|
101
|
+
readonly maxRows: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
102
|
+
/** Enter sends and Shift+Enter breaks the line (default); `false` swaps them. */
|
|
103
|
+
readonly sendOnEnter: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
104
|
+
/** Quick replies shown above the box; clicking one sends it. */
|
|
105
|
+
readonly suggestions: _angular_core.InputSignal<readonly string[]>;
|
|
106
|
+
/** Focus the textarea on render. */
|
|
107
|
+
readonly autofocus: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
108
|
+
/** The user submitted the draft (and any files). */
|
|
109
|
+
readonly send: _angular_core.OutputEmitterRef<MkChatSend>;
|
|
110
|
+
/** The user pressed *stop* while `busy`. */
|
|
111
|
+
readonly stop: _angular_core.OutputEmitterRef<void>;
|
|
112
|
+
/** Files waiting to be sent. */
|
|
113
|
+
readonly files: _angular_core.WritableSignal<File[]>;
|
|
114
|
+
protected readonly dragging: _angular_core.WritableSignal<boolean>;
|
|
115
|
+
private readonly textarea;
|
|
116
|
+
private readonly fileInput;
|
|
117
|
+
protected readonly canSend: _angular_core.Signal<boolean>;
|
|
118
|
+
protected readonly remaining: _angular_core.Signal<number | null>;
|
|
119
|
+
constructor();
|
|
120
|
+
/** Focus the textarea. */
|
|
121
|
+
focus(): void;
|
|
122
|
+
/** Empty the draft and the attachment list. */
|
|
123
|
+
clear(): void;
|
|
124
|
+
/** Submit the current draft (no-op when there is nothing to send or while busy). */
|
|
125
|
+
submit(): void;
|
|
126
|
+
/** Add files, honouring `maxFiles` and `accept`. */
|
|
127
|
+
addFiles(list: ArrayLike<File> | null | undefined): void;
|
|
128
|
+
removeFile(index: number): void;
|
|
129
|
+
protected onInput(event: Event): void;
|
|
130
|
+
protected onKeydown(event: KeyboardEvent): void;
|
|
131
|
+
protected onPaste(event: ClipboardEvent): void;
|
|
132
|
+
protected onDragOver(event: DragEvent): void;
|
|
133
|
+
protected onDrop(event: DragEvent): void;
|
|
134
|
+
protected openPicker(): void;
|
|
135
|
+
protected onFilesPicked(event: Event): void;
|
|
136
|
+
protected onSuggestion(text: string): void;
|
|
137
|
+
protected onPrimary(): void;
|
|
138
|
+
/** Human-readable size, e.g. `1.2 MB`. */
|
|
139
|
+
protected formatSize(bytes: number): string;
|
|
140
|
+
private accepts;
|
|
141
|
+
private autosize;
|
|
142
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkPromptBox, never>;
|
|
143
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkPromptBox, "mk-prompt-box", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "attachments": { "alias": "attachments"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "maxRows": { "alias": "maxRows"; "required": false; "isSignal": true; }; "sendOnEnter": { "alias": "sendOnEnter"; "required": false; "isSignal": true; }; "suggestions": { "alias": "suggestions"; "required": false; "isSignal": true; }; "autofocus": { "alias": "autofocus"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "send": "send"; "stop": "stop"; }, never, never, true, never>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* ChatMessage — one bubble: avatar, author and time, attachment previews,
|
|
148
|
+
* tool-call cards, the text (Markdown for assistants) with a streaming
|
|
149
|
+
* cursor, and copy / retry actions. `mk-chat` renders these for you; use it
|
|
150
|
+
* directly to build your own list.
|
|
151
|
+
*/
|
|
152
|
+
declare class MkChatMessageComponent {
|
|
153
|
+
protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
|
|
154
|
+
/** The message to render. */
|
|
155
|
+
readonly message: _angular_core.InputSignal<MkChatMessage>;
|
|
156
|
+
/** Render on the "own" (end) side — `mk-chat` sets this from `ownRole`. */
|
|
157
|
+
readonly own: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
158
|
+
/** Render `text` as Markdown (assistants only; user text is always plain). */
|
|
159
|
+
readonly markdown: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
160
|
+
readonly showAvatar: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
161
|
+
readonly showTimestamp: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
162
|
+
/** Offer a copy button on hover / focus. */
|
|
163
|
+
readonly copyable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
164
|
+
/** The retry button of a failed message was pressed. */
|
|
165
|
+
readonly retry: _angular_core.OutputEmitterRef<MkChatMessage>;
|
|
166
|
+
protected readonly authorName: _angular_core.Signal<string>;
|
|
167
|
+
protected readonly time: _angular_core.Signal<string>;
|
|
168
|
+
protected readonly ariaLabel: _angular_core.Signal<string | null>;
|
|
169
|
+
protected readonly useMarkdown: _angular_core.Signal<boolean>;
|
|
170
|
+
protected isImage(a: MkChatAttachment): boolean;
|
|
171
|
+
protected formatSize(bytes: number | undefined): string;
|
|
172
|
+
protected toolIcon(tool: MkChatToolCall): string;
|
|
173
|
+
protected toolStatus(tool: MkChatToolCall): string;
|
|
174
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkChatMessageComponent, never>;
|
|
175
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkChatMessageComponent, "mk-chat-message", never, { "message": { "alias": "message"; "required": true; "isSignal": true; }; "own": { "alias": "own"; "required": false; "isSignal": true; }; "markdown": { "alias": "markdown"; "required": false; "isSignal": true; }; "showAvatar": { "alias": "showAvatar"; "required": false; "isSignal": true; }; "showTimestamp": { "alias": "showTimestamp"; "required": false; "isSignal": true; }; "copyable": { "alias": "copyable"; "required": false; "isSignal": true; }; }, { "retry": "retry"; }, never, never, true, never>;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Context handed to an `*mkChatMessageDef` template. */
|
|
179
|
+
interface MkChatMessageContext {
|
|
180
|
+
$implicit: MkChatMessage;
|
|
181
|
+
own: boolean;
|
|
182
|
+
index: number;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Custom message rendering for `mk-chat`:
|
|
186
|
+
*
|
|
187
|
+
* ```html
|
|
188
|
+
* <mk-chat [messages]="messages()">
|
|
189
|
+
* <ng-template mkChatMessageDef let-message let-own="own">
|
|
190
|
+
* <my-bubble [message]="message" [mine]="own" />
|
|
191
|
+
* </ng-template>
|
|
192
|
+
* </mk-chat>
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
declare class MkChatMessageDef {
|
|
196
|
+
readonly template: TemplateRef<any>;
|
|
197
|
+
static ngTemplateContextGuard(_dir: MkChatMessageDef, ctx: unknown): ctx is MkChatMessageContext;
|
|
198
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkChatMessageDef, never>;
|
|
199
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MkChatMessageDef, "ng-template[mkChatMessageDef]", never, {}, {}, never, never, true, never>;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Chat — a conversation: a scrolling, screen-reader-announced log of
|
|
203
|
+
* `mk-chat-message` bubbles that stays pinned to the newest message while
|
|
204
|
+
* text streams in (with a *jump to latest* button once the reader scrolls
|
|
205
|
+
* up), a typing indicator, and an `mk-prompt-box` composer.
|
|
206
|
+
*
|
|
207
|
+
* The component is presentational: hand it `messages` (replace the array or
|
|
208
|
+
* a message object to update — signals compare by reference) and react to
|
|
209
|
+
* `(send)` / `(stop)` / `(retry)` with your own transport.
|
|
210
|
+
*
|
|
211
|
+
* ```html
|
|
212
|
+
* <mk-chat
|
|
213
|
+
* [messages]="messages()"
|
|
214
|
+
* [busy]="generating()"
|
|
215
|
+
* [typing]="peerTyping()"
|
|
216
|
+
* attachments
|
|
217
|
+
* [suggestions]="starters"
|
|
218
|
+
* (send)="ask($event)"
|
|
219
|
+
* (stop)="abort()"
|
|
220
|
+
* (retry)="resend($event)"
|
|
221
|
+
* style="height: 32rem"
|
|
222
|
+
* >
|
|
223
|
+
* <div mkChatHeader>…title, model picker…</div>
|
|
224
|
+
* <div mkChatEmpty>…first-run hint…</div>
|
|
225
|
+
* </mk-chat>
|
|
226
|
+
* ```
|
|
227
|
+
*
|
|
228
|
+
* Slots: `[mkChatHeader]`, `[mkChatEmpty]`, `[mkChatFooter]` (under the composer).
|
|
229
|
+
*/
|
|
230
|
+
declare class MkChat {
|
|
231
|
+
protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
|
|
232
|
+
/** The conversation, oldest first. */
|
|
233
|
+
readonly messages: _angular_core.InputSignal<readonly MkChatMessage[]>;
|
|
234
|
+
/** Which role renders on the "own" side (default `user`). */
|
|
235
|
+
readonly ownRole: _angular_core.InputSignal<MkChatRole>;
|
|
236
|
+
/** Render assistant text as Markdown. */
|
|
237
|
+
readonly markdown: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
238
|
+
readonly showAvatars: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
239
|
+
readonly showTimestamps: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
240
|
+
/** Someone else is typing (shows the dots indicator). */
|
|
241
|
+
readonly typing: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
242
|
+
/** A reply is being generated: composer shows *stop*. */
|
|
243
|
+
readonly busy: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
244
|
+
/** Disable the composer. */
|
|
245
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
246
|
+
/** Hide the composer entirely (read-only transcript). */
|
|
247
|
+
readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
248
|
+
readonly placeholder: _angular_core.InputSignal<string | undefined>;
|
|
249
|
+
/** Allow attachments in the composer. */
|
|
250
|
+
readonly attachments: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
251
|
+
readonly accept: _angular_core.InputSignal<string>;
|
|
252
|
+
readonly maxFiles: _angular_core.InputSignal<number>;
|
|
253
|
+
readonly maxLength: _angular_core.InputSignal<number>;
|
|
254
|
+
/** Quick replies above the composer; each click sends its text. */
|
|
255
|
+
readonly suggestions: _angular_core.InputSignal<readonly string[]>;
|
|
256
|
+
/** Text shown when there are no messages (or project `[mkChatEmpty]`). */
|
|
257
|
+
readonly emptyMessage: _angular_core.InputSignal<string | undefined>;
|
|
258
|
+
/** Keep the log pinned to the newest message while the reader is at the bottom. */
|
|
259
|
+
readonly autoScroll: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
260
|
+
/** Accessible name of the log region. */
|
|
261
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
262
|
+
readonly send: _angular_core.OutputEmitterRef<MkChatSend>;
|
|
263
|
+
readonly stop: _angular_core.OutputEmitterRef<void>;
|
|
264
|
+
readonly retry: _angular_core.OutputEmitterRef<MkChatMessage>;
|
|
265
|
+
protected readonly messageDef: _angular_core.Signal<MkChatMessageDef | undefined>;
|
|
266
|
+
private readonly log;
|
|
267
|
+
private readonly composer;
|
|
268
|
+
/** The reader is (near) the bottom of the log. */
|
|
269
|
+
protected readonly atBottom: _angular_core.WritableSignal<boolean>;
|
|
270
|
+
/** Messages that arrived while scrolled up. */
|
|
271
|
+
protected readonly unseen: _angular_core.WritableSignal<number>;
|
|
272
|
+
private lastCount;
|
|
273
|
+
protected readonly resolvedEmpty: _angular_core.Signal<string>;
|
|
274
|
+
protected readonly resolvedPlaceholder: _angular_core.Signal<string>;
|
|
275
|
+
constructor();
|
|
276
|
+
/** Scroll the log to the newest message. */
|
|
277
|
+
scrollToBottom(): void;
|
|
278
|
+
/** Focus the composer. */
|
|
279
|
+
focus(): void;
|
|
280
|
+
protected onScroll(): void;
|
|
281
|
+
protected isOwn(m: MkChatMessage): boolean;
|
|
282
|
+
protected trackMessage: (_: number, m: MkChatMessage) => string;
|
|
283
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkChat, never>;
|
|
284
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkChat, "mk-chat", never, { "messages": { "alias": "messages"; "required": false; "isSignal": true; }; "ownRole": { "alias": "ownRole"; "required": false; "isSignal": true; }; "markdown": { "alias": "markdown"; "required": false; "isSignal": true; }; "showAvatars": { "alias": "showAvatars"; "required": false; "isSignal": true; }; "showTimestamps": { "alias": "showTimestamps"; "required": false; "isSignal": true; }; "typing": { "alias": "typing"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "attachments": { "alias": "attachments"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "suggestions": { "alias": "suggestions"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "autoScroll": { "alias": "autoScroll"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "send": "send"; "stop": "stop"; "retry": "retry"; }, ["messageDef"], ["[mkChatHeader]", "[mkChatEmpty]", "[mkChatFooter]"], true, never>;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export { MkChat, MkChatMessageComponent, MkChatMessageDef, MkPromptBox };
|
|
288
|
+
export type { MkChatAttachment, MkChatAuthor, MkChatMessage, MkChatMessageContext, MkChatRole, MkChatSend, MkChatToolCall, MkChatToolStatus };
|