ngx-dynamic-entity 1.7.0 → 1.8.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-dynamic-entity.mjs","sources":["../../src/lib/services/entity-ref-cache.ts","../../src/lib/tokens/injection-tokens.ts","../../src/lib/providers/provide-ngx-dynamic-entity.ts","../../src/lib/services/validation-messages.service.ts","../../src/lib/field-types/text-field.component.ts","../../src/lib/field-types/textarea-field.component.ts","../../src/lib/field-types/markdown-field.component.ts","../../src/lib/field-types/number-field.component.ts","../../src/lib/field-types/currency-field.component.ts","../../src/lib/field-types/email-field.component.ts","../../src/lib/field-types/password-field.component.ts","../../src/lib/field-types/checkbox-field.component.ts","../../src/lib/field-types/boolean-field.component.ts","../../src/lib/field-types/date-field.component.ts","../../src/lib/field-types/date-time-field.component.ts","../../src/lib/field-types/time-field.component.ts","../../src/lib/field-types/month-year-field.component.ts","../../src/lib/services/lookup-registry.service.ts","../../src/lib/field-types/dropdown-field.component.ts","../../src/lib/field-types/radio-field.component.ts","../../src/lib/field-types/multi-select-field.component.ts","../../src/lib/services/entity-ref-registry.service.ts","../../src/lib/services/entity-reference.service.ts","../../src/lib/services/cascade-data.service.ts","../../src/lib/services/entity-ref-selection.service.ts","../../src/lib/field-types/entity-ref-field.component.ts","../../src/lib/services/field-registry.service.ts","../../src/lib/services/rbac.service.ts","../../src/lib/form/dynamic-field/dynamic-field.component.ts","../../src/lib/field-types/group-field.component.ts","../../src/lib/services/validator-registry.service.ts","../../src/lib/field-types/array-field.component.ts","../../src/lib/services/file-upload.service.ts","../../src/lib/field-types/image-field.component.ts","../../src/lib/field-types/file-field.component.ts","../../src/lib/providers/provide-field-types.ts","../../src/lib/services/hook-registry.service.ts","../../src/lib/services/rules-evaluation.service.ts","../../src/lib/services/config-source.service.ts","../../src/lib/form/dynamic-form.component.ts","../../src/lib/form/dynamic-form.component.html","../../src/lib/form/dynamic-record-form.component.ts","../../src/lib/form/dynamic-record-form.component.html","../../src/public-api.ts","../../src/ngx-dynamic-entity.ts"],"sourcesContent":["import type { ReferenceOption } from '@dynamic-entity/core';\n\n/**\n * Backing store for cached reference options.\n *\n * Pluggable on purpose. The reference implementation kept its cache in a service instance,\n * so every entity label was re-fetched on a browser refresh (issue #22 in the architecture\n * doc). A consumer that wants the cache to survive a reload can back this with\n * sessionStorage; the default keeps it in memory, which is the right call for a library\n * that must not silently persist a tenant's data.\n */\nexport interface EntityRefCacheStore {\n get(key: string): ReferenceOption[] | undefined;\n set(key: string, value: ReferenceOption[]): void;\n delete(key: string): void;\n /** Every key currently held — used for prefix invalidation of one entity. */\n keys(): string[];\n clear(): void;\n}\n\n/** Default in-memory store. Lives as long as the injector that created it. */\nexport class InMemoryEntityRefCacheStore implements EntityRefCacheStore {\n private readonly map = new Map<string, ReferenceOption[]>();\n\n get(key: string): ReferenceOption[] | undefined {\n return this.map.get(key);\n }\n\n set(key: string, value: ReferenceOption[]): void {\n this.map.set(key, value);\n }\n\n delete(key: string): void {\n this.map.delete(key);\n }\n\n keys(): string[] {\n return [...this.map.keys()];\n }\n\n clear(): void {\n this.map.clear();\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport type { Type } from '@angular/core';\nimport type {\n CommonModuleEntry,\n EntityReferenceLoader,\n FileUploadHandler,\n LookupListSource,\n RecordMigration,\n} from '@dynamic-entity/core';\nimport { InMemoryEntityRefCacheStore, type EntityRefCacheStore } from '../services/entity-ref-cache';\n\n/** Roles that see XXXXXXXXX for masked fields. Presentational only — enforce authz server-side. */\nexport const MASKED_ROLES = new InjectionToken<string[]>('MASKED_ROLES');\n\n/**\n * Consumer **overrides**: fieldType string → Angular component class.\n * Highest priority — beats anything registered through `provideFieldTypes()`.\n */\nexport const FIELD_TYPE_REGISTRY = new InjectionToken<Map<string, Type<any>>>('FIELD_TYPE_REGISTRY');\n\n/**\n * Multi-provider of field-type sets, contributed by `provideFieldTypes()` /\n * `provideBuiltInFieldTypes()`. Multi so several calls compose instead of clobbering;\n * later sets win on key collision. This is the seam that keeps unused field components\n * out of the bundle — nothing is imported until a set names it.\n */\nexport const FIELD_TYPE_SETS = new InjectionToken<Record<string, Type<any>>[]>('FIELD_TYPE_SETS');\n\n/**\n * Registry: entity key → option loader.\n *\n * A loader receives a `ReferenceLoaderContext` (`parentValue`, `filters`, `lang`) and may\n * return an array, a Promise, or an Observable of `ReferenceOption[]`. `ctx` is optional,\n * so a zero-arg loader (`() => svc.list()`) is still a valid registration.\n */\nexport const ENTITY_REF_REGISTRY = new InjectionToken<Map<string, EntityReferenceLoader>>(\n 'ENTITY_REF_REGISTRY',\n);\n\n/**\n * Registry: list name → the values of a named master list (`field.listName`).\n *\n * A source may be the values themselves (array / Promise / Observable) or a **loader function**,\n * which is what you want for anything fetched: a bare Promise is created when the provider is\n * built, so every list would load whether or not a form uses it.\n *\n * Values are normalised by `normalizeLookupValues` — bare strings and `LocalizedText` are\n * accepted alongside the full `{ code, name, sortOrder }` shape.\n *\n * @example\n * provideNgxDynamicEntity({\n * lookups: {\n * employeeStatus: () => listService.getByName('employeeStatus'),\n * grades: ['Junior', 'Senior'],\n * },\n * })\n */\nexport const LOOKUP_REGISTRY = new InjectionToken<Map<string, LookupListSource>>('LOOKUP_REGISTRY');\n\n/**\n * Ordered steps that move a saved record forward when a config's `version` increases.\n *\n * Without these, `EntityFormConfig.version` and `VersionedRecord._configVersion` are\n * declarations nothing acts on: a schema can be edited freely while records keep their old\n * shape, and nothing reconciles the two. Registering migrations makes the version numbers\n * mean something.\n *\n * @example\n * provideNgxDynamicEntity({\n * migrations: [\n * { from: 1, to: 2, description: 'split name', migrate: r => ({ ...r, firstName: r['name'] }) },\n * ],\n * })\n */\nexport const RECORD_MIGRATIONS = new InjectionToken<RecordMigration[]>('RECORD_MIGRATIONS');\n\n/**\n * Overrides for the messages shown under an invalid field, keyed by Angular error key\n * (`required`, `minlength`, `pattern`, …) plus a few field-specific keys.\n *\n * The built-in messages are English literals. Registering here is what makes a non-English\n * form possible without re-implementing every field component; unlisted keys keep their\n * default, so overriding one does not mean supplying them all.\n */\nexport const VALIDATION_MESSAGES = new InjectionToken<Record<string, any>>('VALIDATION_MESSAGES');\n\n/** Registry: validator key → ValidatorFn */\nexport const VALIDATOR_REGISTRY = new InjectionToken<Map<string, any>>('VALIDATOR_REGISTRY');\n\n/**\n * Registry: validator key → AsyncValidatorFn.\n *\n * Kept separate from VALIDATOR_REGISTRY because Angular applies the two differently: an async\n * validator runs only once the synchronous ones pass, and puts the control into `pending`\n * while it does. Name them from a schema with `validators: { customAsync: ['uniqueEmail'] }`.\n */\nexport const ASYNC_VALIDATOR_REGISTRY = new InjectionToken<Map<string, any>>(\n 'ASYNC_VALIDATOR_REGISTRY',\n);\n\n/**\n * A registered hook: receives the payload, returns it (or a replacement), sync or async.\n *\n * Spelled out rather than typed as `Function`, which accepts class declarations and any\n * arity and gives a consumer no signature to write against.\n */\nexport type HookFn = (data: any, context?: unknown) => unknown | Promise<unknown>;\n\n/** Registry: hook key → async (data, context) => data */\nexport const HOOK_REGISTRY = new InjectionToken<Map<string, HookFn>>('HOOK_REGISTRY');\n\n/**\n * Consumer-registered list of common module tabs (documents, audit, tasks, etc.).\n * The library ships no built-in implementations. Consumers provide their own list\n * so the builder's module-picker and the renderer's tab switcher know what's available.\n *\n * @example\n * providers: [\n * {\n * provide: COMMON_MODULES_REGISTRY,\n * useValue: [\n * { id: 'documents', label: { en: 'Documents' }, component: 'app-documents-view' },\n * { id: 'audit', label: { en: 'Audit Log' }, component: 'app-audit' },\n * ] satisfies CommonModuleEntry[]\n * }\n * ]\n */\nexport const COMMON_MODULES_REGISTRY = new InjectionToken<CommonModuleEntry[]>(\n 'COMMON_MODULES_REGISTRY',\n);\n\n/**\n * Consumer-provided file/image upload handler.\n * When supplied, image-field and file-field call it to persist the File and receive a stable\n * URL back. Without it the field stores `{ file, name, size, mimeType }` for the consumer to\n * upload on submit. May return the result directly, as a Promise, or as an Observable.\n *\n * @example\n * { provide: UPLOAD_HANDLER, useFactory: () => (file: File) => myUploadService.upload(file) }\n */\nexport const UPLOAD_HANDLER = new InjectionToken<FileUploadHandler>('UPLOAD_HANDLER');\n\n/**\n * Backing store for the entity-reference options cache. Defaults to in-memory.\n * Provide your own to make the cache outlive a page refresh.\n *\n * @example\n * { provide: ENTITY_REF_CACHE_STORE, useClass: SessionStorageRefCache }\n */\nexport const ENTITY_REF_CACHE_STORE = new InjectionToken<EntityRefCacheStore>(\n 'ENTITY_REF_CACHE_STORE',\n { providedIn: 'root', factory: () => new InMemoryEntityRefCacheStore() },\n);\n\n/**\n * Consumer-provided predicate function to check whether user roles can edit system default tabs or fields.\n * Defaults to allowing edits if not provided.\n */\nexport const SYSTEM_DEFAULT_CAN_EDIT = new InjectionToken<(roles: string[]) => boolean>(\n 'SYSTEM_DEFAULT_CAN_EDIT',\n);\n\nexport type ConfigSourceHandler = (\n entityKey: string,\n) => any;\n\n/**\n * Registry/Resolver for resolving an EntityFormConfig by entity key across entities (Phase 8).\n * Enables cross-entity field referencing (`isReferenced`, `referencedEntityKey`, `referencedFieldId`, `hasDrift`).\n */\nexport const CONFIG_SOURCE = new InjectionToken<ConfigSourceHandler>('CONFIG_SOURCE');\n\n\n\n/**\n * Turns the markdown a `markdown` field stores into HTML for display.\n *\n * Optional, and deliberately not bundled: these packages declare no runtime dependencies\n * beyond `tslib`, and a markdown parser is a large one to force on every consumer. Without\n * a renderer the field still works — it stores and shows the source text, with line breaks\n * preserved and nothing interpreted.\n *\n * The returned HTML is bound through `[innerHTML]`, so Angular's sanitizer strips scripts\n * and event handlers before it reaches the DOM. That is a backstop, not a licence: a\n * renderer should still be configured to escape raw HTML in its input, because sanitizing\n * removes the dangerous parts silently rather than telling the author their content was\n * altered.\n *\n * @example\n * import { marked } from 'marked';\n * { provide: MARKDOWN_RENDERER, useValue: (src: string) => marked.parse(src) as string }\n */\nexport const MARKDOWN_RENDERER = new InjectionToken<(source: string) => string>(\n 'MARKDOWN_RENDERER',\n);\n","import { EnvironmentProviders, makeEnvironmentProviders, Type } from '@angular/core';\nimport type { EntityReferenceLoader, LookupListSource, RecordMigration } from '@dynamic-entity/core';\nimport {\n ENTITY_REF_REGISTRY,\n FIELD_TYPE_REGISTRY,\n HOOK_REGISTRY,\n type HookFn,\n ASYNC_VALIDATOR_REGISTRY,\n RECORD_MIGRATIONS,\n VALIDATION_MESSAGES,\n LOOKUP_REGISTRY,\n MASKED_ROLES,\n VALIDATOR_REGISTRY,\n} from '../tokens/injection-tokens';\n\nexport interface NgxDynamicEntityConfig {\n /** Roles that see masked field values as XXXXXXXXX */\n maskedRoles?: string[];\n /** Custom field type components keyed by type string */\n fieldTypes?: Record<string, Type<any>>;\n /**\n * Entity-ref option loaders keyed by entity key.\n * Each receives `{ parentValue, filters, lang }` and may return an array, Promise, or Observable.\n */\n entityRefs?: Record<string, EntityReferenceLoader>;\n /**\n * Named master lists keyed by list name, for fields that set `listName`.\n * Each may be the values themselves (array/Promise/Observable) or a loader function — prefer\n * a loader for anything fetched, so an unused list is never loaded.\n */\n lookups?: Record<string, LookupListSource>;\n /**\n * Override the messages shown under invalid fields, keyed by Angular error key. A value is\n * a string, or a function receiving `(language, error)` when it needs the error's detail.\n * Unlisted keys keep their English default.\n */\n validationMessages?: Record<string, string | ((language: string, error: any) => string)>;\n /**\n * Async validator functions keyed by name, for checks that need a server — uniqueness,\n * availability, a remote rule. Name them from a schema with\n * `validators: { customAsync: ['uniqueEmail'] }`.\n *\n * Each is an Angular `AsyncValidatorFn`: it receives the control and returns a Promise or\n * Observable of `ValidationErrors | null`. The control is `pending` while it runs, and the\n * form cannot be submitted until every pending check settles.\n */\n asyncValidators?: Record<string, any>;\n /** Custom validator functions keyed by validator name */\n validators?: Record<string, any>;\n /** Hook functions keyed by hook name */\n hooks?: Record<string, HookFn>;\n /**\n * Ordered steps that upgrade a saved record when `EntityFormConfig.version` moves ahead\n * of the record's `_configVersion`. Applied to `initialData` before the form is patched.\n */\n migrations?: RecordMigration[];\n}\n\n/**\n * Provider function for ngx-dynamic-entity.\n * All options are optional — consumers provide only what they use (ISP).\n *\n * Usage in app.config.ts:\n * provideNgxDynamicEntity({\n * maskedRoles: ['IT_SUPPORT'],\n * entityRefs: { clients: () => clientService.getOptions() },\n * })\n */\nexport const provideNgxDynamicEntity = (config: NgxDynamicEntityConfig = {}): EnvironmentProviders =>\n makeEnvironmentProviders([\n { provide: MASKED_ROLES, useValue: config.maskedRoles ?? [] },\n { provide: FIELD_TYPE_REGISTRY, useValue: new Map(Object.entries(config.fieldTypes ?? {})) },\n { provide: ENTITY_REF_REGISTRY, useValue: new Map(Object.entries(config.entityRefs ?? {})) },\n { provide: LOOKUP_REGISTRY, useValue: new Map(Object.entries(config.lookups ?? {})) },\n { provide: VALIDATOR_REGISTRY, useValue: new Map(Object.entries(config.validators ?? {})) },\n {\n provide: ASYNC_VALIDATOR_REGISTRY,\n useValue: new Map(Object.entries(config.asyncValidators ?? {})),\n },\n { provide: HOOK_REGISTRY, useValue: new Map(Object.entries(config.hooks ?? {})) },\n { provide: RECORD_MIGRATIONS, useValue: config.migrations ?? [] },\n { provide: VALIDATION_MESSAGES, useValue: config.validationMessages ?? {} },\n ]);\n","import { Injectable, inject } from '@angular/core';\nimport type { ValidationErrors } from '@angular/forms';\nimport { VALIDATION_MESSAGES } from '../tokens/injection-tokens';\n\n/**\n * Resolves an Angular `ValidationErrors` object to the message shown under a field.\n *\n * These strings used to be hardcoded English literals inside each field component, so a\n * German form meant re-implementing every field type — the labels honoured `language` while\n * the errors underneath them did not.\n *\n * A message is a plain string, or a function when it needs the error's own detail\n * (`minlength.requiredLength`, `min.min`, and so on). The active `language` is passed\n * through, so one registration can serve every locale:\n *\n * ```typescript\n * provideNgxDynamicEntity({\n * validationMessages: {\n * required: lang => (lang === 'de' ? 'Pflichtfeld.' : 'This field is required.'),\n * minlength: (lang, err) => `Mindestens ${err['requiredLength']} Zeichen.`,\n * },\n * });\n * ```\n *\n * Unregistered keys fall back to the defaults below, so overriding one message does not\n * mean supplying them all.\n */\nexport type ValidationMessage = string | ((language: string, error: any) => string);\n\n/** The built-in English messages. Every key here can be overridden individually. */\nexport const DEFAULT_VALIDATION_MESSAGES: Record<string, ValidationMessage> = {\n required: 'This field is required.',\n requiredSelection: 'Please select an option.',\n email: 'Please enter a valid email address.',\n pattern: 'Invalid format.',\n minlength: (_lang, err) => `Minimum ${err?.requiredLength} characters required.`,\n maxlength: (_lang, err) => `Maximum ${err?.requiredLength} characters allowed.`,\n min: (_lang, err) => `Value must be at least ${err?.min}.`,\n max: (_lang, err) => `Value must not exceed ${err?.max}.`,\n invalid: 'Invalid value.',\n invalidNumber: 'Invalid number.',\n invalidSelection: 'Invalid selection.',\n};\n\n@Injectable({ providedIn: 'root' })\nexport class ValidationMessagesService {\n private readonly overrides = inject(VALIDATION_MESSAGES, { optional: true }) ?? {};\n\n /**\n * The message for the first error present, in the order the caller lists.\n *\n * Order is the caller's because it is field-specific: a dropdown wants\n * `requiredSelection` where a text input wants `required`, and the first match wins so the\n * most specific message is the one shown.\n */\n resolve(\n errors: ValidationErrors | null | undefined,\n language: string,\n order: readonly (string | readonly [errorKey: string, messageKey: string])[],\n fallbackKey = 'invalid',\n ): string {\n if (!errors) return '';\n\n for (const entry of order) {\n // A tuple maps an Angular error key to a different message key: a dropdown raises the\n // standard `required` error but reads better as \"Please select an option\", and both\n // messages stay independently overridable.\n const [errorKey, messageKey] = typeof entry === 'string' ? [entry, entry] : entry;\n // `errors[errorKey]` is usually an object of detail, but `required` is simply `true`.\n if (errors[errorKey] === undefined) continue;\n return this.messageFor(messageKey, language, errors[errorKey]);\n }\n return this.messageFor(fallbackKey, language, null);\n }\n\n /** One message by key, honouring an override before the default. */\n messageFor(key: string, language: string, error: unknown): string {\n const message = this.overrides[key] ?? DEFAULT_VALIDATION_MESSAGES[key];\n if (message === undefined) return '';\n return typeof message === 'function' ? message(language, error) : message;\n }\n}\n","import { Component, Input, OnDestroy, inject, ChangeDetectionStrategy, signal } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { ValidationMessagesService } from '../services/validation-messages.service';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-text-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div\n class=\"ngx-field ngx-field--text\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\"\n [class.ngx-field--readonly]=\"readonly\"\n [class.ngx-field--masked]=\"masked\"\n [class.ngx-field--invalid]=\"control && control.invalid && control.touched\"\n >\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}@if (field.validators?.required) { <span class=\"ngx-field__req\">*</span> }</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ displayValue() ?? '—' }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n type=\"text\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder\"\n [attr.disabled]=\"field.disabled ? true : null\"\n [attr.aria-invalid]=\"control.invalid && control.touched\"\n [attr.aria-describedby]=\"errorMessage ? field.id + '-error' : null\"\n />\n @if (errorMessage) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\" [id]=\"field.id + '-error'\" role=\"alert\">{{ errorMessage }}</span>\n }\n }\n </div>\n `,\n})\nexport class TextFieldComponent implements OnDestroy {\n private readonly messages = inject(ValidationMessagesService);\n private displaySub?: Subscription;\n\n @Input() field!: NestedFieldConfig;\n @Input()\n set control(value: AbstractControl) {\n this._control = value;\n this.displaySub?.unsubscribe();\n this.displayValue.set(value?.value ?? null);\n this.displaySub = value?.valueChanges.subscribe(v => this.displayValue.set(v));\n }\n get control(): AbstractControl {\n return this._control;\n }\n private _control!: AbstractControl;\n\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Readonly markup reads this signal so an external patch (autoPatch) is visible under OnPush. */\n readonly displayValue = signal<unknown>(null);\n\n ngOnDestroy(): void {\n this.displaySub?.unsubscribe();\n }\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n get errorMessage(): string {\n if (!this.control || !this.control.errors || !this.control.touched) return '';\n return this.messages.resolve(\n this.control.errors,\n this.language,\n ['required', 'email', 'minlength', 'maxlength', 'pattern'],\n );\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-textarea-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--textarea\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value }}</span>\n } @else {\n <textarea\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder\"\n [attr.disabled]=\"field.disabled ? true : null\"\n rows=\"3\"\n ></textarea>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class TextareaFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n}\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n DestroyRef,\n Input,\n OnChanges,\n SimpleChanges,\n inject,\n signal,\n} from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { MARKDOWN_RENDERER } from '../tokens/injection-tokens';\n\n/**\n * Markdown field: a long-form input that stores **markdown source**, never HTML.\n *\n * Storing the source rather than rendered HTML is the whole design. The record stays plain\n * text — diffable, portable, safe to log, and impossible to turn into stored XSS by writing\n * it into a database. Rendering happens at display time and only when a consumer asks for\n * it, via `MARKDOWN_RENDERER`.\n *\n * Without a renderer this degrades to exactly what `textarea` does, plus preserved line\n * breaks: the source is shown as text with nothing interpreted. That is the default because\n * these packages declare no runtime dependencies beyond `tslib`, and a markdown parser is a\n * large thing to force on a consumer who wanted a form library.\n *\n * With a renderer, its HTML is bound through `[innerHTML]`, which Angular sanitizes — see\n * the token's own note on why that is a backstop rather than a licence.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-markdown-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div\n class=\"ngx-field ngx-field--markdown\"\n [attr.data-testid]=\"'field-' + field.id\"\n [attr.data-field-type]=\"field.type\"\n [class.ngx-field--readonly]=\"readonly\"\n [class.ngx-field--masked]=\"masked\"\n >\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n @if (rendered(); as html) {\n <div class=\"ngx-field__value ngx-field__markdown\" [attr.data-testid]=\"'field-' + field.id + '-value'\" [innerHTML]=\"html\"></div>\n } @else {\n <!-- No renderer: the source is the display. The stylesheet keeps its line\n breaks with white-space: pre-wrap, and interpolation escapes it. -->\n <span class=\"ngx-field__value ngx-field__markdown--source\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value }}</span>\n }\n } @else {\n <div class=\"ngx-field__markdown-editor\">\n @if (canPreview) {\n <div class=\"ngx-field__markdown-tabs\" role=\"group\" [attr.aria-label]=\"label + ' editor mode'\">\n <button\n type=\"button\"\n class=\"ngx-field__markdown-tab\"\n [attr.data-testid]=\"'field-' + field.id + '-write'\"\n [attr.aria-pressed]=\"!previewing()\"\n (click)=\"previewing.set(false)\"\n >\n Write\n </button>\n <button\n type=\"button\"\n class=\"ngx-field__markdown-tab\"\n [attr.data-testid]=\"'field-' + field.id + '-preview'\"\n [attr.aria-pressed]=\"previewing()\"\n (click)=\"previewing.set(true)\"\n >\n Preview\n </button>\n </div>\n }\n\n @if (previewing()) {\n <div class=\"ngx-field__markdown ngx-field__markdown--preview\" [attr.data-testid]=\"'field-' + field.id + '-preview-body'\" [innerHTML]=\"rendered()\"></div>\n } @else {\n <textarea\n [id]=\"field.id\"\n class=\"ngx-field__input ngx-field__input--markdown\"\n [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder\"\n [attr.disabled]=\"field.disabled ? true : null\"\n rows=\"6\"\n ></textarea>\n }\n </div>\n\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class MarkdownFieldComponent implements OnChanges {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Optional — the field is fully usable without one. */\n private readonly render = inject(MARKDOWN_RENDERER, { optional: true });\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly previewing = signal(false);\n\n private valueSub?: { unsubscribe(): void };\n\n /**\n * Re-render when the value changes from outside this component.\n *\n * `rendered()` reads `control.value`, which under OnPush is neither an input nor a\n * template event: typing in the textarea updates through `formControl`, but a host\n * calling `patchValue`, a rule, or an `autoPatch` mapping does not mark this component\n * dirty. The preview and the read-only view would keep showing the previous document\n * while the record already held a different one.\n */\n ngOnChanges(changes: SimpleChanges): void {\n if (!changes['control']) return;\n this.valueSub?.unsubscribe();\n this.valueSub = this.control?.valueChanges?.subscribe(() => this.cdr.markForCheck());\n if (this.valueSub) this.destroyRef.onDestroy(() => this.valueSub?.unsubscribe());\n }\n\n /** A Preview tab that can only ever show the source back is worse than no tab. */\n protected get canPreview(): boolean {\n return !!this.render;\n }\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n /**\n * Rendered HTML, or null when there is no renderer or nothing to render.\n *\n * A renderer is consumer code and may throw on input it does not like. Letting that\n * escape would take down the whole form over one malformed field, so it falls back to the\n * source text — which is what the field would have shown with no renderer at all.\n */\n protected rendered(): string | null {\n const source = this.control?.value;\n if (!this.render || typeof source !== 'string' || source === '') return null;\n try {\n return this.render(source);\n } catch {\n return null;\n }\n }\n}\n","import { Component, Input, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { ValidationMessagesService } from '../services/validation-messages.service';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-number-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div\n class=\"ngx-field ngx-field--number\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\"\n [class.ngx-field--readonly]=\"readonly\"\n [class.ngx-field--masked]=\"masked\"\n [class.ngx-field--invalid]=\"control && control.invalid && control.touched\"\n >\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">\n {{ label }}\n @if (field.validators?.required) { <span class=\"ngx-field__req\">*</span> }\n </label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value ?? '—' }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n type=\"number\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder\"\n [attr.disabled]=\"field.disabled ? true : null\"\n [attr.aria-invalid]=\"control.invalid && control.touched\"\n [attr.aria-describedby]=\"errorMessage ? field.id + '-error' : null\"\n />\n @if (errorMessage) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\" [id]=\"field.id + '-error'\" role=\"alert\">{{ errorMessage }}</span>\n }\n }\n </div>\n `,\n})\nexport class NumberFieldComponent {\n private readonly messages = inject(ValidationMessagesService);\n\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n get errorMessage(): string {\n if (!this.control || !this.control.errors || !this.control.touched) return '';\n return this.messages.resolve(\n this.control.errors,\n this.language,\n ['required', 'min', 'max'],\n 'invalidNumber',\n );\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/** Currency field: number input with locale-aware currency symbol prefix. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-currency-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--currency\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ symbol }}{{ control.value }}</span>\n } @else {\n <div class=\"ngx-field__currency-wrap\">\n <span class=\"ngx-field__currency-symbol\">{{ symbol }}</span>\n <input\n class=\"ngx-field__input ngx-field__input--currency\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"number\"\n step=\"0.01\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder || '0.00'\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n </div>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class CurrencyFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n /** Picks the currency symbol from the locale — defaults to '$'. */\n get symbol(): string {\n try {\n return (0).toLocaleString(this.language, { style: 'currency', currency: 'USD', minimumFractionDigits: 0 })\n .replace(/[\\d,.\\s]/g, '').trim() || '$';\n } catch {\n return '$';\n }\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/** Email field: type=\"email\" input with inline validation hint. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-email-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--email\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">\n <a [href]=\"'mailto:' + control.value\" class=\"ngx-field__email-link\">{{ control.value || '—' }}</a>\n </span>\n } @else {\n <input\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"email\"\n autocomplete=\"email\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder || 'you@example.com'\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n @if (control.invalid && control.touched) {\n @if (control.errors?.['required']) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">Email is required</span>\n } @else if (control.errors?.['email']) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">Enter a valid email address</span>\n } @else {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n }\n </div>\n `,\n})\nexport class EmailFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n}\n","import { Component, Input, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/** Password field: masked input with show/hide eye toggle. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-password-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--password\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">••••••••</span>\n } @else {\n <div class=\"ngx-field__password-wrap\">\n <input\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [type]=\"visible() ? 'text' : 'password'\"\n autocomplete=\"current-password\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder || '••••••••'\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n <button\n type=\"button\"\n class=\"ngx-field__eye-btn\"\n (click)=\"toggleVisibility()\"\n [attr.aria-label]=\"visible() ? 'Hide password' : 'Show password'\"\n >\n {{ visible() ? '🙈' : '👁' }}\n </button>\n </div>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class PasswordFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n readonly visible = signal(false);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n toggleVisibility(): void {\n this.visible.update(v => !v);\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-checkbox-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--checkbox\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n @if (masked) {\n <label class=\"ngx-field__label\">{{ label }}</label>\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <label class=\"ngx-field__label\">{{ label }}</label>\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value ? 'Yes' : 'No' }}</span>\n } @else {\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">\n <input\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"checkbox\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n {{ label }}\n </label>\n }\n </div>\n `,\n})\nexport class CheckboxFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/**\n * Boolean field: a slide-toggle style switch (true/false).\n * Distinct from `checkbox` (which is a standalone bool) in that it renders as a\n * toggle switch with Yes/No labels for clearer binary state communication.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-boolean-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--boolean\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n @if (masked) {\n <label class=\"ngx-field__label\">{{ label }}</label>\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <label class=\"ngx-field__label\">{{ label }}</label>\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value ? 'Yes' : 'No' }}</span>\n } @else {\n <div class=\"ngx-field__toggle-wrap\">\n <label class=\"ngx-field__toggle-label\">{{ label }}</label>\n <label class=\"ngx-field__toggle-switch\" [class.ngx-field__toggle-switch--checked]=\"control.value\">\n <input\n class=\"ngx-field__toggle-input\"\n type=\"checkbox\"\n role=\"switch\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n [attr.aria-checked]=\"control.value\"\n />\n <span class=\"ngx-field__toggle-track\">\n <span class=\"ngx-field__toggle-thumb\"></span>\n </span>\n <span class=\"ngx-field__toggle-text\">{{ control.value ? 'Yes' : 'No' }}</span>\n </label>\n </div>\n }\n </div>\n `,\n})\nexport class BooleanFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-date-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--date\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ formatDate(control.value) }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"date\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class DateFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n /** ISO 8601 date → locale display string (ONEHERMES convention: always UTC, display in user locale) */\n formatDate(value: string | null): string {\n if (!value) return '—';\n try {\n return new Date(value).toLocaleDateString();\n } catch {\n return value;\n }\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/**\n * Reads a stored value into a `Date`.\n *\n * A bare calendar date is pinned to *local* midnight. `new Date('2020-01-01')` reads a\n * date-only string as UTC midnight, which renders as the previous day anywhere west of\n * Greenwich — and every legacy `datetime` value has exactly that shape, because the type\n * used to render through `DateFieldComponent` and its `type=\"date\"` input.\n */\nfunction parseStored(value: unknown): Date | null {\n if (value === null || value === undefined || value === '') return null;\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;\n\n const raw = String(value);\n const dateOnly = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(raw);\n if (dateOnly) return new Date(+dateOnly[1], +dateOnly[2] - 1, +dateOnly[3]);\n\n const parsed = new Date(raw);\n return Number.isNaN(parsed.getTime()) ? null : parsed;\n}\n\nconst pad = (n: number): string => String(n).padStart(2, '0');\n\n/**\n * Date & Time field: a single `datetime-local` input.\n *\n * The type is stored as ISO 8601 UTC, per the same convention `date` follows, while the\n * input works in the viewer's local zone — `datetime-local` has no offset, so the two\n * conversions here are what keep a value stable across a round trip.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-date-time-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--datetime\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ formatDateTime(control.value) }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"datetime-local\"\n [value]=\"inputValue\"\n (change)=\"onInput($any($event.target).value)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class DateTimeFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n /** Stored ISO 8601 → the `YYYY-MM-DDTHH:mm` local form the input requires. */\n get inputValue(): string {\n const d = parseStored(this.control?.value);\n if (!d) return '';\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;\n }\n\n /** The input's local `YYYY-MM-DDTHH:mm` → stored ISO 8601 UTC. */\n onInput(value: string): void {\n if (!value) {\n this.control.setValue(null);\n this.control.markAsTouched();\n return;\n }\n const d = new Date(value);\n // An unparseable value is stored verbatim rather than silently discarded, so a validator\n // sees what the user actually entered.\n this.control.setValue(Number.isNaN(d.getTime()) ? value : d.toISOString());\n this.control.markAsTouched();\n }\n\n /**\n * Displays date *and* time. `DateFieldComponent` used `toLocaleDateString()` here, so a\n * datetime read back through the field showed no time while the same value in the record\n * summary — which goes through core's `formatDisplayValue` — showed it.\n */\n formatDateTime(value: unknown): string {\n const d = parseStored(value);\n return d ? d.toLocaleString() : '—';\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { formatDisplayValue, resolveLabel } from '@dynamic-entity/core';\n\n/**\n * Time field: a bare time of day, with no date and no zone attached.\n *\n * Stored as `HH:mm` — exactly the value `<input type=\"time\">` reads and writes, so the\n * control binds straight through with no conversion. That is the whole reason this is a\n * separate type from `datetime`: a recurring 09:00 opening time is not a moment in time,\n * and converting it to UTC would move it whenever the offset changed.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-time-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--time\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ formatTime(control.value) }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"time\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class TimeFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n /**\n * Defers to core rather than parsing `HH:mm` locally. The other date-ish components each\n * grew their own formatter, and `datetime` ended up showing one thing in the field and\n * another in the record summary because the two drifted apart.\n */\n formatTime(value: unknown): string {\n return formatDisplayValue('time', undefined, value, this.language);\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\nconst MONTH_NAMES = [\n 'January', 'February', 'March', 'April', 'May', 'June',\n 'July', 'August', 'September', 'October', 'November', 'December',\n];\n\nconst CURRENT_YEAR = new Date().getFullYear();\nconst YEARS = Array.from({ length: 80 }, (_, i) => CURRENT_YEAR - i);\n\n/**\n * Month-Year field: two linked selects (Month + Year).\n * Value stored as ISO partial date string \"YYYY-MM\" for unambiguous storage.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-month-year-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--month-year\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ formatValue(control.value) }}</span>\n } @else {\n <div class=\"ngx-field__month-year-wrap\">\n <select\n class=\"ngx-field__input ngx-field__input--month\" [attr.data-testid]=\"'field-' + field.id + '-month'\"\n [value]=\"selectedMonth\"\n (change)=\"onMonthChange($any($event.target).value)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n >\n <option value=\"\">Month</option>\n @for (m of months; track m.value) {\n <option [value]=\"m.value\">{{ m.label }}</option>\n }\n </select>\n <select\n class=\"ngx-field__input ngx-field__input--year\" [attr.data-testid]=\"'field-' + field.id + '-year'\"\n [value]=\"selectedYear\"\n (change)=\"onYearChange($any($event.target).value)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n >\n <option value=\"\">Year</option>\n @for (y of years; track y) {\n <option [value]=\"y\">{{ y }}</option>\n }\n </select>\n </div>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class MonthYearFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n readonly months = MONTH_NAMES.map((label, i) => ({ value: String(i + 1).padStart(2, '0'), label }));\n readonly years = YEARS;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n /** Parses \"YYYY-MM\" or \"YYYY-MM-DD\" stored value → month part. */\n get selectedMonth(): string {\n const v = String(this.control.value ?? '');\n return v.length >= 7 ? v.substring(5, 7) : '';\n }\n\n get selectedYear(): string {\n const v = String(this.control.value ?? '');\n return v.length >= 4 ? v.substring(0, 4) : '';\n }\n\n onMonthChange(month: string): void {\n const year = this.selectedYear || new Date().getFullYear().toString();\n this.control.setValue(month ? `${year}-${month}` : null);\n this.control.markAsTouched();\n }\n\n onYearChange(year: string): void {\n const month = this.selectedMonth || '01';\n this.control.setValue(year ? `${year}-${month}` : null);\n this.control.markAsTouched();\n }\n\n formatValue(value: unknown): string {\n if (!value) return '—';\n const [year, monthNum] = String(value).split('-');\n const monthName = MONTH_NAMES[parseInt(monthNum, 10) - 1];\n return monthName && year ? `${monthName} ${year}` : String(value);\n }\n}\n","import { Injectable, inject, type WritableSignal } from '@angular/core';\nimport type {\n DropdownOption,\n LookupListLoader,\n LookupListResult,\n LookupListSource,\n LookupListValue,\n NestedFieldConfig,\n RawLookupListValue,\n Subscribable,\n} from '@dynamic-entity/core';\nimport { lookupValuesToOptions, normalizeLookupValues, resolveLabel } from '@dynamic-entity/core';\nimport { LOOKUP_REGISTRY } from '../tokens/injection-tokens';\n\n/** Cache-key field separator. Kept out of template literals so it stays visible in source. */\nconst SEP = '|';\n\n/**\n * LookupRegistryService — the cache in front of consumer-registered master lists.\n *\n * Three layers, deliberately the same shape as `EntityReferenceService`, because the problem is\n * the same: one list is typically used by many fields across many entities.\n * 1. **options** — resolved `DropdownOption[]` per (list name, lang).\n * 2. **in-flight** — the pending Promise, so N fields on one list trigger one load, not N.\n * 3. **labels** — synchronous value → text (parity plan §6.2). This is not a nicety: since\n * `viewMode` defaults to true a record opens read-only, so rendering a stored value as\n * text is the *first* thing a `listName` field has to do. An async-only registry would\n * paint the raw stored value and then flip, on every record open.\n *\n * A failed load rejects and caches nothing, so one transient error does not serve an empty\n * list forever — the same fix made for entity references in phase 5.\n */\n@Injectable({ providedIn: 'root' })\nexport class LookupRegistryService {\n private readonly registry =\n inject(LOOKUP_REGISTRY, { optional: true }) ?? new Map<string, LookupListSource>();\n\n /** `listName|lang` -> resolved options. */\n private readonly options = new Map<string, DropdownOption[]>();\n /** `listName|lang` -> normalised values, so a consumer can reach `code` / `isSystemDefined`. */\n private readonly values = new Map<string, LookupListValue[]>();\n /** Loads in progress, keyed as above. */\n private readonly inFlight = new Map<string, Promise<DropdownOption[]>>();\n /** `listName|lang|text` -> display text, for the synchronous read-only path. */\n private readonly labels = new Map<string, string>();\n\n has(listName: string): boolean {\n return this.registry.has(listName);\n }\n\n /**\n * Options for a named list, from cache when present.\n * Concurrent callers with the same key share one load.\n */\n async load(listName: string, lang = 'en'): Promise<DropdownOption[]> {\n const key = this.cacheKey(listName, lang);\n\n const cached = this.options.get(key);\n if (cached) return cached;\n\n const pending = this.inFlight.get(key);\n if (pending) return pending;\n\n const source = this.registry.get(listName);\n if (source === undefined) return [];\n\n const load = this.invoke(source, lang).then(raw => {\n const values = normalizeLookupValues(raw);\n const options = lookupValuesToOptions(values);\n this.values.set(key, values);\n this.options.set(key, options);\n this.rememberLabels(listName, lang, options);\n return options;\n });\n\n // Only the `.then` above writes to the cache, and a rejection skips it: the caller still\n // gets an empty list, but the next call retries instead of reading a poisoned entry.\n const guarded = load\n .catch(() => [] as DropdownOption[])\n .finally(() => this.inFlight.delete(key));\n\n this.inFlight.set(key, guarded);\n return guarded;\n }\n\n /** Cached options without triggering a load. `undefined` when not loaded. */\n peek(listName: string, lang = 'en'): DropdownOption[] | undefined {\n return this.options.get(this.cacheKey(listName, lang));\n }\n\n /**\n * Cached list values, carrying `_id`, `code`, `isSystemDefined` and `from`.\n * The library never reads those; this is the seam for a consumer that needs them.\n */\n valuesFor(listName: string, lang = 'en'): LookupListValue[] | undefined {\n return this.values.get(this.cacheKey(listName, lang));\n }\n\n /**\n * Display text for a stored value, synchronously. `undefined` when the list has not loaded\n * or holds no matching value — the caller keeps its own fallback, which is the stored text.\n *\n * Every language of an option is indexed, so a record saved under one language renders in\n * another: a value stored as `'Aktiv'` resolves to `'Active'` under `lang: 'en'`.\n */\n labelFor(listName: string | undefined, value: unknown, lang = 'en'): string | undefined {\n if (!listName || value === null || value === undefined || value === '') return undefined;\n for (const text of this.candidateTexts(value, lang)) {\n const hit = this.labels.get(this.labelKey(listName, lang, text));\n if (hit) return hit;\n }\n return undefined;\n }\n\n // ─── Field-level resolution — inline options win, else `listName` ────────────\n\n /** True when this field's options have to come from the registry. */\n needsResolve(field: NestedFieldConfig | undefined): boolean {\n return !!field?.listName && !field.options?.length;\n }\n\n /**\n * The options to render right now, without awaiting: inline options, else whatever the\n * registry already holds. Empty on a cold miss — pair with `resolveOptions`.\n */\n optionsFor(field: NestedFieldConfig | undefined, lang = 'en'): DropdownOption[] {\n if (!field) return [];\n if (field.options?.length) return field.options;\n if (!field.listName) return [];\n return this.peek(field.listName, lang) ?? [];\n }\n\n /** The options for a field, loading the named list if needed. */\n resolveOptions(field: NestedFieldConfig | undefined, lang = 'en'): Promise<DropdownOption[]> {\n if (!this.needsResolve(field)) return Promise.resolve(this.optionsFor(field, lang));\n return this.load(field!.listName!, lang);\n }\n\n /** Drop everything cached for one list, leaving other lists intact. */\n invalidate(listName: string): void {\n const prefix = `${listName}${SEP}`;\n for (const map of [this.options, this.values, this.inFlight]) {\n for (const key of [...map.keys()]) {\n if (key.startsWith(prefix)) map.delete(key);\n }\n }\n for (const key of [...this.labels.keys()]) {\n if (key.startsWith(prefix)) this.labels.delete(key);\n }\n }\n\n clear(): void {\n this.options.clear();\n this.values.clear();\n this.inFlight.clear();\n this.labels.clear();\n }\n\n // ─── Internals ──────────────────────────────────────────────────────────────\n\n private cacheKey(listName: string, lang: string): string {\n return [listName, lang].join(SEP);\n }\n\n private labelKey(listName: string, lang: string, text: string): string {\n return [listName, lang, text].join(SEP);\n }\n\n /** Index an option under every language it carries, so any stored spelling finds it. */\n private rememberLabels(listName: string, lang: string, options: DropdownOption[]): void {\n for (const option of options) {\n const display = resolveLabel(option, lang);\n if (!display) continue;\n for (const text of Object.values(option)) {\n if (typeof text === 'string' && text !== '') {\n this.labels.set(this.labelKey(listName, lang, text), display);\n }\n }\n }\n }\n\n /** The texts a stored value could have been indexed under. */\n private candidateTexts(value: unknown, lang: string): string[] {\n if (typeof value === 'object') {\n const texts = Object.values(value as Record<string, unknown>).filter(\n (v): v is string => typeof v === 'string' && v !== '',\n );\n const resolved = resolveLabel(value as Record<string, string>, lang);\n return resolved ? [resolved, ...texts] : texts;\n }\n return [String(value)];\n }\n\n // ─── Source coercion (values | loader, array | Promise | Observable) ─────────\n\n private invoke(source: LookupListSource, lang: string): Promise<RawLookupListValue[]> {\n let result: LookupListResult;\n try {\n result = typeof source === 'function' ? (source as LookupListLoader)({ lang }) : source;\n } catch (err) {\n // Reject rather than resolve empty: `load` must be able to tell failure from an empty\n // list, or it would cache the failure.\n return Promise.reject(err);\n }\n return this.toPromise(result);\n }\n\n private toPromise(result: LookupListResult): Promise<RawLookupListValue[]> {\n if (Array.isArray(result)) return Promise.resolve(result);\n if (this.isSubscribable(result)) {\n // First emission wins, so a stream that stays open still resolves the load.\n return new Promise<RawLookupListValue[]>((resolve, reject) => {\n let settled = false;\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n fn();\n };\n result.subscribe({\n next: value => settle(() => resolve(value ?? [])),\n error: err => settle(() => reject(err)),\n // Completing without emitting is a legitimate empty list, and is cached.\n complete: () => settle(() => resolve([])),\n });\n });\n }\n return Promise.resolve(result as Promise<RawLookupListValue[]>);\n }\n\n private isSubscribable(value: unknown): value is Subscribable<RawLookupListValue[]> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Subscribable<RawLookupListValue[]>).subscribe === 'function'\n );\n }\n}\n\n/** A choice field component, as far as option resolution is concerned. */\nexport interface ChoiceOptionHost {\n readonly field: NestedFieldConfig | undefined;\n readonly language: string;\n readonly options: WritableSignal<DropdownOption[]>;\n}\n\nconst hostLastConfig = new WeakMap<ChoiceOptionHost, { field?: NestedFieldConfig; lang?: string }>();\n\n/**\n * Point a choice component's `options` signal at the right source (parity plan §6.3).\n *\n * Called from the `field` / `language` input setters of `dropdown`, `radio` and `multiSelect` —\n * the wiring is theirs, the decision is the service's, which is what keeps the field\n * five-input contract intact: options are never pushed in as a sixth input.\n *\n * Setters rather than `ngOnChanges` on purpose. `ngOnChanges` only fires for inputs Angular\n * itself sets, so a component whose `field` is assigned directly — which the field specs do,\n * and any consumer holding a `ComponentRef` may do — would render no options at all.\n *\n * Paints synchronously first (inline options, or a warm list), then fills in when a cold list\n * lands. The late result is dropped if the field or language changed while it was in flight.\n */\nexport function refreshChoiceOptions(host: ChoiceOptionHost, lookups: LookupRegistryService): void {\n const last = hostLastConfig.get(host);\n if (last && last.field === host.field && last.lang === host.language) {\n return;\n }\n hostLastConfig.set(host, { field: host.field, lang: host.language });\n\n host.options.set(lookups.optionsFor(host.field, host.language));\n if (!lookups.needsResolve(host.field)) return;\n\n const listName = host.field?.listName;\n const lang = host.language;\n void lookups.resolveOptions(host.field, host.language).then(options => {\n if (host.field?.listName === listName && host.language === lang) host.options.set(options);\n });\n}\n","import { Component, Input, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { DropdownOption, NestedFieldConfig } from '@dynamic-entity/core';\nimport {\n getOptionStoredValue,\n resolveLabel,\n resolveOptionLabel,\n valuesMatch,\n} from '@dynamic-entity/core';\nimport { LookupRegistryService, refreshChoiceOptions } from '../services/lookup-registry.service';\nimport { ValidationMessagesService } from '../services/validation-messages.service';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-dropdown-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div\n class=\"ngx-field ngx-field--dropdown\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\"\n [class.ngx-field--readonly]=\"readonly\"\n [class.ngx-field--masked]=\"masked\"\n [class.ngx-field--invalid]=\"control && control.invalid && control.touched\"\n >\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">\n {{ label }}\n @if (field.validators?.required) { <span class=\"ngx-field__req\">*</span> }\n </label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ getLabel(control.value) }}</span>\n } @else {\n <select\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [compareWith]=\"compareFn\"\n [attr.disabled]=\"field.disabled ? true : null\"\n [attr.aria-invalid]=\"control.invalid && control.touched\"\n [attr.aria-describedby]=\"errorMessage ? field.id + '-error' : null\"\n >\n <option [value]=\"''\">{{ placeholder || 'Select...' }}</option>\n @for (option of options(); track getOptLabel(option)) {\n @if (isObjectVal(option)) {\n <option [ngValue]=\"getOptStoredVal(option)\">{{ getOptLabel(option) }}</option>\n } @else {\n <option [value]=\"getOptStoredVal(option)\">{{ getOptLabel(option) }}</option>\n }\n }\n </select>\n @if (errorMessage) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\" [id]=\"field.id + '-error'\" role=\"alert\">{{ errorMessage }}</span>\n }\n }\n </div>\n `,\n})\nexport class DropdownFieldComponent {\n private readonly lookups = inject(LookupRegistryService);\n private readonly messages = inject(ValidationMessagesService);\n\n private _field!: NestedFieldConfig;\n private _language = 'en';\n\n /** Setter-based so options resolve however the input is set — see `refreshChoiceOptions`. */\n @Input() set field(value: NestedFieldConfig) {\n this._field = value;\n refreshChoiceOptions(this, this.lookups);\n }\n get field(): NestedFieldConfig {\n return this._field;\n }\n\n @Input() set language(value: string) {\n this._language = value || 'en';\n refreshChoiceOptions(this, this.lookups);\n }\n get language(): string {\n return this._language;\n }\n\n @Input() control!: AbstractControl;\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Inline `options`, or the field's named list resolved through the registry (§6.3). */\n readonly options = signal<DropdownOption[]>([]);\n\n readonly compareFn = (o1: unknown, o2: unknown): boolean => valuesMatch(o1, o2, this.language);\n\n isObjectVal(option: DropdownOption): boolean {\n const val = getOptionStoredValue(option);\n return typeof val === 'object' && val !== null;\n }\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n getOptStoredVal(option: DropdownOption): unknown {\n return getOptionStoredValue(option);\n }\n\n getOptLabel(option: DropdownOption): string {\n return resolveOptionLabel(option, this.language);\n }\n\n /**\n * Read-only display. Never awaits (§6.2): a warm list resolves the label, a cold one falls\n * back to the stored text — which under the §2 contract *is* the display value, so it is\n * never wrong, only unlocalised.\n */\n getLabel(value: unknown): string {\n if (value == null || value === '') return '—';\n const option = this.options().find(o => valuesMatch(getOptionStoredValue(o), value, this.language));\n if (option) return this.getOptLabel(option);\n const cached = this.lookups.labelFor(this.field?.listName, value, this.language);\n if (cached) return cached;\n return typeof value === 'object' ? resolveLabel(value as Record<string, string>, this.language) : String(value ?? '—');\n }\n\n get errorMessage(): string {\n if (!this.control || !this.control.errors || !this.control.touched) return '';\n // `requiredSelection` rather than `required`: \"Please select an option\" reads better on a\n // dropdown than \"This field is required\", and both stay independently overridable.\n return this.messages.resolve(\n this.control.errors,\n this.language,\n [['required', 'requiredSelection']],\n 'invalidSelection',\n );\n }\n}\n","import { Component, Input, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { DropdownOption, NestedFieldConfig } from '@dynamic-entity/core';\nimport {\n getOptionStoredValue,\n resolveLabel,\n resolveOptionLabel,\n resolveOptionValue,\n valuesMatch,\n} from '@dynamic-entity/core';\nimport { LookupRegistryService, refreshChoiceOptions } from '../services/lookup-registry.service';\n\n/** Radio field: a group of radio buttons built from field.options. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-radio-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--radio\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <fieldset class=\"ngx-field__fieldset\">\n <legend class=\"ngx-field__label\">{{ label }}</legend>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ getSelectedLabel() }}</span>\n } @else {\n <div class=\"ngx-field__radio-group\">\n @for (option of options(); track getOptLabel(option)) {\n <label class=\"ngx-field__radio-option\" [attr.for]=\"getRadioId(option)\">\n <input\n [id]=\"getRadioId(option)\"\n type=\"radio\"\n class=\"ngx-field__radio-input\"\n [formControl]=\"$any(control)\"\n [value]=\"getOptStoredVal(option)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n <span class=\"ngx-field__radio-label\">{{ getOptLabel(option) }}</span>\n </label>\n }\n </div>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </fieldset>\n </div>\n `,\n})\nexport class RadioFieldComponent {\n private readonly lookups = inject(LookupRegistryService);\n\n private _field!: NestedFieldConfig;\n private _language = 'en';\n\n /** Setter-based so options resolve however the input is set — see `refreshChoiceOptions`. */\n @Input() set field(value: NestedFieldConfig) {\n this._field = value;\n refreshChoiceOptions(this, this.lookups);\n }\n get field(): NestedFieldConfig {\n return this._field;\n }\n\n @Input() set language(value: string) {\n this._language = value || 'en';\n refreshChoiceOptions(this, this.lookups);\n }\n get language(): string {\n return this._language;\n }\n\n @Input() control!: AbstractControl;\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Inline `options`, or the field's named list resolved through the registry (§6.3). */\n readonly options = signal<DropdownOption[]>([]);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n getOptStoredVal(option: DropdownOption): unknown {\n return getOptionStoredValue(option);\n }\n\n /**\n * Stable DOM id for one radio, so the <label for> association works.\n * Slugified because the option text is the value now — \"On Leave\" must not put a space\n * into an id attribute.\n */\n getRadioId(option: DropdownOption): string {\n const text = String(this.getOptVal(option) ?? 'opt');\n return `${this.field.id}-${text.trim().replace(/\\s+/g, '_').toLowerCase()}`;\n }\n\n getOptVal(option: DropdownOption): string | number | boolean {\n return resolveOptionValue(option, this.language);\n }\n\n getOptLabel(option: DropdownOption): string {\n return resolveOptionLabel(option, this.language);\n }\n\n /** Read-only display — synchronous, per §6.2. See `DropdownFieldComponent.getLabel`. */\n getSelectedLabel(): string {\n const value = this.control?.value;\n // `typeof null === 'object'`, so without this guard an empty value fell through to\n // `resolveLabel(null)` and rendered as blank — dropdown and multiSelect both show an em dash.\n if (value === null || value === undefined || value === '') return '—';\n const selected = this.options().find(o => valuesMatch(getOptionStoredValue(o), value, this.language));\n if (selected) return this.getOptLabel(selected);\n const cached = this.lookups.labelFor(this.field?.listName, value, this.language);\n if (cached) return cached;\n return typeof value === 'object' ? resolveLabel(value as Record<string, string>, this.language) : String(value ?? '—');\n }\n}\n","import { Component, Input, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { DropdownOption, NestedFieldConfig } from '@dynamic-entity/core';\nimport {\n getOptionStoredValue,\n resolveLabel,\n resolveOptionLabel,\n valuesMatch,\n} from '@dynamic-entity/core';\nimport { LookupRegistryService, refreshChoiceOptions } from '../services/lookup-registry.service';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-multi-select-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--multiSelect\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ getLabels(control.value) }}</span>\n } @else {\n <select\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [compareWith]=\"compareFn\"\n [attr.disabled]=\"field.disabled ? true : null\"\n multiple\n size=\"4\"\n >\n @for (option of options(); track getOptLabel(option)) {\n @if (isObjectVal(option)) {\n <option [ngValue]=\"getOptStoredVal(option)\">{{ getOptLabel(option) }}</option>\n } @else {\n <option [value]=\"getOptStoredVal(option)\">{{ getOptLabel(option) }}</option>\n }\n }\n </select>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class MultiSelectFieldComponent {\n private readonly lookups = inject(LookupRegistryService);\n\n private _field!: NestedFieldConfig;\n private _language = 'en';\n\n /** Setter-based so options resolve however the input is set — see `refreshChoiceOptions`. */\n @Input() set field(value: NestedFieldConfig) {\n this._field = value;\n refreshChoiceOptions(this, this.lookups);\n }\n get field(): NestedFieldConfig {\n return this._field;\n }\n\n @Input() set language(value: string) {\n this._language = value || 'en';\n refreshChoiceOptions(this, this.lookups);\n }\n get language(): string {\n return this._language;\n }\n\n @Input() control!: AbstractControl;\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Inline `options`, or the field's named list resolved through the registry (§6.3). */\n readonly options = signal<DropdownOption[]>([]);\n\n readonly compareFn = (o1: unknown, o2: unknown): boolean => valuesMatch(o1, o2, this.language);\n\n isObjectVal(option: DropdownOption): boolean {\n const val = getOptionStoredValue(option);\n return typeof val === 'object' && val !== null;\n }\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n getOptStoredVal(option: DropdownOption): unknown {\n return getOptionStoredValue(option);\n }\n\n getOptLabel(option: DropdownOption): string {\n return resolveOptionLabel(option, this.language);\n }\n\n /** Read-only display — synchronous, per §6.2. See `DropdownFieldComponent.getLabel`. */\n getLabels(values: unknown): string {\n if (!Array.isArray(values) || !values.length) return '—';\n return values\n .map(v => {\n const opt = this.options().find(o => valuesMatch(getOptionStoredValue(o), v, this.language));\n if (opt) return this.getOptLabel(opt);\n const cached = this.lookups.labelFor(this.field?.listName, v, this.language);\n if (cached) return cached;\n return typeof v === 'object' && v !== null ? resolveLabel(v as Record<string, string>, this.language) : String(v);\n })\n .join(', ');\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type { EntityReferenceLoader } from '@dynamic-entity/core';\nimport { ENTITY_REF_REGISTRY } from '../tokens/injection-tokens';\n\n/**\n * EntityRefRegistryService — resolves entity-ref option loader functions.\n * Entity-ref options come ONLY from this registry.\n * Never pass loaders via @Input() on field components.\n *\n * Consumers register loaders via provideNgxDynamicEntity({ entityRefs: { clients: () => [...] } }).\n * EntityRefFieldComponent injects this service and calls resolve(field.component ?? field.id).\n */\n@Injectable({ providedIn: 'root' })\nexport class EntityRefRegistryService {\n private readonly registry =\n inject(ENTITY_REF_REGISTRY, { optional: true }) ?? new Map<string, EntityReferenceLoader>();\n\n /**\n * Get the option loader for an entity key.\n * @returns The loader, or null if none is registered.\n */\n resolve(entityKey: string): EntityReferenceLoader | null {\n return this.registry.get(entityKey) ?? null;\n }\n\n has(entityKey: string): boolean {\n return this.registry.has(entityKey);\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type {\n EntityReferenceLoader,\n RawReferenceItem,\n ReferenceLoaderContext,\n ReferenceLoaderResult,\n ReferenceOption,\n Subscribable,\n} from '@dynamic-entity/core';\nimport {\n buildReferenceCacheKey,\n entityKeyFromCacheKey,\n normalizeReferenceOptions,\n resolveLabel,\n valuesMatch,\n} from '@dynamic-entity/core';\nimport { ENTITY_REF_CACHE_STORE } from '../tokens/injection-tokens';\nimport { EntityRefRegistryService } from './entity-ref-registry.service';\n\n/** Label-cache field separator. Kept out of template literals so it stays visible in source. */\nconst LABEL_SEP = '|';\n\n/**\n * EntityReferenceService — the cache in front of consumer-registered option loaders.\n *\n * Three layers, matching the reference implementation:\n * 1. **options** — resolved `ReferenceOption[]` per (entity, lang, displayFields, filters).\n * 2. **in-flight** — the pending Promise, so N fields referencing one entity trigger one\n * load rather than N. This is the layer that actually removes duplicate HTTP calls;\n * an options cache alone does nothing for concurrent first loads.\n * 3. **labels** — synchronous value → text, for rendering a stored reference without\n * waiting on a load.\n *\n * Invalidation is per entity, not global. The reference could only `clearCache()` everything\n * (issue #16), so saving one record re-fetched every entity's options.\n */\n@Injectable({ providedIn: 'root' })\nexport class EntityReferenceService {\n private readonly registry = inject(EntityRefRegistryService);\n private readonly store = inject(ENTITY_REF_CACHE_STORE);\n\n /** Loads in progress, keyed the same way as the options cache. */\n private readonly inFlight = new Map<string, Promise<ReferenceOption[]>>();\n /** `entityKey|lang|canonicalValue` -> display text. */\n private readonly labels = new Map<string, string>();\n\n /**\n * Options for an entity, from cache when present.\n * Concurrent callers with the same key share one load.\n */\n async load(entityKey: string, ctx: ReferenceLoaderContext = {}): Promise<ReferenceOption[]> {\n const key = buildReferenceCacheKey(entityKey, {\n lang: ctx.lang,\n filters: ctx.filters,\n displayFields: ctx.displayFields,\n parentValue: ctx.parentValue,\n });\n\n const cached = this.store.get(key);\n if (cached) return cached;\n\n const pending = this.inFlight.get(key);\n if (pending) return pending;\n\n const loader = this.registry.resolve(entityKey);\n if (!loader) return [];\n\n const load = this.invoke(loader, ctx)\n .then(raw => {\n // displayFields drive label building, which is why they are part of the cache key.\n const options = normalizeReferenceOptions(\n raw as RawReferenceItem[],\n ctx.displayFields ? { enabled: true, displayFields: ctx.displayFields } : undefined,\n ctx.lang ?? 'en',\n );\n this.store.set(key, options);\n this.rememberLabels(entityKey, ctx.lang ?? 'en', options);\n return options;\n });\n\n // A failed load resolves to [] for the caller but is never written to the store, so a\n // transient error is retried on the next call instead of poisoning the cache. Only the\n // `.then` above caches, and a rejection skips it.\n const guarded = load\n .catch(() => [] as ReferenceOption[])\n .finally(() => this.inFlight.delete(key));\n\n this.inFlight.set(key, guarded);\n return guarded;\n }\n\n /** Cached options without triggering a load. `undefined` when not cached. */\n peek(entityKey: string, ctx: ReferenceLoaderContext = {}): ReferenceOption[] | undefined {\n return this.store.get(\n buildReferenceCacheKey(entityKey, {\n lang: ctx.lang,\n filters: ctx.filters,\n displayFields: ctx.displayFields,\n parentValue: ctx.parentValue,\n }),\n );\n }\n\n /**\n * Display text for a stored reference value, synchronously.\n * Returns `undefined` when the entity's options have never been loaded.\n */\n labelFor(entityKey: string, value: unknown, lang = 'en'): string | undefined {\n return this.labels.get(this.labelKey(entityKey, lang, value));\n }\n\n /** Drop everything cached for one entity, leaving other entities intact. */\n invalidate(entityKey: string): void {\n for (const key of this.store.keys()) {\n if (entityKeyFromCacheKey(key) === entityKey) this.store.delete(key);\n }\n for (const key of [...this.inFlight.keys()]) {\n if (entityKeyFromCacheKey(key) === entityKey) this.inFlight.delete(key);\n }\n const prefix = `${entityKey}${LABEL_SEP}`;\n for (const key of [...this.labels.keys()]) {\n if (key.startsWith(prefix)) this.labels.delete(key);\n }\n }\n\n clear(): void {\n this.store.clear();\n this.inFlight.clear();\n this.labels.clear();\n }\n\n private rememberLabels(entityKey: string, lang: string, options: ReferenceOption[]): void {\n for (const option of options) {\n this.labels.set(this.labelKey(entityKey, lang, option.value), option.label);\n }\n }\n\n /** Label-cache key. An object value collapses to its resolved text for the active language. */\n private labelKey(entityKey: string, lang: string, value: unknown): string {\n const canonical =\n value !== null && typeof value === 'object'\n ? resolveLabel(value as Record<string, string>, lang)\n : String(value ?? '');\n return [entityKey, lang, canonical].join(LABEL_SEP);\n }\n\n // ─── Loader result coercion (array | Promise | Observable) ──────────────────\n\n private invoke(\n loader: EntityReferenceLoader,\n ctx: ReferenceLoaderContext,\n ): Promise<ReferenceOption[]> {\n let result: ReferenceLoaderResult;\n try {\n result = loader(ctx);\n } catch (err) {\n // Reject rather than resolve empty: `load` must be able to tell failure from\n // \"no matches\", or it would cache the failure.\n return Promise.reject(err);\n }\n return this.toPromise(result);\n }\n\n private toPromise(result: ReferenceLoaderResult): Promise<ReferenceOption[]> {\n if (Array.isArray(result)) return Promise.resolve(result);\n if (this.isSubscribable(result)) {\n // First emission wins, so an Observable that stays open still resolves the load.\n return new Promise<ReferenceOption[]>((resolve, reject) => {\n let settled = false;\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n fn();\n };\n result.subscribe({\n next: value => settle(() => resolve(value ?? [])),\n // An erroring stream is a failed load, not an empty one — see `invoke`.\n error: err => settle(() => reject(err)),\n // Completing without emitting is a legitimate empty result, and is cached.\n complete: () => settle(() => resolve([])),\n });\n });\n }\n return Promise.resolve(result as Promise<ReferenceOption[]>);\n }\n\n private isSubscribable(value: unknown): value is Subscribable<ReferenceOption[]> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Subscribable<ReferenceOption[]>).subscribe === 'function'\n );\n }\n\n /** Exposed for cascade filtering, which matches a parent value against option values. */\n matches(a: unknown, b: unknown, lang = 'en'): boolean {\n return valuesMatch(a, b, lang);\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type {\n EntityFormConfig,\n NestedFieldConfig,\n NestedTabConfig,\n ReferenceLoaderContext,\n ReferenceOption,\n} from '@dynamic-entity/core';\nimport { applyCascadeFilter } from '@dynamic-entity/core';\nimport { EntityRefRegistryService } from './entity-ref-registry.service';\nimport { EntityReferenceService } from './entity-reference.service';\n\n/**\n * CascadeDataService — loads entity-reference options and applies parent→child cascades.\n *\n * Loaders come from the registry only. This service owns the three things a\n * field component should not: resolving the loader, coercing whatever it returned\n * (array | Promise | Observable) into a Promise, and filtering by the parent's value.\n */\n@Injectable({ providedIn: 'root' })\nexport class CascadeDataService {\n private readonly registry = inject(EntityRefRegistryService);\n private readonly references = inject(EntityReferenceService);\n\n /** Preload runs by formConfigId, so a second call joins the first rather than re-fetching. */\n private readonly preloads = new Map<string, Promise<void>>();\n\n /** Registry key for a field: explicit `linkedEntityKey`, else the field id. */\n entityKeyFor(field: NestedFieldConfig): string {\n return field.entityReference?.linkedEntityKey ?? field.id;\n }\n\n /** Whether a loader is registered for this field. */\n canLoad(field: NestedFieldConfig): boolean {\n return this.registry.has(this.entityKeyFor(field));\n }\n\n /**\n * Load the options for a field, cascade-filtered against `parentValue`.\n * Returns `[]` when no loader is registered, or when a cascade child has no parent value yet.\n */\n async load(\n field: NestedFieldConfig,\n ctx: ReferenceLoaderContext = {},\n ): Promise<ReferenceOption[]> {\n const cfg = field.entityReference;\n if (!this.canLoad(field)) return [];\n\n // A cascade child with no parent selection must offer nothing.\n const hasParentValue =\n ctx.parentValue !== null && ctx.parentValue !== undefined && ctx.parentValue !== '';\n if (cfg?.parentField && !hasParentValue) return [];\n\n const lang = ctx.lang ?? 'en';\n\n // When the cascade can be resolved locally (`lookupFilter`/`lookupPath`), fetch the\n // unfiltered set once and filter per parent below — switching parent then costs nothing.\n // Otherwise the loader is the only thing that can narrow the list, so `parentValue` is\n // passed through and becomes part of the cache identity (one entry per parent).\n const filtersLocally = !!(cfg?.lookupFilter || cfg?.lookupPath);\n\n const options = await this.references.load(this.entityKeyFor(field), {\n ...ctx,\n parentValue: filtersLocally ? undefined : ctx.parentValue,\n filters: { ...(cfg?.filters ?? {}), ...(ctx.filters ?? {}) },\n displayFields: cfg?.displayFields,\n lang,\n });\n\n return applyCascadeFilter(options, ctx.parentValue, cfg, lang);\n }\n\n // ─── Preload ────────────────────────────────────────────────────────────────\n\n /**\n * Warm the cache for every entity a config's cascades depend on, so changing a parent\n * resolves from memory instead of a round-trip.\n *\n * Idempotent per `formConfigId`: calling it again returns the in-flight or completed run\n * rather than re-fetching.\n */\n initializeCascadeData(formConfigId: string, config: EntityFormConfig, lang = 'en'): Promise<void> {\n const existing = this.preloads.get(formConfigId);\n if (existing) return existing;\n\n const fields = this.cascadeFields(config);\n const run = Promise.all(\n fields.map(field =>\n this.references.load(this.entityKeyFor(field), {\n filters: field.entityReference?.filters,\n displayFields: field.entityReference?.displayFields,\n lang,\n }),\n ),\n ).then(() => undefined);\n\n this.preloads.set(formConfigId, run);\n return run;\n }\n\n /** Resolves true once `initializeCascadeData` for this config has finished. */\n async waitForData(formConfigId: string): Promise<boolean> {\n const run = this.preloads.get(formConfigId);\n if (!run) return false;\n await run;\n return true;\n }\n\n /**\n * Child options for a parent selection, from cache only — no load is triggered.\n * Returns `[]` when the entity has not been preloaded.\n */\n getCachedChildOptions(\n field: NestedFieldConfig,\n parentValue: unknown,\n lang = 'en',\n ): ReferenceOption[] {\n const cfg = field.entityReference;\n const cached = this.references.peek(this.entityKeyFor(field), {\n filters: cfg?.filters,\n displayFields: cfg?.displayFields,\n lang,\n });\n if (!cached) return [];\n return applyCascadeFilter(cached, parentValue, cfg, lang);\n }\n\n /** Forget the preload for one config. The option cache itself is untouched. */\n clearCache(formConfigId: string): void {\n this.preloads.delete(formConfigId);\n }\n\n /** Every entity-ref field in the config that participates in a cascade. */\n private cascadeFields(config: EntityFormConfig): NestedFieldConfig[] {\n const found: NestedFieldConfig[] = [];\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const field of fields ?? []) {\n const cfg = field.entityReference;\n if (cfg?.enabled && (cfg.parentField || cfg.lookupPath || cfg.lookupFilter)) {\n found.push(field);\n }\n walkFields(field.children);\n }\n };\n const walkTabs = (tabs: NestedTabConfig[] | undefined) => {\n for (const tab of tabs ?? []) {\n walkFields(tab.fields);\n walkTabs(tab.children);\n }\n };\n walkTabs(config?.tabs);\n return found;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport type { ReferenceOption } from '@dynamic-entity/core';\n\nexport interface EntityRefSelection {\n fieldId: string;\n /** The chosen option, or `null` when the selection was cleared. */\n option: ReferenceOption | null;\n}\n\n/**\n * EntityRefSelectionService — the channel an entity-ref field uses to publish *which record*\n * the user picked, so the owning form can run `autoPatch` against it.\n *\n * The control value alone is not enough: `autoPatch` copies fields out of the selected\n * record, which only the field component has after loading its options.\n *\n * Provided at `DynamicFormComponent` level so each form instance gets its own channel;\n * the `root` fallback keeps standalone field components injectable in isolation.\n */\n@Injectable({ providedIn: 'root' })\nexport class EntityRefSelectionService {\n private readonly subject = new Subject<EntityRefSelection>();\n\n readonly selection$ = this.subject.asObservable();\n\n emit(fieldId: string, option: ReferenceOption | null): void {\n this.subject.next({ fieldId, option });\n }\n}\n","import { Component, DestroyRef, Input, OnInit, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig, ReferenceOption } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { CascadeDataService } from '../services/cascade-data.service';\nimport { EntityRefSelectionService } from '../services/entity-ref-selection.service';\n\n/**\n * EntityRefFieldComponent — a select populated from a consumer-registered loader.\n *\n * Cascades: when `entityReference.parentField` is set, the component watches that sibling\n * control (via `control.parent`) and reloads its own options on every parent change,\n * clearing a now-invalid selection. It publishes the picked record on\n * `EntityRefSelectionService` so the owning form can run `autoPatch`.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-ref-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--entity-ref\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"'field-' + field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ getLabel(control.value) }}</span>\n } @else {\n @if (loading()) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-loading'\" role=\"status\">Loading…</span>\n } @else {\n <select\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [id]=\"'field-' + field.id\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n >\n <option value=\"\">{{ placeholder || 'Select...' }}</option>\n @for (option of options(); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n @if (awaitingParent()) {\n <span class=\"ngx-field__hint\" [attr.data-testid]=\"'field-' + field.id + '-hint'\">Select {{ parentFieldId }} first.</span>\n }\n }\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class EntityRefFieldComponent implements OnInit {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n private readonly cascade = inject(CascadeDataService);\n private readonly selectionBus = inject(EntityRefSelectionService);\n private readonly destroyRef = inject(DestroyRef);\n\n readonly options = signal<ReferenceOption[]>([]);\n readonly loading = signal(false);\n /** True when this field cascades but its parent has no value yet. */\n readonly awaitingParent = signal(false);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n get parentFieldId(): string | undefined {\n return this.field?.entityReference?.parentField;\n }\n\n ngOnInit(): void {\n if (this.masked) return;\n void this.reload();\n this.watchParent();\n this.control?.valueChanges\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(value => this.publishSelection(String(value ?? '')));\n }\n\n /** Reload options against the parent's current value. */\n async reload(): Promise<void> {\n const parentValue = this.parentValue();\n this.awaitingParent.set(\n !!this.parentFieldId && (parentValue === null || parentValue === undefined || parentValue === ''),\n );\n\n if (!this.cascade.canLoad(this.field)) {\n this.options.set([]);\n return;\n }\n\n this.loading.set(true);\n try {\n this.options.set(\n await this.cascade.load(this.field, { parentValue, lang: this.language }),\n );\n } finally {\n this.loading.set(false);\n }\n }\n\n /**\n * Publish the selected option so autoPatch can copy from its record.\n *\n * Driven from `valueChanges` rather than the select's `change` event: that event is the\n * same one the `formControl` directive listens to, so reading the control inside a\n * template `(change)` handler can see the previous value. `valueChanges` fires after the\n * model has updated — including Playwright `selectOption`, which updates the control\n * through the value accessor.\n */\n onSelectionChange(value?: string): void {\n this.publishSelection(value ?? String(this.control?.value ?? ''));\n }\n\n private publishSelection(current: string): void {\n const selected = this.options().find(o => String(o.value) === current);\n this.selectionBus.emit(this.field.id, selected ?? null);\n }\n\n getLabel(value: any): string {\n const option = this.options().find(o => String(o.value) === String(value));\n return option?.label ?? (value ?? '—');\n }\n\n private parentValue(): unknown {\n const parentId = this.parentFieldId;\n if (!parentId) return undefined;\n return this.control?.parent?.get(parentId)?.value;\n }\n\n /** Reload (and drop a stale selection) whenever the parent control changes. */\n private watchParent(): void {\n const parentId = this.parentFieldId;\n if (!parentId) return;\n const parentControl = this.control?.parent?.get(parentId);\n if (!parentControl) return;\n\n parentControl.valueChanges\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n if (this.control.value) {\n this.control.setValue('', { emitEvent: false });\n this.selectionBus.emit(this.field.id, null);\n }\n void this.reload();\n });\n }\n}\n","import { Injectable, Type, inject } from '@angular/core';\nimport { FIELD_TYPE_REGISTRY, FIELD_TYPE_SETS } from '../tokens/injection-tokens';\n\n/**\n * FieldRegistryService — resolves field type strings to Angular component classes.\n *\n * **Tree-shaking contract:** this service holds *no* static imports of field components.\n * Nothing is bundled until something registers it, which is what makes the built-ins\n * opt-in. Register them with `provideBuiltInFieldTypes()` (all 19 keys) or a narrower\n * subset via `provideFieldTypes({ ... })` — see `providers/provide-field-types.ts`.\n *\n * Resolution order: consumer token registry → runtime registrations → nothing.\n */\n@Injectable({ providedIn: 'root' })\nexport class FieldRegistryService {\n private readonly consumerRegistry =\n inject(FIELD_TYPE_REGISTRY, { optional: true }) ?? new Map<string, Type<any>>();\n private readonly dynamicRegistry = new Map<string, Type<any>>();\n\n constructor() {\n // Sets contributed by provideFieldTypes()/provideBuiltInFieldTypes(), in declaration order.\n for (const set of inject(FIELD_TYPE_SETS, { optional: true }) ?? []) {\n this.registerAll(set);\n }\n }\n\n /** Register a field type component mapping at runtime. */\n register(type: string, component: Type<any>): void {\n this.dynamicRegistry.set(type, component);\n }\n\n /** Register multiple field type component mappings at runtime. */\n registerAll(map: Record<string, Type<any>>): void {\n for (const [type, comp] of Object.entries(map)) {\n this.dynamicRegistry.set(type, comp);\n }\n }\n\n /**\n * Resolve a field type string to a component class.\n * Consumer token registry takes priority over runtime registrations.\n */\n resolve(fieldType: string): Type<any> | null {\n return this.consumerRegistry.get(fieldType) ?? this.dynamicRegistry.get(fieldType) ?? null;\n }\n\n /** Check if a field type has a registered component. */\n has(fieldType: string): boolean {\n return this.consumerRegistry.has(fieldType) || this.dynamicRegistry.has(fieldType);\n }\n\n /** Every registered field type key. Consumer overrides and runtime registrations combined. */\n registeredTypes(): string[] {\n return [...new Set([...this.dynamicRegistry.keys(), ...this.consumerRegistry.keys()])].sort();\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type { EntityFormConfig, NestedFieldConfig, NestedTabConfig } from '@dynamic-entity/core';\nimport { shouldMaskField as coreShouldMaskField, resolveEffectiveMask as coreResolveEffectiveMask } from '@dynamic-entity/core';\nimport { MASKED_ROLES } from '../tokens/injection-tokens';\n\n/**\n * RbacService — ALL permission checks and masking logic live here.\n */\n@Injectable({ providedIn: 'root' })\nexport class RbacService {\n private readonly maskedRoles = inject(MASKED_ROLES, { optional: true }) ?? [];\n\n /**\n * Check if any of the user's roles satisfy the required roles.\n * hasPermission(roles, undefined) → true (no restriction).\n */\n hasPermission(userRoles: string[], requiredRoles?: string[]): boolean {\n if (!requiredRoles?.length) return true;\n return userRoles.some(r => requiredRoles.includes(r));\n }\n\n /** 3-level OR resolution */\n resolveEffectiveMask(formMask?: boolean, tabMask?: boolean, fieldMask?: boolean): boolean {\n return coreResolveEffectiveMask(formMask, tabMask, fieldMask);\n }\n\n /** Check if the user's roles include any masked role */\n isUserMaskedRole(userRoles: string[]): boolean {\n return this.maskedRoles.some(r => userRoles.includes(r));\n }\n\n /** Determine if a specific field should be masked for this user */\n shouldMaskField(field: NestedFieldConfig, tab: NestedTabConfig | undefined, config: EntityFormConfig, userRoles: string[]): boolean {\n return coreShouldMaskField(field, tab, config, userRoles, this.maskedRoles);\n }\n\n /** Get view/edit/delete permissions for a config */\n getPermissions(config: EntityFormConfig, userRoles: string[]) {\n return {\n canView: this.hasPermission(userRoles, config.permissions?.view),\n canEdit: this.hasPermission(userRoles, config.permissions?.edit),\n canDelete: this.hasPermission(userRoles, config.permissions?.delete),\n };\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ComponentRef,\n Injector,\n Input,\n OnChanges, OnDestroy,\n SimpleChanges,\n ViewChild,\n ViewContainerRef,\n inject,\n isDevMode,\n} from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport type { NestedFieldConfig, EntityFormConfig, NestedTabConfig } from '@dynamic-entity/core';\nimport { findTab } from '@dynamic-entity/core';\nimport { FieldRegistryService } from '../../services/field-registry.service';\nimport { RbacService } from '../../services/rbac.service';\n\n/**\n * DynamicFieldComponent — mounts the correct field component for a given NestedFieldConfig.\n * Uses ViewContainerRef.createComponent() and passes inputs via setInput(); see\n * DynamicFieldComponentContract for the five inputs every field component receives.\n * Never add field-type-specific logic here — this component must remain generic.\n *\n * The 5 inputs (field, control, language, readonly, masked) are passed to every mounted\n * component uniformly — no special-casing per type.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-dynamic-field',\n standalone: true,\n template: `<ng-container #fieldHost></ng-container>`,\n})\nexport class DynamicFieldComponent implements OnChanges, OnDestroy {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() config!: EntityFormConfig;\n @Input() currentTabId?: string;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() userRoles: string[] = [];\n\n @ViewChild('fieldHost', { read: ViewContainerRef, static: true })\n private readonly fieldHost!: ViewContainerRef;\n\n private readonly fieldRegistry = inject(FieldRegistryService);\n private readonly rbacService = inject(RbacService);\n /**\n * Passed into `createComponent` so a hosted field sees this host's injector — including\n * `DynamicFormComponent`'s scoped `EntityRefSelectionService`. Without it, a standalone\n * field resolves the root bus and `autoPatch` never runs.\n */\n private readonly injector = inject(Injector);\n\n private componentRef: ComponentRef<unknown> | null = null;\n\n ngOnChanges(_changes: SimpleChanges): void {\n this.mountField();\n }\n\n private mountField(): void {\n if (!this.field || !this.control) return;\n\n const ComponentClass = this.fieldRegistry.resolve(this.field.type);\n if (!ComponentClass) {\n this.warnUnresolved(this.field.type);\n return; // Unknown field type — render nothing\n }\n\n // Determine masking for this specific field\n const tab: NestedTabConfig | null = this.currentTabId ? findTab(this.config?.tabs, this.currentTabId) : null;\n const masked = this.rbacService.shouldMaskField(this.field, tab ?? undefined, this.config, this.userRoles);\n\n // Re-use existing component if same type, otherwise recreate\n if (this.componentRef && this.componentRef.instance instanceof ComponentClass) {\n this.setInputs(this.componentRef, masked);\n return;\n }\n\n this.fieldHost.clear();\n this.componentRef = this.fieldHost.createComponent(ComponentClass, {\n injector: this.injector,\n });\n this.setInputs(this.componentRef, masked);\n this.watchControl();\n this.componentRef.changeDetectorRef.detectChanges();\n }\n\n /**\n * Field types are opt-in (see `provideFieldTypes` / `provideBuiltInFieldTypes`), so an\n * unregistered type renders nothing. Say so once per type in dev builds rather than\n * leaving a silently blank slot.\n */\n private warnUnresolved(type: string): void {\n if (!isDevMode() || DynamicFieldComponent.warnedTypes.has(type)) return;\n DynamicFieldComponent.warnedTypes.add(type);\n console.warn(\n `[ngx-dynamic-entity] No component registered for field type \"${type}\" — the field was not rendered. ` +\n `Register it with provideFieldTypes({ '${type}': MyComponent }) or provideBuiltInFieldTypes().`,\n );\n }\n\n private static readonly warnedTypes = new Set<string>();\n\n /**\n * Re-check the hosted field component.\n *\n * The field components are OnPush, so they re-render on an input change, an event from\n * their own template, or a signal they read. `form.markAllAsTouched()` is none of those —\n * it flips `touched` from outside, and every field's error message depends on it. Without\n * this, a blocked submit would mark the form touched and no error would appear.\n */\n refresh(): void {\n this.componentRef?.changeDetectorRef.detectChanges();\n }\n\n /**\n * Re-check the hosted component whenever its control changes from outside.\n *\n * The field components are OnPush, so they re-render on an input change or an event from\n * their own template. A control mutated externally is neither — and that is not an edge\n * case: patchForm, reset, autoPatch and patchOnTrue all do exactly that. Without this, a\n * field patched from a record would keep rendering its previous value.\n *\n * `detectChanges()` rather than `markForCheck()`: a selection that arrives from a native\n * `change` event (or Playwright) may not be followed by another Angular tick, so a dirty\n * flag would never be flushed. Running CD on the hosted component now is the copy showing up.\n *\n * Done here rather than in each of the eighteen field components: the host owns the\n * component reference, so one subscription covers every type including custom ones.\n */\n private watchControl(): void {\n this.controlSub?.unsubscribe();\n if (!this.control) return;\n\n this.controlSub = this.control.valueChanges.subscribe(() => this.refresh());\n }\n\n private controlSub?: Subscription;\n\n ngOnDestroy(): void {\n this.controlSub?.unsubscribe();\n }\n\n /**\n * Pass all 5 contract inputs via ComponentRef.setInput() — uniform for all types.\n * The public shape is DynamicFieldComponentContract.\n * Must use setInput(), not property assignment: the field components declare inputs with\n * definite assignment and no initializer, and the lib compiles with\n * useDefineForClassFields:false, so `'field' in instance` is false until first set.\n */\n private setInputs(ref: ComponentRef<unknown>, masked: boolean): void {\n ref.setInput('field', this.field);\n ref.setInput('control', this.control);\n ref.setInput('language', this.language);\n ref.setInput('readonly', this.readonly || !!this.field.readonly);\n ref.setInput('masked', masked);\n }\n}\n","import { Component, Input, forwardRef, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig, EntityFormConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { DynamicFieldComponent } from '../form/dynamic-field/dynamic-field.component';\n\n/** Renders a nested fieldset container for a group field's children. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-group-field',\n standalone: true,\n imports: [ReactiveFormsModule, forwardRef(() => DynamicFieldComponent)],\n template: `\n <fieldset class=\"ngx-field ngx-field--group\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <legend class=\"ngx-field__legend\">{{ label }}</legend>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else {\n <div class=\"ngx-field__group-children\">\n @for (child of field.children ?? []; track child.id) {\n @if (child.visibility !== false) {\n <ngx-dynamic-field\n [field]=\"child\"\n [control]=\"getChildControl(child.id)\"\n [config]=\"config\"\n [language]=\"language\"\n [readonly]=\"readonly || !!child.readonly\"\n [userRoles]=\"userRoles\"\n />\n }\n }\n </div>\n }\n </fieldset>\n `,\n styles: [\n `\n .ngx-field--group {\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n margin-bottom: 16px;\n background: #fafafa;\n }\n .ngx-field__legend {\n font-weight: 600;\n font-size: 14px;\n padding: 0 8px;\n color: #334155;\n }\n .ngx-field__group-children {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n `,\n ],\n})\nexport class GroupFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() config!: EntityFormConfig;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n @Input() userRoles: string[] = [];\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n getChildControl(childId: string): AbstractControl {\n const group = this.control as FormGroup;\n return group?.get(childId) as AbstractControl;\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { AsyncValidatorFn, ValidatorFn, Validators } from '@angular/forms';\nimport type { FieldValidators } from '@dynamic-entity/core';\nimport { ASYNC_VALIDATOR_REGISTRY, VALIDATOR_REGISTRY } from '../tokens/injection-tokens';\n\n/**\n * ValidatorRegistryService — resolves validator configs / key strings to Angular ValidatorFns.\n */\n@Injectable({ providedIn: 'root' })\nexport class ValidatorRegistryService {\n private readonly consumerRegistry = inject(VALIDATOR_REGISTRY, { optional: true }) ?? new Map();\n private readonly asyncRegistry = inject(ASYNC_VALIDATOR_REGISTRY, { optional: true }) ?? new Map();\n\n /**\n * Resolve a validator key string to a ValidatorFn.\n * Supports parameterized built-ins like 'min:0', 'maxLength:255'.\n */\n resolve(validatorKey: string): ValidatorFn | null {\n if (this.consumerRegistry.has(validatorKey)) {\n return this.consumerRegistry.get(validatorKey);\n }\n\n if (validatorKey === 'required') return Validators.required;\n if (validatorKey === 'email') return Validators.email;\n\n const [name, param] = validatorKey.split(':');\n const value = parseFloat(param);\n\n if (name === 'min' && !isNaN(value)) return Validators.min(value);\n if (name === 'max' && !isNaN(value)) return Validators.max(value);\n if (name === 'minLength' && !isNaN(value)) return Validators.minLength(value);\n if (name === 'maxLength' && !isNaN(value)) return Validators.maxLength(value);\n\n return null;\n }\n\n /** Resolve multiple validator keys into a ValidatorFn[] */\n resolveAll(validatorKeys: string[] = []): ValidatorFn[] {\n return validatorKeys.map(k => this.resolve(k)).filter((v): v is ValidatorFn => v !== null);\n }\n\n /** Resolve a FieldValidators object or string[] into ValidatorFn[] */\n resolveFromConfig(config?: FieldValidators | string[]): ValidatorFn[] {\n if (!config) return [];\n if (Array.isArray(config)) return this.resolveAll(config);\n\n const fnList: ValidatorFn[] = [];\n if (config.required) fnList.push(Validators.required);\n if (config.min !== undefined) fnList.push(Validators.min(config.min));\n if (config.max !== undefined) fnList.push(Validators.max(config.max));\n if (config.minLength !== undefined) fnList.push(Validators.minLength(config.minLength));\n if (config.maxLength !== undefined) fnList.push(Validators.maxLength(config.maxLength));\n if (config.pattern) fnList.push(Validators.pattern(config.pattern));\n if (config.email) fnList.push(Validators.email);\n\n // Named validators from the consumer registry. This branch previously hardcoded the\n // built-ins and consulted the registry only for the `string[]` form of this config, so\n // a validator the consumer had registered could not be named from a typed schema\n // without casting it to `any`.\n for (const key of config.custom ?? []) {\n const fn = this.resolve(key);\n if (fn) fnList.push(fn);\n }\n\n return fnList;\n }\n\n /**\n * Resolve the async validators a field names, in `validators.customAsync`.\n *\n * Async validators are deliberately a separate registry and a separate config key: Angular\n * attaches them through `setAsyncValidators`, runs them only once the synchronous ones\n * pass, and holds the control in `pending` until they settle. Mixing them into the\n * synchronous list would silently never run them.\n *\n * An unknown name is skipped rather than throwing, matching the synchronous behaviour.\n */\n resolveAsyncFromConfig(config?: FieldValidators | string[]): AsyncValidatorFn[] {\n if (!config || Array.isArray(config)) return [];\n\n const out: AsyncValidatorFn[] = [];\n for (const key of config.customAsync ?? []) {\n const fn = this.asyncRegistry.get(key);\n if (fn) out.push(fn);\n }\n return out;\n }\n}\n","import { Component, Input, inject, forwardRef, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';\nimport { AbstractControl, FormArray, FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig, EntityFormConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { DynamicFieldComponent } from '../form/dynamic-field/dynamic-field.component';\nimport { ValidatorRegistryService } from '../services/validator-registry.service';\n\n/** Renders repeating rows for a FormArray, with Add Item and Remove. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-array-field',\n standalone: true,\n imports: [ReactiveFormsModule, forwardRef(() => DynamicFieldComponent)],\n template: `\n <div class=\"ngx-field ngx-field--array\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <div class=\"ngx-field__array-header\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (!readonly && !masked) {\n <button type=\"button\" class=\"ngx-field__array-add-btn\"\n [attr.data-testid]=\"'field-' + field.id + '-add'\" (click)=\"addItem()\">\n + Add Item\n </button>\n }\n </div>\n\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else {\n <div class=\"ngx-field__array-list\">\n @for (itemGroup of formArray.controls; track idx; let idx = $index) {\n <div class=\"ngx-field__array-item\" [attr.data-testid]=\"'field-' + field.id + '-row'\">\n <div class=\"ngx-field__array-item-header\">\n <span class=\"ngx-field__array-item-title\">Item #{{ idx + 1 }}</span>\n @if (!readonly) {\n <button type=\"button\" class=\"ngx-field__array-remove-btn\"\n [attr.data-testid]=\"'field-' + field.id + '-remove-' + idx\" (click)=\"removeItem(idx)\">\n Remove\n </button>\n }\n </div>\n <div class=\"ngx-field__array-item-fields\">\n @for (child of field.children ?? []; track child.id) {\n @if (child.visibility !== false) {\n <ngx-dynamic-field\n [field]=\"child\"\n [control]=\"getItemChildControl(itemGroup, child.id)\"\n [config]=\"config\"\n [language]=\"language\"\n [readonly]=\"readonly || !!child.readonly\"\n [userRoles]=\"userRoles\"\n />\n }\n }\n </div>\n </div>\n }\n @if (formArray.controls.length === 0) {\n <div class=\"ngx-field__array-empty\" [attr.data-testid]=\"'field-' + field.id + '-empty'\">No items added yet.</div>\n }\n </div>\n }\n </div>\n `,\n styles: [\n `\n .ngx-field--array {\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n margin-bottom: 16px;\n background: #f8fafc;\n }\n .ngx-field__array-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n }\n .ngx-field__array-add-btn {\n background: #2563eb;\n color: #fff;\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n font-weight: 500;\n cursor: pointer;\n }\n .ngx-field__array-add-btn:hover {\n background: #1d4ed8;\n }\n .ngx-field__array-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .ngx-field__array-item {\n background: #fff;\n border: 1px solid #cbd5e1;\n border-radius: 6px;\n padding: 12px;\n }\n .ngx-field__array-item-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n border-bottom: 1px solid #f1f5f9;\n padding-bottom: 6px;\n }\n .ngx-field__array-item-title {\n font-weight: 600;\n font-size: 13px;\n color: #475569;\n }\n .ngx-field__array-remove-btn {\n background: #ef4444;\n color: #fff;\n border: none;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n }\n .ngx-field__array-empty {\n color: #94a3b8;\n font-style: italic;\n font-size: 13px;\n }\n `,\n ],\n})\nexport class ArrayFieldComponent {\n /**\n * addItem/removeItem are public and may be called from outside this component's template,\n * which under OnPush would not re-render. The host also watches the control, but this\n * keeps the component correct on its own.\n */\n private readonly cdr = inject(ChangeDetectorRef);\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() config!: EntityFormConfig;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n @Input() userRoles: string[] = [];\n\n private readonly fb = inject(FormBuilder);\n private readonly validatorRegistry = inject(ValidatorRegistryService);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get formArray(): FormArray {\n return this.control as FormArray;\n }\n\n getItemChildControl(itemGroup: AbstractControl, childId: string): AbstractControl {\n return (itemGroup as FormGroup).get(childId) as AbstractControl;\n }\n\n addItem(): void {\n const controls: Record<string, any> = {};\n for (const child of this.field.children ?? []) {\n const validators = this.validatorRegistry.resolveFromConfig(child.validators);\n controls[child.id] = [child.defaultValue ?? null, validators];\n }\n const group = this.fb.group(controls);\n this.formArray.push(group);\n this.cdr.markForCheck();\n }\n\n removeItem(index: number): void {\n this.formArray.removeAt(index);\n this.cdr.markForCheck();\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type { FileRef, Subscribable, UploadResult } from '@dynamic-entity/core';\nimport { UPLOAD_HANDLER } from '../tokens/injection-tokens';\n\n/**\n * FileUploadService — the single place image-field and file-field agree on how a\n * selected `File` becomes a `FileRef`.\n *\n * With `UPLOAD_HANDLER` registered the file is persisted and stored as `{ url }`;\n * without one it is stored as `{ file }` for the consumer to upload at submit time.\n */\n@Injectable({ providedIn: 'root' })\nexport class FileUploadService {\n private readonly handler = inject(UPLOAD_HANDLER, { optional: true });\n\n get hasHandler(): boolean {\n return !!this.handler;\n }\n\n /** Metadata common to both persisted and unpersisted refs. */\n private describe(file: File): FileRef {\n return { name: file.name, size: file.size, mimeType: file.type };\n }\n\n /**\n * Turn a selected File into the value to store on the control.\n * @throws when a registered handler rejects — callers surface it as a field error.\n */\n async toFileRef(file: File): Promise<FileRef> {\n const meta = this.describe(file);\n if (!this.handler) return { ...meta, file };\n\n const result = await this.normalize(this.handler(file));\n return { ...meta, url: result.url, name: result.name ?? meta.name };\n }\n\n /** Object URL for previewing an unpersisted File. Callers must revoke it. */\n previewUrlFor(ref: FileRef | null | undefined): string | null {\n if (!ref) return null;\n if (ref.url) return ref.url;\n if (ref.file && typeof URL !== 'undefined' && typeof URL.createObjectURL === 'function') {\n return URL.createObjectURL(ref.file);\n }\n return null;\n }\n\n revokePreviewUrl(url: string | null): void {\n if (!url || !url.startsWith('blob:')) return;\n if (typeof URL !== 'undefined' && typeof URL.revokeObjectURL === 'function') {\n URL.revokeObjectURL(url);\n }\n }\n\n private normalize(\n result: UploadResult | Promise<UploadResult> | Subscribable<UploadResult>,\n ): Promise<UploadResult> {\n if (this.isSubscribable(result)) {\n return new Promise<UploadResult>((resolve, reject) => {\n let settled = false;\n result.subscribe({\n next: value => {\n if (settled) return;\n settled = true;\n resolve(value);\n },\n error: err => {\n if (settled) return;\n settled = true;\n reject(err);\n },\n complete: () => {\n if (settled) return;\n settled = true;\n reject(new Error('Upload handler completed without emitting a result.'));\n },\n });\n });\n }\n return Promise.resolve(result as UploadResult | Promise<UploadResult>);\n }\n\n private isSubscribable(value: unknown): value is Subscribable<UploadResult> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Subscribable<UploadResult>).subscribe === 'function'\n );\n }\n}\n","import { Component, OnDestroy, inject, Input, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport type { FileRef, NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { FileUploadService } from '../services/file-upload.service';\n\n/**\n * Image field: preview thumbnail + upload button.\n *\n * With `UPLOAD_HANDLER` registered the file is persisted and stored as `{ url }`; without one\n * it is stored as `{ file }` and previewed from an object URL (revoked when replaced/destroyed).\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-image-field',\n standalone: true,\n imports: [],\n template: `\n <div class=\"ngx-field ngx-field--image\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"'field-' + field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else {\n <div class=\"ngx-field__image-wrap\">\n @if (previewUrl()) {\n <img class=\"ngx-field__image-preview\" [src]=\"previewUrl()\" [alt]=\"label\" />\n } @else {\n <div class=\"ngx-field__image-placeholder\">\n <span>📷</span>\n <span>No image</span>\n </div>\n }\n @if (!readonly) {\n <div class=\"ngx-field__image-actions\">\n <label class=\"ngx-field__upload-btn\" [class.ngx-field__upload-btn--loading]=\"uploading()\">\n @if (uploading()) {\n <span>Uploading…</span>\n } @else {\n <span>{{ previewUrl() ? 'Change' : 'Upload' }}</span>\n <input\n type=\"file\"\n class=\"ngx-field__file-input\"\n [id]=\"'field-' + field.id\"\n accept=\"image/*\"\n [disabled]=\"field.disabled || uploading()\"\n (change)=\"onFileSelect($any($event.target).files[0])\"\n />\n }\n </label>\n @if (previewUrl()) {\n <button type=\"button\" class=\"ngx-field__remove-btn\" (click)=\"remove()\">Remove</button>\n }\n </div>\n }\n </div>\n @if (uploadError()) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">{{ uploadError() }}</span>\n }\n }\n </div>\n `,\n})\nexport class ImageFieldComponent implements OnDestroy {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n private readonly uploads = inject(FileUploadService);\n\n readonly uploading = signal(false);\n readonly uploadError = signal<string | null>(null);\n\n /** Cached so an object URL is minted once per File, not once per change-detection pass. */\n private previewSource: FileRef | null = null;\n private previewCache: string | null = null;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n previewUrl(): string | null {\n const value = (this.control?.value as FileRef | null) ?? null;\n if (value === this.previewSource) return this.previewCache;\n\n this.uploads.revokePreviewUrl(this.previewCache);\n this.previewSource = value;\n this.previewCache = this.uploads.previewUrlFor(value);\n return this.previewCache;\n }\n\n async onFileSelect(file: File | undefined): Promise<void> {\n if (!file) return;\n this.uploadError.set(null);\n this.uploading.set(true);\n try {\n this.control.setValue(await this.uploads.toFileRef(file));\n this.control.markAsTouched();\n } catch {\n this.uploadError.set('Upload failed. Please try again.');\n } finally {\n this.uploading.set(false);\n }\n }\n\n remove(): void {\n this.control.setValue(null);\n this.control.markAsTouched();\n }\n\n ngOnDestroy(): void {\n this.uploads.revokePreviewUrl(this.previewCache);\n }\n}\n","import { Component, inject, Input, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport type { FileRef, NestedFieldConfig } from '@dynamic-entity/core';\nimport { fileRefName, resolveLabel } from '@dynamic-entity/core';\nimport { FileUploadService } from '../services/file-upload.service';\n\n/**\n * File field: file input with filename display and download link.\n * Shares the `FileRef` / `UPLOAD_HANDLER` contract with image-field via FileUploadService.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-file-field',\n standalone: true,\n imports: [],\n template: `\n <div class=\"ngx-field ngx-field--file\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"'field-' + field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n @if (fileUrl()) {\n <a class=\"ngx-field__file-link\" [href]=\"fileUrl()!\" target=\"_blank\" rel=\"noopener\">\n 📎 {{ fileName() || 'Download file' }}\n </a>\n } @else {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">—</span>\n }\n } @else {\n <div class=\"ngx-field__file-wrap\">\n @if (fileName()) {\n <div class=\"ngx-field__file-selected\">\n <span class=\"ngx-field__file-name\">📎 {{ fileName() }}</span>\n <button type=\"button\" class=\"ngx-field__remove-btn\" (click)=\"remove()\" aria-label=\"Remove file\">✕</button>\n </div>\n }\n <label class=\"ngx-field__upload-btn\" [class.ngx-field__upload-btn--loading]=\"uploading()\">\n @if (uploading()) {\n <span>Uploading…</span>\n } @else {\n <span>{{ fileName() ? 'Replace file' : 'Choose file' }}</span>\n <input\n type=\"file\"\n class=\"ngx-field__file-input\"\n [id]=\"'field-' + field.id\"\n [disabled]=\"field.disabled || uploading()\"\n (change)=\"onFileSelect($any($event.target).files[0])\"\n />\n }\n </label>\n </div>\n @if (uploadError()) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">{{ uploadError() }}</span>\n }\n }\n </div>\n `,\n})\nexport class FileFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n private readonly uploads = inject(FileUploadService);\n\n readonly uploading = signal(false);\n readonly uploadError = signal<string | null>(null);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n private get value(): FileRef | null {\n return (this.control?.value as FileRef | null) ?? null;\n }\n\n fileUrl(): string | null {\n return this.value?.url ?? null;\n }\n\n fileName(): string | null {\n return fileRefName(this.value) || null;\n }\n\n async onFileSelect(file: File | undefined): Promise<void> {\n if (!file) return;\n this.uploadError.set(null);\n this.uploading.set(true);\n try {\n this.control.setValue(await this.uploads.toFileRef(file));\n this.control.markAsTouched();\n } catch {\n this.uploadError.set('Upload failed. Please try again.');\n } finally {\n this.uploading.set(false);\n }\n }\n\n remove(): void {\n this.control.setValue(null);\n this.control.markAsTouched();\n }\n}\n","import { EnvironmentProviders, Type, makeEnvironmentProviders } from '@angular/core';\nimport { FIELD_TYPE_SETS } from '../tokens/injection-tokens';\n\nimport { TextFieldComponent } from '../field-types/text-field.component';\nimport { TextareaFieldComponent } from '../field-types/textarea-field.component';\nimport { MarkdownFieldComponent } from '../field-types/markdown-field.component';\nimport { NumberFieldComponent } from '../field-types/number-field.component';\nimport { CurrencyFieldComponent } from '../field-types/currency-field.component';\nimport { EmailFieldComponent } from '../field-types/email-field.component';\nimport { PasswordFieldComponent } from '../field-types/password-field.component';\nimport { CheckboxFieldComponent } from '../field-types/checkbox-field.component';\nimport { BooleanFieldComponent } from '../field-types/boolean-field.component';\nimport { DateFieldComponent } from '../field-types/date-field.component';\nimport { DateTimeFieldComponent } from '../field-types/date-time-field.component';\nimport { TimeFieldComponent } from '../field-types/time-field.component';\nimport { MonthYearFieldComponent } from '../field-types/month-year-field.component';\nimport { DropdownFieldComponent } from '../field-types/dropdown-field.component';\nimport { RadioFieldComponent } from '../field-types/radio-field.component';\nimport { MultiSelectFieldComponent } from '../field-types/multi-select-field.component';\nimport { EntityRefFieldComponent } from '../field-types/entity-ref-field.component';\nimport { GroupFieldComponent } from '../field-types/group-field.component';\nimport { ArrayFieldComponent } from '../field-types/array-field.component';\nimport { ImageFieldComponent } from '../field-types/image-field.component';\nimport { FileFieldComponent } from '../field-types/file-field.component';\n\n/**\n * Field-type registration — the tree-shaking seam.\n *\n * `FieldRegistryService` imports no components. Whatever you register here is what gets\n * bundled, so an app that only uses text/number/dropdown pays for three components and\n * their imports, not nineteen.\n *\n * ```ts\n * // Everything (convenient; bundles all built-ins):\n * provideNgxDynamicEntity(), provideBuiltInFieldTypes()\n *\n * // Only what this app renders:\n * provideFieldTypes({ text: TextFieldComponent, number: NumberFieldComponent })\n * ```\n *\n * Both merge into `FIELD_TYPE_REGISTRY`; later registrations win on key collision.\n */\n\n/** Map of every built-in field type key → component. Referencing this pulls in all of them. */\nexport function builtInFieldTypes(): Record<string, Type<any>> {\n return {\n text: TextFieldComponent,\n textarea: TextareaFieldComponent,\n markdown: MarkdownFieldComponent,\n number: NumberFieldComponent,\n currency: CurrencyFieldComponent,\n email: EmailFieldComponent,\n password: PasswordFieldComponent,\n checkbox: CheckboxFieldComponent,\n boolean: BooleanFieldComponent,\n date: DateFieldComponent,\n datetime: DateTimeFieldComponent,\n time: TimeFieldComponent,\n monthYear: MonthYearFieldComponent,\n dropdown: DropdownFieldComponent,\n radio: RadioFieldComponent,\n multiSelect: MultiSelectFieldComponent,\n 'entity-ref': EntityRefFieldComponent,\n group: GroupFieldComponent,\n array: ArrayFieldComponent,\n image: ImageFieldComponent,\n file: FileFieldComponent,\n };\n}\n\n/** Register a specific set of field types. Only the components you name are bundled. */\nexport function provideFieldTypes(types: Record<string, Type<any>>): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: FIELD_TYPE_SETS, useValue: types, multi: true },\n ]);\n}\n\n/** Register all 19 built-in field type keys. Convenience for apps that use most of them. */\nexport function provideBuiltInFieldTypes(): EnvironmentProviders {\n return provideFieldTypes(builtInFieldTypes());\n}\n","import { Injectable, inject } from '@angular/core';\nimport { HOOK_REGISTRY } from '../tokens/injection-tokens';\n\n/**\n * HookRegistryService — stores and runs Angular-side pre/post hooks.\n * Consumers register hooks via provideNgxDynamicEntity({ hooks: { 'clients:beforeSave': fn } }).\n */\n@Injectable({ providedIn: 'root' })\nexport class HookRegistryService {\n private readonly registry = inject(HOOK_REGISTRY, { optional: true }) ?? new Map();\n\n has(key: string): boolean {\n return this.registry.has(key);\n }\n\n async run(key: string, data: any, context: any = {}): Promise<any> {\n const hook = this.registry.get(key);\n if (!hook) return data;\n return hook(data, context);\n }\n}\n","import { Injectable } from '@angular/core';\nimport type { EntityFormConfig, FormRule, RuleEvaluationResult } from '@dynamic-entity/core';\nimport { evaluateFormRules, filterRulesForTab } from '@dynamic-entity/core';\n\n/**\n * RulesEvaluationService — evaluates dynamic form rules against active reactive form state.\n */\n@Injectable({ providedIn: 'root' })\nexport class RulesEvaluationService {\n /**\n * Evaluate rules against form values and optional original baseline values.\n */\n evaluate(\n rules: FormRule[] | undefined | null,\n values: Record<string, unknown>,\n originalValues?: Record<string, unknown>,\n ): RuleEvaluationResult {\n return evaluateFormRules(rules, values, originalValues);\n }\n\n /**\n * Filter rules pertinent to a single tab.\n */\n filterForTab(rules: FormRule[] | undefined | null, tabId: string, config: EntityFormConfig): FormRule[] {\n return filterRulesForTab(rules, tabId, config);\n }\n}\n","import { Injectable, Inject, Optional } from '@angular/core';\nimport type { EntityFormConfig } from '@dynamic-entity/core';\nimport { isObservable, firstValueFrom } from 'rxjs';\nimport { CONFIG_SOURCE, type ConfigSourceHandler } from '../tokens/injection-tokens';\n\n@Injectable({ providedIn: 'root' })\nexport class ConfigSourceService {\n private readonly cache = new Map<string, EntityFormConfig>();\n private readonly inFlight = new Map<string, Promise<EntityFormConfig | undefined>>();\n\n private readonly handler?: ConfigSourceHandler;\n\n constructor(@Optional() @Inject(CONFIG_SOURCE) handler?: any) {\n this.handler = handler;\n }\n\n /** Retrieve an entity config by key, with caching and in-flight deduplication. */\n async getConfig(entityKey: string): Promise<EntityFormConfig | undefined> {\n if (!entityKey || !this.handler) return undefined;\n if (this.cache.has(entityKey)) return this.cache.get(entityKey);\n if (this.inFlight.has(entityKey)) return this.inFlight.get(entityKey);\n\n const promise = (async () => {\n try {\n const raw = this.handler!(entityKey);\n let resolved: EntityFormConfig | undefined;\n\n if (isObservable(raw)) {\n resolved = await firstValueFrom(raw as any);\n } else {\n resolved = await Promise.resolve(raw as any);\n }\n\n if (resolved) {\n this.cache.set(entityKey, resolved);\n }\n return resolved;\n } catch (err) {\n console.warn(`ConfigSourceService failed to load config for entity \"${entityKey}\"`, err);\n return undefined;\n } finally {\n this.inFlight.delete(entityKey);\n }\n })();\n\n this.inFlight.set(entityKey, promise);\n return promise;\n }\n\n /** Clear cached configs (e.g. after a config edit in the builder). */\n clearCache(entityKey?: string): void {\n if (entityKey) {\n this.cache.delete(entityKey);\n } else {\n this.cache.clear();\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n Input,\n Output,\n EventEmitter,\n OnChanges,\n OnDestroy,\n OnInit,\n SimpleChanges,\n signal,\n computed,\n inject,\n isDevMode,\n ElementRef,\n ViewChild,\n ViewChildren,\n QueryList,\n HostListener,\n} from '@angular/core';\nimport { NgComponentOutlet } from '@angular/common';\nimport { AbstractControl, FormArray, FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\nimport type {\n AutoPatchConfig,\n EntityFormConfig,\n FormRule,\n NestedFieldConfig,\n NestedTabConfig,\n} from '@dynamic-entity/core';\nimport {\n ambiguousFieldIds,\n collectFieldScopes,\n fieldRefFor,\n parseFieldRef,\n refOf,\n toRefToken,\n applyAutoPatch,\n applyPatchOnTrue,\n migrateRecord,\n evaluateFieldVisibility,\n findTab,\n getTabData,\n getTabPath,\n getValueByPath,\n normalizeArrayStructures,\n normalizeConfigOptions,\n resolveLabel,\n setTabData,\n setValueByPath,\n} from '@dynamic-entity/core';\nimport { DynamicFieldComponent } from './dynamic-field/dynamic-field.component';\nimport { COMMON_MODULES_REGISTRY, RECORD_MIGRATIONS } from '../tokens/injection-tokens';\nimport { ValidatorRegistryService } from '../services/validator-registry.service';\nimport { HookRegistryService } from '../services/hook-registry.service';\nimport { RbacService } from '../services/rbac.service';\nimport { RulesEvaluationService } from '../services/rules-evaluation.service';\nimport { EntityRefSelectionService } from '../services/entity-ref-selection.service';\n\n/**\n * DynamicFormComponent — the main form component.\n * Renders a reactive form from EntityFormConfig with tab support, responsive 12-col grid,\n * rules evaluation, conditional visibility, autoPatch/patchOnTrue, criticalField locking,\n * keyboard shortcuts (Ctrl+S, Esc), and RBAC-gated submission.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-dynamic-form',\n standalone: true,\n imports: [ReactiveFormsModule, DynamicFieldComponent, NgComponentOutlet],\n // Scoped per form instance: entity-ref selections must not leak between concurrent forms.\n providers: [EntityRefSelectionService],\n templateUrl: './dynamic-form.component.html',\n styles: [\n `\n .ngx-form__panel {\n display: grid;\n grid-template-columns: repeat(12, minmax(0, 1fr));\n gap: 16px 20px;\n align-items: start;\n }\n .ngx-form__field-slot {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n min-width: 0;\n }\n .ngx-form__field-slot ngx-dynamic-field {\n flex: 1;\n min-width: 0;\n }\n .ngx-form__lock {\n flex: 0 0 auto;\n margin-top: 22px;\n background: none;\n border: 1px solid transparent;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n line-height: 1;\n padding: 4px 6px;\n }\n .ngx-form__lock:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n }\n @media (max-width: 768px) {\n .ngx-form__panel {\n grid-template-columns: 1fr;\n }\n .ngx-form__field-slot {\n grid-column: span 12 !important;\n }\n }\n `,\n ],\n})\nexport class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {\n // ─── Inputs ───────────────────────────────────────────────────────────────\n /**\n * The schema to render.\n *\n * An accessor pair rather than a plain field: `ngOnChanges` normalises the option shape,\n * and that result is kept here instead of being written back over the input. Reassigning\n * an `@Input` works, but it mutates what the parent handed us — and a parent using OnPush\n * or signals would never observe the replacement anyway.\n *\n * Reads of `this.config` get the normalised copy once it exists, so every internal caller\n * is unaffected.\n */\n @Input()\n set config(value: EntityFormConfig) {\n this.rawConfig = value;\n this.normalizedConfig = undefined; // re-normalised in ngOnChanges\n }\n get config(): EntityFormConfig {\n return this.normalizedConfig ?? this.rawConfig;\n }\n private rawConfig!: EntityFormConfig;\n private normalizedConfig?: EntityFormConfig;\n @Input() rules?: FormRule[];\n @Input() initialData?: Record<string, any>;\n /** Session-original values for `VALUE_CHANGED` rules. Captured from the first build when omitted. */\n @Input() originalData?: Record<string, any>;\n @Input() userRoles: string[] = [];\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n /** Field ids forced read-only while the rest of the form stays editable. */\n @Input() readOnlyFields: string[] = [];\n /**\n * Render rule `info` banners inline. The record editor sets this false and renders its\n * own dismissible versions, so the two do not double up.\n */\n @Input() showInfoBanners: boolean = true;\n @Input() loading: boolean = false;\n @Input() error: string | null = null;\n /**\n * Milliseconds to debounce `formChange`. The reference debounces at 300ms so a consumer\n * re-rendering on every value change is not driven per keystroke. Zero emits\n * synchronously, which the record editor relies on for its own bookkeeping.\n */\n @Input() changeDebounceMs: number = 0;\n /**\n * Preview mode: seed one empty row per `array` field so the structure is visible, then\n * disable the form. Used by the builder's live preview.\n */\n @Input() preview: boolean = false;\n\n // ─── Outputs ──────────────────────────────────────────────────────────────\n @Output() formSubmit = new EventEmitter<Record<string, any>>();\n @Output() formChange = new EventEmitter<Record<string, any>>();\n @Output() formReset = new EventEmitter<void>();\n /** The visible tab changed. Lets a host track it without reaching into this component. */\n @Output() activeTabChange = new EventEmitter<string>();\n /**\n * Emitted when a `beforeSave` hook aborted the save — by returning false or throwing.\n * `formSubmit` does not fire in that case.\n */\n @Output() saveRejected = new EventEmitter<{ reason: string; error?: unknown }>();\n\n // ─── Services ─────────────────────────────────────────────────────────────\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly fb = inject(FormBuilder);\n private readonly validatorRegistry = inject(ValidatorRegistryService);\n private readonly hookRegistry = inject(HookRegistryService);\n private readonly rbacService = inject(RbacService);\n private readonly rulesEvaluation = inject(RulesEvaluationService);\n private readonly entityRefSelection = inject(EntityRefSelectionService);\n private readonly commonModulesRegistry = inject(COMMON_MODULES_REGISTRY, { optional: true });\n private readonly migrations = inject(RECORD_MIGRATIONS, { optional: true }) ?? [];\n\n protected readonly Object = Object;\n\n // ─── Signals (local reactive state) ───────────────────────────────────────\n readonly activeTab = signal<string>('');\n readonly activeSubTab = signal<string>('');\n readonly isSaving = signal(false);\n readonly formValues = signal<Record<string, any>>({});\n /** Baseline captured at first build, used when `originalData` is not supplied. */\n readonly sessionBaseline = signal<Record<string, any>>({});\n /** Critical fields the user has explicitly unlocked for editing. */\n readonly unlockedFields = signal<ReadonlySet<string>>(new Set<string>());\n\n /** The active tab's field panel, focused after a tab switch. */\n @ViewChild('formPanel') private formPanel?: ElementRef<HTMLElement>;\n\n /** The hosted field components, so an external control-state change can reach them. */\n @ViewChildren(DynamicFieldComponent) private fieldHosts?: QueryList<DynamicFieldComponent>;\n\n // ─── Form ─────────────────────────────────────────────────────────────────\n form!: FormGroup;\n\n private valueSub?: Subscription;\n private statusSub?: Subscription;\n private selectionSub?: Subscription;\n /** Previous values, for detecting `patchOnTrue` false→true transitions. */\n private previousValues: Record<string, any> = {};\n\n // ─── Keyboard Shortcuts ───────────────────────────────────────────────────\n @HostListener('window:keydown', ['$event'])\n handleKeyboardEvent(event: KeyboardEvent): void {\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {\n event.preventDefault();\n if (!this.readonly && this.canSubmit && this.form?.valid) {\n this.submit();\n }\n }\n }\n\n // ─── Computed ─────────────────────────────────────────────────────────────\n readonly ruleResult = computed(() =>\n this.rulesEvaluation.evaluate(this.rules, this.formValues(), this.baseline()),\n );\n\n /**\n * Critical fields whose value differs from the session baseline.\n * These drive the deferred `VALUE_CHANGED` banner — a critical edit is announced once,\n * against the value the record had when the session started, not per keystroke.\n */\n readonly changedCriticalFields = computed<NestedFieldConfig[]>(() => {\n const baseline = this.baseline();\n if (!baseline || Object.keys(baseline).length === 0) return [];\n const values = this.formValues();\n return this.allFields().filter(\n f => f.criticalField && !this.sameValue(values[f.id], baseline[f.id]),\n );\n });\n\n get tabs(): NestedTabConfig[] {\n return this.config?.tabs || [];\n }\n\n get visibleTabs(): NestedTabConfig[] {\n const hidden = this.ruleResult().hiddenTabs;\n return this.tabs.filter(tab => tab.visibility !== false && !hidden.includes(tab.id));\n }\n\n get activeTabConfig(): NestedTabConfig | null {\n const tabId = this.activeTab();\n if (!tabId) return this.visibleTabs[0] ?? null;\n return findTab(this.tabs, tabId);\n }\n\n get visibleSubTabs(): NestedTabConfig[] {\n const active = this.activeTabConfig;\n if (!active?.children || active.children.length === 0) return [];\n const hidden = this.ruleResult().hiddenTabs;\n return active.children.filter(tab => tab.visibility !== false && !hidden.includes(tab.id));\n }\n\n get activeSubTabConfig(): NestedTabConfig | null {\n const subTabs = this.visibleSubTabs;\n if (!subTabs.length) return null;\n const subId = this.activeSubTab();\n return subTabs.find(s => s.id === subId) ?? subTabs[0];\n }\n\n get activeTabModuleComponent(): any | null {\n const active = this.activeSubTabConfig ?? this.activeTabConfig;\n if (!active?.moduleName || !this.commonModulesRegistry) return null;\n const entry = this.commonModulesRegistry.find(\n m => m.id === active.moduleName || m.component === active.moduleName,\n );\n return entry ? entry.component : null;\n }\n\n get fieldsForActiveTab(): NestedFieldConfig[] {\n const active = this.activeSubTabConfig ?? this.activeTabConfig;\n if (active?.moduleName) return [];\n const rawFields = active ? (active.fields || []) : ((this.config?.tabs || []).flatMap(t => t.fields || []));\n const currentValues = this.formValues();\n const hiddenFields = new Set<string>(this.ruleResult().hiddenFields);\n\n return rawFields.filter(\n field => evaluateFieldVisibility(field, currentValues) && !this.namesField(hiddenFields, field),\n );\n }\n\n /**\n * Entity-level permissions for the current roles.\n *\n * Cached rather than recomputed: this is read from the template several times per change\n * detection pass, and a fresh object each time is both wasted allocation and a new\n * identity for anything comparing by reference. Invalidated in `ngOnChanges` when\n * `config` or `userRoles` change, which are its only inputs.\n */\n get permissions(): ReturnType<RbacService['getPermissions']> {\n return (this.permissionsCache ??= this.rbacService.getPermissions(this.config, this.userRoles));\n }\n\n private permissionsCache: ReturnType<RbacService['getPermissions']> | null = null;\n\n /**\n * Whether the current roles may see this record at all.\n *\n * `permissions.view` used to be computed and thrown away — a user whose roles failed it\n * still received the complete form with every value in the DOM. It is honoured now.\n *\n * As with masking, this is presentational: it stops the browser rendering data, it does\n * not stop the data reaching the browser. Authorize on the server.\n */\n get canView(): boolean {\n return this.permissions.canView;\n }\n\n /**\n * Whether the current roles may delete this record.\n *\n * The library ships no delete affordance, so this is surfaced for the consumer to gate\n * their own — exposed rather than dropped, because a permission the schema declares\n * should be answerable.\n */\n get canDelete(): boolean {\n return this.permissions.canDelete;\n }\n\n get canSubmit(): boolean {\n return this.canView && this.permissions.canEdit && !this.readonly;\n }\n\n /**\n * Errors raised by `validation` rules, keyed by the target they point at.\n *\n * A rule can declare the record invalid independently of Angular's validators, so form\n * validity alone is not the whole picture. `DynamicRecordFormComponent.saveSection()`\n * has always honoured these; `submit()` did not, which meant the same rule blocked one\n * save path and merely painted a banner on the other — and anything wiring\n * `(formSubmit)` to persistence wrote records the rules engine had already rejected.\n */\n get ruleValidationErrors(): Record<string, string> {\n return this.ruleResult().validationErrors;\n }\n\n /** True when a `validation` rule is currently blocking submission. */\n get hasRuleErrors(): boolean {\n return Object.keys(this.ruleValidationErrors).length > 0;\n }\n\n /**\n * True while an async validator is still running.\n *\n * Angular reports a control with an outstanding async check as `pending`, and `invalid` is\n * false until it settles — so without this a form could be submitted in the gap before a\n * uniqueness check came back.\n */\n get isValidating(): boolean {\n return this.form.pending;\n }\n\n /** Single source of truth for both the submit guard and the button's disabled state. */\n get submitBlocked(): boolean {\n return this.form.invalid || this.form.pending || this.hasRuleErrors;\n }\n\n ngOnInit(): void {\n this.selectionSub = this.entityRefSelection.selection$.subscribe(({ fieldId, option }) => {\n this.runAutoPatch(fieldId, option?.record);\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['config'] || changes['userRoles']) {\n this.permissionsCache = null;\n }\n if (changes['config'] && this.rawConfig) {\n // Configs arrive as plain JSON from storage or an API, where TypeScript cannot enforce\n // the option shape. Normalise here, at the library boundary, so everything downstream\n // can rely on an option being a LocalizedText. Returns the same object when it already\n // is, so a well-formed config costs nothing.\n // Kept in a field of our own rather than written back to the @Input. Reassigning an\n // input works, but it surprises a parent that holds the same object — and a parent\n // using OnPush or signals would not see the replacement anyway.\n this.normalizedConfig = normalizeConfigOptions(this.config);\n }\n if (changes['config'] || changes['initialData']) {\n this.buildForm();\n if (this.visibleTabs.length > 0 && !this.activeTab()) {\n this.setActiveTab(this.visibleTabs[0].id);\n }\n }\n }\n\n ngOnDestroy(): void {\n this.valueSub?.unsubscribe();\n this.statusSub?.unsubscribe();\n this.selectionSub?.unsubscribe();\n }\n\n /**\n * `focusPanel: false` is for a caller that is about to focus something more specific.\n *\n * Activating a tab moves focus into its panel, which is right for a keyboard user pressing\n * a tab. A quick-jump also switches tabs, but then focuses the field it was aiming at — and\n * the panel focus runs on `requestAnimationFrame`, after `afterNextRender`, so it landed\n * second and took the focus back every time. Saying so is better than out-timing it.\n */\n setActiveTab(tabId: string, options?: { focusPanel?: boolean }): void {\n const changed = this.activeTab() !== tabId;\n if (changed) this.activeTabChange.emit(tabId);\n this.activeTab.set(tabId);\n if (changed && options?.focusPanel !== false) this.focusActivePanel();\n const parent = findTab(this.tabs, tabId);\n if (parent?.children?.length) {\n this.activeSubTab.set(parent.children[0].id);\n } else {\n this.activeSubTab.set('');\n }\n }\n\n setActiveSubTab(subTabId: string, options?: { focusPanel?: boolean }): void {\n const changed = this.activeSubTab() !== subTabId;\n this.activeSubTab.set(subTabId);\n if (changed && options?.focusPanel !== false) this.focusActivePanel();\n }\n\n getFieldSpan(field: NestedFieldConfig): string {\n const span = field.colSpan ?? 12;\n return `span ${Math.min(12, Math.max(1, span))}`;\n }\n\n // ─── criticalField locking ────────────────────────────────────────────────\n\n /** A critical field stays read-only until the user deliberately unlocks it. */\n isFieldLocked(field: NestedFieldConfig): boolean {\n return !!field.criticalField && !this.unlockedFields().has(field.id);\n }\n\n /**\n * Whether this field renders read-only, from any of the four reasons: the whole form,\n * the field's own flag, a caller-supplied `readOnlyFields` entry, or a criticalField lock.\n */\n isFieldReadonly(field: NestedFieldConfig): boolean {\n return (\n this.readonly ||\n // `permissions.edit` gated the Save button and nothing else, so a role without edit\n // rights received a fully editable form: it could type into every field, and only\n // discovered the record was not theirs to change when no Save button appeared. The\n // permission means the record may not be edited, so the fields say so.\n !this.permissions.canEdit ||\n !!field.readonly ||\n this.readOnlyFields.includes(field.id) ||\n this.isFieldLocked(field)\n );\n }\n\n toggleFieldLock(field: NestedFieldConfig): void {\n // Unlocking is an edit. Without the permission check a viewer could open the lock on a\n // critical field, which is the one control that exists to make editing deliberate.\n if (!field.criticalField || this.readonly || !this.permissions.canEdit) return;\n const next = new Set(this.unlockedFields());\n if (next.has(field.id)) next.delete(field.id);\n else next.add(field.id);\n this.unlockedFields.set(next);\n }\n\n resolveFieldLabel(field: NestedFieldConfig): string {\n return resolveLabel(field.label, this.language);\n }\n\n // ─── Form construction ────────────────────────────────────────────────────\n\n private buildForm(): void {\n if (!this.config) return;\n const group: Record<string, AbstractControl> = {};\n\n const buildTabControls = (tabs: NestedTabConfig[], parentGroup: Record<string, AbstractControl>) => {\n for (const tab of tabs) {\n if (tab.flatData) {\n for (const field of tab.fields || []) {\n this.buildFieldControl(field, parentGroup);\n }\n if (tab.children) buildTabControls(tab.children, parentGroup);\n } else {\n const tabGroup: Record<string, AbstractControl> = {};\n for (const field of tab.fields || []) {\n this.buildFieldControl(field, tabGroup);\n }\n if (tab.children) buildTabControls(tab.children, tabGroup);\n parentGroup[tab.id] = this.fb.group(tabGroup);\n }\n }\n };\n\n buildTabControls(this.config.tabs || [], group);\n this.form = this.fb.group(group);\n this.warnAmbiguousRuleReferences();\n\n if (this.initialData) {\n this.patchForm(this.upgradeRecord(this.initialData));\n }\n\n const initialFlattened = this.flattenFormValues();\n this.formValues.set(initialFlattened);\n this.previousValues = { ...initialFlattened };\n this.sessionBaseline.set({ ...initialFlattened });\n this.unlockedFields.set(new Set<string>());\n this.syncHiddenFieldState(initialFlattened);\n\n if (this.preview) {\n // Show what an array field looks like rather than an empty slot, then freeze.\n for (const field of this.allFields()) {\n if (field.type !== 'array') continue;\n const array = this.getArrayControl(field.id);\n if (array && array.length === 0) array.push(this.buildArrayRow(field, undefined));\n }\n this.form.disable({ emitEvent: false });\n }\n\n // Rebuilding must not stack subscriptions on successive config/data changes.\n this.valueSub?.unsubscribe();\n const changes$ = this.changeDebounceMs > 0\n ? this.form.valueChanges.pipe(debounceTime(this.changeDebounceMs))\n : this.form.valueChanges;\n // Validity is not value: an async validator settling flips `pending` and then `invalid`\n // with no value change and no template event, so under OnPush the Save button would\n // never re-enable. submitBlocked reads form.pending and form.invalid, so this is what\n // keeps it honest.\n this.statusSub?.unsubscribe();\n this.statusSub = this.form.statusChanges.subscribe(() => this.cdr.markForCheck());\n\n this.valueSub = changes$.subscribe(() => {\n const flattened = this.flattenFormValues();\n this.formValues.set(flattened);\n this.runPatchOnTrue(flattened);\n this.syncHiddenFieldState(flattened);\n this.previousValues = { ...flattened };\n this.formChange.emit(this.extractRecord());\n });\n }\n\n private buildFieldControl(field: NestedFieldConfig, group: Record<string, AbstractControl>): void {\n if (field.type === 'group') {\n const subGroup: Record<string, AbstractControl> = {};\n for (const child of field.children || []) {\n this.buildFieldControl(child, subGroup);\n }\n group[field.id] = this.fb.group(subGroup);\n } else if (field.type === 'array') {\n group[field.id] = this.fb.array([]);\n } else {\n const validators = this.validatorRegistry.resolveFromConfig(field.validators);\n const asyncValidators = this.validatorRegistry.resolveAsyncFromConfig(field.validators);\n group[field.id] = this.fb.control(\n { value: field.defaultValue ?? null, disabled: field.disabled ?? false },\n validators,\n asyncValidators,\n );\n }\n }\n\n /** One row of an `array` field: a FormGroup when the field declares columns, else a bare control. */\n /**\n * The `FormArray` behind an `array` field, for callers that manage rows themselves —\n * the record editor's inline row drawer.\n */\n getArrayControl(fieldId: string, tabId?: string): FormArray | null {\n const ctrl = this.getControl(fieldId, tabId);\n return ctrl instanceof FormArray ? ctrl : null;\n }\n\n /**\n * Build one detached row for an `array` field, with the field's own validators applied.\n * Exposed so a row can be edited outside the form and pushed on save.\n */\n createArrayRow(field: NestedFieldConfig, value?: unknown): AbstractControl {\n return this.buildArrayRow(field, value);\n }\n\n private buildArrayRow(field: NestedFieldConfig | undefined, item: unknown): AbstractControl {\n if (!field?.children?.length) return this.fb.control(item);\n\n const rowGroup: Record<string, AbstractControl> = {};\n for (const child of field.children) {\n this.buildFieldControl(child, rowGroup);\n }\n const group = this.fb.group(rowGroup);\n if (item && typeof item === 'object') group.patchValue(item as Record<string, unknown>);\n return group;\n }\n\n /**\n * Mark every control touched, then re-check the field components.\n *\n * They are OnPush and `touched` is flipped from outside their own template, so the second\n * half is what makes the error messages actually appear.\n */\n private markAllTouched(): void {\n this.form.markAllAsTouched();\n this.fieldHosts?.forEach(host => host.refresh());\n }\n\n /**\n * Bring a record up to the config's `version` before it reaches the form.\n *\n * Done here because this is the one place a record enters the renderer, so a consumer\n * cannot forget it. Migration is a no-op unless the consumer registered steps *and* the\n * record is behind — an unstamped record is deliberately left alone (see `migrateRecord`).\n *\n * A missing or broken step throws from core. That is not swallowed: rendering a\n * half-understood record would write it back in a shape matching neither schema.\n */\n private upgradeRecord(data: Record<string, any>): Record<string, any> {\n if (!this.migrations.length || !this.config) return data;\n\n const result = migrateRecord(data, this.config, this.migrations);\n if (result.applied.length && isDevMode()) {\n console.info(\n `[ngx-dynamic-entity] Migrated a \"${this.config.entity}\" record from config version ` +\n `${result.from} to ${result.to} (steps: ${result.applied.join(', ')}).`,\n );\n }\n return result.record;\n }\n\n private patchForm(data: Record<string, any>): void {\n if (!data || !this.form) return;\n const fieldsById = new Map(this.allFields().map(f => [f.id, f]));\n const patchedFieldIds = new Set<string>();\n\n const walkTabs = (tabs: NestedTabConfig[]) => {\n for (const tab of tabs) {\n const tabData = getTabData(tab.id, data, this.config);\n for (const field of tab.fields || []) {\n let val = tabData && typeof tabData === 'object' ? tabData[field.id] : undefined;\n if (field.refererField) {\n const refVal = getValueByPath(data, field.refererField);\n if (refVal !== undefined) val = refVal;\n }\n if (val === undefined) continue;\n\n const ctrl = this.getControl(field.id, tab.id);\n if (!ctrl) continue;\n\n if (ctrl instanceof FormArray && Array.isArray(val)) {\n ctrl.clear();\n for (const item of val) {\n ctrl.push(this.buildArrayRow(fieldsById.get(field.id), item));\n }\n } else {\n ctrl.patchValue(val, { emitEvent: false });\n }\n patchedFieldIds.add(field.id);\n }\n if (tab.children) walkTabs(tab.children);\n }\n };\n\n walkTabs(this.config.tabs || []);\n this.warnUnconsumedInitialData(data, fieldsById, patchedFieldIds);\n }\n\n /**\n * A record is nested by tab id (`{ tabId: { fieldId: value } }`) unless the tab sets\n * `flatData: true`. Handing a flat record to a nested tab finds nothing, so the fields\n * stay empty — with no error and no clue. That silent miss is the most expensive way to\n * lose an hour with this library, so name it in dev builds.\n *\n * Only top-level keys that match a known field id are reported: anything else is assumed\n * to be the consumer's own record metadata (ids, timestamps, `_configVersion`) and is not\n * our business.\n */\n private warnUnconsumedInitialData(\n data: Record<string, any>,\n fieldsById: Map<string, NestedFieldConfig>,\n patchedFieldIds: Set<string>,\n ): void {\n if (!isDevMode() || !this.config) return;\n\n const tabIds = new Set<string>();\n const collectTabIds = (tabs: NestedTabConfig[]) => {\n for (const tab of tabs) {\n tabIds.add(tab.id);\n if (tab.children) collectTabIds(tab.children);\n }\n };\n collectTabIds(this.config.tabs || []);\n\n const unconsumed = Object.keys(data).filter(\n key =>\n !tabIds.has(key) && // a tab id at the root is the nested container, not a stray field\n data[key] !== undefined &&\n fieldsById.has(key) &&\n !patchedFieldIds.has(key) &&\n !this.warnedUnconsumedKeys.has(key),\n );\n if (!unconsumed.length) return;\n\n for (const key of unconsumed) this.warnedUnconsumedKeys.add(key);\n\n const shown = unconsumed.slice(0, 5).join(', ');\n const more = unconsumed.length > 5 ? ` (+${unconsumed.length - 5} more)` : '';\n const plural = unconsumed.length === 1;\n console.warn(\n `[ngx-dynamic-entity] initialData has top-level ${plural ? 'key' : 'keys'} matching ` +\n `${plural ? 'a field that was' : 'fields that were'} not populated: ${shown}${more}. ` +\n `A record is nested by tab id ({ tabId: { fieldId: value } }) unless the tab sets ` +\n `flatData: true. Either nest the value under its tab id, or set flatData: true on ` +\n `the tab holding ${plural ? 'that field' : 'those fields'}.`,\n );\n }\n\n /** Warn once per key per form instance — patchForm re-runs on every initialData change. */\n private readonly warnedUnconsumedKeys = new Set<string>();\n\n /** Assemble full nested record from per-tab FormGroups, respecting flatData, refererField & arrays. */\n extractRecord(): Record<string, any> {\n if (!this.form || !this.config) return {};\n let record: Record<string, any> = {};\n\n const walkTabs = (tabs: NestedTabConfig[]) => {\n for (const tab of tabs) {\n const fieldValBag: Record<string, unknown> = {};\n for (const field of tab.fields || []) {\n const ctrl = this.getControl(field.id, tab.id);\n if (ctrl) {\n fieldValBag[field.id] = ctrl.value;\n }\n }\n\n setTabData(record, tab.id, fieldValBag, this.config);\n\n for (const field of tab.fields || []) {\n if (field.refererField) {\n const ctrl = this.getControl(field.id, tab.id);\n if (ctrl) {\n setValueByPath(record, field.refererField, ctrl.value);\n }\n }\n }\n\n if (tab.children) walkTabs(tab.children);\n }\n };\n\n walkTabs(this.config.tabs || []);\n record = normalizeArrayStructures(record, this.config);\n return record;\n }\n\n /**\n * Warns when a rule names a field id that two scopes define.\n *\n * Field ids are unique per scope, so `address` may exist on both Personal Details and Work\n * Details — but a rule carries a bare id and no scope, so it cannot say which one it means.\n * `flattenFormValues` keys by bare id, so one of the two silently wins and the rule reads\n * whichever landed there.\n *\n * `validateConfig({ rules })` catches this statically. The check here remains because\n * consumers that never call the validator still get a signal in development.\n */\n private warnAmbiguousRuleReferences(): void {\n if (!isDevMode() || !this.rules?.length || !this.config) return;\n\n const ambiguous = ambiguousFieldIds(this.config);\n if (ambiguous.size === 0) return;\n\n const referenced = new Set<string>();\n for (const rule of this.rules) {\n if (rule.fieldId) referenced.add(rule.fieldId);\n for (const condition of rule.conditions ?? []) {\n if (condition.compareToField) referenced.add(condition.compareToField);\n }\n for (const target of rule.targets ?? []) {\n if (target.type === 'field' && target.id) referenced.add(target.id);\n }\n }\n\n for (const raw of referenced) {\n const parsed = parseFieldRef(raw);\n if (parsed.kind === 'ref') continue;\n const id = parsed.value;\n const scopes = ambiguous.get(id);\n if (!scopes || DynamicFormComponent.warnedAmbiguousIds.has(id)) continue;\n DynamicFormComponent.warnedAmbiguousIds.add(id);\n console.warn(\n `[ngx-dynamic-entity] A rule references field \"${id}\", which is defined in ${scopes.join(' and ')}. ` +\n `A bare id cannot say which one is meant, so the rule will read whichever the form finds first. ` +\n `Name it by path instead, as [${scopes[0]}.${id}].`,\n );\n }\n }\n\n private static readonly warnedAmbiguousIds = new Set<string>();\n\n /**\n * The value map rules and `showWhen` are evaluated against.\n *\n * Every field appears under two keys: its bare id, and its `refererField` path wrapped in brackets.\n * The bare id is what every config written so far uses and is kept exactly as it was — but\n * ids are unique per scope, so when two scopes define one the last field walked wins and\n * the rule reads whichever that is. `[personal.address]` names one field and cannot be\n * ambiguous, which is why a rule that has to distinguish them uses the ref.\n *\n * Both live in one flat map on purpose: `evaluateFormRules` takes a `Record<string,\n * unknown>` and needs no knowledge of refs at all — the extra keys simply resolve.\n */\n /**\n * Whether a rule result names this field.\n *\n * A rule target is either a bare field id — how every config so far addresses a field — or\n * a bracketed path, which is the only way to name one of two fields that share an id.\n * Both have to match, or a rule written either way would fail to hide what it targeted.\n */\n private namesField(names: ReadonlySet<string>, field: NestedFieldConfig): boolean {\n if (names.has(field.id)) return true;\n const ref = field.refererField ?? this.pathFor(field);\n return ref ? names.has(toRefToken(ref)) : false;\n }\n\n /** The field's declared path, or the one its position implies when it carries none. */\n private pathFor(field: NestedFieldConfig): string | null {\n const entry = collectFieldScopes(this.config).find(e => e.field === field);\n return entry ? fieldRefFor(entry.scope, field.id) : null;\n }\n\n private flattenFormValues(): Record<string, any> {\n const out: Record<string, any> = {};\n for (const entry of collectFieldScopes(this.config)) {\n const field = entry.field;\n if (!field?.id) continue;\n const ctrl = this.getControl(field.id, entry.scope.split('.').pop());\n if (!ctrl) continue;\n out[field.id] = ctrl.value;\n out[toRefToken(refOf(field, entry.scope))] = ctrl.value;\n }\n return out;\n }\n\n private getTabGroup(tabId: string): FormGroup | null {\n const path = getTabPath(this.config?.tabs, tabId);\n if (!path || path.length === 0) return this.form;\n let curr: AbstractControl | null = this.form;\n for (const p of path) {\n if (!curr || !(curr instanceof FormGroup)) return null;\n curr = curr.get(p);\n }\n return curr instanceof FormGroup ? curr : null;\n }\n\n // ─── autoPatch / patchOnTrue ──────────────────────────────────────────────\n\n /**\n * `autoPatch` — copy mapped fields out of the record the user just selected in an\n * entity-ref field into the configured target tab's controls.\n */\n private runAutoPatch(fieldId: string, record: Record<string, unknown> | undefined): void {\n if (!record) return;\n const field = this.allFields().find(f => f.id === fieldId);\n const autoPatch = field?.autoPatch;\n if (!autoPatch) return;\n\n const patch = applyAutoPatch(autoPatch, record);\n for (const [targetId, value] of Object.entries(patch)) {\n const control = this.resolveTargetControl(autoPatch, targetId);\n control?.patchValue(value);\n }\n // Readonly targets interpolate `control.value` under OnPush. `detectChanges` on the\n // hosted component flushes that write immediately — `markForCheck` waits for a later\n // tick that a Playwright selection never schedules.\n this.fieldHosts?.forEach(host => host.refresh());\n }\n\n /**\n * `patchOnTrue` — when a boolean/checkbox field transitions to `true`,\n * copy `from` → `to` within the current record.\n */\n private runPatchOnTrue(values: Record<string, any>): void {\n for (const field of this.allFields()) {\n const mappings = field.patchOnTrue;\n if (!mappings?.length) continue;\n\n const wasTrue = this.previousValues[field.id] === true;\n const isTrue = values[field.id] === true;\n if (!isTrue || wasTrue) continue;\n\n const patch = applyPatchOnTrue(mappings, values);\n for (const [targetId, value] of Object.entries(patch)) {\n this.getControl(targetId)?.patchValue(value, { emitEvent: false });\n }\n }\n }\n\n /** Prefer a control declared on the configured target tab; fall back to a top-level control. */\n private resolveTargetControl(autoPatch: AutoPatchConfig, targetId: string): AbstractControl | null {\n const tab = findTab(this.tabs, autoPatch.targetTab);\n const inTargetTab = (tab?.fields ?? []).some(f => f.id === targetId);\n if (tab && !inTargetTab) return null;\n return this.getControl(targetId, autoPatch.targetTab);\n }\n\n // ─── Helpers ──────────────────────────────────────────────────────────────\n\n /**\n * The fields the render filter operates on — a tab's own fields, at every tab depth.\n * Deliberately not `allFields()`: `group` and `array` children are shown or hidden with\n * their parent, and toggling a child's state independently would fight the parent's.\n */\n private tabFields(): NestedFieldConfig[] {\n const out: NestedFieldConfig[] = [];\n const walk = (tabs: NestedTabConfig[] | undefined) => {\n for (const tab of tabs ?? []) {\n out.push(...(tab.fields ?? []));\n walk(tab.children);\n }\n };\n walk(this.config?.tabs);\n return out;\n }\n\n /**\n * Keep a hidden field's control out of form validity.\n *\n * A field hidden by a rule or a `showWhen` condition is filtered out of the render, but\n * its validators stay attached — so a hidden *required* field holds `form.invalid` true\n * forever, permanently disabling Save with nothing on screen to explain why.\n *\n * Disabling is the fix rather than stripping validators: Angular excludes disabled\n * controls from validity, and the field's own validators survive intact for when it\n * comes back. Values are untouched — `flattenFormValues` and `extractRecord` both read\n * `control.value`, which a disabled control still carries, so rule evaluation and the\n * emitted record see exactly what they saw before. That also keeps this from feeding\n * back on itself: hiding a field cannot change the values the rules are evaluated over.\n *\n * The visibility predicate is the same one `fieldsForActiveTab` filters with, so what is\n * rendered and what counts toward validity cannot drift apart.\n */\n private syncHiddenFieldState(values: Record<string, any>): void {\n if (this.preview) return; // preview freezes the whole form on purpose\n\n const hiddenByRule = new Set<string>(this.ruleResult().hiddenFields);\n\n for (const field of this.tabFields()) {\n const ctrl = this.getControl(field.id);\n if (!ctrl) continue;\n\n const hidden = this.namesField(hiddenByRule, field) || !evaluateFieldVisibility(field, values);\n\n if (hidden) {\n if (ctrl.enabled) ctrl.disable({ emitEvent: false });\n } else if (ctrl.disabled && !field.disabled) {\n ctrl.enable({ emitEvent: false });\n }\n }\n }\n\n /** Every field in the config, including `group`/`array` children. */\n private allFields(): NestedFieldConfig[] {\n const out: NestedFieldConfig[] = [];\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const f of fields ?? []) {\n out.push(f);\n if (f.children?.length) walkFields(f.children);\n }\n };\n const walkTabs = (tabs: NestedTabConfig[] | undefined) => {\n for (const t of tabs ?? []) {\n walkFields(t.fields);\n walkTabs(t.children);\n }\n };\n walkTabs(this.config?.tabs);\n return out;\n }\n\n /** An empty `originalData` counts as \"not supplied\" — fall back to the captured baseline. */\n private baseline(): Record<string, any> {\n const supplied = this.originalData;\n if (supplied && Object.keys(supplied).length > 0) return supplied;\n return this.sessionBaseline();\n }\n\n private sameValue(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n const aEmpty = a === null || a === undefined || a === '';\n const bEmpty = b === null || b === undefined || b === '';\n if (aEmpty && bEmpty) return true;\n if (typeof a === 'object' || typeof b === 'object') {\n return JSON.stringify(a ?? null) === JSON.stringify(b ?? null);\n }\n return false;\n }\n\n getControl(fieldId: string, currentTabId?: string): AbstractControl | null {\n if (!this.form) return null;\n\n // A bracketed path names exactly one control, and the form nests by tab exactly as the\n // path does — so `form.get('work.address')` walks straight to it. Anything that names a\n // field can therefore use a path: `showWhen` keys, `patchOnTrue` mappings and `autoPatch`\n // targets, not only rules.\n const parsed = parseFieldRef(fieldId);\n if (parsed.kind === 'ref') return this.form.get(parsed.value);\n\n if (currentTabId) {\n const tabGrp = this.getTabGroup(currentTabId);\n const ctrl = tabGrp?.get(fieldId);\n if (ctrl) return ctrl;\n }\n\n const rootCtrl = this.form.get(fieldId);\n if (rootCtrl) return rootCtrl;\n\n const findInGroup = (group: FormGroup): AbstractControl | null => {\n for (const key of Object.keys(group.controls)) {\n const c = group.controls[key];\n if (key === fieldId) return c;\n if (c instanceof FormGroup) {\n const found = findInGroup(c);\n if (found) return found;\n }\n }\n return null;\n };\n\n return findInGroup(this.form);\n }\n\n /**\n * Move focus into the newly shown panel.\n *\n * Activating a tab replaces everything below it while focus stays on the tab button, so a\n * screen-reader or keyboard user is given no indication that the content changed and must\n * tab back through the strip to reach it. Deferred a frame because the panel's contents\n * are rendered by the change detection this call is part of.\n */\n private focusActivePanel(): void {\n if (typeof requestAnimationFrame !== 'function') return;\n requestAnimationFrame(() => this.formPanel?.nativeElement?.focus?.());\n }\n\n /** Accessible name for the field panel — it is the tabpanel for the active tab. */\n get activeTabLabel(): string {\n const tab = this.activeSubTabConfig ?? this.activeTabConfig;\n return tab ? this.resolveTabLabel(tab) : '';\n }\n\n /**\n * Why a referenced field is flagged.\n *\n * `hasDrift` was written by the builder and read by nothing at runtime, so a field whose\n * source definition had changed since it was linked looked entirely normal to the person\n * filling the form in.\n */\n driftHint(field: NestedFieldConfig): string {\n const source = field.referencedEntityKey\n ? `\"${field.referencedEntityKey}\"`\n : 'its source entity';\n return `This field is linked to ${source} and its definition there has changed since it was linked.`;\n }\n\n resolveTabLabel(tab: NestedTabConfig): string {\n return resolveLabel(tab.label, this.language);\n }\n\n async submit(): Promise<void> {\n if (!this.canSubmit || this.submitBlocked) {\n this.markAllTouched();\n return;\n }\n\n const rawData = this.extractRecord();\n let processedData = rawData;\n\n this.isSaving.set(true);\n try {\n // beforeSave can now abort the save: returning false, or throwing, stops it. Previously\n // its return value simply replaced the payload and the submit proceeded regardless, so\n // a hook that wanted to veto — a server-side check, a confirmation — had no way to.\n const hookKey = `${this.config?.entity}:beforeSave`;\n if (this.hookRegistry.has(hookKey)) {\n const result = await this.hookRegistry.run(hookKey, processedData);\n if (result === false) {\n this.saveRejected.emit({ reason: 'beforeSave returned false' });\n return;\n }\n // Anything else is the payload to submit; `undefined` means \"unchanged\".\n if (result !== undefined && result !== true) processedData = result;\n }\n\n this.formSubmit.emit(processedData);\n } catch (err) {\n // A hook that throws aborts the save and reports why, rather than the error escaping\n // into an unhandled rejection with the form left looking as though it saved.\n this.saveRejected.emit({ reason: err instanceof Error ? err.message : String(err), error: err });\n } finally {\n this.isSaving.set(false);\n }\n }\n\n reset(): void {\n this.form.reset();\n if (this.initialData) this.patchForm(this.initialData);\n const values = this.flattenFormValues();\n this.formValues.set(values);\n this.previousValues = { ...values };\n this.unlockedFields.set(new Set<string>());\n this.formReset.emit();\n }\n}\n","@if (canView) {\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\" class=\"ngx-form\" novalidate>\n\n <!-- Error message banner -->\n @if (error) {\n <div class=\"ngx-form__error-banner\" role=\"alert\" data-testid=\"form-error\">{{ error }}</div>\n }\n\n <!-- Rules Info Banners -->\n @for (infoKey of showInfoBanners ? Object.keys(ruleResult().infoBanners) : []; track infoKey) {\n <div class=\"ngx-form__info-banner\" role=\"status\" [attr.data-testid]=\"'info-banner-' + infoKey\">\n ℹ️ {{ ruleResult().infoBanners[infoKey] }}\n </div>\n }\n\n <!-- Rules Validation Errors & Warnings -->\n @for (errKey of Object.keys(ruleResult().validationErrors); track errKey) {\n <div class=\"ngx-form__error-banner\" role=\"alert\" [attr.data-testid]=\"'rule-error-' + errKey\">\n ⚠️ {{ ruleResult().validationErrors[errKey] }}\n </div>\n }\n @for (warnKey of Object.keys(ruleResult().validationWarnings); track warnKey) {\n <div class=\"ngx-form__warning-banner\" role=\"status\" [attr.data-testid]=\"'rule-warning-' + warnKey\">\n ⚡ {{ ruleResult().validationWarnings[warnKey] }}\n </div>\n }\n\n <!-- Deferred VALUE_CHANGED notice for criticalField edits (vs session baseline) -->\n @if (changedCriticalFields().length > 0) {\n <div class=\"ngx-form__warning-banner\" role=\"status\" data-testid=\"critical-change-banner\">\n 🔒 Critical field changed:\n @for (field of changedCriticalFields(); track field.id) {\n <span>{{ resolveFieldLabel(field) }}{{ $last ? '' : ', ' }}</span>\n }\n — this differs from the value at the start of this session.\n </div>\n }\n\n <!-- Primary Tab bar — only if visible tabs defined -->\n @if (visibleTabs.length > 0) {\n <div class=\"ngx-form__tabs\" role=\"tablist\" data-testid=\"tab-strip\">\n @for (tab of visibleTabs; track tab.id) {\n <button\n type=\"button\"\n class=\"ngx-form__tab\"\n [attr.data-testid]=\"'tab-' + tab.id\"\n [class.ngx-form__tab--active]=\"activeTab() === tab.id\"\n (click)=\"setActiveTab(tab.id)\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab() === tab.id\"\n >\n {{ resolveTabLabel(tab) }}\n </button>\n }\n </div>\n }\n\n <!-- Sub-tab bar — only if active tab has sub-tabs -->\n @if (visibleSubTabs.length > 0) {\n <div class=\"ngx-form__tabs ngx-form__tabs--sub\" role=\"tablist\" data-testid=\"subtab-strip\" style=\"margin-top: -12px; margin-bottom: 12px; font-size: 13px;\">\n @for (subTab of visibleSubTabs; track subTab.id) {\n <button\n type=\"button\"\n class=\"ngx-form__tab ngx-form__tab--sub\"\n [attr.data-testid]=\"'subtab-' + subTab.id\"\n [class.ngx-form__tab--active]=\"(activeSubTabConfig?.id) === subTab.id\"\n (click)=\"setActiveSubTab(subTab.id)\"\n role=\"tab\"\n [attr.aria-selected]=\"(activeSubTabConfig?.id) === subTab.id\"\n >\n {{ resolveTabLabel(subTab) }}\n </button>\n }\n </div>\n }\n\n <!--\n One tabpanel per tab, wrapping both branches. Focus moves here on a tab switch, and a\n module tab is still a tab — putting the panel semantics on only the fields branch left\n a module tab with nowhere for focus to land.\n -->\n <div\n role=\"tabpanel\"\n tabindex=\"-1\"\n #formPanel\n class=\"ngx-form__tabpanel\"\n [attr.aria-label]=\"activeTabLabel\"\n >\n @if (activeTabModuleComponent) {\n <div class=\"ngx-form__module-panel\" data-testid=\"module-panel\">\n <ng-container *ngComponentOutlet=\"activeTabModuleComponent; inputs: (activeSubTabConfig || activeTabConfig)?.moduleInputs\"></ng-container>\n </div>\n } @else {\n <!-- Fields for active tab (Responsive 12-column grid) -->\n <div class=\"ngx-form__panel\" data-testid=\"form-panel\">\n @for (field of fieldsForActiveTab; track field.id) {\n <div\n class=\"ngx-form__field-slot\"\n [style.gridColumn]=\"getFieldSpan(field)\"\n [attr.id]=\"'field-container-' + field.id\"\n tabindex=\"-1\"\n >\n <ngx-dynamic-field\n [field]=\"field\"\n [control]=\"getControl(field.id, (activeSubTabConfig || activeTabConfig)?.id)!\"\n [config]=\"config\"\n [currentTabId]=\"(activeSubTabConfig || activeTabConfig)?.id\"\n [language]=\"language\"\n [readonly]=\"isFieldReadonly(field)\"\n [userRoles]=\"userRoles\"\n />\n @if (field.hasDrift) {\n <!--\n Drift was previously visible only in the builder, so a referenced field whose\n source had changed looked completely normal to the person filling the form in.\n role=\"status\" rather than \"alert\": it is information, not an error.\n -->\n <span\n class=\"ngx-field__drift\"\n role=\"status\"\n [attr.data-testid]=\"'field-' + field.id + '-drift'\"\n [title]=\"driftHint(field)\"\n >⚠ {{ driftHint(field) }}</span>\n }\n @if (field.criticalField && !readonly) {\n <button\n type=\"button\"\n class=\"ngx-form__lock\"\n [attr.data-testid]=\"'lock-' + field.id\"\n [attr.aria-pressed]=\"!isFieldLocked(field)\"\n [attr.aria-label]=\"\n (isFieldLocked(field) ? 'Unlock ' : 'Lock ') + resolveFieldLabel(field)\n \"\n [title]=\"\n isFieldLocked(field)\n ? 'Critical field — click to unlock for editing'\n : 'Critical field — click to lock'\n \"\n (click)=\"toggleFieldLock(field)\"\n >\n {{ isFieldLocked(field) ? '🔒' : '🔓' }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Submit button — gated by RBAC and isSaving lock -->\n @if (!readonly && permissions.canEdit) {\n <div class=\"ngx-form__actions\" data-testid=\"form-actions\">\n <button\n type=\"button\"\n class=\"ngx-form__reset\"\n data-testid=\"form-reset\"\n (click)=\"reset()\"\n [disabled]=\"isSaving()\"\n >\n Reset\n </button>\n <button\n type=\"submit\"\n class=\"ngx-form__submit\"\n data-testid=\"form-submit\"\n [disabled]=\"submitBlocked\"\n title=\"Shortcut: Ctrl+S\"\n >\n @if (isSaving() || loading) {\n Saving…\n } @else {\n Save\n }\n </button>\n </div>\n }\n\n </form>\n} @else {\n <!-- permissions.view denied: render nothing of the record.\n Presentational only — the server must not send data this user may not see. -->\n <div class=\"ngx-form__denied\" role=\"status\" data-testid=\"form-access-denied\">\n You do not have permission to view this record.\n </div>\n}\n","import { ChangeDetectionStrategy, Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, signal, computed, inject, afterNextRender, ElementRef, Injector, ViewChild } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { AbstractControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport type { EntityFormConfig, FormRule, NestedFieldConfig, NestedTabConfig } from '@dynamic-entity/core';\nimport { findTab, formatDisplayValue, getTabData, resolveLabel } from '@dynamic-entity/core';\nimport { DynamicFormComponent } from './dynamic-form.component';\nimport { DynamicFieldComponent } from './dynamic-field/dynamic-field.component';\nimport { RulesEvaluationService } from '../services/rules-evaluation.service';\nimport { RbacService } from '../services/rbac.service';\n\n/**\n * Distinguishes \"no tab holds this field\" from \"the field holds undefined\", so the tab walk\n * can keep searching in the first case and stop in the second.\n */\nconst FIELD_NOT_FOUND = Symbol('field-not-found');\n\n/**\n * DynamicRecordFormComponent — comprehensive tabbed record view & edit component.\n * Supports cross-tab rule evaluation, profile header, summary drawer (showOnMinimize),\n * interactive quick-jump links, and baseline modification tracking.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-dynamic-record-form',\n standalone: true,\n imports: [CommonModule, ReactiveFormsModule, DynamicFormComponent, DynamicFieldComponent],\n templateUrl: './dynamic-record-form.component.html',\n styles: [\n `\n .ngx-record-editor {\n display: flex;\n flex-direction: column;\n gap: 16px;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n padding: 20px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n }\n .ngx-record-editor__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding-bottom: 16px;\n border-bottom: 1px solid #f3f4f6;\n }\n .ngx-record-editor__title-group {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .ngx-record-editor__avatar {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n object-fit: cover;\n background: #e0e7ff;\n color: #4f46e5;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 18px;\n }\n .ngx-record-editor__title {\n font-size: 20px;\n font-weight: 700;\n color: #111827;\n margin: 0;\n }\n .ngx-record-editor__subtitle {\n font-size: 13px;\n color: #6b7280;\n }\n .ngx-record-editor__header-toggle {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: #374151;\n }\n .ngx-record-editor__header-toggle-text {\n font-weight: 600;\n }\n .ngx-record-editor__banner {\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 500;\n }\n .ngx-record-editor__banner--info {\n background: #eff6ff;\n border: 1px solid #dbeafe;\n color: #1d4ed8;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n }\n .ngx-record-editor__banner-dismiss {\n background: none;\n border: none;\n cursor: pointer;\n color: inherit;\n font-size: 14px;\n line-height: 1;\n padding: 2px 6px;\n border-radius: 4px;\n }\n .ngx-record-editor__banner-dismiss:hover {\n background: rgba(0, 0, 0, 0.06);\n }\n .ngx-record-editor__banner--error {\n background: #fef2f2;\n border: 1px solid #fecaca;\n color: #b91c1c;\n }\n .ngx-record-editor__section-bar {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n }\n .ngx-record-editor__section-hint {\n margin-right: auto;\n font-size: 12px;\n color: #6b7280;\n }\n .ngx-record-editor__banner--warning {\n background: #fffbeb;\n border: 1px solid #fef3c7;\n color: #b45309;\n }\n .ngx-record-editor__rows {\n border: 1px solid #f3f4f6;\n border-radius: 8px;\n padding: 12px 14px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .ngx-record-editor__rows-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n }\n .ngx-record-editor__row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n background: #f9fafb;\n }\n .ngx-record-editor__row-text {\n flex: 1;\n font-size: 13px;\n overflow-wrap: anywhere;\n }\n .ngx-record-editor__row-btn {\n background: none;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n padding: 2px 8px;\n }\n .ngx-record-editor__row-empty {\n font-size: 12px;\n color: #6b7280;\n margin: 0;\n }\n .ngx-record-editor__drawer {\n border: 1px solid #dbeafe;\n background: #f8fafc;\n border-radius: 8px;\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .ngx-record-editor__summary-panel {\n background: #f9fafb;\n border: 1px solid #f3f4f6;\n border-radius: 8px;\n padding: 12px 16px;\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 12px;\n }\n .ngx-record-editor__summary-item {\n display: flex;\n flex-direction: column;\n cursor: pointer;\n padding: 6px 10px;\n border-radius: 6px;\n transition: background 0.15s;\n }\n .ngx-record-editor__summary-item:hover {\n background: #eff6ff;\n }\n .ngx-record-editor__summary-label {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #6b7280;\n font-weight: 600;\n }\n .ngx-record-editor__summary-val {\n font-size: 14px;\n font-weight: 600;\n color: #1f2937;\n }\n `,\n ],\n})\nexport class DynamicRecordFormComponent implements OnChanges {\n @Input() config!: EntityFormConfig;\n @Input() rules?: FormRule[];\n @Input() initialData?: Record<string, any>;\n @Input() userRoles: string[] = [];\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() loading: boolean = false;\n @Input() error: string | null = null;\n /** Whole record read-only, regardless of RBAC. Equivalent to the reference's `isReadOnly`. */\n @Input() isReadOnly: boolean = false;\n /** Specific field ids forced read-only while the rest of the record stays editable. */\n @Input() readOnlyFields: string[] = [];\n /**\n * Open the record read-only, with a per-tab \"Edit section\" flow — one tab is edited and\n * validated at a time. This is the framework's `EntityRecordComponent` model and the\n * default here.\n *\n * Set false for a directly editable record with no view/edit distinction.\n */\n @Input() viewMode: boolean = true;\n\n @Output() formSubmit = new EventEmitter<Record<string, any>>();\n @Output() formChange = new EventEmitter<Record<string, any>>();\n @Output() formReset = new EventEmitter<void>();\n /** One tab section was saved. Carries the whole record, plus which tab was edited. */\n @Output() sectionSave = new EventEmitter<{ tabId: string; record: Record<string, any> }>();\n\n @ViewChild(DynamicFormComponent) dynamicFormComp?: DynamicFormComponent;\n\n private readonly rulesEvaluation = inject(RulesEvaluationService);\n private readonly rbacService = inject(RbacService);\n private readonly host: ElementRef<HTMLElement> = inject(ElementRef);\n private readonly injector = inject(Injector);\n\n readonly currentData = signal<Record<string, any>>({});\n readonly originalBaseline = signal<Record<string, any>>({});\n\n /**\n * Info banners the user has dismissed, by field id.\n *\n * The reference's contract: an info banner persists until dismissed, **not** until the\n * value changes. Dismissal is keyed by field so re-triggering a different field's rule\n * still shows. Re-armed when a different record is loaded.\n */\n private readonly dismissed = signal<ReadonlySet<string>>(new Set<string>());\n\n /**\n * Info banners from the rules engine that are still showing.\n *\n * A getter, not a `computed`: the source is `dynamicFormComp`, a ViewChild. A computed\n * evaluated before the view initialises would capture no dependency on the child's\n * `ruleResult` signal and then never recompute. Read per change-detection pass instead.\n */\n get infoBanners(): { fieldId: string; message: string }[] {\n const result = this.dynamicFormComp?.ruleResult();\n const gone = this.dismissed();\n return Object.entries(result?.infoBanners ?? {})\n .filter(([fieldId]) => !gone.has(fieldId))\n .map(([fieldId, message]) => ({ fieldId, message: String(message) }));\n }\n\n dismissInfoBanner(fieldId: string): void {\n this.dismissed.set(new Set(this.dismissed()).add(fieldId));\n }\n\n /**\n * Whether the current roles may edit this record.\n *\n * `userRoles` was declared as an input here and then read by nothing at all — this\n * component computed no permissions of any kind, so the record view was fully editable\n * for every role while the plain form at least hid its Save button. Cached on the same\n * terms as the sibling component: it depends only on `config` and `userRoles`.\n */\n private permissionsCache: ReturnType<RbacService['getPermissions']> | null = null;\n\n get permissions(): ReturnType<RbacService['getPermissions']> {\n return (this.permissionsCache ??= this.rbacService.getPermissions(this.config, this.userRoles));\n }\n\n /** True when nothing in the record may be edited. */\n get recordReadOnly(): boolean {\n return this.readonly || this.isReadOnly || !this.permissions.canEdit;\n }\n\n // ─── Inline array-row editing ───────────────────────────────────────────────\n\n /**\n * A row of an `array` field is edited in a drawer, not inline in the tab panel.\n *\n * The drawer is rendered outside the tab container on purpose: the reference found that\n * building a row's FormGroup inside the tab view races the tab's own initialisation, so\n * the row form is kept detached and only pushed into the FormArray on save.\n */\n readonly inlineRowField = signal<NestedFieldConfig | null>(null);\n readonly inlineRowIndex = signal<number | null>(null);\n inlineRowForm: FormGroup | null = null;\n\n /** `array` fields on the tab currently shown, so the template can list their rows. */\n get arrayFieldsForActiveTab(): NestedFieldConfig[] {\n const tabId = this.activeTabId;\n const tab = tabId ? findTab(this.config?.tabs, tabId) : null;\n return (tab?.fields ?? []).filter(f => f.type === 'array');\n }\n\n /**\n * Rows currently held by an `array` field, read from the record value.\n *\n * Deliberately not read off the child's FormArray: that control only exists once the\n * child has initialised, so rendering from it changed value mid-pass. `currentData` is a\n * signal seeded from `initialData` and kept current by the child's `formChange`.\n */\n rowsOf(field: NestedFieldConfig): Record<string, unknown>[] {\n const tabId = this.activeTabId;\n const tabData = tabId ? getTabData(tabId, this.currentData(), this.config) : null;\n const rows = (tabData as Record<string, unknown> | null)?.[field.id];\n return Array.isArray(rows) ? (rows as Record<string, unknown>[]) : [];\n }\n\n /** One row rendered as text, so the list is readable without opening the drawer. */\n rowSummary(field: NestedFieldConfig, row: Record<string, unknown>): string {\n const value = row ?? {};\n const parts = (field.children ?? [])\n .map(child => value[child.id])\n .filter(v => v !== null && v !== undefined && v !== '')\n .map(v => (typeof v === 'object' ? JSON.stringify(v) : String(v)));\n return parts.length ? parts.join(' · ') : '(empty)';\n }\n\n openAddRow(field: NestedFieldConfig): void {\n if (this.sectionReadOnly) return;\n this.inlineRowField.set(field);\n this.inlineRowIndex.set(null);\n this.inlineRowForm = this.dynamicFormComp?.createArrayRow(field) as FormGroup;\n }\n\n openEditRow(field: NestedFieldConfig, index: number): void {\n if (this.sectionReadOnly) return;\n this.inlineRowField.set(field);\n this.inlineRowIndex.set(index);\n this.inlineRowForm = this.dynamicFormComp?.createArrayRow(field, this.rowsOf(field)[index]) as FormGroup;\n }\n\n cancelRow(): void {\n this.inlineRowField.set(null);\n this.inlineRowIndex.set(null);\n this.inlineRowForm = null;\n }\n\n /** Commit the drawer into the FormArray. Rules re-evaluate off the resulting value change. */\n saveRow(): void {\n const field = this.inlineRowField();\n const form = this.dynamicFormComp;\n if (!field || !form || !this.inlineRowForm) return;\n\n if (this.inlineRowForm.invalid) {\n this.inlineRowForm.markAllAsTouched();\n return;\n }\n\n const array = form.getArrayControl(field.id, this.activeTabId ?? undefined);\n if (!array) return;\n\n const index = this.inlineRowIndex();\n if (index === null) array.push(form.createArrayRow(field, this.inlineRowForm.value));\n else array.at(index).patchValue(this.inlineRowForm.value);\n\n array.updateValueAndValidity();\n this.currentData.set(form.extractRecord());\n this.cancelRow();\n }\n\n deleteRow(field: NestedFieldConfig, index: number): void {\n if (this.sectionReadOnly) return;\n const array = this.dynamicFormComp?.getArrayControl(field.id, this.activeTabId ?? undefined);\n array?.removeAt(index);\n array?.updateValueAndValidity();\n if (this.dynamicFormComp) this.currentData.set(this.dynamicFormComp.extractRecord());\n if (this.inlineRowIndex() === index) this.cancelRow();\n }\n\n // ─── Per-tab section editing ────────────────────────────────────────────────\n\n /**\n * The tab currently open for editing, or null when the record is being viewed.\n *\n * The reference edits one tab section at a time rather than the whole record, and\n * validates only that section on save — a required field on an untouched tab must not\n * block saving the tab you are actually working on.\n */\n readonly editingTabId = signal<string | null>(null);\n\n /**\n * The tab the inner form is showing.\n *\n * Tracked here rather than read off the ViewChild. The child resolves its first tab as\n * part of its own initialisation, so reading it during this component's render changed\n * value mid-pass — an ExpressionChangedAfterItHasBeenChecked error. Seeded from the\n * config and kept in step by the child's `activeTabChange` output.\n */\n private readonly activeTabIdSig = signal<string | null>(null);\n\n get activeTabId(): string | null {\n return this.activeTabIdSig();\n }\n\n onActiveTabChange(tabId: string): void {\n if (this.activeTabIdSig() === tabId) return;\n this.activeTabIdSig.set(tabId);\n // Editing does not follow the user to another tab.\n this.editingTabId.set(null);\n this.cancelRow();\n }\n\n /** First tab a user can see, used to seed the active tab before the child reports one. */\n private firstVisibleTabId(): string | null {\n return this.config?.tabs?.find(t => t.visibility !== false)?.id ?? null;\n }\n\n /** Errors from the last save attempt, by field id. */\n readonly sectionErrors = signal<Record<string, string>>({});\n\n /** Template access to `Object.keys` for iterating the error map. */\n protected readonly Object = Object;\n\n get isEditingActiveTab(): boolean {\n // Without view mode there is no view/edit distinction — everything is always editable.\n if (!this.viewMode) return true;\n return !!this.activeTabId && this.editingTabId() === this.activeTabId;\n }\n\n /** Fields render read-only unless their own tab is the one being edited. */\n get sectionReadOnly(): boolean {\n return this.recordReadOnly || !this.isEditingActiveTab;\n }\n\n editSection(): void {\n if (!this.viewMode || this.recordReadOnly || !this.activeTabId) return;\n this.sectionErrors.set({});\n this.editingTabId.set(this.activeTabId);\n }\n\n /** Discard this section's edits, restoring each field from the session baseline. */\n cancelSection(): void {\n const tabId = this.editingTabId();\n const form = this.dynamicFormComp;\n if (tabId && form) {\n const tab = findTab(this.config?.tabs, tabId);\n const baselineTab = (getTabData(tabId, this.originalBaseline(), this.config) ?? {}) as Record<string, unknown>;\n for (const field of tab?.fields ?? []) {\n const baselineValue = baselineTab[field.id];\n\n // A FormArray cannot be restored with setValue — that demands a value shaped exactly\n // like the current rows. Rebuild it from the baseline rows instead.\n const array = form.getArrayControl(field.id, tabId);\n if (array) {\n array.clear();\n for (const row of Array.isArray(baselineValue) ? baselineValue : []) {\n array.push(form.createArrayRow(field, row));\n }\n array.updateValueAndValidity();\n continue;\n }\n\n form.getControl(field.id, tabId)?.setValue(baselineValue ?? null);\n }\n this.currentData.set(form.extractRecord());\n }\n this.sectionErrors.set({});\n this.editingTabId.set(null);\n }\n\n /**\n * Validate this section only, then emit it. Validation is scoped two ways: Angular\n * validity of the tab's own controls, and rules filtered to this tab — a rule targeting\n * a hidden tab must not block the save (the reference's OV0-968 fix).\n */\n saveSection(): void {\n const tabId = this.editingTabId();\n const form = this.dynamicFormComp;\n if (!tabId || !form) return;\n\n const tab = findTab(this.config?.tabs, tabId);\n const errors: Record<string, string> = {};\n\n for (const field of tab?.fields ?? []) {\n const ctrl = form.getControl(field.id, tabId);\n if (ctrl?.invalid) {\n ctrl.markAsTouched();\n errors[field.id] = `${resolveLabel(field.label, this.language)} is invalid.`;\n }\n }\n\n const scoped = this.rulesEvaluation.filterForTab(this.rules, tabId, this.config);\n const ruleErrors = this.rulesEvaluation.evaluate(scoped, form.formValues(), this.originalBaseline())\n .validationErrors;\n Object.assign(errors, ruleErrors);\n\n if (Object.keys(errors).length > 0) {\n this.sectionErrors.set(errors);\n return;\n }\n\n this.sectionErrors.set({});\n this.editingTabId.set(null);\n\n const record = form.extractRecord();\n this.currentData.set(record);\n this.sectionSave.emit({ tabId, record });\n }\n\n /**\n * Seed the session baseline from the loaded record so `VALUE_CHANGED` rules and the\n * modification banner compare against the record as it was opened — not as it was\n * after the first keystroke.\n */\n ngOnChanges(changes: SimpleChanges): void {\n // Permissions depend on these two and nothing else; a stale cache would keep a record\n // editable after a role switch.\n if (changes['config'] || changes['userRoles']) {\n this.permissionsCache = null;\n }\n if (changes['initialData'] || changes['config']) {\n this.originalBaseline.set({ ...(this.initialData ?? {}) });\n this.currentData.set({ ...(this.initialData ?? {}) });\n this.activeTabIdSig.set(this.firstVisibleTabId());\n // A different record is a different set of banners — re-arm them.\n this.dismissed.set(new Set<string>());\n }\n }\n\n get recordTitle(): string {\n if (!this.config) return 'Record';\n return this.config.name ? resolveLabel(this.config.name, this.language) : this.config.entity;\n }\n\n get avatarLetter(): string {\n return (this.recordTitle || 'R').charAt(0).toUpperCase();\n }\n\n // ─── Header fields (isProfileImage / isHeaderToggle) ────────────────────────\n\n /** Every field in the config, at any depth. */\n private allFields(): NestedFieldConfig[] {\n const out: NestedFieldConfig[] = [];\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const f of fields ?? []) {\n out.push(f);\n walkFields(f.children);\n }\n };\n const walkTabs = (tabs: NestedTabConfig[] | undefined) => {\n for (const t of tabs ?? []) {\n walkFields(t.fields);\n walkTabs(t.children);\n }\n };\n walkTabs(this.config?.tabs);\n return out;\n }\n\n /** The field flagged `isProfileImage`, rendered as the record avatar. */\n get headerProfileField(): NestedFieldConfig | null {\n return this.allFields().find(f => f.isProfileImage) ?? null;\n }\n\n /** The field flagged `isHeaderToggle`, rendered as a status switch in the header. */\n get headerToggleField(): NestedFieldConfig | null {\n return this.allFields().find(f => f.isHeaderToggle) ?? null;\n }\n\n /** Avatar image URL, when the profile field holds a persisted FileRef. */\n get profileImageUrl(): string | null {\n const field = this.headerProfileField;\n if (!field) return null;\n const value = this.fieldValue(field.id) as { url?: string } | null;\n return value?.url ?? null;\n }\n\n get headerToggleValue(): boolean {\n const field = this.headerToggleField;\n return field ? this.fieldValue(field.id) === true : false;\n }\n\n /**\n * Flip the header toggle. It writes straight to the control rather than going through\n * section editing — the reference treats it as a record-level status switch, not part of\n * any one tab's section.\n */\n toggleHeaderStatus(): void {\n const field = this.headerToggleField;\n if (!field || this.recordReadOnly) return;\n const ctrl = this.controlFor(field.id);\n if (!ctrl) return;\n ctrl.setValue(!this.headerToggleValue);\n if (this.dynamicFormComp) this.currentData.set(this.dynamicFormComp.extractRecord());\n }\n\n /** Locate a field's control wherever it lives, since header fields may be on any tab. */\n private controlFor(fieldId: string): AbstractControl | null {\n return this.dynamicFormComp?.getControl(fieldId) ?? null;\n }\n\n /**\n * A field's current value, read from the record so it is stable during render.\n *\n * Resolved through `getTabData` so it honours exactly the nesting contract the form\n * patches with — `{ tabId: { fieldId } }`, or the record root when the tab sets\n * `flatData`. Reading the record flat instead is not a shortcut: it makes the summary\n * display values the form never loaded, which reads as \"the data is there\" while every\n * control behind it is empty.\n *\n * Walks sub-tabs as well: a summary, header, or profile field may sit on any tab at any\n * depth.\n */\n private fieldValue(fieldId: string): unknown {\n const visit = (tabs: NestedTabConfig[] = []): unknown => {\n for (const tab of tabs) {\n const data = getTabData(tab.id, this.currentData(), this.config) as Record<string, unknown> | null;\n if (data && fieldId in data) return data[fieldId];\n if (tab.children) {\n const found = visit(tab.children);\n if (found !== FIELD_NOT_FOUND) return found;\n }\n }\n return FIELD_NOT_FOUND;\n };\n\n const result = visit(this.config?.tabs);\n return result === FIELD_NOT_FOUND ? undefined : result;\n }\n\n readonly isModified = computed(() => {\n const orig = this.originalBaseline();\n const curr = this.currentData();\n if (!orig || !curr || Object.keys(orig).length === 0) return false;\n return JSON.stringify(orig) !== JSON.stringify(curr);\n });\n\n readonly summaryFields = computed<NestedFieldConfig[]>(() => {\n const fields: NestedFieldConfig[] = [];\n const walkTabs = (tabs: NestedTabConfig[] = []) => {\n for (const t of tabs) {\n for (const f of t.fields ?? []) {\n if (f.showOnMinimize) fields.push(f);\n }\n if (t.children) walkTabs(t.children);\n }\n };\n walkTabs(this.config?.tabs);\n return fields;\n });\n\n onFormChange(data: Record<string, any>): void {\n // Baseline is seeded from `initialData` in ngOnChanges; only fill it here when the\n // record was opened empty (create flow), so the first emitted shape becomes the baseline.\n if (Object.keys(this.originalBaseline()).length === 0) {\n this.originalBaseline.set({ ...data });\n }\n this.currentData.set(data);\n this.formChange.emit(data);\n }\n\n onFormSubmit(data: Record<string, any>): void {\n this.formSubmit.emit(data);\n }\n\n onFormReset(): void {\n this.formReset.emit();\n }\n\n formatFieldLabel(field: NestedFieldConfig): string {\n return resolveLabel(field.label, this.language);\n }\n\n /** Summary values render through the shared core formatter, not a local stringifier. */\n formatFieldValue(field: NestedFieldConfig): string {\n return formatDisplayValue(field.type, field.options, this.fieldValue(field.id), this.language);\n }\n\n /**\n * Finds which tab — and, where the field lives one level down, which sub-tab — owns a\n * field. The walk used to check top-level `fields` only, so every field in a sub-tab was\n * simply not found and the jump did nothing at all.\n */\n private locateField(fieldId: string): { tabId: string; subTabId?: string } | null {\n for (const tab of this.config?.tabs || []) {\n if ((tab.fields || []).some(f => f.id === fieldId)) return { tabId: tab.id };\n for (const child of tab.children || []) {\n if ((child.fields || []).some(f => f.id === fieldId)) {\n return { tabId: tab.id, subTabId: child.id };\n }\n }\n }\n return null;\n }\n\n /**\n * Switches to the tab holding `fieldId`, then scrolls it into view and moves focus to it.\n *\n * The wait for the new tab to render used to be a 50 ms `setTimeout`, which was wrong three\n * ways: `document` is undefined on a server render, 50 ms is a guess that a large tab can\n * outrun, and nothing cancelled the timer if the component went away first.\n * `afterNextRender` fixes all three — it never runs on the server, it runs when the panel\n * has actually rendered rather than when a guess expires, and it is tied to the injector so\n * destroying the component cancels it. The query is scoped to this component's own element,\n * so the library no longer reaches for the global `document` at all.\n */\n jumpToField(fieldId: string): void {\n const location = this.locateField(fieldId);\n if (!location) return;\n\n // The panel must not take the focus back: this jump is going to focus the field itself.\n this.dynamicFormComp?.setActiveTab(location.tabId, { focusPanel: false });\n // `setActiveTab` resets to a tab's first child, so the sub-tab has to be selected after\n // it, not before. Without this the walk found sub-tab fields and then rendered the wrong\n // panel, so the element the callback below looks for never existed.\n if (location.subTabId) {\n this.dynamicFormComp?.setActiveSubTab(location.subTabId, { focusPanel: false });\n }\n\n afterNextRender(\n () => {\n // The field id comes from config, so it never goes into a selector string: no\n // escaping to get wrong, and no need for `CSS.escape`, which jsdom and older\n // browsers do not provide and whose absence throws silently inside a render hook.\n const wanted = `field-container-${fieldId}`;\n const el = Array.from(\n this.host.nativeElement.querySelectorAll<HTMLElement>('[id^=\"field-container-\"]'),\n ).find(slot => slot.id === wanted);\n if (!el) return;\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n // The slot carries tabindex=\"-1\" so this actually moves focus. Without it the jump\n // scrolled the field into view and left focus behind on the link.\n el.focus();\n },\n { injector: this.injector },\n );\n }\n}\n","<div class=\"ngx-record-editor\">\n <!-- Record Header -->\n <div class=\"ngx-record-editor__header\">\n <div class=\"ngx-record-editor__title-group\">\n @if (profileImageUrl) {\n <img\n class=\"ngx-record-editor__avatar\"\n data-testid=\"header-profile-image\"\n [src]=\"profileImageUrl\"\n [alt]=\"recordTitle\"\n />\n } @else {\n <div class=\"ngx-record-editor__avatar\" data-testid=\"header-avatar-initial\">\n {{ avatarLetter }}\n </div>\n }\n <div>\n <h2 class=\"ngx-record-editor__title\" data-testid=\"record-title\">\n {{ recordTitle }}\n </h2>\n <span class=\"ngx-record-editor__subtitle\">Entity: {{ config.entity }}</span>\n </div>\n </div>\n\n <!-- Record-level status switch, outside section editing -->\n @if (headerToggleField; as toggleField) {\n <label class=\"ngx-record-editor__header-toggle\">\n <span>{{ formatFieldLabel(toggleField) }}</span>\n <input\n type=\"checkbox\"\n role=\"switch\"\n data-testid=\"header-toggle\"\n [checked]=\"headerToggleValue\"\n [disabled]=\"recordReadOnly\"\n [attr.aria-checked]=\"headerToggleValue\"\n (change)=\"toggleHeaderStatus()\"\n />\n <span class=\"ngx-record-editor__header-toggle-text\">{{ headerToggleValue ? 'Yes' : 'No' }}</span>\n </label>\n }\n </div>\n\n <!-- Dismissible info banners (rules `info` action) -->\n @for (banner of infoBanners; track banner.fieldId) {\n <div\n class=\"ngx-record-editor__banner ngx-record-editor__banner--info\"\n role=\"status\"\n [attr.data-testid]=\"'info-banner-' + banner.fieldId\"\n >\n <span>ℹ️ {{ banner.message }}</span>\n <button\n type=\"button\"\n class=\"ngx-record-editor__banner-dismiss\"\n [attr.data-testid]=\"'dismiss-' + banner.fieldId\"\n [attr.aria-label]=\"'Dismiss: ' + banner.message\"\n (click)=\"dismissInfoBanner(banner.fieldId)\"\n >✕</button>\n </div>\n }\n\n <!-- Modification baseline banner -->\n @if (isModified()) {\n <div class=\"ngx-record-editor__banner ngx-record-editor__banner--warning\">\n 🔒 Record modified from session baseline — unsaved changes pending.\n </div>\n }\n\n <!-- Summary Panel (showOnMinimize fields with interactive jump) -->\n @if (summaryFields().length > 0) {\n <div class=\"ngx-record-editor__summary-panel\" data-testid=\"summary-panel\">\n @for (sf of summaryFields(); track sf.id) {\n <div\n class=\"ngx-record-editor__summary-item\"\n [attr.data-testid]=\"'summary-' + sf.id\"\n (click)=\"jumpToField(sf.id)\"\n [title]=\"'Click to jump to ' + formatFieldLabel(sf)\"\n >\n <span class=\"ngx-record-editor__summary-label\">{{ formatFieldLabel(sf) }}</span>\n <span class=\"ngx-record-editor__summary-val\">{{ formatFieldValue(sf) }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Section edit bar: one tab is edited at a time, and validated on its own -->\n @if (viewMode && !recordReadOnly) {\n <div class=\"ngx-record-editor__section-bar\">\n @if (isEditingActiveTab) {\n <span class=\"ngx-record-editor__section-hint\">Editing this section</span>\n <button type=\"button\" class=\"ngx-form__reset\" data-testid=\"cancel-section\" (click)=\"cancelSection()\">\n Cancel\n </button>\n <button type=\"button\" class=\"ngx-form__submit\" data-testid=\"save-section\" (click)=\"saveSection()\">\n Save section\n </button>\n } @else {\n <button type=\"button\" class=\"ngx-form__reset\" data-testid=\"edit-section\" (click)=\"editSection()\">\n Edit section\n </button>\n }\n </div>\n }\n\n @if (Object.keys(sectionErrors()).length > 0) {\n <div class=\"ngx-record-editor__banner ngx-record-editor__banner--error\" role=\"alert\" data-testid=\"section-errors\">\n @for (key of Object.keys(sectionErrors()); track key) {\n <div>⚠️ {{ sectionErrors()[key] }}</div>\n }\n </div>\n }\n\n <!-- Array rows: listed here, edited in the drawer below -->\n @for (arrayField of arrayFieldsForActiveTab; track arrayField.id) {\n <div class=\"ngx-record-editor__rows\" [attr.data-testid]=\"'rows-' + arrayField.id\">\n <div class=\"ngx-record-editor__rows-head\">\n <span class=\"ngx-record-editor__summary-label\">{{ formatFieldLabel(arrayField) }}</span>\n @if (!sectionReadOnly) {\n <button\n type=\"button\"\n class=\"ngx-form__reset\"\n [attr.data-testid]=\"'add-row-' + arrayField.id\"\n (click)=\"openAddRow(arrayField)\"\n >+ Row</button>\n }\n </div>\n\n @for (row of rowsOf(arrayField); track $index) {\n <div class=\"ngx-record-editor__row\" [attr.data-testid]=\"'row-' + arrayField.id + '-' + $index\">\n <span class=\"ngx-record-editor__row-text\">{{ rowSummary(arrayField, row) }}</span>\n @if (!sectionReadOnly) {\n <button type=\"button\" class=\"ngx-record-editor__row-btn\"\n [attr.data-testid]=\"'edit-row-' + arrayField.id + '-' + $index\"\n (click)=\"openEditRow(arrayField, $index)\">Edit</button>\n <button type=\"button\" class=\"ngx-record-editor__row-btn\"\n [attr.data-testid]=\"'delete-row-' + arrayField.id + '-' + $index\"\n (click)=\"deleteRow(arrayField, $index)\">Delete</button>\n }\n </div>\n } @empty {\n <p class=\"ngx-record-editor__row-empty\">No rows yet.</p>\n }\n </div>\n }\n\n <!--\n Row drawer. Deliberately outside the tab panel: building a row's FormGroup inside the\n tab view races the tab's own initialisation (the reference hit this with FormArray).\n -->\n @if (inlineRowField(); as rowField) {\n <div class=\"ngx-record-editor__drawer\" data-testid=\"row-drawer\" [formGroup]=\"inlineRowForm!\">\n <div class=\"ngx-record-editor__rows-head\">\n <strong>{{ inlineRowIndex() === null ? 'Add' : 'Edit' }} {{ formatFieldLabel(rowField) }} row</strong>\n </div>\n\n <div class=\"ngx-form__panel\">\n @for (child of rowField.children ?? []; track child.id) {\n <ngx-dynamic-field\n [field]=\"child\"\n [control]=\"inlineRowForm!.get(child.id)!\"\n [config]=\"config\"\n [language]=\"language\"\n [readonly]=\"false\"\n [userRoles]=\"userRoles\"\n [style.gridColumn]=\"'span 12'\"\n />\n }\n </div>\n\n <div class=\"ngx-record-editor__section-bar\">\n <button type=\"button\" class=\"ngx-form__reset\" data-testid=\"cancel-row\" (click)=\"cancelRow()\">Cancel</button>\n <button type=\"button\" class=\"ngx-form__submit\" data-testid=\"save-row\" (click)=\"saveRow()\">Save row</button>\n </div>\n </div>\n }\n\n <!-- Main Dynamic Form -->\n <ngx-dynamic-form\n [config]=\"config\"\n [rules]=\"rules\"\n [initialData]=\"initialData\"\n [originalData]=\"originalBaseline()\"\n [userRoles]=\"userRoles\"\n [language]=\"language\"\n [readonly]=\"sectionReadOnly\"\n [readOnlyFields]=\"readOnlyFields\"\n [showInfoBanners]=\"false\"\n [loading]=\"loading\"\n [error]=\"error\"\n (formChange)=\"onFormChange($event)\"\n (formSubmit)=\"onFormSubmit($event)\"\n (formReset)=\"onFormReset()\"\n (activeTabChange)=\"onActiveTabChange($event)\"\n />\n</div>\n","// Tokens\nexport * from './lib/tokens/injection-tokens';\n\n// Providers\nexport * from './lib/providers/provide-ngx-dynamic-entity';\nexport * from './lib/providers/provide-field-types';\n\n// Services\nexport * from './lib/services/field-registry.service';\nexport * from './lib/services/hook-registry.service';\nexport * from './lib/services/validator-registry.service';\nexport * from './lib/services/entity-ref-registry.service';\nexport * from './lib/services/entity-ref-selection.service';\nexport * from './lib/services/cascade-data.service';\nexport * from './lib/services/entity-reference.service';\nexport * from './lib/services/entity-ref-cache';\nexport * from './lib/services/lookup-registry.service';\nexport * from './lib/services/rbac.service';\nexport * from './lib/services/rules-evaluation.service';\nexport * from './lib/services/config-source.service';\nexport * from './lib/services/validation-messages.service';\n\n// Components — the library ships form UI only; rendering a data table is the consumer's choice.\nexport * from './lib/form/dynamic-form.component';\nexport * from './lib/form/dynamic-record-form.component';\nexport * from './lib/form/dynamic-field/dynamic-field.component';\n\n// The contract a field component must satisfy to be registered with provideFieldTypes.\n// Previously this existed only as a code comment and an ADR that is gitignored, so a\n// consumer had no interface to implement against.\nexport * from './lib/field-types/field-component.contract';\n\n// Field type components — every one, individually importable.\n//\n// The tree-shaking seam is `provideFieldTypes({ image: ImageFieldComponent })`: register\n// only what you use and the rest never enters the bundle. That only works for components a\n// consumer can name, and ten of these were unreachable — so wanting eleven of the twenty\n// meant calling provideBuiltInFieldTypes() and bundling all of them, which is exactly what\n// the seam exists to avoid.\nexport * from './lib/field-types/text-field.component';\nexport * from './lib/field-types/textarea-field.component';\nexport * from './lib/field-types/markdown-field.component';\nexport * from './lib/field-types/number-field.component';\nexport * from './lib/field-types/currency-field.component';\nexport * from './lib/field-types/email-field.component';\nexport * from './lib/field-types/password-field.component';\nexport * from './lib/field-types/checkbox-field.component';\nexport * from './lib/field-types/boolean-field.component';\nexport * from './lib/field-types/date-field.component';\nexport * from './lib/field-types/date-time-field.component';\nexport * from './lib/field-types/time-field.component';\nexport * from './lib/field-types/month-year-field.component';\nexport * from './lib/field-types/dropdown-field.component';\nexport * from './lib/field-types/radio-field.component';\nexport * from './lib/field-types/multi-select-field.component';\nexport * from './lib/field-types/entity-ref-field.component';\nexport * from './lib/field-types/group-field.component';\nexport * from './lib/field-types/array-field.component';\nexport * from './lib/field-types/image-field.component';\nexport * from './lib/field-types/file-field.component';\n\n// Value helpers — a dropdown value is now a language-keyed object, so a consumer rendering\n// record values needs these. Re-exported so they don't have to depend on core directly.\nexport {\n resolveLabel,\n resolveOptionLabel,\n resolveOptionValue,\n formatDisplayValue,\n valuesMatch,\n normalizeOption,\n normalizeConfig,\n} from '@dynamic-entity/core';\n\n// Re-export core types so consumers need only one import\nexport type {\n EntityFormConfig,\n NestedTabConfig,\n NestedFieldConfig,\n FieldTableConfig,\n RichFieldType,\n LocalizedText,\n DropdownOption,\n VersionedRecord,\n EntityPermissions,\n RbacContext,\n FieldValidators,\n EntityReferenceConfig,\n EntityReferenceLoader,\n ReferenceOption,\n ReferenceLoaderContext,\n AutoPatchConfig,\n PatchOnTrueMapping,\n FileRef,\n FormRule,\n RuleCondition,\n RuleAction,\n RuleEvaluationResult,\n CommonModuleEntry,\n} from '@dynamic-entity/core';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["coreResolveEffectiveMask","coreShouldMaskField"],"mappings":";;;;;;;;;;;AAoBA;MACa,2BAA2B,CAAA;AACrB,IAAA,GAAG,GAAG,IAAI,GAAG,EAA6B;AAE3D,IAAA,GAAG,CAAC,GAAW,EAAA;QACb,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;IAC1B;IAEA,GAAG,CAAC,GAAW,EAAE,KAAwB,EAAA;QACvC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;IAC1B;AAEA,IAAA,MAAM,CAAC,GAAW,EAAA;AAChB,QAAA,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;IACtB;IAEA,IAAI,GAAA;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAC7B;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE;IAClB;AACD;;AChCD;MACa,YAAY,GAAG,IAAI,cAAc,CAAW,cAAc;AAEvE;;;AAGG;MACU,mBAAmB,GAAG,IAAI,cAAc,CAAyB,qBAAqB;AAEnG;;;;;AAKG;MACU,eAAe,GAAG,IAAI,cAAc,CAA8B,iBAAiB;AAEhG;;;;;;AAMG;MACU,mBAAmB,GAAG,IAAI,cAAc,CACnD,qBAAqB;AAGvB;;;;;;;;;;;;;;;;;AAiBG;MACU,eAAe,GAAG,IAAI,cAAc,CAAgC,iBAAiB;AAElG;;;;;;;;;;;;;;AAcG;MACU,iBAAiB,GAAG,IAAI,cAAc,CAAoB,mBAAmB;AAE1F;;;;;;;AAOG;MACU,mBAAmB,GAAG,IAAI,cAAc,CAAsB,qBAAqB;AAEhG;MACa,kBAAkB,GAAG,IAAI,cAAc,CAAmB,oBAAoB;AAE3F;;;;;;AAMG;MACU,wBAAwB,GAAG,IAAI,cAAc,CACxD,0BAA0B;AAW5B;MACa,aAAa,GAAG,IAAI,cAAc,CAAsB,eAAe;AAEpF;;;;;;;;;;;;;;;AAeG;MACU,uBAAuB,GAAG,IAAI,cAAc,CACvD,yBAAyB;AAG3B;;;;;;;;AAQG;MACU,cAAc,GAAG,IAAI,cAAc,CAAoB,gBAAgB;AAEpF;;;;;;AAMG;AACI,MAAM,sBAAsB,GAAG,IAAI,cAAc,CACtD,wBAAwB,EACxB,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,2BAA2B,EAAE,EAAE;AAG1E;;;AAGG;MACU,uBAAuB,GAAG,IAAI,cAAc,CACvD,yBAAyB;AAO3B;;;AAGG;MACU,aAAa,GAAG,IAAI,cAAc,CAAsB,eAAe;AAIpF;;;;;;;;;;;;;;;;;AAiBG;MACU,iBAAiB,GAAG,IAAI,cAAc,CACjD,mBAAmB;;ACvIrB;;;;;;;;;AASG;AACI,MAAM,uBAAuB,GAAG,CAAC,MAAA,GAAiC,EAAE,KACzE,wBAAwB,CAAC;IACvB,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE;IAC7D,EAAE,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,EAAE;IAC5F,EAAE,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,EAAE;IAC5F,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,EAAE;IACrF,EAAE,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,EAAE;AAC3F,IAAA;AACE,QAAA,OAAO,EAAE,wBAAwB;AACjC,QAAA,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;AAChE,KAAA;IACD,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE;IACjF,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE,EAAE;IACjE,EAAE,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,CAAC,kBAAkB,IAAI,EAAE,EAAE;AAC5E,CAAA;;ACrDH;AACO,MAAM,2BAA2B,GAAsC;AAC5E,IAAA,QAAQ,EAAE,yBAAyB;AACnC,IAAA,iBAAiB,EAAE,0BAA0B;AAC7C,IAAA,KAAK,EAAE,qCAAqC;AAC5C,IAAA,OAAO,EAAE,iBAAiB;AAC1B,IAAA,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,CAAA,QAAA,EAAW,GAAG,EAAE,cAAc,CAAA,qBAAA,CAAuB;AAChF,IAAA,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,CAAA,QAAA,EAAW,GAAG,EAAE,cAAc,CAAA,oBAAA,CAAsB;AAC/E,IAAA,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,CAAA,uBAAA,EAA0B,GAAG,EAAE,GAAG,CAAA,CAAA,CAAG;AAC1D,IAAA,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,CAAA,sBAAA,EAAyB,GAAG,EAAE,GAAG,CAAA,CAAA,CAAG;AACzD,IAAA,OAAO,EAAE,gBAAgB;AACzB,IAAA,aAAa,EAAE,iBAAiB;AAChC,IAAA,gBAAgB,EAAE,oBAAoB;;MAI3B,yBAAyB,CAAA;AACnB,IAAA,SAAS,GAAG,MAAM,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE;AAElF;;;;;;AAMG;IACH,OAAO,CACL,MAA2C,EAC3C,QAAgB,EAChB,KAA4E,EAC5E,WAAW,GAAG,SAAS,EAAA;AAEvB,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;AAEtB,QAAA,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE;;;;YAIzB,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK;;AAEjF,YAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,SAAS;gBAAE;AACpC,YAAA,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChE;QACA,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC;IACrD;;AAGA,IAAA,UAAU,CAAC,GAAW,EAAE,QAAgB,EAAE,KAAc,EAAA;AACtD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,2BAA2B,CAAC,GAAG,CAAC;QACvE,IAAI,OAAO,KAAK,SAAS;AAAE,YAAA,OAAO,EAAE;AACpC,QAAA,OAAO,OAAO,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,OAAO;IAC3E;wGAnCW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAzB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,yBAAyB,cADZ,MAAM,EAAA,CAAA;;4FACnB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBADrC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MCDrB,kBAAkB,CAAA;AACZ,IAAA,QAAQ,GAAG,MAAM,CAAC,yBAAyB,CAAC;AACrD,IAAA,UAAU;AAET,IAAA,KAAK;IACd,IACI,OAAO,CAAC,KAAsB,EAAA;AAChC,QAAA,IAAI,CAAC,QAAQ,GAAG,KAAK;AACrB,QAAA,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE;QAC9B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC;QAC3C,IAAI,CAAC,UAAU,GAAG,KAAK,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChF;AACA,IAAA,IAAI,OAAO,GAAA;QACT,OAAO,IAAI,CAAC,QAAQ;IACtB;AACQ,IAAA,QAAQ;IAEP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;;AAGvB,IAAA,YAAY,GAAG,MAAM,CAAU,IAAI,mFAAC;IAE7C,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE;IAChC;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC7D;AAEA,IAAA,IAAI,YAAY,GAAA;AACd,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;AAAE,YAAA,OAAO,EAAE;AAC7E,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAC1B,IAAI,CAAC,OAAO,CAAC,MAAM,EACnB,IAAI,CAAC,QAAQ,EACb,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,CAAC,CAC3D;IACH;wGA3CW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA/BnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA9BS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAgClB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBApC9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BT,EAAA,CAAA;AACF,iBAAA;;sBAKE;;sBACA;;sBAYA;;sBACA;;sBACA;;;MC5BU,sBAAsB,CAAA;AACxB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC7D;wGAbW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAxBvB;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAvBS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAyBlB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBA7BlC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;ACvBH;;;;;;;;;;;;;;;AAeG;MAyEU,sBAAsB,CAAA;AACxB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;;IAGf,MAAM,GAAG,MAAM,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACtD,IAAA,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAC/B,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAE7B,IAAA,UAAU,GAAG,MAAM,CAAC,KAAK,iFAAC;AAErC,IAAA,QAAQ;AAEhB;;;;;;;;AAQG;AACH,IAAA,WAAW,CAAC,OAAsB,EAAA;AAChC,QAAA,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YAAE;AACzB,QAAA,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE;QAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QACpF,IAAI,IAAI,CAAC,QAAQ;AAAE,YAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;IAClF;;AAGA,IAAA,IAAc,UAAU,GAAA;AACtB,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM;IACtB;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC7D;AAEA;;;;;;AAMG;IACO,QAAQ,GAAA;AAChB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK;AAClC,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,EAAE;AAAE,YAAA,OAAO,IAAI;AAC5E,QAAA,IAAI;AACF,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAC5B;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,IAAI;QACb;IACF;wGA5DW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAnEvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiET,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAlES,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAoElB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAxElC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiET,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;MChEU,oBAAoB,CAAA;AACd,IAAA,QAAQ,GAAG,MAAM,CAAC,yBAAyB,CAAC;AAEpD,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC7D;AAEA,IAAA,IAAI,YAAY,GAAA;AACd,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;AAAE,YAAA,OAAO,EAAE;QAC7E,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAC1B,IAAI,CAAC,OAAO,CAAC,MAAM,EACnB,IAAI,CAAC,QAAQ,EACb,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,EAC1B,eAAe,CAChB;IACH;wGAzBW,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAlCrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAjCS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAmClB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAvChC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,kBAAkB;AAC5B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCT,EAAA,CAAA;AACF,iBAAA;;sBAIE;;sBACA;;sBACA;;sBACA;;sBACA;;;AC/CH;MAiCa,sBAAsB,CAAA;AACxB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC7D;;AAGA,IAAA,IAAI,MAAM,GAAA;AACR,QAAA,IAAI;YACF,OAAO,CAAC,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC,EAAE;iBACtG,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG;QAC3C;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,GAAG;QACZ;IACF;wGAvBW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA3BvB;;;;;;;;;;;;;;;;;;;;;;;;;AAyBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA1BS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FA4BlB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAhClC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;AAyBT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;ACtCH;MAsCa,mBAAmB,CAAA;AACrB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC7D;wGAbW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhCpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA/BS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAiClB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBArC/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;AC3CH;MAwCa,sBAAsB,CAAA;AACxB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEvB,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,8EAAC;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC7D;IAEA,gBAAgB,GAAA;AACd,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9B;wGAnBW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAlCvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAjCS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAmClB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAvClC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;MChBU,sBAAsB,CAAA;AACxB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;wGATW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAxBvB;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAvBS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,uGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAyBlB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBA7BlC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;AClCH;;;;AAIG;MAqCU,qBAAqB,CAAA;AACvB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;wGATW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA/BtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA9BS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,uGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAgClB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBApCjC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,mBAAmB;AAC7B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;MClBU,kBAAkB,CAAA;AACpB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;;AAGA,IAAA,UAAU,CAAC,KAAoB,EAAA;AAC7B,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,GAAG;AACtB,QAAA,IAAI;YACF,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,kBAAkB,EAAE;QAC7C;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,KAAK;QACd;IACF;wGAnBW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvBnB;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAtBS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAwBlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBA5B9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;ACjCH;;;;;;;AAOG;AACH,SAAS,WAAW,CAAC,KAAc,EAAA;IACjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;IACtE,IAAI,KAAK,YAAY,IAAI;AAAE,QAAA,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,KAAK;AAE9E,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;IACzB,MAAM,QAAQ,GAAG,2BAA2B,CAAC,IAAI,CAAC,GAAG,CAAC;AACtD,IAAA,IAAI,QAAQ;QAAE,OAAO,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAE3E,IAAA,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;AAC5B,IAAA,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,MAAM;AACvD;AAEA,MAAM,GAAG,GAAG,CAAC,CAAS,KAAa,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AAE7D;;;;;;AAMG;MA8BU,sBAAsB,CAAA;AACxB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;;AAGA,IAAA,IAAI,UAAU,GAAA;QACZ,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC;AAC1C,QAAA,IAAI,CAAC,CAAC;AAAE,YAAA,OAAO,EAAE;AACjB,QAAA,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA,CAAA,EAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAA,CAAA,EAAI,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA,CAAA,EAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA,CAAA,EAAI,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE;IACtH;;AAGA,IAAA,OAAO,CAAC,KAAa,EAAA;QACnB,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC3B,YAAA,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;YAC5B;QACF;AACA,QAAA,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC;;;QAGzB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AAC1E,QAAA,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;IAC9B;AAEA;;;;AAIG;AACH,IAAA,cAAc,CAAC,KAAc,EAAA;AAC3B,QAAA,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC;AAC5B,QAAA,OAAO,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,GAAG,GAAG;IACrC;wGAxCW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAxBvB;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAvBS,mBAAmB,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAyBlB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBA7BlC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,qBAAqB;AAC/B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;AC/DH;;;;;;;AAOG;MA6BU,kBAAkB,CAAA;AACpB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEhC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA;;;;AAIG;AACH,IAAA,UAAU,CAAC,KAAc,EAAA;AACvB,QAAA,OAAO,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACpE;wGAlBW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvBnB;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAtBS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAwBlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBA5B9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;ACzCH,MAAM,WAAW,GAAG;IAClB,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IACtD,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU;CACjE;AAED,MAAM,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;AAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,YAAY,GAAG,CAAC,CAAC;AAEpE;;;AAGG;MA8CU,uBAAuB,CAAA;AACzB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEvB,IAAA,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1F,KAAK,GAAG,KAAK;AAEtB,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;;AAGA,IAAA,IAAI,aAAa,GAAA;AACf,QAAA,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE;IAC/C;AAEA,IAAA,IAAI,YAAY,GAAA;AACd,QAAA,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE;IAC/C;AAEA,IAAA,aAAa,CAAC,KAAa,EAAA;AACzB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;AACrE,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,GAAG,GAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,GAAG,IAAI,CAAC;AACxD,QAAA,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;IAC9B;AAEA,IAAA,YAAY,CAAC,IAAY,EAAA;AACvB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI;AACxC,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,GAAG,IAAI,CAAC;AACvD,QAAA,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;IAC9B;AAEA,IAAA,WAAW,CAAC,KAAc,EAAA;AACxB,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,GAAG;AACtB,QAAA,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;AACjD,QAAA,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;AACzD,QAAA,OAAO,SAAS,IAAI,IAAI,GAAG,GAAG,SAAS,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,GAAG,MAAM,CAAC,KAAK,CAAC;IACnE;wGA1CW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAvB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAxCxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAvCS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAyClB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBA7CnC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,sBAAsB;AAChC,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;ACrDH;AACA,MAAM,GAAG,GAAG,GAAG;AAEf;;;;;;;;;;;;;;AAcG;MAEU,qBAAqB,CAAA;AACf,IAAA,QAAQ,GACvB,MAAM,CAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,GAAG,EAA4B;;AAGnE,IAAA,OAAO,GAAG,IAAI,GAAG,EAA4B;;AAE7C,IAAA,MAAM,GAAG,IAAI,GAAG,EAA6B;;AAE7C,IAAA,QAAQ,GAAG,IAAI,GAAG,EAAqC;;AAEvD,IAAA,MAAM,GAAG,IAAI,GAAG,EAAkB;AAEnD,IAAA,GAAG,CAAC,QAAgB,EAAA;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;IACpC;AAEA;;;AAGG;AACH,IAAA,MAAM,IAAI,CAAC,QAAgB,EAAE,IAAI,GAAG,IAAI,EAAA;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;QAEzC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;AACpC,QAAA,IAAI,MAAM;AAAE,YAAA,OAAO,MAAM;QAEzB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;AACtC,QAAA,IAAI,OAAO;AAAE,YAAA,OAAO,OAAO;QAE3B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC1C,IAAI,MAAM,KAAK,SAAS;AAAE,YAAA,OAAO,EAAE;AAEnC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,IAAG;AAChD,YAAA,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,CAAC;AACzC,YAAA,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC;YAC9B,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC;AAC5C,YAAA,OAAO,OAAO;AAChB,QAAA,CAAC,CAAC;;;QAIF,MAAM,OAAO,GAAG;AACb,aAAA,KAAK,CAAC,MAAM,EAAsB;AAClC,aAAA,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAE3C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC;AAC/B,QAAA,OAAO,OAAO;IAChB;;AAGA,IAAA,IAAI,CAAC,QAAgB,EAAE,IAAI,GAAG,IAAI,EAAA;AAChC,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACxD;AAEA;;;AAGG;AACH,IAAA,SAAS,CAAC,QAAgB,EAAE,IAAI,GAAG,IAAI,EAAA;AACrC,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACvD;AAEA;;;;;;AAMG;AACH,IAAA,QAAQ,CAAC,QAA4B,EAAE,KAAc,EAAE,IAAI,GAAG,IAAI,EAAA;AAChE,QAAA,IAAI,CAAC,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,YAAA,OAAO,SAAS;AACxF,QAAA,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE;AACnD,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAChE,YAAA,IAAI,GAAG;AAAE,gBAAA,OAAO,GAAG;QACrB;AACA,QAAA,OAAO,SAAS;IAClB;;;AAKA,IAAA,YAAY,CAAC,KAAoC,EAAA;AAC/C,QAAA,OAAO,CAAC,CAAC,KAAK,EAAE,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM;IACpD;AAEA;;;AAGG;AACH,IAAA,UAAU,CAAC,KAAoC,EAAE,IAAI,GAAG,IAAI,EAAA;AAC1D,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,EAAE;AACrB,QAAA,IAAI,KAAK,CAAC,OAAO,EAAE,MAAM;YAAE,OAAO,KAAK,CAAC,OAAO;QAC/C,IAAI,CAAC,KAAK,CAAC,QAAQ;AAAE,YAAA,OAAO,EAAE;AAC9B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE;IAC9C;;AAGA,IAAA,cAAc,CAAC,KAAoC,EAAE,IAAI,GAAG,IAAI,EAAA;AAC9D,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;AAAE,YAAA,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC,IAAI,CAAC,KAAM,CAAC,QAAS,EAAE,IAAI,CAAC;IAC1C;;AAGA,IAAA,UAAU,CAAC,QAAgB,EAAA;AACzB,QAAA,MAAM,MAAM,GAAG,CAAA,EAAG,QAAQ,CAAA,EAAG,GAAG,EAAE;AAClC,QAAA,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC5D,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE;AACjC,gBAAA,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;AAAE,oBAAA,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;YAC7C;QACF;AACA,QAAA,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE;AACzC,YAAA,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;AAAE,gBAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;QACrD;IACF;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACpB,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;AACrB,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;IACrB;;IAIQ,QAAQ,CAAC,QAAgB,EAAE,IAAY,EAAA;QAC7C,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACnC;AAEQ,IAAA,QAAQ,CAAC,QAAgB,EAAE,IAAY,EAAE,IAAY,EAAA;AAC3D,QAAA,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACzC;;AAGQ,IAAA,cAAc,CAAC,QAAgB,EAAE,IAAY,EAAE,OAAyB,EAAA;AAC9E,QAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC;AAC1C,YAAA,IAAI,CAAC,OAAO;gBAAE;YACd,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;gBACxC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,EAAE,EAAE;AAC3C,oBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC;gBAC/D;YACF;QACF;IACF;;IAGQ,cAAc,CAAC,KAAc,EAAE,IAAY,EAAA;AACjD,QAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAgC,CAAC,CAAC,MAAM,CAClE,CAAC,CAAC,KAAkB,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CACtD;YACD,MAAM,QAAQ,GAAG,YAAY,CAAC,KAA+B,EAAE,IAAI,CAAC;AACpE,YAAA,OAAO,QAAQ,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,GAAG,KAAK;QAChD;AACA,QAAA,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB;;IAIQ,MAAM,CAAC,MAAwB,EAAE,IAAY,EAAA;AACnD,QAAA,IAAI,MAAwB;AAC5B,QAAA,IAAI;AACF,YAAA,MAAM,GAAG,OAAO,MAAM,KAAK,UAAU,GAAI,MAA2B,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM;QACzF;QAAE,OAAO,GAAG,EAAE;;;AAGZ,YAAA,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;QAC5B;AACA,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;IAC/B;AAEQ,IAAA,SAAS,CAAC,MAAwB,EAAA;AACxC,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAAE,YAAA,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;AACzD,QAAA,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;;YAE/B,OAAO,IAAI,OAAO,CAAuB,CAAC,OAAO,EAAE,MAAM,KAAI;gBAC3D,IAAI,OAAO,GAAG,KAAK;AACnB,gBAAA,MAAM,MAAM,GAAG,CAAC,EAAc,KAAI;AAChC,oBAAA,IAAI,OAAO;wBAAE;oBACb,OAAO,GAAG,IAAI;AACd,oBAAA,EAAE,EAAE;AACN,gBAAA,CAAC;gBACD,MAAM,CAAC,SAAS,CAAC;AACf,oBAAA,IAAI,EAAE,KAAK,IAAI,MAAM,CAAC,MAAM,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AACjD,oBAAA,KAAK,EAAE,GAAG,IAAI,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;;AAEvC,oBAAA,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;AAC1C,iBAAA,CAAC;AACJ,YAAA,CAAC,CAAC;QACJ;AACA,QAAA,OAAO,OAAO,CAAC,OAAO,CAAC,MAAuC,CAAC;IACjE;AAEQ,IAAA,cAAc,CAAC,KAAc,EAAA;AACnC,QAAA,QACE,OAAO,KAAK,KAAK,QAAQ;AACzB,YAAA,KAAK,KAAK,IAAI;AACd,YAAA,OAAQ,KAA4C,CAAC,SAAS,KAAK,UAAU;IAEjF;wGA1MW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAArB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,qBAAqB,cADR,MAAM,EAAA,CAAA;;4FACnB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBADjC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AAqNlC,MAAM,cAAc,GAAG,IAAI,OAAO,EAAkE;AAEpG;;;;;;;;;;;;;AAaG;AACG,SAAU,oBAAoB,CAAC,IAAsB,EAAE,OAA8B,EAAA;IACzF,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;AACrC,IAAA,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,EAAE;QACpE;IACF;AACA,IAAA,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;AAEpE,IAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/D,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE;AAEvC,IAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ;AACrC,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ;AAC1B,IAAA,KAAK,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,IAAG;AACpE,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;AAAE,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AAC5F,IAAA,CAAC,CAAC;AACJ;;MCzNa,sBAAsB,CAAA;AAChB,IAAA,OAAO,GAAG,MAAM,CAAC,qBAAqB,CAAC;AACvC,IAAA,QAAQ,GAAG,MAAM,CAAC,yBAAyB,CAAC;AAErD,IAAA,MAAM;IACN,SAAS,GAAG,IAAI;;IAGxB,IAAa,KAAK,CAAC,KAAwB,EAAA;AACzC,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;IAC1C;AACA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;IAEA,IAAa,QAAQ,CAAC,KAAa,EAAA;AACjC,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK,IAAI,IAAI;AAC9B,QAAA,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;IAC1C;AACA,IAAA,IAAI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,SAAS;IACvB;AAES,IAAA,OAAO;IACP,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;;AAGvB,IAAA,OAAO,GAAG,MAAM,CAAmB,EAAE,8EAAC;AAEtC,IAAA,SAAS,GAAG,CAAC,EAAW,EAAE,EAAW,KAAc,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC;AAE9F,IAAA,WAAW,CAAC,MAAsB,EAAA;AAChC,QAAA,MAAM,GAAG,GAAG,oBAAoB,CAAC,MAAM,CAAC;QACxC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;IAChD;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC7D;AAEA,IAAA,eAAe,CAAC,MAAsB,EAAA;AACpC,QAAA,OAAO,oBAAoB,CAAC,MAAM,CAAC;IACrC;AAEA,IAAA,WAAW,CAAC,MAAsB,EAAA;QAChC,OAAO,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;IAClD;AAEA;;;;AAIG;AACH,IAAA,QAAQ,CAAC,KAAc,EAAA;AACrB,QAAA,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE;AAAE,YAAA,OAAO,GAAG;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,WAAW,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AACnG,QAAA,IAAI,MAAM;AAAE,YAAA,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;AAChF,QAAA,IAAI,MAAM;AAAE,YAAA,OAAO,MAAM;QACzB,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,YAAY,CAAC,KAA+B,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC;IACxH;AAEA,IAAA,IAAI,YAAY,GAAA;AACd,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;AAAE,YAAA,OAAO,EAAE;;;QAG7E,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAC1B,IAAI,CAAC,OAAO,CAAC,MAAM,EACnB,IAAI,CAAC,QAAQ,EACb,CAAC,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC,EACnC,kBAAkB,CACnB;IACH;wGA9EW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA1CvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAzCS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,0BAAA,EAAA,QAAA,EAAA,6GAAA,EAAA,MAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FA2ClB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBA/ClC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCT,EAAA,CAAA;AACF,iBAAA;;sBASE;;sBAQA;;sBAQA;;sBACA;;sBACA;;;ACzEH;MAuCa,mBAAmB,CAAA;AACb,IAAA,OAAO,GAAG,MAAM,CAAC,qBAAqB,CAAC;AAEhD,IAAA,MAAM;IACN,SAAS,GAAG,IAAI;;IAGxB,IAAa,KAAK,CAAC,KAAwB,EAAA;AACzC,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;IAC1C;AACA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;IAEA,IAAa,QAAQ,CAAC,KAAa,EAAA;AACjC,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK,IAAI,IAAI;AAC9B,QAAA,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;IAC1C;AACA,IAAA,IAAI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,SAAS;IACvB;AAES,IAAA,OAAO;IACP,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;;AAGvB,IAAA,OAAO,GAAG,MAAM,CAAmB,EAAE,8EAAC;AAE/C,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,eAAe,CAAC,MAAsB,EAAA;AACpC,QAAA,OAAO,oBAAoB,CAAC,MAAM,CAAC;IACrC;AAEA;;;;AAIG;AACH,IAAA,UAAU,CAAC,MAAsB,EAAA;AAC/B,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC;QACpD,OAAO,CAAA,EAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAA,CAAA,EAAI,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA,CAAE;IAC7E;AAEA,IAAA,SAAS,CAAC,MAAsB,EAAA;QAC9B,OAAO,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;IAClD;AAEA,IAAA,WAAW,CAAC,MAAsB,EAAA;QAChC,OAAO,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;IAClD;;IAGA,gBAAgB,GAAA;AACd,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK;;;QAGjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,YAAA,OAAO,GAAG;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,WAAW,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AACrG,QAAA,IAAI,QAAQ;AAAE,YAAA,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;AAChF,QAAA,IAAI,MAAM;AAAE,YAAA,OAAO,MAAM;QACzB,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,YAAY,CAAC,KAA+B,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC;IACxH;wGAnEW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAjCpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAhCS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,yBAAA,EAAA,QAAA,EAAA,8FAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,iBAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAkClB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAtC/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BT,EAAA,CAAA;AACF,iBAAA;;sBAQE;;sBAQA;;sBAQA;;sBACA;;sBACA;;;MC3BU,yBAAyB,CAAA;AACnB,IAAA,OAAO,GAAG,MAAM,CAAC,qBAAqB,CAAC;AAEhD,IAAA,MAAM;IACN,SAAS,GAAG,IAAI;;IAGxB,IAAa,KAAK,CAAC,KAAwB,EAAA;AACzC,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;IAC1C;AACA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;IAEA,IAAa,QAAQ,CAAC,KAAa,EAAA;AACjC,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK,IAAI,IAAI;AAC9B,QAAA,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;IAC1C;AACA,IAAA,IAAI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,SAAS;IACvB;AAES,IAAA,OAAO;IACP,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;;AAGvB,IAAA,OAAO,GAAG,MAAM,CAAmB,EAAE,8EAAC;AAEtC,IAAA,SAAS,GAAG,CAAC,EAAW,EAAE,EAAW,KAAc,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC;AAE9F,IAAA,WAAW,CAAC,MAAsB,EAAA;AAChC,QAAA,MAAM,GAAG,GAAG,oBAAoB,CAAC,MAAM,CAAC;QACxC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;IAChD;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,eAAe,CAAC,MAAsB,EAAA;AACpC,QAAA,OAAO,oBAAoB,CAAC,MAAM,CAAC;IACrC;AAEA,IAAA,WAAW,CAAC,MAAsB,EAAA;QAChC,OAAO,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;IAClD;;AAGA,IAAA,SAAS,CAAC,MAAe,EAAA;QACvB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM;AAAE,YAAA,OAAO,GAAG;AACxD,QAAA,OAAO;aACJ,GAAG,CAAC,CAAC,IAAG;YACP,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,WAAW,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC5F,YAAA,IAAI,GAAG;AAAE,gBAAA,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC;AAC5E,YAAA,IAAI,MAAM;AAAE,gBAAA,OAAO,MAAM;YACzB,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,GAAG,YAAY,CAAC,CAA2B,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AACnH,QAAA,CAAC;aACA,IAAI,CAAC,IAAI,CAAC;IACf;wGA7DW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAzB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAjC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAhCS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kCAAA,EAAA,QAAA,EAAA,2FAAA,EAAA,MAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAkClB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAtCrC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,wBAAwB;AAClC,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BT,EAAA,CAAA;AACF,iBAAA;;sBAQE;;sBAQA;;sBAQA;;sBACA;;sBACA;;;ACtEH;;;;;;;AAOG;MAEU,wBAAwB,CAAA;AAClB,IAAA,QAAQ,GACvB,MAAM,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,GAAG,EAAiC;AAE7F;;;AAGG;AACH,IAAA,OAAO,CAAC,SAAiB,EAAA;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI;IAC7C;AAEA,IAAA,GAAG,CAAC,SAAiB,EAAA;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;IACrC;wGAdW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAxB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,wBAAwB,cADX,MAAM,EAAA,CAAA;;4FACnB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBADpC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACOlC;AACA,MAAM,SAAS,GAAG,GAAG;AAErB;;;;;;;;;;;;;AAaG;MAEU,sBAAsB,CAAA;AAChB,IAAA,QAAQ,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAC3C,IAAA,KAAK,GAAG,MAAM,CAAC,sBAAsB,CAAC;;AAGtC,IAAA,QAAQ,GAAG,IAAI,GAAG,EAAsC;;AAExD,IAAA,MAAM,GAAG,IAAI,GAAG,EAAkB;AAEnD;;;AAGG;AACH,IAAA,MAAM,IAAI,CAAC,SAAiB,EAAE,MAA8B,EAAE,EAAA;AAC5D,QAAA,MAAM,GAAG,GAAG,sBAAsB,CAAC,SAAS,EAAE;YAC5C,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,aAAa,EAAE,GAAG,CAAC,aAAa;YAChC,WAAW,EAAE,GAAG,CAAC,WAAW;AAC7B,SAAA,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;AAClC,QAAA,IAAI,MAAM;AAAE,YAAA,OAAO,MAAM;QAEzB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;AACtC,QAAA,IAAI,OAAO;AAAE,YAAA,OAAO,OAAO;QAE3B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;AAC/C,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;QAEtB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG;aACjC,IAAI,CAAC,GAAG,IAAG;;AAEV,YAAA,MAAM,OAAO,GAAG,yBAAyB,CACvC,GAAyB,EACzB,GAAG,CAAC,aAAa,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,SAAS,EACnF,GAAG,CAAC,IAAI,IAAI,IAAI,CACjB;YACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC;AAC5B,YAAA,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,OAAO,CAAC;AACzD,YAAA,OAAO,OAAO;AAChB,QAAA,CAAC,CAAC;;;;QAKJ,MAAM,OAAO,GAAG;AACb,aAAA,KAAK,CAAC,MAAM,EAAuB;AACnC,aAAA,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAE3C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC;AAC/B,QAAA,OAAO,OAAO;IAChB;;AAGA,IAAA,IAAI,CAAC,SAAiB,EAAE,GAAA,GAA8B,EAAE,EAAA;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CACnB,sBAAsB,CAAC,SAAS,EAAE;YAChC,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,aAAa,EAAE,GAAG,CAAC,aAAa;YAChC,WAAW,EAAE,GAAG,CAAC,WAAW;AAC7B,SAAA,CAAC,CACH;IACH;AAEA;;;AAGG;AACH,IAAA,QAAQ,CAAC,SAAiB,EAAE,KAAc,EAAE,IAAI,GAAG,IAAI,EAAA;AACrD,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/D;;AAGA,IAAA,UAAU,CAAC,SAAiB,EAAA;QAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE;AACnC,YAAA,IAAI,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS;AAAE,gBAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;QACtE;AACA,QAAA,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE;AAC3C,YAAA,IAAI,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS;AAAE,gBAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC;QACzE;AACA,QAAA,MAAM,MAAM,GAAG,CAAA,EAAG,SAAS,CAAA,EAAG,SAAS,EAAE;AACzC,QAAA,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE;AACzC,YAAA,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;AAAE,gBAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;QACrD;IACF;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;AAClB,QAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;AACrB,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;IACrB;AAEQ,IAAA,cAAc,CAAC,SAAiB,EAAE,IAAY,EAAE,OAA0B,EAAA;AAChF,QAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC;QAC7E;IACF;;AAGQ,IAAA,QAAQ,CAAC,SAAiB,EAAE,IAAY,EAAE,KAAc,EAAA;QAC9D,MAAM,SAAS,GACb,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK;AACjC,cAAE,YAAY,CAAC,KAA+B,EAAE,IAAI;AACpD,cAAE,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;AACzB,QAAA,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;IACrD;;IAIQ,MAAM,CACZ,MAA6B,EAC7B,GAA2B,EAAA;AAE3B,QAAA,IAAI,MAA6B;AACjC,QAAA,IAAI;AACF,YAAA,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC;QACtB;QAAE,OAAO,GAAG,EAAE;;;AAGZ,YAAA,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;QAC5B;AACA,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;IAC/B;AAEQ,IAAA,SAAS,CAAC,MAA6B,EAAA;AAC7C,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAAE,YAAA,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;AACzD,QAAA,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;;YAE/B,OAAO,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,MAAM,KAAI;gBACxD,IAAI,OAAO,GAAG,KAAK;AACnB,gBAAA,MAAM,MAAM,GAAG,CAAC,EAAc,KAAI;AAChC,oBAAA,IAAI,OAAO;wBAAE;oBACb,OAAO,GAAG,IAAI;AACd,oBAAA,EAAE,EAAE;AACN,gBAAA,CAAC;gBACD,MAAM,CAAC,SAAS,CAAC;AACf,oBAAA,IAAI,EAAE,KAAK,IAAI,MAAM,CAAC,MAAM,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;;AAEjD,oBAAA,KAAK,EAAE,GAAG,IAAI,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;;AAEvC,oBAAA,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;AAC1C,iBAAA,CAAC;AACJ,YAAA,CAAC,CAAC;QACJ;AACA,QAAA,OAAO,OAAO,CAAC,OAAO,CAAC,MAAoC,CAAC;IAC9D;AAEQ,IAAA,cAAc,CAAC,KAAc,EAAA;AACnC,QAAA,QACE,OAAO,KAAK,KAAK,QAAQ;AACzB,YAAA,KAAK,KAAK,IAAI;AACd,YAAA,OAAQ,KAAyC,CAAC,SAAS,KAAK,UAAU;IAE9E;;AAGA,IAAA,OAAO,CAAC,CAAU,EAAE,CAAU,EAAE,IAAI,GAAG,IAAI,EAAA;QACzC,OAAO,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC;IAChC;wGAhKW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,sBAAsB,cADT,MAAM,EAAA,CAAA;;4FACnB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBADlC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACxBlC;;;;;;AAMG;MAEU,kBAAkB,CAAA;AACZ,IAAA,QAAQ,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAC3C,IAAA,UAAU,GAAG,MAAM,CAAC,sBAAsB,CAAC;;AAG3C,IAAA,QAAQ,GAAG,IAAI,GAAG,EAAyB;;AAG5D,IAAA,YAAY,CAAC,KAAwB,EAAA;QACnC,OAAO,KAAK,CAAC,eAAe,EAAE,eAAe,IAAI,KAAK,CAAC,EAAE;IAC3D;;AAGA,IAAA,OAAO,CAAC,KAAwB,EAAA;AAC9B,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACpD;AAEA;;;AAGG;AACH,IAAA,MAAM,IAAI,CACR,KAAwB,EACxB,MAA8B,EAAE,EAAA;AAEhC,QAAA,MAAM,GAAG,GAAG,KAAK,CAAC,eAAe;AACjC,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;AAAE,YAAA,OAAO,EAAE;;AAGnC,QAAA,MAAM,cAAc,GAClB,GAAG,CAAC,WAAW,KAAK,IAAI,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,GAAG,CAAC,WAAW,KAAK,EAAE;AACrF,QAAA,IAAI,GAAG,EAAE,WAAW,IAAI,CAAC,cAAc;AAAE,YAAA,OAAO,EAAE;AAElD,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,IAAI;;;;;AAM7B,QAAA,MAAM,cAAc,GAAG,CAAC,EAAE,GAAG,EAAE,YAAY,IAAI,GAAG,EAAE,UAAU,CAAC;AAE/D,QAAA,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;AACnE,YAAA,GAAG,GAAG;YACN,WAAW,EAAE,cAAc,GAAG,SAAS,GAAG,GAAG,CAAC,WAAW;AACzD,YAAA,OAAO,EAAE,EAAE,IAAI,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE;YAC5D,aAAa,EAAE,GAAG,EAAE,aAAa;YACjC,IAAI;AACL,SAAA,CAAC;AAEF,QAAA,OAAO,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC;IAChE;;AAIA;;;;;;AAMG;AACH,IAAA,qBAAqB,CAAC,YAAoB,EAAE,MAAwB,EAAE,IAAI,GAAG,IAAI,EAAA;QAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC;AAChD,QAAA,IAAI,QAAQ;AAAE,YAAA,OAAO,QAAQ;QAE7B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CACrB,MAAM,CAAC,GAAG,CAAC,KAAK,IACd,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;AAC7C,YAAA,OAAO,EAAE,KAAK,CAAC,eAAe,EAAE,OAAO;AACvC,YAAA,aAAa,EAAE,KAAK,CAAC,eAAe,EAAE,aAAa;YACnD,IAAI;SACL,CAAC,CACH,CACF,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC;QAEvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC;AACpC,QAAA,OAAO,GAAG;IACZ;;IAGA,MAAM,WAAW,CAAC,YAAoB,EAAA;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC;AAC3C,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,KAAK;AACtB,QAAA,MAAM,GAAG;AACT,QAAA,OAAO,IAAI;IACb;AAEA;;;AAGG;AACH,IAAA,qBAAqB,CACnB,KAAwB,EACxB,WAAoB,EACpB,IAAI,GAAG,IAAI,EAAA;AAEX,QAAA,MAAM,GAAG,GAAG,KAAK,CAAC,eAAe;AACjC,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;YAC5D,OAAO,EAAE,GAAG,EAAE,OAAO;YACrB,aAAa,EAAE,GAAG,EAAE,aAAa;YACjC,IAAI;AACL,SAAA,CAAC;AACF,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;QACtB,OAAO,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC;IAC3D;;AAGA,IAAA,UAAU,CAAC,YAAoB,EAAA;AAC7B,QAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC;IACpC;;AAGQ,IAAA,aAAa,CAAC,MAAwB,EAAA;QAC5C,MAAM,KAAK,GAAwB,EAAE;AACrC,QAAA,MAAM,UAAU,GAAG,CAAC,MAAuC,KAAI;AAC7D,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE,EAAE;AAChC,gBAAA,MAAM,GAAG,GAAG,KAAK,CAAC,eAAe;AACjC,gBAAA,IAAI,GAAG,EAAE,OAAO,KAAK,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,YAAY,CAAC,EAAE;AAC3E,oBAAA,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;gBACnB;AACA,gBAAA,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC5B;AACF,QAAA,CAAC;AACD,QAAA,MAAM,QAAQ,GAAG,CAAC,IAAmC,KAAI;AACvD,YAAA,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE;AAC5B,gBAAA,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;AACtB,gBAAA,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;YACxB;AACF,QAAA,CAAC;AACD,QAAA,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;AACtB,QAAA,OAAO,KAAK;IACd;wGApIW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,cADL,MAAM,EAAA,CAAA;;4FACnB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAD9B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACTlC;;;;;;;;;AASG;MAEU,yBAAyB,CAAA;AACnB,IAAA,OAAO,GAAG,IAAI,OAAO,EAAsB;AAEnD,IAAA,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;IAEjD,IAAI,CAAC,OAAe,EAAE,MAA8B,EAAA;QAClD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IACxC;wGAPW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAzB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,yBAAyB,cADZ,MAAM,EAAA,CAAA;;4FACnB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBADrC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACZlC;;;;;;;AAOG;MAwCU,uBAAuB,CAAA;AACzB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEf,IAAA,OAAO,GAAG,MAAM,CAAC,kBAAkB,CAAC;AACpC,IAAA,YAAY,GAAG,MAAM,CAAC,yBAAyB,CAAC;AAChD,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAEvC,IAAA,OAAO,GAAG,MAAM,CAAoB,EAAE,8EAAC;AACvC,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,8EAAC;;AAEvB,IAAA,cAAc,GAAG,MAAM,CAAC,KAAK,qFAAC;AAEvC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC7D;AAEA,IAAA,IAAI,aAAa,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE,eAAe,EAAE,WAAW;IACjD;IAEA,QAAQ,GAAA;QACN,IAAI,IAAI,CAAC,MAAM;YAAE;AACjB,QAAA,KAAK,IAAI,CAAC,MAAM,EAAE;QAClB,IAAI,CAAC,WAAW,EAAE;QAClB,IAAI,CAAC,OAAO,EAAE;AACX,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;AACxC,aAAA,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IACnE;;AAGA,IAAA,MAAM,MAAM,GAAA;AACV,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE;QACtC,IAAI,CAAC,cAAc,CAAC,GAAG,CACrB,CAAC,CAAC,IAAI,CAAC,aAAa,KAAK,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,EAAE,CAAC,CAClG;AAED,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACrC,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB;QACF;AAEA,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI;YACF,IAAI,CAAC,OAAO,CAAC,GAAG,CACd,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAC1E;QACH;gBAAU;AACR,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACzB;IACF;AAEA;;;;;;;;AAQG;AACH,IAAA,iBAAiB,CAAC,KAAc,EAAA;AAC9B,QAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IACnE;AAEQ,IAAA,gBAAgB,CAAC,OAAe,EAAA;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC;AACtE,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,IAAI,IAAI,CAAC;IACzD;AAEA,IAAA,QAAQ,CAAC,KAAU,EAAA;QACjB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1E,OAAO,MAAM,EAAE,KAAK,KAAK,KAAK,IAAI,GAAG,CAAC;IACxC;IAEQ,WAAW,GAAA;AACjB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa;AACnC,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,SAAS;AAC/B,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK;IACnD;;IAGQ,WAAW,GAAA;AACjB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa;AACnC,QAAA,IAAI,CAAC,QAAQ;YAAE;AACf,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;AACzD,QAAA,IAAI,CAAC,aAAa;YAAE;AAEpB,QAAA,aAAa,CAAC;AACX,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aACxC,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACtB,gBAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAC/C,gBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC;YAC7C;AACA,YAAA,KAAK,IAAI,CAAC,MAAM,EAAE;AACpB,QAAA,CAAC,CAAC;IACN;wGAxGW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAvB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAlCxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAjCS,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,0BAAA,EAAA,QAAA,EAAA,6GAAA,EAAA,MAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAmClB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAvCnC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,sBAAsB;AAChC,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mBAAmB,CAAC;AAC9B,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;ACzDH;;;;;;;;;AASG;MAEU,oBAAoB,CAAA;AACd,IAAA,gBAAgB,GAC/B,MAAM,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,GAAG,EAAqB;AAChE,IAAA,eAAe,GAAG,IAAI,GAAG,EAAqB;AAE/D,IAAA,WAAA,GAAA;;AAEE,QAAA,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;AACnE,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;QACvB;IACF;;IAGA,QAAQ,CAAC,IAAY,EAAE,SAAoB,EAAA;QACzC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC;IAC3C;;AAGA,IAAA,WAAW,CAAC,GAA8B,EAAA;AACxC,QAAA,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YAC9C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC;QACtC;IACF;AAEA;;;AAGG;AACH,IAAA,OAAO,CAAC,SAAiB,EAAA;AACvB,QAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI;IAC5F;;AAGA,IAAA,GAAG,CAAC,SAAiB,EAAA;AACnB,QAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC;IACpF;;IAGA,eAAe,GAAA;QACb,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;IAC/F;wGAxCW,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAApB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,oBAAoB,cADP,MAAM,EAAA,CAAA;;4FACnB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBADhC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACRlC;;AAEG;MAEU,WAAW,CAAA;AACL,IAAA,WAAW,GAAG,MAAM,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE;AAE7E;;;AAGG;IACH,aAAa,CAAC,SAAmB,EAAE,aAAwB,EAAA;QACzD,IAAI,CAAC,aAAa,EAAE,MAAM;AAAE,YAAA,OAAO,IAAI;AACvC,QAAA,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACvD;;AAGA,IAAA,oBAAoB,CAAC,QAAkB,EAAE,OAAiB,EAAE,SAAmB,EAAA;QAC7E,OAAOA,oBAAwB,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;IAC/D;;AAGA,IAAA,gBAAgB,CAAC,SAAmB,EAAA;AAClC,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC1D;;AAGA,IAAA,eAAe,CAAC,KAAwB,EAAE,GAAgC,EAAE,MAAwB,EAAE,SAAmB,EAAA;AACvH,QAAA,OAAOC,eAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC;IAC7E;;IAGA,cAAc,CAAC,MAAwB,EAAE,SAAmB,EAAA;QAC1D,OAAO;AACL,YAAA,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC;AAChE,YAAA,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC;AAChE,YAAA,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;SACrE;IACH;wGAlCW,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAX,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,cADE,MAAM,EAAA,CAAA;;4FACnB,WAAW,EAAA,UAAA,EAAA,CAAA;kBADvB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACYlC;;;;;;;;AAQG;MAOU,qBAAqB,CAAA;AACvB,IAAA,KAAK;AACL,IAAA,OAAO;AACP,IAAA,MAAM;AACN,IAAA,YAAY;IACZ,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,SAAS,GAAa,EAAE;AAGhB,IAAA,SAAS;AAET,IAAA,aAAa,GAAG,MAAM,CAAC,oBAAoB,CAAC;AAC5C,IAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AAClD;;;;AAIG;AACc,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IAEpC,YAAY,GAAiC,IAAI;AAEzD,IAAA,WAAW,CAAC,QAAuB,EAAA;QACjC,IAAI,CAAC,UAAU,EAAE;IACnB;IAEQ,UAAU,GAAA;QAChB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AAElC,QAAA,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAClE,IAAI,CAAC,cAAc,EAAE;YACnB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;AACpC,YAAA,OAAO;QACT;;QAGA,MAAM,GAAG,GAA2B,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI;QAC5G,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;;AAG1G,QAAA,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,YAAY,cAAc,EAAE;YAC7E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;YACzC;QACF;AAEA,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;QACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,cAAc,EAAE;YACjE,QAAQ,EAAE,IAAI,CAAC,QAAQ;AACxB,SAAA,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;QACzC,IAAI,CAAC,YAAY,EAAE;AACnB,QAAA,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,aAAa,EAAE;IACrD;AAEA;;;;AAIG;AACK,IAAA,cAAc,CAAC,IAAY,EAAA;QACjC,IAAI,CAAC,SAAS,EAAE,IAAI,qBAAqB,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE;AACjE,QAAA,qBAAqB,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AAC3C,QAAA,OAAO,CAAC,IAAI,CACV,CAAA,6DAAA,EAAgE,IAAI,CAAA,gCAAA,CAAkC;YACpG,CAAA,sCAAA,EAAyC,IAAI,CAAA,gDAAA,CAAkD,CAClG;IACH;AAEQ,IAAA,OAAgB,WAAW,GAAG,IAAI,GAAG,EAAU;AAEvD;;;;;;;AAOG;IACH,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,YAAY,EAAE,iBAAiB,CAAC,aAAa,EAAE;IACtD;AAEA;;;;;;;;;;;;;;AAcG;IACK,YAAY,GAAA;AAClB,QAAA,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE;QAC9B,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AAEnB,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7E;AAEQ,IAAA,UAAU;IAElB,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE;IAChC;AAEA;;;;;;AAMG;IACK,SAAS,CAAC,GAA0B,EAAE,MAAe,EAAA;QAC3D,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;QACjC,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC;QACrC,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC;AACvC,QAAA,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;AAChE,QAAA,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAChC;wGA5HW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,MAAA,EAAA,QAAA,EAAA,YAAA,EAAA,cAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,WAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,WAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,IAAA,EASA,gBAAgB,EAAA,MAAA,EAAA,IAAA,EAAA,CAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAXtC,CAAA,wCAAA,CAA0C,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAEzC,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBANjC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,mBAAmB;AAC7B,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,QAAQ,EAAE,CAAA,wCAAA,CAA0C;AACrD,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;sBAEA,SAAS;uBAAC,WAAW,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE;;;ACtClE;MAqDa,mBAAmB,CAAA;AACrB,IAAA,KAAK;AACL,IAAA,OAAO;AACP,IAAA,MAAM;IACN,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;IACvB,SAAS,GAAa,EAAE;AAEjC,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,eAAe,CAAC,OAAe,EAAA;AAC7B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAoB;AACvC,QAAA,OAAO,KAAK,EAAE,GAAG,CAAC,OAAO,CAAoB;IAC/C;wGAhBW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,MAAA,EAAA,QAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA/CpB;;;;;;;;;;;;;;;;;;;;;;;GAuBT,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,yQAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,CAAA,MAxBS,mBAAmB,oDAAmB,qBAAqB,CAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,cAAA,EAAA,UAAA,EAAA,UAAA,EAAA,WAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAgD1D,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBApD/B,SAAS;AACS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC,iBAAiB,EAAA,UAAA,EACf,IAAI,WACP,CAAC,mBAAmB,EAAE,UAAU,CAAC,MAAM,qBAAqB,CAAC,CAAC,EAAA,QAAA,EAC7D;;;;;;;;;;;;;;;;;;;;;;;AAuBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,yQAAA,CAAA,EAAA;;sBAyBA;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;;AC7DH;;AAEG;MAEU,wBAAwB,CAAA;AAClB,IAAA,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,GAAG,EAAE;AAC9E,IAAA,aAAa,GAAG,MAAM,CAAC,wBAAwB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,GAAG,EAAE;AAElG;;;AAGG;AACH,IAAA,OAAO,CAAC,YAAoB,EAAA;QAC1B,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;YAC3C,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC;QAChD;QAEA,IAAI,YAAY,KAAK,UAAU;YAAE,OAAO,UAAU,CAAC,QAAQ;QAC3D,IAAI,YAAY,KAAK,OAAO;YAAE,OAAO,UAAU,CAAC,KAAK;AAErD,QAAA,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC;AAC7C,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAE/B,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AAAE,YAAA,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;QACjE,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AAAE,YAAA,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;QACjE,IAAI,IAAI,KAAK,WAAW,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AAAE,YAAA,OAAO,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC;QAC7E,IAAI,IAAI,KAAK,WAAW,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AAAE,YAAA,OAAO,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC;AAE7E,QAAA,OAAO,IAAI;IACb;;IAGA,UAAU,CAAC,gBAA0B,EAAE,EAAA;QACrC,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAuB,CAAC,KAAK,IAAI,CAAC;IAC5F;;AAGA,IAAA,iBAAiB,CAAC,MAAmC,EAAA;AACnD,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;AACtB,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAAE,YAAA,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAEzD,MAAM,MAAM,GAAkB,EAAE;QAChC,IAAI,MAAM,CAAC,QAAQ;AAAE,YAAA,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;AACrD,QAAA,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;AAAE,YAAA,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACrE,QAAA,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;AAAE,YAAA,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACrE,QAAA,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;AAAE,YAAA,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACvF,QAAA,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;AAAE,YAAA,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACvF,IAAI,MAAM,CAAC,OAAO;AAAE,YAAA,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnE,IAAI,MAAM,CAAC,KAAK;AAAE,YAAA,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;;;;;QAM/C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE;YACrC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;AAC5B,YAAA,IAAI,EAAE;AAAE,gBAAA,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB;AAEA,QAAA,OAAO,MAAM;IACf;AAEA;;;;;;;;;AASG;AACH,IAAA,sBAAsB,CAAC,MAAmC,EAAA;QACxD,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAAE,YAAA,OAAO,EAAE;QAE/C,MAAM,GAAG,GAAuB,EAAE;QAClC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE;YAC1C,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;AACtC,YAAA,IAAI,EAAE;AAAE,gBAAA,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB;AACA,QAAA,OAAO,GAAG;IACZ;wGA7EW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAxB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,wBAAwB,cADX,MAAM,EAAA,CAAA;;4FACnB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBADpC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACDlC;MA6Ha,mBAAmB,CAAA;AAC9B;;;;AAIG;AACc,IAAA,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC;AACvC,IAAA,KAAK;AACL,IAAA,OAAO;AACP,IAAA,MAAM;IACN,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;IACvB,SAAS,GAAa,EAAE;AAEhB,IAAA,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;AACxB,IAAA,iBAAiB,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAErE,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAI,SAAS,GAAA;QACX,OAAO,IAAI,CAAC,OAAoB;IAClC;IAEA,mBAAmB,CAAC,SAA0B,EAAE,OAAe,EAAA;AAC7D,QAAA,OAAQ,SAAuB,CAAC,GAAG,CAAC,OAAO,CAAoB;IACjE;IAEA,OAAO,GAAA;QACL,MAAM,QAAQ,GAAwB,EAAE;QACxC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,EAAE;AAC7C,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC;AAC7E,YAAA,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,IAAI,EAAE,UAAU,CAAC;QAC/D;QACA,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;AACrC,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;AAC1B,QAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;IACzB;AAEA,IAAA,UAAU,CAAC,KAAa,EAAA;AACtB,QAAA,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC9B,QAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;IACzB;wGA5CW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,MAAA,EAAA,QAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvHpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDT,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,k/BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,CAAA,MAnDS,mBAAmB,oDAAmB,qBAAqB,CAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,cAAA,EAAA,UAAA,EAAA,UAAA,EAAA,WAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAwH1D,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBA5H/B,SAAS;AACS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC,iBAAiB,EAAA,UAAA,EACf,IAAI,WACP,CAAC,mBAAmB,EAAE,UAAU,CAAC,MAAM,qBAAqB,CAAC,CAAC,EAAA,QAAA,EAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,k/BAAA,CAAA,EAAA;;sBA4EA;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;;AC7IH;;;;;;AAMG;MAEU,iBAAiB,CAAA;IACX,OAAO,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAErE,IAAA,IAAI,UAAU,GAAA;AACZ,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO;IACvB;;AAGQ,IAAA,QAAQ,CAAC,IAAU,EAAA;AACzB,QAAA,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE;IAClE;AAEA;;;AAGG;IACH,MAAM,SAAS,CAAC,IAAU,EAAA;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE;AAE3C,QAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvD,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE;IACrE;;AAGA,IAAA,aAAa,CAAC,GAA+B,EAAA;AAC3C,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,IAAI;QACrB,IAAI,GAAG,CAAC,GAAG;YAAE,OAAO,GAAG,CAAC,GAAG;AAC3B,QAAA,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,KAAK,WAAW,IAAI,OAAO,GAAG,CAAC,eAAe,KAAK,UAAU,EAAE;YACvF,OAAO,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;QACtC;AACA,QAAA,OAAO,IAAI;IACb;AAEA,IAAA,gBAAgB,CAAC,GAAkB,EAAA;QACjC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE;AACtC,QAAA,IAAI,OAAO,GAAG,KAAK,WAAW,IAAI,OAAO,GAAG,CAAC,eAAe,KAAK,UAAU,EAAE;AAC3E,YAAA,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC;QAC1B;IACF;AAEQ,IAAA,SAAS,CACf,MAAyE,EAAA;AAEzE,QAAA,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;YAC/B,OAAO,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,KAAI;gBACnD,IAAI,OAAO,GAAG,KAAK;gBACnB,MAAM,CAAC,SAAS,CAAC;oBACf,IAAI,EAAE,KAAK,IAAG;AACZ,wBAAA,IAAI,OAAO;4BAAE;wBACb,OAAO,GAAG,IAAI;wBACd,OAAO,CAAC,KAAK,CAAC;oBAChB,CAAC;oBACD,KAAK,EAAE,GAAG,IAAG;AACX,wBAAA,IAAI,OAAO;4BAAE;wBACb,OAAO,GAAG,IAAI;wBACd,MAAM,CAAC,GAAG,CAAC;oBACb,CAAC;oBACD,QAAQ,EAAE,MAAK;AACb,wBAAA,IAAI,OAAO;4BAAE;wBACb,OAAO,GAAG,IAAI;AACd,wBAAA,MAAM,CAAC,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;oBAC1E,CAAC;AACF,iBAAA,CAAC;AACJ,YAAA,CAAC,CAAC;QACJ;AACA,QAAA,OAAO,OAAO,CAAC,OAAO,CAAC,MAA8C,CAAC;IACxE;AAEQ,IAAA,cAAc,CAAC,KAAc,EAAA;AACnC,QAAA,QACE,OAAO,KAAK,KAAK,QAAQ;AACzB,YAAA,KAAK,KAAK,IAAI;AACd,YAAA,OAAQ,KAAoC,CAAC,SAAS,KAAK,UAAU;IAEzE;wGA3EW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,cADJ,MAAM,EAAA,CAAA;;4FACnB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAD7B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACLlC;;;;;AAKG;MAoDU,mBAAmB,CAAA;AACrB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEf,IAAA,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAE3C,IAAA,SAAS,GAAG,MAAM,CAAC,KAAK,gFAAC;AACzB,IAAA,WAAW,GAAG,MAAM,CAAgB,IAAI,kFAAC;;IAG1C,aAAa,GAAmB,IAAI;IACpC,YAAY,GAAkB,IAAI;AAE1C,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;IAEA,UAAU,GAAA;QACR,MAAM,KAAK,GAAI,IAAI,CAAC,OAAO,EAAE,KAAwB,IAAI,IAAI;AAC7D,QAAA,IAAI,KAAK,KAAK,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC,YAAY;QAE1D,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC;AAChD,QAAA,IAAI,CAAC,aAAa,GAAG,KAAK;QAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC;QACrD,OAAO,IAAI,CAAC,YAAY;IAC1B;IAEA,MAAM,YAAY,CAAC,IAAsB,EAAA;AACvC,QAAA,IAAI,CAAC,IAAI;YAAE;AACX,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AAC1B,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACxB,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACzD,YAAA,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;QAC9B;AAAE,QAAA,MAAM;AACN,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,kCAAkC,CAAC;QAC1D;gBAAU;AACR,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QAC3B;IACF;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC3B,QAAA,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;IAC9B;IAEA,WAAW,GAAA;QACT,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC;IAClD;wGAnDW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA9CpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAEU,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAnD/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,OAAO,EAAE,EAAE;AACX,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;AC9DH;;;AAGG;MAkDU,kBAAkB,CAAA;AACpB,IAAA,KAAK;AACL,IAAA,OAAO;IACP,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAY,KAAK;AAEf,IAAA,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAE3C,IAAA,SAAS,GAAG,MAAM,CAAC,KAAK,gFAAC;AACzB,IAAA,WAAW,GAAG,MAAM,CAAgB,IAAI,kFAAC;AAElD,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,IAAY,KAAK,GAAA;AACf,QAAA,OAAQ,IAAI,CAAC,OAAO,EAAE,KAAwB,IAAI,IAAI;IACxD;IAEA,OAAO,GAAA;AACL,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI;IAChC;IAEA,QAAQ,GAAA;QACN,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI;IACxC;IAEA,MAAM,YAAY,CAAC,IAAsB,EAAA;AACvC,QAAA,IAAI,CAAC,IAAI;YAAE;AACX,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AAC1B,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACxB,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACzD,YAAA,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;QAC9B;AAAE,QAAA,MAAM;AACN,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,kCAAkC,CAAC;QAC1D;gBAAU;AACR,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QAC3B;IACF;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC3B,QAAA,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;IAC9B;wGA7CW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA5CnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAEU,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAjD9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;oBACT,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,OAAO,EAAE,EAAE;AACX,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CT,EAAA,CAAA;AACF,iBAAA;;sBAEE;;sBACA;;sBACA;;sBACA;;sBACA;;;ACvCH;;;;;;;;;;;;;;;;AAgBG;AAEH;SACgB,iBAAiB,GAAA;IAC/B,OAAO;AACL,QAAA,IAAI,EAAE,kBAAkB;AACxB,QAAA,QAAQ,EAAE,sBAAsB;AAChC,QAAA,QAAQ,EAAE,sBAAsB;AAChC,QAAA,MAAM,EAAE,oBAAoB;AAC5B,QAAA,QAAQ,EAAE,sBAAsB;AAChC,QAAA,KAAK,EAAE,mBAAmB;AAC1B,QAAA,QAAQ,EAAE,sBAAsB;AAChC,QAAA,QAAQ,EAAE,sBAAsB;AAChC,QAAA,OAAO,EAAE,qBAAqB;AAC9B,QAAA,IAAI,EAAE,kBAAkB;AACxB,QAAA,QAAQ,EAAE,sBAAsB;AAChC,QAAA,IAAI,EAAE,kBAAkB;AACxB,QAAA,SAAS,EAAE,uBAAuB;AAClC,QAAA,QAAQ,EAAE,sBAAsB;AAChC,QAAA,KAAK,EAAE,mBAAmB;AAC1B,QAAA,WAAW,EAAE,yBAAyB;AACtC,QAAA,YAAY,EAAE,uBAAuB;AACrC,QAAA,KAAK,EAAE,mBAAmB;AAC1B,QAAA,KAAK,EAAE,mBAAmB;AAC1B,QAAA,KAAK,EAAE,mBAAmB;AAC1B,QAAA,IAAI,EAAE,kBAAkB;KACzB;AACH;AAEA;AACM,SAAU,iBAAiB,CAAC,KAAgC,EAAA;AAChE,IAAA,OAAO,wBAAwB,CAAC;QAC9B,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;AAC3D,KAAA,CAAC;AACJ;AAEA;SACgB,wBAAwB,GAAA;AACtC,IAAA,OAAO,iBAAiB,CAAC,iBAAiB,EAAE,CAAC;AAC/C;;AC7EA;;;AAGG;MAEU,mBAAmB,CAAA;AACb,IAAA,QAAQ,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,GAAG,EAAE;AAElF,IAAA,GAAG,CAAC,GAAW,EAAA;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;IAC/B;IAEA,MAAM,GAAG,CAAC,GAAW,EAAE,IAAS,EAAE,UAAe,EAAE,EAAA;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;AACnC,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,IAAI;AACtB,QAAA,OAAO,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;IAC5B;wGAXW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,cADN,MAAM,EAAA,CAAA;;4FACnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAD/B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACHlC;;AAEG;MAEU,sBAAsB,CAAA;AACjC;;AAEG;AACH,IAAA,QAAQ,CACN,KAAoC,EACpC,MAA+B,EAC/B,cAAwC,EAAA;QAExC,OAAO,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC;IACzD;AAEA;;AAEG;AACH,IAAA,YAAY,CAAC,KAAoC,EAAE,KAAa,EAAE,MAAwB,EAAA;QACxF,OAAO,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC;IAChD;wGAjBW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,sBAAsB,cADT,MAAM,EAAA,CAAA;;4FACnB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBADlC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MCDrB,mBAAmB,CAAA;AACb,IAAA,KAAK,GAAG,IAAI,GAAG,EAA4B;AAC3C,IAAA,QAAQ,GAAG,IAAI,GAAG,EAAiD;AAEnE,IAAA,OAAO;AAExB,IAAA,WAAA,CAA+C,OAAa,EAAA;AAC1D,QAAA,IAAI,CAAC,OAAO,GAAG,OAAO;IACxB;;IAGA,MAAM,SAAS,CAAC,SAAiB,EAAA;AAC/B,QAAA,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,SAAS;AACjD,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;AAC/D,QAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;AAErE,QAAA,MAAM,OAAO,GAAG,CAAC,YAAW;AAC1B,YAAA,IAAI;gBACF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAQ,CAAC,SAAS,CAAC;AACpC,gBAAA,IAAI,QAAsC;AAE1C,gBAAA,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE;AACrB,oBAAA,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAU,CAAC;gBAC7C;qBAAO;oBACL,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAU,CAAC;gBAC9C;gBAEA,IAAI,QAAQ,EAAE;oBACZ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC;gBACrC;AACA,gBAAA,OAAO,QAAQ;YACjB;YAAE,OAAO,GAAG,EAAE;gBACZ,OAAO,CAAC,IAAI,CAAC,CAAA,sDAAA,EAAyD,SAAS,CAAA,CAAA,CAAG,EAAE,GAAG,CAAC;AACxF,gBAAA,OAAO,SAAS;YAClB;oBAAU;AACR,gBAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;YACjC;QACF,CAAC,GAAG;QAEJ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC;AACrC,QAAA,OAAO,OAAO;IAChB;;AAGA,IAAA,UAAU,CAAC,SAAkB,EAAA;QAC3B,IAAI,SAAS,EAAE;AACb,YAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;QAC9B;aAAO;AACL,YAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;QACpB;IACF;AAlDW,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,kBAME,aAAa,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AANlC,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,cADN,MAAM,EAAA,CAAA;;4FACnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAD/B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;0BAOnB;;0BAAY,MAAM;2BAAC,aAAa;;;ACiD/C;;;;;AAKG;MAqDU,oBAAoB,CAAA;;AAE/B;;;;;;;;;;AAUG;IACH,IACI,MAAM,CAAC,KAAuB,EAAA;AAChC,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK;AACtB,QAAA,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;IACpC;AACA,IAAA,IAAI,MAAM,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,SAAS;IAChD;AACQ,IAAA,SAAS;AACT,IAAA,gBAAgB;AACf,IAAA,KAAK;AACL,IAAA,WAAW;;AAEX,IAAA,YAAY;IACZ,SAAS,GAAa,EAAE;IACxB,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;;IAEzB,cAAc,GAAa,EAAE;AACtC;;;AAGG;IACM,eAAe,GAAY,IAAI;IAC/B,OAAO,GAAY,KAAK;IACxB,KAAK,GAAkB,IAAI;AACpC;;;;AAIG;IACM,gBAAgB,GAAW,CAAC;AACrC;;;AAGG;IACM,OAAO,GAAY,KAAK;;AAGvB,IAAA,UAAU,GAAG,IAAI,YAAY,EAAuB;AACpD,IAAA,UAAU,GAAG,IAAI,YAAY,EAAuB;AACpD,IAAA,SAAS,GAAG,IAAI,YAAY,EAAQ;;AAEpC,IAAA,eAAe,GAAG,IAAI,YAAY,EAAU;AACtD;;;AAGG;AACO,IAAA,YAAY,GAAG,IAAI,YAAY,EAAuC;;AAG/D,IAAA,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAC/B,IAAA,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;AACxB,IAAA,iBAAiB,GAAG,MAAM,CAAC,wBAAwB,CAAC;AACpD,IAAA,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC1C,IAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACjC,IAAA,eAAe,GAAG,MAAM,CAAC,sBAAsB,CAAC;AAChD,IAAA,kBAAkB,GAAG,MAAM,CAAC,yBAAyB,CAAC;IACtD,qBAAqB,GAAG,MAAM,CAAC,uBAAuB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC3E,IAAA,UAAU,GAAG,MAAM,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE;IAE9D,MAAM,GAAG,MAAM;;AAGzB,IAAA,SAAS,GAAG,MAAM,CAAS,EAAE,gFAAC;AAC9B,IAAA,YAAY,GAAG,MAAM,CAAS,EAAE,mFAAC;AACjC,IAAA,QAAQ,GAAG,MAAM,CAAC,KAAK,+EAAC;AACxB,IAAA,UAAU,GAAG,MAAM,CAAsB,EAAE,iFAAC;;AAE5C,IAAA,eAAe,GAAG,MAAM,CAAsB,EAAE,sFAAC;;AAEjD,IAAA,cAAc,GAAG,MAAM,CAAsB,IAAI,GAAG,EAAU,qFAAC;;AAGxC,IAAA,SAAS;;AAGI,IAAA,UAAU;;AAGvD,IAAA,IAAI;AAEI,IAAA,QAAQ;AACR,IAAA,SAAS;AACT,IAAA,YAAY;;IAEZ,cAAc,GAAwB,EAAE;;AAIhD,IAAA,mBAAmB,CAAC,KAAoB,EAAA;AACtC,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE;YACvE,KAAK,CAAC,cAAc,EAAE;AACtB,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;gBACxD,IAAI,CAAC,MAAM,EAAE;YACf;QACF;IACF;;IAGS,UAAU,GAAG,QAAQ,CAAC,MAC7B,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,YAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAC9E;AAED;;;;AAIG;AACM,IAAA,qBAAqB,GAAG,QAAQ,CAAsB,MAAK;AAClE,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE;AAChC,QAAA,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,EAAE;AAC9D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE;AAChC,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAC5B,CAAC,IAAI,CAAC,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CACtE;AACH,IAAA,CAAC,4FAAC;AAEF,IAAA,IAAI,IAAI,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE;IAChC;AAEA,IAAA,IAAI,WAAW,GAAA;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,UAAU;QAC3C,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACtF;AAEA,IAAA,IAAI,eAAe,GAAA;AACjB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE;AAC9B,QAAA,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI;QAC9C,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC;IAClC;AAEA,IAAA,IAAI,cAAc,GAAA;AAChB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe;QACnC,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,EAAE;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,UAAU;QAC3C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5F;AAEA,IAAA,IAAI,kBAAkB,GAAA;AACpB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc;QACnC,IAAI,CAAC,OAAO,CAAC,MAAM;AAAE,YAAA,OAAO,IAAI;AAChC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE;AACjC,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC;IACxD;AAEA,IAAA,IAAI,wBAAwB,GAAA;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,eAAe;QAC9D,IAAI,CAAC,MAAM,EAAE,UAAU,IAAI,CAAC,IAAI,CAAC,qBAAqB;AAAE,YAAA,OAAO,IAAI;AACnE,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAC3C,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,UAAU,CACrE;QACD,OAAO,KAAK,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI;IACvC;AAEA,IAAA,IAAI,kBAAkB,GAAA;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,eAAe;QAC9D,IAAI,MAAM,EAAE,UAAU;AAAE,YAAA,OAAO,EAAE;AACjC,QAAA,MAAM,SAAS,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC3G,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE;AACvC,QAAA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,IAAI,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC;QAEpE,OAAO,SAAS,CAAC,MAAM,CACrB,KAAK,IAAI,uBAAuB,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC,CAChG;IACH;AAEA;;;;;;;AAOG;AACH,IAAA,IAAI,WAAW,GAAA;QACb,QAAQ,IAAI,CAAC,gBAAgB,KAAK,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;IAChG;IAEQ,gBAAgB,GAAqD,IAAI;AAEjF;;;;;;;;AAQG;AACH,IAAA,IAAI,OAAO,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO;IACjC;AAEA;;;;;;AAMG;AACH,IAAA,IAAI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS;IACnC;AAEA,IAAA,IAAI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ;IACnE;AAEA;;;;;;;;AAQG;AACH,IAAA,IAAI,oBAAoB,GAAA;AACtB,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,gBAAgB;IAC3C;;AAGA,IAAA,IAAI,aAAa,GAAA;AACf,QAAA,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,GAAG,CAAC;IAC1D;AAEA;;;;;;AAMG;AACH,IAAA,IAAI,YAAY,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO;IAC1B;;AAGA,IAAA,IAAI,aAAa,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,aAAa;IACrE;IAEA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAI;YACvF,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC;AAC5C,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,WAAW,CAAC,OAAsB,EAAA;QAChC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,EAAE;AAC7C,YAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;QAC9B;QACA,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;;;;;;;;YAQvC,IAAI,CAAC,gBAAgB,GAAG,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7D;QACA,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC,EAAE;YAC/C,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE;AACpD,gBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C;QACF;IACF;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE;AAC5B,QAAA,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE;AAC7B,QAAA,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE;IAClC;AAEA;;;;;;;AAOG;IACH,YAAY,CAAC,KAAa,EAAE,OAAkC,EAAA;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,KAAK;AAC1C,QAAA,IAAI,OAAO;AAAE,YAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;AAC7C,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACzB,QAAA,IAAI,OAAO,IAAI,OAAO,EAAE,UAAU,KAAK,KAAK;YAAE,IAAI,CAAC,gBAAgB,EAAE;QACrE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC;AACxC,QAAA,IAAI,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;AAC5B,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C;aAAO;AACL,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B;IACF;IAEA,eAAe,CAAC,QAAgB,EAAE,OAAkC,EAAA;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,KAAK,QAAQ;AAChD,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC/B,QAAA,IAAI,OAAO,IAAI,OAAO,EAAE,UAAU,KAAK,KAAK;YAAE,IAAI,CAAC,gBAAgB,EAAE;IACvE;AAEA,IAAA,YAAY,CAAC,KAAwB,EAAA;AACnC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE;AAChC,QAAA,OAAO,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE;IAClD;;;AAKA,IAAA,aAAa,CAAC,KAAwB,EAAA;AACpC,QAAA,OAAO,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;IACtE;AAEA;;;AAGG;AACH,IAAA,eAAe,CAAC,KAAwB,EAAA;QACtC,QACE,IAAI,CAAC,QAAQ;;;;;AAKb,YAAA,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO;YACzB,CAAC,CAAC,KAAK,CAAC,QAAQ;YAChB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AACtC,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;IAE7B;AAEA,IAAA,eAAe,CAAC,KAAwB,EAAA;;;AAGtC,QAAA,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO;YAAE;QACxE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;AAC3C,QAAA,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;AAAE,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;;AACxC,YAAA,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;AACvB,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;IAC/B;AAEA,IAAA,iBAAiB,CAAC,KAAwB,EAAA;QACxC,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACjD;;IAIQ,SAAS,GAAA;QACf,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE;QAClB,MAAM,KAAK,GAAoC,EAAE;AAEjD,QAAA,MAAM,gBAAgB,GAAG,CAAC,IAAuB,EAAE,WAA4C,KAAI;AACjG,YAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACtB,gBAAA,IAAI,GAAG,CAAC,QAAQ,EAAE;oBAChB,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE;AACpC,wBAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,WAAW,CAAC;oBAC5C;oBACA,IAAI,GAAG,CAAC,QAAQ;AAAE,wBAAA,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC;gBAC/D;qBAAO;oBACL,MAAM,QAAQ,GAAoC,EAAE;oBACpD,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE;AACpC,wBAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC;oBACzC;oBACA,IAAI,GAAG,CAAC,QAAQ;AAAE,wBAAA,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;AAC1D,oBAAA,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;gBAC/C;YACF;AACF,QAAA,CAAC;QAED,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;QAChC,IAAI,CAAC,2BAA2B,EAAE;AAElC,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;AACpB,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtD;AAEA,QAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,EAAE;AACjD,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC;AACrC,QAAA,IAAI,CAAC,cAAc,GAAG,EAAE,GAAG,gBAAgB,EAAE;QAC7C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,GAAG,gBAAgB,EAAE,CAAC;QACjD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,GAAG,EAAU,CAAC;AAC1C,QAAA,IAAI,CAAC,oBAAoB,CAAC,gBAAgB,CAAC;AAE3C,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;;YAEhB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;AACpC,gBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;oBAAE;gBAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;AAC5C,gBAAA,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;AAAE,oBAAA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YACnF;YACA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACzC;;AAGA,QAAA,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE;AAC5B,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,GAAG;AACvC,cAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC;AACjE,cAAE,IAAI,CAAC,IAAI,CAAC,YAAY;;;;;AAK1B,QAAA,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE;QAC7B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAEjF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAK;AACtC,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,EAAE;AAC1C,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;AAC9B,YAAA,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;AAC9B,YAAA,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC;AACpC,YAAA,IAAI,CAAC,cAAc,GAAG,EAAE,GAAG,SAAS,EAAE;YACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;AAC5C,QAAA,CAAC,CAAC;IACJ;IAEQ,iBAAiB,CAAC,KAAwB,EAAE,KAAsC,EAAA;AACxF,QAAA,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;YAC1B,MAAM,QAAQ,GAAoC,EAAE;YACpD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,IAAI,EAAE,EAAE;AACxC,gBAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC;YACzC;AACA,YAAA,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC3C;AAAO,aAAA,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;AACjC,YAAA,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC;aAAO;AACL,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC;AAC7E,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,KAAK,CAAC,UAAU,CAAC;AACvF,YAAA,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC/B,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,EAAE,EACxE,UAAU,EACV,eAAe,CAChB;QACH;IACF;;AAGA;;;AAGG;IACH,eAAe,CAAC,OAAe,EAAE,KAAc,EAAA;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC;QAC5C,OAAO,IAAI,YAAY,SAAS,GAAG,IAAI,GAAG,IAAI;IAChD;AAEA;;;AAGG;IACH,cAAc,CAAC,KAAwB,EAAE,KAAe,EAAA;QACtD,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC;IACzC;IAEQ,aAAa,CAAC,KAAoC,EAAE,IAAa,EAAA;AACvE,QAAA,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM;YAAE,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;QAE1D,MAAM,QAAQ,GAAoC,EAAE;AACpD,QAAA,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,EAAE;AAClC,YAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC;QACzC;QACA,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;AACrC,QAAA,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;AAAE,YAAA,KAAK,CAAC,UAAU,CAAC,IAA+B,CAAC;AACvF,QAAA,OAAO,KAAK;IACd;AAEA;;;;;AAKG;IACK,cAAc,GAAA;AACpB,QAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;AAC5B,QAAA,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;IAClD;AAEA;;;;;;;;;AASG;AACK,IAAA,aAAa,CAAC,IAAyB,EAAA;QAC7C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,IAAI;AAExD,QAAA,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;QAChE,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,SAAS,EAAE,EAAE;YACxC,OAAO,CAAC,IAAI,CACV,CAAA,iCAAA,EAAoC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAA,6BAAA,CAA+B;AACnF,gBAAA,CAAA,EAAG,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,EAAE,CAAA,SAAA,EAAY,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,EAAA,CAAI,CAC1E;QACH;QACA,OAAO,MAAM,CAAC,MAAM;IACtB;AAEQ,IAAA,SAAS,CAAC,IAAyB,EAAA;AACzC,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE;QACzB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AAChE,QAAA,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU;AAEzC,QAAA,MAAM,QAAQ,GAAG,CAAC,IAAuB,KAAI;AAC3C,YAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACtB,gBAAA,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;gBACrD,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE;oBACpC,IAAI,GAAG,GAAG,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,SAAS;AAChF,oBAAA,IAAI,KAAK,CAAC,YAAY,EAAE;wBACtB,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC;wBACvD,IAAI,MAAM,KAAK,SAAS;4BAAE,GAAG,GAAG,MAAM;oBACxC;oBACA,IAAI,GAAG,KAAK,SAAS;wBAAE;AAEvB,oBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;AAC9C,oBAAA,IAAI,CAAC,IAAI;wBAAE;oBAEX,IAAI,IAAI,YAAY,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;wBACnD,IAAI,CAAC,KAAK,EAAE;AACZ,wBAAA,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE;AACtB,4BAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;wBAC/D;oBACF;yBAAO;wBACL,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;oBAC5C;AACA,oBAAA,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/B;gBACA,IAAI,GAAG,CAAC,QAAQ;AAAE,oBAAA,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC1C;AACF,QAAA,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,yBAAyB,CAAC,IAAI,EAAE,UAAU,EAAE,eAAe,CAAC;IACnE;AAEA;;;;;;;;;AASG;AACK,IAAA,yBAAyB,CAC/B,IAAyB,EACzB,UAA0C,EAC1C,eAA4B,EAAA;AAE5B,QAAA,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE;AAElC,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU;AAChC,QAAA,MAAM,aAAa,GAAG,CAAC,IAAuB,KAAI;AAChD,YAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACtB,gBAAA,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClB,IAAI,GAAG,CAAC,QAAQ;AAAE,oBAAA,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC/C;AACF,QAAA,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QAErC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CACzC,GAAG,IACD,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;AAChB,YAAA,IAAI,CAAC,GAAG,CAAC,KAAK,SAAS;AACvB,YAAA,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;AACnB,YAAA,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC;YACzB,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CACtC;QACD,IAAI,CAAC,UAAU,CAAC,MAAM;YAAE;QAExB,KAAK,MAAM,GAAG,IAAI,UAAU;AAAE,YAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC;AAEhE,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC/C,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,UAAU,CAAC,MAAM,GAAG,CAAC,QAAQ,GAAG,EAAE;AAC7E,QAAA,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,KAAK,CAAC;AACtC,QAAA,OAAO,CAAC,IAAI,CACV,CAAA,+CAAA,EAAkD,MAAM,GAAG,KAAK,GAAG,MAAM,CAAA,UAAA,CAAY;AACnF,YAAA,CAAA,EAAG,MAAM,GAAG,kBAAkB,GAAG,kBAAkB,CAAA,gBAAA,EAAmB,KAAK,CAAA,EAAG,IAAI,CAAA,EAAA,CAAI;YACtF,CAAA,iFAAA,CAAmF;YACnF,CAAA,iFAAA,CAAmF;YACnF,CAAA,gBAAA,EAAmB,MAAM,GAAG,YAAY,GAAG,cAAc,CAAA,CAAA,CAAG,CAC/D;IACH;;AAGiB,IAAA,oBAAoB,GAAG,IAAI,GAAG,EAAU;;IAGzD,aAAa,GAAA;QACX,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;QACzC,IAAI,MAAM,GAAwB,EAAE;AAEpC,QAAA,MAAM,QAAQ,GAAG,CAAC,IAAuB,KAAI;AAC3C,YAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;gBACtB,MAAM,WAAW,GAA4B,EAAE;gBAC/C,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE;AACpC,oBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;oBAC9C,IAAI,IAAI,EAAE;wBACR,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK;oBACpC;gBACF;AAEA,gBAAA,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC;gBAEpD,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE;AACpC,oBAAA,IAAI,KAAK,CAAC,YAAY,EAAE;AACtB,wBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;wBAC9C,IAAI,IAAI,EAAE;4BACR,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC;wBACxD;oBACF;gBACF;gBAEA,IAAI,GAAG,CAAC,QAAQ;AAAE,oBAAA,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC1C;AACF,QAAA,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QAChC,MAAM,GAAG,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;AACtD,QAAA,OAAO,MAAM;IACf;AAEA;;;;;;;;;;AAUG;IACK,2BAA2B,GAAA;AACjC,QAAA,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE;QAEzD,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;AAChD,QAAA,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC;YAAE;AAE1B,QAAA,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU;AACpC,QAAA,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;YAC7B,IAAI,IAAI,CAAC,OAAO;AAAE,gBAAA,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAC9C,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE;gBAC7C,IAAI,SAAS,CAAC,cAAc;AAAE,oBAAA,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC;YACxE;YACA,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE;gBACvC,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,EAAE;AAAE,oBAAA,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACrE;QACF;AAEA,QAAA,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE;AAC5B,YAAA,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC;AACjC,YAAA,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK;gBAAE;AAC3B,YAAA,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK;YACvB,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,IAAI,oBAAoB,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE;AAChE,YAAA,oBAAoB,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;AAC/C,YAAA,OAAO,CAAC,IAAI,CACV,CAAA,8CAAA,EAAiD,EAAE,CAAA,uBAAA,EAA0B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA,EAAA,CAAI;gBACnG,CAAA,+FAAA,CAAiG;gBACjG,CAAA,6BAAA,EAAgC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA,EAAA,CAAI,CACtD;QACH;IACF;AAEQ,IAAA,OAAgB,kBAAkB,GAAG,IAAI,GAAG,EAAU;AAE9D;;;;;;;;;;;AAWG;AACH;;;;;;AAMG;IACK,UAAU,CAAC,KAA0B,EAAE,KAAwB,EAAA;AACrE,QAAA,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;AAAE,YAAA,OAAO,IAAI;AACpC,QAAA,MAAM,GAAG,GAAG,KAAK,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;AACrD,QAAA,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK;IACjD;;AAGQ,IAAA,OAAO,CAAC,KAAwB,EAAA;QACtC,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC;AAC1E,QAAA,OAAO,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI;IAC1D;IAEQ,iBAAiB,GAAA;QACvB,MAAM,GAAG,GAAwB,EAAE;QACnC,KAAK,MAAM,KAAK,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;AACnD,YAAA,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK;YACzB,IAAI,CAAC,KAAK,EAAE,EAAE;gBAAE;YAChB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;AACpE,YAAA,IAAI,CAAC,IAAI;gBAAE;YACX,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK;AAC1B,YAAA,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK;QACzD;AACA,QAAA,OAAO,GAAG;IACZ;AAEQ,IAAA,WAAW,CAAC,KAAa,EAAA;AAC/B,QAAA,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC;AACjD,QAAA,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI;AAChD,QAAA,IAAI,IAAI,GAA2B,IAAI,CAAC,IAAI;AAC5C,QAAA,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;YACpB,IAAI,CAAC,IAAI,IAAI,EAAE,IAAI,YAAY,SAAS,CAAC;AAAE,gBAAA,OAAO,IAAI;AACtD,YAAA,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACpB;QACA,OAAO,IAAI,YAAY,SAAS,GAAG,IAAI,GAAG,IAAI;IAChD;;AAIA;;;AAGG;IACK,YAAY,CAAC,OAAe,EAAE,MAA2C,EAAA;AAC/E,QAAA,IAAI,CAAC,MAAM;YAAE;AACb,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC;AAC1D,QAAA,MAAM,SAAS,GAAG,KAAK,EAAE,SAAS;AAClC,QAAA,IAAI,CAAC,SAAS;YAAE;QAEhB,MAAM,KAAK,GAAG,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC;AAC/C,QAAA,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC;AAC9D,YAAA,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC;QAC5B;;;;AAIA,QAAA,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;IAClD;AAEA;;;AAGG;AACK,IAAA,cAAc,CAAC,MAA2B,EAAA;QAChD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;AACpC,YAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW;YAClC,IAAI,CAAC,QAAQ,EAAE,MAAM;gBAAE;AAEvB,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI;YACtD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI;YACxC,IAAI,CAAC,MAAM,IAAI,OAAO;gBAAE;YAExB,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC;AAChD,YAAA,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACrD,gBAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YACpE;QACF;IACF;;IAGQ,oBAAoB,CAAC,SAA0B,EAAE,QAAgB,EAAA;AACvE,QAAA,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC;QACnD,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC;QACpE,IAAI,GAAG,IAAI,CAAC,WAAW;AAAE,YAAA,OAAO,IAAI;QACpC,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,SAAS,CAAC;IACvD;;AAIA;;;;AAIG;IACK,SAAS,GAAA;QACf,MAAM,GAAG,GAAwB,EAAE;AACnC,QAAA,MAAM,IAAI,GAAG,CAAC,IAAmC,KAAI;AACnD,YAAA,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE;AAC5B,gBAAA,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC/B,gBAAA,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YACpB;AACF,QAAA,CAAC;AACD,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AACvB,QAAA,OAAO,GAAG;IACZ;AAEA;;;;;;;;;;;;;;;;AAgBG;AACK,IAAA,oBAAoB,CAAC,MAA2B,EAAA;QACtD,IAAI,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO;AAEzB,QAAA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,IAAI,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC;QAEpE,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;AACtC,YAAA,IAAI,CAAC,IAAI;gBAAE;AAEX,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,MAAM,CAAC;YAE9F,IAAI,MAAM,EAAE;gBACV,IAAI,IAAI,CAAC,OAAO;oBAAE,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YACtD;iBAAO,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;gBAC3C,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YACnC;QACF;IACF;;IAGQ,SAAS,GAAA;QACf,MAAM,GAAG,GAAwB,EAAE;AACnC,QAAA,MAAM,UAAU,GAAG,CAAC,MAAuC,KAAI;AAC7D,YAAA,KAAK,MAAM,CAAC,IAAI,MAAM,IAAI,EAAE,EAAE;AAC5B,gBAAA,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACX,gBAAA,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM;AAAE,oBAAA,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;YAChD;AACF,QAAA,CAAC;AACD,QAAA,MAAM,QAAQ,GAAG,CAAC,IAAmC,KAAI;AACvD,YAAA,KAAK,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE;AAC1B,gBAAA,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;AACpB,gBAAA,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;YACtB;AACF,QAAA,CAAC;AACD,QAAA,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC3B,QAAA,OAAO,GAAG;IACZ;;IAGQ,QAAQ,GAAA;AACd,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY;QAClC,IAAI,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC;AAAE,YAAA,OAAO,QAAQ;AACjE,QAAA,OAAO,IAAI,CAAC,eAAe,EAAE;IAC/B;IAEQ,SAAS,CAAC,CAAU,EAAE,CAAU,EAAA;QACtC,IAAI,CAAC,KAAK,CAAC;AAAE,YAAA,OAAO,IAAI;AACxB,QAAA,MAAM,MAAM,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE;AACxD,QAAA,MAAM,MAAM,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE;QACxD,IAAI,MAAM,IAAI,MAAM;AAAE,YAAA,OAAO,IAAI;QACjC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;AAClD,YAAA,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC;QAChE;AACA,QAAA,OAAO,KAAK;IACd;IAEA,UAAU,CAAC,OAAe,EAAE,YAAqB,EAAA;QAC/C,IAAI,CAAC,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,IAAI;;;;;AAM3B,QAAA,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC;AACrC,QAAA,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QAE7D,IAAI,YAAY,EAAE;YAChB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC;YAC7C,MAAM,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC;AACjC,YAAA,IAAI,IAAI;AAAE,gBAAA,OAAO,IAAI;QACvB;QAEA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;AACvC,QAAA,IAAI,QAAQ;AAAE,YAAA,OAAO,QAAQ;AAE7B,QAAA,MAAM,WAAW,GAAG,CAAC,KAAgB,KAA4B;AAC/D,YAAA,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE;gBAC7C,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAC7B,IAAI,GAAG,KAAK,OAAO;AAAE,oBAAA,OAAO,CAAC;AAC7B,gBAAA,IAAI,CAAC,YAAY,SAAS,EAAE;AAC1B,oBAAA,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC;AAC5B,oBAAA,IAAI,KAAK;AAAE,wBAAA,OAAO,KAAK;gBACzB;YACF;AACA,YAAA,OAAO,IAAI;AACb,QAAA,CAAC;AAED,QAAA,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;IAC/B;AAEA;;;;;;;AAOG;IACK,gBAAgB,GAAA;QACtB,IAAI,OAAO,qBAAqB,KAAK,UAAU;YAAE;AACjD,QAAA,qBAAqB,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IACvE;;AAGA,IAAA,IAAI,cAAc,GAAA;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,eAAe;AAC3D,QAAA,OAAO,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE;IAC7C;AAEA;;;;;;AAMG;AACH,IAAA,SAAS,CAAC,KAAwB,EAAA;AAChC,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC;AACnB,cAAE,CAAA,CAAA,EAAI,KAAK,CAAC,mBAAmB,CAAA,CAAA;cAC7B,mBAAmB;QACvB,OAAO,CAAA,wBAAA,EAA2B,MAAM,CAAA,0DAAA,CAA4D;IACtG;AAEA,IAAA,eAAe,CAAC,GAAoB,EAAA;QAClC,OAAO,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC/C;AAEA,IAAA,MAAM,MAAM,GAAA;QACV,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,EAAE;YACzC,IAAI,CAAC,cAAc,EAAE;YACrB;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE;QACpC,IAAI,aAAa,GAAG,OAAO;AAE3B,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;AACvB,QAAA,IAAI;;;;YAIF,MAAM,OAAO,GAAG,CAAA,EAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAA,WAAA,CAAa;YACnD,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;AAClC,gBAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC;AAClE,gBAAA,IAAI,MAAM,KAAK,KAAK,EAAE;oBACpB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;oBAC/D;gBACF;;AAEA,gBAAA,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI;oBAAE,aAAa,GAAG,MAAM;YACrE;AAEA,YAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC;QACrC;QAAE,OAAO,GAAG,EAAE;;;AAGZ,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,KAAK,GAAG,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAClG;gBAAU;AACR,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;QAC1B;IACF;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;QACjB,IAAI,IAAI,CAAC,WAAW;AAAE,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC;AACtD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE;AACvC,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;AAC3B,QAAA,IAAI,CAAC,cAAc,GAAG,EAAE,GAAG,MAAM,EAAE;QACnC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,GAAG,EAAU,CAAC;AAC1C,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;IACvB;wGAv+BW,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,OAAA,EAAA,WAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,SAAA,EAAA,WAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,SAAA,EAAA,KAAA,EAAA,OAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,SAAA,EAAA,WAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,gBAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,SAAA,EA9CpB,CAAC,yBAAyB,CAAC,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,WAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,WAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,YAAA,EAAA,SAAA,EAwIxB,qBAAqB,EAAA,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECjNrC,6zOAyLA,EAAA,MAAA,EAAA,CAAA,ylBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDlHY,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,sGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,qBAAqB,2JAAE,iBAAiB,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,mBAAA,EAAA,yBAAA,EAAA,2BAAA,EAAA,sCAAA,EAAA,0BAAA,EAAA,2BAAA,CAAA,EAAA,QAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAgD5D,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBApDhC,SAAS;AACS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC,kBAAkB,EAAA,UAAA,EAChB,IAAI,EAAA,OAAA,EACP,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,iBAAiB,CAAC,EAAA,SAAA,EAE7D,CAAC,yBAAyB,CAAC,EAAA,QAAA,EAAA,6zOAAA,EAAA,MAAA,EAAA,CAAA,ylBAAA,CAAA,EAAA;;sBA2DrC;;sBAUA;;sBACA;;sBAEA;;sBACA;;sBACA;;sBACA;;sBAEA;;sBAKA;;sBACA;;sBACA;;sBAMA;;sBAKA;;sBAGA;;sBACA;;sBACA;;sBAEA;;sBAKA;;sBA0BA,SAAS;uBAAC,WAAW;;sBAGrB,YAAY;uBAAC,qBAAqB;;sBAYlC,YAAY;uBAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC;;;AEnN5C;;;AAGG;AACH,MAAM,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAEjD;;;;AAIG;MAqMU,0BAA0B,CAAA;AAC5B,IAAA,MAAM;AACN,IAAA,KAAK;AACL,IAAA,WAAW;IACX,SAAS,GAAa,EAAE;IACxB,QAAQ,GAAW,IAAI;IACvB,QAAQ,GAAY,KAAK;IACzB,OAAO,GAAY,KAAK;IACxB,KAAK,GAAkB,IAAI;;IAE3B,UAAU,GAAY,KAAK;;IAE3B,cAAc,GAAa,EAAE;AACtC;;;;;;AAMG;IACM,QAAQ,GAAY,IAAI;AAEvB,IAAA,UAAU,GAAG,IAAI,YAAY,EAAuB;AACpD,IAAA,UAAU,GAAG,IAAI,YAAY,EAAuB;AACpD,IAAA,SAAS,GAAG,IAAI,YAAY,EAAQ;;AAEpC,IAAA,WAAW,GAAG,IAAI,YAAY,EAAkD;AAEzD,IAAA,eAAe;AAE/B,IAAA,eAAe,GAAG,MAAM,CAAC,sBAAsB,CAAC;AAChD,IAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACjC,IAAA,IAAI,GAA4B,MAAM,CAAC,UAAU,CAAC;AAClD,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AAEnC,IAAA,WAAW,GAAG,MAAM,CAAsB,EAAE,kFAAC;AAC7C,IAAA,gBAAgB,GAAG,MAAM,CAAsB,EAAE,uFAAC;AAE3D;;;;;;AAMG;AACc,IAAA,SAAS,GAAG,MAAM,CAAsB,IAAI,GAAG,EAAU,gFAAC;AAE3E;;;;;;AAMG;AACH,IAAA,IAAI,WAAW,GAAA;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,EAAE;AACjD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE;QAC7B,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE;AAC5C,aAAA,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;aACxC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzE;AAEA,IAAA,iBAAiB,CAAC,OAAe,EAAA;AAC/B,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5D;AAEA;;;;;;;AAOG;IACK,gBAAgB,GAAqD,IAAI;AAEjF,IAAA,IAAI,WAAW,GAAA;QACb,QAAQ,IAAI,CAAC,gBAAgB,KAAK,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;IAChG;;AAGA,IAAA,IAAI,cAAc,GAAA;AAChB,QAAA,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO;IACtE;;AAIA;;;;;;AAMG;AACM,IAAA,cAAc,GAAG,MAAM,CAA2B,IAAI,qFAAC;AACvD,IAAA,cAAc,GAAG,MAAM,CAAgB,IAAI,qFAAC;IACrD,aAAa,GAAqB,IAAI;;AAGtC,IAAA,IAAI,uBAAuB,GAAA;AACzB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW;QAC9B,MAAM,GAAG,GAAG,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,IAAI;QAC5D,OAAO,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC;IAC5D;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,CAAC,KAAwB,EAAA;AAC7B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW;QAC9B,MAAM,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI;QACjF,MAAM,IAAI,GAAI,OAA0C,GAAG,KAAK,CAAC,EAAE,CAAC;AACpE,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAI,IAAkC,GAAG,EAAE;IACvE;;IAGA,UAAU,CAAC,KAAwB,EAAE,GAA4B,EAAA;AAC/D,QAAA,MAAM,KAAK,GAAG,GAAG,IAAI,EAAE;QACvB,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE;aAChC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;AAC5B,aAAA,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE;AACrD,aAAA,GAAG,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS;IACrD;AAEA,IAAA,UAAU,CAAC,KAAwB,EAAA;QACjC,IAAI,IAAI,CAAC,eAAe;YAAE;AAC1B,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC;AAC9B,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,KAAK,CAAc;IAC/E;IAEA,WAAW,CAAC,KAAwB,EAAE,KAAa,EAAA;QACjD,IAAI,IAAI,CAAC,eAAe;YAAE;AAC1B,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC;AAC9B,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC;QAC9B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAc;IAC1G;IAEA,SAAS,GAAA;AACP,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;AAC7B,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;AAC7B,QAAA,IAAI,CAAC,aAAa,GAAG,IAAI;IAC3B;;IAGA,OAAO,GAAA;AACL,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE;AACnC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe;QACjC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE;AAE5C,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE;AAC9B,YAAA,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;YACrC;QACF;AAEA,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC;AAC3E,QAAA,IAAI,CAAC,KAAK;YAAE;AAEZ,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE;QACnC,IAAI,KAAK,KAAK,IAAI;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;;AAC/E,YAAA,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAEzD,KAAK,CAAC,sBAAsB,EAAE;QAC9B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1C,IAAI,CAAC,SAAS,EAAE;IAClB;IAEA,SAAS,CAAC,KAAwB,EAAE,KAAa,EAAA;QAC/C,IAAI,IAAI,CAAC,eAAe;YAAE;AAC1B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC;AAC5F,QAAA,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;QACtB,KAAK,EAAE,sBAAsB,EAAE;QAC/B,IAAI,IAAI,CAAC,eAAe;AAAE,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC;AACpF,QAAA,IAAI,IAAI,CAAC,cAAc,EAAE,KAAK,KAAK;YAAE,IAAI,CAAC,SAAS,EAAE;IACvD;;AAIA;;;;;;AAMG;AACM,IAAA,YAAY,GAAG,MAAM,CAAgB,IAAI,mFAAC;AAEnD;;;;;;;AAOG;AACc,IAAA,cAAc,GAAG,MAAM,CAAgB,IAAI,qFAAC;AAE7D,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,IAAI,CAAC,cAAc,EAAE;IAC9B;AAEA,IAAA,iBAAiB,CAAC,KAAa,EAAA;AAC7B,QAAA,IAAI,IAAI,CAAC,cAAc,EAAE,KAAK,KAAK;YAAE;AACrC,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC;;AAE9B,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,SAAS,EAAE;IAClB;;IAGQ,iBAAiB,GAAA;QACvB,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,KAAK,KAAK,CAAC,EAAE,EAAE,IAAI,IAAI;IACzE;;AAGS,IAAA,aAAa,GAAG,MAAM,CAAyB,EAAE,oFAAC;;IAGxC,MAAM,GAAG,MAAM;AAElC,IAAA,IAAI,kBAAkB,GAAA;;QAEpB,IAAI,CAAC,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,IAAI;AAC/B,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE,KAAK,IAAI,CAAC,WAAW;IACvE;;AAGA,IAAA,IAAI,eAAe,GAAA;QACjB,OAAO,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,kBAAkB;IACxD;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE;AAChE,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;IACzC;;IAGA,aAAa,GAAA;AACX,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE;AACjC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe;AACjC,QAAA,IAAI,KAAK,IAAI,IAAI,EAAE;AACjB,YAAA,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC;AAC7C,YAAA,MAAM,WAAW,IAAI,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAA4B;YAC9G,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE;gBACrC,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;;;AAI3C,gBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC;gBACnD,IAAI,KAAK,EAAE;oBACT,KAAK,CAAC,KAAK,EAAE;AACb,oBAAA,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,GAAG,EAAE,EAAE;AACnE,wBAAA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;oBAC7C;oBACA,KAAK,CAAC,sBAAsB,EAAE;oBAC9B;gBACF;AAEA,gBAAA,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,aAAa,IAAI,IAAI,CAAC;YACnE;YACA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC5C;AACA,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1B,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;IAC7B;AAEA;;;;AAIG;IACH,WAAW,GAAA;AACT,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE;AACjC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe;AACjC,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;YAAE;AAErB,QAAA,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC;QAC7C,MAAM,MAAM,GAA2B,EAAE;QAEzC,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE;AACrC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC;AAC7C,YAAA,IAAI,IAAI,EAAE,OAAO,EAAE;gBACjB,IAAI,CAAC,aAAa,EAAE;AACpB,gBAAA,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc;YAC9E;QACF;AAEA,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;AAChF,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,gBAAgB,EAAE;AAChG,aAAA,gBAAgB;AACnB,QAAA,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;QAEjC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;AAClC,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;YAC9B;QACF;AAEA,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1B,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;AAE3B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE;AACnC,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC1C;AAEA;;;;AAIG;AACH,IAAA,WAAW,CAAC,OAAsB,EAAA;;;QAGhC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,EAAE;AAC7C,YAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;QAC9B;QACA,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE;AAC/C,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC;AAC1D,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC;YACrD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;;YAEjD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,EAAU,CAAC;QACvC;IACF;AAEA,IAAA,IAAI,WAAW,GAAA;QACb,IAAI,CAAC,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,QAAQ;AACjC,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM;IAC9F;AAEA,IAAA,IAAI,YAAY,GAAA;AACd,QAAA,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;IAC1D;;;IAKQ,SAAS,GAAA;QACf,MAAM,GAAG,GAAwB,EAAE;AACnC,QAAA,MAAM,UAAU,GAAG,CAAC,MAAuC,KAAI;AAC7D,YAAA,KAAK,MAAM,CAAC,IAAI,MAAM,IAAI,EAAE,EAAE;AAC5B,gBAAA,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACX,gBAAA,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;YACxB;AACF,QAAA,CAAC;AACD,QAAA,MAAM,QAAQ,GAAG,CAAC,IAAmC,KAAI;AACvD,YAAA,KAAK,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE;AAC1B,gBAAA,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;AACpB,gBAAA,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;YACtB;AACF,QAAA,CAAC;AACD,QAAA,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC3B,QAAA,OAAO,GAAG;IACZ;;AAGA,IAAA,IAAI,kBAAkB,GAAA;AACpB,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,IAAI;IAC7D;;AAGA,IAAA,IAAI,iBAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,IAAI;IAC7D;;AAGA,IAAA,IAAI,eAAe,GAAA;AACjB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB;AACrC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,IAAI;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAA4B;AAClE,QAAA,OAAO,KAAK,EAAE,GAAG,IAAI,IAAI;IAC3B;AAEA,IAAA,IAAI,iBAAiB,GAAA;AACnB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB;AACpC,QAAA,OAAO,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,KAAK;IAC3D;AAEA;;;;AAIG;IACH,kBAAkB,GAAA;AAChB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB;AACpC,QAAA,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,cAAc;YAAE;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;AACtC,QAAA,IAAI,CAAC,IAAI;YAAE;QACX,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC;QACtC,IAAI,IAAI,CAAC,eAAe;AAAE,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC;IACtF;;AAGQ,IAAA,UAAU,CAAC,OAAe,EAAA;QAChC,OAAO,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,OAAO,CAAC,IAAI,IAAI;IAC1D;AAEA;;;;;;;;;;;AAWG;AACK,IAAA,UAAU,CAAC,OAAe,EAAA;AAChC,QAAA,MAAM,KAAK,GAAG,CAAC,IAAA,GAA0B,EAAE,KAAa;AACtD,YAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACtB,gBAAA,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,MAAM,CAAmC;AAClG,gBAAA,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI;AAAE,oBAAA,OAAO,IAAI,CAAC,OAAO,CAAC;AACjD,gBAAA,IAAI,GAAG,CAAC,QAAQ,EAAE;oBAChB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;oBACjC,IAAI,KAAK,KAAK,eAAe;AAAE,wBAAA,OAAO,KAAK;gBAC7C;YACF;AACA,YAAA,OAAO,eAAe;AACxB,QAAA,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;QACvC,OAAO,MAAM,KAAK,eAAe,GAAG,SAAS,GAAG,MAAM;IACxD;AAES,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAK;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACpC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;AAC/B,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,KAAK;AAClE,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AACtD,IAAA,CAAC,iFAAC;AAEO,IAAA,aAAa,GAAG,QAAQ,CAAsB,MAAK;QAC1D,MAAM,MAAM,GAAwB,EAAE;AACtC,QAAA,MAAM,QAAQ,GAAG,CAAC,IAAA,GAA0B,EAAE,KAAI;AAChD,YAAA,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;gBACpB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE;oBAC9B,IAAI,CAAC,CAAC,cAAc;AAAE,wBAAA,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBACtC;gBACA,IAAI,CAAC,CAAC,QAAQ;AAAE,oBAAA,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;YACtC;AACF,QAAA,CAAC;AACD,QAAA,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC3B,QAAA,OAAO,MAAM;AACf,IAAA,CAAC,oFAAC;AAEF,IAAA,YAAY,CAAC,IAAyB,EAAA;;;AAGpC,QAAA,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;YACrD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;QACxC;AACA,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AAC1B,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5B;AAEA,IAAA,YAAY,CAAC,IAAyB,EAAA;AACpC,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5B;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;IACvB;AAEA,IAAA,gBAAgB,CAAC,KAAwB,EAAA;QACvC,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC;IACjD;;AAGA,IAAA,gBAAgB,CAAC,KAAwB,EAAA;QACvC,OAAO,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC;IAChG;AAEA;;;;AAIG;AACK,IAAA,WAAW,CAAC,OAAe,EAAA;QACjC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE;AACzC,YAAA,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC;AAAE,gBAAA,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE;YAC5E,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE;gBACtC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE;AACpD,oBAAA,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE;gBAC9C;YACF;QACF;AACA,QAAA,OAAO,IAAI;IACb;AAEA;;;;;;;;;;AAUG;AACH,IAAA,WAAW,CAAC,OAAe,EAAA;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;AAC1C,QAAA,IAAI,CAAC,QAAQ;YAAE;;AAGf,QAAA,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;;;;AAIzE,QAAA,IAAI,QAAQ,CAAC,QAAQ,EAAE;AACrB,YAAA,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QACjF;QAEA,eAAe,CACb,MAAK;;;;AAIH,YAAA,MAAM,MAAM,GAAG,CAAA,gBAAA,EAAmB,OAAO,EAAE;AAC3C,YAAA,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CACnB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAc,0BAA0B,CAAC,CAClF,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC;AAClC,YAAA,IAAI,CAAC,EAAE;gBAAE;AACT,YAAA,EAAE,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;;;YAG1D,EAAE,CAAC,KAAK,EAAE;QACZ,CAAC,EACD,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAC5B;IACH;wGA1hBW,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAA1B,0BAA0B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,OAAA,EAAA,WAAA,EAAA,aAAA,EAAA,SAAA,EAAA,WAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,OAAA,EAAA,SAAA,EAAA,KAAA,EAAA,OAAA,EAAA,UAAA,EAAA,YAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,SAAA,EAAA,WAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EA4B1B,oBAAoB,EAAA,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECrPjC,uhPAkMA,EAAA,MAAA,EAAA,CAAA,mhGAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDzKY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,sGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,oBAAoB,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,OAAA,EAAA,aAAA,EAAA,cAAA,EAAA,WAAA,EAAA,UAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,OAAA,EAAA,kBAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,YAAA,EAAA,YAAA,EAAA,WAAA,EAAA,iBAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,qBAAqB,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,cAAA,EAAA,UAAA,EAAA,UAAA,EAAA,WAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAgM7E,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBApMtC,SAAS;AACS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC,yBAAyB,cACvB,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,qBAAqB,CAAC,EAAA,QAAA,EAAA,uhPAAA,EAAA,MAAA,EAAA,CAAA,mhGAAA,CAAA,EAAA;;sBAiMxF;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;sBAEA;;sBAEA;;sBAQA;;sBAEA;;sBACA;;sBACA;;sBAEA;;sBAEA,SAAS;uBAAC,oBAAoB;;;AErPjC;;ACAA;;AAEG;;;;"}
1
+ {"version":3,"file":"ngx-dynamic-entity.mjs","sources":["../../src/lib/services/entity-ref-cache.ts","../../src/lib/tokens/injection-tokens.ts","../../src/lib/providers/provide-ngx-dynamic-entity.ts","../../src/lib/services/validation-messages.service.ts","../../src/lib/field-types/text-field.component.ts","../../src/lib/field-types/textarea-field.component.ts","../../src/lib/field-types/markdown-field.component.ts","../../src/lib/field-types/number-field.component.ts","../../src/lib/field-types/currency-field.component.ts","../../src/lib/field-types/email-field.component.ts","../../src/lib/field-types/password-field.component.ts","../../src/lib/field-types/checkbox-field.component.ts","../../src/lib/field-types/boolean-field.component.ts","../../src/lib/field-types/date-field.component.ts","../../src/lib/field-types/date-time-field.component.ts","../../src/lib/field-types/time-field.component.ts","../../src/lib/field-types/month-year-field.component.ts","../../src/lib/services/lookup-registry.service.ts","../../src/lib/field-types/dropdown-field.component.ts","../../src/lib/field-types/radio-field.component.ts","../../src/lib/field-types/multi-select-field.component.ts","../../src/lib/services/entity-ref-registry.service.ts","../../src/lib/services/entity-reference.service.ts","../../src/lib/services/cascade-data.service.ts","../../src/lib/services/entity-ref-selection.service.ts","../../src/lib/field-types/entity-ref-field.component.ts","../../src/lib/services/field-registry.service.ts","../../src/lib/services/rbac.service.ts","../../src/lib/form/dynamic-field/dynamic-field.component.ts","../../src/lib/field-types/group-field.component.ts","../../src/lib/services/validator-registry.service.ts","../../src/lib/field-types/array-field.component.ts","../../src/lib/services/file-upload.service.ts","../../src/lib/field-types/image-field.component.ts","../../src/lib/field-types/file-field.component.ts","../../src/lib/providers/provide-field-types.ts","../../src/lib/services/hook-registry.service.ts","../../src/lib/services/rules-evaluation.service.ts","../../src/lib/services/config-source.service.ts","../../src/lib/form/dynamic-form.component.ts","../../src/lib/form/dynamic-form.component.html","../../src/lib/form/dynamic-record-form.component.ts","../../src/lib/form/dynamic-record-form.component.html","../../src/public-api.ts","../../src/ngx-dynamic-entity.ts"],"sourcesContent":["import type { ReferenceOption } from '@dynamic-entity/core';\n\n/**\n * Backing store for cached reference options.\n *\n * Pluggable on purpose. The reference implementation kept its cache in a service instance,\n * so every entity label was re-fetched on a browser refresh (issue #22 in the architecture\n * doc). A consumer that wants the cache to survive a reload can back this with\n * sessionStorage; the default keeps it in memory, which is the right call for a library\n * that must not silently persist a tenant's data.\n */\nexport interface EntityRefCacheStore {\n get(key: string): ReferenceOption[] | undefined;\n set(key: string, value: ReferenceOption[]): void;\n delete(key: string): void;\n /** Every key currently held — used for prefix invalidation of one entity. */\n keys(): string[];\n clear(): void;\n}\n\n/** Default in-memory store. Lives as long as the injector that created it. */\nexport class InMemoryEntityRefCacheStore implements EntityRefCacheStore {\n private readonly map = new Map<string, ReferenceOption[]>();\n\n get(key: string): ReferenceOption[] | undefined {\n return this.map.get(key);\n }\n\n set(key: string, value: ReferenceOption[]): void {\n this.map.set(key, value);\n }\n\n delete(key: string): void {\n this.map.delete(key);\n }\n\n keys(): string[] {\n return [...this.map.keys()];\n }\n\n clear(): void {\n this.map.clear();\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport type { Type } from '@angular/core';\nimport type {\n CommonModuleEntry,\n EntityReferenceLoader,\n FileUploadHandler,\n LookupListSource,\n RecordMigration,\n} from '@dynamic-entity/core';\nimport { InMemoryEntityRefCacheStore, type EntityRefCacheStore } from '../services/entity-ref-cache';\n\n/** Roles that see XXXXXXXXX for masked fields. Presentational only — enforce authz server-side. */\nexport const MASKED_ROLES = new InjectionToken<string[]>('MASKED_ROLES');\n\n/**\n * Consumer **overrides**: fieldType string → Angular component class.\n * Highest priority — beats anything registered through `provideFieldTypes()`.\n */\nexport const FIELD_TYPE_REGISTRY = new InjectionToken<Map<string, Type<any>>>('FIELD_TYPE_REGISTRY');\n\n/**\n * Multi-provider of field-type sets, contributed by `provideFieldTypes()` /\n * `provideBuiltInFieldTypes()`. Multi so several calls compose instead of clobbering;\n * later sets win on key collision. This is the seam that keeps unused field components\n * out of the bundle — nothing is imported until a set names it.\n */\nexport const FIELD_TYPE_SETS = new InjectionToken<Record<string, Type<any>>[]>('FIELD_TYPE_SETS');\n\n/**\n * Registry: entity key → option loader.\n *\n * A loader receives a `ReferenceLoaderContext` (`parentValue`, `filters`, `lang`) and may\n * return an array, a Promise, or an Observable of `ReferenceOption[]`. `ctx` is optional,\n * so a zero-arg loader (`() => svc.list()`) is still a valid registration.\n */\nexport const ENTITY_REF_REGISTRY = new InjectionToken<Map<string, EntityReferenceLoader>>(\n 'ENTITY_REF_REGISTRY',\n);\n\n/**\n * Registry: list name → the values of a named master list (`field.listName`).\n *\n * A source may be the values themselves (array / Promise / Observable) or a **loader function**,\n * which is what you want for anything fetched: a bare Promise is created when the provider is\n * built, so every list would load whether or not a form uses it.\n *\n * Values are normalised by `normalizeLookupValues` — bare strings and `LocalizedText` are\n * accepted alongside the full `{ code, name, sortOrder }` shape.\n *\n * @example\n * provideNgxDynamicEntity({\n * lookups: {\n * employeeStatus: () => listService.getByName('employeeStatus'),\n * grades: ['Junior', 'Senior'],\n * },\n * })\n */\nexport const LOOKUP_REGISTRY = new InjectionToken<Map<string, LookupListSource>>('LOOKUP_REGISTRY');\n\n/**\n * Ordered steps that move a saved record forward when a config's `version` increases.\n *\n * Without these, `EntityFormConfig.version` and `VersionedRecord._configVersion` are\n * declarations nothing acts on: a schema can be edited freely while records keep their old\n * shape, and nothing reconciles the two. Registering migrations makes the version numbers\n * mean something.\n *\n * @example\n * provideNgxDynamicEntity({\n * migrations: [\n * { from: 1, to: 2, description: 'split name', migrate: r => ({ ...r, firstName: r['name'] }) },\n * ],\n * })\n */\nexport const RECORD_MIGRATIONS = new InjectionToken<RecordMigration[]>('RECORD_MIGRATIONS');\n\n/**\n * Overrides for the messages shown under an invalid field, keyed by Angular error key\n * (`required`, `minlength`, `pattern`, …) plus a few field-specific keys.\n *\n * The built-in messages are English literals. Registering here is what makes a non-English\n * form possible without re-implementing every field component; unlisted keys keep their\n * default, so overriding one does not mean supplying them all.\n */\nexport const VALIDATION_MESSAGES = new InjectionToken<Record<string, any>>('VALIDATION_MESSAGES');\n\n/** Registry: validator key → ValidatorFn */\nexport const VALIDATOR_REGISTRY = new InjectionToken<Map<string, any>>('VALIDATOR_REGISTRY');\n\n/**\n * Registry: validator key → AsyncValidatorFn.\n *\n * Kept separate from VALIDATOR_REGISTRY because Angular applies the two differently: an async\n * validator runs only once the synchronous ones pass, and puts the control into `pending`\n * while it does. Name them from a schema with `validators: { customAsync: ['uniqueEmail'] }`.\n */\nexport const ASYNC_VALIDATOR_REGISTRY = new InjectionToken<Map<string, any>>(\n 'ASYNC_VALIDATOR_REGISTRY',\n);\n\n/**\n * A registered hook: receives the payload, returns it (or a replacement), sync or async.\n *\n * Spelled out rather than typed as `Function`, which accepts class declarations and any\n * arity and gives a consumer no signature to write against.\n */\nexport type HookFn = (data: any, context?: unknown) => unknown | Promise<unknown>;\n\n/** Registry: hook key → async (data, context) => data */\nexport const HOOK_REGISTRY = new InjectionToken<Map<string, HookFn>>('HOOK_REGISTRY');\n\n/**\n * Consumer-registered list of common module tabs (documents, audit, tasks, etc.).\n * The library ships no built-in implementations. Consumers provide their own list\n * so the builder's module-picker and the renderer's tab switcher know what's available.\n *\n * @example\n * providers: [\n * {\n * provide: COMMON_MODULES_REGISTRY,\n * useValue: [\n * { id: 'documents', label: { en: 'Documents' }, component: 'app-documents-view' },\n * { id: 'audit', label: { en: 'Audit Log' }, component: 'app-audit' },\n * ] satisfies CommonModuleEntry[]\n * }\n * ]\n */\nexport const COMMON_MODULES_REGISTRY = new InjectionToken<CommonModuleEntry[]>(\n 'COMMON_MODULES_REGISTRY',\n);\n\n/**\n * Consumer-provided file/image upload handler.\n * When supplied, image-field and file-field call it to persist the File and receive a stable\n * URL back. Without it the field stores `{ file, name, size, mimeType }` for the consumer to\n * upload on submit. May return the result directly, as a Promise, or as an Observable.\n *\n * @example\n * { provide: UPLOAD_HANDLER, useFactory: () => (file: File) => myUploadService.upload(file) }\n */\nexport const UPLOAD_HANDLER = new InjectionToken<FileUploadHandler>('UPLOAD_HANDLER');\n\n/**\n * Backing store for the entity-reference options cache. Defaults to in-memory.\n * Provide your own to make the cache outlive a page refresh.\n *\n * @example\n * { provide: ENTITY_REF_CACHE_STORE, useClass: SessionStorageRefCache }\n */\nexport const ENTITY_REF_CACHE_STORE = new InjectionToken<EntityRefCacheStore>(\n 'ENTITY_REF_CACHE_STORE',\n { providedIn: 'root', factory: () => new InMemoryEntityRefCacheStore() },\n);\n\n/**\n * Consumer-provided predicate function to check whether user roles can edit system default tabs or fields.\n * Defaults to allowing edits if not provided.\n */\nexport const SYSTEM_DEFAULT_CAN_EDIT = new InjectionToken<(roles: string[]) => boolean>(\n 'SYSTEM_DEFAULT_CAN_EDIT',\n);\n\nexport type ConfigSourceHandler = (\n entityKey: string,\n) => any;\n\n/**\n * Registry/Resolver for resolving an EntityFormConfig by entity key across entities (Phase 8).\n * Enables cross-entity field referencing (`isReferenced`, `referencedEntityKey`, `referencedFieldId`, `hasDrift`).\n */\nexport const CONFIG_SOURCE = new InjectionToken<ConfigSourceHandler>('CONFIG_SOURCE');\n\n\n\n/**\n * Turns the markdown a `markdown` field stores into HTML for display.\n *\n * Optional, and deliberately not bundled: these packages declare no runtime dependencies\n * beyond `tslib`, and a markdown parser is a large one to force on every consumer. Without\n * a renderer the field still works — it stores and shows the source text, with line breaks\n * preserved and nothing interpreted.\n *\n * The returned HTML is bound through `[innerHTML]`, so Angular's sanitizer strips scripts\n * and event handlers before it reaches the DOM. That is a backstop, not a licence: a\n * renderer should still be configured to escape raw HTML in its input, because sanitizing\n * removes the dangerous parts silently rather than telling the author their content was\n * altered.\n *\n * @example\n * import { marked } from 'marked';\n * { provide: MARKDOWN_RENDERER, useValue: (src: string) => marked.parse(src) as string }\n */\nexport const MARKDOWN_RENDERER = new InjectionToken<(source: string) => string>(\n 'MARKDOWN_RENDERER',\n);\n","import { EnvironmentProviders, makeEnvironmentProviders, Type } from '@angular/core';\nimport type { EntityReferenceLoader, LookupListSource, RecordMigration } from '@dynamic-entity/core';\nimport {\n ENTITY_REF_REGISTRY,\n FIELD_TYPE_REGISTRY,\n HOOK_REGISTRY,\n type HookFn,\n ASYNC_VALIDATOR_REGISTRY,\n RECORD_MIGRATIONS,\n VALIDATION_MESSAGES,\n LOOKUP_REGISTRY,\n MASKED_ROLES,\n VALIDATOR_REGISTRY,\n} from '../tokens/injection-tokens';\n\nexport interface NgxDynamicEntityConfig {\n /** Roles that see masked field values as XXXXXXXXX */\n maskedRoles?: string[];\n /** Custom field type components keyed by type string */\n fieldTypes?: Record<string, Type<any>>;\n /**\n * Entity-ref option loaders keyed by entity key.\n * Each receives `{ parentValue, filters, lang }` and may return an array, Promise, or Observable.\n */\n entityRefs?: Record<string, EntityReferenceLoader>;\n /**\n * Named master lists keyed by list name, for fields that set `listName`.\n * Each may be the values themselves (array/Promise/Observable) or a loader function — prefer\n * a loader for anything fetched, so an unused list is never loaded.\n */\n lookups?: Record<string, LookupListSource>;\n /**\n * Override the messages shown under invalid fields, keyed by Angular error key. A value is\n * a string, or a function receiving `(language, error)` when it needs the error's detail.\n * Unlisted keys keep their English default.\n */\n validationMessages?: Record<string, string | ((language: string, error: any) => string)>;\n /**\n * Async validator functions keyed by name, for checks that need a server — uniqueness,\n * availability, a remote rule. Name them from a schema with\n * `validators: { customAsync: ['uniqueEmail'] }`.\n *\n * Each is an Angular `AsyncValidatorFn`: it receives the control and returns a Promise or\n * Observable of `ValidationErrors | null`. The control is `pending` while it runs, and the\n * form cannot be submitted until every pending check settles.\n */\n asyncValidators?: Record<string, any>;\n /** Custom validator functions keyed by validator name */\n validators?: Record<string, any>;\n /** Hook functions keyed by hook name */\n hooks?: Record<string, HookFn>;\n /**\n * Ordered steps that upgrade a saved record when `EntityFormConfig.version` moves ahead\n * of the record's `_configVersion`. Applied to `initialData` before the form is patched.\n */\n migrations?: RecordMigration[];\n}\n\n/**\n * Provider function for ngx-dynamic-entity.\n * All options are optional — consumers provide only what they use (ISP).\n *\n * Usage in app.config.ts:\n * provideNgxDynamicEntity({\n * maskedRoles: ['IT_SUPPORT'],\n * entityRefs: { clients: () => clientService.getOptions() },\n * })\n */\nexport const provideNgxDynamicEntity = (config: NgxDynamicEntityConfig = {}): EnvironmentProviders =>\n makeEnvironmentProviders([\n { provide: MASKED_ROLES, useValue: config.maskedRoles ?? [] },\n { provide: FIELD_TYPE_REGISTRY, useValue: new Map(Object.entries(config.fieldTypes ?? {})) },\n { provide: ENTITY_REF_REGISTRY, useValue: new Map(Object.entries(config.entityRefs ?? {})) },\n { provide: LOOKUP_REGISTRY, useValue: new Map(Object.entries(config.lookups ?? {})) },\n { provide: VALIDATOR_REGISTRY, useValue: new Map(Object.entries(config.validators ?? {})) },\n {\n provide: ASYNC_VALIDATOR_REGISTRY,\n useValue: new Map(Object.entries(config.asyncValidators ?? {})),\n },\n { provide: HOOK_REGISTRY, useValue: new Map(Object.entries(config.hooks ?? {})) },\n { provide: RECORD_MIGRATIONS, useValue: config.migrations ?? [] },\n { provide: VALIDATION_MESSAGES, useValue: config.validationMessages ?? {} },\n ]);\n","import { Injectable, inject } from '@angular/core';\nimport type { ValidationErrors } from '@angular/forms';\nimport { VALIDATION_MESSAGES } from '../tokens/injection-tokens';\n\n/**\n * Resolves an Angular `ValidationErrors` object to the message shown under a field.\n *\n * These strings used to be hardcoded English literals inside each field component, so a\n * German form meant re-implementing every field type — the labels honoured `language` while\n * the errors underneath them did not.\n *\n * A message is a plain string, or a function when it needs the error's own detail\n * (`minlength.requiredLength`, `min.min`, and so on). The active `language` is passed\n * through, so one registration can serve every locale:\n *\n * ```typescript\n * provideNgxDynamicEntity({\n * validationMessages: {\n * required: lang => (lang === 'de' ? 'Pflichtfeld.' : 'This field is required.'),\n * minlength: (lang, err) => `Mindestens ${err['requiredLength']} Zeichen.`,\n * },\n * });\n * ```\n *\n * Unregistered keys fall back to the defaults below, so overriding one message does not\n * mean supplying them all.\n */\nexport type ValidationMessage = string | ((language: string, error: any) => string);\n\n/** The built-in English messages. Every key here can be overridden individually. */\nexport const DEFAULT_VALIDATION_MESSAGES: Record<string, ValidationMessage> = {\n required: 'This field is required.',\n requiredSelection: 'Please select an option.',\n email: 'Please enter a valid email address.',\n pattern: 'Invalid format.',\n minlength: (_lang, err) => `Minimum ${err?.requiredLength} characters required.`,\n maxlength: (_lang, err) => `Maximum ${err?.requiredLength} characters allowed.`,\n min: (_lang, err) => `Value must be at least ${err?.min}.`,\n max: (_lang, err) => `Value must not exceed ${err?.max}.`,\n invalid: 'Invalid value.',\n invalidNumber: 'Invalid number.',\n invalidSelection: 'Invalid selection.',\n};\n\n@Injectable({ providedIn: 'root' })\nexport class ValidationMessagesService {\n private readonly overrides = inject(VALIDATION_MESSAGES, { optional: true }) ?? {};\n\n /**\n * The message for the first error present, in the order the caller lists.\n *\n * Order is the caller's because it is field-specific: a dropdown wants\n * `requiredSelection` where a text input wants `required`, and the first match wins so the\n * most specific message is the one shown.\n */\n resolve(\n errors: ValidationErrors | null | undefined,\n language: string,\n order: readonly (string | readonly [errorKey: string, messageKey: string])[],\n fallbackKey = 'invalid',\n ): string {\n if (!errors) return '';\n\n for (const entry of order) {\n // A tuple maps an Angular error key to a different message key: a dropdown raises the\n // standard `required` error but reads better as \"Please select an option\", and both\n // messages stay independently overridable.\n const [errorKey, messageKey] = typeof entry === 'string' ? [entry, entry] : entry;\n // `errors[errorKey]` is usually an object of detail, but `required` is simply `true`.\n if (errors[errorKey] === undefined) continue;\n return this.messageFor(messageKey, language, errors[errorKey]);\n }\n return this.messageFor(fallbackKey, language, null);\n }\n\n /** One message by key, honouring an override before the default. */\n messageFor(key: string, language: string, error: unknown): string {\n const message = this.overrides[key] ?? DEFAULT_VALIDATION_MESSAGES[key];\n if (message === undefined) return '';\n return typeof message === 'function' ? message(language, error) : message;\n }\n}\n","import { Component, Input, OnDestroy, inject, ChangeDetectionStrategy, signal } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { ValidationMessagesService } from '../services/validation-messages.service';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-text-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div\n class=\"ngx-field ngx-field--text\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\"\n [class.ngx-field--readonly]=\"readonly\"\n [class.ngx-field--masked]=\"masked\"\n [class.ngx-field--invalid]=\"control && control.invalid && control.touched\"\n >\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}@if (field.validators?.required) { <span class=\"ngx-field__req\">*</span> }</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ displayValue() ?? '—' }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n type=\"text\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder\"\n [attr.disabled]=\"field.disabled ? true : null\"\n [attr.aria-invalid]=\"control.invalid && control.touched\"\n [attr.aria-describedby]=\"errorMessage ? field.id + '-error' : null\"\n />\n @if (errorMessage) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\" [id]=\"field.id + '-error'\" role=\"alert\">{{ errorMessage }}</span>\n }\n }\n </div>\n `,\n})\nexport class TextFieldComponent implements OnDestroy {\n private readonly messages = inject(ValidationMessagesService);\n private displaySub?: Subscription;\n\n @Input() field!: NestedFieldConfig;\n @Input()\n set control(value: AbstractControl) {\n this._control = value;\n this.displaySub?.unsubscribe();\n this.displayValue.set(value?.value ?? null);\n this.displaySub = value?.valueChanges.subscribe(v => this.displayValue.set(v));\n }\n get control(): AbstractControl {\n return this._control;\n }\n private _control!: AbstractControl;\n\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Readonly markup reads this signal so an external patch (autoPatch) is visible under OnPush. */\n readonly displayValue = signal<unknown>(null);\n\n ngOnDestroy(): void {\n this.displaySub?.unsubscribe();\n }\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n get errorMessage(): string {\n if (!this.control || !this.control.errors || !this.control.touched) return '';\n return this.messages.resolve(\n this.control.errors,\n this.language,\n ['required', 'email', 'minlength', 'maxlength', 'pattern'],\n );\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-textarea-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--textarea\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value }}</span>\n } @else {\n <textarea\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder\"\n [attr.disabled]=\"field.disabled ? true : null\"\n rows=\"3\"\n ></textarea>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class TextareaFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n}\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n DestroyRef,\n Input,\n OnChanges,\n SimpleChanges,\n inject,\n signal,\n} from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { MARKDOWN_RENDERER } from '../tokens/injection-tokens';\n\n/**\n * Markdown field: a long-form input that stores **markdown source**, never HTML.\n *\n * Storing the source rather than rendered HTML is the whole design. The record stays plain\n * text — diffable, portable, safe to log, and impossible to turn into stored XSS by writing\n * it into a database. Rendering happens at display time and only when a consumer asks for\n * it, via `MARKDOWN_RENDERER`.\n *\n * Without a renderer this degrades to exactly what `textarea` does, plus preserved line\n * breaks: the source is shown as text with nothing interpreted. That is the default because\n * these packages declare no runtime dependencies beyond `tslib`, and a markdown parser is a\n * large thing to force on a consumer who wanted a form library.\n *\n * With a renderer, its HTML is bound through `[innerHTML]`, which Angular sanitizes — see\n * the token's own note on why that is a backstop rather than a licence.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-markdown-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div\n class=\"ngx-field ngx-field--markdown\"\n [attr.data-testid]=\"'field-' + field.id\"\n [attr.data-field-type]=\"field.type\"\n [class.ngx-field--readonly]=\"readonly\"\n [class.ngx-field--masked]=\"masked\"\n >\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n @if (rendered(); as html) {\n <div class=\"ngx-field__value ngx-field__markdown\" [attr.data-testid]=\"'field-' + field.id + '-value'\" [innerHTML]=\"html\"></div>\n } @else {\n <!-- No renderer: the source is the display. The stylesheet keeps its line\n breaks with white-space: pre-wrap, and interpolation escapes it. -->\n <span class=\"ngx-field__value ngx-field__markdown--source\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value }}</span>\n }\n } @else {\n <div class=\"ngx-field__markdown-editor\">\n @if (canPreview) {\n <div class=\"ngx-field__markdown-tabs\" role=\"group\" [attr.aria-label]=\"label + ' editor mode'\">\n <button\n type=\"button\"\n class=\"ngx-field__markdown-tab\"\n [attr.data-testid]=\"'field-' + field.id + '-write'\"\n [attr.aria-pressed]=\"!previewing()\"\n (click)=\"previewing.set(false)\"\n >\n Write\n </button>\n <button\n type=\"button\"\n class=\"ngx-field__markdown-tab\"\n [attr.data-testid]=\"'field-' + field.id + '-preview'\"\n [attr.aria-pressed]=\"previewing()\"\n (click)=\"previewing.set(true)\"\n >\n Preview\n </button>\n </div>\n }\n\n @if (previewing()) {\n <div class=\"ngx-field__markdown ngx-field__markdown--preview\" [attr.data-testid]=\"'field-' + field.id + '-preview-body'\" [innerHTML]=\"rendered()\"></div>\n } @else {\n <textarea\n [id]=\"field.id\"\n class=\"ngx-field__input ngx-field__input--markdown\"\n [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder\"\n [attr.disabled]=\"field.disabled ? true : null\"\n rows=\"6\"\n ></textarea>\n }\n </div>\n\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class MarkdownFieldComponent implements OnChanges {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Optional — the field is fully usable without one. */\n private readonly render = inject(MARKDOWN_RENDERER, { optional: true });\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly previewing = signal(false);\n\n private valueSub?: { unsubscribe(): void };\n\n /**\n * Re-render when the value changes from outside this component.\n *\n * `rendered()` reads `control.value`, which under OnPush is neither an input nor a\n * template event: typing in the textarea updates through `formControl`, but a host\n * calling `patchValue`, a rule, or an `autoPatch` mapping does not mark this component\n * dirty. The preview and the read-only view would keep showing the previous document\n * while the record already held a different one.\n */\n ngOnChanges(changes: SimpleChanges): void {\n if (!changes['control']) return;\n this.valueSub?.unsubscribe();\n this.valueSub = this.control?.valueChanges?.subscribe(() => this.cdr.markForCheck());\n if (this.valueSub) this.destroyRef.onDestroy(() => this.valueSub?.unsubscribe());\n }\n\n /** A Preview tab that can only ever show the source back is worse than no tab. */\n protected get canPreview(): boolean {\n return !!this.render;\n }\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n /**\n * Rendered HTML, or null when there is no renderer or nothing to render.\n *\n * A renderer is consumer code and may throw on input it does not like. Letting that\n * escape would take down the whole form over one malformed field, so it falls back to the\n * source text — which is what the field would have shown with no renderer at all.\n */\n protected rendered(): string | null {\n const source = this.control?.value;\n if (!this.render || typeof source !== 'string' || source === '') return null;\n try {\n return this.render(source);\n } catch {\n return null;\n }\n }\n}\n","import { Component, Input, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { ValidationMessagesService } from '../services/validation-messages.service';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-number-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div\n class=\"ngx-field ngx-field--number\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\"\n [class.ngx-field--readonly]=\"readonly\"\n [class.ngx-field--masked]=\"masked\"\n [class.ngx-field--invalid]=\"control && control.invalid && control.touched\"\n >\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">\n {{ label }}\n @if (field.validators?.required) { <span class=\"ngx-field__req\">*</span> }\n </label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value ?? '—' }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n type=\"number\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder\"\n [attr.disabled]=\"field.disabled ? true : null\"\n [attr.aria-invalid]=\"control.invalid && control.touched\"\n [attr.aria-describedby]=\"errorMessage ? field.id + '-error' : null\"\n />\n @if (errorMessage) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\" [id]=\"field.id + '-error'\" role=\"alert\">{{ errorMessage }}</span>\n }\n }\n </div>\n `,\n})\nexport class NumberFieldComponent {\n private readonly messages = inject(ValidationMessagesService);\n\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n get errorMessage(): string {\n if (!this.control || !this.control.errors || !this.control.touched) return '';\n return this.messages.resolve(\n this.control.errors,\n this.language,\n ['required', 'min', 'max'],\n 'invalidNumber',\n );\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/** Currency field: number input with locale-aware currency symbol prefix. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-currency-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--currency\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ symbol }}{{ control.value }}</span>\n } @else {\n <div class=\"ngx-field__currency-wrap\">\n <span class=\"ngx-field__currency-symbol\">{{ symbol }}</span>\n <input\n class=\"ngx-field__input ngx-field__input--currency\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"number\"\n step=\"0.01\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder || '0.00'\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n </div>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class CurrencyFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n /** Picks the currency symbol from the locale — defaults to '$'. */\n get symbol(): string {\n try {\n return (0).toLocaleString(this.language, { style: 'currency', currency: 'USD', minimumFractionDigits: 0 })\n .replace(/[\\d,.\\s]/g, '').trim() || '$';\n } catch {\n return '$';\n }\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/** Email field: type=\"email\" input with inline validation hint. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-email-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--email\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">\n <a [href]=\"'mailto:' + control.value\" class=\"ngx-field__email-link\">{{ control.value || '—' }}</a>\n </span>\n } @else {\n <input\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"email\"\n autocomplete=\"email\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder || 'you@example.com'\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n @if (control.invalid && control.touched) {\n @if (control.errors?.['required']) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">Email is required</span>\n } @else if (control.errors?.['email']) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">Enter a valid email address</span>\n } @else {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n }\n </div>\n `,\n})\nexport class EmailFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n}\n","import { Component, Input, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/** Password field: masked input with show/hide eye toggle. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-password-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--password\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">••••••••</span>\n } @else {\n <div class=\"ngx-field__password-wrap\">\n <input\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [type]=\"visible() ? 'text' : 'password'\"\n autocomplete=\"current-password\"\n [formControl]=\"$any(control)\"\n [placeholder]=\"placeholder || '••••••••'\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n <button\n type=\"button\"\n class=\"ngx-field__eye-btn\"\n (click)=\"toggleVisibility()\"\n [attr.aria-label]=\"visible() ? 'Hide password' : 'Show password'\"\n >\n {{ visible() ? '🙈' : '👁' }}\n </button>\n </div>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class PasswordFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n readonly visible = signal(false);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n toggleVisibility(): void {\n this.visible.update(v => !v);\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-checkbox-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--checkbox\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n @if (masked) {\n <label class=\"ngx-field__label\">{{ label }}</label>\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <label class=\"ngx-field__label\">{{ label }}</label>\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value ? 'Yes' : 'No' }}</span>\n } @else {\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">\n <input\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"checkbox\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n {{ label }}\n </label>\n }\n </div>\n `,\n})\nexport class CheckboxFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/**\n * Boolean field: a slide-toggle style switch (true/false).\n * Distinct from `checkbox` (which is a standalone bool) in that it renders as a\n * toggle switch with Yes/No labels for clearer binary state communication.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-boolean-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--boolean\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n @if (masked) {\n <label class=\"ngx-field__label\">{{ label }}</label>\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <label class=\"ngx-field__label\">{{ label }}</label>\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ control.value ? 'Yes' : 'No' }}</span>\n } @else {\n <div class=\"ngx-field__toggle-wrap\">\n <label class=\"ngx-field__toggle-label\">{{ label }}</label>\n <label class=\"ngx-field__toggle-switch\" [class.ngx-field__toggle-switch--checked]=\"control.value\">\n <input\n class=\"ngx-field__toggle-input\"\n type=\"checkbox\"\n role=\"switch\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n [attr.aria-checked]=\"control.value\"\n />\n <span class=\"ngx-field__toggle-track\">\n <span class=\"ngx-field__toggle-thumb\"></span>\n </span>\n <span class=\"ngx-field__toggle-text\">{{ control.value ? 'Yes' : 'No' }}</span>\n </label>\n </div>\n }\n </div>\n `,\n})\nexport class BooleanFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-date-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--date\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ formatDate(control.value) }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"date\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class DateFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n /** ISO 8601 date → locale display string (ONEHERMES convention: always UTC, display in user locale) */\n formatDate(value: string | null): string {\n if (!value) return '—';\n // `new Date('nonsense')` does not throw and `toLocaleDateString()` returns the *string*\n // \"Invalid Date\", so the try/catch this replaced never fired and readers saw that text\n // instead of their data. Records outlive schemas — a field retyped from text to date can\n // hold anything — so an unparseable value is shown as stored.\n const parsed = new Date(value);\n return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleDateString();\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\n/**\n * Reads a stored value into a `Date`.\n *\n * A bare calendar date is pinned to *local* midnight. `new Date('2020-01-01')` reads a\n * date-only string as UTC midnight, which renders as the previous day anywhere west of\n * Greenwich — and every legacy `datetime` value has exactly that shape, because the type\n * used to render through `DateFieldComponent` and its `type=\"date\"` input.\n */\nfunction parseStored(value: unknown): Date | null {\n if (value === null || value === undefined || value === '') return null;\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;\n\n const raw = String(value);\n const dateOnly = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(raw);\n if (dateOnly) return new Date(+dateOnly[1], +dateOnly[2] - 1, +dateOnly[3]);\n\n const parsed = new Date(raw);\n return Number.isNaN(parsed.getTime()) ? null : parsed;\n}\n\nconst pad = (n: number): string => String(n).padStart(2, '0');\n\n/**\n * Date & Time field: a single `datetime-local` input.\n *\n * The type is stored as ISO 8601 UTC, per the same convention `date` follows, while the\n * input works in the viewer's local zone — `datetime-local` has no offset, so the two\n * conversions here are what keep a value stable across a round trip.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-date-time-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--datetime\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ formatDateTime(control.value) }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"datetime-local\"\n [value]=\"inputValue\"\n (change)=\"onInput($any($event.target).value)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class DateTimeFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n /** Stored ISO 8601 → the `YYYY-MM-DDTHH:mm` local form the input requires. */\n get inputValue(): string {\n const d = parseStored(this.control?.value);\n if (!d) return '';\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;\n }\n\n /** The input's local `YYYY-MM-DDTHH:mm` → stored ISO 8601 UTC. */\n onInput(value: string): void {\n if (!value) {\n this.control.setValue(null);\n this.control.markAsTouched();\n return;\n }\n const d = new Date(value);\n // An unparseable value is stored verbatim rather than silently discarded, so a validator\n // sees what the user actually entered.\n this.control.setValue(Number.isNaN(d.getTime()) ? value : d.toISOString());\n this.control.markAsTouched();\n }\n\n /**\n * Displays date *and* time. `DateFieldComponent` used `toLocaleDateString()` here, so a\n * datetime read back through the field showed no time while the same value in the record\n * summary — which goes through core's `formatDisplayValue` — showed it.\n */\n formatDateTime(value: unknown): string {\n const d = parseStored(value);\n return d ? d.toLocaleString() : '—';\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { formatDisplayValue, resolveLabel } from '@dynamic-entity/core';\n\n/**\n * Time field: a bare time of day, with no date and no zone attached.\n *\n * Stored as `HH:mm` — exactly the value `<input type=\"time\">` reads and writes, so the\n * control binds straight through with no conversion. That is the whole reason this is a\n * separate type from `datetime`: a recurring 09:00 opening time is not a moment in time,\n * and converting it to UTC would move it whenever the offset changed.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-time-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--time\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ formatTime(control.value) }}</span>\n } @else {\n <input\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n type=\"time\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class TimeFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n /**\n * Defers to core rather than parsing `HH:mm` locally. The other date-ish components each\n * grew their own formatter, and `datetime` ended up showing one thing in the field and\n * another in the record summary because the two drifted apart.\n */\n formatTime(value: unknown): string {\n return formatDisplayValue('time', undefined, value, this.language);\n }\n}\n","import { Component, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\n\nconst MONTH_NAMES = [\n 'January', 'February', 'March', 'April', 'May', 'June',\n 'July', 'August', 'September', 'October', 'November', 'December',\n];\n\nconst CURRENT_YEAR = new Date().getFullYear();\nconst YEARS = Array.from({ length: 80 }, (_, i) => CURRENT_YEAR - i);\n\n/**\n * Month-Year field: two linked selects (Month + Year).\n * Value stored as ISO partial date string \"YYYY-MM\" for unambiguous storage.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-month-year-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--month-year\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ formatValue(control.value) }}</span>\n } @else {\n <div class=\"ngx-field__month-year-wrap\">\n <select\n class=\"ngx-field__input ngx-field__input--month\" [attr.data-testid]=\"'field-' + field.id + '-month'\"\n [value]=\"selectedMonth\"\n (change)=\"onMonthChange($any($event.target).value)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n >\n <option value=\"\">Month</option>\n @for (m of months; track m.value) {\n <option [value]=\"m.value\">{{ m.label }}</option>\n }\n </select>\n <select\n class=\"ngx-field__input ngx-field__input--year\" [attr.data-testid]=\"'field-' + field.id + '-year'\"\n [value]=\"selectedYear\"\n (change)=\"onYearChange($any($event.target).value)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n >\n <option value=\"\">Year</option>\n @for (y of years; track y) {\n <option [value]=\"y\">{{ y }}</option>\n }\n </select>\n </div>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class MonthYearFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n readonly months = MONTH_NAMES.map((label, i) => ({ value: String(i + 1).padStart(2, '0'), label }));\n readonly years = YEARS;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n /** Parses \"YYYY-MM\" or \"YYYY-MM-DD\" stored value → month part. */\n get selectedMonth(): string {\n const v = String(this.control.value ?? '');\n return v.length >= 7 ? v.substring(5, 7) : '';\n }\n\n get selectedYear(): string {\n const v = String(this.control.value ?? '');\n return v.length >= 4 ? v.substring(0, 4) : '';\n }\n\n onMonthChange(month: string): void {\n const year = this.selectedYear || new Date().getFullYear().toString();\n this.control.setValue(month ? `${year}-${month}` : null);\n this.control.markAsTouched();\n }\n\n onYearChange(year: string): void {\n const month = this.selectedMonth || '01';\n this.control.setValue(year ? `${year}-${month}` : null);\n this.control.markAsTouched();\n }\n\n formatValue(value: unknown): string {\n if (!value) return '—';\n const [year, monthNum] = String(value).split('-');\n const monthName = MONTH_NAMES[parseInt(monthNum, 10) - 1];\n return monthName && year ? `${monthName} ${year}` : String(value);\n }\n}\n","import { Injectable, inject, type WritableSignal } from '@angular/core';\nimport type {\n DropdownOption,\n LookupListLoader,\n LookupListResult,\n LookupListSource,\n LookupListValue,\n NestedFieldConfig,\n RawLookupListValue,\n Subscribable,\n} from '@dynamic-entity/core';\nimport { lookupValuesToOptions, normalizeLookupValues, resolveLabel } from '@dynamic-entity/core';\nimport { LOOKUP_REGISTRY } from '../tokens/injection-tokens';\n\n/** Cache-key field separator. Kept out of template literals so it stays visible in source. */\nconst SEP = '|';\n\n/**\n * LookupRegistryService — the cache in front of consumer-registered master lists.\n *\n * Three layers, deliberately the same shape as `EntityReferenceService`, because the problem is\n * the same: one list is typically used by many fields across many entities.\n * 1. **options** — resolved `DropdownOption[]` per (list name, lang).\n * 2. **in-flight** — the pending Promise, so N fields on one list trigger one load, not N.\n * 3. **labels** — synchronous value → text (parity plan §6.2). This is not a nicety: since\n * `viewMode` defaults to true a record opens read-only, so rendering a stored value as\n * text is the *first* thing a `listName` field has to do. An async-only registry would\n * paint the raw stored value and then flip, on every record open.\n *\n * A failed load rejects and caches nothing, so one transient error does not serve an empty\n * list forever — the same fix made for entity references in phase 5.\n */\n@Injectable({ providedIn: 'root' })\nexport class LookupRegistryService {\n private readonly registry =\n inject(LOOKUP_REGISTRY, { optional: true }) ?? new Map<string, LookupListSource>();\n\n /** `listName|lang` -> resolved options. */\n private readonly options = new Map<string, DropdownOption[]>();\n /** `listName|lang` -> normalised values, so a consumer can reach `code` / `isSystemDefined`. */\n private readonly values = new Map<string, LookupListValue[]>();\n /** Loads in progress, keyed as above. */\n private readonly inFlight = new Map<string, Promise<DropdownOption[]>>();\n /** `listName|lang|text` -> display text, for the synchronous read-only path. */\n private readonly labels = new Map<string, string>();\n\n has(listName: string): boolean {\n return this.registry.has(listName);\n }\n\n /**\n * Options for a named list, from cache when present.\n * Concurrent callers with the same key share one load.\n */\n async load(listName: string, lang = 'en'): Promise<DropdownOption[]> {\n const key = this.cacheKey(listName, lang);\n\n const cached = this.options.get(key);\n if (cached) return cached;\n\n const pending = this.inFlight.get(key);\n if (pending) return pending;\n\n const source = this.registry.get(listName);\n if (source === undefined) return [];\n\n const load = this.invoke(source, lang).then(raw => {\n const values = normalizeLookupValues(raw);\n const options = lookupValuesToOptions(values);\n this.values.set(key, values);\n this.options.set(key, options);\n this.rememberLabels(listName, lang, options);\n return options;\n });\n\n // Only the `.then` above writes to the cache, and a rejection skips it: the caller still\n // gets an empty list, but the next call retries instead of reading a poisoned entry.\n const guarded = load\n .catch(() => [] as DropdownOption[])\n .finally(() => this.inFlight.delete(key));\n\n this.inFlight.set(key, guarded);\n return guarded;\n }\n\n /** Cached options without triggering a load. `undefined` when not loaded. */\n peek(listName: string, lang = 'en'): DropdownOption[] | undefined {\n return this.options.get(this.cacheKey(listName, lang));\n }\n\n /**\n * Cached list values, carrying `_id`, `code`, `isSystemDefined` and `from`.\n * The library never reads those; this is the seam for a consumer that needs them.\n */\n valuesFor(listName: string, lang = 'en'): LookupListValue[] | undefined {\n return this.values.get(this.cacheKey(listName, lang));\n }\n\n /**\n * Display text for a stored value, synchronously. `undefined` when the list has not loaded\n * or holds no matching value — the caller keeps its own fallback, which is the stored text.\n *\n * Every language of an option is indexed, so a record saved under one language renders in\n * another: a value stored as `'Aktiv'` resolves to `'Active'` under `lang: 'en'`.\n */\n labelFor(listName: string | undefined, value: unknown, lang = 'en'): string | undefined {\n if (!listName || value === null || value === undefined || value === '') return undefined;\n for (const text of this.candidateTexts(value, lang)) {\n const hit = this.labels.get(this.labelKey(listName, lang, text));\n if (hit) return hit;\n }\n return undefined;\n }\n\n // ─── Field-level resolution — inline options win, else `listName` ────────────\n\n /** True when this field's options have to come from the registry. */\n needsResolve(field: NestedFieldConfig | undefined): boolean {\n return !!field?.listName && !field.options?.length;\n }\n\n /**\n * The options to render right now, without awaiting: inline options, else whatever the\n * registry already holds. Empty on a cold miss — pair with `resolveOptions`.\n */\n optionsFor(field: NestedFieldConfig | undefined, lang = 'en'): DropdownOption[] {\n if (!field) return [];\n if (field.options?.length) return field.options;\n if (!field.listName) return [];\n return this.peek(field.listName, lang) ?? [];\n }\n\n /** The options for a field, loading the named list if needed. */\n resolveOptions(field: NestedFieldConfig | undefined, lang = 'en'): Promise<DropdownOption[]> {\n if (!this.needsResolve(field)) return Promise.resolve(this.optionsFor(field, lang));\n return this.load(field!.listName!, lang);\n }\n\n /** Drop everything cached for one list, leaving other lists intact. */\n invalidate(listName: string): void {\n const prefix = `${listName}${SEP}`;\n for (const map of [this.options, this.values, this.inFlight]) {\n for (const key of [...map.keys()]) {\n if (key.startsWith(prefix)) map.delete(key);\n }\n }\n for (const key of [...this.labels.keys()]) {\n if (key.startsWith(prefix)) this.labels.delete(key);\n }\n }\n\n clear(): void {\n this.options.clear();\n this.values.clear();\n this.inFlight.clear();\n this.labels.clear();\n }\n\n // ─── Internals ──────────────────────────────────────────────────────────────\n\n private cacheKey(listName: string, lang: string): string {\n return [listName, lang].join(SEP);\n }\n\n private labelKey(listName: string, lang: string, text: string): string {\n return [listName, lang, text].join(SEP);\n }\n\n /** Index an option under every language it carries, so any stored spelling finds it. */\n private rememberLabels(listName: string, lang: string, options: DropdownOption[]): void {\n for (const option of options) {\n const display = resolveLabel(option, lang);\n if (!display) continue;\n for (const text of Object.values(option)) {\n if (typeof text === 'string' && text !== '') {\n this.labels.set(this.labelKey(listName, lang, text), display);\n }\n }\n }\n }\n\n /** The texts a stored value could have been indexed under. */\n private candidateTexts(value: unknown, lang: string): string[] {\n if (typeof value === 'object') {\n const texts = Object.values(value as Record<string, unknown>).filter(\n (v): v is string => typeof v === 'string' && v !== '',\n );\n const resolved = resolveLabel(value as Record<string, string>, lang);\n return resolved ? [resolved, ...texts] : texts;\n }\n return [String(value)];\n }\n\n // ─── Source coercion (values | loader, array | Promise | Observable) ─────────\n\n private invoke(source: LookupListSource, lang: string): Promise<RawLookupListValue[]> {\n let result: LookupListResult;\n try {\n result = typeof source === 'function' ? (source as LookupListLoader)({ lang }) : source;\n } catch (err) {\n // Reject rather than resolve empty: `load` must be able to tell failure from an empty\n // list, or it would cache the failure.\n return Promise.reject(err);\n }\n return this.toPromise(result);\n }\n\n private toPromise(result: LookupListResult): Promise<RawLookupListValue[]> {\n if (Array.isArray(result)) return Promise.resolve(result);\n if (this.isSubscribable(result)) {\n // First emission wins, so a stream that stays open still resolves the load.\n return new Promise<RawLookupListValue[]>((resolve, reject) => {\n let settled = false;\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n fn();\n };\n result.subscribe({\n next: value => settle(() => resolve(value ?? [])),\n error: err => settle(() => reject(err)),\n // Completing without emitting is a legitimate empty list, and is cached.\n complete: () => settle(() => resolve([])),\n });\n });\n }\n return Promise.resolve(result as Promise<RawLookupListValue[]>);\n }\n\n private isSubscribable(value: unknown): value is Subscribable<RawLookupListValue[]> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Subscribable<RawLookupListValue[]>).subscribe === 'function'\n );\n }\n}\n\n/** A choice field component, as far as option resolution is concerned. */\nexport interface ChoiceOptionHost {\n readonly field: NestedFieldConfig | undefined;\n readonly language: string;\n readonly options: WritableSignal<DropdownOption[]>;\n}\n\nconst hostLastConfig = new WeakMap<ChoiceOptionHost, { field?: NestedFieldConfig; lang?: string }>();\n\n/**\n * Point a choice component's `options` signal at the right source (parity plan §6.3).\n *\n * Called from the `field` / `language` input setters of `dropdown`, `radio` and `multiSelect` —\n * the wiring is theirs, the decision is the service's, which is what keeps the field\n * five-input contract intact: options are never pushed in as a sixth input.\n *\n * Setters rather than `ngOnChanges` on purpose. `ngOnChanges` only fires for inputs Angular\n * itself sets, so a component whose `field` is assigned directly — which the field specs do,\n * and any consumer holding a `ComponentRef` may do — would render no options at all.\n *\n * Paints synchronously first (inline options, or a warm list), then fills in when a cold list\n * lands. The late result is dropped if the field or language changed while it was in flight.\n */\nexport function refreshChoiceOptions(host: ChoiceOptionHost, lookups: LookupRegistryService): void {\n const last = hostLastConfig.get(host);\n if (last && last.field === host.field && last.lang === host.language) {\n return;\n }\n hostLastConfig.set(host, { field: host.field, lang: host.language });\n\n host.options.set(lookups.optionsFor(host.field, host.language));\n if (!lookups.needsResolve(host.field)) return;\n\n const listName = host.field?.listName;\n const lang = host.language;\n void lookups.resolveOptions(host.field, host.language).then(options => {\n if (host.field?.listName === listName && host.language === lang) host.options.set(options);\n });\n}\n","import { Component, Input, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { DropdownOption, NestedFieldConfig } from '@dynamic-entity/core';\nimport {\n getOptionStoredValue,\n resolveLabel,\n resolveOptionLabel,\n valuesMatch,\n} from '@dynamic-entity/core';\nimport { LookupRegistryService, refreshChoiceOptions } from '../services/lookup-registry.service';\nimport { ValidationMessagesService } from '../services/validation-messages.service';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-dropdown-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div\n class=\"ngx-field ngx-field--dropdown\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\"\n [class.ngx-field--readonly]=\"readonly\"\n [class.ngx-field--masked]=\"masked\"\n [class.ngx-field--invalid]=\"control && control.invalid && control.touched\"\n >\n <label class=\"ngx-field__label\" [attr.for]=\"field.id\">\n {{ label }}\n @if (field.validators?.required) { <span class=\"ngx-field__req\">*</span> }\n </label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ getLabel(control.value) }}</span>\n } @else {\n <select\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [compareWith]=\"compareFn\"\n [attr.disabled]=\"field.disabled ? true : null\"\n [attr.aria-invalid]=\"control.invalid && control.touched\"\n [attr.aria-describedby]=\"errorMessage ? field.id + '-error' : null\"\n >\n <option [value]=\"''\">{{ placeholder || 'Select...' }}</option>\n @for (option of options(); track getOptLabel(option)) {\n @if (isObjectVal(option)) {\n <option [ngValue]=\"getOptStoredVal(option)\">{{ getOptLabel(option) }}</option>\n } @else {\n <option [value]=\"getOptStoredVal(option)\">{{ getOptLabel(option) }}</option>\n }\n }\n </select>\n @if (errorMessage) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\" [id]=\"field.id + '-error'\" role=\"alert\">{{ errorMessage }}</span>\n }\n }\n </div>\n `,\n})\nexport class DropdownFieldComponent {\n private readonly lookups = inject(LookupRegistryService);\n private readonly messages = inject(ValidationMessagesService);\n\n private _field!: NestedFieldConfig;\n private _language = 'en';\n\n /** Setter-based so options resolve however the input is set — see `refreshChoiceOptions`. */\n @Input() set field(value: NestedFieldConfig) {\n this._field = value;\n refreshChoiceOptions(this, this.lookups);\n }\n get field(): NestedFieldConfig {\n return this._field;\n }\n\n @Input() set language(value: string) {\n this._language = value || 'en';\n refreshChoiceOptions(this, this.lookups);\n }\n get language(): string {\n return this._language;\n }\n\n @Input() control!: AbstractControl;\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Inline `options`, or the field's named list resolved through the registry (§6.3). */\n readonly options = signal<DropdownOption[]>([]);\n\n readonly compareFn = (o1: unknown, o2: unknown): boolean => valuesMatch(o1, o2, this.language);\n\n isObjectVal(option: DropdownOption): boolean {\n const val = getOptionStoredValue(option);\n return typeof val === 'object' && val !== null;\n }\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n getOptStoredVal(option: DropdownOption): unknown {\n return getOptionStoredValue(option);\n }\n\n getOptLabel(option: DropdownOption): string {\n return resolveOptionLabel(option, this.language);\n }\n\n /**\n * Read-only display. Never awaits (§6.2): a warm list resolves the label, a cold one falls\n * back to the stored text — which under the §2 contract *is* the display value, so it is\n * never wrong, only unlocalised.\n */\n getLabel(value: unknown): string {\n if (value == null || value === '') return '—';\n const option = this.options().find(o => valuesMatch(getOptionStoredValue(o), value, this.language));\n if (option) return this.getOptLabel(option);\n const cached = this.lookups.labelFor(this.field?.listName, value, this.language);\n if (cached) return cached;\n return typeof value === 'object' ? resolveLabel(value as Record<string, string>, this.language) : String(value ?? '—');\n }\n\n get errorMessage(): string {\n if (!this.control || !this.control.errors || !this.control.touched) return '';\n // `requiredSelection` rather than `required`: \"Please select an option\" reads better on a\n // dropdown than \"This field is required\", and both stay independently overridable.\n return this.messages.resolve(\n this.control.errors,\n this.language,\n [['required', 'requiredSelection']],\n 'invalidSelection',\n );\n }\n}\n","import { Component, Input, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { DropdownOption, NestedFieldConfig } from '@dynamic-entity/core';\nimport {\n getOptionStoredValue,\n resolveLabel,\n resolveOptionLabel,\n resolveOptionValue,\n valuesMatch,\n} from '@dynamic-entity/core';\nimport { LookupRegistryService, refreshChoiceOptions } from '../services/lookup-registry.service';\n\n/** Radio field: a group of radio buttons built from field.options. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-radio-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--radio\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <fieldset class=\"ngx-field__fieldset\">\n <legend class=\"ngx-field__label\">{{ label }}</legend>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ getSelectedLabel() }}</span>\n } @else {\n <div class=\"ngx-field__radio-group\">\n @for (option of options(); track getOptLabel(option)) {\n <label class=\"ngx-field__radio-option\" [attr.for]=\"getRadioId(option)\">\n <input\n [id]=\"getRadioId(option)\"\n type=\"radio\"\n class=\"ngx-field__radio-input\"\n [formControl]=\"$any(control)\"\n [value]=\"getOptStoredVal(option)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n />\n <span class=\"ngx-field__radio-label\">{{ getOptLabel(option) }}</span>\n </label>\n }\n </div>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </fieldset>\n </div>\n `,\n})\nexport class RadioFieldComponent {\n private readonly lookups = inject(LookupRegistryService);\n\n private _field!: NestedFieldConfig;\n private _language = 'en';\n\n /** Setter-based so options resolve however the input is set — see `refreshChoiceOptions`. */\n @Input() set field(value: NestedFieldConfig) {\n this._field = value;\n refreshChoiceOptions(this, this.lookups);\n }\n get field(): NestedFieldConfig {\n return this._field;\n }\n\n @Input() set language(value: string) {\n this._language = value || 'en';\n refreshChoiceOptions(this, this.lookups);\n }\n get language(): string {\n return this._language;\n }\n\n @Input() control!: AbstractControl;\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Inline `options`, or the field's named list resolved through the registry (§6.3). */\n readonly options = signal<DropdownOption[]>([]);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n getOptStoredVal(option: DropdownOption): unknown {\n return getOptionStoredValue(option);\n }\n\n /**\n * Stable DOM id for one radio, so the <label for> association works.\n * Slugified because the option text is the value now — \"On Leave\" must not put a space\n * into an id attribute.\n */\n getRadioId(option: DropdownOption): string {\n // `??` cannot fire here: `resolveOptionValue` returns '' for an empty option, not null,\n // so every valueless option produced the same id — and duplicate ids break the `for`\n // that ties each label to its input.\n const raw = String(this.getOptVal(option) ?? '').trim();\n const text = raw || 'opt';\n return `${this.field.id}-${text.trim().replace(/\\s+/g, '_').toLowerCase()}`;\n }\n\n getOptVal(option: DropdownOption): string | number | boolean {\n return resolveOptionValue(option, this.language);\n }\n\n getOptLabel(option: DropdownOption): string {\n return resolveOptionLabel(option, this.language);\n }\n\n /** Read-only display — synchronous, per §6.2. See `DropdownFieldComponent.getLabel`. */\n getSelectedLabel(): string {\n const value = this.control?.value;\n // `typeof null === 'object'`, so without this guard an empty value fell through to\n // `resolveLabel(null)` and rendered as blank — dropdown and multiSelect both show an em dash.\n if (value === null || value === undefined || value === '') return '—';\n const selected = this.options().find(o => valuesMatch(getOptionStoredValue(o), value, this.language));\n if (selected) return this.getOptLabel(selected);\n const cached = this.lookups.labelFor(this.field?.listName, value, this.language);\n if (cached) return cached;\n return typeof value === 'object' ? resolveLabel(value as Record<string, string>, this.language) : String(value ?? '—');\n }\n}\n","import { Component, Input, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { DropdownOption, NestedFieldConfig } from '@dynamic-entity/core';\nimport {\n getOptionStoredValue,\n resolveLabel,\n resolveOptionLabel,\n valuesMatch,\n} from '@dynamic-entity/core';\nimport { LookupRegistryService, refreshChoiceOptions } from '../services/lookup-registry.service';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-multi-select-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--multiSelect\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ getLabels(control.value) }}</span>\n } @else {\n <select\n [id]=\"field.id\"\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [formControl]=\"$any(control)\"\n [compareWith]=\"compareFn\"\n [attr.disabled]=\"field.disabled ? true : null\"\n multiple\n size=\"4\"\n >\n @for (option of options(); track getOptLabel(option)) {\n @if (isObjectVal(option)) {\n <option [ngValue]=\"getOptStoredVal(option)\">{{ getOptLabel(option) }}</option>\n } @else {\n <option [value]=\"getOptStoredVal(option)\">{{ getOptLabel(option) }}</option>\n }\n }\n </select>\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class MultiSelectFieldComponent {\n private readonly lookups = inject(LookupRegistryService);\n\n private _field!: NestedFieldConfig;\n private _language = 'en';\n\n /** Setter-based so options resolve however the input is set — see `refreshChoiceOptions`. */\n @Input() set field(value: NestedFieldConfig) {\n this._field = value;\n refreshChoiceOptions(this, this.lookups);\n }\n get field(): NestedFieldConfig {\n return this._field;\n }\n\n @Input() set language(value: string) {\n this._language = value || 'en';\n refreshChoiceOptions(this, this.lookups);\n }\n get language(): string {\n return this._language;\n }\n\n @Input() control!: AbstractControl;\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n /** Inline `options`, or the field's named list resolved through the registry (§6.3). */\n readonly options = signal<DropdownOption[]>([]);\n\n readonly compareFn = (o1: unknown, o2: unknown): boolean => valuesMatch(o1, o2, this.language);\n\n isObjectVal(option: DropdownOption): boolean {\n const val = getOptionStoredValue(option);\n return typeof val === 'object' && val !== null;\n }\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n getOptStoredVal(option: DropdownOption): unknown {\n return getOptionStoredValue(option);\n }\n\n getOptLabel(option: DropdownOption): string {\n return resolveOptionLabel(option, this.language);\n }\n\n /** Read-only display — synchronous, per §6.2. See `DropdownFieldComponent.getLabel`. */\n getLabels(values: unknown): string {\n if (!Array.isArray(values) || !values.length) return '—';\n return values\n .map(v => {\n const opt = this.options().find(o => valuesMatch(getOptionStoredValue(o), v, this.language));\n if (opt) return this.getOptLabel(opt);\n const cached = this.lookups.labelFor(this.field?.listName, v, this.language);\n if (cached) return cached;\n return typeof v === 'object' && v !== null ? resolveLabel(v as Record<string, string>, this.language) : String(v);\n })\n .join(', ');\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type { EntityReferenceLoader } from '@dynamic-entity/core';\nimport { ENTITY_REF_REGISTRY } from '../tokens/injection-tokens';\n\n/**\n * EntityRefRegistryService — resolves entity-ref option loader functions.\n * Entity-ref options come ONLY from this registry.\n * Never pass loaders via @Input() on field components.\n *\n * Consumers register loaders via provideNgxDynamicEntity({ entityRefs: { clients: () => [...] } }).\n * EntityRefFieldComponent injects this service and calls resolve(field.component ?? field.id).\n */\n@Injectable({ providedIn: 'root' })\nexport class EntityRefRegistryService {\n private readonly registry =\n inject(ENTITY_REF_REGISTRY, { optional: true }) ?? new Map<string, EntityReferenceLoader>();\n\n /**\n * Get the option loader for an entity key.\n * @returns The loader, or null if none is registered.\n */\n resolve(entityKey: string): EntityReferenceLoader | null {\n return this.registry.get(entityKey) ?? null;\n }\n\n has(entityKey: string): boolean {\n return this.registry.has(entityKey);\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type {\n EntityReferenceLoader,\n RawReferenceItem,\n ReferenceLoaderContext,\n ReferenceLoaderResult,\n ReferenceOption,\n Subscribable,\n} from '@dynamic-entity/core';\nimport {\n buildReferenceCacheKey,\n entityKeyFromCacheKey,\n normalizeReferenceOptions,\n resolveLabel,\n valuesMatch,\n} from '@dynamic-entity/core';\nimport { ENTITY_REF_CACHE_STORE } from '../tokens/injection-tokens';\nimport { EntityRefRegistryService } from './entity-ref-registry.service';\n\n/** Label-cache field separator. Kept out of template literals so it stays visible in source. */\nconst LABEL_SEP = '|';\n\n/**\n * EntityReferenceService — the cache in front of consumer-registered option loaders.\n *\n * Three layers, matching the reference implementation:\n * 1. **options** — resolved `ReferenceOption[]` per (entity, lang, displayFields, filters).\n * 2. **in-flight** — the pending Promise, so N fields referencing one entity trigger one\n * load rather than N. This is the layer that actually removes duplicate HTTP calls;\n * an options cache alone does nothing for concurrent first loads.\n * 3. **labels** — synchronous value → text, for rendering a stored reference without\n * waiting on a load.\n *\n * Invalidation is per entity, not global. The reference could only `clearCache()` everything\n * (issue #16), so saving one record re-fetched every entity's options.\n */\n@Injectable({ providedIn: 'root' })\nexport class EntityReferenceService {\n private readonly registry = inject(EntityRefRegistryService);\n private readonly store = inject(ENTITY_REF_CACHE_STORE);\n\n /** Loads in progress, keyed the same way as the options cache. */\n private readonly inFlight = new Map<string, Promise<ReferenceOption[]>>();\n /** `entityKey|lang|canonicalValue` -> display text. */\n private readonly labels = new Map<string, string>();\n\n /**\n * Options for an entity, from cache when present.\n * Concurrent callers with the same key share one load.\n */\n async load(entityKey: string, ctx: ReferenceLoaderContext = {}): Promise<ReferenceOption[]> {\n const key = buildReferenceCacheKey(entityKey, {\n lang: ctx.lang,\n filters: ctx.filters,\n displayFields: ctx.displayFields,\n parentValue: ctx.parentValue,\n });\n\n const cached = this.store.get(key);\n if (cached) return cached;\n\n const pending = this.inFlight.get(key);\n if (pending) return pending;\n\n const loader = this.registry.resolve(entityKey);\n if (!loader) return [];\n\n const load = this.invoke(loader, ctx)\n .then(raw => {\n // displayFields drive label building, which is why they are part of the cache key.\n const options = normalizeReferenceOptions(\n raw as RawReferenceItem[],\n ctx.displayFields ? { enabled: true, displayFields: ctx.displayFields } : undefined,\n ctx.lang ?? 'en',\n );\n this.store.set(key, options);\n this.rememberLabels(entityKey, ctx.lang ?? 'en', options);\n return options;\n });\n\n // A failed load resolves to [] for the caller but is never written to the store, so a\n // transient error is retried on the next call instead of poisoning the cache. Only the\n // `.then` above caches, and a rejection skips it.\n const guarded = load\n .catch(() => [] as ReferenceOption[])\n .finally(() => this.inFlight.delete(key));\n\n this.inFlight.set(key, guarded);\n return guarded;\n }\n\n /** Cached options without triggering a load. `undefined` when not cached. */\n peek(entityKey: string, ctx: ReferenceLoaderContext = {}): ReferenceOption[] | undefined {\n return this.store.get(\n buildReferenceCacheKey(entityKey, {\n lang: ctx.lang,\n filters: ctx.filters,\n displayFields: ctx.displayFields,\n parentValue: ctx.parentValue,\n }),\n );\n }\n\n /**\n * Display text for a stored reference value, synchronously.\n * Returns `undefined` when the entity's options have never been loaded.\n */\n labelFor(entityKey: string, value: unknown, lang = 'en'): string | undefined {\n return this.labels.get(this.labelKey(entityKey, lang, value));\n }\n\n /** Drop everything cached for one entity, leaving other entities intact. */\n invalidate(entityKey: string): void {\n for (const key of this.store.keys()) {\n if (entityKeyFromCacheKey(key) === entityKey) this.store.delete(key);\n }\n for (const key of [...this.inFlight.keys()]) {\n if (entityKeyFromCacheKey(key) === entityKey) this.inFlight.delete(key);\n }\n const prefix = `${entityKey}${LABEL_SEP}`;\n for (const key of [...this.labels.keys()]) {\n if (key.startsWith(prefix)) this.labels.delete(key);\n }\n }\n\n clear(): void {\n this.store.clear();\n this.inFlight.clear();\n this.labels.clear();\n }\n\n private rememberLabels(entityKey: string, lang: string, options: ReferenceOption[]): void {\n for (const option of options) {\n this.labels.set(this.labelKey(entityKey, lang, option.value), option.label);\n }\n }\n\n /** Label-cache key. An object value collapses to its resolved text for the active language. */\n private labelKey(entityKey: string, lang: string, value: unknown): string {\n const canonical =\n value !== null && typeof value === 'object'\n ? resolveLabel(value as Record<string, string>, lang)\n : String(value ?? '');\n return [entityKey, lang, canonical].join(LABEL_SEP);\n }\n\n // ─── Loader result coercion (array | Promise | Observable) ──────────────────\n\n private invoke(\n loader: EntityReferenceLoader,\n ctx: ReferenceLoaderContext,\n ): Promise<ReferenceOption[]> {\n let result: ReferenceLoaderResult;\n try {\n result = loader(ctx);\n } catch (err) {\n // Reject rather than resolve empty: `load` must be able to tell failure from\n // \"no matches\", or it would cache the failure.\n return Promise.reject(err);\n }\n return this.toPromise(result);\n }\n\n private toPromise(result: ReferenceLoaderResult): Promise<ReferenceOption[]> {\n if (Array.isArray(result)) return Promise.resolve(result);\n if (this.isSubscribable(result)) {\n // First emission wins, so an Observable that stays open still resolves the load.\n return new Promise<ReferenceOption[]>((resolve, reject) => {\n let settled = false;\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n fn();\n };\n result.subscribe({\n next: value => settle(() => resolve(value ?? [])),\n // An erroring stream is a failed load, not an empty one — see `invoke`.\n error: err => settle(() => reject(err)),\n // Completing without emitting is a legitimate empty result, and is cached.\n complete: () => settle(() => resolve([])),\n });\n });\n }\n return Promise.resolve(result as Promise<ReferenceOption[]>);\n }\n\n private isSubscribable(value: unknown): value is Subscribable<ReferenceOption[]> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Subscribable<ReferenceOption[]>).subscribe === 'function'\n );\n }\n\n /** Exposed for cascade filtering, which matches a parent value against option values. */\n matches(a: unknown, b: unknown, lang = 'en'): boolean {\n return valuesMatch(a, b, lang);\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type {\n EntityFormConfig,\n NestedFieldConfig,\n NestedTabConfig,\n ReferenceLoaderContext,\n ReferenceOption,\n} from '@dynamic-entity/core';\nimport { applyCascadeFilter } from '@dynamic-entity/core';\nimport { EntityRefRegistryService } from './entity-ref-registry.service';\nimport { EntityReferenceService } from './entity-reference.service';\n\n/**\n * CascadeDataService — loads entity-reference options and applies parent→child cascades.\n *\n * Loaders come from the registry only. This service owns the three things a\n * field component should not: resolving the loader, coercing whatever it returned\n * (array | Promise | Observable) into a Promise, and filtering by the parent's value.\n */\n@Injectable({ providedIn: 'root' })\nexport class CascadeDataService {\n private readonly registry = inject(EntityRefRegistryService);\n private readonly references = inject(EntityReferenceService);\n\n /** Preload runs by formConfigId, so a second call joins the first rather than re-fetching. */\n private readonly preloads = new Map<string, Promise<void>>();\n\n /** Registry key for a field: explicit `linkedEntityKey`, else the field id. */\n entityKeyFor(field: NestedFieldConfig): string {\n return field.entityReference?.linkedEntityKey ?? field.id;\n }\n\n /** Whether a loader is registered for this field. */\n canLoad(field: NestedFieldConfig): boolean {\n return this.registry.has(this.entityKeyFor(field));\n }\n\n /**\n * Load the options for a field, cascade-filtered against `parentValue`.\n * Returns `[]` when no loader is registered, or when a cascade child has no parent value yet.\n */\n async load(\n field: NestedFieldConfig,\n ctx: ReferenceLoaderContext = {},\n ): Promise<ReferenceOption[]> {\n const cfg = field.entityReference;\n if (!this.canLoad(field)) return [];\n\n // A cascade child with no parent selection must offer nothing.\n const hasParentValue =\n ctx.parentValue !== null && ctx.parentValue !== undefined && ctx.parentValue !== '';\n if (cfg?.parentField && !hasParentValue) return [];\n\n const lang = ctx.lang ?? 'en';\n\n // When the cascade can be resolved locally (`lookupFilter`/`lookupPath`), fetch the\n // unfiltered set once and filter per parent below — switching parent then costs nothing.\n // Otherwise the loader is the only thing that can narrow the list, so `parentValue` is\n // passed through and becomes part of the cache identity (one entry per parent).\n const filtersLocally = !!(cfg?.lookupFilter || cfg?.lookupPath);\n\n const options = await this.references.load(this.entityKeyFor(field), {\n ...ctx,\n parentValue: filtersLocally ? undefined : ctx.parentValue,\n filters: { ...(cfg?.filters ?? {}), ...(ctx.filters ?? {}) },\n displayFields: cfg?.displayFields,\n lang,\n });\n\n return applyCascadeFilter(options, ctx.parentValue, cfg, lang);\n }\n\n // ─── Preload ────────────────────────────────────────────────────────────────\n\n /**\n * Warm the cache for every entity a config's cascades depend on, so changing a parent\n * resolves from memory instead of a round-trip.\n *\n * Idempotent per `formConfigId`: calling it again returns the in-flight or completed run\n * rather than re-fetching.\n */\n initializeCascadeData(formConfigId: string, config: EntityFormConfig, lang = 'en'): Promise<void> {\n const existing = this.preloads.get(formConfigId);\n if (existing) return existing;\n\n const fields = this.cascadeFields(config);\n const run = Promise.all(\n fields.map(field =>\n this.references.load(this.entityKeyFor(field), {\n filters: field.entityReference?.filters,\n displayFields: field.entityReference?.displayFields,\n lang,\n }),\n ),\n ).then(() => undefined);\n\n this.preloads.set(formConfigId, run);\n return run;\n }\n\n /** Resolves true once `initializeCascadeData` for this config has finished. */\n async waitForData(formConfigId: string): Promise<boolean> {\n const run = this.preloads.get(formConfigId);\n if (!run) return false;\n await run;\n return true;\n }\n\n /**\n * Child options for a parent selection, from cache only — no load is triggered.\n * Returns `[]` when the entity has not been preloaded.\n */\n getCachedChildOptions(\n field: NestedFieldConfig,\n parentValue: unknown,\n lang = 'en',\n ): ReferenceOption[] {\n const cfg = field.entityReference;\n const cached = this.references.peek(this.entityKeyFor(field), {\n filters: cfg?.filters,\n displayFields: cfg?.displayFields,\n lang,\n });\n if (!cached) return [];\n return applyCascadeFilter(cached, parentValue, cfg, lang);\n }\n\n /** Forget the preload for one config. The option cache itself is untouched. */\n clearCache(formConfigId: string): void {\n this.preloads.delete(formConfigId);\n }\n\n /** Every entity-ref field in the config that participates in a cascade. */\n private cascadeFields(config: EntityFormConfig): NestedFieldConfig[] {\n const found: NestedFieldConfig[] = [];\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const field of fields ?? []) {\n const cfg = field.entityReference;\n if (cfg?.enabled && (cfg.parentField || cfg.lookupPath || cfg.lookupFilter)) {\n found.push(field);\n }\n walkFields(field.children);\n }\n };\n const walkTabs = (tabs: NestedTabConfig[] | undefined) => {\n for (const tab of tabs ?? []) {\n walkFields(tab.fields);\n walkTabs(tab.children);\n }\n };\n walkTabs(config?.tabs);\n return found;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport type { ReferenceOption } from '@dynamic-entity/core';\n\nexport interface EntityRefSelection {\n fieldId: string;\n /** The chosen option, or `null` when the selection was cleared. */\n option: ReferenceOption | null;\n}\n\n/**\n * EntityRefSelectionService — the channel an entity-ref field uses to publish *which record*\n * the user picked, so the owning form can run `autoPatch` against it.\n *\n * The control value alone is not enough: `autoPatch` copies fields out of the selected\n * record, which only the field component has after loading its options.\n *\n * Provided at `DynamicFormComponent` level so each form instance gets its own channel;\n * the `root` fallback keeps standalone field components injectable in isolation.\n */\n@Injectable({ providedIn: 'root' })\nexport class EntityRefSelectionService {\n private readonly subject = new Subject<EntityRefSelection>();\n\n readonly selection$ = this.subject.asObservable();\n\n emit(fieldId: string, option: ReferenceOption | null): void {\n this.subject.next({ fieldId, option });\n }\n}\n","import { Component, DestroyRef, Input, OnInit, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { AbstractControl, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig, ReferenceOption } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { CascadeDataService } from '../services/cascade-data.service';\nimport { EntityRefSelectionService } from '../services/entity-ref-selection.service';\n\n/**\n * EntityRefFieldComponent — a select populated from a consumer-registered loader.\n *\n * Cascades: when `entityReference.parentField` is set, the component watches that sibling\n * control (via `control.parent`) and reloads its own options on every parent change,\n * clearing a now-invalid selection. It publishes the picked record on\n * `EntityRefSelectionService` so the owning form can run `autoPatch`.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-ref-field',\n standalone: true,\n imports: [ReactiveFormsModule],\n template: `\n <div class=\"ngx-field ngx-field--entity-ref\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"'field-' + field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">{{ getLabel(control.value) }}</span>\n } @else {\n @if (loading()) {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-loading'\" role=\"status\">Loading…</span>\n } @else {\n <select\n class=\"ngx-field__input\" [attr.data-testid]=\"'field-' + field.id + '-input'\"\n [id]=\"'field-' + field.id\"\n [formControl]=\"$any(control)\"\n [attr.disabled]=\"field.disabled ? true : null\"\n >\n <option value=\"\">{{ placeholder || 'Select...' }}</option>\n @for (option of options(); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n @if (awaitingParent()) {\n <span class=\"ngx-field__hint\" [attr.data-testid]=\"'field-' + field.id + '-hint'\">Select {{ parentFieldId }} first.</span>\n }\n }\n @if (control.invalid && control.touched) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">This field has an error</span>\n }\n }\n </div>\n `,\n})\nexport class EntityRefFieldComponent implements OnInit {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n private readonly cascade = inject(CascadeDataService);\n private readonly selectionBus = inject(EntityRefSelectionService);\n private readonly destroyRef = inject(DestroyRef);\n\n readonly options = signal<ReferenceOption[]>([]);\n readonly loading = signal(false);\n /** True when this field cascades but its parent has no value yet. */\n readonly awaitingParent = signal(false);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get placeholder(): string {\n return resolveLabel(this.field?.placeholder, this.language);\n }\n\n get parentFieldId(): string | undefined {\n return this.field?.entityReference?.parentField;\n }\n\n ngOnInit(): void {\n if (this.masked) return;\n void this.reload();\n this.watchParent();\n this.control?.valueChanges\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(value => this.publishSelection(String(value ?? '')));\n }\n\n /** Reload options against the parent's current value. */\n async reload(): Promise<void> {\n const parentValue = this.parentValue();\n this.awaitingParent.set(\n !!this.parentFieldId && (parentValue === null || parentValue === undefined || parentValue === ''),\n );\n\n if (!this.cascade.canLoad(this.field)) {\n this.options.set([]);\n return;\n }\n\n this.loading.set(true);\n try {\n this.options.set(\n await this.cascade.load(this.field, { parentValue, lang: this.language }),\n );\n } finally {\n this.loading.set(false);\n }\n }\n\n /**\n * Publish the selected option so autoPatch can copy from its record.\n *\n * Driven from `valueChanges` rather than the select's `change` event: that event is the\n * same one the `formControl` directive listens to, so reading the control inside a\n * template `(change)` handler can see the previous value. `valueChanges` fires after the\n * model has updated — including Playwright `selectOption`, which updates the control\n * through the value accessor.\n */\n onSelectionChange(value?: string): void {\n this.publishSelection(value ?? String(this.control?.value ?? ''));\n }\n\n private publishSelection(current: string): void {\n const selected = this.options().find(o => String(o.value) === current);\n this.selectionBus.emit(this.field.id, selected ?? null);\n }\n\n getLabel(value: any): string {\n const option = this.options().find(o => String(o.value) === String(value));\n return option?.label ?? (value ?? '—');\n }\n\n private parentValue(): unknown {\n const parentId = this.parentFieldId;\n if (!parentId) return undefined;\n return this.control?.parent?.get(parentId)?.value;\n }\n\n /** Reload (and drop a stale selection) whenever the parent control changes. */\n private watchParent(): void {\n const parentId = this.parentFieldId;\n if (!parentId) return;\n const parentControl = this.control?.parent?.get(parentId);\n if (!parentControl) return;\n\n parentControl.valueChanges\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n if (this.control.value) {\n this.control.setValue('', { emitEvent: false });\n this.selectionBus.emit(this.field.id, null);\n }\n void this.reload();\n });\n }\n}\n","import { Injectable, Type, inject } from '@angular/core';\nimport { FIELD_TYPE_REGISTRY, FIELD_TYPE_SETS } from '../tokens/injection-tokens';\n\n/**\n * FieldRegistryService — resolves field type strings to Angular component classes.\n *\n * **Tree-shaking contract:** this service holds *no* static imports of field components.\n * Nothing is bundled until something registers it, which is what makes the built-ins\n * opt-in. Register them with `provideBuiltInFieldTypes()` (all 19 keys) or a narrower\n * subset via `provideFieldTypes({ ... })` — see `providers/provide-field-types.ts`.\n *\n * Resolution order: consumer token registry → runtime registrations → nothing.\n */\n@Injectable({ providedIn: 'root' })\nexport class FieldRegistryService {\n private readonly consumerRegistry =\n inject(FIELD_TYPE_REGISTRY, { optional: true }) ?? new Map<string, Type<any>>();\n private readonly dynamicRegistry = new Map<string, Type<any>>();\n\n constructor() {\n // Sets contributed by provideFieldTypes()/provideBuiltInFieldTypes(), in declaration order.\n for (const set of inject(FIELD_TYPE_SETS, { optional: true }) ?? []) {\n this.registerAll(set);\n }\n }\n\n /** Register a field type component mapping at runtime. */\n register(type: string, component: Type<any>): void {\n this.dynamicRegistry.set(type, component);\n }\n\n /** Register multiple field type component mappings at runtime. */\n registerAll(map: Record<string, Type<any>>): void {\n for (const [type, comp] of Object.entries(map)) {\n this.dynamicRegistry.set(type, comp);\n }\n }\n\n /**\n * Resolve a field type string to a component class.\n * Consumer token registry takes priority over runtime registrations.\n */\n resolve(fieldType: string): Type<any> | null {\n return this.consumerRegistry.get(fieldType) ?? this.dynamicRegistry.get(fieldType) ?? null;\n }\n\n /** Check if a field type has a registered component. */\n has(fieldType: string): boolean {\n return this.consumerRegistry.has(fieldType) || this.dynamicRegistry.has(fieldType);\n }\n\n /** Every registered field type key. Consumer overrides and runtime registrations combined. */\n registeredTypes(): string[] {\n return [...new Set([...this.dynamicRegistry.keys(), ...this.consumerRegistry.keys()])].sort();\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type { EntityFormConfig, NestedFieldConfig, NestedTabConfig } from '@dynamic-entity/core';\nimport { shouldMaskField as coreShouldMaskField, resolveEffectiveMask as coreResolveEffectiveMask } from '@dynamic-entity/core';\nimport { MASKED_ROLES } from '../tokens/injection-tokens';\n\n/**\n * RbacService — ALL permission checks and masking logic live here.\n */\n@Injectable({ providedIn: 'root' })\nexport class RbacService {\n private readonly maskedRoles = inject(MASKED_ROLES, { optional: true }) ?? [];\n\n /**\n * Check if any of the user's roles satisfy the required roles.\n * hasPermission(roles, undefined) → true (no restriction).\n */\n hasPermission(userRoles: string[], requiredRoles?: string[]): boolean {\n if (!requiredRoles?.length) return true;\n return userRoles.some(r => requiredRoles.includes(r));\n }\n\n /** 3-level OR resolution */\n resolveEffectiveMask(formMask?: boolean, tabMask?: boolean, fieldMask?: boolean): boolean {\n return coreResolveEffectiveMask(formMask, tabMask, fieldMask);\n }\n\n /** Check if the user's roles include any masked role */\n isUserMaskedRole(userRoles: string[]): boolean {\n return this.maskedRoles.some(r => userRoles.includes(r));\n }\n\n /** Determine if a specific field should be masked for this user */\n shouldMaskField(field: NestedFieldConfig, tab: NestedTabConfig | undefined, config: EntityFormConfig, userRoles: string[]): boolean {\n return coreShouldMaskField(field, tab, config, userRoles, this.maskedRoles);\n }\n\n /** Get view/edit/delete permissions for a config */\n getPermissions(config: EntityFormConfig, userRoles: string[]) {\n return {\n canView: this.hasPermission(userRoles, config.permissions?.view),\n canEdit: this.hasPermission(userRoles, config.permissions?.edit),\n canDelete: this.hasPermission(userRoles, config.permissions?.delete),\n };\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ComponentRef,\n Injector,\n Input,\n OnChanges, OnDestroy,\n SimpleChanges,\n ViewChild,\n ViewContainerRef,\n inject,\n isDevMode,\n} from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport type { NestedFieldConfig, EntityFormConfig, NestedTabConfig } from '@dynamic-entity/core';\nimport { findTab } from '@dynamic-entity/core';\nimport { FieldRegistryService } from '../../services/field-registry.service';\nimport { RbacService } from '../../services/rbac.service';\n\n/**\n * DynamicFieldComponent — mounts the correct field component for a given NestedFieldConfig.\n * Uses ViewContainerRef.createComponent() and passes inputs via setInput(); see\n * DynamicFieldComponentContract for the five inputs every field component receives.\n * Never add field-type-specific logic here — this component must remain generic.\n *\n * The 5 inputs (field, control, language, readonly, masked) are passed to every mounted\n * component uniformly — no special-casing per type.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-dynamic-field',\n standalone: true,\n template: `<ng-container #fieldHost></ng-container>`,\n})\nexport class DynamicFieldComponent implements OnChanges, OnDestroy {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() config!: EntityFormConfig;\n @Input() currentTabId?: string;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() userRoles: string[] = [];\n\n @ViewChild('fieldHost', { read: ViewContainerRef, static: true })\n private readonly fieldHost!: ViewContainerRef;\n\n private readonly fieldRegistry = inject(FieldRegistryService);\n private readonly rbacService = inject(RbacService);\n /**\n * Passed into `createComponent` so a hosted field sees this host's injector — including\n * `DynamicFormComponent`'s scoped `EntityRefSelectionService`. Without it, a standalone\n * field resolves the root bus and `autoPatch` never runs.\n */\n private readonly injector = inject(Injector);\n\n private componentRef: ComponentRef<unknown> | null = null;\n\n ngOnChanges(_changes: SimpleChanges): void {\n this.mountField();\n }\n\n private mountField(): void {\n if (!this.field || !this.control) return;\n\n const ComponentClass = this.fieldRegistry.resolve(this.field.type);\n if (!ComponentClass) {\n this.warnUnresolved(this.field.type);\n return; // Unknown field type — render nothing\n }\n\n // Determine masking for this specific field\n const tab: NestedTabConfig | null = this.currentTabId ? findTab(this.config?.tabs, this.currentTabId) : null;\n const masked = this.rbacService.shouldMaskField(this.field, tab ?? undefined, this.config, this.userRoles);\n\n // Re-use existing component if same type, otherwise recreate\n if (this.componentRef && this.componentRef.instance instanceof ComponentClass) {\n this.setInputs(this.componentRef, masked);\n return;\n }\n\n this.fieldHost.clear();\n this.componentRef = this.fieldHost.createComponent(ComponentClass, {\n injector: this.injector,\n });\n this.setInputs(this.componentRef, masked);\n this.watchControl();\n this.componentRef.changeDetectorRef.detectChanges();\n }\n\n /**\n * Field types are opt-in (see `provideFieldTypes` / `provideBuiltInFieldTypes`), so an\n * unregistered type renders nothing. Say so once per type in dev builds rather than\n * leaving a silently blank slot.\n */\n private warnUnresolved(type: string): void {\n if (!isDevMode() || DynamicFieldComponent.warnedTypes.has(type)) return;\n DynamicFieldComponent.warnedTypes.add(type);\n console.warn(\n `[ngx-dynamic-entity] No component registered for field type \"${type}\" — the field was not rendered. ` +\n `Register it with provideFieldTypes({ '${type}': MyComponent }) or provideBuiltInFieldTypes().`,\n );\n }\n\n private static readonly warnedTypes = new Set<string>();\n\n /**\n * Re-check the hosted field component.\n *\n * The field components are OnPush, so they re-render on an input change, an event from\n * their own template, or a signal they read. `form.markAllAsTouched()` is none of those —\n * it flips `touched` from outside, and every field's error message depends on it. Without\n * this, a blocked submit would mark the form touched and no error would appear.\n */\n refresh(): void {\n this.componentRef?.changeDetectorRef.detectChanges();\n }\n\n /**\n * Re-check the hosted component whenever its control changes from outside.\n *\n * The field components are OnPush, so they re-render on an input change or an event from\n * their own template. A control mutated externally is neither — and that is not an edge\n * case: patchForm, reset, autoPatch and patchOnTrue all do exactly that. Without this, a\n * field patched from a record would keep rendering its previous value.\n *\n * `detectChanges()` rather than `markForCheck()`: a selection that arrives from a native\n * `change` event (or Playwright) may not be followed by another Angular tick, so a dirty\n * flag would never be flushed. Running CD on the hosted component now is the copy showing up.\n *\n * Done here rather than in each of the eighteen field components: the host owns the\n * component reference, so one subscription covers every type including custom ones.\n */\n private watchControl(): void {\n this.controlSub?.unsubscribe();\n if (!this.control) return;\n\n this.controlSub = this.control.valueChanges.subscribe(() => this.refresh());\n }\n\n private controlSub?: Subscription;\n\n ngOnDestroy(): void {\n this.controlSub?.unsubscribe();\n }\n\n /**\n * Pass all 5 contract inputs via ComponentRef.setInput() — uniform for all types.\n * The public shape is DynamicFieldComponentContract.\n * Must use setInput(), not property assignment: the field components declare inputs with\n * definite assignment and no initializer, and the lib compiles with\n * useDefineForClassFields:false, so `'field' in instance` is false until first set.\n */\n private setInputs(ref: ComponentRef<unknown>, masked: boolean): void {\n ref.setInput('field', this.field);\n ref.setInput('control', this.control);\n ref.setInput('language', this.language);\n ref.setInput('readonly', this.readonly || !!this.field.readonly);\n ref.setInput('masked', masked);\n }\n}\n","import { Component, Input, forwardRef, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig, EntityFormConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { DynamicFieldComponent } from '../form/dynamic-field/dynamic-field.component';\n\n/** Renders a nested fieldset container for a group field's children. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-group-field',\n standalone: true,\n imports: [ReactiveFormsModule, forwardRef(() => DynamicFieldComponent)],\n template: `\n <fieldset class=\"ngx-field ngx-field--group\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <legend class=\"ngx-field__legend\">{{ label }}</legend>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else {\n <div class=\"ngx-field__group-children\">\n @for (child of field.children ?? []; track child.id) {\n @if (child.visibility !== false) {\n <ngx-dynamic-field\n [field]=\"child\"\n [control]=\"getChildControl(child.id)\"\n [config]=\"config\"\n [language]=\"language\"\n [readonly]=\"readonly || !!child.readonly\"\n [userRoles]=\"userRoles\"\n />\n }\n }\n </div>\n }\n </fieldset>\n `,\n styles: [\n `\n .ngx-field--group {\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n margin-bottom: 16px;\n background: #fafafa;\n }\n .ngx-field__legend {\n font-weight: 600;\n font-size: 14px;\n padding: 0 8px;\n color: #334155;\n }\n .ngx-field__group-children {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n `,\n ],\n})\nexport class GroupFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() config!: EntityFormConfig;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n @Input() userRoles: string[] = [];\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n getChildControl(childId: string): AbstractControl {\n const group = this.control as FormGroup;\n return group?.get(childId) as AbstractControl;\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { AsyncValidatorFn, ValidatorFn, Validators } from '@angular/forms';\nimport type { FieldValidators } from '@dynamic-entity/core';\nimport { ASYNC_VALIDATOR_REGISTRY, VALIDATOR_REGISTRY } from '../tokens/injection-tokens';\n\n/**\n * ValidatorRegistryService — resolves validator configs / key strings to Angular ValidatorFns.\n */\n@Injectable({ providedIn: 'root' })\nexport class ValidatorRegistryService {\n private readonly consumerRegistry = inject(VALIDATOR_REGISTRY, { optional: true }) ?? new Map();\n private readonly asyncRegistry = inject(ASYNC_VALIDATOR_REGISTRY, { optional: true }) ?? new Map();\n\n /**\n * Resolve a validator key string to a ValidatorFn.\n * Supports parameterized built-ins like 'min:0', 'maxLength:255'.\n */\n resolve(validatorKey: string): ValidatorFn | null {\n if (this.consumerRegistry.has(validatorKey)) {\n return this.consumerRegistry.get(validatorKey);\n }\n\n if (validatorKey === 'required') return Validators.required;\n if (validatorKey === 'email') return Validators.email;\n\n const [name, param] = validatorKey.split(':');\n const value = parseFloat(param);\n\n if (name === 'min' && !isNaN(value)) return Validators.min(value);\n if (name === 'max' && !isNaN(value)) return Validators.max(value);\n if (name === 'minLength' && !isNaN(value)) return Validators.minLength(value);\n if (name === 'maxLength' && !isNaN(value)) return Validators.maxLength(value);\n\n return null;\n }\n\n /** Resolve multiple validator keys into a ValidatorFn[] */\n resolveAll(validatorKeys: string[] = []): ValidatorFn[] {\n return validatorKeys.map(k => this.resolve(k)).filter((v): v is ValidatorFn => v !== null);\n }\n\n /** Resolve a FieldValidators object or string[] into ValidatorFn[] */\n resolveFromConfig(config?: FieldValidators | string[]): ValidatorFn[] {\n if (!config) return [];\n if (Array.isArray(config)) return this.resolveAll(config);\n\n const fnList: ValidatorFn[] = [];\n if (config.required) fnList.push(Validators.required);\n if (config.min !== undefined) fnList.push(Validators.min(config.min));\n if (config.max !== undefined) fnList.push(Validators.max(config.max));\n if (config.minLength !== undefined) fnList.push(Validators.minLength(config.minLength));\n if (config.maxLength !== undefined) fnList.push(Validators.maxLength(config.maxLength));\n if (config.pattern) fnList.push(Validators.pattern(config.pattern));\n if (config.email) fnList.push(Validators.email);\n\n // Named validators from the consumer registry. This branch previously hardcoded the\n // built-ins and consulted the registry only for the `string[]` form of this config, so\n // a validator the consumer had registered could not be named from a typed schema\n // without casting it to `any`.\n for (const key of config.custom ?? []) {\n const fn = this.resolve(key);\n if (fn) fnList.push(fn);\n }\n\n return fnList;\n }\n\n /**\n * Resolve the async validators a field names, in `validators.customAsync`.\n *\n * Async validators are deliberately a separate registry and a separate config key: Angular\n * attaches them through `setAsyncValidators`, runs them only once the synchronous ones\n * pass, and holds the control in `pending` until they settle. Mixing them into the\n * synchronous list would silently never run them.\n *\n * An unknown name is skipped rather than throwing, matching the synchronous behaviour.\n */\n resolveAsyncFromConfig(config?: FieldValidators | string[]): AsyncValidatorFn[] {\n if (!config || Array.isArray(config)) return [];\n\n const out: AsyncValidatorFn[] = [];\n for (const key of config.customAsync ?? []) {\n const fn = this.asyncRegistry.get(key);\n if (fn) out.push(fn);\n }\n return out;\n }\n}\n","import { Component, Input, inject, forwardRef, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';\nimport { AbstractControl, FormArray, FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport type { NestedFieldConfig, EntityFormConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { DynamicFieldComponent } from '../form/dynamic-field/dynamic-field.component';\nimport { ValidatorRegistryService } from '../services/validator-registry.service';\n\n/** Renders repeating rows for a FormArray, with Add Item and Remove. */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-array-field',\n standalone: true,\n imports: [ReactiveFormsModule, forwardRef(() => DynamicFieldComponent)],\n template: `\n <div class=\"ngx-field ngx-field--array\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <div class=\"ngx-field__array-header\">\n <label class=\"ngx-field__label\">{{ label }}</label>\n @if (!readonly && !masked) {\n <button type=\"button\" class=\"ngx-field__array-add-btn\"\n [attr.data-testid]=\"'field-' + field.id + '-add'\" (click)=\"addItem()\">\n + Add Item\n </button>\n }\n </div>\n\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else {\n <div class=\"ngx-field__array-list\">\n @for (itemGroup of formArray.controls; track idx; let idx = $index) {\n <div class=\"ngx-field__array-item\" [attr.data-testid]=\"'field-' + field.id + '-row'\">\n <div class=\"ngx-field__array-item-header\">\n <span class=\"ngx-field__array-item-title\">Item #{{ idx + 1 }}</span>\n @if (!readonly) {\n <button type=\"button\" class=\"ngx-field__array-remove-btn\"\n [attr.data-testid]=\"'field-' + field.id + '-remove-' + idx\" (click)=\"removeItem(idx)\">\n Remove\n </button>\n }\n </div>\n <div class=\"ngx-field__array-item-fields\">\n @for (child of field.children ?? []; track child.id) {\n @if (child.visibility !== false) {\n <ngx-dynamic-field\n [field]=\"child\"\n [control]=\"getItemChildControl(itemGroup, child.id)\"\n [config]=\"config\"\n [language]=\"language\"\n [readonly]=\"readonly || !!child.readonly\"\n [userRoles]=\"userRoles\"\n />\n }\n }\n </div>\n </div>\n }\n @if (formArray.controls.length === 0) {\n <div class=\"ngx-field__array-empty\" [attr.data-testid]=\"'field-' + field.id + '-empty'\">No items added yet.</div>\n }\n </div>\n }\n </div>\n `,\n styles: [\n `\n .ngx-field--array {\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n margin-bottom: 16px;\n background: #f8fafc;\n }\n .ngx-field__array-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n }\n .ngx-field__array-add-btn {\n background: #2563eb;\n color: #fff;\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n font-weight: 500;\n cursor: pointer;\n }\n .ngx-field__array-add-btn:hover {\n background: #1d4ed8;\n }\n .ngx-field__array-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .ngx-field__array-item {\n background: #fff;\n border: 1px solid #cbd5e1;\n border-radius: 6px;\n padding: 12px;\n }\n .ngx-field__array-item-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n border-bottom: 1px solid #f1f5f9;\n padding-bottom: 6px;\n }\n .ngx-field__array-item-title {\n font-weight: 600;\n font-size: 13px;\n color: #475569;\n }\n .ngx-field__array-remove-btn {\n background: #ef4444;\n color: #fff;\n border: none;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n }\n .ngx-field__array-empty {\n color: #94a3b8;\n font-style: italic;\n font-size: 13px;\n }\n `,\n ],\n})\nexport class ArrayFieldComponent {\n /**\n * addItem/removeItem are public and may be called from outside this component's template,\n * which under OnPush would not re-render. The host also watches the control, but this\n * keeps the component correct on its own.\n */\n private readonly cdr = inject(ChangeDetectorRef);\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() config!: EntityFormConfig;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n @Input() userRoles: string[] = [];\n\n private readonly fb = inject(FormBuilder);\n private readonly validatorRegistry = inject(ValidatorRegistryService);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n get formArray(): FormArray {\n return this.control as FormArray;\n }\n\n getItemChildControl(itemGroup: AbstractControl, childId: string): AbstractControl {\n return (itemGroup as FormGroup).get(childId) as AbstractControl;\n }\n\n addItem(): void {\n const controls: Record<string, any> = {};\n for (const child of this.field.children ?? []) {\n const validators = this.validatorRegistry.resolveFromConfig(child.validators);\n controls[child.id] = [child.defaultValue ?? null, validators];\n }\n const group = this.fb.group(controls);\n this.formArray.push(group);\n this.cdr.markForCheck();\n }\n\n removeItem(index: number): void {\n this.formArray.removeAt(index);\n this.cdr.markForCheck();\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport type { FileRef, Subscribable, UploadResult } from '@dynamic-entity/core';\nimport { UPLOAD_HANDLER } from '../tokens/injection-tokens';\n\n/**\n * FileUploadService — the single place image-field and file-field agree on how a\n * selected `File` becomes a `FileRef`.\n *\n * With `UPLOAD_HANDLER` registered the file is persisted and stored as `{ url }`;\n * without one it is stored as `{ file }` for the consumer to upload at submit time.\n */\n@Injectable({ providedIn: 'root' })\nexport class FileUploadService {\n private readonly handler = inject(UPLOAD_HANDLER, { optional: true });\n\n get hasHandler(): boolean {\n return !!this.handler;\n }\n\n /** Metadata common to both persisted and unpersisted refs. */\n private describe(file: File): FileRef {\n return { name: file.name, size: file.size, mimeType: file.type };\n }\n\n /**\n * Turn a selected File into the value to store on the control.\n * @throws when a registered handler rejects — callers surface it as a field error.\n */\n async toFileRef(file: File): Promise<FileRef> {\n const meta = this.describe(file);\n if (!this.handler) return { ...meta, file };\n\n const result = await this.normalize(this.handler(file));\n return { ...meta, url: result.url, name: result.name ?? meta.name };\n }\n\n /** Object URL for previewing an unpersisted File. Callers must revoke it. */\n previewUrlFor(ref: FileRef | null | undefined): string | null {\n if (!ref) return null;\n if (ref.url) return ref.url;\n if (ref.file && typeof URL !== 'undefined' && typeof URL.createObjectURL === 'function') {\n return URL.createObjectURL(ref.file);\n }\n return null;\n }\n\n revokePreviewUrl(url: string | null): void {\n if (!url || !url.startsWith('blob:')) return;\n if (typeof URL !== 'undefined' && typeof URL.revokeObjectURL === 'function') {\n URL.revokeObjectURL(url);\n }\n }\n\n private normalize(\n result: UploadResult | Promise<UploadResult> | Subscribable<UploadResult>,\n ): Promise<UploadResult> {\n if (this.isSubscribable(result)) {\n return new Promise<UploadResult>((resolve, reject) => {\n let settled = false;\n result.subscribe({\n next: value => {\n if (settled) return;\n settled = true;\n resolve(value);\n },\n error: err => {\n if (settled) return;\n settled = true;\n reject(err);\n },\n complete: () => {\n if (settled) return;\n settled = true;\n reject(new Error('Upload handler completed without emitting a result.'));\n },\n });\n });\n }\n return Promise.resolve(result as UploadResult | Promise<UploadResult>);\n }\n\n private isSubscribable(value: unknown): value is Subscribable<UploadResult> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Subscribable<UploadResult>).subscribe === 'function'\n );\n }\n}\n","import { Component, OnDestroy, inject, Input, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport type { FileRef, NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { FileUploadService } from '../services/file-upload.service';\n\n/**\n * Image field: preview thumbnail + upload button.\n *\n * With `UPLOAD_HANDLER` registered the file is persisted and stored as `{ url }`; without one\n * it is stored as `{ file }` and previewed from an object URL (revoked when replaced/destroyed).\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-image-field',\n standalone: true,\n imports: [],\n template: `\n <div class=\"ngx-field ngx-field--image\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"'field-' + field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else {\n <div class=\"ngx-field__image-wrap\">\n @if (previewUrl()) {\n <img class=\"ngx-field__image-preview\" [src]=\"previewUrl()\" [alt]=\"label\" />\n } @else {\n <div class=\"ngx-field__image-placeholder\">\n <span>📷</span>\n <span>No image</span>\n </div>\n }\n @if (!readonly) {\n <div class=\"ngx-field__image-actions\">\n <label class=\"ngx-field__upload-btn\" [class.ngx-field__upload-btn--loading]=\"uploading()\">\n @if (uploading()) {\n <span>Uploading…</span>\n } @else {\n <span>{{ previewUrl() ? 'Change' : 'Upload' }}</span>\n <input\n type=\"file\"\n class=\"ngx-field__file-input\"\n [id]=\"'field-' + field.id\"\n accept=\"image/*\"\n [disabled]=\"field.disabled || uploading()\"\n (change)=\"onFileSelect($any($event.target).files[0])\"\n />\n }\n </label>\n @if (previewUrl()) {\n <button type=\"button\" class=\"ngx-field__remove-btn\" (click)=\"remove()\">Remove</button>\n }\n </div>\n }\n </div>\n @if (uploadError()) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">{{ uploadError() }}</span>\n }\n }\n </div>\n `,\n})\nexport class ImageFieldComponent implements OnDestroy {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n private readonly uploads = inject(FileUploadService);\n\n readonly uploading = signal(false);\n readonly uploadError = signal<string | null>(null);\n\n /** Cached so an object URL is minted once per File, not once per change-detection pass. */\n private previewSource: FileRef | null = null;\n private previewCache: string | null = null;\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n previewUrl(): string | null {\n const value = (this.control?.value as FileRef | null) ?? null;\n if (value === this.previewSource) return this.previewCache;\n\n this.uploads.revokePreviewUrl(this.previewCache);\n this.previewSource = value;\n this.previewCache = this.uploads.previewUrlFor(value);\n return this.previewCache;\n }\n\n async onFileSelect(file: File | undefined): Promise<void> {\n if (!file) return;\n this.uploadError.set(null);\n this.uploading.set(true);\n try {\n this.control.setValue(await this.uploads.toFileRef(file));\n this.control.markAsTouched();\n } catch {\n this.uploadError.set('Upload failed. Please try again.');\n } finally {\n this.uploading.set(false);\n }\n }\n\n remove(): void {\n this.control.setValue(null);\n this.control.markAsTouched();\n }\n\n ngOnDestroy(): void {\n this.uploads.revokePreviewUrl(this.previewCache);\n }\n}\n","import { Component, inject, Input, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport type { FileRef, NestedFieldConfig } from '@dynamic-entity/core';\nimport { fileRefName, resolveLabel } from '@dynamic-entity/core';\nimport { FileUploadService } from '../services/file-upload.service';\n\n/**\n * File field: file input with filename display and download link.\n * Shares the `FileRef` / `UPLOAD_HANDLER` contract with image-field via FileUploadService.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-file-field',\n standalone: true,\n imports: [],\n template: `\n <div class=\"ngx-field ngx-field--file\"\n [attr.data-testid]=\"'field-' + field.id\" [attr.data-field-type]=\"field.type\" [class.ngx-field--readonly]=\"readonly\" [class.ngx-field--masked]=\"masked\">\n <label class=\"ngx-field__label\" [attr.for]=\"'field-' + field.id\">{{ label }}</label>\n @if (masked) {\n <span class=\"ngx-field__value ngx-field__value--masked\" [attr.data-testid]=\"'field-' + field.id + '-masked'\">XXXXXXXXX</span>\n } @else if (readonly) {\n @if (fileUrl()) {\n <a class=\"ngx-field__file-link\" [href]=\"fileUrl()!\" target=\"_blank\" rel=\"noopener\">\n 📎 {{ fileName() || 'Download file' }}\n </a>\n } @else {\n <span class=\"ngx-field__value\" [attr.data-testid]=\"'field-' + field.id + '-value'\">—</span>\n }\n } @else {\n <div class=\"ngx-field__file-wrap\">\n @if (fileName()) {\n <div class=\"ngx-field__file-selected\">\n <span class=\"ngx-field__file-name\">📎 {{ fileName() }}</span>\n <button type=\"button\" class=\"ngx-field__remove-btn\" (click)=\"remove()\" aria-label=\"Remove file\">✕</button>\n </div>\n }\n <label class=\"ngx-field__upload-btn\" [class.ngx-field__upload-btn--loading]=\"uploading()\">\n @if (uploading()) {\n <span>Uploading…</span>\n } @else {\n <span>{{ fileName() ? 'Replace file' : 'Choose file' }}</span>\n <input\n type=\"file\"\n class=\"ngx-field__file-input\"\n [id]=\"'field-' + field.id\"\n [disabled]=\"field.disabled || uploading()\"\n (change)=\"onFileSelect($any($event.target).files[0])\"\n />\n }\n </label>\n </div>\n @if (uploadError()) {\n <span class=\"ngx-field__error\" [attr.data-testid]=\"'field-' + field.id + '-error'\">{{ uploadError() }}</span>\n }\n }\n </div>\n `,\n})\nexport class FileFieldComponent {\n @Input() field!: NestedFieldConfig;\n @Input() control!: AbstractControl;\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() masked: boolean = false;\n\n private readonly uploads = inject(FileUploadService);\n\n readonly uploading = signal(false);\n readonly uploadError = signal<string | null>(null);\n\n get label(): string {\n return resolveLabel(this.field?.label, this.language);\n }\n\n private get value(): FileRef | null {\n return (this.control?.value as FileRef | null) ?? null;\n }\n\n fileUrl(): string | null {\n return this.value?.url ?? null;\n }\n\n fileName(): string | null {\n return fileRefName(this.value) || null;\n }\n\n async onFileSelect(file: File | undefined): Promise<void> {\n if (!file) return;\n this.uploadError.set(null);\n this.uploading.set(true);\n try {\n this.control.setValue(await this.uploads.toFileRef(file));\n this.control.markAsTouched();\n } catch {\n this.uploadError.set('Upload failed. Please try again.');\n } finally {\n this.uploading.set(false);\n }\n }\n\n remove(): void {\n this.control.setValue(null);\n this.control.markAsTouched();\n }\n}\n","import { EnvironmentProviders, Type, makeEnvironmentProviders } from '@angular/core';\nimport { FIELD_TYPE_SETS } from '../tokens/injection-tokens';\n\nimport { TextFieldComponent } from '../field-types/text-field.component';\nimport { TextareaFieldComponent } from '../field-types/textarea-field.component';\nimport { MarkdownFieldComponent } from '../field-types/markdown-field.component';\nimport { NumberFieldComponent } from '../field-types/number-field.component';\nimport { CurrencyFieldComponent } from '../field-types/currency-field.component';\nimport { EmailFieldComponent } from '../field-types/email-field.component';\nimport { PasswordFieldComponent } from '../field-types/password-field.component';\nimport { CheckboxFieldComponent } from '../field-types/checkbox-field.component';\nimport { BooleanFieldComponent } from '../field-types/boolean-field.component';\nimport { DateFieldComponent } from '../field-types/date-field.component';\nimport { DateTimeFieldComponent } from '../field-types/date-time-field.component';\nimport { TimeFieldComponent } from '../field-types/time-field.component';\nimport { MonthYearFieldComponent } from '../field-types/month-year-field.component';\nimport { DropdownFieldComponent } from '../field-types/dropdown-field.component';\nimport { RadioFieldComponent } from '../field-types/radio-field.component';\nimport { MultiSelectFieldComponent } from '../field-types/multi-select-field.component';\nimport { EntityRefFieldComponent } from '../field-types/entity-ref-field.component';\nimport { GroupFieldComponent } from '../field-types/group-field.component';\nimport { ArrayFieldComponent } from '../field-types/array-field.component';\nimport { ImageFieldComponent } from '../field-types/image-field.component';\nimport { FileFieldComponent } from '../field-types/file-field.component';\n\n/**\n * Field-type registration — the tree-shaking seam.\n *\n * `FieldRegistryService` imports no components. Whatever you register here is what gets\n * bundled, so an app that only uses text/number/dropdown pays for three components and\n * their imports, not nineteen.\n *\n * ```ts\n * // Everything (convenient; bundles all built-ins):\n * provideNgxDynamicEntity(), provideBuiltInFieldTypes()\n *\n * // Only what this app renders:\n * provideFieldTypes({ text: TextFieldComponent, number: NumberFieldComponent })\n * ```\n *\n * Both merge into `FIELD_TYPE_REGISTRY`; later registrations win on key collision.\n */\n\n/** Map of every built-in field type key → component. Referencing this pulls in all of them. */\nexport function builtInFieldTypes(): Record<string, Type<any>> {\n return {\n text: TextFieldComponent,\n textarea: TextareaFieldComponent,\n markdown: MarkdownFieldComponent,\n number: NumberFieldComponent,\n currency: CurrencyFieldComponent,\n email: EmailFieldComponent,\n password: PasswordFieldComponent,\n checkbox: CheckboxFieldComponent,\n boolean: BooleanFieldComponent,\n date: DateFieldComponent,\n datetime: DateTimeFieldComponent,\n time: TimeFieldComponent,\n monthYear: MonthYearFieldComponent,\n dropdown: DropdownFieldComponent,\n radio: RadioFieldComponent,\n multiSelect: MultiSelectFieldComponent,\n 'entity-ref': EntityRefFieldComponent,\n group: GroupFieldComponent,\n array: ArrayFieldComponent,\n image: ImageFieldComponent,\n file: FileFieldComponent,\n };\n}\n\n/** Register a specific set of field types. Only the components you name are bundled. */\nexport function provideFieldTypes(types: Record<string, Type<any>>): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: FIELD_TYPE_SETS, useValue: types, multi: true },\n ]);\n}\n\n/** Register all 19 built-in field type keys. Convenience for apps that use most of them. */\nexport function provideBuiltInFieldTypes(): EnvironmentProviders {\n return provideFieldTypes(builtInFieldTypes());\n}\n","import { Injectable, inject } from '@angular/core';\nimport { HOOK_REGISTRY } from '../tokens/injection-tokens';\n\n/**\n * HookRegistryService — stores and runs Angular-side pre/post hooks.\n * Consumers register hooks via provideNgxDynamicEntity({ hooks: { 'clients:beforeSave': fn } }).\n */\n@Injectable({ providedIn: 'root' })\nexport class HookRegistryService {\n private readonly registry = inject(HOOK_REGISTRY, { optional: true }) ?? new Map();\n\n has(key: string): boolean {\n return this.registry.has(key);\n }\n\n async run(key: string, data: any, context: any = {}): Promise<any> {\n const hook = this.registry.get(key);\n if (!hook) return data;\n return hook(data, context);\n }\n}\n","import { Injectable } from '@angular/core';\nimport type { EntityFormConfig, FormRule, RuleEvaluationResult } from '@dynamic-entity/core';\nimport { evaluateFormRules, filterRulesForTab } from '@dynamic-entity/core';\n\n/**\n * RulesEvaluationService — evaluates dynamic form rules against active reactive form state.\n */\n@Injectable({ providedIn: 'root' })\nexport class RulesEvaluationService {\n /**\n * Evaluate rules against form values and optional original baseline values.\n */\n evaluate(\n rules: FormRule[] | undefined | null,\n values: Record<string, unknown>,\n originalValues?: Record<string, unknown>,\n ): RuleEvaluationResult {\n return evaluateFormRules(rules, values, originalValues);\n }\n\n /**\n * Filter rules pertinent to a single tab.\n */\n filterForTab(rules: FormRule[] | undefined | null, tabId: string, config: EntityFormConfig): FormRule[] {\n return filterRulesForTab(rules, tabId, config);\n }\n}\n","import { Injectable, Inject, Optional } from '@angular/core';\nimport type { EntityFormConfig } from '@dynamic-entity/core';\nimport { isObservable, firstValueFrom } from 'rxjs';\nimport { CONFIG_SOURCE, type ConfigSourceHandler } from '../tokens/injection-tokens';\n\n@Injectable({ providedIn: 'root' })\nexport class ConfigSourceService {\n private readonly cache = new Map<string, EntityFormConfig>();\n private readonly inFlight = new Map<string, Promise<EntityFormConfig | undefined>>();\n\n private readonly handler?: ConfigSourceHandler;\n\n constructor(@Optional() @Inject(CONFIG_SOURCE) handler?: any) {\n this.handler = handler;\n }\n\n /** Retrieve an entity config by key, with caching and in-flight deduplication. */\n async getConfig(entityKey: string): Promise<EntityFormConfig | undefined> {\n if (!entityKey || !this.handler) return undefined;\n if (this.cache.has(entityKey)) return this.cache.get(entityKey);\n if (this.inFlight.has(entityKey)) return this.inFlight.get(entityKey);\n\n const promise = (async () => {\n try {\n const raw = this.handler!(entityKey);\n let resolved: EntityFormConfig | undefined;\n\n if (isObservable(raw)) {\n resolved = await firstValueFrom(raw as any);\n } else {\n resolved = await Promise.resolve(raw as any);\n }\n\n if (resolved) {\n this.cache.set(entityKey, resolved);\n }\n return resolved;\n } catch (err) {\n console.warn(`ConfigSourceService failed to load config for entity \"${entityKey}\"`, err);\n return undefined;\n } finally {\n this.inFlight.delete(entityKey);\n }\n })();\n\n this.inFlight.set(entityKey, promise);\n return promise;\n }\n\n /** Clear cached configs (e.g. after a config edit in the builder). */\n clearCache(entityKey?: string): void {\n if (entityKey) {\n this.cache.delete(entityKey);\n } else {\n this.cache.clear();\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n Input,\n Output,\n EventEmitter,\n OnChanges,\n OnDestroy,\n OnInit,\n SimpleChange,\n SimpleChanges,\n signal,\n computed,\n inject,\n isDevMode,\n ElementRef,\n ViewChild,\n ViewChildren,\n QueryList,\n HostListener,\n} from '@angular/core';\nimport { NgComponentOutlet } from '@angular/common';\nimport { AbstractControl, FormArray, FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\nimport type {\n AutoPatchConfig,\n EntityFormConfig,\n FormRule,\n NestedFieldConfig,\n NestedTabConfig,\n} from '@dynamic-entity/core';\nimport {\n ambiguousFieldIds,\n collectFieldScopes,\n fieldRefFor,\n parseFieldRef,\n refOf,\n toRefToken,\n applyAutoPatch,\n applyPatchOnTrue,\n migrateRecord,\n evaluateFieldVisibility,\n findTab,\n getTabData,\n getTabPath,\n getValueByPath,\n normalizeArrayStructures,\n normalizeConfigOptions,\n resolveLabel,\n setTabData,\n setValueByPath,\n} from '@dynamic-entity/core';\nimport { DynamicFieldComponent } from './dynamic-field/dynamic-field.component';\nimport { COMMON_MODULES_REGISTRY, RECORD_MIGRATIONS } from '../tokens/injection-tokens';\nimport { ValidatorRegistryService } from '../services/validator-registry.service';\nimport { HookRegistryService } from '../services/hook-registry.service';\nimport { RbacService } from '../services/rbac.service';\nimport { RulesEvaluationService } from '../services/rules-evaluation.service';\nimport { EntityRefSelectionService } from '../services/entity-ref-selection.service';\n\n/**\n * DynamicFormComponent — the main form component.\n * Renders a reactive form from EntityFormConfig with tab support, responsive 12-col grid,\n * rules evaluation, conditional visibility, autoPatch/patchOnTrue, criticalField locking,\n * keyboard shortcuts (Ctrl+S, Esc), and RBAC-gated submission.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-dynamic-form',\n standalone: true,\n imports: [ReactiveFormsModule, DynamicFieldComponent, NgComponentOutlet],\n // Scoped per form instance: entity-ref selections must not leak between concurrent forms.\n providers: [EntityRefSelectionService],\n templateUrl: './dynamic-form.component.html',\n styles: [\n `\n .ngx-form__panel {\n display: grid;\n grid-template-columns: repeat(12, minmax(0, 1fr));\n gap: 16px 20px;\n align-items: start;\n }\n .ngx-form__field-slot {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n min-width: 0;\n }\n .ngx-form__field-slot ngx-dynamic-field {\n flex: 1;\n min-width: 0;\n }\n .ngx-form__lock {\n flex: 0 0 auto;\n margin-top: 22px;\n background: none;\n border: 1px solid transparent;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n line-height: 1;\n padding: 4px 6px;\n }\n .ngx-form__lock:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n }\n @media (max-width: 768px) {\n .ngx-form__panel {\n grid-template-columns: 1fr;\n }\n .ngx-form__field-slot {\n grid-column: span 12 !important;\n }\n }\n `,\n ],\n})\nexport class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {\n // ─── Inputs ───────────────────────────────────────────────────────────────\n /**\n * The schema to render.\n *\n * An accessor pair rather than a plain field: `ngOnChanges` normalises the option shape,\n * and that result is kept here instead of being written back over the input. Reassigning\n * an `@Input` works, but it mutates what the parent handed us — and a parent using OnPush\n * or signals would never observe the replacement anyway.\n *\n * Reads of `this.config` get the normalised copy once it exists, so every internal caller\n * is unaffected.\n */\n @Input()\n set config(value: EntityFormConfig) {\n this.rawConfig = value;\n this.normalizedConfig = undefined; // re-normalised in ngOnChanges\n }\n get config(): EntityFormConfig {\n return this.normalizedConfig ?? this.rawConfig;\n }\n private rawConfig!: EntityFormConfig;\n private normalizedConfig?: EntityFormConfig;\n @Input() rules?: FormRule[];\n @Input() initialData?: Record<string, any>;\n /** Session-original values for `VALUE_CHANGED` rules. Captured from the first build when omitted. */\n @Input() originalData?: Record<string, any>;\n @Input() userRoles: string[] = [];\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n /** Field ids forced read-only while the rest of the form stays editable. */\n @Input() readOnlyFields: string[] = [];\n /**\n * Render rule `info` banners inline. The record editor sets this false and renders its\n * own dismissible versions, so the two do not double up.\n */\n @Input() showInfoBanners: boolean = true;\n @Input() loading: boolean = false;\n @Input() error: string | null = null;\n /**\n * Milliseconds to debounce `formChange`. The reference debounces at 300ms so a consumer\n * re-rendering on every value change is not driven per keystroke. Zero emits\n * synchronously, which the record editor relies on for its own bookkeeping.\n */\n @Input() changeDebounceMs: number = 0;\n /**\n * Preview mode: seed one empty row per `array` field so the structure is visible, then\n * disable the form. Used by the builder's live preview.\n */\n @Input() preview: boolean = false;\n\n // ─── Outputs ──────────────────────────────────────────────────────────────\n @Output() formSubmit = new EventEmitter<Record<string, any>>();\n @Output() formChange = new EventEmitter<Record<string, any>>();\n @Output() formReset = new EventEmitter<void>();\n /** The visible tab changed. Lets a host track it without reaching into this component. */\n @Output() activeTabChange = new EventEmitter<string>();\n /**\n * Emitted when a `beforeSave` hook aborted the save — by returning false or throwing.\n * `formSubmit` does not fire in that case.\n */\n @Output() saveRejected = new EventEmitter<{ reason: string; error?: unknown }>();\n\n // ─── Services ─────────────────────────────────────────────────────────────\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly fb = inject(FormBuilder);\n private readonly validatorRegistry = inject(ValidatorRegistryService);\n private readonly hookRegistry = inject(HookRegistryService);\n private readonly rbacService = inject(RbacService);\n private readonly rulesEvaluation = inject(RulesEvaluationService);\n private readonly entityRefSelection = inject(EntityRefSelectionService);\n private readonly commonModulesRegistry = inject(COMMON_MODULES_REGISTRY, { optional: true });\n private readonly migrations = inject(RECORD_MIGRATIONS, { optional: true }) ?? [];\n\n protected readonly Object = Object;\n\n // ─── Signals (local reactive state) ───────────────────────────────────────\n readonly activeTab = signal<string>('');\n readonly activeSubTab = signal<string>('');\n readonly isSaving = signal(false);\n readonly formValues = signal<Record<string, any>>({});\n /** Baseline captured at first build, used when `originalData` is not supplied. */\n readonly sessionBaseline = signal<Record<string, any>>({});\n /** Critical fields the user has explicitly unlocked for editing. */\n readonly unlockedFields = signal<ReadonlySet<string>>(new Set<string>());\n\n /** The active tab's field panel, focused after a tab switch. */\n @ViewChild('formPanel') private formPanel?: ElementRef<HTMLElement>;\n\n /** The hosted field components, so an external control-state change can reach them. */\n @ViewChildren(DynamicFieldComponent) private fieldHosts?: QueryList<DynamicFieldComponent>;\n\n // ─── Form ─────────────────────────────────────────────────────────────────\n form!: FormGroup;\n\n private valueSub?: Subscription;\n private statusSub?: Subscription;\n private selectionSub?: Subscription;\n /** Previous values, for detecting `patchOnTrue` false→true transitions. */\n private previousValues: Record<string, any> = {};\n\n // ─── Keyboard Shortcuts ───────────────────────────────────────────────────\n @HostListener('window:keydown', ['$event'])\n handleKeyboardEvent(event: KeyboardEvent): void {\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {\n event.preventDefault();\n if (!this.readonly && this.canSubmit && this.form?.valid) {\n this.submit();\n }\n }\n }\n\n // ─── Computed ─────────────────────────────────────────────────────────────\n readonly ruleResult = computed(() =>\n this.rulesEvaluation.evaluate(this.rules, this.formValues(), this.baseline()),\n );\n\n /**\n * Critical fields whose value differs from the session baseline.\n * These drive the deferred `VALUE_CHANGED` banner — a critical edit is announced once,\n * against the value the record had when the session started, not per keystroke.\n */\n readonly changedCriticalFields = computed<NestedFieldConfig[]>(() => {\n const baseline = this.baseline();\n if (!baseline || Object.keys(baseline).length === 0) return [];\n const values = this.formValues();\n return this.allFields().filter(\n f => f.criticalField && !this.sameValue(values[f.id], baseline[f.id]),\n );\n });\n\n get tabs(): NestedTabConfig[] {\n return this.config?.tabs || [];\n }\n\n get visibleTabs(): NestedTabConfig[] {\n const hidden = this.ruleResult().hiddenTabs;\n return this.tabs.filter(tab => tab.visibility !== false && !hidden.includes(tab.id));\n }\n\n get activeTabConfig(): NestedTabConfig | null {\n const tabId = this.activeTab();\n if (!tabId) return this.visibleTabs[0] ?? null;\n return findTab(this.tabs, tabId);\n }\n\n get visibleSubTabs(): NestedTabConfig[] {\n const active = this.activeTabConfig;\n if (!active?.children || active.children.length === 0) return [];\n const hidden = this.ruleResult().hiddenTabs;\n return active.children.filter(tab => tab.visibility !== false && !hidden.includes(tab.id));\n }\n\n get activeSubTabConfig(): NestedTabConfig | null {\n const subTabs = this.visibleSubTabs;\n if (!subTabs.length) return null;\n const subId = this.activeSubTab();\n return subTabs.find(s => s.id === subId) ?? subTabs[0];\n }\n\n get activeTabModuleComponent(): any | null {\n const active = this.activeSubTabConfig ?? this.activeTabConfig;\n if (!active?.moduleName || !this.commonModulesRegistry) return null;\n const entry = this.commonModulesRegistry.find(\n m => m.id === active.moduleName || m.component === active.moduleName,\n );\n return entry ? entry.component : null;\n }\n\n get fieldsForActiveTab(): NestedFieldConfig[] {\n const active = this.activeSubTabConfig ?? this.activeTabConfig;\n if (active?.moduleName) return [];\n const rawFields = active ? (active.fields || []) : ((this.config?.tabs || []).flatMap(t => t.fields || []));\n const currentValues = this.formValues();\n const hiddenFields = new Set<string>(this.ruleResult().hiddenFields);\n\n return rawFields.filter(\n field => evaluateFieldVisibility(field, currentValues) && !this.namesField(hiddenFields, field),\n );\n }\n\n /**\n * Entity-level permissions for the current roles.\n *\n * Cached rather than recomputed: this is read from the template several times per change\n * detection pass, and a fresh object each time is both wasted allocation and a new\n * identity for anything comparing by reference. Invalidated in `ngOnChanges` when\n * `config` or `userRoles` change, which are its only inputs.\n */\n get permissions(): ReturnType<RbacService['getPermissions']> {\n return (this.permissionsCache ??= this.rbacService.getPermissions(this.config, this.userRoles));\n }\n\n private permissionsCache: ReturnType<RbacService['getPermissions']> | null = null;\n\n /**\n * Whether the current roles may see this record at all.\n *\n * `permissions.view` used to be computed and thrown away — a user whose roles failed it\n * still received the complete form with every value in the DOM. It is honoured now.\n *\n * As with masking, this is presentational: it stops the browser rendering data, it does\n * not stop the data reaching the browser. Authorize on the server.\n */\n get canView(): boolean {\n return this.permissions.canView;\n }\n\n /**\n * Whether the current roles may delete this record.\n *\n * The library ships no delete affordance, so this is surfaced for the consumer to gate\n * their own — exposed rather than dropped, because a permission the schema declares\n * should be answerable.\n */\n get canDelete(): boolean {\n return this.permissions.canDelete;\n }\n\n get canSubmit(): boolean {\n return this.canView && this.permissions.canEdit && !this.readonly;\n }\n\n /**\n * Errors raised by `validation` rules, keyed by the target they point at.\n *\n * A rule can declare the record invalid independently of Angular's validators, so form\n * validity alone is not the whole picture. `DynamicRecordFormComponent.saveSection()`\n * has always honoured these; `submit()` did not, which meant the same rule blocked one\n * save path and merely painted a banner on the other — and anything wiring\n * `(formSubmit)` to persistence wrote records the rules engine had already rejected.\n */\n get ruleValidationErrors(): Record<string, string> {\n return this.ruleResult().validationErrors;\n }\n\n /** True when a `validation` rule is currently blocking submission. */\n get hasRuleErrors(): boolean {\n return Object.keys(this.ruleValidationErrors).length > 0;\n }\n\n /**\n * True while an async validator is still running.\n *\n * Angular reports a control with an outstanding async check as `pending`, and `invalid` is\n * false until it settles — so without this a form could be submitted in the gap before a\n * uniqueness check came back.\n */\n get isValidating(): boolean {\n return this.form.pending;\n }\n\n /** Single source of truth for both the submit guard and the button's disabled state. */\n get submitBlocked(): boolean {\n return this.form.invalid || this.form.pending || this.hasRuleErrors;\n }\n\n ngOnInit(): void {\n this.selectionSub = this.entityRefSelection.selection$.subscribe(({ fieldId, option }) => {\n this.runAutoPatch(fieldId, option?.record);\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['config'] || changes['userRoles']) {\n this.permissionsCache = null;\n }\n if (changes['config'] && this.rawConfig) {\n // Configs arrive as plain JSON from storage or an API, where TypeScript cannot enforce\n // the option shape. Normalise here, at the library boundary, so everything downstream\n // can rely on an option being a LocalizedText. Returns the same object when it already\n // is, so a well-formed config costs nothing.\n // Kept in a field of our own rather than written back to the @Input. Reassigning an\n // input works, but it surprises a parent that holds the same object — and a parent\n // using OnPush or signals would not see the replacement anyway.\n this.normalizedConfig = normalizeConfigOptions(this.config);\n }\n if (changes['config'] || changes['initialData']) {\n this.buildForm();\n\n // Clear *before* the guard below, not after it.\n //\n // The reset used to sit behind `if (visibleTabs.length === 0) return`, so a swap that\n // arrived while no tab was visible — a config still being applied, or every tab hidden\n // by a rule at that instant — skipped it entirely and the previous record's tab\n // survived into the next one. Clearing is unconditional and cheap, and safe on its own\n // because `activeTabConfig` already falls back to the first visible tab when nothing\n // is selected. Selecting the tab is what needs tabs to exist; forgetting the old one\n // does not.\n if (changes['config'] || this.isRecordSwap(changes['initialData'])) {\n this.activeTab.set('');\n this.activeSubTab.set('');\n }\n\n if (this.visibleTabs.length === 0) return;\n\n // The first tab used to be chosen only when no tab was active yet, and nothing ever\n // cleared `activeTab` — so a form that stays mounted while `initialData` is swapped\n // opened the next record on the tab the previous one was left on. The demo escaped it\n // by destroying the form between records; a host that keeps it mounted did not.\n //\n // Resetting here is consistent with what already happens: `buildForm` assigns a brand\n // new FormGroup, so a changed `initialData` has already discarded every control and\n // all validation state. The tab was the one thing pretending nothing had changed.\n if (!this.activeTab()) {\n // No focus steal: the panel gains focus when a *user* picks a tab, not when a host\n // swaps the record underneath them.\n this.setActiveTab(this.visibleTabs[0].id, { focusPanel: false });\n }\n }\n }\n\n /**\n * Whether an `initialData` change represents loading a different record.\n *\n * Not every change does. A template binding like `[initialData]=\"record() || {}\"` yields a\n * fresh object literal on each evaluation, so `ngOnChanges` fires with two empty objects\n * and nothing has actually been loaded — resetting there would drag someone back to the\n * first tab while they were filling in a new record on the third.\n */\n private isRecordSwap(change: SimpleChange | undefined): boolean {\n if (!change || change.isFirstChange()) return false;\n const empty = (v: unknown): boolean =>\n v === null || v === undefined || (typeof v === 'object' && Object.keys(v as object).length === 0);\n return !(empty(change.previousValue) && empty(change.currentValue));\n }\n\n ngOnDestroy(): void {\n this.valueSub?.unsubscribe();\n this.statusSub?.unsubscribe();\n this.selectionSub?.unsubscribe();\n }\n\n /**\n * `focusPanel: false` is for a caller that is about to focus something more specific.\n *\n * Activating a tab moves focus into its panel, which is right for a keyboard user pressing\n * a tab. A quick-jump also switches tabs, but then focuses the field it was aiming at — and\n * the panel focus runs on `requestAnimationFrame`, after `afterNextRender`, so it landed\n * second and took the focus back every time. Saying so is better than out-timing it.\n */\n setActiveTab(tabId: string, options?: { focusPanel?: boolean }): void {\n const changed = this.activeTab() !== tabId;\n if (changed) this.activeTabChange.emit(tabId);\n this.activeTab.set(tabId);\n if (changed && options?.focusPanel !== false) this.focusActivePanel();\n const parent = findTab(this.tabs, tabId);\n if (parent?.children?.length) {\n this.activeSubTab.set(parent.children[0].id);\n } else {\n this.activeSubTab.set('');\n }\n }\n\n setActiveSubTab(subTabId: string, options?: { focusPanel?: boolean }): void {\n const changed = this.activeSubTab() !== subTabId;\n this.activeSubTab.set(subTabId);\n if (changed && options?.focusPanel !== false) this.focusActivePanel();\n }\n\n getFieldSpan(field: NestedFieldConfig): string {\n const span = field.colSpan ?? 12;\n return `span ${Math.min(12, Math.max(1, span))}`;\n }\n\n // ─── criticalField locking ────────────────────────────────────────────────\n\n /** A critical field stays read-only until the user deliberately unlocks it. */\n isFieldLocked(field: NestedFieldConfig): boolean {\n return !!field.criticalField && !this.unlockedFields().has(field.id);\n }\n\n /**\n * Whether this field renders read-only, from any of the four reasons: the whole form,\n * the field's own flag, a caller-supplied `readOnlyFields` entry, or a criticalField lock.\n */\n isFieldReadonly(field: NestedFieldConfig): boolean {\n return (\n this.readonly ||\n // `permissions.edit` gated the Save button and nothing else, so a role without edit\n // rights received a fully editable form: it could type into every field, and only\n // discovered the record was not theirs to change when no Save button appeared. The\n // permission means the record may not be edited, so the fields say so.\n !this.permissions.canEdit ||\n !!field.readonly ||\n this.readOnlyFields.includes(field.id) ||\n this.isFieldLocked(field)\n );\n }\n\n toggleFieldLock(field: NestedFieldConfig): void {\n // Unlocking is an edit. Without the permission check a viewer could open the lock on a\n // critical field, which is the one control that exists to make editing deliberate.\n if (!field.criticalField || this.readonly || !this.permissions.canEdit) return;\n const next = new Set(this.unlockedFields());\n if (next.has(field.id)) next.delete(field.id);\n else next.add(field.id);\n this.unlockedFields.set(next);\n }\n\n resolveFieldLabel(field: NestedFieldConfig): string {\n return resolveLabel(field.label, this.language);\n }\n\n // ─── Form construction ────────────────────────────────────────────────────\n\n private buildForm(): void {\n if (!this.config) return;\n const group: Record<string, AbstractControl> = {};\n\n const buildTabControls = (tabs: NestedTabConfig[], parentGroup: Record<string, AbstractControl>) => {\n for (const tab of tabs) {\n if (tab.flatData) {\n for (const field of tab.fields || []) {\n this.buildFieldControl(field, parentGroup);\n }\n if (tab.children) buildTabControls(tab.children, parentGroup);\n } else {\n const tabGroup: Record<string, AbstractControl> = {};\n for (const field of tab.fields || []) {\n this.buildFieldControl(field, tabGroup);\n }\n if (tab.children) buildTabControls(tab.children, tabGroup);\n parentGroup[tab.id] = this.fb.group(tabGroup);\n }\n }\n };\n\n buildTabControls(this.config.tabs || [], group);\n this.form = this.fb.group(group);\n this.warnAmbiguousRuleReferences();\n\n if (this.initialData) {\n this.patchForm(this.upgradeRecord(this.initialData));\n }\n\n const initialFlattened = this.flattenFormValues();\n this.formValues.set(initialFlattened);\n this.previousValues = { ...initialFlattened };\n this.sessionBaseline.set({ ...initialFlattened });\n this.unlockedFields.set(new Set<string>());\n this.syncHiddenFieldState(initialFlattened);\n\n if (this.preview) {\n // Show what an array field looks like rather than an empty slot, then freeze.\n for (const field of this.allFields()) {\n if (field.type !== 'array') continue;\n const array = this.getArrayControl(field.id);\n if (array && array.length === 0) array.push(this.buildArrayRow(field, undefined));\n }\n this.form.disable({ emitEvent: false });\n }\n\n // Rebuilding must not stack subscriptions on successive config/data changes.\n this.valueSub?.unsubscribe();\n const changes$ = this.changeDebounceMs > 0\n ? this.form.valueChanges.pipe(debounceTime(this.changeDebounceMs))\n : this.form.valueChanges;\n // Validity is not value: an async validator settling flips `pending` and then `invalid`\n // with no value change and no template event, so under OnPush the Save button would\n // never re-enable. submitBlocked reads form.pending and form.invalid, so this is what\n // keeps it honest.\n this.statusSub?.unsubscribe();\n this.statusSub = this.form.statusChanges.subscribe(() => this.cdr.markForCheck());\n\n this.valueSub = changes$.subscribe(() => {\n const flattened = this.flattenFormValues();\n this.formValues.set(flattened);\n this.runPatchOnTrue(flattened);\n this.syncHiddenFieldState(flattened);\n this.previousValues = { ...flattened };\n this.formChange.emit(this.extractRecord());\n });\n }\n\n private buildFieldControl(field: NestedFieldConfig, group: Record<string, AbstractControl>): void {\n if (field.type === 'group') {\n const subGroup: Record<string, AbstractControl> = {};\n for (const child of field.children || []) {\n this.buildFieldControl(child, subGroup);\n }\n group[field.id] = this.fb.group(subGroup);\n } else if (field.type === 'array') {\n group[field.id] = this.fb.array([]);\n } else {\n const validators = this.validatorRegistry.resolveFromConfig(field.validators);\n const asyncValidators = this.validatorRegistry.resolveAsyncFromConfig(field.validators);\n group[field.id] = this.fb.control(\n { value: field.defaultValue ?? null, disabled: field.disabled ?? false },\n validators,\n asyncValidators,\n );\n }\n }\n\n /** One row of an `array` field: a FormGroup when the field declares columns, else a bare control. */\n /**\n * The `FormArray` behind an `array` field, for callers that manage rows themselves —\n * the record editor's inline row drawer.\n */\n getArrayControl(fieldId: string, tabId?: string): FormArray | null {\n const ctrl = this.getControl(fieldId, tabId);\n return ctrl instanceof FormArray ? ctrl : null;\n }\n\n /**\n * Build one detached row for an `array` field, with the field's own validators applied.\n * Exposed so a row can be edited outside the form and pushed on save.\n */\n createArrayRow(field: NestedFieldConfig, value?: unknown): AbstractControl {\n return this.buildArrayRow(field, value);\n }\n\n private buildArrayRow(field: NestedFieldConfig | undefined, item: unknown): AbstractControl {\n if (!field?.children?.length) return this.fb.control(item);\n\n const rowGroup: Record<string, AbstractControl> = {};\n for (const child of field.children) {\n this.buildFieldControl(child, rowGroup);\n }\n const group = this.fb.group(rowGroup);\n if (item && typeof item === 'object') group.patchValue(item as Record<string, unknown>);\n return group;\n }\n\n /**\n * Mark every control touched, then re-check the field components.\n *\n * They are OnPush and `touched` is flipped from outside their own template, so the second\n * half is what makes the error messages actually appear.\n */\n private markAllTouched(): void {\n this.form.markAllAsTouched();\n this.fieldHosts?.forEach(host => host.refresh());\n }\n\n /**\n * Bring a record up to the config's `version` before it reaches the form.\n *\n * Done here because this is the one place a record enters the renderer, so a consumer\n * cannot forget it. Migration is a no-op unless the consumer registered steps *and* the\n * record is behind — an unstamped record is deliberately left alone (see `migrateRecord`).\n *\n * A missing or broken step throws from core. That is not swallowed: rendering a\n * half-understood record would write it back in a shape matching neither schema.\n */\n private upgradeRecord(data: Record<string, any>): Record<string, any> {\n if (!this.migrations.length || !this.config) return data;\n\n const result = migrateRecord(data, this.config, this.migrations);\n if (result.applied.length && isDevMode()) {\n console.info(\n `[ngx-dynamic-entity] Migrated a \"${this.config.entity}\" record from config version ` +\n `${result.from} to ${result.to} (steps: ${result.applied.join(', ')}).`,\n );\n }\n return result.record;\n }\n\n private patchForm(data: Record<string, any>): void {\n if (!data || !this.form) return;\n const fieldsById = new Map(this.allFields().map(f => [f.id, f]));\n const patchedFieldIds = new Set<string>();\n\n const walkTabs = (tabs: NestedTabConfig[]) => {\n for (const tab of tabs) {\n const tabData = getTabData(tab.id, data, this.config);\n for (const field of tab.fields || []) {\n let val = tabData && typeof tabData === 'object' ? tabData[field.id] : undefined;\n if (field.refererField) {\n const refVal = getValueByPath(data, field.refererField);\n if (refVal !== undefined) val = refVal;\n }\n if (val === undefined) continue;\n\n const ctrl = this.getControl(field.id, tab.id);\n if (!ctrl) continue;\n\n if (ctrl instanceof FormArray && Array.isArray(val)) {\n ctrl.clear();\n for (const item of val) {\n ctrl.push(this.buildArrayRow(fieldsById.get(field.id), item));\n }\n } else {\n ctrl.patchValue(val, { emitEvent: false });\n }\n patchedFieldIds.add(field.id);\n }\n if (tab.children) walkTabs(tab.children);\n }\n };\n\n walkTabs(this.config.tabs || []);\n this.warnUnconsumedInitialData(data, fieldsById, patchedFieldIds);\n }\n\n /**\n * A record is nested by tab id (`{ tabId: { fieldId: value } }`) unless the tab sets\n * `flatData: true`. Handing a flat record to a nested tab finds nothing, so the fields\n * stay empty — with no error and no clue. That silent miss is the most expensive way to\n * lose an hour with this library, so name it in dev builds.\n *\n * Only top-level keys that match a known field id are reported: anything else is assumed\n * to be the consumer's own record metadata (ids, timestamps, `_configVersion`) and is not\n * our business.\n */\n private warnUnconsumedInitialData(\n data: Record<string, any>,\n fieldsById: Map<string, NestedFieldConfig>,\n patchedFieldIds: Set<string>,\n ): void {\n if (!isDevMode() || !this.config) return;\n\n const tabIds = new Set<string>();\n const collectTabIds = (tabs: NestedTabConfig[]) => {\n for (const tab of tabs) {\n tabIds.add(tab.id);\n if (tab.children) collectTabIds(tab.children);\n }\n };\n collectTabIds(this.config.tabs || []);\n\n const unconsumed = Object.keys(data).filter(\n key =>\n !tabIds.has(key) && // a tab id at the root is the nested container, not a stray field\n data[key] !== undefined &&\n fieldsById.has(key) &&\n !patchedFieldIds.has(key) &&\n !this.warnedUnconsumedKeys.has(key),\n );\n if (!unconsumed.length) return;\n\n for (const key of unconsumed) this.warnedUnconsumedKeys.add(key);\n\n const shown = unconsumed.slice(0, 5).join(', ');\n const more = unconsumed.length > 5 ? ` (+${unconsumed.length - 5} more)` : '';\n const plural = unconsumed.length === 1;\n console.warn(\n `[ngx-dynamic-entity] initialData has top-level ${plural ? 'key' : 'keys'} matching ` +\n `${plural ? 'a field that was' : 'fields that were'} not populated: ${shown}${more}. ` +\n `A record is nested by tab id ({ tabId: { fieldId: value } }) unless the tab sets ` +\n `flatData: true. Either nest the value under its tab id, or set flatData: true on ` +\n `the tab holding ${plural ? 'that field' : 'those fields'}.`,\n );\n }\n\n /** Warn once per key per form instance — patchForm re-runs on every initialData change. */\n private readonly warnedUnconsumedKeys = new Set<string>();\n\n /** Assemble full nested record from per-tab FormGroups, respecting flatData, refererField & arrays. */\n extractRecord(): Record<string, any> {\n if (!this.form || !this.config) return {};\n let record: Record<string, any> = {};\n\n const walkTabs = (tabs: NestedTabConfig[]) => {\n for (const tab of tabs) {\n const fieldValBag: Record<string, unknown> = {};\n for (const field of tab.fields || []) {\n const ctrl = this.getControl(field.id, tab.id);\n if (ctrl) {\n fieldValBag[field.id] = ctrl.value;\n }\n }\n\n setTabData(record, tab.id, fieldValBag, this.config);\n\n for (const field of tab.fields || []) {\n if (field.refererField) {\n const ctrl = this.getControl(field.id, tab.id);\n if (ctrl) {\n setValueByPath(record, field.refererField, ctrl.value);\n }\n }\n }\n\n if (tab.children) walkTabs(tab.children);\n }\n };\n\n walkTabs(this.config.tabs || []);\n record = normalizeArrayStructures(record, this.config);\n return record;\n }\n\n /**\n * Warns when a rule names a field id that two scopes define.\n *\n * Field ids are unique per scope, so `address` may exist on both Personal Details and Work\n * Details — but a rule carries a bare id and no scope, so it cannot say which one it means.\n * `flattenFormValues` keys by bare id, so one of the two silently wins and the rule reads\n * whichever landed there.\n *\n * `validateConfig({ rules })` catches this statically. The check here remains because\n * consumers that never call the validator still get a signal in development.\n */\n private warnAmbiguousRuleReferences(): void {\n if (!isDevMode() || !this.rules?.length || !this.config) return;\n\n const ambiguous = ambiguousFieldIds(this.config);\n if (ambiguous.size === 0) return;\n\n const referenced = new Set<string>();\n for (const rule of this.rules) {\n if (rule.fieldId) referenced.add(rule.fieldId);\n for (const condition of rule.conditions ?? []) {\n if (condition.compareToField) referenced.add(condition.compareToField);\n }\n for (const target of rule.targets ?? []) {\n if (target.type === 'field' && target.id) referenced.add(target.id);\n }\n }\n\n for (const raw of referenced) {\n const parsed = parseFieldRef(raw);\n if (parsed.kind === 'ref') continue;\n const id = parsed.value;\n const scopes = ambiguous.get(id);\n if (!scopes || DynamicFormComponent.warnedAmbiguousIds.has(id)) continue;\n DynamicFormComponent.warnedAmbiguousIds.add(id);\n console.warn(\n `[ngx-dynamic-entity] A rule references field \"${id}\", which is defined in ${scopes.join(' and ')}. ` +\n `A bare id cannot say which one is meant, so the rule will read whichever the form finds first. ` +\n `Name it by path instead, as [${scopes[0]}.${id}].`,\n );\n }\n }\n\n private static readonly warnedAmbiguousIds = new Set<string>();\n\n /**\n * The value map rules and `showWhen` are evaluated against.\n *\n * Every field appears under two keys: its bare id, and its `refererField` path wrapped in brackets.\n * The bare id is what every config written so far uses and is kept exactly as it was — but\n * ids are unique per scope, so when two scopes define one the last field walked wins and\n * the rule reads whichever that is. `[personal.address]` names one field and cannot be\n * ambiguous, which is why a rule that has to distinguish them uses the ref.\n *\n * Both live in one flat map on purpose: `evaluateFormRules` takes a `Record<string,\n * unknown>` and needs no knowledge of refs at all — the extra keys simply resolve.\n */\n /**\n * Whether a rule result names this field.\n *\n * A rule target is either a bare field id — how every config so far addresses a field — or\n * a bracketed path, which is the only way to name one of two fields that share an id.\n * Both have to match, or a rule written either way would fail to hide what it targeted.\n */\n private namesField(names: ReadonlySet<string>, field: NestedFieldConfig): boolean {\n if (names.has(field.id)) return true;\n const ref = field.refererField ?? this.pathFor(field);\n return ref ? names.has(toRefToken(ref)) : false;\n }\n\n /** The field's declared path, or the one its position implies when it carries none. */\n private pathFor(field: NestedFieldConfig): string | null {\n const entry = collectFieldScopes(this.config).find(e => e.field === field);\n return entry ? fieldRefFor(entry.scope, field.id) : null;\n }\n\n private flattenFormValues(): Record<string, any> {\n const out: Record<string, any> = {};\n for (const entry of collectFieldScopes(this.config)) {\n const field = entry.field;\n if (!field?.id) continue;\n const ctrl = this.getControl(field.id, entry.scope.split('.').pop());\n if (!ctrl) continue;\n out[field.id] = ctrl.value;\n out[toRefToken(refOf(field, entry.scope))] = ctrl.value;\n }\n return out;\n }\n\n private getTabGroup(tabId: string): FormGroup | null {\n const path = getTabPath(this.config?.tabs, tabId);\n if (!path || path.length === 0) return this.form;\n let curr: AbstractControl | null = this.form;\n for (const p of path) {\n if (!curr || !(curr instanceof FormGroup)) return null;\n curr = curr.get(p);\n }\n return curr instanceof FormGroup ? curr : null;\n }\n\n // ─── autoPatch / patchOnTrue ──────────────────────────────────────────────\n\n /**\n * `autoPatch` — copy mapped fields out of the record the user just selected in an\n * entity-ref field into the configured target tab's controls.\n */\n private runAutoPatch(fieldId: string, record: Record<string, unknown> | undefined): void {\n if (!record) return;\n const field = this.allFields().find(f => f.id === fieldId);\n const autoPatch = field?.autoPatch;\n if (!autoPatch) return;\n\n const patch = applyAutoPatch(autoPatch, record);\n for (const [targetId, value] of Object.entries(patch)) {\n const control = this.resolveTargetControl(autoPatch, targetId);\n control?.patchValue(value);\n }\n // Readonly targets interpolate `control.value` under OnPush. `detectChanges` on the\n // hosted component flushes that write immediately — `markForCheck` waits for a later\n // tick that a Playwright selection never schedules.\n this.fieldHosts?.forEach(host => host.refresh());\n }\n\n /**\n * `patchOnTrue` — when a boolean/checkbox field transitions to `true`,\n * copy `from` → `to` within the current record.\n */\n private runPatchOnTrue(values: Record<string, any>): void {\n for (const field of this.allFields()) {\n const mappings = field.patchOnTrue;\n if (!mappings?.length) continue;\n\n const wasTrue = this.previousValues[field.id] === true;\n const isTrue = values[field.id] === true;\n if (!isTrue || wasTrue) continue;\n\n const patch = applyPatchOnTrue(mappings, values);\n for (const [targetId, value] of Object.entries(patch)) {\n this.getControl(targetId)?.patchValue(value, { emitEvent: false });\n }\n }\n }\n\n /** Prefer a control declared on the configured target tab; fall back to a top-level control. */\n private resolveTargetControl(autoPatch: AutoPatchConfig, targetId: string): AbstractControl | null {\n const tab = findTab(this.tabs, autoPatch.targetTab);\n const inTargetTab = (tab?.fields ?? []).some(f => f.id === targetId);\n if (tab && !inTargetTab) return null;\n return this.getControl(targetId, autoPatch.targetTab);\n }\n\n // ─── Helpers ──────────────────────────────────────────────────────────────\n\n /**\n * The fields the render filter operates on — a tab's own fields, at every tab depth.\n * Deliberately not `allFields()`: `group` and `array` children are shown or hidden with\n * their parent, and toggling a child's state independently would fight the parent's.\n */\n private tabFields(): NestedFieldConfig[] {\n const out: NestedFieldConfig[] = [];\n const walk = (tabs: NestedTabConfig[] | undefined) => {\n for (const tab of tabs ?? []) {\n out.push(...(tab.fields ?? []));\n walk(tab.children);\n }\n };\n walk(this.config?.tabs);\n return out;\n }\n\n /**\n * Keep a hidden field's control out of form validity.\n *\n * A field hidden by a rule or a `showWhen` condition is filtered out of the render, but\n * its validators stay attached — so a hidden *required* field holds `form.invalid` true\n * forever, permanently disabling Save with nothing on screen to explain why.\n *\n * Disabling is the fix rather than stripping validators: Angular excludes disabled\n * controls from validity, and the field's own validators survive intact for when it\n * comes back. Values are untouched — `flattenFormValues` and `extractRecord` both read\n * `control.value`, which a disabled control still carries, so rule evaluation and the\n * emitted record see exactly what they saw before. That also keeps this from feeding\n * back on itself: hiding a field cannot change the values the rules are evaluated over.\n *\n * The visibility predicate is the same one `fieldsForActiveTab` filters with, so what is\n * rendered and what counts toward validity cannot drift apart.\n */\n private syncHiddenFieldState(values: Record<string, any>): void {\n if (this.preview) return; // preview freezes the whole form on purpose\n\n const hiddenByRule = new Set<string>(this.ruleResult().hiddenFields);\n\n for (const field of this.tabFields()) {\n const ctrl = this.getControl(field.id);\n if (!ctrl) continue;\n\n const hidden = this.namesField(hiddenByRule, field) || !evaluateFieldVisibility(field, values);\n\n if (hidden) {\n if (ctrl.enabled) ctrl.disable({ emitEvent: false });\n } else if (ctrl.disabled && !field.disabled) {\n ctrl.enable({ emitEvent: false });\n }\n }\n }\n\n /** Every field in the config, including `group`/`array` children. */\n private allFields(): NestedFieldConfig[] {\n const out: NestedFieldConfig[] = [];\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const f of fields ?? []) {\n out.push(f);\n if (f.children?.length) walkFields(f.children);\n }\n };\n const walkTabs = (tabs: NestedTabConfig[] | undefined) => {\n for (const t of tabs ?? []) {\n walkFields(t.fields);\n walkTabs(t.children);\n }\n };\n walkTabs(this.config?.tabs);\n return out;\n }\n\n /** An empty `originalData` counts as \"not supplied\" — fall back to the captured baseline. */\n private baseline(): Record<string, any> {\n const supplied = this.originalData;\n if (supplied && Object.keys(supplied).length > 0) return supplied;\n return this.sessionBaseline();\n }\n\n private sameValue(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n const aEmpty = a === null || a === undefined || a === '';\n const bEmpty = b === null || b === undefined || b === '';\n if (aEmpty && bEmpty) return true;\n if (typeof a === 'object' || typeof b === 'object') {\n return JSON.stringify(a ?? null) === JSON.stringify(b ?? null);\n }\n return false;\n }\n\n getControl(fieldId: string, currentTabId?: string): AbstractControl | null {\n if (!this.form) return null;\n\n // A bracketed path names exactly one control, and the form nests by tab exactly as the\n // path does — so `form.get('work.address')` walks straight to it. Anything that names a\n // field can therefore use a path: `showWhen` keys, `patchOnTrue` mappings and `autoPatch`\n // targets, not only rules.\n const parsed = parseFieldRef(fieldId);\n if (parsed.kind === 'ref') return this.form.get(parsed.value);\n\n if (currentTabId) {\n const tabGrp = this.getTabGroup(currentTabId);\n const ctrl = tabGrp?.get(fieldId);\n if (ctrl) return ctrl;\n }\n\n const rootCtrl = this.form.get(fieldId);\n if (rootCtrl) return rootCtrl;\n\n const findInGroup = (group: FormGroup): AbstractControl | null => {\n for (const key of Object.keys(group.controls)) {\n const c = group.controls[key];\n if (key === fieldId) return c;\n if (c instanceof FormGroup) {\n const found = findInGroup(c);\n if (found) return found;\n }\n }\n return null;\n };\n\n return findInGroup(this.form);\n }\n\n /**\n * Move focus into the newly shown panel.\n *\n * Activating a tab replaces everything below it while focus stays on the tab button, so a\n * screen-reader or keyboard user is given no indication that the content changed and must\n * tab back through the strip to reach it. Deferred a frame because the panel's contents\n * are rendered by the change detection this call is part of.\n */\n private focusActivePanel(): void {\n if (typeof requestAnimationFrame !== 'function') return;\n requestAnimationFrame(() =>\n // `preventScroll` because this focus exists to tell a screen reader the panel changed,\n // not to move the page. The default scrolls the panel into view, which on a short\n // viewport jumps the layout — enough that a Save button below it moves out from under\n // a tap. The panel sits directly beneath the tab strip and is already on screen.\n this.formPanel?.nativeElement?.focus?.({ preventScroll: true }),\n );\n }\n\n /** Accessible name for the field panel — it is the tabpanel for the active tab. */\n get activeTabLabel(): string {\n const tab = this.activeSubTabConfig ?? this.activeTabConfig;\n return tab ? this.resolveTabLabel(tab) : '';\n }\n\n /**\n * Why a referenced field is flagged.\n *\n * `hasDrift` was written by the builder and read by nothing at runtime, so a field whose\n * source definition had changed since it was linked looked entirely normal to the person\n * filling the form in.\n */\n driftHint(field: NestedFieldConfig): string {\n const source = field.referencedEntityKey\n ? `\"${field.referencedEntityKey}\"`\n : 'its source entity';\n return `This field is linked to ${source} and its definition there has changed since it was linked.`;\n }\n\n resolveTabLabel(tab: NestedTabConfig): string {\n return resolveLabel(tab.label, this.language);\n }\n\n async submit(): Promise<void> {\n if (!this.canSubmit || this.submitBlocked) {\n this.markAllTouched();\n return;\n }\n\n const rawData = this.extractRecord();\n let processedData = rawData;\n\n this.isSaving.set(true);\n try {\n // beforeSave can now abort the save: returning false, or throwing, stops it. Previously\n // its return value simply replaced the payload and the submit proceeded regardless, so\n // a hook that wanted to veto — a server-side check, a confirmation — had no way to.\n const hookKey = `${this.config?.entity}:beforeSave`;\n if (this.hookRegistry.has(hookKey)) {\n const result = await this.hookRegistry.run(hookKey, processedData);\n if (result === false) {\n this.saveRejected.emit({ reason: 'beforeSave returned false' });\n return;\n }\n // Anything else is the payload to submit; `undefined` means \"unchanged\".\n if (result !== undefined && result !== true) processedData = result;\n }\n\n this.formSubmit.emit(processedData);\n } catch (err) {\n // A hook that throws aborts the save and reports why, rather than the error escaping\n // into an unhandled rejection with the form left looking as though it saved.\n this.saveRejected.emit({ reason: err instanceof Error ? err.message : String(err), error: err });\n } finally {\n this.isSaving.set(false);\n }\n }\n\n reset(): void {\n this.form.reset();\n if (this.initialData) this.patchForm(this.initialData);\n const values = this.flattenFormValues();\n this.formValues.set(values);\n this.previousValues = { ...values };\n this.unlockedFields.set(new Set<string>());\n this.formReset.emit();\n }\n}\n","@if (canView) {\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\" class=\"ngx-form\" novalidate>\n\n <!-- Error message banner -->\n @if (error) {\n <div class=\"ngx-form__error-banner\" role=\"alert\" data-testid=\"form-error\">{{ error }}</div>\n }\n\n <!-- Rules Info Banners -->\n @for (infoKey of showInfoBanners ? Object.keys(ruleResult().infoBanners) : []; track infoKey) {\n <div class=\"ngx-form__info-banner\" role=\"status\" [attr.data-testid]=\"'info-banner-' + infoKey\">\n ℹ️ {{ ruleResult().infoBanners[infoKey] }}\n </div>\n }\n\n <!-- Rules Validation Errors & Warnings -->\n @for (errKey of Object.keys(ruleResult().validationErrors); track errKey) {\n <div class=\"ngx-form__error-banner\" role=\"alert\" [attr.data-testid]=\"'rule-error-' + errKey\">\n ⚠️ {{ ruleResult().validationErrors[errKey] }}\n </div>\n }\n @for (warnKey of Object.keys(ruleResult().validationWarnings); track warnKey) {\n <div class=\"ngx-form__warning-banner\" role=\"status\" [attr.data-testid]=\"'rule-warning-' + warnKey\">\n ⚡ {{ ruleResult().validationWarnings[warnKey] }}\n </div>\n }\n\n <!-- Deferred VALUE_CHANGED notice for criticalField edits (vs session baseline) -->\n @if (changedCriticalFields().length > 0) {\n <div class=\"ngx-form__warning-banner\" role=\"status\" data-testid=\"critical-change-banner\">\n 🔒 Critical field changed:\n @for (field of changedCriticalFields(); track field.id) {\n <span>{{ resolveFieldLabel(field) }}{{ $last ? '' : ', ' }}</span>\n }\n — this differs from the value at the start of this session.\n </div>\n }\n\n <!-- Primary Tab bar — only if visible tabs defined -->\n @if (visibleTabs.length > 0) {\n <div class=\"ngx-form__tabs\" role=\"tablist\" data-testid=\"tab-strip\">\n @for (tab of visibleTabs; track tab.id) {\n <button\n type=\"button\"\n class=\"ngx-form__tab\"\n [attr.data-testid]=\"'tab-' + tab.id\"\n [class.ngx-form__tab--active]=\"activeTab() === tab.id\"\n (click)=\"setActiveTab(tab.id)\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab() === tab.id\"\n >\n {{ resolveTabLabel(tab) }}\n </button>\n }\n </div>\n }\n\n <!-- Sub-tab bar — only if active tab has sub-tabs -->\n @if (visibleSubTabs.length > 0) {\n <div class=\"ngx-form__tabs ngx-form__tabs--sub\" role=\"tablist\" data-testid=\"subtab-strip\" style=\"margin-top: -12px; margin-bottom: 12px; font-size: 13px;\">\n @for (subTab of visibleSubTabs; track subTab.id) {\n <button\n type=\"button\"\n class=\"ngx-form__tab ngx-form__tab--sub\"\n [attr.data-testid]=\"'subtab-' + subTab.id\"\n [class.ngx-form__tab--active]=\"(activeSubTabConfig?.id) === subTab.id\"\n (click)=\"setActiveSubTab(subTab.id)\"\n role=\"tab\"\n [attr.aria-selected]=\"(activeSubTabConfig?.id) === subTab.id\"\n >\n {{ resolveTabLabel(subTab) }}\n </button>\n }\n </div>\n }\n\n <!--\n One tabpanel per tab, wrapping both branches. Focus moves here on a tab switch, and a\n module tab is still a tab — putting the panel semantics on only the fields branch left\n a module tab with nowhere for focus to land.\n -->\n <div\n role=\"tabpanel\"\n tabindex=\"-1\"\n #formPanel\n class=\"ngx-form__tabpanel\"\n [attr.aria-label]=\"activeTabLabel\"\n >\n @if (activeTabModuleComponent) {\n <div class=\"ngx-form__module-panel\" data-testid=\"module-panel\">\n <ng-container *ngComponentOutlet=\"activeTabModuleComponent; inputs: (activeSubTabConfig || activeTabConfig)?.moduleInputs\"></ng-container>\n </div>\n } @else {\n <!-- Fields for active tab (Responsive 12-column grid) -->\n <div class=\"ngx-form__panel\" data-testid=\"form-panel\">\n @for (field of fieldsForActiveTab; track field.id) {\n <div\n class=\"ngx-form__field-slot\"\n [style.gridColumn]=\"getFieldSpan(field)\"\n [attr.id]=\"'field-container-' + field.id\"\n tabindex=\"-1\"\n >\n <ngx-dynamic-field\n [field]=\"field\"\n [control]=\"getControl(field.id, (activeSubTabConfig || activeTabConfig)?.id)!\"\n [config]=\"config\"\n [currentTabId]=\"(activeSubTabConfig || activeTabConfig)?.id\"\n [language]=\"language\"\n [readonly]=\"isFieldReadonly(field)\"\n [userRoles]=\"userRoles\"\n />\n @if (field.hasDrift) {\n <!--\n Drift was previously visible only in the builder, so a referenced field whose\n source had changed looked completely normal to the person filling the form in.\n role=\"status\" rather than \"alert\": it is information, not an error.\n -->\n <span\n class=\"ngx-field__drift\"\n role=\"status\"\n [attr.data-testid]=\"'field-' + field.id + '-drift'\"\n [title]=\"driftHint(field)\"\n >⚠ {{ driftHint(field) }}</span>\n }\n @if (field.criticalField && !readonly) {\n <button\n type=\"button\"\n class=\"ngx-form__lock\"\n [attr.data-testid]=\"'lock-' + field.id\"\n [attr.aria-pressed]=\"!isFieldLocked(field)\"\n [attr.aria-label]=\"\n (isFieldLocked(field) ? 'Unlock ' : 'Lock ') + resolveFieldLabel(field)\n \"\n [title]=\"\n isFieldLocked(field)\n ? 'Critical field — click to unlock for editing'\n : 'Critical field — click to lock'\n \"\n (click)=\"toggleFieldLock(field)\"\n >\n {{ isFieldLocked(field) ? '🔒' : '🔓' }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Submit button — gated by RBAC and isSaving lock -->\n @if (!readonly && permissions.canEdit) {\n <div class=\"ngx-form__actions\" data-testid=\"form-actions\">\n <button\n type=\"button\"\n class=\"ngx-form__reset\"\n data-testid=\"form-reset\"\n (click)=\"reset()\"\n [disabled]=\"isSaving()\"\n >\n Reset\n </button>\n <button\n type=\"submit\"\n class=\"ngx-form__submit\"\n data-testid=\"form-submit\"\n [disabled]=\"submitBlocked\"\n title=\"Shortcut: Ctrl+S\"\n >\n @if (isSaving() || loading) {\n Saving…\n } @else {\n Save\n }\n </button>\n </div>\n }\n\n </form>\n} @else {\n <!-- permissions.view denied: render nothing of the record.\n Presentational only — the server must not send data this user may not see. -->\n <div class=\"ngx-form__denied\" role=\"status\" data-testid=\"form-access-denied\">\n You do not have permission to view this record.\n </div>\n}\n","import { ChangeDetectionStrategy, Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, signal, computed, inject, afterNextRender, ElementRef, Injector, ViewChild } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { AbstractControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport type { EntityFormConfig, FormRule, NestedFieldConfig, NestedTabConfig } from '@dynamic-entity/core';\nimport { findTab, formatDisplayValue, getTabData, resolveLabel } from '@dynamic-entity/core';\nimport { DynamicFormComponent } from './dynamic-form.component';\nimport { DynamicFieldComponent } from './dynamic-field/dynamic-field.component';\nimport { RulesEvaluationService } from '../services/rules-evaluation.service';\nimport { RbacService } from '../services/rbac.service';\n\n/**\n * Distinguishes \"no tab holds this field\" from \"the field holds undefined\", so the tab walk\n * can keep searching in the first case and stop in the second.\n */\nconst FIELD_NOT_FOUND = Symbol('field-not-found');\n\n/**\n * DynamicRecordFormComponent — comprehensive tabbed record view & edit component.\n * Supports cross-tab rule evaluation, profile header, summary drawer (showOnMinimize),\n * interactive quick-jump links, and baseline modification tracking.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-dynamic-record-form',\n standalone: true,\n imports: [CommonModule, ReactiveFormsModule, DynamicFormComponent, DynamicFieldComponent],\n templateUrl: './dynamic-record-form.component.html',\n styles: [\n `\n .ngx-record-editor {\n display: flex;\n flex-direction: column;\n gap: 16px;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n padding: 20px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n }\n .ngx-record-editor__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding-bottom: 16px;\n border-bottom: 1px solid #f3f4f6;\n }\n .ngx-record-editor__title-group {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .ngx-record-editor__avatar {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n object-fit: cover;\n background: #e0e7ff;\n color: #4f46e5;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 18px;\n }\n .ngx-record-editor__title {\n font-size: 20px;\n font-weight: 700;\n color: #111827;\n margin: 0;\n }\n .ngx-record-editor__subtitle {\n font-size: 13px;\n color: #6b7280;\n }\n .ngx-record-editor__header-toggle {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: #374151;\n }\n .ngx-record-editor__header-toggle-text {\n font-weight: 600;\n }\n .ngx-record-editor__banner {\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 500;\n }\n .ngx-record-editor__banner--info {\n background: #eff6ff;\n border: 1px solid #dbeafe;\n color: #1d4ed8;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n }\n .ngx-record-editor__banner-dismiss {\n background: none;\n border: none;\n cursor: pointer;\n color: inherit;\n font-size: 14px;\n line-height: 1;\n padding: 2px 6px;\n border-radius: 4px;\n }\n .ngx-record-editor__banner-dismiss:hover {\n background: rgba(0, 0, 0, 0.06);\n }\n .ngx-record-editor__banner--error {\n background: #fef2f2;\n border: 1px solid #fecaca;\n color: #b91c1c;\n }\n .ngx-record-editor__section-bar {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n }\n .ngx-record-editor__section-hint {\n margin-right: auto;\n font-size: 12px;\n color: #6b7280;\n }\n .ngx-record-editor__banner--warning {\n background: #fffbeb;\n border: 1px solid #fef3c7;\n color: #b45309;\n }\n .ngx-record-editor__rows {\n border: 1px solid #f3f4f6;\n border-radius: 8px;\n padding: 12px 14px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .ngx-record-editor__rows-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n }\n .ngx-record-editor__row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n background: #f9fafb;\n }\n .ngx-record-editor__row-text {\n flex: 1;\n font-size: 13px;\n overflow-wrap: anywhere;\n }\n .ngx-record-editor__row-btn {\n background: none;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n padding: 2px 8px;\n }\n .ngx-record-editor__row-empty {\n font-size: 12px;\n color: #6b7280;\n margin: 0;\n }\n .ngx-record-editor__drawer {\n border: 1px solid #dbeafe;\n background: #f8fafc;\n border-radius: 8px;\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .ngx-record-editor__summary-panel {\n background: #f9fafb;\n border: 1px solid #f3f4f6;\n border-radius: 8px;\n padding: 12px 16px;\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 12px;\n }\n .ngx-record-editor__summary-item {\n display: flex;\n flex-direction: column;\n cursor: pointer;\n padding: 6px 10px;\n border-radius: 6px;\n transition: background 0.15s;\n }\n .ngx-record-editor__summary-item:hover {\n background: #eff6ff;\n }\n .ngx-record-editor__summary-label {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #6b7280;\n font-weight: 600;\n }\n .ngx-record-editor__summary-val {\n font-size: 14px;\n font-weight: 600;\n color: #1f2937;\n }\n `,\n ],\n})\nexport class DynamicRecordFormComponent implements OnChanges {\n @Input() config!: EntityFormConfig;\n @Input() rules?: FormRule[];\n @Input() initialData?: Record<string, any>;\n @Input() userRoles: string[] = [];\n @Input() language: string = 'en';\n @Input() readonly: boolean = false;\n @Input() loading: boolean = false;\n @Input() error: string | null = null;\n /** Whole record read-only, regardless of RBAC. Equivalent to the reference's `isReadOnly`. */\n @Input() isReadOnly: boolean = false;\n /** Specific field ids forced read-only while the rest of the record stays editable. */\n @Input() readOnlyFields: string[] = [];\n /**\n * Open the record read-only, with a per-tab \"Edit section\" flow — one tab is edited and\n * validated at a time. This is the framework's `EntityRecordComponent` model and the\n * default here.\n *\n * Set false for a directly editable record with no view/edit distinction.\n */\n @Input() viewMode: boolean = true;\n\n @Output() formSubmit = new EventEmitter<Record<string, any>>();\n @Output() formChange = new EventEmitter<Record<string, any>>();\n @Output() formReset = new EventEmitter<void>();\n /** One tab section was saved. Carries the whole record, plus which tab was edited. */\n @Output() sectionSave = new EventEmitter<{ tabId: string; record: Record<string, any> }>();\n\n @ViewChild(DynamicFormComponent) dynamicFormComp?: DynamicFormComponent;\n\n private readonly rulesEvaluation = inject(RulesEvaluationService);\n private readonly rbacService = inject(RbacService);\n private readonly host: ElementRef<HTMLElement> = inject(ElementRef);\n private readonly injector = inject(Injector);\n\n readonly currentData = signal<Record<string, any>>({});\n readonly originalBaseline = signal<Record<string, any>>({});\n\n /**\n * Info banners the user has dismissed, by field id.\n *\n * The reference's contract: an info banner persists until dismissed, **not** until the\n * value changes. Dismissal is keyed by field so re-triggering a different field's rule\n * still shows. Re-armed when a different record is loaded.\n */\n private readonly dismissed = signal<ReadonlySet<string>>(new Set<string>());\n\n /**\n * Info banners from the rules engine that are still showing.\n *\n * A getter, not a `computed`: the source is `dynamicFormComp`, a ViewChild. A computed\n * evaluated before the view initialises would capture no dependency on the child's\n * `ruleResult` signal and then never recompute. Read per change-detection pass instead.\n */\n get infoBanners(): { fieldId: string; message: string }[] {\n const result = this.dynamicFormComp?.ruleResult();\n const gone = this.dismissed();\n return Object.entries(result?.infoBanners ?? {})\n .filter(([fieldId]) => !gone.has(fieldId))\n .map(([fieldId, message]) => ({ fieldId, message: String(message) }));\n }\n\n dismissInfoBanner(fieldId: string): void {\n this.dismissed.set(new Set(this.dismissed()).add(fieldId));\n }\n\n /**\n * Whether the current roles may edit this record.\n *\n * `userRoles` was declared as an input here and then read by nothing at all — this\n * component computed no permissions of any kind, so the record view was fully editable\n * for every role while the plain form at least hid its Save button. Cached on the same\n * terms as the sibling component: it depends only on `config` and `userRoles`.\n */\n private permissionsCache: ReturnType<RbacService['getPermissions']> | null = null;\n\n get permissions(): ReturnType<RbacService['getPermissions']> {\n return (this.permissionsCache ??= this.rbacService.getPermissions(this.config, this.userRoles));\n }\n\n /** True when nothing in the record may be edited. */\n get recordReadOnly(): boolean {\n return this.readonly || this.isReadOnly || !this.permissions.canEdit;\n }\n\n // ─── Inline array-row editing ───────────────────────────────────────────────\n\n /**\n * A row of an `array` field is edited in a drawer, not inline in the tab panel.\n *\n * The drawer is rendered outside the tab container on purpose: the reference found that\n * building a row's FormGroup inside the tab view races the tab's own initialisation, so\n * the row form is kept detached and only pushed into the FormArray on save.\n */\n readonly inlineRowField = signal<NestedFieldConfig | null>(null);\n readonly inlineRowIndex = signal<number | null>(null);\n inlineRowForm: FormGroup | null = null;\n\n /** `array` fields on the tab currently shown, so the template can list their rows. */\n get arrayFieldsForActiveTab(): NestedFieldConfig[] {\n const tabId = this.activeTabId;\n const tab = tabId ? findTab(this.config?.tabs, tabId) : null;\n return (tab?.fields ?? []).filter(f => f.type === 'array');\n }\n\n /**\n * Rows currently held by an `array` field, read from the record value.\n *\n * Deliberately not read off the child's FormArray: that control only exists once the\n * child has initialised, so rendering from it changed value mid-pass. `currentData` is a\n * signal seeded from `initialData` and kept current by the child's `formChange`.\n */\n rowsOf(field: NestedFieldConfig): Record<string, unknown>[] {\n const tabId = this.activeTabId;\n const tabData = tabId ? getTabData(tabId, this.currentData(), this.config) : null;\n const rows = (tabData as Record<string, unknown> | null)?.[field.id];\n return Array.isArray(rows) ? (rows as Record<string, unknown>[]) : [];\n }\n\n /** One row rendered as text, so the list is readable without opening the drawer. */\n rowSummary(field: NestedFieldConfig, row: Record<string, unknown>): string {\n const value = row ?? {};\n const parts = (field.children ?? [])\n .map(child => value[child.id])\n .filter(v => v !== null && v !== undefined && v !== '')\n .map(v => (typeof v === 'object' ? JSON.stringify(v) : String(v)));\n return parts.length ? parts.join(' · ') : '(empty)';\n }\n\n openAddRow(field: NestedFieldConfig): void {\n if (this.sectionReadOnly) return;\n this.inlineRowField.set(field);\n this.inlineRowIndex.set(null);\n this.inlineRowForm = this.dynamicFormComp?.createArrayRow(field) as FormGroup;\n }\n\n openEditRow(field: NestedFieldConfig, index: number): void {\n if (this.sectionReadOnly) return;\n this.inlineRowField.set(field);\n this.inlineRowIndex.set(index);\n this.inlineRowForm = this.dynamicFormComp?.createArrayRow(field, this.rowsOf(field)[index]) as FormGroup;\n }\n\n cancelRow(): void {\n this.inlineRowField.set(null);\n this.inlineRowIndex.set(null);\n this.inlineRowForm = null;\n }\n\n /** Commit the drawer into the FormArray. Rules re-evaluate off the resulting value change. */\n saveRow(): void {\n const field = this.inlineRowField();\n const form = this.dynamicFormComp;\n if (!field || !form || !this.inlineRowForm) return;\n\n if (this.inlineRowForm.invalid) {\n this.inlineRowForm.markAllAsTouched();\n return;\n }\n\n const array = form.getArrayControl(field.id, this.activeTabId ?? undefined);\n if (!array) return;\n\n const index = this.inlineRowIndex();\n if (index === null) array.push(form.createArrayRow(field, this.inlineRowForm.value));\n else array.at(index).patchValue(this.inlineRowForm.value);\n\n array.updateValueAndValidity();\n this.currentData.set(form.extractRecord());\n this.cancelRow();\n }\n\n deleteRow(field: NestedFieldConfig, index: number): void {\n if (this.sectionReadOnly) return;\n const array = this.dynamicFormComp?.getArrayControl(field.id, this.activeTabId ?? undefined);\n array?.removeAt(index);\n array?.updateValueAndValidity();\n if (this.dynamicFormComp) this.currentData.set(this.dynamicFormComp.extractRecord());\n if (this.inlineRowIndex() === index) this.cancelRow();\n }\n\n // ─── Per-tab section editing ────────────────────────────────────────────────\n\n /**\n * The tab currently open for editing, or null when the record is being viewed.\n *\n * The reference edits one tab section at a time rather than the whole record, and\n * validates only that section on save — a required field on an untouched tab must not\n * block saving the tab you are actually working on.\n */\n readonly editingTabId = signal<string | null>(null);\n\n /**\n * The tab the inner form is showing.\n *\n * Tracked here rather than read off the ViewChild. The child resolves its first tab as\n * part of its own initialisation, so reading it during this component's render changed\n * value mid-pass — an ExpressionChangedAfterItHasBeenChecked error. Seeded from the\n * config and kept in step by the child's `activeTabChange` output.\n */\n private readonly activeTabIdSig = signal<string | null>(null);\n\n get activeTabId(): string | null {\n return this.activeTabIdSig();\n }\n\n onActiveTabChange(tabId: string): void {\n if (this.activeTabIdSig() === tabId) return;\n this.activeTabIdSig.set(tabId);\n // Editing does not follow the user to another tab.\n this.editingTabId.set(null);\n this.cancelRow();\n }\n\n /** First tab a user can see, used to seed the active tab before the child reports one. */\n private firstVisibleTabId(): string | null {\n return this.config?.tabs?.find(t => t.visibility !== false)?.id ?? null;\n }\n\n /** Errors from the last save attempt, by field id. */\n readonly sectionErrors = signal<Record<string, string>>({});\n\n /** Template access to `Object.keys` for iterating the error map. */\n protected readonly Object = Object;\n\n get isEditingActiveTab(): boolean {\n // Without view mode there is no view/edit distinction — everything is always editable.\n if (!this.viewMode) return true;\n return !!this.activeTabId && this.editingTabId() === this.activeTabId;\n }\n\n /** Fields render read-only unless their own tab is the one being edited. */\n get sectionReadOnly(): boolean {\n return this.recordReadOnly || !this.isEditingActiveTab;\n }\n\n editSection(): void {\n if (!this.viewMode || this.recordReadOnly || !this.activeTabId) return;\n this.sectionErrors.set({});\n this.editingTabId.set(this.activeTabId);\n }\n\n /** Discard this section's edits, restoring each field from the session baseline. */\n cancelSection(): void {\n const tabId = this.editingTabId();\n const form = this.dynamicFormComp;\n if (tabId && form) {\n const tab = findTab(this.config?.tabs, tabId);\n const baselineTab = (getTabData(tabId, this.originalBaseline(), this.config) ?? {}) as Record<string, unknown>;\n for (const field of tab?.fields ?? []) {\n const baselineValue = baselineTab[field.id];\n\n // A FormArray cannot be restored with setValue — that demands a value shaped exactly\n // like the current rows. Rebuild it from the baseline rows instead.\n const array = form.getArrayControl(field.id, tabId);\n if (array) {\n array.clear();\n for (const row of Array.isArray(baselineValue) ? baselineValue : []) {\n array.push(form.createArrayRow(field, row));\n }\n array.updateValueAndValidity();\n continue;\n }\n\n form.getControl(field.id, tabId)?.setValue(baselineValue ?? null);\n }\n this.currentData.set(form.extractRecord());\n }\n this.sectionErrors.set({});\n this.editingTabId.set(null);\n }\n\n /**\n * Validate this section only, then emit it. Validation is scoped two ways: Angular\n * validity of the tab's own controls, and rules filtered to this tab — a rule targeting\n * a hidden tab must not block the save (the reference's OV0-968 fix).\n */\n saveSection(): void {\n const tabId = this.editingTabId();\n const form = this.dynamicFormComp;\n if (!tabId || !form) return;\n\n const tab = findTab(this.config?.tabs, tabId);\n const errors: Record<string, string> = {};\n\n for (const field of tab?.fields ?? []) {\n const ctrl = form.getControl(field.id, tabId);\n if (ctrl?.invalid) {\n ctrl.markAsTouched();\n errors[field.id] = `${resolveLabel(field.label, this.language)} is invalid.`;\n }\n }\n\n const scoped = this.rulesEvaluation.filterForTab(this.rules, tabId, this.config);\n const ruleErrors = this.rulesEvaluation.evaluate(scoped, form.formValues(), this.originalBaseline())\n .validationErrors;\n Object.assign(errors, ruleErrors);\n\n if (Object.keys(errors).length > 0) {\n this.sectionErrors.set(errors);\n return;\n }\n\n this.sectionErrors.set({});\n this.editingTabId.set(null);\n\n const record = form.extractRecord();\n this.currentData.set(record);\n this.sectionSave.emit({ tabId, record });\n }\n\n /**\n * Seed the session baseline from the loaded record so `VALUE_CHANGED` rules and the\n * modification banner compare against the record as it was opened — not as it was\n * after the first keystroke.\n */\n ngOnChanges(changes: SimpleChanges): void {\n // Permissions depend on these two and nothing else; a stale cache would keep a record\n // editable after a role switch.\n if (changes['config'] || changes['userRoles']) {\n this.permissionsCache = null;\n }\n if (changes['initialData'] || changes['config']) {\n this.originalBaseline.set({ ...(this.initialData ?? {}) });\n this.currentData.set({ ...(this.initialData ?? {}) });\n this.activeTabIdSig.set(this.firstVisibleTabId());\n // A different record is a different set of banners — re-arm them.\n this.dismissed.set(new Set<string>());\n }\n }\n\n get recordTitle(): string {\n if (!this.config) return 'Record';\n return this.config.name ? resolveLabel(this.config.name, this.language) : this.config.entity;\n }\n\n get avatarLetter(): string {\n return (this.recordTitle || 'R').charAt(0).toUpperCase();\n }\n\n // ─── Header fields (isProfileImage / isHeaderToggle) ────────────────────────\n\n /** Every field in the config, at any depth. */\n private allFields(): NestedFieldConfig[] {\n const out: NestedFieldConfig[] = [];\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const f of fields ?? []) {\n out.push(f);\n walkFields(f.children);\n }\n };\n const walkTabs = (tabs: NestedTabConfig[] | undefined) => {\n for (const t of tabs ?? []) {\n walkFields(t.fields);\n walkTabs(t.children);\n }\n };\n walkTabs(this.config?.tabs);\n return out;\n }\n\n /** The field flagged `isProfileImage`, rendered as the record avatar. */\n get headerProfileField(): NestedFieldConfig | null {\n return this.allFields().find(f => f.isProfileImage) ?? null;\n }\n\n /** The field flagged `isHeaderToggle`, rendered as a status switch in the header. */\n get headerToggleField(): NestedFieldConfig | null {\n return this.allFields().find(f => f.isHeaderToggle) ?? null;\n }\n\n /** Avatar image URL, when the profile field holds a persisted FileRef. */\n get profileImageUrl(): string | null {\n const field = this.headerProfileField;\n if (!field) return null;\n const value = this.fieldValue(field.id) as { url?: string } | null;\n return value?.url ?? null;\n }\n\n get headerToggleValue(): boolean {\n const field = this.headerToggleField;\n return field ? this.fieldValue(field.id) === true : false;\n }\n\n /**\n * Flip the header toggle. It writes straight to the control rather than going through\n * section editing — the reference treats it as a record-level status switch, not part of\n * any one tab's section.\n */\n toggleHeaderStatus(): void {\n const field = this.headerToggleField;\n if (!field || this.recordReadOnly) return;\n const ctrl = this.controlFor(field.id);\n if (!ctrl) return;\n ctrl.setValue(!this.headerToggleValue);\n if (this.dynamicFormComp) this.currentData.set(this.dynamicFormComp.extractRecord());\n }\n\n /** Locate a field's control wherever it lives, since header fields may be on any tab. */\n private controlFor(fieldId: string): AbstractControl | null {\n return this.dynamicFormComp?.getControl(fieldId) ?? null;\n }\n\n /**\n * A field's current value, read from the record so it is stable during render.\n *\n * Resolved through `getTabData` so it honours exactly the nesting contract the form\n * patches with — `{ tabId: { fieldId } }`, or the record root when the tab sets\n * `flatData`. Reading the record flat instead is not a shortcut: it makes the summary\n * display values the form never loaded, which reads as \"the data is there\" while every\n * control behind it is empty.\n *\n * Walks sub-tabs as well: a summary, header, or profile field may sit on any tab at any\n * depth.\n */\n private fieldValue(fieldId: string): unknown {\n const visit = (tabs: NestedTabConfig[] = []): unknown => {\n for (const tab of tabs) {\n const data = getTabData(tab.id, this.currentData(), this.config) as Record<string, unknown> | null;\n if (data && fieldId in data) return data[fieldId];\n if (tab.children) {\n const found = visit(tab.children);\n if (found !== FIELD_NOT_FOUND) return found;\n }\n }\n return FIELD_NOT_FOUND;\n };\n\n const result = visit(this.config?.tabs);\n return result === FIELD_NOT_FOUND ? undefined : result;\n }\n\n readonly isModified = computed(() => {\n const orig = this.originalBaseline();\n const curr = this.currentData();\n if (!orig || !curr || Object.keys(orig).length === 0) return false;\n return JSON.stringify(orig) !== JSON.stringify(curr);\n });\n\n readonly summaryFields = computed<NestedFieldConfig[]>(() => {\n const fields: NestedFieldConfig[] = [];\n const walkTabs = (tabs: NestedTabConfig[] = []) => {\n for (const t of tabs) {\n for (const f of t.fields ?? []) {\n if (f.showOnMinimize) fields.push(f);\n }\n if (t.children) walkTabs(t.children);\n }\n };\n walkTabs(this.config?.tabs);\n return fields;\n });\n\n onFormChange(data: Record<string, any>): void {\n // Baseline is seeded from `initialData` in ngOnChanges; only fill it here when the\n // record was opened empty (create flow), so the first emitted shape becomes the baseline.\n if (Object.keys(this.originalBaseline()).length === 0) {\n this.originalBaseline.set({ ...data });\n }\n this.currentData.set(data);\n this.formChange.emit(data);\n }\n\n onFormSubmit(data: Record<string, any>): void {\n this.formSubmit.emit(data);\n }\n\n onFormReset(): void {\n this.formReset.emit();\n }\n\n formatFieldLabel(field: NestedFieldConfig): string {\n return resolveLabel(field.label, this.language);\n }\n\n /** Summary values render through the shared core formatter, not a local stringifier. */\n formatFieldValue(field: NestedFieldConfig): string {\n return formatDisplayValue(field.type, field.options, this.fieldValue(field.id), this.language);\n }\n\n /**\n * Finds which tab — and, where the field lives one level down, which sub-tab — owns a\n * field. The walk used to check top-level `fields` only, so every field in a sub-tab was\n * simply not found and the jump did nothing at all.\n */\n private locateField(fieldId: string): { tabId: string; subTabId?: string } | null {\n for (const tab of this.config?.tabs || []) {\n if ((tab.fields || []).some(f => f.id === fieldId)) return { tabId: tab.id };\n for (const child of tab.children || []) {\n if ((child.fields || []).some(f => f.id === fieldId)) {\n return { tabId: tab.id, subTabId: child.id };\n }\n }\n }\n return null;\n }\n\n /**\n * Switches to the tab holding `fieldId`, then scrolls it into view and moves focus to it.\n *\n * The wait for the new tab to render used to be a 50 ms `setTimeout`, which was wrong three\n * ways: `document` is undefined on a server render, 50 ms is a guess that a large tab can\n * outrun, and nothing cancelled the timer if the component went away first.\n * `afterNextRender` fixes all three — it never runs on the server, it runs when the panel\n * has actually rendered rather than when a guess expires, and it is tied to the injector so\n * destroying the component cancels it. The query is scoped to this component's own element,\n * so the library no longer reaches for the global `document` at all.\n */\n jumpToField(fieldId: string): void {\n const location = this.locateField(fieldId);\n if (!location) return;\n\n // The panel must not take the focus back: this jump is going to focus the field itself.\n this.dynamicFormComp?.setActiveTab(location.tabId, { focusPanel: false });\n // `setActiveTab` resets to a tab's first child, so the sub-tab has to be selected after\n // it, not before. Without this the walk found sub-tab fields and then rendered the wrong\n // panel, so the element the callback below looks for never existed.\n if (location.subTabId) {\n this.dynamicFormComp?.setActiveSubTab(location.subTabId, { focusPanel: false });\n }\n\n afterNextRender(\n () => {\n // The field id comes from config, so it never goes into a selector string: no\n // escaping to get wrong, and no need for `CSS.escape`, which jsdom and older\n // browsers do not provide and whose absence throws silently inside a render hook.\n const wanted = `field-container-${fieldId}`;\n const el = Array.from(\n this.host.nativeElement.querySelectorAll<HTMLElement>('[id^=\"field-container-\"]'),\n ).find(slot => slot.id === wanted);\n if (!el) return;\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n // The slot carries tabindex=\"-1\" so this actually moves focus. Without it the jump\n // scrolled the field into view and left focus behind on the link.\n el.focus();\n },\n { injector: this.injector },\n );\n }\n}\n","<div class=\"ngx-record-editor\">\n <!-- Record Header -->\n <div class=\"ngx-record-editor__header\">\n <div class=\"ngx-record-editor__title-group\">\n @if (profileImageUrl) {\n <img\n class=\"ngx-record-editor__avatar\"\n data-testid=\"header-profile-image\"\n [src]=\"profileImageUrl\"\n [alt]=\"recordTitle\"\n />\n } @else {\n <div class=\"ngx-record-editor__avatar\" data-testid=\"header-avatar-initial\">\n {{ avatarLetter }}\n </div>\n }\n <div>\n <h2 class=\"ngx-record-editor__title\" data-testid=\"record-title\">\n {{ recordTitle }}\n </h2>\n <span class=\"ngx-record-editor__subtitle\">Entity: {{ config.entity }}</span>\n </div>\n </div>\n\n <!-- Record-level status switch, outside section editing -->\n @if (headerToggleField; as toggleField) {\n <label class=\"ngx-record-editor__header-toggle\">\n <span>{{ formatFieldLabel(toggleField) }}</span>\n <input\n type=\"checkbox\"\n role=\"switch\"\n data-testid=\"header-toggle\"\n [checked]=\"headerToggleValue\"\n [disabled]=\"recordReadOnly\"\n [attr.aria-checked]=\"headerToggleValue\"\n (change)=\"toggleHeaderStatus()\"\n />\n <span class=\"ngx-record-editor__header-toggle-text\">{{ headerToggleValue ? 'Yes' : 'No' }}</span>\n </label>\n }\n </div>\n\n <!-- Dismissible info banners (rules `info` action) -->\n @for (banner of infoBanners; track banner.fieldId) {\n <div\n class=\"ngx-record-editor__banner ngx-record-editor__banner--info\"\n role=\"status\"\n [attr.data-testid]=\"'info-banner-' + banner.fieldId\"\n >\n <span>ℹ️ {{ banner.message }}</span>\n <button\n type=\"button\"\n class=\"ngx-record-editor__banner-dismiss\"\n [attr.data-testid]=\"'dismiss-' + banner.fieldId\"\n [attr.aria-label]=\"'Dismiss: ' + banner.message\"\n (click)=\"dismissInfoBanner(banner.fieldId)\"\n >✕</button>\n </div>\n }\n\n <!-- Modification baseline banner -->\n @if (isModified()) {\n <div class=\"ngx-record-editor__banner ngx-record-editor__banner--warning\">\n 🔒 Record modified from session baseline — unsaved changes pending.\n </div>\n }\n\n <!-- Summary Panel (showOnMinimize fields with interactive jump) -->\n @if (summaryFields().length > 0) {\n <div class=\"ngx-record-editor__summary-panel\" data-testid=\"summary-panel\">\n @for (sf of summaryFields(); track sf.id) {\n <div\n class=\"ngx-record-editor__summary-item\"\n [attr.data-testid]=\"'summary-' + sf.id\"\n (click)=\"jumpToField(sf.id)\"\n [title]=\"'Click to jump to ' + formatFieldLabel(sf)\"\n >\n <span class=\"ngx-record-editor__summary-label\">{{ formatFieldLabel(sf) }}</span>\n <span class=\"ngx-record-editor__summary-val\">{{ formatFieldValue(sf) }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Section edit bar: one tab is edited at a time, and validated on its own -->\n @if (viewMode && !recordReadOnly) {\n <div class=\"ngx-record-editor__section-bar\">\n @if (isEditingActiveTab) {\n <span class=\"ngx-record-editor__section-hint\">Editing this section</span>\n <button type=\"button\" class=\"ngx-form__reset\" data-testid=\"cancel-section\" (click)=\"cancelSection()\">\n Cancel\n </button>\n <button type=\"button\" class=\"ngx-form__submit\" data-testid=\"save-section\" (click)=\"saveSection()\">\n Save section\n </button>\n } @else {\n <button type=\"button\" class=\"ngx-form__reset\" data-testid=\"edit-section\" (click)=\"editSection()\">\n Edit section\n </button>\n }\n </div>\n }\n\n @if (Object.keys(sectionErrors()).length > 0) {\n <div class=\"ngx-record-editor__banner ngx-record-editor__banner--error\" role=\"alert\" data-testid=\"section-errors\">\n @for (key of Object.keys(sectionErrors()); track key) {\n <div>⚠️ {{ sectionErrors()[key] }}</div>\n }\n </div>\n }\n\n <!-- Array rows: listed here, edited in the drawer below -->\n @for (arrayField of arrayFieldsForActiveTab; track arrayField.id) {\n <div class=\"ngx-record-editor__rows\" [attr.data-testid]=\"'rows-' + arrayField.id\">\n <div class=\"ngx-record-editor__rows-head\">\n <span class=\"ngx-record-editor__summary-label\">{{ formatFieldLabel(arrayField) }}</span>\n @if (!sectionReadOnly) {\n <button\n type=\"button\"\n class=\"ngx-form__reset\"\n [attr.data-testid]=\"'add-row-' + arrayField.id\"\n (click)=\"openAddRow(arrayField)\"\n >+ Row</button>\n }\n </div>\n\n @for (row of rowsOf(arrayField); track $index) {\n <div class=\"ngx-record-editor__row\" [attr.data-testid]=\"'row-' + arrayField.id + '-' + $index\">\n <span class=\"ngx-record-editor__row-text\">{{ rowSummary(arrayField, row) }}</span>\n @if (!sectionReadOnly) {\n <button type=\"button\" class=\"ngx-record-editor__row-btn\"\n [attr.data-testid]=\"'edit-row-' + arrayField.id + '-' + $index\"\n (click)=\"openEditRow(arrayField, $index)\">Edit</button>\n <button type=\"button\" class=\"ngx-record-editor__row-btn\"\n [attr.data-testid]=\"'delete-row-' + arrayField.id + '-' + $index\"\n (click)=\"deleteRow(arrayField, $index)\">Delete</button>\n }\n </div>\n } @empty {\n <p class=\"ngx-record-editor__row-empty\">No rows yet.</p>\n }\n </div>\n }\n\n <!--\n Row drawer. Deliberately outside the tab panel: building a row's FormGroup inside the\n tab view races the tab's own initialisation (the reference hit this with FormArray).\n -->\n @if (inlineRowField(); as rowField) {\n <div class=\"ngx-record-editor__drawer\" data-testid=\"row-drawer\" [formGroup]=\"inlineRowForm!\">\n <div class=\"ngx-record-editor__rows-head\">\n <strong>{{ inlineRowIndex() === null ? 'Add' : 'Edit' }} {{ formatFieldLabel(rowField) }} row</strong>\n </div>\n\n <div class=\"ngx-form__panel\">\n @for (child of rowField.children ?? []; track child.id) {\n <ngx-dynamic-field\n [field]=\"child\"\n [control]=\"inlineRowForm!.get(child.id)!\"\n [config]=\"config\"\n [language]=\"language\"\n [readonly]=\"false\"\n [userRoles]=\"userRoles\"\n [style.gridColumn]=\"'span 12'\"\n />\n }\n </div>\n\n <div class=\"ngx-record-editor__section-bar\">\n <button type=\"button\" class=\"ngx-form__reset\" data-testid=\"cancel-row\" (click)=\"cancelRow()\">Cancel</button>\n <button type=\"button\" class=\"ngx-form__submit\" data-testid=\"save-row\" (click)=\"saveRow()\">Save row</button>\n </div>\n </div>\n }\n\n <!-- Main Dynamic Form -->\n <ngx-dynamic-form\n [config]=\"config\"\n [rules]=\"rules\"\n [initialData]=\"initialData\"\n [originalData]=\"originalBaseline()\"\n [userRoles]=\"userRoles\"\n [language]=\"language\"\n [readonly]=\"sectionReadOnly\"\n [readOnlyFields]=\"readOnlyFields\"\n [showInfoBanners]=\"false\"\n [loading]=\"loading\"\n [error]=\"error\"\n (formChange)=\"onFormChange($event)\"\n (formSubmit)=\"onFormSubmit($event)\"\n (formReset)=\"onFormReset()\"\n (activeTabChange)=\"onActiveTabChange($event)\"\n />\n</div>\n","// Tokens\nexport * from './lib/tokens/injection-tokens';\n\n// Providers\nexport * from './lib/providers/provide-ngx-dynamic-entity';\nexport * from './lib/providers/provide-field-types';\n\n// Services\nexport * from './lib/services/field-registry.service';\nexport * from './lib/services/hook-registry.service';\nexport * from './lib/services/validator-registry.service';\nexport * from './lib/services/entity-ref-registry.service';\nexport * from './lib/services/entity-ref-selection.service';\nexport * from './lib/services/cascade-data.service';\nexport * from './lib/services/entity-reference.service';\nexport * from './lib/services/entity-ref-cache';\nexport * from './lib/services/lookup-registry.service';\nexport * from './lib/services/rbac.service';\nexport * from './lib/services/rules-evaluation.service';\nexport * from './lib/services/config-source.service';\nexport * from './lib/services/validation-messages.service';\n\n// Components — the library ships form UI only; rendering a data table is the consumer's choice.\nexport * from './lib/form/dynamic-form.component';\nexport * from './lib/form/dynamic-record-form.component';\nexport * from './lib/form/dynamic-field/dynamic-field.component';\n\n// The contract a field component must satisfy to be registered with provideFieldTypes.\n// Previously this existed only as a code comment and an ADR that is gitignored, so a\n// consumer had no interface to implement against.\nexport * from './lib/field-types/field-component.contract';\n\n// Field type components — every one, individually importable.\n//\n// The tree-shaking seam is `provideFieldTypes({ image: ImageFieldComponent })`: register\n// only what you use and the rest never enters the bundle. That only works for components a\n// consumer can name, and ten of these were unreachable — so wanting eleven of the twenty\n// meant calling provideBuiltInFieldTypes() and bundling all of them, which is exactly what\n// the seam exists to avoid.\nexport * from './lib/field-types/text-field.component';\nexport * from './lib/field-types/textarea-field.component';\nexport * from './lib/field-types/markdown-field.component';\nexport * from './lib/field-types/number-field.component';\nexport * from './lib/field-types/currency-field.component';\nexport * from './lib/field-types/email-field.component';\nexport * from './lib/field-types/password-field.component';\nexport * from './lib/field-types/checkbox-field.component';\nexport * from './lib/field-types/boolean-field.component';\nexport * from './lib/field-types/date-field.component';\nexport * from './lib/field-types/date-time-field.component';\nexport * from './lib/field-types/time-field.component';\nexport * from './lib/field-types/month-year-field.component';\nexport * from './lib/field-types/dropdown-field.component';\nexport * from './lib/field-types/radio-field.component';\nexport * from './lib/field-types/multi-select-field.component';\nexport * from './lib/field-types/entity-ref-field.component';\nexport * from './lib/field-types/group-field.component';\nexport * from './lib/field-types/array-field.component';\nexport * from './lib/field-types/image-field.component';\nexport * from './lib/field-types/file-field.component';\n\n// Value helpers — a dropdown value is now a language-keyed object, so a consumer rendering\n// record values needs these. Re-exported so they don't have to depend on core directly.\nexport {\n resolveLabel,\n resolveOptionLabel,\n resolveOptionValue,\n formatDisplayValue,\n valuesMatch,\n normalizeOption,\n normalizeConfig,\n} from '@dynamic-entity/core';\n\n// Re-export core types so consumers need only one import\nexport type {\n EntityFormConfig,\n NestedTabConfig,\n NestedFieldConfig,\n FieldTableConfig,\n RichFieldType,\n LocalizedText,\n DropdownOption,\n VersionedRecord,\n EntityPermissions,\n RbacContext,\n FieldValidators,\n EntityReferenceConfig,\n EntityReferenceLoader,\n ReferenceOption,\n ReferenceLoaderContext,\n AutoPatchConfig,\n PatchOnTrueMapping,\n FileRef,\n FormRule,\n RuleCondition,\n RuleAction,\n RuleEvaluationResult,\n CommonModuleEntry,\n} from '@dynamic-entity/core';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["coreResolveEffectiveMask","coreShouldMaskField"],"mappings":"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"}