{
  "version": 3,
  "sources": ["../../src/i18n/locales/sv/r-common.json", "../../src/i18n/locales/sv/r-pipes.json", "../../src/i18n/locales/sv/r-validation.json", "../../src/i18n/icu.ts", "../../src/i18n/catalogue.ts", "../../src/i18n/locales/en/r-common.json", "../../src/i18n/locales/en/r-pipes.json", "../../src/i18n/locales/en/r-validation.json", "../../src/i18n/builtins.ts", "../../src/i18n/i18n.ts", "../../src/forms/FormReader.ts", "../../src/errors.ts", "../../src/forms/FormValidator.ts", "../../src/forms/setFormData.ts", "../../src/forms/ValidationRules.ts"],
  "sourcesContent": ["{\r\n    \"greeting\": \"Hej, {name}!\",\r\n    \"items\": \"{count, plural, one {# sak} other {# saker}}\"\r\n}\r\n", "{\r\n    \"today\": \"idag\",\r\n    \"yesterday\": \"ig\u00E5r\",\r\n    \"daysAgo\": \"{count, plural, one {# dag sedan} other {# dagar sedan}}\",\r\n    \"pieces\": \"{count, plural, =0 {inga} one {en} other {# st}}\"\r\n}\r\n", "{\r\n    \"required\": \"Detta f\u00E4lt \u00E4r obligatoriskt.\",\r\n    \"range\": \"Talet m\u00E5ste vara mellan {min} och {max}, var {actual}.\",\r\n    \"digits\": \"Ange endast siffror.\"\r\n}\r\n", "/**\r\n * @module icu\r\n * ICU message format support for internationalization.\r\n * Provides pluralization, select, and value interpolation.\r\n *\r\n * @example\r\n * // Simple interpolation\r\n * formatICU('Hello, {name}!', { name: 'World' });\r\n * // Returns: 'Hello, World!'\r\n *\r\n * @example\r\n * // Pluralization\r\n * formatICU('{count, plural, one {# item} other {# items}}', { count: 5 });\r\n * // Returns: '5 items'\r\n *\r\n * @example\r\n * // Select\r\n * formatICU('{gender, select, male {He} female {She} other {They}}', { gender: 'female' });\r\n * // Returns: 'She'\r\n */\r\n\r\nconst pluralRulesCache = new Map<string, Intl.PluralRules>();\r\n\r\n/**\r\n * Function type for message formatters.\r\n * Implement this to provide custom message formatting.\r\n */\r\nexport type MessageFormatter = (\r\n    message: string,\r\n    values?: Record<string, any>,\r\n    locale?: string\r\n) => string;\r\n\r\n\r\nfunction getPluralRule(locale: string): Intl.PluralRules {\r\n    if (!pluralRulesCache.has(locale)) {\r\n        pluralRulesCache.set(locale, new Intl.PluralRules(locale));\r\n    }\r\n    return pluralRulesCache.get(locale)!;\r\n}\r\n\r\nfunction escapeRegex(s: string): string {\r\n    return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n\r\n/**\r\n * Default ICU message formatter implementation.\r\n * Supports simple interpolation, pluralization with exact matches, and select.\r\n *\r\n * @param message - ICU format message string\r\n * @param values - Values to interpolate\r\n * @param locale - Locale for plural rules (default: 'en')\r\n * @returns Formatted message string\r\n *\r\n * @example\r\n * defaultFormatICU('{n, plural, =0 {none} one {# item} other {# items}}', { n: 0 }, 'en');\r\n * // Returns: 'none'\r\n *\r\n * @example\r\n * defaultFormatICU('{role, select, admin {Full access} other {Limited access}}', { role: 'admin' });\r\n * // Returns: 'Full access'\r\n */\r\nexport function defaultFormatICU(\r\n    message: string,\r\n    values?: Record<string, any>,\r\n    locale: string = 'en'\r\n): string {\r\n    return message.replace(\r\n        /\\{(\\w+)(?:, (plural|select),((?:[^{}]*\\{[^{}]*\\})+))?\\}/g,\r\n        (_, key, type, categoriesPart) => {\r\n            const value = values?.[key];\r\n\r\n            if (type === 'plural') {\r\n                const exact = new RegExp(\r\n                    `=${escapeRegex(String(value))}\\\\s*\\\\{([^{}]*)\\\\}`\r\n                ).exec(categoriesPart);\r\n                if (exact) {\r\n                    return exact[1]\r\n                        .replace(`{${key}}`, String(value))\r\n                        .replace('#', String(value));\r\n                }\r\n\r\n                const rules = getPluralRule(locale);\r\n                const category = rules.select(value);\r\n                const match =\r\n                    new RegExp(`${category}\\\\s*\\\\{([^{}]*)\\\\}`).exec(categoriesPart) ||\r\n                    new RegExp(`other\\\\s*\\\\{([^{}]*)\\\\}`).exec(categoriesPart);\r\n                if (match) {\r\n                    return match[1]\r\n                        .replace(`{${key}}`, String(value))\r\n                        .replace('#', String(value));\r\n                }\r\n                return String(value);\r\n            }\r\n\r\n            if (type === 'select') {\r\n                const escaped = escapeRegex(String(value));\r\n                const match =\r\n                    new RegExp(`\\\\b${escaped}\\\\s*\\\\{([^{}]*)\\\\}`).exec(categoriesPart) ||\r\n                    new RegExp(`\\\\bother\\\\s*\\\\{([^{}]*)\\\\}`).exec(categoriesPart);\r\n                return match ? match[1] : String(value);\r\n            }\r\n\r\n            return value !== undefined ? String(value) : `{${key}}`;\r\n        },\r\n    );\r\n}\r\n\r\n/**\r\n * The active message formatter. Defaults to `defaultFormatICU`.\r\n * Can be replaced with `setMessageFormatter` for custom formatting.\r\n */\r\nexport let formatICU: MessageFormatter = defaultFormatICU;\r\n\r\n/**\r\n * Replaces the default message formatter with a custom implementation.\r\n * Use this to integrate with external i18n libraries like FormatJS.\r\n *\r\n * @param formatter - The custom formatter function\r\n *\r\n * @example\r\n * // Use FormatJS IntlMessageFormat\r\n * import { IntlMessageFormat } from 'intl-messageformat';\r\n *\r\n * setMessageFormatter((message, values, locale) => {\r\n *     const fmt = new IntlMessageFormat(message, locale);\r\n *     return fmt.format(values);\r\n * });\r\n */\r\nexport function setMessageFormatter(formatter: MessageFormatter) {\r\n    formatICU = formatter;\r\n}", "/**\n * @module i18n/catalogue\n * Registry of translation files, filled by the application at startup.\n *\n * A bundler resolves import paths relative to the file that contains them, so a\n * library can never discover translation files that live in an application. The\n * application therefore hands its files to the library instead.\n *\n * @example\n * // Vite\n * import { registerCatalogue } from '@relax.js/core/i18n';\n * registerCatalogue(import.meta.glob('./locales/*\\/*.json', { eager: true }));\n *\n * @example\n * // Any bundler, or no bundler at all\n * import { registerNamespace } from '@relax.js/core/i18n';\n * import shellEn from './locales/en/shell.json';\n * registerNamespace('en', 'shell', shellEn);\n */\n\nexport type TranslationMap = Record<string, string>;\n\n/**\n * Loads a namespace the first time it is used, so translations for locales\n * nobody selects stay out of the initial download.\n */\nexport type NamespaceLoader = () => Promise<TranslationMap | { default: TranslationMap }>;\n\n/**\n * A namespace given either as ready messages or as a loader that fetches them.\n */\nexport type NamespaceSource = TranslationMap | NamespaceLoader;\n\nconst catalogue: Record<string, Record<string, NamespaceSource>> = {};\n\n/**\n * Reduces `en-US` to `en`, so a browser language matches a translation folder.\n */\nexport function normalizeLocale(locale: string): string {\n    return locale.toLowerCase().split('-')[0];\n}\n\nfunction unwrapModule(value: TranslationMap | { default: TranslationMap }): TranslationMap {\n    const candidate = (value as { default?: TranslationMap }).default;\n    return candidate && typeof candidate === 'object' ? candidate : (value as TranslationMap);\n}\n\n/**\n * Adds a single namespace to the catalogue.\n *\n * Registering the same locale and namespace twice replaces the previous entry,\n * which lets an application override a built-in namespace such as `r-validation`.\n *\n * @param locale - Locale code, normalized the same way as `setLocale()`\n * @param namespace - Namespace name used in front of the colon in `t('shell:title')`\n * @param source - The messages, or a function that loads them on first use\n *\n * @example\n * import shellEn from './locales/en/shell.json';\n * registerNamespace('en', 'shell', shellEn);\n *\n * @example\n * registerNamespace('sv', 'shell', () => import('./locales/sv/shell.json'));\n */\nexport function registerNamespace(\n    locale: string,\n    namespace: string,\n    source: NamespaceSource,\n): void {\n    const normalized = normalizeLocale(locale);\n    if (!catalogue[normalized]) catalogue[normalized] = {};\n    catalogue[normalized][namespace] = source;\n}\n\n/**\n * Adds every namespace in a path-keyed record, so a whole `locales/` folder is\n * registered in one call.\n *\n * The locale and namespace are read from the last two segments of each key, so\n * `./locales/en/shell.json` becomes locale `en` and namespace `shell`. Values may\n * be the messages, a module with the messages as its default export, or a\n * function returning either. That covers Vite's eager and lazy `import.meta.glob`,\n * webpack's `require.context`, and a plain object written by hand.\n *\n * @param modules - Record keyed by file path\n *\n * @example\n * // Vite, everything in the first download\n * registerCatalogue(import.meta.glob('./locales/*\\/*.json', { eager: true }));\n *\n * @example\n * // Vite, each locale downloaded when it is first selected\n * registerCatalogue(import.meta.glob('./locales/*\\/*.json'));\n *\n * @example\n * // No bundler\n * registerCatalogue({\n *     './locales/en/shell.json': { title: 'Dashboard' },\n *     './locales/sv/shell.json': { title: 'Instrumentpanel' },\n * });\n */\nexport function registerCatalogue(modules: Record<string, unknown>): void {\n    for (const path of Object.keys(modules)) {\n        const segments = path.replace(/\\.json$/i, '').split('/').filter(Boolean);\n        if (segments.length < 2) {\n            console.warn(\n                `i18n: skipped catalogue entry '${path}' because it has no {locale}/{namespace} part.`,\n            );\n            continue;\n        }\n        const namespace = segments[segments.length - 1];\n        const locale = segments[segments.length - 2];\n        registerNamespace(locale, namespace, modules[path] as NamespaceSource);\n    }\n}\n\n/**\n * Returns the messages for a namespace, or `undefined` when it was never registered.\n *\n * Rejects when a registered loader fails, so a network error is reported rather\n * than mistaken for a namespace nobody registered.\n */\nexport async function resolveNamespace(\n    locale: string,\n    namespace: string,\n): Promise<TranslationMap | undefined> {\n    const source = catalogue[normalizeLocale(locale)]?.[namespace];\n    if (!source) return undefined;\n    if (typeof source === 'function') return unwrapModule(await source());\n    return unwrapModule(source);\n}\n", "{\r\n    \"greeting\": \"Hello, {name}!\",\r\n    \"items\": \"{count, plural, one {# item} other {# items}}\"\r\n}\r\n", "{\r\n    \"today\": \"today\",\r\n    \"yesterday\": \"yesterday\",\r\n    \"daysAgo\": \"{count, plural, one {# day ago} other {# days ago}}\",\r\n    \"pieces\": \"{count, plural, =0 {none} one {one} other {# pcs}}\"\r\n}\r\n", "{\r\n    \"required\": \"This field is required.\",\r\n    \"range\": \"Number must be between {min} and {max}, was {actual}.\",\r\n    \"digits\": \"Please enter only digits.\"\r\n}\r\n", "/**\n * @module i18n/builtins\n * Registers the namespaces that ship with Relaxjs.\n *\n * English is imported directly so it is always present in the bundle and can act\n * as the fallback for every other locale. The remaining locales are loaded the\n * first time they are selected.\n */\n\nimport { registerNamespace } from './catalogue';\nimport enCommon from './locales/en/r-common.json';\nimport enPipes from './locales/en/r-pipes.json';\nimport enValidation from './locales/en/r-validation.json';\n\n/**\n * Fills the catalogue with `r-common`, `r-pipes`, and `r-validation`.\n *\n * Called once when the i18n module loads. An application may replace any of these\n * afterwards by registering the same locale and namespace again.\n */\nexport function registerBuiltinNamespaces(): void {\n    registerNamespace('en', 'r-common', enCommon);\n    registerNamespace('en', 'r-pipes', enPipes);\n    registerNamespace('en', 'r-validation', enValidation);\n\n    registerNamespace('sv', 'r-common', () => import('./locales/sv/r-common.json'));\n    registerNamespace('sv', 'r-pipes', () => import('./locales/sv/r-pipes.json'));\n    registerNamespace('sv', 'r-validation', () => import('./locales/sv/r-validation.json'));\n}\n", "/**\r\n * @module i18n\r\n * Internationalization support with namespace-based translations.\r\n * Uses ICU message format for pluralization, select, and formatting.\r\n *\r\n * @example\r\n * // Initialize locale\r\n * await setLocale('sv');\r\n *\r\n * // Use translations\r\n * const greeting = t('r-common:greeting', { name: 'John' });\r\n * const items = t('shop:items', { count: 5 });\r\n */\r\n\r\nimport { formatICU } from './icu';\r\nimport { registerBuiltinNamespaces } from './builtins';\r\nimport { normalizeLocale, resolveNamespace, TranslationMap } from './catalogue';\r\n\r\ntype Locale = string;\r\ntype Namespace = string;\r\ntype Translations = Record<Namespace, TranslationMap>;\r\n\r\n/**\r\n * Extra behaviour for a single `t()` call.\r\n */\r\nexport interface TranslateOptions {\r\n    /**\r\n     * Text to show when the key is missing, instead of the key itself.\r\n     *\r\n     * Use it for wording that must never be absent, such as a legally required\r\n     * notice. The fallback goes through the same formatter, so it can contain\r\n     * placeholders.\r\n     */\r\n    fallback?: string;\r\n}\r\n\r\nexport type MissingTranslationHandler = (\r\n    key: string,\r\n    namespace: string,\r\n    locale: string,\r\n) => void;\r\n\r\n/**\r\n * Dispatched on `document` after `setLocale()` completes.\r\n * The `locale` property contains the new normalized locale code.\r\n *\r\n * @example\r\n * document.addEventListener('localechange', (e) => {\r\n *     console.log(`Locale changed to ${e.locale}`);\r\n *     this.render();\r\n * });\r\n */\r\nexport class LocaleChangeEvent extends Event {\r\n    readonly locale: string;\r\n    constructor(locale: string) {\r\n        super('localechange', { bubbles: false });\r\n        this.locale = locale;\r\n    }\r\n}\r\n\r\ndeclare global {\r\n    interface DocumentEventMap {\r\n        localechange: LocaleChangeEvent;\r\n    }\r\n}\r\n\r\nconst fallbackLocale: Locale = 'en';\r\nlet currentLocale: Locale = fallbackLocale;\r\nconst loadedNamespaces = new Set<Namespace>();\r\nconst translations: Translations = {};\r\nlet missingHandler: MissingTranslationHandler | null = null;\r\n\r\nregisterBuiltinNamespaces();\r\n\r\n/**\r\n * Sets the current locale and loads the common namespace.\r\n * Clears previously loaded translations and dispatches a `localechange` event.\r\n *\r\n * @param locale - The locale code (e.g., 'en', 'sv', 'en-US')\r\n *\r\n * @example\r\n * await setLocale('sv');\r\n */\r\nexport async function setLocale(locale: string): Promise<void> {\r\n    const normalized = normalizeLocale(locale);\r\n    currentLocale = normalized;\r\n    loadedNamespaces.clear();\r\n    Object.keys(translations).forEach(ns => delete translations[ns]);\r\n    await loadNamespace('r-common');\r\n    if (typeof document !== 'undefined') {\r\n        document.dispatchEvent(new LocaleChangeEvent(normalized));\r\n    }\r\n}\r\n\r\nasync function tryResolve(\r\n    locale: Locale,\r\n    namespace: Namespace,\r\n): Promise<TranslationMap | undefined> {\r\n    try {\r\n        return await resolveNamespace(locale, namespace);\r\n    } catch (err) {\r\n        console.warn(\r\n            `i18n: could not load namespace '${namespace}' for locale '${locale}'.`,\r\n            err,\r\n        );\r\n        return undefined;\r\n    }\r\n}\r\n\r\n/**\r\n * Loads a translation namespace from the catalogue.\r\n * Falls back to the default locale when the namespace is not translated yet.\r\n *\r\n * Never rejects. A namespace nobody registered is reported as a warning so that\r\n * one forgotten file cannot stop the application from starting.\r\n *\r\n * @param namespace - The namespace to load (e.g., 'shop', 'errors')\r\n *\r\n * @example\r\n * await loadNamespace('shop');\r\n * const price = t('shop:priceLabel');\r\n */\r\nexport async function loadNamespace(namespace: Namespace): Promise<void> {\r\n    if (loadedNamespaces.has(namespace)) return;\r\n\r\n    let messages = await tryResolve(currentLocale, namespace);\r\n    if (!messages && currentLocale !== fallbackLocale) {\r\n        messages = await tryResolve(fallbackLocale, namespace);\r\n    }\r\n\r\n    if (!messages) {\r\n        console.warn(\r\n            `i18n: namespace '${namespace}' is not registered for locale '${currentLocale}'. ` +\r\n            `Register it during startup with registerCatalogue() or registerNamespace().`,\r\n        );\r\n        return;\r\n    }\r\n\r\n    translations[namespace] = messages;\r\n    loadedNamespaces.add(namespace);\r\n}\r\n\r\n/**\r\n * Loads multiple translation namespaces in parallel.\r\n *\r\n * @param namespaces - Array of namespace names to load\r\n *\r\n * @example\r\n * await loadNamespaces(['r-pipes', 'r-validation']);\r\n */\r\nexport async function loadNamespaces(namespaces: Namespace[]): Promise<void> {\r\n    await Promise.all(namespaces.map(ns => loadNamespace(ns)));\r\n}\r\n\r\n/**\r\n * Translates a key with optional value interpolation.\r\n * Supports ICU message format for pluralization and select.\r\n *\r\n * @param fullKey - Translation key in format 'namespace:key' or just 'key' (uses 'r-common')\r\n * @param values - Values to interpolate into the message\r\n * @param options - Set `fallback` for text that must never be missing\r\n * @returns The translated string, the fallback, or the key if neither is available\r\n *\r\n * @example\r\n * // Simple translation\r\n * t('greeting'); // Uses r-common:greeting\r\n *\r\n * // With namespace\r\n * t('errors:notFound');\r\n *\r\n * // With interpolation\r\n * t('welcome', { name: 'John' }); // \"Welcome, John!\"\r\n *\r\n * // With pluralization (ICU format)\r\n * t('items', { count: 5 }); // \"5 items\" or \"5 f\u00F6rem\u00E5l\"\r\n *\r\n * // Wording that must never render as a raw key\r\n * t('shell:aiDisclosure', undefined, {\r\n *     fallback: 'You are interacting with an AI system.',\r\n * });\r\n */\r\nexport function t(\r\n    fullKey: string,\r\n    values?: Record<string, any>,\r\n    options?: TranslateOptions,\r\n): string {\r\n    const [namespace, key] = fullKey.includes(':')\r\n        ? fullKey.split(':')\r\n        : ['r-common', fullKey];\r\n    const message = translations[namespace]?.[key];\r\n\r\n    if (!message) {\r\n        if (missingHandler) missingHandler(key, namespace, currentLocale);\r\n        if (options?.fallback === undefined) return fullKey;\r\n        return format(options.fallback, values, options.fallback);\r\n    }\r\n\r\n    return format(message, values, options?.fallback ?? fullKey);\r\n}\r\n\r\nfunction format(message: string, values: Record<string, any> | undefined, onError: string): string {\r\n    try {\r\n        return formatICU(message, values, currentLocale) as string;\r\n    } catch {\r\n        return onError;\r\n    }\r\n}\r\n\r\n/**\r\n * Returns the current locale code.\r\n *\r\n * @returns The normalized locale code (e.g., 'en', 'sv')\r\n */\r\nexport function getCurrentLocale(): string {\r\n    return currentLocale;\r\n}\r\n\r\n/**\r\n * Registers a handler called when `t()` encounters a missing translation key.\r\n * Pass `null` to remove the handler.\r\n *\r\n * @param handler - Callback receiving the key, namespace, and locale\r\n *\r\n * @example\r\n * onMissingTranslation((key, ns, locale) => {\r\n *     console.warn(`Missing: ${ns}:${key} [${locale}]`);\r\n * });\r\n */\r\nexport function onMissingTranslation(handler: MissingTranslationHandler | null): void {\r\n    missingHandler = handler;\r\n}\r\n", "/**\r\n * @module FormReader\r\n * Utilities for reading form data into typed objects.\r\n * Handles type conversion based on input types and data-type attributes.\r\n *\r\n * @example\r\n * // Basic form reading\r\n * const form = document.querySelector('form');\r\n * const data = readData(form);\r\n *\r\n * // Type-safe mapping to a class instance\r\n * const user = mapFormToClass(form, new UserDTO());\r\n */\r\n\r\nimport { getCurrentLocale } from '../i18n/i18n';\r\n\r\n/**\r\n * Maps form field values to a class instance's properties.\r\n * Automatically converts values based on input types (checkbox, number, date).\r\n *\r\n * Form field names must match property names on the target instance.\r\n *\r\n * @template T - The type of the class instance\r\n * @param form - The HTML form element to read from\r\n * @param instance - The class instance to populate\r\n * @param options - Configuration options\r\n * @param options.throwOnMissingProperty - Throw if form field has no matching property\r\n * @param options.throwOnMissingField - Throw if class property has no matching form field\r\n * @returns The populated instance\r\n *\r\n * @example\r\n * class UserDTO {\r\n *     name: string = '';\r\n *     email: string = '';\r\n *     age: number = 0;\r\n *     newsletter: boolean = false;\r\n * }\r\n *\r\n * const form = document.querySelector('form');\r\n * const user = mapFormToClass(form, new UserDTO());\r\n * console.log(user.name, user.age, user.newsletter);\r\n *\r\n * @example\r\n * // With validation\r\n * const user = mapFormToClass(form, new UserDTO(), {\r\n *     throwOnMissingProperty: true,  // Catch typos in form field names\r\n *     throwOnMissingField: true      // Ensure all DTO fields are in form\r\n * });\r\n */\r\nexport function mapFormToClass<T extends object>(\r\n    form: HTMLFormElement,\r\n    instance: T,\r\n    options: {\r\n        throwOnMissingProperty?: boolean;\r\n        throwOnMissingField?: boolean;\r\n    } = {}\r\n): T {\r\n    const formElements = form.querySelectorAll('input, select, textarea');\r\n\r\n    formElements.forEach((element) => {\r\n        if (!element.hasAttribute('name')) return;\r\n        if (booleanAttr(element, 'disabled')) return;\r\n\r\n        const propertyName = element.getAttribute('name')!;\r\n\r\n        if (!(propertyName in instance)) {\r\n            if (options.throwOnMissingProperty) {\r\n                throw new Error(\r\n                    `Form field \"${propertyName}\" has no matching property in class instance`\r\n                );\r\n            }\r\n            return;\r\n        }\r\n\r\n        const value = readElementValue(element);\r\n        if (value === SKIP) return;\r\n\r\n        (instance as Record<string, unknown>)[propertyName] = value;\r\n    });\r\n\r\n    if (options.throwOnMissingField) {\r\n        const formFieldNames = new Set<string>();\r\n        formElements.forEach((element) => {\r\n            if (element.hasAttribute('name')) {\r\n                formFieldNames.add(element.getAttribute('name')!);\r\n            }\r\n        });\r\n\r\n        for (const prop in instance) {\r\n            if (\r\n                typeof instance[prop] !== 'function' &&\r\n                Object.prototype.hasOwnProperty.call(instance, prop) &&\r\n                !formFieldNames.has(prop)\r\n            ) {\r\n                throw new Error(\r\n                    `Class property \"${prop}\" has no matching form field`\r\n                );\r\n            }\r\n        }\r\n    }\r\n\r\n    return instance;\r\n}\r\n\r\n/**\r\n * Configuration options for form reading operations.\r\n */\r\nexport interface FormReaderOptions {\r\n    /** Prefix to strip from field names when mapping to properties */\r\n    prefix?: string;\r\n    /** If true, checkboxes return their value instead of true/false */\r\n    disableBinaryCheckbox?: boolean;\r\n    /** If true, radio buttons return their value instead of true/false */\r\n    disableBinaryRadioButton?: boolean;\r\n}\r\n\r\n/**\r\n * Gets the appropriate type converter function for a form element.\r\n * Uses the `data-type` attribute if present, otherwise infers from input type.\r\n *\r\n * @param element - The form element to get a converter for\r\n * @returns A function that converts string values to the appropriate type\r\n *\r\n * @example\r\n * // With data-type attribute\r\n * <input name=\"age\" data-type=\"number\" />\r\n * const converter = getDataConverter(input);\r\n * converter('42'); // Returns: 42 (number)\r\n *\r\n * @example\r\n * // Inferred from input type\r\n * <input type=\"checkbox\" name=\"active\" />\r\n * const converter = getDataConverter(checkbox);\r\n * converter('true'); // Returns: true (boolean)\r\n */\r\nexport function getDataConverter(element: HTMLElement): ConverterFunc {\r\n    const dataType = element.getAttribute('data-type') as DataType | null;\r\n    if (dataType) {\r\n        return createConverterFromDataType(dataType);\r\n    }\r\n\r\n    if (element instanceof HTMLInputElement) {\r\n        return createConverterFromInputType(element.type as InputType);\r\n    }\r\n\r\n    // Handle custom form-associated elements with checked property (boolean values)\r\n    if ('checked' in element && typeof (element as any).checked === 'boolean') {\r\n        return BooleanConverter as ConverterFunc;\r\n    }\r\n\r\n    return (str) => str;\r\n}\r\n\r\n\r\n/**\r\n * Reads all form data into a plain object with automatic type conversion.\r\n * Handles multiple values (e.g., multi-select) and custom form-associated elements.\r\n *\r\n * Type conversion is based on:\r\n * 1. `data-type` attribute if present (number, boolean, string, Date)\r\n * 2. Input type (checkbox, number, date, etc.)\r\n * 3. Falls back to string\r\n *\r\n * @param form - The HTML form element to read\r\n * @returns Object with property names matching field names\r\n *\r\n * @example\r\n * // HTML form\r\n * <form>\r\n *     <input name=\"username\" value=\"john\" />\r\n *     <input name=\"age\" type=\"number\" value=\"25\" />\r\n *     <input name=\"active\" type=\"checkbox\" checked />\r\n *     <select name=\"colors\" multiple>\r\n *         <option value=\"red\" selected>Red</option>\r\n *         <option value=\"blue\" selected>Blue</option>\r\n *     </select>\r\n * </form>\r\n *\r\n * // Reading the form\r\n * const data = readData(form);\r\n * // Returns: { username: 'john', age: 25, active: true, colors: ['red', 'blue'] }\r\n *\r\n * @example\r\n * // With custom form elements\r\n * <form>\r\n *     <r-input name=\"email\" value=\"test@example.com\" />\r\n *     <r-checkbox name=\"terms\" checked />\r\n * </form>\r\n * const data = readData(form);\r\n 1*/\r\nexport function readData<T = Record<string, unknown>>(form: HTMLFormElement): T{\r\n    const data: Record<string, unknown> = {};\r\n    const formData = new FormData(form);\r\n    const seen = new Set<string>();\r\n\r\n    formData.forEach((_, name) => {\r\n        if (seen.has(name)) return;\r\n        seen.add(name);\r\n\r\n        const values = formData.getAll(name);\r\n        const element = form.elements.namedItem(name);\r\n        const converter = element ? getDataConverter(element as HTMLElement) : (v: string) => v;\r\n\r\n        if (values.length === 1) {\r\n            const v = values[0];\r\n            data[name] = typeof v === 'string' ? converter(v) : v;\r\n        } else {\r\n            data[name] = values.map(v => typeof v === 'string' ? converter(v) : v);\r\n        }\r\n    });\r\n\r\n    for (let i = 0; i < form.elements.length; i++) {\r\n        const el = form.elements[i] as HTMLInputElement;\r\n        if (el.type === 'checkbox' && el.name && !seen.has(el.name)) {\r\n            seen.add(el.name);\r\n            data[el.name] = false;\r\n        }\r\n    }\r\n\r\n    return data as T;\r\n}\r\n\r\n/**\r\n * Function type for converting string form values to typed values.\r\n */\r\nexport type ConverterFunc = (value: string) => unknown;\r\n\r\n/**\r\n * Supported data-type attribute values for explicit type conversion.\r\n */\r\nexport type DataType = 'number' | 'boolean' | 'string' | 'Date';\r\n\r\n/**\r\n * Supported HTML input types for automatic type inference.\r\n */\r\nexport type InputType =\r\n    | 'tel'\r\n    | 'text'\r\n    | 'checkbox'\r\n    | 'radio'\r\n    | 'number'\r\n    | 'color'\r\n    | 'date'\r\n    | 'datetime-local'\r\n    | 'month'\r\n    | 'week'\r\n    | 'time';\r\n\r\n/**\r\n * Converts string values to booleans.\r\n * Handles 'true'/'false' strings and numeric values (>0 is true).\r\n *\r\n * @param value - String value to convert\r\n * @returns Boolean value or undefined if empty\r\n * @throws Error if value cannot be interpreted as boolean\r\n */\r\nexport function BooleanConverter(value?: string): boolean | undefined {\r\n    if (!value || value == '') {\r\n        return undefined;\r\n    }\r\n\r\n    const lower = value.toLowerCase();\r\n\r\n    if (lower === 'true' || lower === 'on' || Number(value) > 0) {\r\n        return true;\r\n    }\r\n\r\n    if (lower === 'false' || lower === 'off' || Number(value) <= 0) {\r\n        return false;\r\n    }\r\n\r\n    throw new Error(\"Could not convert value '\" + value + \"' to boolean.\");\r\n}\r\n\r\n/**\r\n * Converts string values to numbers.\r\n *\r\n * @param value - String value to convert\r\n * @returns Number value or undefined if empty\r\n * @throws Error if value is not a valid number\r\n */\r\nexport function NumberConverter(value?: string): number | undefined {\r\n    if (!value || value == '') {\r\n        return undefined;\r\n    }\r\n    const nr = Number(value);\r\n    if (!isNaN(nr)) {\r\n        return nr;\r\n    }\r\n    throw new Error(\"Could not convert value '\" + value + \"' to number.\");\r\n}\r\n\r\n/**\r\n * Detects the order of day/month/year parts for a given locale\r\n * using `Intl.DateTimeFormat.formatToParts`.\r\n *\r\n * @example\r\n * getLocaleDateOrder('en-US')  // ['month', 'day', 'year']\r\n * getLocaleDateOrder('sv')     // ['year', 'month', 'day']\r\n * getLocaleDateOrder('de')     // ['day', 'month', 'year']\r\n */\r\nfunction getLocaleDateOrder(locale: string): ('day' | 'month' | 'year')[] {\r\n    const parts = new Intl.DateTimeFormat(locale).formatToParts(new Date(2024, 0, 15));\r\n    return parts\r\n        .filter((p): p is Intl.DateTimeFormatPart & { type: 'day' | 'month' | 'year' } =>\r\n            p.type === 'day' || p.type === 'month' || p.type === 'year')\r\n        .map(p => p.type);\r\n}\r\n\r\n/**\r\n * Converts string values to Date objects.\r\n * Supports both ISO format (`2024-01-15`) and locale-specific formats\r\n * (`01/15/2024` for en-US, `15.01.2024` for de, etc.) based on the\r\n * current i18n locale.\r\n *\r\n * @param value - Date string in ISO or locale format\r\n * @returns Date object\r\n * @throws Error if value is not a valid date\r\n *\r\n * @example\r\n * // ISO format (from <input type=\"date\">)\r\n * DateConverter('2024-01-15')   // Date(2024, 0, 15)\r\n *\r\n * // Locale format (from <input type=\"text\" data-type=\"Date\">)\r\n * // with locale set to 'sv': 2024-01-15\r\n * // with locale set to 'en-US': 01/15/2024\r\n * // with locale set to 'de': 15.01.2024\r\n */\r\nexport function DateConverter(value: string): Date | undefined {\r\n    if (!value || value === '') return undefined;\r\n\r\n    if (/^\\d{4}-\\d{2}-\\d{2}(T|$)/.test(value)) {\r\n        const date = new Date(value);\r\n        if (!isNaN(date.getTime())) return date;\r\n    }\r\n\r\n    const numericParts = value.split(/[\\/.\\-\\s]/);\r\n    if (numericParts.length >= 3 && numericParts.every(p => /^\\d+$/.test(p))) {\r\n        const locale = getCurrentLocale();\r\n        const order = getLocaleDateOrder(locale);\r\n        const mapped: Record<string, number> = {};\r\n        order.forEach((type, i) => {\r\n            mapped[type] = parseInt(numericParts[i], 10);\r\n        });\r\n\r\n        if (mapped.year !== undefined && mapped.month !== undefined && mapped.day !== undefined) {\r\n            if (mapped.year < 100) mapped.year += 2000;\r\n            const date = new Date(mapped.year, mapped.month - 1, mapped.day);\r\n            if (!isNaN(date.getTime())) return date;\r\n        }\r\n    }\r\n\r\n    const date = new Date(value);\r\n    if (isNaN(date.getTime())) {\r\n        throw new Error('Invalid date format');\r\n    }\r\n    return date;\r\n}\r\n\r\n/**\r\n * Creates a converter function based on the data-type attribute value.\r\n *\r\n * @param dataType - The data-type attribute value\r\n * @returns Appropriate converter function for the type\r\n */\r\nexport function createConverterFromDataType(dataType: DataType): ConverterFunc {\r\n    switch (dataType) {\r\n        case 'boolean':\r\n            return BooleanConverter as ConverterFunc;\r\n        case 'number':\r\n            return NumberConverter as ConverterFunc;\r\n        case 'Date':\r\n            return DateConverter;\r\n        case 'string':\r\n            return (value) => (!value || value == '' ? undefined : value);\r\n        default:\r\n            throw new Error(`Unknown data-type \"${dataType}\".`);\r\n    }\r\n}\r\n\r\n/**\r\n * Creates a converter function based on HTML input type.\r\n * Handles special types like checkbox, date, time, week, and month.\r\n *\r\n * @param inputType - The HTML input type attribute value\r\n * @returns Appropriate converter function for the type\r\n */\r\nexport function createConverterFromInputType(inputType: InputType): ConverterFunc {\r\n    switch (inputType) {\r\n        case 'checkbox':\r\n            return BooleanConverter as ConverterFunc;\r\n\r\n        case 'number':\r\n            return NumberConverter as ConverterFunc;\r\n\r\n        case 'date':\r\n        case 'datetime-local':\r\n            return DateConverter;\r\n\r\n        case 'month':\r\n            return (value) => {\r\n                const [year, month] = value.split('-').map(Number);\r\n                return new Date(year, month - 1);\r\n            };\r\n\r\n        case 'week':\r\n            return (value) => {\r\n                const [year, week] = value.split('-W').map(Number);\r\n                return { year, week };\r\n            };\r\n\r\n        case 'time':\r\n            return (value) => {\r\n                const [hours, minutes, seconds = 0] = value.split(':').map(Number);\r\n                return { hours, minutes, seconds };\r\n            };\r\n\r\n        default:\r\n            return (value) => (!value || value == '' ? undefined : value);\r\n    }\r\n}\r\n\r\nfunction booleanAttr(element: Element, name: string): boolean {\r\n    const el = element as Record<string, any>;\r\n    if (name in el && typeof el[name] === 'boolean') return el[name];\r\n    const attr = element.getAttribute(name);\r\n    if (attr === null) return false;\r\n    if (attr === '' || attr.toLowerCase() === 'true' || attr.toLowerCase() === name) return true;\r\n    return false;\r\n}\r\n\r\nconst SKIP = Symbol('skip');\r\n\r\nfunction readElementValue(element: Element): unknown {\r\n    const el = element as Record<string, any>;\r\n    const type = el.type || element.getAttribute('type') || '';\r\n\r\n    if (type === 'checkbox') {\r\n        return booleanAttr(element, 'checked');\r\n    }\r\n\r\n    if (type === 'radio') {\r\n        if (!booleanAttr(element, 'checked')) return SKIP;\r\n        return el.value;\r\n    }\r\n\r\n    if (type === 'number') {\r\n        return el.value ? Number(el.value) : null;\r\n    }\r\n\r\n    if (type === 'date') {\r\n        return el.value ? new Date(el.value) : null;\r\n    }\r\n\r\n    if ('selectedOptions' in el && booleanAttr(element, 'multiple')) {\r\n        return Array.from(el.selectedOptions as NodeListOf<HTMLOptionElement>)\r\n            .map((o: HTMLOptionElement) => o.value);\r\n    }\r\n\r\n    if ('value' in el) {\r\n        return el.value;\r\n    }\r\n\r\n    return undefined;\r\n}", "/**\r\n * Global error handling for Relaxjs.\r\n * Register a handler with `onError()` to intercept errors before they throw.\r\n * Call `ctx.suppress()` in the handler to prevent the error from being thrown.\r\n *\r\n * @example\r\n * import { onError } from 'relaxjs';\r\n *\r\n * onError((error, ctx) => {\r\n *     logToService(error.message, error.context);\r\n *     showToast(error.message);\r\n *     ctx.suppress();\r\n * });\r\n */\r\n\r\n/**\r\n * Passed to error handlers to control error behavior.\r\n * Call `suppress()` to prevent the error from being thrown.\r\n */\r\nexport interface ErrorContext {\r\n    suppress(): void;\r\n}\r\n\r\n/**\r\n * Error with structured context for debugging.\r\n * The `context` record contains details like route name, component tag, route data.\r\n *\r\n * @example\r\n * onError((error, ctx) => {\r\n *     console.log(error.context.route);\r\n *     console.log(error.context.componentTagName);\r\n * });\r\n */\r\nexport class RelaxError extends Error {\r\n    constructor(\r\n        message: string,\r\n        public context: Record<string, unknown>,\r\n    ) {\r\n        super(message);\r\n    }\r\n}\r\n\r\n/** @internal */\r\ntype ErrorHandler = (error: RelaxError, ctx: ErrorContext) => void;\r\n\r\nlet handler: ErrorHandler | null = null;\r\n\r\n/**\r\n * Registers a global error handler for Relaxjs errors.\r\n * The handler receives the error and an `ErrorContext`.\r\n * Call `ctx.suppress()` to prevent the error from being thrown.\r\n * Only one handler can be active at a time; subsequent calls replace the previous handler.\r\n *\r\n * @example\r\n * onError((error, ctx) => {\r\n *     if (error.context.route === 'optional-panel') {\r\n *         ctx.suppress();\r\n *         return;\r\n *     }\r\n *     showErrorDialog(error.message);\r\n * });\r\n */\r\nexport function onError(fn: ErrorHandler) {\r\n    handler = fn;\r\n}\r\n\r\n/**\r\n * Reports an error through the global handler.\r\n * Returns the `RelaxError` if it should be thrown, or `null` if the handler suppressed it.\r\n * The caller is responsible for throwing the returned error.\r\n *\r\n * @param message - Human-readable error description\r\n * @param context - Structured data for debugging (route, component, params, cause, etc.)\r\n * @returns The error to throw, or `null` if suppressed\r\n *\r\n * @example\r\n * const error = reportError('Failed to load route component', {\r\n *     route: 'user',\r\n *     componentTagName: 'user-profile',\r\n *     routeData: { id: 123 },\r\n * });\r\n * if (error) throw error;\r\n */\r\nexport function reportError(message: string, context: Record<string, unknown>): RelaxError | null {\r\n    const error = new RelaxError(message, context);\r\n    if (handler) {\r\n        let suppressed = false;\r\n        const ctx: ErrorContext = {\r\n            suppress() { suppressed = true; },\r\n        };\r\n        handler(error, ctx);\r\n        if (suppressed) {\r\n            return null;\r\n        }\r\n    }\r\n    return error;\r\n}\r\n\r\n/**\r\n * Wraps an async function into a synchronous callback suitable for addEventListener.\r\n * Catches promise rejections and reports them through the global error handler.\r\n *\r\n * @param fn - Async function to wrap\r\n * @returns Synchronous function that can be passed to addEventListener\r\n *\r\n * @example\r\n * button.addEventListener('click', asyncHandler(async (e) => {\r\n *     await saveData();\r\n * }));\r\n *\r\n * @example\r\n * form.addEventListener('submit', asyncHandler(async (e) => {\r\n *     e.preventDefault();\r\n *     await submitForm();\r\n * }));\r\n */\r\nexport function asyncHandler<TArgs extends unknown[]>(\r\n    fn: (...args: TArgs) => Promise<void>,\r\n): (...args: TArgs) => void {\r\n    return function (this: any, ...args: TArgs) {\r\n        fn.call(this, ...args).catch((cause: unknown) => {\r\n            const error = reportError('Async callback failed', { cause });\r\n            if (error) throw error;\r\n        });\r\n    };\r\n}\r\n", "import { reportError } from '../errors';\r\n\r\n/**\r\n * @module FormValidator\r\n * Form validation with support for native HTML5 validation and error summaries.\r\n * Provides automatic validation on submit with customizable behavior.\r\n *\r\n * @example\r\n * // Basic usage with submit callback\r\n * const form = document.querySelector('form');\r\n * const validator = new FormValidator(form, {\r\n *     submitCallback: () => saveData()\r\n * });\r\n *\r\n * @example\r\n * // With auto-validation on input\r\n * const validator = new FormValidator(form, {\r\n *     autoValidate: true,\r\n *     useSummary: true\r\n * });\r\n */\r\n\r\n/**\r\n * Gets the human-readable field name from its associated label.\r\n */\r\nfunction getFieldName(element: HTMLElement): string | null {\r\n    const id = element.getAttribute('id');\r\n    if (id) {\r\n        const form = element.closest('form');\r\n        if (form) {\r\n            const label = form.querySelector(`label[for=\"${id}\"]`) as HTMLLabelElement | null;\r\n            if (label) {\r\n                return label.textContent?.trim() || null;\r\n            }\r\n        }\r\n    }\r\n\r\n    return null;\r\n}\r\n\r\n/**\r\n * Configuration options for FormValidator.\r\n */\r\nexport interface ValidatorOptions {\r\n    /** Validate on every input event, not just submit */\r\n    autoValidate?: boolean;\r\n    /** Show errors in a summary element instead of browser tooltips */\r\n    useSummary?: boolean;\r\n    /** Custom validation function called before native validation */\r\n    customChecks?: (form: HTMLFormElement) => void;\r\n    /** Always prevent default form submission */\r\n    preventDefault?: boolean;\r\n    /** Prevent default on validation failure (default: true) */\r\n    preventDefaultOnFailed?: boolean;\r\n    /** Callback invoked when form passes validation */\r\n    submitCallback?: () => void | Promise<void>;\r\n}\r\n\r\n/**\r\n * Form validation helper that integrates with HTML5 validation.\r\n * Supports error summaries, auto-validation, and custom submit handling.\r\n *\r\n * @example\r\n * // Prevent submission and handle manually\r\n * class MyComponent extends HTMLElement {\r\n *     private validator: FormValidator;\r\n *\r\n *     connectedCallback() {\r\n *         const form = this.querySelector('form');\r\n *         this.validator = new FormValidator(form, {\r\n *             submitCallback: () => this.handleSubmit()\r\n *         });\r\n *     }\r\n *\r\n *     private async handleSubmit() {\r\n *         const data = readData(this.form);\r\n *         await fetch('/api/save', { method: 'POST', body: JSON.stringify(data) });\r\n *     }\r\n * }\r\n *\r\n * @example\r\n * // With error summary display\r\n * const validator = new FormValidator(form, {\r\n *     useSummary: true,\r\n *     autoValidate: true\r\n * });\r\n */\r\nexport class FormValidator {\r\n    private errorSummary?: HTMLDivElement;\r\n\r\n    constructor(\r\n        private form: HTMLFormElement,\r\n        private options?: ValidatorOptions\r\n    ) {\r\n        if (!this.form) {\r\n            throw new Error('Form must be specified.');\r\n        }\r\n\r\n        this.form.addEventListener('submit', (event) => {\r\n            if (\r\n                options?.preventDefault ||\r\n                this.options?.submitCallback != null\r\n            ) {\r\n                event.preventDefault();\r\n            }\r\n            if (this.options?.customChecks) {\r\n                this.options.customChecks(form);\r\n            }\r\n\r\n            if (this.validateForm()) {\r\n                try {\r\n                    const result = this.options?.submitCallback?.call(this);\r\n                    if (result instanceof Promise) {\r\n                        result.catch((cause) => {\r\n                            const error = reportError('submitCallback failed', { cause });\r\n                            if (error) throw error;\r\n                        });\r\n                    }\r\n                } catch (cause) {\r\n                    const error = reportError('submitCallback failed', { cause });\r\n                    if (error) throw error;\r\n                }\r\n            } else {\r\n                if (options?.preventDefaultOnFailed !== false) {\r\n                    event.preventDefault();\r\n                }\r\n            }\r\n        });\r\n\r\n        if (options?.autoValidate) {\r\n            form.addEventListener('input', (/*e: InputEvent*/) => {\r\n                this.validateForm();\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Validates all form fields.\r\n     * Uses native HTML5 validation and optionally displays an error summary.\r\n     *\r\n     * @returns true if form is valid, false otherwise\r\n     */\r\n    public validateForm(): boolean {\r\n        const formElements = Array.from(\r\n            this.form.querySelectorAll('input,textarea,select')\r\n        ) as (HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement)[];\r\n        let isFormValid = true;\r\n\r\n        if (this.options?.useSummary !== true) {\r\n            if (this.form.checkValidity()) {\r\n                return true;\r\n            }\r\n\r\n            this.form.reportValidity();\r\n            this.focusFirstErrorElement();\r\n            return false;\r\n        }\r\n\r\n        const errorMessages: string[] = [];\r\n\r\n        formElements.forEach((element) => {\r\n            if (!element.checkValidity()) {\r\n                isFormValid = false;\r\n                const fieldName =\r\n                    getFieldName.call(this, element) ||\r\n                    element.name ||\r\n                    'Unnamed Field';\r\n                errorMessages.push(\r\n                    `${fieldName}: ${element.validationMessage}`\r\n                );\r\n            }\r\n        });\r\n\r\n        if (!isFormValid) {\r\n            this.displayErrorSummary(errorMessages);\r\n            this.focusFirstErrorElement();\r\n        } else {\r\n            this.clearErrorSummary();\r\n        }\r\n\r\n        return isFormValid;\r\n    }\r\n\r\n    /**\r\n     * Displays a list of error messages in the summary element.\r\n     *\r\n     * @param messages - Array of error messages to display\r\n     */\r\n    public displayErrorSummary(messages: string[]) {\r\n        this.clearErrorSummary();\r\n        if (!this.errorSummary){\r\n            this.createErrorSummary();\r\n        }\r\n\r\n        const errorList = this.errorSummary!.querySelector('ul')!;\r\n        messages.forEach((message) => {\r\n            const listItem = document.createElement('li');\r\n            listItem.textContent = message;\r\n            errorList.appendChild(listItem);\r\n        });\r\n    }\r\n\r\n    private createErrorSummary() {\r\n        const errorSummary = document.createElement('div');\r\n        errorSummary.className = 'error-summary';\r\n        errorSummary.style.color = 'red';\r\n        errorSummary.setAttribute('role', 'alert');\r\n        errorSummary.setAttribute('aria-live', 'assertive');\r\n        errorSummary.setAttribute('aria-atomic', 'true');\r\n        this.errorSummary = errorSummary;\r\n\r\n        const errorList = document.createElement('ul');\r\n        this.errorSummary.appendChild(errorList);\r\n\r\n        this.form.prepend(errorSummary);\r\n    }\r\n    /**\r\n     * Adds a single error to the summary display.\r\n     *\r\n     * @param fieldName - The name of the field with the error\r\n     * @param message - The error message\r\n     */\r\n    public addErrorToSummary(fieldName: string, message: string) {\r\n        if (!this.errorSummary){\r\n            this.createErrorSummary();\r\n        }\r\n        const errorList = this.errorSummary!.querySelector('ul')!;\r\n        const listItem = document.createElement('li');\r\n        listItem.textContent = `${fieldName}: ${message}`;\r\n        errorList.appendChild(listItem);\r\n    }\r\n\r\n    /**\r\n     * Clears all errors from the summary display.\r\n     */\r\n    public clearErrorSummary() {\r\n        if (this.errorSummary){\r\n            const ul = this.errorSummary.querySelector('ul');\r\n            if (ul) ul.innerHTML = '';\r\n        }\r\n    }\r\n\r\n    private focusFirstErrorElement() {\r\n        const firstInvalidElement = this.form.querySelector(':invalid');\r\n        if (\r\n            firstInvalidElement instanceof HTMLElement &&\r\n            document.activeElement !== firstInvalidElement\r\n        ) {\r\n            firstInvalidElement.focus();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Finds a form element relative to the given element.\r\n     * Searches parent first, then direct children.\r\n     *\r\n     * @param element - The element to search from\r\n     * @returns The found form element\r\n     * @throws Error if no form is found\r\n     *\r\n     * @example\r\n     * class MyComponent extends HTMLElement {\r\n     *     connectedCallback() {\r\n     *         const form = FormValidator.FindForm(this);\r\n     *         new FormValidator(form);\r\n     *     }\r\n     * }\r\n     */\r\n    public static FindForm(element: HTMLElement): HTMLFormElement {\r\n        if (element.parentElement?.tagName == 'FORM') {\r\n            return <HTMLFormElement>element.parentElement;\r\n        } else {\r\n            for (let i = 0; i < element.children.length; i++) {\r\n                const child = element.children[i];\r\n                if (child.tagName == 'FORM') {\r\n                    return <HTMLFormElement>child;\r\n                }\r\n            }\r\n        }\r\n\r\n        throw new Error(\r\n            'Parent or a direct child must be a FORM for class ' +\r\n                element.constructor.name\r\n        );\r\n    }\r\n}\r\n", "/**\r\n * Sets form field values from a data object using the name attribute.\r\n * Supports dot notation for accessing nested properties and array handling.\r\n *\r\n * When `context` is provided, `<select>` elements are populated with options\r\n * before their value is set. The option source is resolved from either the\r\n * `data-source` attribute or, as a fallback, the select's `name` attribute.\r\n * The resolved property on `context` can be an array or a method returning\r\n * an array. The `data-source` attribute may also declare which item\r\n * properties to use as value and text.\r\n *\r\n * @param form - The HTML form element to populate\r\n * @param data - The data object containing values to set in the form\r\n * @param context - Optional sources used to populate `<select>` options\r\n *\r\n * @example\r\n * // Basic usage with flat object\r\n * const form = document.querySelector('form');\r\n * const data = { name: 'John', email: 'john@example.com' };\r\n * setFormData(form, data);\r\n *\r\n * @example\r\n * // Using with nested objects via dot notation\r\n * const form = document.querySelector('form');\r\n * const data = {\r\n *   user: {\r\n *     name: 'John',\r\n *     contact: {\r\n *       email: 'john@example.com'\r\n *     }\r\n *   }\r\n * };\r\n * // Form has fields with names like \"user.name\" and \"user.contact.email\"\r\n * setFormData(form, data);\r\n *\r\n * @example\r\n * // Using with simple arrays using [] notation\r\n * const form = document.querySelector('form');\r\n * const data = {\r\n *   hobbies: ['Reading', 'Cycling', 'Cooking']\r\n * };\r\n * // Form has multiple fields with names like \"hobbies[]\"\r\n * setFormData(form, data);\r\n *\r\n * @example\r\n * // Using with array of objects using numeric indexers\r\n * const form = document.querySelector('form');\r\n * const data = {\r\n *   users: [\r\n *     { name: 'John', email: 'john@example.com' },\r\n *     { name: 'Jane', email: 'jane@example.com' }\r\n *   ]\r\n * };\r\n * // Form has fields with names like \"users[0].name\", \"users[1].email\", etc.\r\n * setFormData(form, data);\r\n *\r\n * @example\r\n * // Populating a <select> from context using the name convention\r\n * // <select name=\"country\"></select>\r\n * setFormData(form, { country: 'se' }, {\r\n *   country: [\r\n *     { value: 'se', text: 'Sweden' },\r\n *     { value: 'us', text: 'United States' }\r\n *   ]\r\n * });\r\n *\r\n * @example\r\n * // Using data-source with custom value/text properties\r\n * // <select name=\"country\" data-source=\"countries(id, name)\"></select>\r\n * setFormData(form, { country: 2 }, {\r\n *   countries: [\r\n *     { id: 1, name: 'Sweden' },\r\n *     { id: 2, name: 'United States' }\r\n *   ]\r\n * });\r\n *\r\n * @example\r\n * // data-source as a method on context\r\n * // <select name=\"country\" data-source=\"getCountries\"></select>\r\n * setFormData(form, { country: 'se' }, {\r\n *   getCountries: () => [\r\n *     { value: 'se', text: 'Sweden' },\r\n *     { value: 'us', text: 'United States' }\r\n *   ]\r\n * });\r\n *\r\n * @example\r\n * // Grouping options into <optgroup> using a third field in data-source\r\n * // <select name=\"country\" data-source=\"countries(id, name, region)\"></select>\r\n * setFormData(form, { country: 2 }, {\r\n *   countries: [\r\n *     { id: 1, name: 'Sweden', region: 'Europe' },\r\n *     { id: 2, name: 'United States', region: 'Americas' },\r\n *     { id: 3, name: 'Germany', region: 'Europe' }\r\n *   ]\r\n * });\r\n * // Produces two <optgroup> elements, \"Europe\" and \"Americas\", in the\r\n * // order each group first appears in the items array.\r\n */\r\nexport function setFormData(form: HTMLFormElement, data: object, context?: object): void {\r\n    if (context) {\r\n        const selects = form.querySelectorAll('select[name]');\r\n        selects.forEach(select => {\r\n            populateSelectOptions(select as HTMLSelectElement, context as Record<string, any>);\r\n        });\r\n    }\r\n\r\n    const formElements = form.querySelectorAll('[name]');\r\n\r\n    formElements.forEach(element => {\r\n\r\n      const name = element.getAttribute('name');\r\n      if (!name) return;\r\n\r\n      // Handle simple array notation (e.g., hobbies[])\r\n      if (name.endsWith('[]')) {\r\n        const arrayName = name.slice(0, -2);\r\n        const arrayValue = getValueByComplexPath(data, arrayName);\r\n\r\n        if (Array.isArray(arrayValue)) {\r\n          const el = element as Record<string, any>;\r\n          const type = el.type || element.getAttribute('type') || '';\r\n\r\n          if (type === 'checkbox' || type === 'radio') {\r\n            el.checked = arrayValue.includes(el.value);\r\n          } else if ('options' in el && boolAttr(element, 'multiple')) {\r\n            arrayValue.forEach(val => {\r\n              const option = Array.from(el.options as HTMLOptionElement[])\r\n                .find((opt: HTMLOptionElement) => opt.value === String(val));\r\n              if (option) (option as HTMLOptionElement).selected = true;\r\n            });\r\n          } else if ('value' in el) {\r\n            const allWithName = form.querySelectorAll(`[name=\"${name}\"]`);\r\n            const idx = Array.from(allWithName).indexOf(element);\r\n            if (idx >= 0 && idx < arrayValue.length) {\r\n              el.value = String(arrayValue[idx]);\r\n            }\r\n          }\r\n        }\r\n        return;\r\n      }\r\n\r\n      // Handle complex paths with array indexers and dot notation\r\n      const value = getValueByComplexPath(data, name);\r\n      if (value === undefined || value === null) return;\r\n\r\n      setElementValue(element, value);\r\n    });\r\n  }\r\n  \r\n  function getValueByComplexPath(obj: object, path: string): any {\r\n    // Handle array indexers like users[0].name\r\n    const segments = [];\r\n    let currentSegment = '';\r\n    let inBrackets = false;\r\n    \r\n    for (let i = 0; i < path.length; i++) {\r\n      const char = path[i];\r\n      \r\n      if (char === '[' && !inBrackets) {\r\n        if (currentSegment) {\r\n          segments.push(currentSegment);\r\n          currentSegment = '';\r\n        }\r\n        inBrackets = true;\r\n        currentSegment += char;\r\n      } else if (char === ']' && inBrackets) {\r\n        currentSegment += char;\r\n        segments.push(currentSegment);\r\n        currentSegment = '';\r\n        inBrackets = false;\r\n      } else if (char === '.' && !inBrackets) {\r\n        if (currentSegment) {\r\n          segments.push(currentSegment);\r\n          currentSegment = '';\r\n        }\r\n      } else {\r\n        currentSegment += char;\r\n      }\r\n    }\r\n    \r\n    if (currentSegment) {\r\n      segments.push(currentSegment);\r\n    }\r\n    \r\n    return segments.reduce<any>((result, segment) => {\r\n      if (!result || typeof result !== 'object') return undefined;\r\n\r\n      // Handle array indexer segments like [0]\r\n      if (segment.startsWith('[') && segment.endsWith(']')) {\r\n        const index = segment.slice(1, -1);\r\n        return result[index];\r\n      }\r\n\r\n      return result[segment];\r\n    }, obj);\r\n  }\r\n\r\n  function setElementValue(element: Element, value: any): void {\r\n    const el = element as Record<string, any>;\r\n    const type = el.type || element.getAttribute('type') || '';\r\n\r\n    if (type === 'checkbox') {\r\n      el.checked = Boolean(value);\r\n    } else if (type === 'radio') {\r\n      el.checked = el.value === String(value);\r\n    } else if (type === 'date' && value instanceof Date) {\r\n      el.value = value.toISOString().split('T')[0];\r\n    } else if (type === 'datetime-local' && value instanceof Date) {\r\n      const pad = (n: number) => String(n).padStart(2, '0');\r\n      el.value = `${value.getFullYear()}-${pad(value.getMonth() + 1)}-${pad(value.getDate())}T${pad(value.getHours())}:${pad(value.getMinutes())}`;\r\n    } else if ('options' in el && boolAttr(element, 'multiple') && Array.isArray(value)) {\r\n      const options = Array.from(el.options as HTMLOptionElement[]);\r\n      const vals = value.map(String);\r\n      options.forEach((opt: HTMLOptionElement) => {\r\n        opt.selected = vals.includes(opt.value);\r\n      });\r\n    } else if ('value' in el) {\r\n      el.value = String(value);\r\n    }\r\n  }\r\n\r\n  function populateSelectOptions(select: HTMLSelectElement, context: Record<string, any>): void {\r\n    const dataSource = select.getAttribute('data-source');\r\n    const name = select.getAttribute('name') || '';\r\n\r\n    let sourceKey: string;\r\n    let valueField = 'value';\r\n    let textField = 'text';\r\n    let groupField: string | null = null;\r\n\r\n    if (dataSource) {\r\n      const match = dataSource.match(/^\\s*(\\w+)\\s*(?:\\(\\s*(\\w+)\\s*,\\s*(\\w+)\\s*(?:,\\s*(\\w+)\\s*)?\\))?\\s*$/);\r\n      if (!match) return;\r\n      sourceKey = match[1];\r\n      if (match[2] && match[3]) {\r\n        valueField = match[2];\r\n        textField = match[3];\r\n      }\r\n      if (match[4]) {\r\n        groupField = match[4];\r\n      }\r\n    } else {\r\n      sourceKey = name.endsWith('[]') ? name.slice(0, -2) : name;\r\n      if (!sourceKey) return;\r\n    }\r\n\r\n    const source = context[sourceKey];\r\n    if (source === undefined) return;\r\n\r\n    const items = typeof source === 'function' ? source.call(context) : source;\r\n    if (!Array.isArray(items)) return;\r\n\r\n    const placeholders = Array.from(select.options).filter(opt => opt.value === '');\r\n    select.innerHTML = '';\r\n    placeholders.forEach(opt => select.add(opt));\r\n\r\n    const groups = new Map<string, HTMLOptGroupElement>();\r\n\r\n    for (const item of items) {\r\n      if (item === null || item === undefined) continue;\r\n\r\n      let value: string;\r\n      let text: string;\r\n      let groupLabel = '';\r\n\r\n      if (typeof item === 'object') {\r\n        value = String(item[valueField]);\r\n        text = String(item[textField]);\r\n        if (groupField) {\r\n          const raw = item[groupField];\r\n          if (raw !== null && raw !== undefined && String(raw) !== '') {\r\n            groupLabel = String(raw);\r\n          }\r\n        }\r\n      } else {\r\n        const str = String(item);\r\n        value = str;\r\n        text = str;\r\n      }\r\n\r\n      const option = new Option(text, value);\r\n      if (groupLabel) {\r\n        let optgroup = groups.get(groupLabel);\r\n        if (!optgroup) {\r\n          optgroup = document.createElement('optgroup');\r\n          optgroup.label = groupLabel;\r\n          groups.set(groupLabel, optgroup);\r\n          select.appendChild(optgroup);\r\n        }\r\n        optgroup.appendChild(option);\r\n      } else {\r\n        select.add(option);\r\n      }\r\n    }\r\n  }\r\n\r\n  function boolAttr(element: Element, name: string): boolean {\r\n    const el = element as Record<string, any>;\r\n    if (name in el && typeof el[name] === 'boolean') return el[name];\r\n    const attr = element.getAttribute(name);\r\n    if (attr === null) return false;\r\n    if (attr === '' || attr.toLowerCase() === 'true' || attr.toLowerCase() === name) return true;\r\n    return false;\r\n  }", "/**\r\n * @module ValidationRules\r\n * Form validation rules for use with FormValidator.\r\n * Provides declarative validation through decorators.\r\n *\r\n * Validation messages use the i18n system. Load the 'r-validation' namespace\r\n * for localized error messages:\r\n *\r\n * @example\r\n * await loadNamespace('r-validation');\r\n *\r\n * @example\r\n * // In HTML, use validation attributes\r\n * <input name=\"age\" data-validate=\"required range(0-120)\" />\r\n */\r\n\r\nimport { t } from '../i18n/i18n';\r\n\r\n/**\r\n * Context provided to validators during validation.\r\n */\r\nexport interface ValidationContext {\r\n    /** The HTML input type (text, number, email, etc.) */\r\n    inputType: string;\r\n    /** The data-type attribute value if present */\r\n    dataType?: string;\r\n    /** Adds an error message to the validation result */\r\n    addError(message: string): void;\r\n}\r\n\r\n/**\r\n * Interface for custom validators.\r\n * @internal\r\n */\r\ninterface Validator {\r\n    /**\r\n     * Validates the given value.\r\n     * @param value - The string value to validate\r\n     * @param context - Validation context with type info and error reporting\r\n     */\r\n    validate(value: string, context: ValidationContext): void;\r\n}\r\n\r\n/** @internal */\r\ninterface ValidatorRegistryEntry {\r\n    validator: new (...args: any[]) => Validator;\r\n    validInputTypes: string[];\r\n}\r\n\r\nconst validators: Map<string, ValidatorRegistryEntry> = new Map();\r\n\r\n/**\r\n * Decorator to register a validator class for a specific validation name.\r\n *\r\n * @param validationName - The name used in data-validate attribute\r\n * @param validInputTypes - Optional list of input types this validator applies to\r\n *\r\n * @example\r\n * @RegisterValidator('email')\r\n * class EmailValidation implements Validator {\r\n *     validate(value: string, context: ValidationContext) {\r\n *         if (!value.includes('@')) {\r\n *             context.addError('Invalid email address');\r\n *         }\r\n *     }\r\n * }\r\n */\r\nexport function RegisterValidator(validationName: string, validInputTypes: string[] = []) {\r\n    return function (target: new (...args: any[]) => Validator) {\r\n        validators.set(validationName, { validator: target, validInputTypes });\r\n    };\r\n}\r\n\r\n/**\r\n * Looks up a registered validator by name.\r\n *\r\n * @param name - The validator name used in `data-validate`\r\n * @returns The registry entry, or `undefined` if not found\r\n */\r\nexport function getValidator(name: string): ValidatorRegistryEntry | undefined {\r\n    return validators.get(name);\r\n}\r\n\r\n/**\r\n * Validates that a field has a non-empty value.\r\n * Use with `data-validate=\"required\"`.\r\n */\r\n@RegisterValidator('required')\r\nexport class RequiredValidation implements Validator {\r\n    static create(rule: string): RequiredValidation | null {\r\n        return rule === 'required' ? new RequiredValidation() : null;\r\n    }\r\n\r\n    validate(value: string, context: ValidationContext) {\r\n        if (value.trim() !== ''){\r\n            return;\r\n        }\r\n\r\n        context.addError(this.getMessage());\r\n    }\r\n\r\n    getMessage(): string {\r\n        return t('r-validation:required');\r\n    }\r\n}\r\n\r\n/**\r\n * Validates that a numeric value falls within a specified range.\r\n * Use with `data-validate=\"range(min-max)\"`.\r\n *\r\n * @example\r\n * <input name=\"age\" type=\"number\" data-validate=\"range(0-120)\" />\r\n */\r\n@RegisterValidator('range', ['number'])\r\nexport class RangeValidation implements Validator {\r\n    min: number;\r\n    max: number;\r\n\r\n    constructor(min: number, max: number) {\r\n        this.min = min;\r\n        this.max = max;\r\n    }\r\n\r\n    static create(rule: string): RangeValidation | null {\r\n        const rangeMatch = rule.match(/^range\\((-?\\d+(?:\\.\\d+)?)-(-?\\d+(?:\\.\\d+)?)\\)$/);\r\n        if (rangeMatch) {\r\n            const [, min, max] = rangeMatch;\r\n            return new RangeValidation(parseFloat(min), parseFloat(max));\r\n        }\r\n        return null;\r\n    }\r\n\r\n    validate(value: string, context: ValidationContext) {\r\n        if (value.trim() === '') return;\r\n\r\n        const num = parseFloat(value);\r\n        if (!isNaN(num) && num >= this.min && num <= this.max){\r\n            return;\r\n        }\r\n\r\n        context.addError(this.getMessage(value));\r\n    }\r\n\r\n    getMessage(actual: string): string {\r\n        return t('r-validation:range', { min: this.min, max: this.max, actual });\r\n    }\r\n}\r\n\r\n/**\r\n * Validates that a value contains only numeric digits (0-9).\r\n * Use with `data-validate=\"digits\"`.\r\n */\r\n@RegisterValidator('digits', ['number'])\r\nexport class DigitsValidation implements Validator {\r\n    static create(rule: string): DigitsValidation | null {\r\n        return rule === 'digits' ? new DigitsValidation() : null;\r\n    }\r\n\r\n    validate(value: string, context: ValidationContext) {\r\n        if (/^\\d+$/.test(value)){\r\n            return;\r\n        }\r\n\r\n        context.addError(this.getMessage());\r\n    }\r\n\r\n    getMessage(): string {\r\n        return t('r-validation:digits');\r\n    }\r\n}\r\n"],
  "mappings": "myEAAA,IAAAA,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAA,SACI,SAAY,eACZ,MAAS,8CACb,ICHA,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAA,SACI,MAAS,OACT,UAAa,UACb,QAAW,2DACX,OAAU,kDACd,ICLA,IAAAC,GAAAC,EAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAA,SACI,SAAY,qCACZ,MAAS,4DACT,OAAU,sBACd,ICiBA,IAAMC,EAAmB,IAAI,IAa7B,SAASC,GAAcC,EAAkC,CACrD,OAAKF,EAAiB,IAAIE,CAAM,GAC5BF,EAAiB,IAAIE,EAAQ,IAAI,KAAK,YAAYA,CAAM,CAAC,EAEtDF,EAAiB,IAAIE,CAAM,CACtC,CAEA,SAASC,GAAYC,EAAmB,CACpC,OAAOA,EAAE,QAAQ,sBAAuB,MAAM,CAClD,CAmBO,SAASC,GACZC,EACAC,EACAL,EAAiB,KACX,CACN,OAAOI,EAAQ,QACX,2DACA,CAACE,EAAGC,EAAKC,EAAMC,IAAmB,CAC9B,IAAMC,EAAQL,IAASE,CAAG,EAE1B,GAAIC,IAAS,SAAU,CACnB,IAAMG,EAAQ,IAAI,OACd,IAAIV,GAAY,OAAOS,CAAK,CAAC,CAAC,oBAClC,EAAE,KAAKD,CAAc,EACrB,GAAIE,EACA,OAAOA,EAAM,CAAC,EACT,QAAQ,IAAIJ,CAAG,IAAK,OAAOG,CAAK,CAAC,EACjC,QAAQ,IAAK,OAAOA,CAAK,CAAC,EAInC,IAAME,EADQb,GAAcC,CAAM,EACX,OAAOU,CAAK,EAC7BG,EACF,IAAI,OAAO,GAAGD,CAAQ,oBAAoB,EAAE,KAAKH,CAAc,GAC/D,IAAI,OAAO,yBAAyB,EAAE,KAAKA,CAAc,EAC7D,OAAII,EACOA,EAAM,CAAC,EACT,QAAQ,IAAIN,CAAG,IAAK,OAAOG,CAAK,CAAC,EACjC,QAAQ,IAAK,OAAOA,CAAK,CAAC,EAE5B,OAAOA,CAAK,CACvB,CAEA,GAAIF,IAAS,SAAU,CACnB,IAAMM,EAAUb,GAAY,OAAOS,CAAK,CAAC,EACnCG,EACF,IAAI,OAAO,MAAMC,CAAO,oBAAoB,EAAE,KAAKL,CAAc,GACjE,IAAI,OAAO,4BAA4B,EAAE,KAAKA,CAAc,EAChE,OAAOI,EAAQA,EAAM,CAAC,EAAI,OAAOH,CAAK,CAC1C,CAEA,OAAOA,IAAU,OAAY,OAAOA,CAAK,EAAI,IAAIH,CAAG,GACxD,CACJ,CACJ,CAMO,IAAIQ,GAA8BZ,GC/EzC,IAAMa,EAA6D,CAAC,EAK7D,SAASC,GAAgBC,EAAwB,CACpD,OAAOA,EAAO,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAC5C,CAwBO,SAASC,EACZC,EACAC,EACAC,EACI,CACJ,IAAMC,EAAaC,GAAgBJ,CAAM,EACpCK,EAAUF,CAAU,IAAGE,EAAUF,CAAU,EAAI,CAAC,GACrDE,EAAUF,CAAU,EAAEF,CAAS,EAAIC,CACvC,CCxEA,IAAAI,GAAA,CACI,SAAY,iBACZ,MAAS,+CACb,ECHA,IAAAC,GAAA,CACI,MAAS,QACT,UAAa,YACb,QAAW,sDACX,OAAU,oDACd,ECLA,IAAAC,GAAA,CACI,SAAY,0BACZ,MAAS,wDACT,OAAU,2BACd,ECgBO,SAASC,IAAkC,CAC9CC,EAAkB,KAAM,WAAYC,EAAQ,EAC5CD,EAAkB,KAAM,UAAWE,EAAO,EAC1CF,EAAkB,KAAM,eAAgBG,EAAY,EAEpDH,EAAkB,KAAM,WAAY,IAAM,mCAAoC,EAC9EA,EAAkB,KAAM,UAAW,IAAM,mCAAmC,EAC5EA,EAAkB,KAAM,eAAgB,IAAM,mCAAwC,CAC1F,CCsCA,IAAMI,GAAyB,KAC3BC,EAAwBD,GAE5B,IAAME,GAA6B,CAAC,EAChCC,GAAmD,KAEvDC,GAA0B,EA6GnB,SAASC,EACZC,EACAC,EACAC,EACM,CACN,GAAM,CAACC,EAAWC,CAAG,EAAIJ,EAAQ,SAAS,GAAG,EACvCA,EAAQ,MAAM,GAAG,EACjB,CAAC,WAAYA,CAAO,EACpBK,EAAUC,GAAaH,CAAS,IAAIC,CAAG,EAE7C,OAAKC,EAMEE,GAAOF,EAASJ,EAAQC,GAAS,UAAYF,CAAO,GALnDQ,IAAgBA,GAAeJ,EAAKD,EAAWM,CAAa,EAC5DP,GAAS,WAAa,OAAkBF,EACrCO,GAAOL,EAAQ,SAAUD,EAAQC,EAAQ,QAAQ,EAIhE,CAEA,SAASK,GAAOF,EAAiBJ,EAAyCS,EAAyB,CAC/F,GAAI,CACA,OAAOC,GAAUN,EAASJ,EAAQQ,CAAa,CACnD,MAAQ,CACJ,OAAOC,CACX,CACJ,CAOO,SAASE,IAA2B,CACvC,OAAOH,CACX,CCtKO,SAASI,GACZC,EACAC,EACAC,EAGI,CAAC,EACJ,CACD,IAAMC,EAAeH,EAAK,iBAAiB,yBAAyB,EAuBpE,GArBAG,EAAa,QAASC,GAAY,CAE9B,GADI,CAACA,EAAQ,aAAa,MAAM,GAC5BC,EAAYD,EAAS,UAAU,EAAG,OAEtC,IAAME,EAAeF,EAAQ,aAAa,MAAM,EAEhD,GAAI,EAAEE,KAAgBL,GAAW,CAC7B,GAAIC,EAAQ,uBACR,MAAM,IAAI,MACN,eAAeI,CAAY,8CAC/B,EAEJ,MACJ,CAEA,IAAMC,EAAQC,GAAiBJ,CAAO,EAClCG,IAAUE,KAEbR,EAAqCK,CAAY,EAAIC,EAC1D,CAAC,EAEGL,EAAQ,oBAAqB,CAC7B,IAAMQ,EAAiB,IAAI,IAC3BP,EAAa,QAASC,GAAY,CAC1BA,EAAQ,aAAa,MAAM,GAC3BM,EAAe,IAAIN,EAAQ,aAAa,MAAM,CAAE,CAExD,CAAC,EAED,QAAWO,KAAQV,EACf,GACI,OAAOA,EAASU,CAAI,GAAM,YAC1B,OAAO,UAAU,eAAe,KAAKV,EAAUU,CAAI,GACnD,CAACD,EAAe,IAAIC,CAAI,EAExB,MAAM,IAAI,MACN,mBAAmBA,CAAI,8BAC3B,CAGZ,CAEA,OAAOV,CACX,CAiCO,SAASW,GAAiBR,EAAqC,CAClE,IAAMS,EAAWT,EAAQ,aAAa,WAAW,EACjD,OAAIS,EACOC,GAA4BD,CAAQ,EAG3CT,aAAmB,iBACZW,GAA6BX,EAAQ,IAAiB,EAI7D,YAAaA,GAAW,OAAQA,EAAgB,SAAY,UACrDY,EAGHC,GAAQA,CACpB,CAuCO,SAASC,GAAsClB,EAAyB,CAC3E,IAAMmB,EAAgC,CAAC,EACjCC,EAAW,IAAI,SAASpB,CAAI,EAC5BqB,EAAO,IAAI,IAEjBD,EAAS,QAAQ,CAACE,EAAGC,IAAS,CAC1B,GAAIF,EAAK,IAAIE,CAAI,EAAG,OACpBF,EAAK,IAAIE,CAAI,EAEb,IAAMC,EAASJ,EAAS,OAAOG,CAAI,EAC7BnB,EAAUJ,EAAK,SAAS,UAAUuB,CAAI,EACtCE,EAAYrB,EAAUQ,GAAiBR,CAAsB,EAAKsB,GAAcA,EAEtF,GAAIF,EAAO,SAAW,EAAG,CACrB,IAAME,EAAIF,EAAO,CAAC,EAClBL,EAAKI,CAAI,EAAI,OAAOG,GAAM,SAAWD,EAAUC,CAAC,EAAIA,CACxD,MACIP,EAAKI,CAAI,EAAIC,EAAO,IAAIE,GAAK,OAAOA,GAAM,SAAWD,EAAUC,CAAC,EAAIA,CAAC,CAE7E,CAAC,EAED,QAASC,EAAI,EAAGA,EAAI3B,EAAK,SAAS,OAAQ2B,IAAK,CAC3C,IAAMC,EAAK5B,EAAK,SAAS2B,CAAC,EACtBC,EAAG,OAAS,YAAcA,EAAG,MAAQ,CAACP,EAAK,IAAIO,EAAG,IAAI,IACtDP,EAAK,IAAIO,EAAG,IAAI,EAChBT,EAAKS,EAAG,IAAI,EAAI,GAExB,CAEA,OAAOT,CACX,CAoCO,SAASH,EAAiBT,EAAqC,CAClE,GAAI,CAACA,GAASA,GAAS,GACnB,OAGJ,IAAMsB,EAAQtB,EAAM,YAAY,EAEhC,GAAIsB,IAAU,QAAUA,IAAU,MAAQ,OAAOtB,CAAK,EAAI,EACtD,MAAO,GAGX,GAAIsB,IAAU,SAAWA,IAAU,OAAS,OAAOtB,CAAK,GAAK,EACzD,MAAO,GAGX,MAAM,IAAI,MAAM,4BAA8BA,EAAQ,eAAe,CACzE,CASO,SAASuB,EAAgBvB,EAAoC,CAChE,GAAI,CAACA,GAASA,GAAS,GACnB,OAEJ,IAAMwB,EAAK,OAAOxB,CAAK,EACvB,GAAI,CAAC,MAAMwB,CAAE,EACT,OAAOA,EAEX,MAAM,IAAI,MAAM,4BAA8BxB,EAAQ,cAAc,CACxE,CAWA,SAASyB,GAAmBC,EAA8C,CAEtE,OADc,IAAI,KAAK,eAAeA,CAAM,EAAE,cAAc,IAAI,KAAK,KAAM,EAAG,EAAE,CAAC,EAE5E,OAAQC,GACLA,EAAE,OAAS,OAASA,EAAE,OAAS,SAAWA,EAAE,OAAS,MAAM,EAC9D,IAAIA,GAAKA,EAAE,IAAI,CACxB,CAqBO,SAASC,EAAc5B,EAAiC,CAC3D,GAAI,CAACA,GAASA,IAAU,GAAI,OAE5B,GAAI,0BAA0B,KAAKA,CAAK,EAAG,CACvC,IAAM6B,EAAO,IAAI,KAAK7B,CAAK,EAC3B,GAAI,CAAC,MAAM6B,EAAK,QAAQ,CAAC,EAAG,OAAOA,CACvC,CAEA,IAAMC,EAAe9B,EAAM,MAAM,WAAW,EAC5C,GAAI8B,EAAa,QAAU,GAAKA,EAAa,MAAMH,GAAK,QAAQ,KAAKA,CAAC,CAAC,EAAG,CACtE,IAAMD,EAASK,GAAiB,EAC1BC,EAAQP,GAAmBC,CAAM,EACjCO,EAAiC,CAAC,EAKxC,GAJAD,EAAM,QAAQ,CAACE,EAAMd,IAAM,CACvBa,EAAOC,CAAI,EAAI,SAASJ,EAAaV,CAAC,EAAG,EAAE,CAC/C,CAAC,EAEGa,EAAO,OAAS,QAAaA,EAAO,QAAU,QAAaA,EAAO,MAAQ,OAAW,CACjFA,EAAO,KAAO,MAAKA,EAAO,MAAQ,KACtC,IAAMJ,EAAO,IAAI,KAAKI,EAAO,KAAMA,EAAO,MAAQ,EAAGA,EAAO,GAAG,EAC/D,GAAI,CAAC,MAAMJ,EAAK,QAAQ,CAAC,EAAG,OAAOA,CACvC,CACJ,CAEA,IAAMA,EAAO,IAAI,KAAK7B,CAAK,EAC3B,GAAI,MAAM6B,EAAK,QAAQ,CAAC,EACpB,MAAM,IAAI,MAAM,qBAAqB,EAEzC,OAAOA,CACX,CAQO,SAAStB,GAA4BD,EAAmC,CAC3E,OAAQA,EAAU,CACd,IAAK,UACD,OAAOG,EACX,IAAK,SACD,OAAOc,EACX,IAAK,OACD,OAAOK,EACX,IAAK,SACD,OAAQ5B,GAAW,CAACA,GAASA,GAAS,GAAK,OAAYA,EAC3D,QACI,MAAM,IAAI,MAAM,sBAAsBM,CAAQ,IAAI,CAC1D,CACJ,CASO,SAASE,GAA6B2B,EAAqC,CAC9E,OAAQA,EAAW,CACf,IAAK,WACD,OAAO1B,EAEX,IAAK,SACD,OAAOc,EAEX,IAAK,OACL,IAAK,iBACD,OAAOK,EAEX,IAAK,QACD,OAAQ5B,GAAU,CACd,GAAM,CAACoC,EAAMC,CAAK,EAAIrC,EAAM,MAAM,GAAG,EAAE,IAAI,MAAM,EACjD,OAAO,IAAI,KAAKoC,EAAMC,EAAQ,CAAC,CACnC,EAEJ,IAAK,OACD,OAAQrC,GAAU,CACd,GAAM,CAACoC,EAAME,CAAI,EAAItC,EAAM,MAAM,IAAI,EAAE,IAAI,MAAM,EACjD,MAAO,CAAE,KAAAoC,EAAM,KAAAE,CAAK,CACxB,EAEJ,IAAK,OACD,OAAQtC,GAAU,CACd,GAAM,CAACuC,EAAOC,EAASC,EAAU,CAAC,EAAIzC,EAAM,MAAM,GAAG,EAAE,IAAI,MAAM,EACjE,MAAO,CAAE,MAAAuC,EAAO,QAAAC,EAAS,QAAAC,CAAQ,CACrC,EAEJ,QACI,OAAQzC,GAAW,CAACA,GAASA,GAAS,GAAK,OAAYA,CAC/D,CACJ,CAEA,SAASF,EAAYD,EAAkBmB,EAAuB,CAC1D,IAAMK,EAAKxB,EACX,GAAImB,KAAQK,GAAM,OAAOA,EAAGL,CAAI,GAAM,UAAW,OAAOK,EAAGL,CAAI,EAC/D,IAAM0B,EAAO7C,EAAQ,aAAamB,CAAI,EACtC,OAAI0B,IAAS,KAAa,GACtBA,IAAS,IAAMA,EAAK,YAAY,IAAM,QAAUA,EAAK,YAAY,IAAM1B,CAE/E,CAEA,IAAMd,GAAO,OAAO,MAAM,EAE1B,SAASD,GAAiBJ,EAA2B,CACjD,IAAMwB,EAAKxB,EACLqC,EAAOb,EAAG,MAAQxB,EAAQ,aAAa,MAAM,GAAK,GAExD,GAAIqC,IAAS,WACT,OAAOpC,EAAYD,EAAS,SAAS,EAGzC,GAAIqC,IAAS,QACT,OAAKpC,EAAYD,EAAS,SAAS,EAC5BwB,EAAG,MADmCnB,GAIjD,GAAIgC,IAAS,SACT,OAAOb,EAAG,MAAQ,OAAOA,EAAG,KAAK,EAAI,KAGzC,GAAIa,IAAS,OACT,OAAOb,EAAG,MAAQ,IAAI,KAAKA,EAAG,KAAK,EAAI,KAG3C,GAAI,oBAAqBA,GAAMvB,EAAYD,EAAS,UAAU,EAC1D,OAAO,MAAM,KAAKwB,EAAG,eAAgD,EAChE,IAAKsB,GAAyBA,EAAE,KAAK,EAG9C,GAAI,UAAWtB,EACX,OAAOA,EAAG,KAIlB,CC/aO,IAAMuB,EAAN,cAAyB,KAAM,CAClC,YACIC,EACOC,EACT,CACE,MAAMD,CAAO,EAFN,aAAAC,CAGX,CACJ,EAKIC,GAA+B,KAsC5B,SAASC,EAAYC,EAAiBC,EAAqD,CAC9F,IAAMC,EAAQ,IAAIC,EAAWH,EAASC,CAAO,EAC7C,GAAIG,GAAS,CACT,IAAIC,EAAa,GAKjB,GADAD,GAAQF,EAHkB,CACtB,UAAW,CAAEG,EAAa,EAAM,CACpC,CACkB,EACdA,EACA,OAAO,IAEf,CACA,OAAOH,CACX,CCvEA,SAASI,GAAaC,EAAqC,CACvD,IAAMC,EAAKD,EAAQ,aAAa,IAAI,EACpC,GAAIC,EAAI,CACJ,IAAMC,EAAOF,EAAQ,QAAQ,MAAM,EACnC,GAAIE,EAAM,CACN,IAAMC,EAAQD,EAAK,cAAc,cAAcD,CAAE,IAAI,EACrD,GAAIE,EACA,OAAOA,EAAM,aAAa,KAAK,GAAK,IAE5C,CACJ,CAEA,OAAO,IACX,CAiDO,IAAMC,EAAN,KAAoB,CAGvB,YACYF,EACAG,EACV,CAFU,UAAAH,EACA,aAAAG,EAER,GAAI,CAAC,KAAK,KACN,MAAM,IAAI,MAAM,yBAAyB,EAG7C,KAAK,KAAK,iBAAiB,SAAWC,GAAU,CAW5C,IATID,GAAS,gBACT,KAAK,SAAS,gBAAkB,OAEhCC,EAAM,eAAe,EAErB,KAAK,SAAS,cACd,KAAK,QAAQ,aAAaJ,CAAI,EAG9B,KAAK,aAAa,EAClB,GAAI,CACA,IAAMK,EAAS,KAAK,SAAS,gBAAgB,KAAK,IAAI,EAClDA,aAAkB,SAClBA,EAAO,MAAOC,GAAU,CACpB,IAAMC,EAAQC,EAAY,wBAAyB,CAAE,MAAAF,CAAM,CAAC,EAC5D,GAAIC,EAAO,MAAMA,CACrB,CAAC,CAET,OAASD,EAAO,CACZ,IAAMC,EAAQC,EAAY,wBAAyB,CAAE,MAAAF,CAAM,CAAC,EAC5D,GAAIC,EAAO,MAAMA,CACrB,MAEIJ,GAAS,yBAA2B,IACpCC,EAAM,eAAe,CAGjC,CAAC,EAEGD,GAAS,cACTH,EAAK,iBAAiB,QAAS,IAAuB,CAClD,KAAK,aAAa,CACtB,CAAC,CAET,CAQO,cAAwB,CAC3B,IAAMS,EAAe,MAAM,KACvB,KAAK,KAAK,iBAAiB,uBAAuB,CACtD,EACIC,EAAc,GAElB,GAAI,KAAK,SAAS,aAAe,GAC7B,OAAI,KAAK,KAAK,cAAc,EACjB,IAGX,KAAK,KAAK,eAAe,EACzB,KAAK,uBAAuB,EACrB,IAGX,IAAMC,EAA0B,CAAC,EAEjC,OAAAF,EAAa,QAASX,GAAY,CAC9B,GAAI,CAACA,EAAQ,cAAc,EAAG,CAC1BY,EAAc,GACd,IAAME,EACFf,GAAa,KAAK,KAAMC,CAAO,GAC/BA,EAAQ,MACR,gBACJa,EAAc,KACV,GAAGC,CAAS,KAAKd,EAAQ,iBAAiB,EAC9C,CACJ,CACJ,CAAC,EAEIY,EAID,KAAK,kBAAkB,GAHvB,KAAK,oBAAoBC,CAAa,EACtC,KAAK,uBAAuB,GAKzBD,CACX,CAOO,oBAAoBG,EAAoB,CAC3C,KAAK,kBAAkB,EAClB,KAAK,cACN,KAAK,mBAAmB,EAG5B,IAAMC,EAAY,KAAK,aAAc,cAAc,IAAI,EACvDD,EAAS,QAASE,GAAY,CAC1B,IAAMC,EAAW,SAAS,cAAc,IAAI,EAC5CA,EAAS,YAAcD,EACvBD,EAAU,YAAYE,CAAQ,CAClC,CAAC,CACL,CAEQ,oBAAqB,CACzB,IAAMC,EAAe,SAAS,cAAc,KAAK,EACjDA,EAAa,UAAY,gBACzBA,EAAa,MAAM,MAAQ,MAC3BA,EAAa,aAAa,OAAQ,OAAO,EACzCA,EAAa,aAAa,YAAa,WAAW,EAClDA,EAAa,aAAa,cAAe,MAAM,EAC/C,KAAK,aAAeA,EAEpB,IAAMH,EAAY,SAAS,cAAc,IAAI,EAC7C,KAAK,aAAa,YAAYA,CAAS,EAEvC,KAAK,KAAK,QAAQG,CAAY,CAClC,CAOO,kBAAkBL,EAAmBG,EAAiB,CACpD,KAAK,cACN,KAAK,mBAAmB,EAE5B,IAAMD,EAAY,KAAK,aAAc,cAAc,IAAI,EACjDE,EAAW,SAAS,cAAc,IAAI,EAC5CA,EAAS,YAAc,GAAGJ,CAAS,KAAKG,CAAO,GAC/CD,EAAU,YAAYE,CAAQ,CAClC,CAKO,mBAAoB,CACvB,GAAI,KAAK,aAAa,CAClB,IAAME,EAAK,KAAK,aAAa,cAAc,IAAI,EAC3CA,IAAIA,EAAG,UAAY,GAC3B,CACJ,CAEQ,wBAAyB,CAC7B,IAAMC,EAAsB,KAAK,KAAK,cAAc,UAAU,EAE1DA,aAA+B,aAC/B,SAAS,gBAAkBA,GAE3BA,EAAoB,MAAM,CAElC,CAkBA,OAAc,SAASrB,EAAuC,CAC1D,GAAIA,EAAQ,eAAe,SAAW,OAClC,OAAwBA,EAAQ,cAEhC,QAASsB,EAAI,EAAGA,EAAItB,EAAQ,SAAS,OAAQsB,IAAK,CAC9C,IAAMC,EAAQvB,EAAQ,SAASsB,CAAC,EAChC,GAAIC,EAAM,SAAW,OACjB,OAAwBA,CAEhC,CAGJ,MAAM,IAAI,MACN,qDACIvB,EAAQ,YAAY,IAC5B,CACJ,CACJ,EC1LO,SAASwB,GAAYC,EAAuBC,EAAcC,EAAwB,CACjFA,GACgBF,EAAK,iBAAiB,cAAc,EAC5C,QAAQG,GAAU,CACtBC,GAAsBD,EAA6BD,CAA8B,CACrF,CAAC,EAGgBF,EAAK,iBAAiB,QAAQ,EAEtC,QAAQK,GAAW,CAE9B,IAAMC,EAAOD,EAAQ,aAAa,MAAM,EACxC,GAAI,CAACC,EAAM,OAGX,GAAIA,EAAK,SAAS,IAAI,EAAG,CACvB,IAAMC,EAAYD,EAAK,MAAM,EAAG,EAAE,EAC5BE,EAAaC,GAAsBR,EAAMM,CAAS,EAExD,GAAI,MAAM,QAAQC,CAAU,EAAG,CAC7B,IAAME,EAAKL,EACLM,EAAOD,EAAG,MAAQL,EAAQ,aAAa,MAAM,GAAK,GAExD,GAAIM,IAAS,YAAcA,IAAS,QAClCD,EAAG,QAAUF,EAAW,SAASE,EAAG,KAAK,UAChC,YAAaA,GAAME,GAASP,EAAS,UAAU,EACxDG,EAAW,QAAQK,GAAO,CACxB,IAAMC,EAAS,MAAM,KAAKJ,EAAG,OAA8B,EACxD,KAAMK,GAA2BA,EAAI,QAAU,OAAOF,CAAG,CAAC,EACzDC,IAASA,EAA6B,SAAW,GACvD,CAAC,UACQ,UAAWJ,EAAI,CACxB,IAAMM,EAAchB,EAAK,iBAAiB,UAAUM,CAAI,IAAI,EACtDW,EAAM,MAAM,KAAKD,CAAW,EAAE,QAAQX,CAAO,EAC/CY,GAAO,GAAKA,EAAMT,EAAW,SAC/BE,EAAG,MAAQ,OAAOF,EAAWS,CAAG,CAAC,EAErC,CACF,CACA,MACF,CAGA,IAAMC,EAAQT,GAAsBR,EAAMK,CAAI,EACnBY,GAAU,MAErCC,GAAgBd,EAASa,CAAK,CAChC,CAAC,CACH,CAEA,SAAST,GAAsBW,EAAaC,EAAmB,CAE7D,IAAMC,EAAW,CAAC,EACdC,EAAiB,GACjBC,EAAa,GAEjB,QAASC,EAAI,EAAGA,EAAIJ,EAAK,OAAQI,IAAK,CACpC,IAAMC,EAAOL,EAAKI,CAAC,EAEfC,IAAS,KAAO,CAACF,GACfD,IACFD,EAAS,KAAKC,CAAc,EAC5BA,EAAiB,IAEnBC,EAAa,GACbD,GAAkBG,GACTA,IAAS,KAAOF,GACzBD,GAAkBG,EAClBJ,EAAS,KAAKC,CAAc,EAC5BA,EAAiB,GACjBC,EAAa,IACJE,IAAS,KAAO,CAACF,EACtBD,IACFD,EAAS,KAAKC,CAAc,EAC5BA,EAAiB,IAGnBA,GAAkBG,CAEtB,CAEA,OAAIH,GACFD,EAAS,KAAKC,CAAc,EAGvBD,EAAS,OAAY,CAACK,EAAQC,IAAY,CAC/C,GAAI,GAACD,GAAU,OAAOA,GAAW,UAGjC,IAAIC,EAAQ,WAAW,GAAG,GAAKA,EAAQ,SAAS,GAAG,EAAG,CACpD,IAAMC,EAAQD,EAAQ,MAAM,EAAG,EAAE,EACjC,OAAOD,EAAOE,CAAK,CACrB,CAEA,OAAOF,EAAOC,CAAO,EACvB,EAAGR,CAAG,CACR,CAEA,SAASD,GAAgBd,EAAkBa,EAAkB,CAC3D,IAAMR,EAAKL,EACLM,EAAOD,EAAG,MAAQL,EAAQ,aAAa,MAAM,GAAK,GAExD,GAAIM,IAAS,WACXD,EAAG,QAAU,EAAQQ,UACZP,IAAS,QAClBD,EAAG,QAAUA,EAAG,QAAU,OAAOQ,CAAK,UAC7BP,IAAS,QAAUO,aAAiB,KAC7CR,EAAG,MAAQQ,EAAM,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,UAClCP,IAAS,kBAAoBO,aAAiB,KAAM,CAC7D,IAAMY,EAAOC,GAAc,OAAOA,CAAC,EAAE,SAAS,EAAG,GAAG,EACpDrB,EAAG,MAAQ,GAAGQ,EAAM,YAAY,CAAC,IAAIY,EAAIZ,EAAM,SAAS,EAAI,CAAC,CAAC,IAAIY,EAAIZ,EAAM,QAAQ,CAAC,CAAC,IAAIY,EAAIZ,EAAM,SAAS,CAAC,CAAC,IAAIY,EAAIZ,EAAM,WAAW,CAAC,CAAC,EAC5I,SAAW,YAAaR,GAAME,GAASP,EAAS,UAAU,GAAK,MAAM,QAAQa,CAAK,EAAG,CACnF,IAAMc,EAAU,MAAM,KAAKtB,EAAG,OAA8B,EACtDuB,EAAOf,EAAM,IAAI,MAAM,EAC7Bc,EAAQ,QAASjB,GAA2B,CAC1CA,EAAI,SAAWkB,EAAK,SAASlB,EAAI,KAAK,CACxC,CAAC,CACH,KAAW,UAAWL,IACpBA,EAAG,MAAQ,OAAOQ,CAAK,EAE3B,CAEA,SAASd,GAAsBD,EAA2BD,EAAoC,CAC5F,IAAMgC,EAAa/B,EAAO,aAAa,aAAa,EAC9CG,EAAOH,EAAO,aAAa,MAAM,GAAK,GAExCgC,EACAC,EAAa,QACbC,EAAY,OACZC,EAA4B,KAEhC,GAAIJ,EAAY,CACd,IAAMK,EAAQL,EAAW,MAAM,mEAAmE,EAClG,GAAI,CAACK,EAAO,OACZJ,EAAYI,EAAM,CAAC,EACfA,EAAM,CAAC,GAAKA,EAAM,CAAC,IACrBH,EAAaG,EAAM,CAAC,EACpBF,EAAYE,EAAM,CAAC,GAEjBA,EAAM,CAAC,IACTD,EAAaC,EAAM,CAAC,EAExB,SACEJ,EAAY7B,EAAK,SAAS,IAAI,EAAIA,EAAK,MAAM,EAAG,EAAE,EAAIA,EAClD,CAAC6B,EAAW,OAGlB,IAAMK,EAAStC,EAAQiC,CAAS,EAChC,GAAIK,IAAW,OAAW,OAE1B,IAAMC,EAAQ,OAAOD,GAAW,WAAaA,EAAO,KAAKtC,CAAO,EAAIsC,EACpE,GAAI,CAAC,MAAM,QAAQC,CAAK,EAAG,OAE3B,IAAMC,EAAe,MAAM,KAAKvC,EAAO,OAAO,EAAE,OAAOY,GAAOA,EAAI,QAAU,EAAE,EAC9EZ,EAAO,UAAY,GACnBuC,EAAa,QAAQ3B,GAAOZ,EAAO,IAAIY,CAAG,CAAC,EAE3C,IAAM4B,EAAS,IAAI,IAEnB,QAAWC,KAAQH,EAAO,CACxB,GAAIG,GAAS,KAA4B,SAEzC,IAAI1B,EACA2B,EACAC,EAAa,GAEjB,GAAI,OAAOF,GAAS,UAGlB,GAFA1B,EAAQ,OAAO0B,EAAKR,CAAU,CAAC,EAC/BS,EAAO,OAAOD,EAAKP,CAAS,CAAC,EACzBC,EAAY,CACd,IAAMS,EAAMH,EAAKN,CAAU,EACvBS,GAAQ,MAA6B,OAAOA,CAAG,IAAM,KACvDD,EAAa,OAAOC,CAAG,EAE3B,MACK,CACL,IAAMC,EAAM,OAAOJ,CAAI,EACvB1B,EAAQ8B,EACRH,EAAOG,CACT,CAEA,IAAMlC,EAAS,IAAI,OAAO+B,EAAM3B,CAAK,EACrC,GAAI4B,EAAY,CACd,IAAIG,EAAWN,EAAO,IAAIG,CAAU,EAC/BG,IACHA,EAAW,SAAS,cAAc,UAAU,EAC5CA,EAAS,MAAQH,EACjBH,EAAO,IAAIG,EAAYG,CAAQ,EAC/B9C,EAAO,YAAY8C,CAAQ,GAE7BA,EAAS,YAAYnC,CAAM,CAC7B,MACEX,EAAO,IAAIW,CAAM,CAErB,CACF,CAEA,SAASF,GAASP,EAAkBC,EAAuB,CACzD,IAAMI,EAAKL,EACX,GAAIC,KAAQI,GAAM,OAAOA,EAAGJ,CAAI,GAAM,UAAW,OAAOI,EAAGJ,CAAI,EAC/D,IAAM4C,EAAO7C,EAAQ,aAAaC,CAAI,EACtC,OAAI4C,IAAS,KAAa,GACtBA,IAAS,IAAMA,EAAK,YAAY,IAAM,QAAUA,EAAK,YAAY,IAAM5C,CAE7E,CC/PF,IAAM6C,GAAkD,IAAI,IAkBrD,SAASC,EAAkBC,EAAwBC,EAA4B,CAAC,EAAG,CACtF,OAAO,SAAUC,EAA2C,CACxDJ,GAAW,IAAIE,EAAgB,CAAE,UAAWE,EAAQ,gBAAAD,CAAgB,CAAC,CACzE,CACJ,CAQO,SAASE,GAAaC,EAAkD,CAC3E,OAAON,GAAW,IAAIM,CAAI,CAC9B,CAjFA,IAAAC,GAAAC,EAuFAD,GAAA,CAACN,EAAkB,UAAU,GACtB,IAAMQ,EAAN,MAAMA,CAAwC,CACjD,OAAO,OAAOC,EAAyC,CACnD,OAAOA,IAAS,WAAa,IAAID,EAAuB,IAC5D,CAEA,SAASE,EAAeC,EAA4B,CAC5CD,EAAM,KAAK,IAAM,IAIrBC,EAAQ,SAAS,KAAK,WAAW,CAAC,CACtC,CAEA,YAAqB,CACjB,OAAOC,EAAE,uBAAuB,CACpC,CACJ,EAhBOL,EAAAM,EAAA,MAAML,EAANM,EAAAP,EAAA,uBADPD,GACaE,GAANO,EAAAR,EAAA,EAAMC,GAAN,IAAMQ,EAANR,EAxFPS,GAAAV,EAiHAU,GAAA,CAACjB,EAAkB,QAAS,CAAC,QAAQ,CAAC,GAC/B,IAAMkB,EAAN,MAAMA,CAAqC,CAI9C,YAAYC,EAAaC,EAAa,CAHtC,gBACA,gBAGI,KAAK,IAAMD,EACX,KAAK,IAAMC,CACf,CAEA,OAAO,OAAOX,EAAsC,CAChD,IAAMY,EAAaZ,EAAK,MAAM,gDAAgD,EAC9E,GAAIY,EAAY,CACZ,GAAM,CAAC,CAAEF,EAAKC,CAAG,EAAIC,EACrB,OAAO,IAAIH,EAAgB,WAAWC,CAAG,EAAG,WAAWC,CAAG,CAAC,CAC/D,CACA,OAAO,IACX,CAEA,SAASV,EAAeC,EAA4B,CAChD,GAAID,EAAM,KAAK,IAAM,GAAI,OAEzB,IAAMY,EAAM,WAAWZ,CAAK,EACxB,CAAC,MAAMY,CAAG,GAAKA,GAAO,KAAK,KAAOA,GAAO,KAAK,KAIlDX,EAAQ,SAAS,KAAK,WAAWD,CAAK,CAAC,CAC3C,CAEA,WAAWa,EAAwB,CAC/B,OAAOX,EAAE,qBAAsB,CAAE,IAAK,KAAK,IAAK,IAAK,KAAK,IAAK,OAAAW,CAAO,CAAC,CAC3E,CACJ,EAhCOhB,EAAAM,EAAA,MAAMK,EAANJ,EAAAP,EAAA,oBADPU,GACaC,GAANH,EAAAR,EAAA,EAAMW,GAAN,IAAMM,EAANN,EAlHPO,GAAAlB,EAwJAkB,GAAA,CAACzB,EAAkB,SAAU,CAAC,QAAQ,CAAC,GAChC,IAAM0B,EAAN,MAAMA,CAAsC,CAC/C,OAAO,OAAOjB,EAAuC,CACjD,OAAOA,IAAS,SAAW,IAAIiB,EAAqB,IACxD,CAEA,SAAShB,EAAeC,EAA4B,CAC5C,QAAQ,KAAKD,CAAK,GAItBC,EAAQ,SAAS,KAAK,WAAW,CAAC,CACtC,CAEA,YAAqB,CACjB,OAAOC,EAAE,qBAAqB,CAClC,CACJ,EAhBOL,EAAAM,EAAA,MAAMa,EAANZ,EAAAP,EAAA,qBADPkB,GACaC,GAANX,EAAAR,EAAA,EAAMmB,GAAN,IAAMC,EAAND",
  "names": ["require_r_common", "__commonJSMin", "exports", "module", "require_r_pipes", "__commonJSMin", "exports", "module", "require_r_validation", "__commonJSMin", "exports", "module", "pluralRulesCache", "getPluralRule", "locale", "escapeRegex", "s", "defaultFormatICU", "message", "values", "_", "key", "type", "categoriesPart", "value", "exact", "category", "match", "escaped", "formatICU", "catalogue", "normalizeLocale", "locale", "registerNamespace", "locale", "namespace", "source", "normalized", "normalizeLocale", "catalogue", "r_common_default", "r_pipes_default", "r_validation_default", "registerBuiltinNamespaces", "registerNamespace", "r_common_default", "r_pipes_default", "r_validation_default", "fallbackLocale", "currentLocale", "translations", "missingHandler", "registerBuiltinNamespaces", "t", "fullKey", "values", "options", "namespace", "key", "message", "translations", "format", "missingHandler", "currentLocale", "onError", "formatICU", "getCurrentLocale", "mapFormToClass", "form", "instance", "options", "formElements", "element", "booleanAttr", "propertyName", "value", "readElementValue", "SKIP", "formFieldNames", "prop", "getDataConverter", "dataType", "createConverterFromDataType", "createConverterFromInputType", "BooleanConverter", "str", "readData", "data", "formData", "seen", "_", "name", "values", "converter", "v", "i", "el", "lower", "NumberConverter", "nr", "getLocaleDateOrder", "locale", "p", "DateConverter", "date", "numericParts", "getCurrentLocale", "order", "mapped", "type", "inputType", "year", "month", "week", "hours", "minutes", "seconds", "attr", "o", "RelaxError", "message", "context", "handler", "reportError", "message", "context", "error", "RelaxError", "handler", "suppressed", "getFieldName", "element", "id", "form", "label", "FormValidator", "options", "event", "result", "cause", "error", "reportError", "formElements", "isFormValid", "errorMessages", "fieldName", "messages", "errorList", "message", "listItem", "errorSummary", "ul", "firstInvalidElement", "i", "child", "setFormData", "form", "data", "context", "select", "populateSelectOptions", "element", "name", "arrayName", "arrayValue", "getValueByComplexPath", "el", "type", "boolAttr", "val", "option", "opt", "allWithName", "idx", "value", "setElementValue", "obj", "path", "segments", "currentSegment", "inBrackets", "i", "char", "result", "segment", "index", "pad", "n", "options", "vals", "dataSource", "sourceKey", "valueField", "textField", "groupField", "match", "source", "items", "placeholders", "groups", "item", "text", "groupLabel", "raw", "str", "optgroup", "attr", "validators", "RegisterValidator", "validationName", "validInputTypes", "target", "getValidator", "name", "_RequiredValidation_decorators", "_init", "_RequiredValidation", "rule", "value", "context", "t", "__decoratorStart", "__decorateElement", "__runInitializers", "RequiredValidation", "_RangeValidation_decorators", "_RangeValidation", "min", "max", "rangeMatch", "num", "actual", "RangeValidation", "_DigitsValidation_decorators", "_DigitsValidation", "DigitsValidation"]
}
